Skip to content

Commit e4d9959

Browse files
committed
Update apps
1 parent 7bfa94d commit e4d9959

File tree

6 files changed

+213
-31
lines changed

6 files changed

+213
-31
lines changed

flipp_pomodoro_app.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ typedef enum {
1717
FlippPomodoroAppCustomEventStageSkip = 100,
1818
FlippPomodoroAppCustomEventStageComplete, // By Expiration
1919
FlippPomodoroAppCustomEventTimerTick,
20+
FlippPomodoroAppCustomEventTimerAskHint,
2021
FlippPomodoroAppCustomEventStateUpdated,
2122
FlippPomodoroAppCustomEventResumeTimer,
2223
} FlippPomodoroAppCustomEvent;

modules/flipp_pomodoro.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ PomodoroStage stages_sequence[] = {
1818
};
1919

2020
char* current_stage_label[] = {
21-
[FlippPomodoroStageFocus] = "Continue focus for:",
22-
[FlippPomodoroStageRest] = "Keep rest for:",
23-
[FlippPomodoroStageLongBreak] = "Long Break for:",
21+
[FlippPomodoroStageFocus] = "Focusing...",
22+
[FlippPomodoroStageRest] = "Short Break...",
23+
[FlippPomodoroStageLongBreak] = "Long Break...",
2424
};
2525

