Skip to content

Commit

Permalink
[FL-3897] Happy mode (flipperdevices#3863)
Browse files Browse the repository at this point in the history
* feat: happy mode
* feat: remove sad dolphin when powering off in happy mode
* style: address review comments
* Dolphin: add missing furi_checks
* Komi: add missing region initialization on startup

Co-authored-by: あく <alleteam@gmail.com>
  • Loading branch information
2 people authored and ofabel committed Sep 26, 2024
1 parent bc728cf commit 999652c
Show file tree
Hide file tree
Showing 23 changed files with 231 additions and 72 deletions.
33 changes: 32 additions & 1 deletion applications/services/dolphin/dolphin.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ void dolphin_deed(DolphinDeed deed) {
furi_record_close(RECORD_DOLPHIN);
}

void dolphin_get_settings(Dolphin* dolphin, DolphinSettings* settings) {
furi_check(dolphin);
furi_check(settings);

DolphinEvent event;
event.type = DolphinEventTypeSettingsGet;
event.settings = settings;
dolphin_event_send_wait(dolphin, &event);
}

void dolphin_set_settings(Dolphin* dolphin, DolphinSettings* settings) {
furi_check(dolphin);
furi_check(settings);

DolphinEvent event;
event.type = DolphinEventTypeSettingsSet;
event.settings = settings;
dolphin_event_send_wait(dolphin, &event);
}

DolphinStats dolphin_stats(Dolphin* dolphin) {
furi_check(dolphin);

Expand Down Expand Up @@ -211,7 +231,9 @@ static bool dolphin_process_event(FuriEventLoopObject* object, void* context) {

} else if(event.type == DolphinEventTypeStats) {
event.stats->icounter = dolphin->state->data.icounter;
event.stats->butthurt = dolphin->state->data.butthurt;
event.stats->butthurt = (dolphin->state->data.flags & DolphinFlagHappyMode) ?
0 :
dolphin->state->data.butthurt;
event.stats->timestamp = dolphin->state->data.timestamp;
event.stats->level = dolphin_get_level(dolphin->state->data.icounter);
event.stats->level_up_is_pending =
Expand All @@ -228,6 +250,15 @@ static bool dolphin_process_event(FuriEventLoopObject* object, void* context) {
dolphin_state_load(dolphin->state);
furi_event_loop_timer_start(dolphin->butthurt_timer, BUTTHURT_INCREASE_PERIOD_TICKS);

} else if(event.type == DolphinEventTypeSettingsGet) {
event.settings->happy_mode = dolphin->state->data.flags & DolphinFlagHappyMode;

} else if(event.type == DolphinEventTypeSettingsSet) {
dolphin->state->data.flags &= ~DolphinFlagHappyMode;
if(event.settings->happy_mode) dolphin->state->data.flags |= DolphinFlagHappyMode;
dolphin->state->dirty = true;
dolphin_state_save(dolphin->state);

} else {
furi_crash();
}
Expand Down
8 changes: 8 additions & 0 deletions applications/services/dolphin/dolphin.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ typedef struct {
bool level_up_is_pending;
} DolphinStats;

typedef struct {
bool happy_mode;
} DolphinSettings;

typedef enum {
DolphinPubsubEventUpdate,
} DolphinPubsubEvent;
Expand All @@ -31,6 +35,10 @@ typedef enum {
*/
void dolphin_deed(DolphinDeed deed);

void dolphin_get_settings(Dolphin* dolphin, DolphinSettings* settings);

void dolphin_set_settings(Dolphin* dolphin, DolphinSettings* settings);

/** Retrieve dolphin stats
* Thread safe, blocking
*/
Expand Down
3 changes: 3 additions & 0 deletions applications/services/dolphin/dolphin_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ typedef enum {
DolphinEventTypeFlush,
DolphinEventTypeLevel,
DolphinEventTypeReloadState,
DolphinEventTypeSettingsGet,
DolphinEventTypeSettingsSet,
} DolphinEventType;

typedef struct {
Expand All @@ -21,6 +23,7 @@ typedef struct {
union {
DolphinDeed deed;
DolphinStats* stats;
DolphinSettings* settings;
};
} DolphinEvent;

Expand Down
4 changes: 4 additions & 0 deletions applications/services/dolphin/helpers/dolphin_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

#include "dolphin_deed.h"

typedef enum {
DolphinFlagHappyMode = 1,
} DolphinFlags;

typedef struct DolphinState DolphinState;
typedef struct {
uint8_t icounter_daily_limit[DolphinAppMAX];
Expand Down
6 changes: 6 additions & 0 deletions applications/settings/desktop_settings/desktop_settings_app.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <furi.h>
#include <gui/modules/popup.h>
#include <gui/modules/dialog_ex.h>
#include <gui/scene_manager.h>

#include <desktop/desktop.h>
Expand Down Expand Up @@ -42,6 +43,7 @@ DesktopSettingsApp* desktop_settings_app_alloc(void) {
app->pin_input_view = desktop_view_pin_input_alloc();
app->pin_setup_howto_view = desktop_settings_view_pin_setup_howto_alloc();
app->pin_setup_howto2_view = desktop_settings_view_pin_setup_howto2_alloc();
app->dialog_ex = dialog_ex_alloc();

view_dispatcher_add_view(
app->view_dispatcher, DesktopSettingsAppViewMenu, submenu_get_view(app->submenu));
Expand All @@ -63,6 +65,8 @@ DesktopSettingsApp* desktop_settings_app_alloc(void) {
app->view_dispatcher,
DesktopSettingsAppViewIdPinSetupHowto2,
desktop_settings_view_pin_setup_howto2_get_view(app->pin_setup_howto2_view));
view_dispatcher_add_view(
app->view_dispatcher, DesktopSettingsAppViewDialogEx, dialog_ex_get_view(app->dialog_ex));
return app;
}

Expand All @@ -75,12 +79,14 @@ void desktop_settings_app_free(DesktopSettingsApp* app) {
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewDialogEx);
variable_item_list_free(app->variable_item_list);
submenu_free(app->submenu);
popup_free(app->popup);
desktop_view_pin_input_free(app->pin_input_view);
desktop_settings_view_pin_setup_howto_free(app->pin_setup_howto_view);
desktop_settings_view_pin_setup_howto2_free(app->pin_setup_howto2_view);
dialog_ex_free(app->dialog_ex);
// View dispatcher
view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager);
Expand Down
3 changes: 3 additions & 0 deletions applications/settings/desktop_settings/desktop_settings_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <gui/scene_manager.h>
#include <gui/modules/submenu.h>
#include <gui/modules/variable_item_list.h>
#include <gui/modules/dialog_ex.h>
#include <dialogs/dialogs.h>
#include <assets_icons.h>

Expand All @@ -21,6 +22,7 @@ typedef enum {
DesktopSettingsAppViewIdPinInput,
DesktopSettingsAppViewIdPinSetupHowto,
DesktopSettingsAppViewIdPinSetupHowto2,
DesktopSettingsAppViewDialogEx,
} DesktopSettingsAppView;

typedef struct {
Expand All @@ -36,6 +38,7 @@ typedef struct {
DesktopViewPinInput* pin_input_view;
DesktopSettingsViewPinSetupHowto* pin_setup_howto_view;
DesktopSettingsViewPinSetupHowto2* pin_setup_howto2_view;
DialogEx* dialog_ex;

DesktopPinCode pincode_buffer;
bool pincode_buffer_filled;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
// reserve 100 for button presses, submenu selections, etc.
DesktopSettingsCustomEventExit = 100,
DesktopSettingsCustomEventDone,

DesktopSettingsCustomEvent1stPinEntered,
DesktopSettingsCustomEventPinsEqual,
DesktopSettingsCustomEventPinsDifferent,

DesktopSettingsCustomEventSetPin,
DesktopSettingsCustomEventChangePin,
DesktopSettingsCustomEventDisablePin,

DesktopSettingsCustomEventSetDefault,
DesktopSettingsCustomEventSetDummy,
} DesktopSettingsCustomEvent;

#ifdef __cplusplus
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ ADD_SCENE(desktop_settings, pin_setup_done, PinSetupDone)

ADD_SCENE(desktop_settings, quick_apps_menu, QuickAppsMenu)
ADD_SCENE(desktop_settings, quick_apps_direction_menu, QuickAppsDirectionMenu)

ADD_SCENE(desktop_settings, happy_mode, HappyMode)
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <furi.h>
#include <gui/scene_manager.h>
#include <gui/view_dispatcher.h>
#include <gui/modules/dialog_ex.h>
#include <dolphin/dolphin.h>

#include "desktop_settings_scene.h"
#include "../desktop_settings_app.h"
#include "../desktop_settings_custom_event.h"

static void desktop_settings_scene_happy_mode_done_callback(DialogExResult result, void* context) {
DesktopSettingsApp* app = context;
DolphinSettings settings;
Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN);
dolphin_get_settings(dolphin, &settings);
settings.happy_mode = (result == DialogExResultRight);
dolphin_set_settings(dolphin, &settings);
furi_record_close(RECORD_DOLPHIN);
view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
}

void desktop_settings_scene_happy_mode_on_enter(void* context) {
DesktopSettingsApp* app = context;
Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN);
DolphinSettings settings;
dolphin_get_settings(dolphin, &settings);
furi_record_close(RECORD_DOLPHIN);

dialog_ex_set_header(app->dialog_ex, "Happy Mode", 64, 0, AlignCenter, AlignTop);
dialog_ex_set_text(
app->dialog_ex,
"I will never get angry at you\nfor not spending time with me\nas long as this mode is enabled",
64,
30,
AlignCenter,
AlignCenter);
dialog_ex_set_left_button_text(app->dialog_ex, settings.happy_mode ? "Disable" : "Go back");
dialog_ex_set_right_button_text(
app->dialog_ex, settings.happy_mode ? "Keep enabled" : "Enable");
dialog_ex_set_result_callback(app->dialog_ex, desktop_settings_scene_happy_mode_done_callback);
dialog_ex_set_context(app->dialog_ex, app);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewDialogEx);
}

bool desktop_settings_scene_happy_mode_on_event(void* context, SceneManagerEvent event) {
DesktopSettingsApp* app = context;
bool consumed = false;

if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DesktopSettingsCustomEventExit:
scene_manager_previous_scene(app->scene_manager);
consumed = true;
break;
default:
furi_crash();
}
}
return consumed;
}

void desktop_settings_scene_happy_mode_on_exit(void* context) {
UNUSED(context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
#include <gui/scene_manager.h>
#include <desktop/helpers/pin_code.h>
#include "../desktop_settings_app.h"
#include "../desktop_settings_custom_event.h"
#include <desktop/desktop_settings.h>
#include <desktop/views/desktop_view_pin_input.h>
#include "desktop_settings_scene.h"
#include "desktop_settings_scene_i.h"

#define SCENE_EVENT_EXIT (0U)
#define SCENE_EVENT_PINS_EQUAL (1U)
#define SCENE_EVENT_PINS_DIFFERENT (2U)

static void pin_auth_done_callback(const DesktopPinCode* pin_code, void* context) {
furi_assert(pin_code);
furi_assert(context);
Expand All @@ -20,15 +17,17 @@ static void pin_auth_done_callback(const DesktopPinCode* pin_code, void* context
app->pincode_buffer = *pin_code;

if(desktop_pin_code_check(pin_code)) {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_EQUAL);
view_dispatcher_send_custom_event(
app->view_dispatcher, DesktopSettingsCustomEventPinsEqual);
} else {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_DIFFERENT);
view_dispatcher_send_custom_event(
app->view_dispatcher, DesktopSettingsCustomEventPinsDifferent);
}
}

static void pin_auth_back_callback(void* context) {
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
}

void desktop_settings_scene_pin_auth_on_enter(void* context) {
Expand All @@ -54,13 +53,13 @@ bool desktop_settings_scene_pin_auth_on_event(void* context, SceneManagerEvent e

if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_EVENT_PINS_DIFFERENT:
case DesktopSettingsCustomEventPinsDifferent:
scene_manager_set_scene_state(
app->scene_manager, DesktopSettingsAppScenePinError, SCENE_STATE_PIN_ERROR_WRONG);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinError);
consumed = true;
break;
case SCENE_EVENT_PINS_EQUAL: {
case DesktopSettingsCustomEventPinsEqual: {
uint32_t state =
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppScenePinAuth);
if(state == SCENE_STATE_PIN_AUTH_CHANGE_PIN) {
Expand All @@ -73,7 +72,7 @@ bool desktop_settings_scene_pin_auth_on_event(void* context, SceneManagerEvent e
consumed = true;
break;
}
case SCENE_EVENT_EXIT:
case DesktopSettingsCustomEventExit:
scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu);
consumed = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
#include <gui/modules/popup.h>

#include "../desktop_settings_app.h"
#include "../desktop_settings_custom_event.h"
#include <desktop/desktop_settings.h>
#include "desktop_settings_scene.h"

#define SCENE_EVENT_EXIT (0U)

static void pin_disable_back_callback(void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
}

void desktop_settings_scene_pin_disable_on_enter(void* context) {
Expand All @@ -35,7 +34,7 @@ bool desktop_settings_scene_pin_disable_on_event(void* context, SceneManagerEven

if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_EVENT_EXIT:
case DesktopSettingsCustomEventExit:
scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu);
consumed = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,19 @@
#include "desktop_settings_scene_i.h"
#include <desktop/helpers/pin_code.h>
#include "../desktop_settings_app.h"

#define SCENE_EVENT_EXIT (0U)
#include "../desktop_settings_custom_event.h"

static void pin_error_back_callback(void* context) {
furi_assert(context);
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
}

static void pin_error_done_callback(const DesktopPinCode* pin_code, void* context) {
UNUSED(pin_code);
furi_assert(context);
DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
}

void desktop_settings_scene_pin_error_on_enter(void* context) {
Expand Down Expand Up @@ -55,7 +54,7 @@ bool desktop_settings_scene_pin_error_on_event(void* context, SceneManagerEvent

if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SCENE_EVENT_EXIT:
case DesktopSettingsCustomEventExit:
scene_manager_previous_scene(app->scene_manager);
consumed = true;
break;
Expand Down
Loading

0 comments on commit 999652c

Please sign in to comment.