From 6d820e01fdd33897bc2c147ca32604cdcd4d84d5 Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Thu, 23 Apr 2026 00:16:50 -0400 Subject: [PATCH] Initial UI design --- package.json | 8 +++- resources/sleep.pdc | Bin 0 -> 94 bytes src/c/main.c | 92 +++++++++++++++++++++++++++++--------------- src/pkjs/index.js | 2 +- 4 files changed, 69 insertions(+), 33 deletions(-) create mode 100644 resources/sleep.pdc diff --git a/package.json b/package.json index 25f369c..539a4c0 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,13 @@ ], "projectType": "native", "resources": { - "media": [] + "media": [ + { + "type": "raw", + "name": "SLEEP_ICON", + "file": "sleep.pdc" + } + ] }, "sdkVersion": "3", "targetPlatforms": [ diff --git a/resources/sleep.pdc b/resources/sleep.pdc new file mode 100644 index 0000000000000000000000000000000000000000..80f990e4d6b20a42fe9d5e6568c57d6647a44838 GIT binary patch literal 94 zcmWG=arO*jU|?WmkYo^NU}9iqIKcFufq|Q$hk=D*4}%F1moT(2tYL5gViSfrK+!b} fGC&a?pg0eM4G^+GG%*4hEvalue->cstring); } } @@ -39,7 +41,7 @@ static void inbox_received_handler_watched(DictionaryIterator *iter, void *conte static void inbox_received_handler_ready(DictionaryIterator *iter, void *context) { Tuple *ready_tuple = dict_find(iter, MESSAGE_KEY_PKJS_READY); if (ready_tuple) { - APP_LOG(APP_LOG_LEVEL_INFO, "Received PKJS_READY, calling PKJS..."); + // APP_LOG(APP_LOG_LEVEL_INFO, "Received PKJS_READY, calling PKJS..."); send_sleep_time_to_pkjs(); app_message_register_inbox_received(inbox_received_handler_watched); } @@ -56,53 +58,77 @@ static void update_sleep_time(time_t start, time_t end) { cb_update_sleep_time, NULL); } +static void button_bar_update_proc(Layer *layer, GContext *ctx) { + graphics_context_set_fill_color(ctx, GColorLiberty); + graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone); +} + +static void sleep_bar_update_proc(Layer *layer, GContext *ctx) { + graphics_context_set_fill_color(ctx, GColorVividViolet); + graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone); +} + +static void sleep_icon_update_proc(Layer *layer, GContext *ctx) { + gdraw_command_image_draw(ctx, s_sleep_icon, GPoint(0, 0)); +} + static void main_window_load(Window *window) { - s_sleep_time_header_layer = text_layer_create(GRect(6, 0, PBL_DISPLAY_WIDTH, 30)); - text_layer_set_background_color(s_sleep_time_header_layer, GColorClear); - text_layer_set_font(s_sleep_time_header_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD)); - text_layer_set_text(s_sleep_time_header_layer, "Last Sleep"); - s_sleep_time_layer = text_layer_create(GRect(10, 24, PBL_DISPLAY_WIDTH, 30)); + // button bar + s_button_bar_layer = layer_create(GRect(PBL_DISPLAY_WIDTH - 25, 0, 25, PBL_DISPLAY_HEIGHT)); + layer_set_update_proc(s_button_bar_layer, button_bar_update_proc); + + // sleep bar + s_sleep_bar_layer = layer_create(GRect(0, 0, PBL_DISPLAY_WIDTH, PBL_IF_ROUND_ELSE(49, 31))); + layer_set_update_proc(s_sleep_bar_layer, sleep_bar_update_proc); + + // sleep icon + s_sleep_icon_layer = layer_create(GRect(PBL_IF_ROUND_ELSE((PBL_DISPLAY_WIDTH / 2) - 13, 4), 4, PBL_DISPLAY_WIDTH, 50)); + layer_set_update_proc(s_sleep_icon_layer, sleep_icon_update_proc); + + // sleep time + s_sleep_time_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(24, -2), PBL_DISPLAY_WIDTH, 30)); text_layer_set_background_color(s_sleep_time_layer, GColorClear); - text_layer_set_font(s_sleep_time_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24)); + text_layer_set_font(s_sleep_time_layer, fonts_get_system_font(PBL_IF_ROUND_ELSE(FONT_KEY_GOTHIC_18_BOLD, FONT_KEY_GOTHIC_24_BOLD))); + text_layer_set_text_alignment(s_sleep_time_layer, GTextAlignmentCenter); + text_layer_set_text_color(s_sleep_time_layer, GColorWhite); if (s_sleep_timestamp != 0) { static char buffer[8]; struct tm *timeinfo = localtime(&s_sleep_timestamp); strftime(buffer, sizeof(buffer), clock_is_24h_style() ? "%H:%M" : "%I:%M", timeinfo); text_layer_set_text(s_sleep_time_layer, buffer); } else { - text_layer_set_text(s_sleep_time_layer, "N/A (rough night?)"); + text_layer_set_text(s_sleep_time_layer, "No sleep last night"); } - s_last_watched_header_layer = text_layer_create(GRect(6, 72, PBL_DISPLAY_WIDTH, 30)); - text_layer_set_background_color(s_last_watched_header_layer, GColorClear); - text_layer_set_font(s_last_watched_header_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD)); - text_layer_set_text(s_last_watched_header_layer, "Last Episode"); - s_last_watched_layer = text_layer_create(GRect(10, 96, PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT)); + + // watched title + s_last_watched_layer = text_layer_create(GRect(0, PBL_DISPLAY_HEIGHT / 2 - 24, PBL_DISPLAY_WIDTH - 4, PBL_DISPLAY_HEIGHT)); + text_layer_set_background_color(s_last_watched_layer, GColorClear); + text_layer_set_font(s_last_watched_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24)); + if (s_sleep_data_accessible) { + text_layer_set_text(s_last_watched_layer, "N/A"); // default - will be updated before display + } else { + text_layer_set_text(s_last_watched_layer, "Sleep data inaccessible!\nEnsure Pebble Health is enabled."); + } + #if PBL_ROUND text_layer_set_text_alignment(s_last_watched_layer, GTextAlignmentCenter); #endif - text_layer_set_background_color(s_last_watched_layer, GColorClear); - text_layer_set_font(s_last_watched_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24)); - text_layer_set_text(s_last_watched_layer, "N/A"); // default - will be updated before display - s_pin_notice_layer = text_layer_create(GRect(0, PBL_DISPLAY_HEIGHT - 50, PBL_DISPLAY_WIDTH, 50)); - text_layer_set_background_color(s_pin_notice_layer, GColorClear); - text_layer_set_font(s_pin_notice_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14)); - text_layer_set_text_alignment(s_pin_notice_layer, GTextAlignmentCenter); // add layers as children to windows Layer *window_layer = window_get_root_layer(window); - layer_add_child(window_layer, text_layer_get_layer(s_sleep_time_header_layer)); + layer_add_child(window_layer, s_button_bar_layer); + layer_add_child(window_layer, s_sleep_bar_layer); + layer_add_child(window_layer, s_sleep_icon_layer); layer_add_child(window_layer, text_layer_get_layer(s_sleep_time_layer)); - layer_add_child(window_layer, text_layer_get_layer(s_last_watched_header_layer)); layer_add_child(window_layer, text_layer_get_layer(s_last_watched_layer)); - layer_add_child(window_layer, text_layer_get_layer(s_pin_notice_layer)); } static void main_window_unload(Window *window) { - text_layer_destroy(s_sleep_time_header_layer); + layer_destroy(s_sleep_icon_layer); + layer_destroy(s_sleep_bar_layer); + layer_destroy(s_button_bar_layer); text_layer_destroy(s_sleep_time_layer); - text_layer_destroy(s_last_watched_header_layer); text_layer_destroy(s_last_watched_layer); - text_layer_destroy(s_pin_notice_layer); } static void init() { @@ -120,11 +146,15 @@ static void init() { time_t end = time(NULL); time_t start = end - (SECONDS_PER_DAY * 1.5); if (health_service_any_activity_accessible(HealthActivitySleep, start, end) == HealthServiceAccessibilityMaskAvailable) { + s_sleep_data_accessible = true; update_sleep_time(start, end); } else { - APP_LOG(APP_LOG_LEVEL_DEBUG, "Sleep activity inaccessible", NULL); + s_sleep_data_accessible = false; } + // load PDCs + s_sleep_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_SLEEP_ICON); + window_stack_push(s_main_window, true); } diff --git a/src/pkjs/index.js b/src/pkjs/index.js index b49bad9..3d33bec 100644 --- a/src/pkjs/index.js +++ b/src/pkjs/index.js @@ -65,7 +65,7 @@ function callAPI(fullURL, apiKey, isJellyfin, trackedUser, sleepTimestamp) { }); } if (lastWatched != "") { - console.log("Last watched: " + lastWatched); + //console.log("Last watched: " + lastWatched); var dict = { 'PKJS_LAST_WATCHED': lastWatched } Pebble.sendAppMessage(dict); }