Add soft-reload after changing settings

This commit is contained in:
2026-05-02 14:52:29 -04:00
parent b669e03d60
commit dc2b1a129c
2 changed files with 118 additions and 100 deletions

View File

@@ -7,7 +7,7 @@ static uint8_t s_is_jellyfin;
static GColor s_color_primary = GColorWhite;
static GColor s_color_secondary = GColorWhite;
// declare window statics
// declare window/layer statics
static Window *s_main_window;
static TextLayer *s_config_app_layer;
static TextLayer *s_sleep_time_layer;
@@ -28,91 +28,6 @@ static time_t s_sleep_timestamp;
static bool s_sleep_session_found;
static bool s_sleep_data_accessible;
static void load_complete_animation_handler(Animation *animation, bool finished, void *context) {
layer_set_hidden(text_layer_get_layer(s_sleep_time_layer), false);
animation_destroy(animation);
}
static void send_sleep_time_to_pkjs() {
DictionaryIterator *out;
AppMessageResult result = app_message_outbox_begin(&out);
if (result != APP_MSG_OK) {
text_layer_set_text(s_last_watched_layer, "outbox_begin failure");
return;
}
if (s_sleep_session_found) {
dict_write_uint32(out, MESSAGE_KEY_PKJS_SLEEP_TIMESTAMP, s_sleep_timestamp);
} else {
// send current UNIX timestamp to fetch the last thing played
dict_write_uint32(out, MESSAGE_KEY_PKJS_SLEEP_TIMESTAMP, time(NULL));
}
result = app_message_outbox_send();
if (result != APP_MSG_OK) {
text_layer_set_text(s_last_watched_layer, "outbox_send failure");
return;
}
}
static void inbox_received_handler(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...");
send_sleep_time_to_pkjs();
}
Tuple *clay_tuple = dict_find(iter, MESSAGE_KEY_CLAY_API_IS_JELLYFIN);
if (clay_tuple) {
// APP_LOG(APP_LOG_LEVEL_INFO, "Received CLAY_API_IS_JELLYFIN, updating UI...");
bool is_jellyfin = clay_tuple->value->int32 == 1;
if (is_jellyfin) {
persist_write_int(0, 1);
s_color_primary = GColorVividViolet;
s_color_secondary = GColorPictonBlue;
#if PBL_ROUND
s_pin_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_PIN_ROUND_JELLYFIN_ICON);
#endif
} else {
persist_write_int(0, 2);
s_color_primary = GColorChromeYellow;
s_color_secondary = GColorLightGray;
#if PBL_ROUND
s_pin_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_PIN_ROUND_PLEX_ICON);
#endif
}
layer_mark_dirty(s_sleep_bar_layer);
#if PBL_ROUND
layer_mark_dirty(s_pin_icon_layer);
#else
layer_mark_dirty(s_button_bar_layer);
#endif
}
Tuple *watched_tuple = dict_find(iter, MESSAGE_KEY_PKJS_LAST_WATCHED);
if (watched_tuple) {
// APP_LOG(APP_LOG_LEVEL_INFO, "Received PKJS_LAST_WATCHED, displaying...");
if (s_sleep_session_found) {
text_layer_set_text(s_last_watched_layer, watched_tuple->value->cstring);
} else {
static char last_watched_buffer[1024];
snprintf(last_watched_buffer, sizeof(last_watched_buffer), "Last item played:\n%s", watched_tuple->value->cstring);
text_layer_set_text(s_last_watched_layer, last_watched_buffer);
}
#if PBL_DISPLAY_WIDTH >= 200
PropertyAnimation *sleep_bar_prop = property_animation_create_layer_frame(s_sleep_bar_layer, &s_sleep_bar_start, &GRect(0, -PBL_DISPLAY_HEIGHT + PBL_IF_ROUND_ELSE(53, 31), PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT));
#else
PropertyAnimation *sleep_bar_prop = property_animation_create_layer_frame(s_sleep_bar_layer, &s_sleep_bar_start, &GRect(0, -PBL_DISPLAY_HEIGHT + PBL_IF_ROUND_ELSE(49, 31), PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT));
#endif
Animation *sleep_bar_anim = property_animation_get_animation(sleep_bar_prop);
animation_set_duration(sleep_bar_anim, 512);
PropertyAnimation *sleep_icon_prop = property_animation_create_layer_frame(s_sleep_icon_layer, &s_sleep_icon_start, &GRect(PBL_IF_ROUND_ELSE((PBL_DISPLAY_WIDTH / 2) - 13, 4), 4, 25, 25));
Animation *sleep_icon_anim = property_animation_get_animation(sleep_icon_prop);
animation_set_duration(sleep_icon_anim, 512);
Animation *load_spawn_anim = animation_spawn_create(sleep_bar_anim, sleep_icon_anim, NULL);
animation_set_handlers(load_spawn_anim, (AnimationHandlers){.stopped = load_complete_animation_handler}, NULL);
animation_schedule(load_spawn_anim);
}
}
static bool cb_update_sleep_time(HealthActivity activity, time_t start_time, time_t end_time, void *context) {
s_sleep_timestamp = start_time;
return false;
@@ -226,11 +141,110 @@ static void main_window_load(Window *window) {
}
static void main_window_unload(Window *window) {
text_layer_destroy(s_last_watched_layer);
text_layer_destroy(s_sleep_time_layer);
layer_destroy(s_sleep_icon_layer);
layer_destroy(s_sleep_bar_layer);
layer_destroy(s_pin_icon_layer);
layer_destroy(s_button_bar_layer);
text_layer_destroy(s_sleep_time_layer);
text_layer_destroy(s_last_watched_layer);
}
static void send_sleep_time_to_pkjs() {
DictionaryIterator *out;
AppMessageResult result = app_message_outbox_begin(&out);
if (result != APP_MSG_OK) {
text_layer_set_text(s_last_watched_layer, "outbox_begin failure");
return;
}
if (s_sleep_session_found) {
dict_write_uint32(out, MESSAGE_KEY_PKJS_SLEEP_TIMESTAMP, s_sleep_timestamp);
} else {
// send current UNIX timestamp to fetch the last thing played
dict_write_uint32(out, MESSAGE_KEY_PKJS_SLEEP_TIMESTAMP, time(NULL));
}
result = app_message_outbox_send();
if (result != APP_MSG_OK) {
text_layer_set_text(s_last_watched_layer, "outbox_send failure");
return;
}
}
static void soft_reload() {
window_stack_remove(s_main_window, false);
window_destroy(s_main_window);
s_main_window = window_create();
window_set_background_color(s_main_window, GColorBlack);
window_set_window_handlers(
s_main_window,
(WindowHandlers){.load = main_window_load, .unload = main_window_unload});
window_stack_push(s_main_window, false);
send_sleep_time_to_pkjs();
}
static void load_complete_animation_handler(Animation *animation, bool finished, void *context) {
layer_set_hidden(text_layer_get_layer(s_sleep_time_layer), false);
animation_destroy(animation);
}
static void inbox_received_handler(DictionaryIterator *iter, void *context) {
Tuple *ready_tuple = dict_find(iter, MESSAGE_KEY_PKJS_READY);
if (ready_tuple) {
send_sleep_time_to_pkjs();
return;
}
Tuple *clay_tuple = dict_find(iter, MESSAGE_KEY_CLAY_API_IS_JELLYFIN);
if (clay_tuple) {
bool is_jellyfin = clay_tuple->value->int32 == 1;
if (is_jellyfin) {
persist_write_int(0, 1);
s_color_primary = GColorVividViolet;
s_color_secondary = GColorPictonBlue;
#if PBL_ROUND
s_pin_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_PIN_ROUND_JELLYFIN_ICON);
#endif
} else {
persist_write_int(0, 2);
s_color_primary = GColorChromeYellow;
s_color_secondary = GColorLightGray;
#if PBL_ROUND
s_pin_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_PIN_ROUND_PLEX_ICON);
#endif
}
layer_mark_dirty(s_sleep_bar_layer);
#if PBL_ROUND
layer_mark_dirty(s_pin_icon_layer);
#else
layer_mark_dirty(s_button_bar_layer);
#endif
soft_reload(); // app needs "restarted" when settings are changed
return;
}
Tuple *watched_tuple = dict_find(iter, MESSAGE_KEY_PKJS_LAST_WATCHED);
if (watched_tuple) {
if (s_sleep_session_found) {
text_layer_set_text(s_last_watched_layer, watched_tuple->value->cstring);
} else {
static char last_watched_buffer[1024];
snprintf(last_watched_buffer, sizeof(last_watched_buffer), "Last item played:\n%s", watched_tuple->value->cstring);
text_layer_set_text(s_last_watched_layer, last_watched_buffer);
}
#if PBL_DISPLAY_WIDTH >= 200
PropertyAnimation *sleep_bar_prop = property_animation_create_layer_frame(s_sleep_bar_layer, &s_sleep_bar_start, &GRect(0, -PBL_DISPLAY_HEIGHT + PBL_IF_ROUND_ELSE(53, 31), PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT));
#else
PropertyAnimation *sleep_bar_prop = property_animation_create_layer_frame(s_sleep_bar_layer, &s_sleep_bar_start, &GRect(0, -PBL_DISPLAY_HEIGHT + PBL_IF_ROUND_ELSE(49, 31), PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT));
#endif
Animation *sleep_bar_anim = property_animation_get_animation(sleep_bar_prop);
animation_set_duration(sleep_bar_anim, 512);
PropertyAnimation *sleep_icon_prop = property_animation_create_layer_frame(s_sleep_icon_layer, &s_sleep_icon_start, &GRect(PBL_IF_ROUND_ELSE((PBL_DISPLAY_WIDTH / 2) - 13, 4), 4, 25, 25));
Animation *sleep_icon_anim = property_animation_get_animation(sleep_icon_prop);
animation_set_duration(sleep_icon_anim, 512);
Animation *load_spawn_anim = animation_spawn_create(sleep_bar_anim, sleep_icon_anim, NULL);
animation_set_handlers(load_spawn_anim, (AnimationHandlers){.stopped = load_complete_animation_handler}, NULL);
animation_schedule(load_spawn_anim);
return;
}
}
static void init() {

View File

@@ -51,17 +51,22 @@ function callAPI(fullURL, apiKey, isJellyfin, trackedUser, sleepTimestamp) {
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 0) {
switch (xhr.status) {
case 200:
break;
case 0:
reportApiError("API UNREACHABLE");
return;
}
if (xhr.status < 200 || xhr.status >= 300) {
if (xhr.status == 401) {
case 401:
case 403:
reportApiError("API ERROR: " + xhr.status + " (CHECK API KEY)");
} else {
reportApiError("API ERROR: " + xhr.status);
}
return;
case 404:
case 405:
reportApiError("API ERROR: " + xhr.status + " (INVALID ENDPOINT?)");
return;
default:
reportApiError("API ERROR: " + xhr.status);
}
if (!xhr.responseText) {
reportApiError("API EMPTY RESPONSE");
@@ -111,7 +116,6 @@ function callAPI(fullURL, apiKey, isJellyfin, trackedUser, sleepTimestamp) {
});
}
if (lastWatched != "") {
//console.log("Last watched: " + lastWatched);
Pebble.sendAppMessage({ PKJS_LAST_WATCHED: lastWatched });
} else {
Pebble.sendAppMessage({ PKJS_LAST_WATCHED: "NO WATCH HISTORY FOUND FOR USER " + trackedUser });