Bläddra i källkod

feat: long cycle (#42) (#45)

* add current stage labels

* add drop loop

* add long sequence

* add docs for current label method

* unified context references
Mikhail Gubenko 3 år sedan
förälder
incheckning
2f2962d96a

+ 1 - 1
flipp_pomodoro_app.c

@@ -35,7 +35,7 @@ static bool flipp_pomodoro_app_custom_event_callback(void *ctx, uint32_t event)
             FlippPomodoroAppCustomEventStateUpdated);
         return CustomEventConsumed;
     case FlippPomodoroAppCustomEventStageComplete:
-        if (flipp_pomodoro__get_stage(app->state) == Work)
+        if (flipp_pomodoro__get_stage(app->state) == FlippPomodoroStageFocus)
         {
             // REGISTER a deed on work stage complete to get an acheivement
             DOLPHIN_DEED(DolphinDeedPluginGameWin);

+ 3 - 2
helpers/notifications.h

@@ -8,6 +8,7 @@ extern const NotificationSequence rest_start_notification;
 
 /// @brief Defines a notification sequence that should indicate start of specific pomodoro stage.
 const NotificationSequence *stage_start_notification_sequence_map[] = {
-    [Work] = &work_start_notification,
-    [Rest] = &rest_start_notification,
+    [FlippPomodoroStageFocus] = &work_start_notification,
+    [FlippPomodoroStageRest] = &rest_start_notification,
+    [FlippPomodoroStageLongBreak] = &rest_start_notification,
 };

+ 39 - 13
modules/flipp_pomodoro.c

@@ -3,35 +3,60 @@
 #include "../helpers/time.h"
 #include "flipp_pomodoro.h"
 
-char *next_stage_label[] = {
-    [Work] = "Get Rest",
-    [Rest] = "Start Work",
+PomodoroStage stages_sequence[] = {
+    FlippPomodoroStageFocus,
+    FlippPomodoroStageRest,
+
+    FlippPomodoroStageFocus,
+    FlippPomodoroStageRest,
+
+    FlippPomodoroStageFocus,
+    FlippPomodoroStageRest,
+
+    FlippPomodoroStageFocus,
+    FlippPomodoroStageLongBreak,
 };
 
-const PomodoroStage stage_rotaion_map[] = {
-    [Work] = Rest,
-    [Rest] = Work,
+char *current_stage_label[] = {
+    [FlippPomodoroStageFocus] = "Continue focus for:",
+    [FlippPomodoroStageRest] = "Keep rest for:",
+    [FlippPomodoroStageLongBreak] = "Long Break for:",
 };
 
-const PomodoroStage default_stage = Work;
+char *next_stage_label[] = {
+    [FlippPomodoroStageFocus] = "Focus",
+    [FlippPomodoroStageRest] = "Short Break",
+    [FlippPomodoroStageLongBreak] = "Long Break",
+};
+
+PomodoroStage flipp_pomodoro__stage_by_index(int index) {
+    const int one_loop_size = sizeof(stages_sequence);
+    return stages_sequence[index % one_loop_size];
+}
 
 void flipp_pomodoro__toggle_stage(FlippPomodoroState *state)
 {
     furi_assert(state);
-    state->stage = stage_rotaion_map[flipp_pomodoro__get_stage(state)];
+    state->current_stage_index = state->current_stage_index + 1;
     state->started_at_timestamp = time_now();
 };
 
 PomodoroStage flipp_pomodoro__get_stage(FlippPomodoroState *state)
 {
     furi_assert(state);
-    return state->stage;
+    return flipp_pomodoro__stage_by_index(state->current_stage_index);
+};
+
+char *flipp_pomodoro__current_stage_label(FlippPomodoroState *state)
+{
+    furi_assert(state);
+    return current_stage_label[flipp_pomodoro__get_stage(state)];
 };
 
 char *flipp_pomodoro__next_stage_label(FlippPomodoroState *state)
 {
     furi_assert(state);
-    return next_stage_label[flipp_pomodoro__get_stage(state)];
+    return next_stage_label[flipp_pomodoro__stage_by_index(state->current_stage_index + 1)];
 };
 
 void flipp_pomodoro__destroy(FlippPomodoroState *state)
@@ -43,8 +68,9 @@ void flipp_pomodoro__destroy(FlippPomodoroState *state)
 uint32_t flipp_pomodoro__current_stage_total_duration(FlippPomodoroState *state)
 {
     const int32_t stage_duration_seconds_map[] = {
-        [Work] = 25 * TIME_SECONDS_IN_MINUTE,
-        [Rest] = 5 * TIME_SECONDS_IN_MINUTE,
+        [FlippPomodoroStageFocus] = 25 * TIME_SECONDS_IN_MINUTE,
+        [FlippPomodoroStageRest] = 5 * TIME_SECONDS_IN_MINUTE,
+        [FlippPomodoroStageLongBreak] = 30 * TIME_SECONDS_IN_MINUTE,
     };
 
     return stage_duration_seconds_map[flipp_pomodoro__get_stage(state)];
@@ -73,6 +99,6 @@ FlippPomodoroState *flipp_pomodoro__new()
     FlippPomodoroState *state = malloc(sizeof(FlippPomodoroState));
     const uint32_t now = time_now();
     state->started_at_timestamp = now;
-    state->stage = default_stage;
+    state->current_stage_index = 0;
     return state;
 };

+ 9 - 2
modules/flipp_pomodoro.h

@@ -6,14 +6,16 @@
 /// @brief Options of pomodoro stages
 typedef enum
 {
-    Work,
-    Rest,
+    FlippPomodoroStageFocus,
+    FlippPomodoroStageRest,
+    FlippPomodoroStageLongBreak,
 } PomodoroStage;
 
 /// @brief State of the pomodoro timer
 typedef struct
 {
     PomodoroStage stage;
+    uint8_t current_stage_index;
     uint32_t started_at_timestamp;
 } FlippPomodoroState;
 
@@ -34,6 +36,11 @@ void flipp_pomodoro__destroy(FlippPomodoroState *state);
 /// @returns Time difference to the end of current stage
 TimeDifference flipp_pomodoro__stage_remaining_duration(FlippPomodoroState *state);
 
+/// @brief Label of currently active stage
+/// @param state - pointer to the state of pomorodo
+/// @returns A string that explains current stage
+char *flipp_pomodoro__current_stage_label(FlippPomodoroState *state);
+
 /// @brief Label of transition to the next stage
 /// @param state - pointer to the state of pomorodo.
 /// @returns string with the label of the "skipp" button

+ 2 - 2
scenes/flipp_pomodoro_scene.c

@@ -9,14 +9,14 @@ void (*const flipp_pomodoro_scene_on_enter_handlers[])(void*) = {
 
 // Generate scene on_event handlers array
 #define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
-bool (*const flipp_pomodoro_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
+bool (*const flipp_pomodoro_scene_on_event_handlers[])(void* ctx, SceneManagerEvent event) = {
 #include "config/flipp_pomodoro_scene_config.h"
 };
 #undef ADD_SCENE
 
 // Generate scene on_exit handlers array
 #define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
-void (*const flipp_pomodoro_scene_on_exit_handlers[])(void* context) = {
+void (*const flipp_pomodoro_scene_on_exit_handlers[])(void* ctx) = {
 #include "config/flipp_pomodoro_scene_config.h"
 };
 #undef ADD_SCENE

+ 2 - 2
scenes/flipp_pomodoro_scene.h

@@ -18,11 +18,11 @@ extern const SceneManagerHandlers flipp_pomodoro_scene_handlers;
 
 // Generate scene on_event handlers declaration
 #define ADD_SCENE(prefix, name, id) \
-    bool prefix##_scene_##name##_on_event(void *context, SceneManagerEvent event);
+    bool prefix##_scene_##name##_on_event(void *ctx, SceneManagerEvent event);
 #include "config/flipp_pomodoro_scene_config.h"
 #undef ADD_SCENE
 
 // Generate scene on_exit handlers declaration
-#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void *context);
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void *ctx);
 #include "config/flipp_pomodoro_scene_config.h"
 #undef ADD_SCENE

+ 8 - 8
scenes/flipp_pomodoro_scene_timer.c

@@ -12,11 +12,11 @@ enum
 
 uint8_t ExitSignal = 0;
 
-void flipp_pomodoro_scene_timer_sync_view_state(void *context)
+void flipp_pomodoro_scene_timer_sync_view_state(void *ctx)
 {
-    furi_assert(context);
+    furi_assert(ctx);
 
-    FlippPomodoroApp *app = context;
+    FlippPomodoroApp *app = ctx;
 
     flipp_pomodoro_view_timer_set_state(
         flipp_pomodoro_view_timer_get_view(app->timer_view),
@@ -34,11 +34,11 @@ void flipp_pomodoro_scene_timer_on_next_stage(void *ctx)
         FlippPomodoroAppCustomEventStageSkip);
 };
 
-void flipp_pomodoro_scene_timer_on_enter(void *context)
+void flipp_pomodoro_scene_timer_on_enter(void *ctx)
 {
-    furi_assert(context);
+    furi_assert(ctx);
 
-    FlippPomodoroApp *app = context;
+    FlippPomodoroApp *app = ctx;
 
     view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewTimer);
     flipp_pomodoro_scene_timer_sync_view_state(app);
@@ -83,7 +83,7 @@ bool flipp_pomodoro_scene_timer_on_event(void *ctx, SceneManagerEvent event)
     return SceneEventNotConusmed;
 };
 
-void flipp_pomodoro_scene_timer_on_exit(void *context)
+void flipp_pomodoro_scene_timer_on_exit(void *ctx)
 {
-    UNUSED(context);
+    UNUSED(ctx);
 };

+ 49 - 3
views/flipp_pomodoro_timer_view.c

@@ -30,8 +30,9 @@ typedef struct
 } FlippPomodoroTimerViewModel;
 
 static const Icon *stage_background_image[] = {
-    [Work] = &A_flipp_pomodoro_focus_64,
-    [Rest] = &A_flipp_pomodoro_rest_64,
+    [FlippPomodoroStageFocus] = &A_flipp_pomodoro_focus_64,
+    [FlippPomodoroStageRest] = &A_flipp_pomodoro_rest_64,
+    [FlippPomodoroStageLongBreak] = &A_flipp_pomodoro_rest_64,
 };
 
 static void flipp_pomodoro_view_timer_draw_countdown(Canvas *canvas, TimeDifference remaining_time)
@@ -42,7 +43,7 @@ static void flipp_pomodoro_view_timer_draw_countdown(Canvas *canvas, TimeDiffere
     const uint8_t countdown_box_height = canvas_height(canvas) * 0.4;
     const uint8_t countdown_box_width = canvas_width(canvas) * 0.5;
     const uint8_t countdown_box_x = canvas_width(canvas) - countdown_box_width - right_border_margin;
-    const uint8_t countdown_box_y = 0;
+    const uint8_t countdown_box_y = 15;
 
     elements_bold_rounded_frame(canvas,
                                 countdown_box_x,
@@ -64,6 +65,48 @@ static void flipp_pomodoro_view_timer_draw_countdown(Canvas *canvas, TimeDiffere
     furi_string_free(timer_string);
 };
 
+static void draw_str_with_drop_shadow(
+    Canvas *canvas,  uint8_t x,
+    uint8_t y,
+    Align horizontal,
+    Align vertical,
+    const char* str
+    ) {
+        canvas_set_color(canvas, ColorWhite);
+        for (int x_off = -2; x_off <= 2; x_off++)
+        {
+            for (int y_off = -2; y_off <= 2; y_off++)
+            {
+               canvas_draw_str_aligned(
+                canvas,
+                x + x_off,
+                y + y_off,
+                horizontal,
+                vertical,
+                str);
+            }
+        }
+        canvas_set_color(canvas, ColorBlack);
+        canvas_draw_str_aligned(
+            canvas,
+            x,
+            y,
+            horizontal,
+            vertical,
+            str);
+    }
+
+static void flipp_pomodoro_view_timer_draw_current_stage_label(Canvas *canvas, FlippPomodoroState *state) {
+    canvas_set_font(canvas, FontPrimary);
+    draw_str_with_drop_shadow(
+        canvas,
+        canvas_width(canvas),
+        0,
+        AlignRight,
+        AlignTop,
+        flipp_pomodoro__current_stage_label(state));
+}
+
 static void flipp_pomodoro_view_timer_draw_callback(Canvas *canvas, void *_model)
 {
     if (!_model)
@@ -83,6 +126,9 @@ static void flipp_pomodoro_view_timer_draw_callback(Canvas *canvas, void *_model
         canvas,
         flipp_pomodoro__stage_remaining_duration(model->state));
 
+    flipp_pomodoro_view_timer_draw_current_stage_label(canvas, model->state);
+    canvas_set_color(canvas, ColorBlack);
+
     canvas_set_font(canvas, FontSecondary);
     elements_button_right(canvas, flipp_pomodoro__next_stage_label(model->state));
 };

+ 1 - 1
views/flipp_pomodoro_timer_view.h

@@ -5,7 +5,7 @@
 
 typedef struct FlippPomodoroTimerView FlippPomodoroTimerView;
 
-typedef void (*FlippPomodoroTimerViewInputCb)(void *context);
+typedef void (*FlippPomodoroTimerViewInputCb)(void *ctx);
 
 FlippPomodoroTimerView *flipp_pomodoro_view_timer_alloc();