diff options
| -rw-r--r-- | src/c/fastforge.c | 51 | ||||
| -rw-r--r-- | src/c/fastforge.h | 1 | ||||
| -rw-r--r-- | src/c/fastforge_core.c | 21 |
3 files changed, 64 insertions, 9 deletions
diff --git a/src/c/fastforge.c b/src/c/fastforge.c index 8d410a7..f1d0131 100644 --- a/src/c/fastforge.c +++ b/src/c/fastforge.c @@ -7,15 +7,16 @@ enum { MAIN_MENU_INDEX_START_NEW = 0, - MAIN_MENU_INDEX_CURRENT_TIMER = 1, - MAIN_MENU_INDEX_STOP_CURRENT = 2, - MAIN_MENU_INDEX_CANCEL_CURRENT = 3, - MAIN_MENU_INDEX_HISTORY = 4, - MAIN_MENU_INDEX_STATS = 5, - MAIN_MENU_INDEX_SETTINGS = 6, - MAIN_MENU_INDEX_BACKUP = 7, - MAIN_MENU_INDEX_ABOUT = 8, - MAIN_MENU_ITEM_COUNT = 9 + MAIN_MENU_INDEX_RESUME_LAST = 1, /* undo an accidental fast_stop */ + MAIN_MENU_INDEX_CURRENT_TIMER = 2, + MAIN_MENU_INDEX_STOP_CURRENT = 3, + MAIN_MENU_INDEX_CANCEL_CURRENT = 4, + MAIN_MENU_INDEX_HISTORY = 5, + MAIN_MENU_INDEX_STATS = 6, + MAIN_MENU_INDEX_SETTINGS = 7, + MAIN_MENU_INDEX_BACKUP = 8, + MAIN_MENU_INDEX_ABOUT = 9, + MAIN_MENU_ITEM_COUNT = 10 }; enum { @@ -48,6 +49,7 @@ MenuLayer *s_history_menu_layer; static SimpleMenuSection s_main_menu_sections[1]; static SimpleMenuSection s_presets_menu_sections[1]; static SimpleMenuItem s_main_menu_items[MAIN_MENU_ITEM_COUNT]; +static char s_menu_resume_subtitle[40]; static SimpleMenuItem s_presets_menu_items[PRESET_MENU_ITEM_COUNT]; static TextLayer *s_title_layer; @@ -676,8 +678,20 @@ static void sync_main_menu_state(void) { snprintf(s_menu_stop_subtitle, sizeof(s_menu_stop_subtitle), "No fast running"); snprintf(s_menu_cancel_subtitle, sizeof(s_menu_cancel_subtitle), "No fast running"); } + + /* Resume subtitle: show the duration of the last fast when it is resumable. */ + if (!fast_is_running() && history_count > 0) { + char dur[16]; + format_duration_hours_minutes( + entry_duration_seconds(&history[history_count - 1]), dur, sizeof(dur)); + snprintf(s_menu_resume_subtitle, sizeof(s_menu_resume_subtitle), "Last: %s", dur); + } else { + snprintf(s_menu_resume_subtitle, sizeof(s_menu_resume_subtitle), "No previous fast"); + } + s_main_menu_items[MAIN_MENU_INDEX_STOP_CURRENT].subtitle = s_menu_stop_subtitle; s_main_menu_items[MAIN_MENU_INDEX_CANCEL_CURRENT].subtitle = s_menu_cancel_subtitle; + s_main_menu_items[MAIN_MENU_INDEX_RESUME_LAST].subtitle = s_menu_resume_subtitle; if (s_main_menu_layer) { menu_layer_reload_data(simple_menu_layer_get_menu_layer(s_main_menu_layer)); @@ -1103,6 +1117,20 @@ static void menu_start_new_fast_callback(int index, void *context) { safe_push_window(s_presets_window, true); } +/* Undo an accidental stop: restore the last history entry as the running fast. */ +static void menu_resume_last_callback(int index, void *context) { + (void)index; + (void)context; + if (!fast_resume_last()) { + show_placeholder_window("CANNOT RESUME", + "No previous fast to resume, or a fast is already running.", + "BACK Menu"); + return; + } + safe_push_window(s_timer_window, true); + refresh_all_ui_state(); +} + static void menu_current_timer_callback(int index, void *context) { (void)index; (void)context; @@ -1818,6 +1846,11 @@ static void configure_main_menu_items(void) { .subtitle = "Open preset targets", .callback = menu_start_new_fast_callback }; + s_main_menu_items[MAIN_MENU_INDEX_RESUME_LAST] = (SimpleMenuItem) { + .title = "Resume Last Fast", + .subtitle = s_menu_resume_subtitle, /* set dynamically by sync_main_menu_state */ + .callback = menu_resume_last_callback + }; s_main_menu_items[MAIN_MENU_INDEX_CURRENT_TIMER] = (SimpleMenuItem) { .title = "Current Timer", .subtitle = "Live countdown screen", diff --git a/src/c/fastforge.h b/src/c/fastforge.h index de1959c..b3f4dc4 100644 --- a/src/c/fastforge.h +++ b/src/c/fastforge.h @@ -29,6 +29,7 @@ bool fast_is_running(void); bool fast_start(uint16_t preset_target_minutes); bool fast_stop(void); bool fast_cancel(void); +bool fast_resume_last(void); bool history_delete_entry(int index); #endif diff --git a/src/c/fastforge_core.c b/src/c/fastforge_core.c index 605ea3b..5f2d9e5 100644 --- a/src/c/fastforge_core.c +++ b/src/c/fastforge_core.c @@ -317,6 +317,27 @@ bool fast_stop(void) { return true; } +/* Restore the most-recently completed fast as the running fast. + * Removes the last history entry, sets it as current_fast with end_time=0, + * and reschedules the alarm. Acts as an "undo stop". */ +bool fast_resume_last(void) { + if (fast_is_running() || history_count <= 0) { + return false; + } + + current_fast = history[history_count - 1]; + current_fast.end_time = 0; /* mark as running again */ + history_count--; + memset(&history[history_count], 0, sizeof(FastEntry)); + + recompute_streak_data_for_today(); + save_all_data(); + schedule_alarm_if_needed(); + APP_LOG(APP_LOG_LEVEL_INFO, "Resumed last fast: start=%ld target=%u", + (long)current_fast.start_time, current_fast.target_minutes); + return true; +} + /* Cancel discards the running fast without recording it in history. */ bool fast_cancel(void) { if (!fast_is_running()) { |
