Skip to content

Commit

Permalink
API 31 / unzip sources
Browse files Browse the repository at this point in the history
  • Loading branch information
xMasterX committed Jun 29, 2023
0 parents commit 0a1b42c
Show file tree
Hide file tree
Showing 26 changed files with 776 additions and 0 deletions.
11 changes: 11 additions & 0 deletions application.fam
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
App(
appid="flipp_pomodoro",
name="Flipp Pomodoro",
apptype=FlipperAppType.EXTERNAL,
entry_point="flipp_pomodoro_app",
requires=["gui", "notification", "dolphin"],
stack_size=1 * 1024,
fap_category="Misc_Extra",
fap_icon_assets="images",
fap_icon="flipp_pomodoro_10.png",
)
Binary file added flipp_pomodoro_10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
100 changes: 100 additions & 0 deletions flipp_pomodoro_app.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "flipp_pomodoro_app_i.h"

enum {
CustomEventConsumed = true,
CustomEventNotConsumed = false,
};

static bool flipp_pomodoro_app_back_event_callback(void* ctx) {
furi_assert(ctx);
FlippPomodoroApp* app = ctx;
return scene_manager_handle_back_event(app->scene_manager);
};

static void flipp_pomodoro_app_tick_event_callback(void* ctx) {
furi_assert(ctx);
FlippPomodoroApp* app = ctx;

scene_manager_handle_custom_event(app->scene_manager, FlippPomodoroAppCustomEventTimerTick);
};

static bool flipp_pomodoro_app_custom_event_callback(void* ctx, uint32_t event) {
furi_assert(ctx);
FlippPomodoroApp* app = ctx;

switch(event) {
case FlippPomodoroAppCustomEventStageSkip:
flipp_pomodoro__toggle_stage(app->state);
view_dispatcher_send_custom_event(
app->view_dispatcher, FlippPomodoroAppCustomEventStateUpdated);
return CustomEventConsumed;
case FlippPomodoroAppCustomEventStageComplete:
if(flipp_pomodoro__get_stage(app->state) == FlippPomodoroStageFocus) {
// REGISTER a deed on work stage complete to get an acheivement
dolphin_deed(DolphinDeedPluginGameWin);
};

flipp_pomodoro__toggle_stage(app->state);
notification_message(
app->notification_app,
stage_start_notification_sequence_map[flipp_pomodoro__get_stage(app->state)]);
view_dispatcher_send_custom_event(
app->view_dispatcher, FlippPomodoroAppCustomEventStateUpdated);
return CustomEventConsumed;
default:
break;
}
return scene_manager_handle_custom_event(app->scene_manager, event);
};

FlippPomodoroApp* flipp_pomodoro_app_alloc() {
FlippPomodoroApp* app = malloc(sizeof(FlippPomodoroApp));
app->state = flipp_pomodoro__new();

app->scene_manager = scene_manager_alloc(&flipp_pomodoro_scene_handlers, app);
app->gui = furi_record_open(RECORD_GUI);
app->notification_app = furi_record_open(RECORD_NOTIFICATION);

app->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_set_custom_event_callback(
app->view_dispatcher, flipp_pomodoro_app_custom_event_callback);
view_dispatcher_set_tick_event_callback(
app->view_dispatcher, flipp_pomodoro_app_tick_event_callback, 1000);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
view_dispatcher_set_navigation_event_callback(
app->view_dispatcher, flipp_pomodoro_app_back_event_callback);

app->timer_view = flipp_pomodoro_view_timer_alloc();

view_dispatcher_add_view(
app->view_dispatcher,
FlippPomodoroAppViewTimer,
flipp_pomodoro_view_timer_get_view(app->timer_view));

scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneTimer);

return app;
};

void flipp_pomodoro_app_free(FlippPomodoroApp* app) {
view_dispatcher_remove_view(app->view_dispatcher, FlippPomodoroAppViewTimer);
view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager);
flipp_pomodoro_view_timer_free(app->timer_view);
free(app);
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_NOTIFICATION);
};

int32_t flipp_pomodoro_app(void* p) {
UNUSED(p);
FlippPomodoroApp* app = flipp_pomodoro_app_alloc();

view_dispatcher_run(app->view_dispatcher);

flipp_pomodoro_app_free(app);

return 0;
};
32 changes: 32 additions & 0 deletions flipp_pomodoro_app.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>
#include <gui/view_dispatcher.h>
#include <gui/scene_manager.h>
#include <notification/notification_messages.h>
#include "views/flipp_pomodoro_timer_view.h"

#include "modules/flipp_pomodoro.h"

typedef enum {
// Reserve first 100 events for button types and indexes, starting from 0
FlippPomodoroAppCustomEventStageSkip = 100,
FlippPomodoroAppCustomEventStageComplete, // By Expiration
FlippPomodoroAppCustomEventTimerTick,
FlippPomodoroAppCustomEventStateUpdated,
} FlippPomodoroAppCustomEvent;

typedef struct {
SceneManager* scene_manager;
ViewDispatcher* view_dispatcher;
Gui* gui;
NotificationApp* notification_app;
FlippPomodoroTimerView* timer_view;
FlippPomodoroState* state;
} FlippPomodoroApp;

typedef enum {
FlippPomodoroAppViewTimer,
} FlippPomodoroAppView;
31 changes: 31 additions & 0 deletions flipp_pomodoro_app_i.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#define FURI_DEBUG 1

/**
* Index of dependencies for the main app
*/

// Platform Imports

#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>
#include <gui/view_stack.h>
#include <gui/view_dispatcher.h>
#include <gui/scene_manager.h>
#include <gui/elements.h>
#include <dolphin/dolphin.h>
#include <input/input.h>