2626
char* next_stage_label[] = {

scenes/flipp_pomodoro_scene_timer.c

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,49 @@
88

99
enum { SceneEventConusmed = true, SceneEventNotConusmed = false };
1010

11+
static char* work_hints[] = {
12+
"Can you explain the problem as if I'm five?",
13+
"Expected output vs. reality: what's the difference?",
14+
"Ever thought of slicing the problem into bite-sized pieces?",
15+
"What's the story when you walk through the code?",
16+
"Any error messages gossiping about the issue?",
17+
"What tricks have you tried to fix this?",
18+
"Did you test the code, or just hoping for the best?",
19+
"How's this code mingling with the rest of the app?",
20+
"Any sneaky side effects causing mischief?",
21+
"What are you assuming, and is it safe to do so?",
22+
"Did you remember to invite all the edge cases to the party?",
23+
"What happens in the isolation chamber (running code separately)?",
24+
"Can you make the issue appear on command?",
25+
"What's the scene at the crime spot when the error occurs?",
26+
"Did you seek wisdom from the grand oracle (Google)?",
27+
"What if you take a different path to solve this?",
28+
"Did you take a coffee break to reboot your brain?"};
29+
30+
static char* break_hints[] = {
31+
"Time to stretch! Remember, your body isn't made of code.",
32+
"Hydrate or diedrate! Grab a glass of water.",
33+
"Blink! Your eyes need a break too.",
34+
"How about a quick dance-off with your shadow?",
35+
"Ever tried chair yoga? Now's the time!",
36+
"Time for a quick peek out the window. The outside world still exists!",
37+
"Quick, think about kittens! Or puppies! Or baby turtles!",
38+
"Time for a laugh. Look up a joke or two!",
39+
"Sing a song. Bonus points for making up your own lyrics.",
40+
"Do a quick tidy-up. A clean space is a happy space!",
41+
"Time to play 'air' musical instrument for a minute.",
42+
"How about a quick doodle? Unleash your inner Picasso!",
43+
"Practice your superhero pose. Feel the power surge!",
44+
"Quick, tell yourself a joke. Don't worry, I won't judge.",
45+
"Time to practice your mime skills. Stuck in a box, anyone?",
46+
"Ever tried juggling? Now's your chance!",
47+
"Do a quick self high-five, you're doing great!"};
48+
49+
static char* random_string_of_list(char** hints, size_t num_hints) {
50+
int random_index = rand() % num_hints;
51+
return hints[random_index];
52+
}
53+
1154
void flipp_pomodoro_scene_timer_sync_view_state(void* ctx) {
1255
furi_assert(ctx);
1356

@@ -25,6 +68,12 @@ void flipp_pomodoro_scene_timer_on_next_stage(void* ctx) {
2568
view_dispatcher_send_custom_event(app->view_dispatcher, FlippPomodoroAppCustomEventStageSkip);
2669
};
2770

71+
void flipp_pomodoro_scene_timer_on_ask_hint(void* ctx) {
72+
FlippPomodoroApp* app = ctx;
73+
view_dispatcher_send_custom_event(
74+
app->view_dispatcher, FlippPomodoroAppCustomEventTimerAskHint);
75+
}
76+
2877
void flipp_pomodoro_scene_timer_on_enter(void* ctx) {
2978
furi_assert(ctx);
3079

@@ -37,21 +86,49 @@ void flipp_pomodoro_scene_timer_on_enter(void* ctx) {
3786

3887
view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewTimer);
3988
flipp_pomodoro_scene_timer_sync_view_state(app);
89+
90+
flipp_pomodoro_view_timer_set_callback_context(app->timer_view, app);
91+
92+
flipp_pomodoro_view_timer_set_on_ok_cb(
93+
app->timer_view, flipp_pomodoro_scene_timer_on_ask_hint);
94+
4095
flipp_pomodoro_view_timer_set_on_right_cb(
41-
app->timer_view, flipp_pomodoro_scene_timer_on_next_stage, app);
96+
app->timer_view, flipp_pomodoro_scene_timer_on_next_stage);
4297
};
4398

99+
char* flipp_pomodoro_scene_timer_get_contextual_hint(FlippPomodoroApp* app) {
100+
switch(flipp_pomodoro__get_stage(app->state)) {
101+
case FlippPomodoroStageFocus:
102+
return random_string_of_list(work_hints, sizeof(work_hints) / sizeof(work_hints[0]));
103+
case FlippPomodoroStageRest:
104+
case FlippPomodoroStageLongBreak:
105+
return random_string_of_list(break_hints, sizeof(break_hints) / sizeof(break_hints[0]));
106+
default:
107+
return "What's up?";
108+
}
109+
}
110+
44111
void flipp_pomodoro_scene_timer_handle_custom_event(
45112
FlippPomodoroApp* app,
46113
FlippPomodoroAppCustomEvent custom_event) {
47-
if(custom_event == FlippPomodoroAppCustomEventTimerTick &&
48-
flipp_pomodoro__is_stage_expired(app->state)) {
49-
view_dispatcher_send_custom_event(
50-
app->view_dispatcher, FlippPomodoroAppCustomEventStageComplete);
51-
}
52-
53-
if(custom_event == FlippPomodoroAppCustomEventStateUpdated) {
114+
switch(custom_event) {
115+
case FlippPomodoroAppCustomEventTimerTick:
116+
if(flipp_pomodoro__is_stage_expired(app->state)) {
117+
view_dispatcher_send_custom_event(
118+
app->view_dispatcher, FlippPomodoroAppCustomEventStageComplete);
119+
}
120+
break;
121+
case FlippPomodoroAppCustomEventStateUpdated:
54122
flipp_pomodoro_scene_timer_sync_view_state(app);
123+
break;
124+
case FlippPomodoroAppCustomEventTimerAskHint:
125+
flipp_pomodoro_view_timer_display_hint(
126+
flipp_pomodoro_view_timer_get_view(app->timer_view),
127+
flipp_pomodoro_scene_timer_get_contextual_hint(app));
128+
break;
129+
default:
130+
// optional: code to be executed if custom_event doesn't match any cases
131+
break;
55132
}
56133
};
57134

views/flipp_pomodoro_info_view.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static void
2929

3030
furi_string_printf(
3131
stats_string,
32-
"So Long,\nand Thanks for All the Focus...\nand for completing\n%i pomodoro(s)",
32+
"So Long,\nand Thanks for All the Focus...\nand for completing\n\e#%i\e# pomodoro(s)",
3333
model->pomodoros_completed);
3434
const char* stats_string_formatted = furi_string_get_cstr(stats_string);
3535

views/flipp_pomodoro_timer_view.c

Lines changed: 112 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ enum {
1818
struct FlippPomodoroTimerView {
1919
View* view;
2020
FlippPomodoroTimerViewInputCb right_cb;
21-
void* right_cb_ctx;
21+
FlippPomodoroTimerViewInputCb ok_cb;
22+
void* callback_context;
2223
};
2324

2425
typedef struct {
2526
IconAnimation* icon;
2627
FlippPomodoroState* state;
28+
size_t scroll_counter;
29+
char* current_hint;
2730
} FlippPomodoroTimerViewModel;
2831

2932
static const Icon* stage_background_image[] = {
@@ -89,6 +92,55 @@ static void
8992
flipp_pomodoro__current_stage_label(state));
9093
}
9194

95+
static void
96+
flipp_pomodoro_view_timer_draw_hint(Canvas* canvas, FlippPomodoroTimerViewModel* model) {
97+
size_t MAX_SCROLL_COUNTER = 300;
98+
uint8_t SCROLL_DELAY_FRAMES = 3;
99+
100+
if(model->scroll_counter >= MAX_SCROLL_COUNTER || model->current_hint == NULL) {
101+
return;
102+
}
103+
104+
uint8_t hint_width = 90;
105+
uint8_t hint_height = 18;
106+
107+
uint8_t hint_x = canvas_width(canvas) - hint_width - 6;
108+
uint8_t hint_y = 35;
109+
110+
FuriString* displayed_hint_string = furi_string_alloc();
111+
112+
furi_string_printf(displayed_hint_string, "%s", model->current_hint);
113+
114+
size_t perfect_duration = furi_string_size(displayed_hint_string) * 1.5;
115+
116+
if(model->scroll_counter > perfect_duration) {
117+
model->scroll_counter = MAX_SCROLL_COUNTER;
118+
furi_string_free(displayed_hint_string);
119+
return;
120+
}
121+
122+
size_t scroll_offset = (model->scroll_counter < SCROLL_DELAY_FRAMES) ?
123+
0 :
124+
model->scroll_counter - SCROLL_DELAY_FRAMES;
125+
126+
canvas_set_color(canvas, ColorWhite);
127+
canvas_draw_box(canvas, hint_x, hint_y, hint_width + 3, hint_height);
128+
canvas_set_color(canvas, ColorBlack);
129+
130+
elements_bubble(canvas, hint_x, hint_y, hint_width, hint_height);
131+
132+
elements_scrollable_text_line(
133+
canvas,
134+
hint_x + 6,
135+
hint_y + 12,
136+
hint_width - 4,
137+
displayed_hint_string,
138+
scroll_offset,
139+
true);
140+
furi_string_free(displayed_hint_string);
141+
model->scroll_counter++;
142+
}
143+
92144
static void flipp_pomodoro_view_timer_draw_callback(Canvas* canvas, void* _model) {
93145
if(!_model) {
94146
return;
@@ -105,42 +157,58 @@ static void flipp_pomodoro_view_timer_draw_callback(Canvas* canvas, void* _model
105157
canvas, flipp_pomodoro__stage_remaining_duration(model->state));
106158

107159
flipp_pomodoro_view_timer_draw_current_stage_label(canvas, model->state);
160+
108161
canvas_set_color(canvas, ColorBlack);
109162

110163
canvas_set_font(canvas, FontSecondary);
111164
elements_button_right(canvas, flipp_pomodoro__next_stage_label(model->state));
165+
flipp_pomodoro_view_timer_draw_hint(canvas, model);
112166
};
113167

114168
bool flipp_pomodoro_view_timer_input_callback(InputEvent* event, void* ctx) {
115169
furi_assert(ctx);
116170
furi_assert(event);
117171
FlippPomodoroTimerView* timer = ctx;
118172

119-
const bool should_trigger_right_event_cb = (event->type == InputTypePress) &&
120-
(event->key == InputKeyRight) &&
121-
(timer->right_cb != NULL);
173+
const bool is_press_event = event->type == InputTypePress;
122174

123-
if(should_trigger_right_event_cb) {
124-
furi_assert(timer->right_cb);
125-
furi_assert(timer->right_cb_ctx);
126-
timer->right_cb(timer->right_cb_ctx);
127-
return ViewInputConsumed;
128-
};
175+
if(!is_press_event) {
176+
return ViewInputNotConusmed;
177+
}
129178

130-
return ViewInputNotConusmed;
179+
switch(event->key) {
180+
case InputKeyRight:
181+
timer->right_cb(timer->callback_context);
182+
return ViewInputConsumed;
183+
case InputKeyOk:
184+
timer->ok_cb(timer->callback_context);
185+
return ViewInputConsumed;
186+
default:
187+
return ViewInputNotConusmed;
188+
}
131189
};
132190

133191
View* flipp_pomodoro_view_timer_get_view(FlippPomodoroTimerView* timer) {
134192
furi_assert(timer);
135193
return timer->view;
136194
};
137195

196+
void flipp_pomodoro_view_timer_display_hint(View* view, char* hint) {
197+
with_view_model(
198+
view,
199+
FlippPomodoroTimerViewModel * model,
200+
{
201+
model->scroll_counter = 0;
202+
model->current_hint = hint;
203+
},
204+
true);
205+
}
206+
138207
void flipp_pomodoro_view_timer_assign_animation(View* view) {
139208
with_view_model(
140209
view,
141210
FlippPomodoroTimerViewModel * model,
142211
{
143-
furi_assert(model->state);
144212
if(model->icon) {
145213
icon_animation_free(model->icon);
146214
}
@@ -160,28 +228,55 @@ FlippPomodoroTimerView* flipp_pomodoro_view_timer_alloc() {
160228
flipp_pomodoro_view_timer_get_view(timer),
161229
ViewModelTypeLockFree,
162230
sizeof(FlippPomodoroTimerViewModel));
231+
163232
view_set_context(flipp_pomodoro_view_timer_get_view(timer), timer);
164233
view_set_draw_callback(timer->view, flipp_pomodoro_view_timer_draw_callback);
165234
view_set_input_callback(timer->view, flipp_pomodoro_view_timer_input_callback);
166235

236+
with_view_model(
237+
flipp_pomodoro_view_timer_get_view(timer),
238+
FlippPomodoroTimerViewModel * model,
239+
{ model->scroll_counter = 0; },
240+
false);
241+
167242
return timer;
168243
};
169244

245+
void flipp_pomodoro_view_timer_set_callback_context(
246+
FlippPomodoroTimerView* timer,
247+
void* callback_ctx) {
248+
furi_assert(timer);
249+
furi_assert(callback_ctx);
250+
timer->callback_context = callback_ctx;
251+
}
252+
170253
void flipp_pomodoro_view_timer_set_on_right_cb(
171254
FlippPomodoroTimerView* timer,
172-
FlippPomodoroTimerViewInputCb right_cb,
173-
void* right_cb_ctx) {
255+
FlippPomodoroTimerViewInputCb right_cb) {
256+
furi_assert(timer);
174257
furi_assert(right_cb);
175-
furi_assert(right_cb_ctx);
176258
timer->right_cb = right_cb;
177-
timer->right_cb_ctx = right_cb_ctx;
178259
};
179260

261+
void flipp_pomodoro_view_timer_set_on_ok_cb(
262+
FlippPomodoroTimerView* timer,
263+
FlippPomodoroTimerViewInputCb ok_kb) {
264+
furi_assert(ok_kb);
265+
furi_assert(timer);
266+
timer->ok_cb = ok_kb;
267+
}
268+
180269
void flipp_pomodoro_view_timer_set_state(View* view, FlippPomodoroState* state) {
181270
furi_assert(view);
182271
furi_assert(state);
183272
with_view_model(
184-
view, FlippPomodoroTimerViewModel * model, { model->state = state; }, false);
273+
view,
274+
FlippPomodoroTimerViewModel * model,
275+
{
276+
model->state = state;
277+
model->current_hint = NULL;
278+
},
279+
false);
185280
flipp_pomodoro_view_timer_assign_animation(view);
186281
};
187282

views/flipp_pomodoro_timer_view.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,16 @@ void flipp_pomodoro_view_timer_free(FlippPomodoroTimerView* timer);
1515

1616
void flipp_pomodoro_view_timer_set_state(View* view, FlippPomodoroState* state);
1717

18+
void flipp_pomodoro_view_timer_set_callback_context(
19+
FlippPomodoroTimerView* timer,
20+
void* callback_ctx);
21+
1822
void flipp_pomodoro_view_timer_set_on_right_cb(
1923
FlippPomodoroTimerView* timer,
20-
FlippPomodoroTimerViewInputCb right_cb,
21-
void* right_cb_ctx);
24+
FlippPomodoroTimerViewInputCb right_cb);
25+
26+
void flipp_pomodoro_view_timer_set_on_ok_cb(
27+
FlippPomodoroTimerView* timer,
28+
FlippPomodoroTimerViewInputCb ok_cb);
29+
30+
void flipp_pomodoro_view_timer_display_hint(View* view, char* hint);

0 commit comments

Comments
 (0)