Skip to content

Commit

Permalink
Update apps
Browse files Browse the repository at this point in the history
  • Loading branch information
xMasterX committed Jul 17, 2023
1 parent 7bfa94d commit e4d9959
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 31 deletions.
1 change: 1 addition & 0 deletions flipp_pomodoro_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ typedef enum {
FlippPomodoroAppCustomEventStageSkip = 100,
FlippPomodoroAppCustomEventStageComplete, // By Expiration
FlippPomodoroAppCustomEventTimerTick,
FlippPomodoroAppCustomEventTimerAskHint,
FlippPomodoroAppCustomEventStateUpdated,
FlippPomodoroAppCustomEventResumeTimer,
} FlippPomodoroAppCustomEvent;
Expand Down
6 changes: 3 additions & 3 deletions modules/flipp_pomodoro.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ PomodoroStage stages_sequence[] = {
};

char* current_stage_label[] = {
[FlippPomodoroStageFocus] = "Continue focus for:",
[FlippPomodoroStageRest] = "Keep rest for:",
[FlippPomodoroStageLongBreak] = "Long Break for:",
[FlippPomodoroStageFocus] = "Focusing...",
[FlippPomodoroStageRest] = "Short Break...",
[FlippPomodoroStageLongBreak] = "Long Break...",
};

char* next_stage_label[] = {
Expand Down
93 changes: 85 additions & 8 deletions scenes/flipp_pomodoro_scene_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,49 @@

enum { SceneEventConusmed = true, SceneEventNotConusmed = false };

static char* work_hints[] = {
"Can you explain the problem as if I'm five?",
"Expected output vs. reality: what's the difference?",
"Ever thought of slicing the problem into bite-sized pieces?",
"What's the story when you walk through the code?",
"Any error messages gossiping about the issue?",
"What tricks have you tried to fix this?",
"Did you test the code, or just hoping for the best?",
"How's this code mingling with the rest of the app?",
"Any sneaky side effects causing mischief?",
"What are you assuming, and is it safe to do so?",
"Did you remember to invite all the edge cases to the party?",
"What happens in the isolation chamber (running code separately)?",
"Can you make the issue appear on command?",
"What's the scene at the crime spot when the error occurs?",
"Did you seek wisdom from the grand oracle (Google)?",
"What if you take a different path to solve this?",
"Did you take a coffee break to reboot your brain?"};

static char* break_hints[] = {
"Time to stretch! Remember, your body isn't made of code.",
"Hydrate or diedrate! Grab a glass of water.",
"Blink! Your eyes need a break too.",
"How about a quick dance-off with your shadow?",
"Ever tried chair yoga? Now's the time!",
"Time for a quick peek out the window. The outside world still exists!",
"Quick, think about kittens! Or puppies! Or baby turtles!",
"Time for a laugh. Look up a joke or two!",
"Sing a song. Bonus points for making up your own lyrics.",
"Do a quick tidy-up. A clean space is a happy space!",
"Time to play 'air' musical instrument for a minute.",
"How about a quick doodle? Unleash your inner Picasso!",
"Practice your superhero pose. Feel the power surge!",
"Quick, tell yourself a joke. Don't worry, I won't judge.",
"Time to practice your mime skills. Stuck in a box, anyone?",
"Ever tried juggling? Now's your chance!",
"Do a quick self high-five, you're doing great!"};

static char* random_string_of_list(char** hints, size_t num_hints) {
int random_index = rand() % num_hints;
return hints[random_index];
}

void flipp_pomodoro_scene_timer_sync_view_state(void* ctx) {
furi_assert(ctx);

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

void flipp_pomodoro_scene_timer_on_ask_hint(void* ctx) {
FlippPomodoroApp* app = ctx;
view_dispatcher_send_custom_event(
app->view_dispatcher, FlippPomodoroAppCustomEventTimerAskHint);
}

void flipp_pomodoro_scene_timer_on_enter(void* ctx) {
furi_assert(ctx);

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

view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewTimer);
flipp_pomodoro_scene_timer_sync_view_state(app);

flipp_pomodoro_view_timer_set_callback_context(app->timer_view, app);

flipp_pomodoro_view_timer_set_on_ok_cb(
app->timer_view, flipp_pomodoro_scene_timer_on_ask_hint);

flipp_pomodoro_view_timer_set_on_right_cb(
app->timer_view, flipp_pomodoro_scene_timer_on_next_stage, app);
app->timer_view, flipp_pomodoro_scene_timer_on_next_stage);
};