// App resource imports

#include "helpers/time.h"
#include "helpers/notifications.h"
#include "modules/flipp_pomodoro.h"
#include "flipp_pomodoro_app.h"
#include "scenes/flipp_pomodoro_scene.h"
#include "views/flipp_pomodoro_timer_view.h"

// Auto-compiled icons
#include "flipp_pomodoro_icons.h"
5 changes: 5 additions & 0 deletions helpers/debug.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <furi.h>

#define TAG "FlippPomodoro"
49 changes: 49 additions & 0 deletions helpers/notifications.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <notification/notification_messages.h>

const NotificationSequence work_start_notification = {
&message_display_backlight_on,

&message_vibro_on,

&message_note_b5,
&message_delay_250,

&message_note_d5,
&message_delay_250,

&message_sound_off,
&message_vibro_off,

&message_green_255,
&message_delay_1000,
&message_green_0,
&message_delay_250,
&message_green_255,
&message_delay_1000,

NULL,
};

const NotificationSequence rest_start_notification = {
&message_display_backlight_on,

&message_vibro_on,

&message_note_d5,
&message_delay_250,

&message_note_b5,
&message_delay_250,

&message_sound_off,
&message_vibro_off,

&message_red_255,
&message_delay_1000,
&message_red_0,
&message_delay_250,
&message_red_255,
&message_delay_1000,

NULL,
};
14 changes: 14 additions & 0 deletions helpers/notifications.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include "../modules/flipp_pomodoro.h"
#include <notification/notification_messages.h>

extern const NotificationSequence work_start_notification;
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[] = {
[FlippPomodoroStageFocus] = &work_start_notification,
[FlippPomodoroStageRest] = &rest_start_notification,
[FlippPomodoroStageLongBreak] = &rest_start_notification,
};
20 changes: 20 additions & 0 deletions helpers/time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <furi.h>
#include <furi_hal.h>
#include "time.h"

const int TIME_SECONDS_IN_MINUTE = 60;
const int TIME_MINUTES_IN_HOUR = 60;

uint32_t time_now() {
return furi_hal_rtc_get_timestamp();
};

TimeDifference time_difference_seconds(uint32_t begin, uint32_t end) {
const uint32_t duration_seconds = end - begin;

uint32_t minutes = (duration_seconds / TIME_MINUTES_IN_HOUR) % TIME_MINUTES_IN_HOUR;
uint32_t seconds = duration_seconds % TIME_SECONDS_IN_MINUTE;

return (
TimeDifference){.total_seconds = duration_seconds, .minutes = minutes, .seconds = seconds};
};
24 changes: 24 additions & 0 deletions helpers/time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <furi.h>
#include <furi_hal.h>

extern const int TIME_SECONDS_IN_MINUTE;
extern const int TIME_MINUTES_IN_HOUR;

/// @brief Container for a time period
typedef struct {
uint8_t seconds;
uint8_t minutes;
uint32_t total_seconds;
} TimeDifference;

/// @brief Time by the moment of calling
/// @return A timestamp(seconds percision)
uint32_t time_now();

/// @brief Calculates difference between two provided timestamps
/// @param begin - start timestamp of the period
/// @param end - end timestamp of the period to measure
/// @return TimeDifference struct
TimeDifference time_difference_seconds(uint32_t begin, uint32_t end);
Binary file added images/flipp_pomodoro_focus_64/frame_00.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/flipp_pomodoro_focus_64/frame_01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions images/flipp_pomodoro_focus_64/frame_rate
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
Binary file added images/flipp_pomodoro_rest_64/frame_00.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/flipp_pomodoro_rest_64/frame_01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions images/flipp_pomodoro_rest_64/frame_rate
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
89 changes: 89 additions & 0 deletions modules/flipp_pomodoro.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include <furi.h>
#include <furi_hal.h>
#include "../helpers/time.h"
#include "flipp_pomodoro.h"

PomodoroStage stages_sequence[] = {
FlippPomodoroStageFocus,
FlippPomodoroStageRest,

FlippPomodoroStageFocus,
FlippPomodoroStageRest,

FlippPomodoroStageFocus,
FlippPomodoroStageRest,

FlippPomodoroStageFocus,
FlippPomodoroStageLongBreak,
};

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

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->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 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__stage_by_index(state->current_stage_index + 1)];
};

uint32_t flipp_pomodoro__current_stage_total_duration(FlippPomodoroState* state) {
const int32_t stage_duration_seconds_map[] = {
[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)];
};

uint32_t flipp_pomodoro__stage_expires_timestamp(FlippPomodoroState* state) {
return state->started_at_timestamp + flipp_pomodoro__current_stage_total_duration(state);
};

TimeDifference flipp_pomodoro__stage_remaining_duration(FlippPomodoroState* state) {
const uint32_t stage_ends_at = flipp_pomodoro__stage_expires_timestamp(state);
return time_difference_seconds(time_now(), stage_ends_at);
};

bool flipp_pomodoro__is_stage_expired(FlippPomodoroState* state) {
const uint32_t expired_by = flipp_pomodoro__stage_expires_timestamp(state);
const uint8_t seamless_change_span_seconds = 1;
return (time_now() - seamless_change_span_seconds) >= expired_by;
};

FlippPomodoroState* flipp_pomodoro__new() {
FlippPomodoroState* state = malloc(sizeof(FlippPomodoroState));
const uint32_t now = time_now();
state->started_at_timestamp = now;
state->current_stage_index = 0;
return state;
};
Loading

0 comments on commit 0a1b42c

Please sign in to comment.