char* flipp_pomodoro_scene_timer_get_contextual_hint(FlippPomodoroApp* app) {
switch(flipp_pomodoro__get_stage(app->state)) {
case FlippPomodoroStageFocus:
return random_string_of_list(work_hints, sizeof(work_hints) / sizeof(work_hints[0]));
case FlippPomodoroStageRest:
case FlippPomodoroStageLongBreak:
return random_string_of_list(break_hints, sizeof(break_hints) / sizeof(break_hints[0]));
default:
return "What's up?";
}
}

void flipp_pomodoro_scene_timer_handle_custom_event(
FlippPomodoroApp* app,
FlippPomodoroAppCustomEvent custom_event) {
if(custom_event == FlippPomodoroAppCustomEventTimerTick &&
flipp_pomodoro__is_stage_expired(app->state)) {
view_dispatcher_send_custom_event(
app->view_dispatcher, FlippPomodoroAppCustomEventStageComplete);
}

if(custom_event == FlippPomodoroAppCustomEventStateUpdated) {
switch(custom_event) {
case FlippPomodoroAppCustomEventTimerTick:
if(flipp_pomodoro__is_stage_expired(app->state)) {
view_dispatcher_send_custom_event(
app->view_dispatcher, FlippPomodoroAppCustomEventStageComplete);
}
break;
case FlippPomodoroAppCustomEventStateUpdated:
flipp_pomodoro_scene_timer_sync_view_state(app);
break;
case FlippPomodoroAppCustomEventTimerAskHint:
flipp_pomodoro_view_timer_display_hint(
flipp_pomodoro_view_timer_get_view(app->timer_view),
flipp_pomodoro_scene_timer_get_contextual_hint(app));
break;
default:
// optional: code to be executed if custom_event doesn't match any cases
break;
}
};

Expand Down
2 changes: 1 addition & 1 deletion views/flipp_pomodoro_info_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ static void

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

Expand Down
129 changes: 112 additions & 17 deletions views/flipp_pomodoro_timer_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ enum {
struct FlippPomodoroTimerView {
View* view;
FlippPomodoroTimerViewInputCb right_cb;
void* right_cb_ctx;
FlippPomodoroTimerViewInputCb ok_cb;
void* callback_context;
};

typedef struct {
IconAnimation* icon;
FlippPomodoroState* state;
size_t scroll_counter;
char* current_hint;
} FlippPomodoroTimerViewModel;

static const Icon* stage_background_image[] = {
Expand Down Expand Up @@ -89,6 +92,55 @@ static void
flipp_pomodoro__current_stage_label(state));
}

static void
flipp_pomodoro_view_timer_draw_hint(Canvas* canvas, FlippPomodoroTimerViewModel* model) {
size_t MAX_SCROLL_COUNTER = 300;
uint8_t SCROLL_DELAY_FRAMES = 3;

if(model->scroll_counter >= MAX_SCROLL_COUNTER || model->current_hint == NULL) {
return;
}

uint8_t hint_width = 90;
uint8_t hint_height = 18;

uint8_t hint_x = canvas_width(canvas) - hint_width - 6;
uint8_t hint_y = 35;

FuriString* displayed_hint_string = furi_string_alloc();

furi_string_printf(displayed_hint_string, "%s", model->current_hint);

size_t perfect_duration = furi_string_size(displayed_hint_string) * 1.5;

if(model->scroll_counter > perfect_duration) {
model->scroll_counter = MAX_SCROLL_COUNTER;
furi_string_free(displayed_hint_string);
return;
}

size_t scroll_offset = (model->scroll_counter < SCROLL_DELAY_FRAMES) ?
0 :
model->scroll_counter - SCROLL_DELAY_FRAMES;

canvas_set_color(canvas, ColorWhite);
canvas_draw_box(canvas, hint_x, hint_y, hint_width + 3, hint_height);
canvas_set_color(canvas, ColorBlack);

elements_bubble(canvas, hint_x, hint_y, hint_width, hint_height);

elements_scrollable_text_line(
canvas,
hint_x + 6,
hint_y + 12,
hint_width - 4,
displayed_hint_string,
scroll_offset,
true);
furi_string_free(displayed_hint_string);
model->scroll_counter++;
}

static void flipp_pomodoro_view_timer_draw_callback(Canvas* canvas, void* _model) {
if(!_model) {
return;
Expand All @@ -105,42 +157,58 @@ 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));
flipp_pomodoro_view_timer_draw_hint(canvas, model);
};

bool flipp_pomodoro_view_timer_input_callback(InputEvent* event, void* ctx) {
furi_assert(ctx);
furi_assert(event);
FlippPomodoroTimerView* timer = ctx;

const bool should_trigger_right_event_cb = (event->type == InputTypePress) &&
(event->key == InputKeyRight) &&
(timer->right_cb != NULL);
const bool is_press_event = event->type == InputTypePress;

if(should_trigger_right_event_cb) {
furi_assert(timer->right_cb);
furi_assert(timer->right_cb_ctx);
timer->right_cb(timer->right_cb_ctx);
return ViewInputConsumed;
};
if(!is_press_event) {
return ViewInputNotConusmed;
}

return ViewInputNotConusmed;
switch(event->key) {
case InputKeyRight:
timer->right_cb(timer->callback_context);
return ViewInputConsumed;
case InputKeyOk:
timer->ok_cb(timer->callback_context);
return ViewInputConsumed;
default:
return ViewInputNotConusmed;
}
};

View* flipp_pomodoro_view_timer_get_view(FlippPomodoroTimerView* timer) {
furi_assert(timer);
return timer->view;
};

void flipp_pomodoro_view_timer_display_hint(View* view, char* hint) {
with_view_model(
view,
FlippPomodoroTimerViewModel * model,
{
model->scroll_counter = 0;
model->current_hint = hint;
},
true);
}

void flipp_pomodoro_view_timer_assign_animation(View* view) {
with_view_model(
view,
FlippPomodoroTimerViewModel * model,
{
furi_assert(model->state);
if(model->icon) {
icon_animation_free(model->icon);
}
Expand All @@ -160,28 +228,55 @@ FlippPomodoroTimerView* flipp_pomodoro_view_timer_alloc() {
flipp_pomodoro_view_timer_get_view(timer),
ViewModelTypeLockFree,
sizeof(FlippPomodoroTimerViewModel));

view_set_context(flipp_pomodoro_view_timer_get_view(timer), timer);
view_set_draw_callback(timer->view, flipp_pomodoro_view_timer_draw_callback);
view_set_input_callback(timer->view, flipp_pomodoro_view_timer_input_callback);

with_view_model(
flipp_pomodoro_view_timer_get_view(timer),
FlippPomodoroTimerViewModel * model,
{ model->scroll_counter = 0; },
false);

return timer;
};

void flipp_pomodoro_view_timer_set_callback_context(
FlippPomodoroTimerView* timer,
void* callback_ctx) {
furi_assert(timer);
furi_assert(callback_ctx);
timer->callback_context = callback_ctx;
}

void flipp_pomodoro_view_timer_set_on_right_cb(
FlippPomodoroTimerView* timer,
FlippPomodoroTimerViewInputCb right_cb,
void* right_cb_ctx) {
FlippPomodoroTimerViewInputCb right_cb) {
furi_assert(timer);
furi_assert(right_cb);
furi_assert(right_cb_ctx);
timer->right_cb = right_cb;
timer->right_cb_ctx = right_cb_ctx;
};

void flipp_pomodoro_view_timer_set_on_ok_cb(
FlippPomodoroTimerView* timer,
FlippPomodoroTimerViewInputCb ok_kb) {
furi_assert(ok_kb);
furi_assert(timer);
timer->ok_cb = ok_kb;
}

void flipp_pomodoro_view_timer_set_state(View* view, FlippPomodoroState* state) {
furi_assert(view);
furi_assert(state);
with_view_model(
view, FlippPomodoroTimerViewModel * model, { model->state = state; }, false);
view,
FlippPomodoroTimerViewModel * model,
{
model->state = state;
model->current_hint = NULL;
},
false);
flipp_pomodoro_view_timer_assign_animation(view);
};

Expand Down
13 changes: 11 additions & 2 deletions views/flipp_pomodoro_timer_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@ void flipp_pomodoro_view_timer_free(FlippPomodoroTimerView* timer);

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

void flipp_pomodoro_view_timer_set_callback_context(
FlippPomodoroTimerView* timer,
void* callback_ctx);

void flipp_pomodoro_view_timer_set_on_right_cb(
FlippPomodoroTimerView* timer,
FlippPomodoroTimerViewInputCb right_cb,
void* right_cb_ctx);
FlippPomodoroTimerViewInputCb right_cb);

void flipp_pomodoro_view_timer_set_on_ok_cb(
FlippPomodoroTimerView* timer,
FlippPomodoroTimerViewInputCb ok_cb);

void flipp_pomodoro_view_timer_display_hint(View* view, char* hint);

0 comments on commit e4d9959

Please sign in to comment.