Selaa lähdekoodia

fix cnt down timer & update pomodoro

MX 2 vuotta sitten
vanhempi
commit
c97cdcd824
30 muutettua tiedostoa jossa 405 lisäystä ja 744 poistoa
  1. BIN
      apps/Bluetooth/fbp.fap
  2. BIN
      apps/Tools/cntdown_tim.fap
  3. BIN
      apps/Tools/flipp_pomodoro.fap
  4. 22 1
      apps_source_code/flipp_pomodoro/flipp_pomodoro_app.c
  5. 6 0
      apps_source_code/flipp_pomodoro/flipp_pomodoro_app.h
  6. 1 1
      apps_source_code/flipp_pomodoro/flipp_pomodoro_app_i.h
  7. BIN
      apps_source_code/flipp_pomodoro/images/flipp_pomodoro_learn_50x128.png
  8. 5 0
      apps_source_code/flipp_pomodoro/modules/flipp_pomodoro.c
  9. 0 1
      apps_source_code/flipp_pomodoro/modules/flipp_pomodoro.h
  10. 26 0
      apps_source_code/flipp_pomodoro/modules/flipp_pomodoro_statistics.c
  11. 45 0
      apps_source_code/flipp_pomodoro/modules/flipp_pomodoro_statistics.h
  12. 1 0
      apps_source_code/flipp_pomodoro/scenes/config/flipp_pomodoro_scene_config.h
  13. 1 0
      apps_source_code/flipp_pomodoro/scenes/flipp_pomodoro_scene.h
  14. 59 0
      apps_source_code/flipp_pomodoro/scenes/flipp_pomodoro_scene_info.c
  15. 9 3
      apps_source_code/flipp_pomodoro/scenes/flipp_pomodoro_scene_timer.c
  16. 152 0
      apps_source_code/flipp_pomodoro/views/flipp_pomodoro_info_view.c
  17. 71 0
      apps_source_code/flipp_pomodoro/views/flipp_pomodoro_info_view.h
  18. 4 1
      apps_source_code/flipp_pomodoro/views/flipp_pomodoro_timer_view.c
  19. 3 0
      apps_source_code/fpz_cntdown_timer-main/views/countdown_view.c
  20. 0 3
      non_catalog_apps/flipper-bp/README.md
  21. 0 13
      non_catalog_apps/flipper-bp/application.fam
  22. 0 119
      non_catalog_apps/flipper-bp/fbp.c
  23. 0 38
      non_catalog_apps/flipper-bp/fbp.h
  24. 0 183
      non_catalog_apps/flipper-bp/tcode.c
  25. 0 61
      non_catalog_apps/flipper-bp/tcode.h
  26. BIN
      non_catalog_apps/flipper-bp/uart_10px.png
  27. 0 157
      non_catalog_apps/flipper-bp/views/gpio_simple_motor.c
  28. 0 13
      non_catalog_apps/flipper-bp/views/gpio_simple_motor.h
  29. 0 138
      non_catalog_apps/flipper-bp/views/internal.c
  30. 0 12
      non_catalog_apps/flipper-bp/views/internal.h

BIN
apps/Bluetooth/fbp.fap


BIN
apps/Tools/cntdown_tim.fap


BIN
apps/Tools/flipp_pomodoro.fap


+ 22 - 1
apps_source_code/flipp_pomodoro/flipp_pomodoro_app.c

@@ -1,5 +1,7 @@
 #include "flipp_pomodoro_app_i.h"
 
+#define TAG "FlippPomodoro"
+
 enum {
     CustomEventConsumed = true,
     CustomEventNotConsumed = false,
@@ -32,6 +34,9 @@ static bool flipp_pomodoro_app_custom_event_callback(void* ctx, uint32_t event)
         if(flipp_pomodoro__get_stage(app->state) == FlippPomodoroStageFocus) {
             // REGISTER a deed on work stage complete to get an acheivement
             dolphin_deed(DolphinDeedPluginGameWin);
+            FURI_LOG_I(TAG, "Focus stage reward added");
+
+            flipp_pomodoro_statistics__increase_focus_stages_completed(app->statistics);
         };
 
         flipp_pomodoro__toggle_stage(app->state);
@@ -56,6 +61,8 @@ FlippPomodoroApp* flipp_pomodoro_app_alloc() {
     app->notification_app = furi_record_open(RECORD_NOTIFICATION);
 
     app->view_dispatcher = view_dispatcher_alloc();
+    app->statistics = flipp_pomodoro_statistics__new();
+
     view_dispatcher_enable_queue(app->view_dispatcher);
     view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
     view_dispatcher_set_custom_event_callback(
@@ -67,22 +74,32 @@ FlippPomodoroApp* flipp_pomodoro_app_alloc() {
         app->view_dispatcher, flipp_pomodoro_app_back_event_callback);
 
     app->timer_view = flipp_pomodoro_view_timer_alloc();
+    app->info_view = flipp_pomodoro_info_view_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);
+    view_dispatcher_add_view(
+        app->view_dispatcher,
+        FlippPomodoroAppViewInfo,
+        flipp_pomodoro_info_view_get_view(app->info_view));
 
+    scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneTimer);
+    FURI_LOG_I(TAG, "Alloc complete");
     return app;
 };
 
 void flipp_pomodoro_app_free(FlippPomodoroApp* app) {
     view_dispatcher_remove_view(app->view_dispatcher, FlippPomodoroAppViewTimer);
+    view_dispatcher_remove_view(app->view_dispatcher, FlippPomodoroAppViewInfo);
     view_dispatcher_free(app->view_dispatcher);
     scene_manager_free(app->scene_manager);
     flipp_pomodoro_view_timer_free(app->timer_view);
+    flipp_pomodoro_info_view_free(app->info_view);
+    flipp_pomodoro_statistics__destroy(app->statistics);
+    flipp_pomodoro__destroy(app->state);
     free(app);
     furi_record_close(RECORD_GUI);
     furi_record_close(RECORD_NOTIFICATION);
@@ -90,8 +107,12 @@ void flipp_pomodoro_app_free(FlippPomodoroApp* app) {
 
 int32_t flipp_pomodoro_app(void* p) {
     UNUSED(p);
+    FURI_LOG_I(TAG, "Initial");
     FlippPomodoroApp* app = flipp_pomodoro_app_alloc();
 
+    FURI_LOG_I(TAG, "Run deed added");
+    dolphin_deed(DolphinDeedPluginGameStart);
+
     view_dispatcher_run(app->view_dispatcher);
 
     flipp_pomodoro_app_free(app);

+ 6 - 0
apps_source_code/flipp_pomodoro/flipp_pomodoro_app.h

@@ -7,8 +7,10 @@
 #include <gui/scene_manager.h>
 #include <notification/notification_messages.h>
 #include "views/flipp_pomodoro_timer_view.h"
+#include "views/flipp_pomodoro_info_view.h"
 
 #include "modules/flipp_pomodoro.h"
+#include "modules/flipp_pomodoro_statistics.h"
 
 typedef enum {
     // Reserve first 100 events for button types and indexes, starting from 0
@@ -16,6 +18,7 @@ typedef enum {
     FlippPomodoroAppCustomEventStageComplete, // By Expiration
     FlippPomodoroAppCustomEventTimerTick,
     FlippPomodoroAppCustomEventStateUpdated,
+    FlippPomodoroAppCustomEventResumeTimer,
 } FlippPomodoroAppCustomEvent;
 
 typedef struct {
@@ -24,9 +27,12 @@ typedef struct {
     Gui* gui;
     NotificationApp* notification_app;
     FlippPomodoroTimerView* timer_view;
+    FlippPomodoroInfoView* info_view;
     FlippPomodoroState* state;
+    FlippPomodoroStatistics* statistics;
 } FlippPomodoroApp;
 
 typedef enum {
     FlippPomodoroAppViewTimer,
+    FlippPomodoroAppViewInfo,
 } FlippPomodoroAppView;

+ 1 - 1
apps_source_code/flipp_pomodoro/flipp_pomodoro_app_i.h

@@ -1,6 +1,6 @@
 #pragma once
 
-#define FURI_DEBUG 1
+// #define FURI_DEBUG 1
 
 /**
  * Index of dependencies for the main app

BIN
apps_source_code/flipp_pomodoro/images/flipp_pomodoro_learn_50x128.png


+ 5 - 0
apps_source_code/flipp_pomodoro/modules/flipp_pomodoro.c

@@ -55,6 +55,11 @@ char* flipp_pomodoro__next_stage_label(FlippPomodoroState* state) {
     return next_stage_label[flipp_pomodoro__stage_by_index(state->current_stage_index + 1)];
 };
 
+void flipp_pomodoro__destroy(FlippPomodoroState* state) {
+    furi_assert(state);
+    free(state);
+};
+
 uint32_t flipp_pomodoro__current_stage_total_duration(FlippPomodoroState* state) {
     const int32_t stage_duration_seconds_map[] = {
         [FlippPomodoroStageFocus] = 25 * TIME_SECONDS_IN_MINUTE,

+ 0 - 1
apps_source_code/flipp_pomodoro/modules/flipp_pomodoro.h

@@ -12,7 +12,6 @@ typedef enum {
 
 /// @brief State of the pomodoro timer
 typedef struct {
-    PomodoroStage stage;
     uint8_t current_stage_index;
     uint32_t started_at_timestamp;
 } FlippPomodoroState;

+ 26 - 0
apps_source_code/flipp_pomodoro/modules/flipp_pomodoro_statistics.c

@@ -0,0 +1,26 @@
+#include "flipp_pomodoro_statistics.h"
+
+FlippPomodoroStatistics* flipp_pomodoro_statistics__new() {
+    FlippPomodoroStatistics* statistics = malloc(sizeof(FlippPomodoroStatistics));
+
+    statistics->focus_stages_completed = 0;
+
+    return statistics;
+}
+
+// Return the number of completed focus stages
+uint8_t
+    flipp_pomodoro_statistics__get_focus_stages_completed(FlippPomodoroStatistics* statistics) {
+    return statistics->focus_stages_completed;
+}
+
+// Increase the number of completed focus stages by one
+void flipp_pomodoro_statistics__increase_focus_stages_completed(
+    FlippPomodoroStatistics* statistics) {
+    statistics->focus_stages_completed++;
+}
+
+void flipp_pomodoro_statistics__destroy(FlippPomodoroStatistics* statistics) {
+    furi_assert(statistics);
+    free(statistics);
+};

+ 45 - 0
apps_source_code/flipp_pomodoro/modules/flipp_pomodoro_statistics.h

@@ -0,0 +1,45 @@
+#pragma once
+#include <furi_hal.h>
+
+/** @brief FlippPomodoroStatistics structure
+ *
+ *  This structure is used to keep track of completed focus stages.
+ */
+typedef struct {
+    uint8_t focus_stages_completed;
+} FlippPomodoroStatistics;
+
+/** @brief Allocate and initialize a new FlippPomodoroStatistics
+ *
+ *  This function allocates a new FlippPomodoroStatistics structure, initializes its members
+ *  and returns a pointer to it.
+ *
+ *  @return A pointer to a new FlippPomodoroStatistics structure
+ */
+FlippPomodoroStatistics* flipp_pomodoro_statistics__new();
+
+/** @brief Get the number of completed focus stages
+ *
+ *  This function retrieves the number of completed focus stages in a FlippPomodoroStatistics structure.
+ *
+ *  @param statistics A pointer to a FlippPomodoroStatistics structure
+ *  @return The number of completed focus stages
+ */
+uint8_t flipp_pomodoro_statistics__get_focus_stages_completed(FlippPomodoroStatistics* statistics);
+
+/** @brief Increase the number of completed focus stages
+ *
+ *  This function increases the count of the completed focus stages by one in a FlippPomodoroStatistics structure.
+ *
+ *  @param statistics A pointer to a FlippPomodoroStatistics structure
+ */
+void flipp_pomodoro_statistics__increase_focus_stages_completed(
+    FlippPomodoroStatistics* statistics);
+
+/** @brief Free a FlippPomodoroStatistics structure
+ *
+ *  This function frees the memory used by a FlippPomodoroStatistics structure.
+ *
+ *  @param statistics A pointer to a FlippPomodoroStatistics structure
+ */
+void flipp_pomodoro_statistics__destroy(FlippPomodoroStatistics* state);

+ 1 - 0
apps_source_code/flipp_pomodoro/scenes/config/flipp_pomodoro_scene_config.h

@@ -1 +1,2 @@
+ADD_SCENE(flipp_pomodoro, info, Info)
 ADD_SCENE(flipp_pomodoro, timer, Timer)

+ 1 - 0
apps_source_code/flipp_pomodoro/scenes/flipp_pomodoro_scene.h

@@ -1,3 +1,4 @@
+#pragma once
 #include <gui/scene_manager.h>
 
 // Generate scene id and total number

+ 59 - 0
apps_source_code/flipp_pomodoro/scenes/flipp_pomodoro_scene_info.c

@@ -0,0 +1,59 @@
+#include <furi.h>
+#include <gui/view_dispatcher.h>
+#include <gui/scene_manager.h>
+#include "flipp_pomodoro_scene.h"
+#include "../flipp_pomodoro_app.h"
+#include "../views/flipp_pomodoro_info_view.h"
+
+enum { SceneEventConusmed = true, SceneEventNotConusmed = false };
+
+void flipp_pomodoro_scene_info_on_back_to_timer(void* ctx) {
+    furi_assert(ctx);
+    FlippPomodoroApp* app = ctx;
+
+    view_dispatcher_send_custom_event(
+        app->view_dispatcher, FlippPomodoroAppCustomEventResumeTimer);
+};
+
+void flipp_pomodoro_scene_info_on_enter(void* ctx) {
+    furi_assert(ctx);
+    FlippPomodoroApp* app = ctx;
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewInfo);
+    flipp_pomodoro_info_view_set_pomodoros_completed(
+        flipp_pomodoro_info_view_get_view(app->info_view),
+        flipp_pomodoro_statistics__get_focus_stages_completed(app->statistics));
+    flipp_pomodoro_info_view_set_mode(
+        flipp_pomodoro_info_view_get_view(app->info_view), FlippPomodoroInfoViewModeStats);
+    flipp_pomodoro_info_view_set_resume_timer_cb(
+        app->info_view, flipp_pomodoro_scene_info_on_back_to_timer, app);
+};
+
+void flipp_pomodoro_scene_info_handle_custom_event(
+    FlippPomodoroApp* app,
+    FlippPomodoroAppCustomEvent custom_event) {
+    if(custom_event == FlippPomodoroAppCustomEventResumeTimer) {
+        scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneTimer);
+    }
+};
+
+bool flipp_pomodoro_scene_info_on_event(void* ctx, SceneManagerEvent event) {
+    furi_assert(ctx);
+    FlippPomodoroApp* app = ctx;
+
+    switch(event.type) {
+    case SceneManagerEventTypeBack:
+        view_dispatcher_stop(app->view_dispatcher);
+        return SceneEventConusmed;
+    case SceneManagerEventTypeCustom:
+        flipp_pomodoro_scene_info_handle_custom_event(app, event.event);
+        return SceneEventConusmed;
+    default:
+        break;
+    };
+    return SceneEventNotConusmed;
+};
+
+void flipp_pomodoro_scene_info_on_exit(void* ctx) {
+    UNUSED(ctx);
+};

+ 9 - 3
apps_source_code/flipp_pomodoro/scenes/flipp_pomodoro_scene_timer.c

@@ -1,13 +1,13 @@
 #include <furi.h>
 #include <gui/scene_manager.h>
 #include <gui/view_dispatcher.h>
+#include <gui/scene_manager.h>
+#include "flipp_pomodoro_scene.h"
 #include "../flipp_pomodoro_app.h"
 #include "../views/flipp_pomodoro_timer_view.h"
 
 enum { SceneEventConusmed = true, SceneEventNotConusmed = false };
 
-uint8_t ExitSignal = 0;
-
 void flipp_pomodoro_scene_timer_sync_view_state(void* ctx) {
     furi_assert(ctx);
 
@@ -30,6 +30,11 @@ void flipp_pomodoro_scene_timer_on_enter(void* ctx) {
 
     FlippPomodoroApp* app = ctx;
 
+    if(flipp_pomodoro__is_stage_expired(app->state)) {
+        flipp_pomodoro__destroy(app->state);
+        app->state = flipp_pomodoro__new();
+    }
+
     view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewTimer);
     flipp_pomodoro_scene_timer_sync_view_state(app);
     flipp_pomodoro_view_timer_set_on_right_cb(
@@ -59,7 +64,8 @@ bool flipp_pomodoro_scene_timer_on_event(void* ctx, SceneManagerEvent event) {
         flipp_pomodoro_scene_timer_handle_custom_event(app, event.event);
         return SceneEventConusmed;
     case SceneManagerEventTypeBack:
-        return ExitSignal;
+        scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneInfo);
+        return SceneEventConusmed;
     default:
         break;
     };

+ 152 - 0
apps_source_code/flipp_pomodoro/views/flipp_pomodoro_info_view.c

@@ -0,0 +1,152 @@
+
+#include <furi.h>
+#include <gui/gui.h>
+#include <gui/elements.h>
+#include <gui/view.h>
+#include "flipp_pomodoro_info_view.h"
+// Auto-compiled icons
+#include "flipp_pomodoro_icons.h"
+
+enum {
+    ViewInputConsumed = true,
+    ViewInputNotConusmed = false,
+};
+
+struct FlippPomodoroInfoView {
+    View* view;
+    FlippPomodoroInfoViewUserActionCb resume_timer_cb;
+    void* user_action_cb_ctx;
+};
+
+typedef struct {
+    uint8_t pomodoros_completed;
+    FlippPomodoroInfoViewMode mode;
+} FlippPomodoroInfoViewModel;
+
+static void
+    flipp_pomodoro_info_view_draw_statistics(Canvas* canvas, FlippPomodoroInfoViewModel* model) {
+    FuriString* stats_string = furi_string_alloc();
+
+    furi_string_printf(
+        stats_string,
+        "So Long,\nand Thanks for All the Focus...\nand for completing\n%i pomodoro(s)",
+        model->pomodoros_completed);
+    const char* stats_string_formatted = furi_string_get_cstr(stats_string);
+
+    elements_text_box(
+        canvas,
+        0,
+        0,
+        canvas_width(canvas),
+        canvas_height(canvas) - 10,
+        AlignCenter,
+        AlignCenter,
+        stats_string_formatted,
+        true);
+
+    furi_string_free(stats_string);
+
+    elements_button_left(canvas, "Guide");
+}
+
+static void
+    flipp_pomodoro_info_view_draw_about(Canvas* canvas, FlippPomodoroInfoViewModel* model) {
+    UNUSED(model);
+    canvas_draw_icon(canvas, 0, 0, &I_flipp_pomodoro_learn_50x128);
+    elements_button_left(canvas, "Stats");
+}
+
+static void flipp_pomodoro_info_view_draw_callback(Canvas* canvas, void* _model) {
+    if(!_model) {
+        return;
+    };
+
+    FlippPomodoroInfoViewModel* model = _model;
+
+    canvas_clear(canvas);
+
+    if(model->mode == FlippPomodoroInfoViewModeStats) {
+        flipp_pomodoro_info_view_draw_statistics(canvas, model);
+    } else {
+        flipp_pomodoro_info_view_draw_about(canvas, model);
+    }
+
+    elements_button_right(canvas, "Resume");
+}
+
+void flipp_pomodoro_info_view_set_mode(View* view, FlippPomodoroInfoViewMode desired_mode) {
+    with_view_model(
+        view, FlippPomodoroInfoViewModel * model, { model->mode = desired_mode; }, false);
+}
+
+void flipp_pomodoro_info_view_toggle_mode(FlippPomodoroInfoView* info_view) {
+    with_view_model(
+        flipp_pomodoro_info_view_get_view(info_view),
+        FlippPomodoroInfoViewModel * model,
+        {
+            flipp_pomodoro_info_view_set_mode(
+                flipp_pomodoro_info_view_get_view(info_view),
+                (model->mode == FlippPomodoroInfoViewModeStats) ? FlippPomodoroInfoViewModeAbout :
+                                                                  FlippPomodoroInfoViewModeStats);
+        },
+        true);
+}
+
+bool flipp_pomodoro_info_view_input_callback(InputEvent* event, void* ctx) {
+    FlippPomodoroInfoView* info_view = ctx;
+
+    if(event->type == InputTypePress) {
+        if(event->key == InputKeyRight && info_view->resume_timer_cb != NULL) {
+            info_view->resume_timer_cb(info_view->user_action_cb_ctx);
+            return ViewInputConsumed;
+        } else if(event->key == InputKeyLeft) {
+            flipp_pomodoro_info_view_toggle_mode(info_view);
+            return ViewInputConsumed;
+        }
+    }
+
+    return ViewInputNotConusmed;
+}
+
+FlippPomodoroInfoView* flipp_pomodoro_info_view_alloc() {
+    FlippPomodoroInfoView* info_view = malloc(sizeof(FlippPomodoroInfoView));
+    info_view->view = view_alloc();
+
+    view_allocate_model(
+        flipp_pomodoro_info_view_get_view(info_view),
+        ViewModelTypeLockFree,
+        sizeof(FlippPomodoroInfoViewModel));
+    view_set_context(flipp_pomodoro_info_view_get_view(info_view), info_view);
+    view_set_draw_callback(
+        flipp_pomodoro_info_view_get_view(info_view), flipp_pomodoro_info_view_draw_callback);
+    view_set_input_callback(
+        flipp_pomodoro_info_view_get_view(info_view), flipp_pomodoro_info_view_input_callback);
+
+    return info_view;
+}
+
+View* flipp_pomodoro_info_view_get_view(FlippPomodoroInfoView* info_view) {
+    return info_view->view;
+}
+
+void flipp_pomodoro_info_view_free(FlippPomodoroInfoView* info_view) {
+    furi_assert(info_view);
+    view_free(info_view->view);
+    free(info_view);
+}
+
+void flipp_pomodoro_info_view_set_pomodoros_completed(View* view, uint8_t pomodoros_completed) {
+    with_view_model(
+        view,
+        FlippPomodoroInfoViewModel * model,
+        { model->pomodoros_completed = pomodoros_completed; },
+        false);
+}
+
+void flipp_pomodoro_info_view_set_resume_timer_cb(
+    FlippPomodoroInfoView* info_view,
+    FlippPomodoroInfoViewUserActionCb user_action_cb,
+    void* user_action_cb_ctx) {
+    info_view->resume_timer_cb = user_action_cb;
+    info_view->user_action_cb_ctx = user_action_cb_ctx;
+}

+ 71 - 0
apps_source_code/flipp_pomodoro/views/flipp_pomodoro_info_view.h

@@ -0,0 +1,71 @@
+#pragma once
+
+#include <gui/view.h>
+
+/** @brief Mode types for FlippPomodoroInfoView
+ *
+ *  These are the modes that can be used in the FlippPomodoroInfoView
+ */
+typedef enum {
+    FlippPomodoroInfoViewModeStats,
+    FlippPomodoroInfoViewModeAbout,
+} FlippPomodoroInfoViewMode;
+
+/** @brief Forward declaration of the FlippPomodoroInfoView struct */
+typedef struct FlippPomodoroInfoView FlippPomodoroInfoView;
+
+/** @brief User action callback function type
+ *
+ *  Callback functions of this type are called when a user action is performed.
+ */
+typedef void (*FlippPomodoroInfoViewUserActionCb)(void* ctx);
+
+/** @brief Allocate a new FlippPomodoroInfoView
+ *
+ *  Allocates a new FlippPomodoroInfoView and returns a pointer to it.
+ *  @return A pointer to a new FlippPomodoroInfoView
+ */
+FlippPomodoroInfoView* flipp_pomodoro_info_view_alloc();
+
+/** @brief Get the view from a FlippPomodoroInfoView
+ *
+ *  Returns a pointer to the view associated with a FlippPomodoroInfoView.
+ *  @param info_view A pointer to a FlippPomodoroInfoView
+ *  @return A pointer to the view of the FlippPomodoroInfoView
+ */
+View* flipp_pomodoro_info_view_get_view(FlippPomodoroInfoView* info_view);
+
+/** @brief Free a FlippPomodoroInfoView
+ *
+ *  Frees the memory used by a FlippPomodoroInfoView.
+ *  @param info_view A pointer to a FlippPomodoroInfoView
+ */
+void flipp_pomodoro_info_view_free(FlippPomodoroInfoView* info_view);
+
+/** @brief Set the number of completed pomodoros in the view
+ *
+ *  Sets the number of completed pomodoros that should be displayed in the view.
+ *  @param info_view A pointer to the view
+ *  @param pomodoros_completed The number of completed pomodoros
+ */
+void flipp_pomodoro_info_view_set_pomodoros_completed(View* info_view, uint8_t pomodoros_completed);
+
+/** @brief Set the callback function to be called when the timer should be resumed
+ *
+ *  Sets the callback function that will be called when the timer should be resumed.
+ *  @param info_view A pointer to the FlippPomodoroInfoView
+ *  @param user_action_cb The callback function
+ *  @param user_action_cb_ctx The context to be passed to the callback function
+ */
+void flipp_pomodoro_info_view_set_resume_timer_cb(
+    FlippPomodoroInfoView* info_view,
+    FlippPomodoroInfoViewUserActionCb user_action_cb,
+    void* user_action_cb_ctx);
+
+/** @brief Set the mode of the view
+ *
+ *  Sets the mode that should be used in the view.
+ *  @param view A pointer to the view
+ *  @param desired_mode The desired mode
+ */
+void flipp_pomodoro_info_view_set_mode(View* view, FlippPomodoroInfoViewMode desired_mode);

+ 4 - 1
apps_source_code/flipp_pomodoro/views/flipp_pomodoro_timer_view.c

@@ -156,7 +156,10 @@ FlippPomodoroTimerView* flipp_pomodoro_view_timer_alloc() {
     FlippPomodoroTimerView* timer = malloc(sizeof(FlippPomodoroTimerView));
     timer->view = view_alloc();
 
-    view_allocate_model(timer->view, ViewModelTypeLockFree, sizeof(FlippPomodoroTimerViewModel));
+    view_allocate_model(
+        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);

+ 3 - 0
apps_source_code/fpz_cntdown_timer-main/views/countdown_view.c

@@ -129,6 +129,9 @@ static bool countdown_timer_view_on_input(InputEvent* event, void* ctx) {
                 handle_misc_cmd(hw, CountDownTimerToggleCounting);
             }
             break;
+        case InputKeyBack:
+            return false;
+            break;
 
         default:
             break;

+ 0 - 3
non_catalog_apps/flipper-bp/README.md

@@ -1,3 +0,0 @@
-# Flipper BP
-
-Custom implementation of T-Code protocol for Flipper Zero devices.

+ 0 - 13
non_catalog_apps/flipper-bp/application.fam

@@ -1,13 +0,0 @@
-App(
-    appid="fbp",
-    name="Flipper BP",
-    apptype=FlipperAppType.EXTERNAL,
-    entry_point="fbp_app",
-    stack_size=1 * 1024,
-    requires=[
-        "bt",
-        "gui",
-    ],
-    fap_category="Bluetooth",
-    fap_icon="uart_10px.png",
-)

+ 0 - 119
non_catalog_apps/flipper-bp/fbp.c

@@ -1,119 +0,0 @@
-#include "fbp.h"
-
-enum FBPSubmenuIndex {
-    FBPSubmenuIndexInternal,
-    FBPSubmenuIndexGPIOSimpleMotor,
-};
-
-uint32_t fbp_start_view(void* context) {
-    UNUSED(context);
-    return FBPAppViewSubmenu;
-}
-
-uint32_t fbp_exit(void* context) {
-    UNUSED(context);
-    return VIEW_NONE;
-}
-
-void fbp_submenu_callback(void* context, uint32_t index) {
-    furi_assert(context);
-    FBP* app = context;
-    if(index == FBPSubmenuIndexInternal) {
-        view_dispatcher_switch_to_view(app->view_dispatcher, FBPAppViewInternal);
-    } else if(index == FBPSubmenuIndexGPIOSimpleMotor) {
-        view_dispatcher_switch_to_view(app->view_dispatcher, FBPAppViewGPIOSimpleMotor);
-    }
-}
-
-FBP* fbp_alloc() {
-    FBP* app = malloc(sizeof(FBP));
-    app->app_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
-    app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
-
-    app->bt_connected = false;
-    app->bt = furi_record_open(RECORD_BT);
-
-    app->gui = furi_record_open(RECORD_GUI);
-    app->view_dispatcher = view_dispatcher_alloc();
-    view_dispatcher_enable_queue(app->view_dispatcher);
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-
-    // set submenu
-    app->submenu = submenu_alloc();
-    view_set_previous_callback(submenu_get_view(app->submenu), fbp_exit);
-    view_dispatcher_add_view(
-        app->view_dispatcher, FBPAppViewSubmenu, submenu_get_view(app->submenu));
-
-    // add Flipper Internal View
-    app->flipper_vibrator = flipper_vibrator_alloc(app);
-    submenu_add_item(
-        app->submenu,
-        "Flipper Internal Vibrator",
-        FBPSubmenuIndexInternal,
-        fbp_submenu_callback,
-        app);
-    view_set_previous_callback(flipper_vibrator_get_view(app->flipper_vibrator), fbp_start_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher,
-        FBPAppViewInternal,
-        flipper_vibrator_get_view(app->flipper_vibrator));
-
-    // add GPIO Simple Motor View
-    app->gpio_simple_motor = gpio_simple_motor_alloc(app);
-    submenu_add_item(
-        app->submenu,
-        "Flipper GPIO Simple Motor",
-        FBPSubmenuIndexGPIOSimpleMotor,
-        fbp_submenu_callback,
-        app);
-    view_set_previous_callback(gpio_simple_motor_get_view(app->gpio_simple_motor), fbp_start_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher,
-        FBPAppViewGPIOSimpleMotor,
-        gpio_simple_motor_get_view(app->gpio_simple_motor));
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FBPAppViewSubmenu);
-    return app;
-}
-
-void fbs_free(FBP* app) {
-    furi_assert(app);
-
-    // Free views
-    view_dispatcher_remove_view(app->view_dispatcher, FBPAppViewSubmenu);
-    submenu_free(app->submenu);
-
-    // free Flipper Internal Vibrator
-    view_dispatcher_remove_view(app->view_dispatcher, FBPAppViewInternal);
-    flipper_vibrator_free(app->flipper_vibrator);
-
-    // free GPIO Simple Motor
-    view_dispatcher_remove_view(app->view_dispatcher, FBPAppViewGPIOSimpleMotor);
-    gpio_simple_motor_free(app->gpio_simple_motor);
-
-    // Other deallocations
-    view_dispatcher_free(app->view_dispatcher);
-
-    furi_record_close(RECORD_GUI);
-    app->gui = NULL;
-
-    furi_mutex_free(app->app_mutex);
-    furi_message_queue_free(app->event_queue);
-
-    furi_record_close(RECORD_BT);
-    app->bt = NULL;
-
-    free(app);
-}
-
-int32_t fbp_app(void* p) {
-    UNUSED(p);
-    FBP* app = fbp_alloc();
-
-    view_dispatcher_run(app->view_dispatcher);
-
-    furi_hal_bt_serial_set_event_callback(0, NULL, NULL);
-
-    fbs_free(app);
-    return 0;
-}

+ 0 - 38
non_catalog_apps/flipper-bp/fbp.h

@@ -1,38 +0,0 @@
-#pragma once
-
-#include <furi.h>
-#include <furi_hal_bt.h>
-#include <furi_hal_bt_serial.h>
-#include <bt/bt_service/bt.h>
-#include <gui/gui.h>
-#include <gui/view_dispatcher.h>
-#include <gui/modules/submenu.h>
-
-#include "tcode.h"
-#include "views/internal.h"
-#include "views/gpio_simple_motor.h"
-
-#define TAG "Flipper BP"
-
-typedef struct FBP FBP;
-
-struct FBP {
-    Submenu* submenu;
-    ViewDispatcher* view_dispatcher;
-    Gui* gui;
-
-    Bt* bt;
-    bool bt_connected;
-
-    FuriMutex* app_mutex;
-    FuriMessageQueue* event_queue;
-
-    FlipperVibrator* flipper_vibrator;
-    GPIOSimpleMotor* gpio_simple_motor;
-};
-
-typedef enum {
-    FBPAppViewSubmenu,
-    FBPAppViewInternal,
-    FBPAppViewGPIOSimpleMotor,
-} FBPAppView;

+ 0 - 183
non_catalog_apps/flipper-bp/tcode.c

@@ -1,183 +0,0 @@
-#include "tcode.h"
-
-static TCodeCommandArray decode_device_command(const uint8_t* buffer, uint16_t size) {
-    TCodeCommandArray command_array;
-    if(size < 2) {
-        command_array.size = 0;
-        FURI_LOG_W("TCode Parser", "Unexpected code length for device command");
-        return command_array;
-    }
-
-    command_array.size = 1;
-    command_array.commands = malloc(sizeof(TCodeCommand));
-    command_array.commands[0].command_type = Device;
-
-    switch(buffer[1]) {
-    case '0':
-        FURI_LOG_T("TCode Parser", "Device Identification requested");
-        command_array.commands[0].data.device_command = DeviceIdentification;
-        break;
-    case '1':
-        FURI_LOG_T("TCode Parser", "TCode version requested");
-        command_array.commands[0].data.device_command = TCodeVersion;
-        break;
-    case '2':
-        FURI_LOG_T("TCode Parser", "Preferences list requested");
-        command_array.commands[0].data.device_command = ListAxesAndUserRangePreferences;
-        break;
-    case 'S':
-        FURI_LOG_T("TCode Parser", "Stop requested");
-        command_array.commands[0].data.device_command = Stop;
-        break;
-    default:
-        command_array.size = 0;
-        break;
-    }
-
-    return command_array;
-}
-
-static TCodeCommandArray decode_general_command(const uint8_t* buffer, uint16_t size) {
-    // size of the array = amount of spaces + 1
-    uint16_t counter = 1;
-    for(uint16_t i = 0; i < size; i++) {
-        if(buffer[i] == 32) {
-            counter++;
-        }
-    }
-
-    FURI_LOG_T("TCode Parser", "Found %u commands in the message", counter);
-
-    TCodeCommandArray commands_array;
-    commands_array.size = counter;
-    commands_array.commands = malloc(commands_array.size * sizeof(TCodeCommand));
-
-    uint16_t position = 0;
-    for(uint16_t i = 0; i < counter; i++) {
-        TCodeCommand command;
-        command.command_type = Unknown;
-
-        TCodeCommandMotionType motion_type;
-        switch(buffer[position]) {
-        case 'L':
-        case 'l':
-            motion_type = Linear;
-            break;
-        case 'R':
-        case 'r':
-            motion_type = Rotate;
-            break;
-        case 'V':
-        case 'v':
-            motion_type = Vibrate;
-            break;
-        case 'A':
-        case 'a':
-            motion_type = Auxiliary;
-            break;
-        default: // error
-            FURI_LOG_W("TCode Parser", "Unexpected motion type: %u", buffer[position]);
-            return commands_array;
-        }
-        FURI_LOG_T("TCode Parser", "Parsed motion_type: %u", motion_type);
-        position++;
-
-        uint16_t channel = buffer[position] - 48; // single ascii character 0-9
-        FURI_LOG_T("TCode Parser", "Parsed channel: %u", channel);
-        position++;
-
-        // X characters that are digits
-        uint16_t current_position = position;
-        while(buffer[position] >= 48 && buffer[position] <= 57 && position < size) {
-            position++;
-        }
-
-        uint8_t* magnitude = malloc(2 + (position - current_position) + 1); // "0.XXXX\0"
-        magnitude[0] = '0';
-        magnitude[1] = '.';
-        for(uint16_t x = 0; x < (position - current_position); x++) {
-            magnitude[x + 2] = buffer[current_position + x];
-        }
-        magnitude[position - current_position + 2] = '\0';
-        float magnitude_float = strtof((char*)magnitude, NULL);
-        free(magnitude);
-        FURI_LOG_T("TCode Parser", "Parsed magnitude: %f", (double)magnitude_float);
-
-        FURI_LOG_T("TCode Parser REMOVE ME", "Current position: %u, size: %u", position, size);
-        FURI_LOG_T("TCode Parser REMOVE ME", "%u", buffer[position]);
-        if(position == size || buffer[position] == ' ' || buffer[position] == '\n') {
-            FURI_LOG_T("TCode Parser", "Command type: Magnitude");
-            command.command_type = Magnitude;
-            command.data.magnitude_command.motion_type = motion_type;
-            command.data.magnitude_command.channel_id = channel;
-            command.data.magnitude_command.magnitude = magnitude_float;
-            commands_array.commands[i] = command;
-            position++;
-            continue;
-        }
-
-        uint8_t current_step = buffer[position];
-        position++;
-
-        uint16_t int_value = 0;
-        while(buffer[position] >= 48 && buffer[position] <= 57 && position < size) {
-            int_value *= 10;
-            int_value += buffer[position] - 48;
-            position++;
-        }
-
-        command.data.magnitude_time_interval_command.motion_type = motion_type;
-        command.data.magnitude_time_interval_command.channel_id = channel;
-        command.data.magnitude_time_interval_command.magnitude = magnitude_float;
-
-        if(current_step == 'I' || current_step == 'i') {
-            FURI_LOG_T("TCode Parser", "Command type: MagnitudeTimeInterval");
-            command.command_type = MagnitudeTimeInterval;
-            command.data.magnitude_time_interval_command.time_interval_milliseconds = int_value;
-        }
-
-        if(current_step == 'S' || current_step == 's') {
-            FURI_LOG_T("TCode Parser", "Command type: MagnitudeSpeed");
-            command.command_type = MagnitudeSpeed;
-            command.data.magnitude_speed_command.speed_per_hundred_milliseconds = int_value;
-        }
-
-        if(command.command_type == Unknown) {
-            FURI_LOG_W("TCode Parser", "Unknown command type!");
-        }
-
-        commands_array.commands[i] = command;
-        position++;
-        if(position >= size) {
-            break;
-        }
-    }
-
-    return commands_array;
-}
-
-TCodeCommandArray tcode_decode(uint8_t* buffer, uint16_t size) {
-    switch(buffer[0]) {
-    case 'd':
-    case 'D':
-        FURI_LOG_T("TCode Parser", "Parsing device command...");
-        return decode_device_command(buffer, size);
-    case 'l':
-    case 'L':
-    case 'r':
-    case 'R':
-    case 'v':
-    case 'V':
-    case 'a':
-    case 'A':
-        FURI_LOG_T("TCode Parser", "Parsing general command...");
-        return decode_general_command(buffer, size);
-    default: // error
-    {
-        TCodeCommandArray error;
-        error.size = 0;
-        error.commands = NULL;
-        return error;
-    }
-    }
-}

+ 0 - 61
non_catalog_apps/flipper-bp/tcode.h

@@ -1,61 +0,0 @@
-#pragma once
-#include <furi.h>
-
-typedef enum {
-    Device,
-    Magnitude,
-    MagnitudeTimeInterval,
-    MagnitudeSpeed,
-    Unknown,
-} TCodeCommandType;
-
-typedef enum {
-    DeviceIdentification,
-    TCodeVersion,
-    ListAxesAndUserRangePreferences,
-    Stop,
-} DeviceCommand;
-
-typedef enum {
-    Linear,
-    Rotate,
-    Vibrate,
-    Auxiliary,
-} TCodeCommandMotionType;
-
-typedef struct {
-    TCodeCommandMotionType motion_type;
-    uint8_t channel_id;
-    float magnitude;
-} TCodeMagnitudeCommand;
-
-typedef struct {
-    TCodeCommandMotionType motion_type;
-    uint8_t channel_id;
-    float magnitude;
-    uint16_t time_interval_milliseconds;
-} TCodeMagnitudeTimeIntervalCommand;
-
-typedef struct {
-    TCodeCommandMotionType motion_type;
-    uint8_t channel_id;
-    float magnitude;
-    uint16_t speed_per_hundred_milliseconds;
-} TCodeMagnitudeSpeedCommand;
-
-typedef struct {
-    TCodeCommandType command_type;
-    union {
-        DeviceCommand device_command;
-        TCodeMagnitudeCommand magnitude_command;
-        TCodeMagnitudeTimeIntervalCommand magnitude_time_interval_command;
-        TCodeMagnitudeSpeedCommand magnitude_speed_command;
-    } data;
-} TCodeCommand;
-
-typedef struct {
-    uint16_t size;
-    TCodeCommand* commands;
-} TCodeCommandArray;
-
-TCodeCommandArray tcode_decode(uint8_t* buffer, uint16_t size);

BIN
non_catalog_apps/flipper-bp/uart_10px.png


+ 0 - 157
non_catalog_apps/flipper-bp/views/gpio_simple_motor.c

@@ -1,157 +0,0 @@
-#include "gpio_simple_motor.h"
-#include "../fbp.h"
-
-static const uint16_t BT_SERIAL_BUFFER_SIZE = 128;
-static const uint32_t DEFAULT_FREQ = 1000;
-static const FuriHalPwmOutputId DEFAULT_PWM_OUTPUT_ID = FuriHalPwmOutputIdTim1PA7;
-
-struct GPIOSimpleMotor {
-    View* view;
-    FBP* fbp;
-
-    uint8_t current_pwm_duty;
-};
-
-typedef struct {
-    char* display_text_1;
-    char* display_text_2;
-    char* display_text_3;
-} GPIOSimpleMotorModel;
-
-static void process_general_command(TCodeCommand command, GPIOSimpleMotor* motor) {
-    if(command.command_type == Magnitude &&
-       command.data.magnitude_command.motion_type == Vibrate &&
-       command.data.magnitude_command.channel_id == 0) {
-        // just enable vibration on X
-        uint8_t new_duty = (uint8_t)(command.data.magnitude_command.magnitude * 100);
-        if(new_duty > 100) {
-            new_duty = 100;
-        }
-        FURI_LOG_D(TAG, "Setting vibration power on %u", new_duty);
-
-        // using Pulse-Widht Modulation to control a motor via a transistor
-        // just google for a typical arduino + PWM + motor scheme
-        if(new_duty == 0) {
-            if(furi_hal_pwm_is_running(DEFAULT_PWM_OUTPUT_ID)) {
-                furi_hal_pwm_stop(DEFAULT_PWM_OUTPUT_ID);
-            }
-        } else if(motor->current_pwm_duty == 0) {
-            if(!furi_hal_pwm_is_running(DEFAULT_PWM_OUTPUT_ID)) {
-                furi_hal_pwm_start(DEFAULT_PWM_OUTPUT_ID, DEFAULT_FREQ, new_duty);
-            }
-        } else {
-            furi_hal_pwm_set_params(DEFAULT_PWM_OUTPUT_ID, DEFAULT_FREQ, new_duty);
-        }
-        motor->current_pwm_duty = new_duty;
-        return;
-    }
-}
-
-static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context) {
-    furi_assert(context);
-    GPIOSimpleMotor* motor = context;
-
-    if(event.event == SerialServiceEventTypeDataReceived) {
-        TCodeCommandArray commands = tcode_decode(event.data.buffer, event.data.size);
-        FURI_LOG_D(TAG, "Decoded commands array size: %u", commands.size);
-        for(uint16_t i = 0; i < commands.size; i++) {
-            FURI_LOG_D(TAG, "Command #%u, type: %u\n", i, commands.commands[i].command_type);
-        }
-        for(uint16_t i = 0; i < commands.size; i++) {
-            // looking for first vibro command to execute
-            TCodeCommand current_command = commands.commands[i];
-            TCodeCommandType type = current_command.command_type;
-            if((type == Magnitude || type == MagnitudeSpeed || type == MagnitudeTimeInterval)) {
-                process_general_command(current_command, motor);
-            }
-        }
-    }
-    return 0;
-}
-
-static bool input_callback(InputEvent* event, void* ctx) {
-    furi_assert(ctx);
-    GPIOSimpleMotor* motor = ctx;
-    if(event->key == InputKeyBack) {
-        furi_hal_bt_serial_set_event_callback(0, NULL, NULL);
-        return false;
-    }
-
-    if(event->key == InputKeyOk) {
-        if(furi_hal_bt_is_active()) {
-            FURI_LOG_D(TAG, "BT is working, hijacking the serial connection...");
-            furi_hal_bt_start_advertising();
-            furi_hal_bt_serial_set_event_callback(
-                BT_SERIAL_BUFFER_SIZE, bt_serial_event_callback, motor);
-
-            with_view_model(
-                motor->view,
-                GPIOSimpleMotorModel * model,
-                {
-                    model->display_text_1 = "";
-                    model->display_text_2 = "Ready ^_^";
-                    model->display_text_3 = "";
-                },
-                true);
-
-        } else {
-            FURI_LOG_E(TAG, "Please, enable the Bluetooth and restart the app");
-
-            with_view_model(
-                motor->view,
-                GPIOSimpleMotorModel * model,
-                {
-                    model->display_text_1 = "Error:";
-                    model->display_text_2 = "Bluetooth is not enabled";
-                    model->display_text_3 = "";
-                },
-                true);
-        }
-    }
-    return true;
-}
-
-static void draw_callback(Canvas* canvas, void* ctx) {
-    furi_assert(ctx);
-    GPIOSimpleMotorModel* app = ctx;
-    canvas_draw_str_aligned(canvas, 64, 24, AlignCenter, AlignCenter, (char*)app->display_text_1);
-    canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, (char*)app->display_text_2);
-    canvas_draw_str_aligned(canvas, 64, 40, AlignCenter, AlignCenter, (char*)app->display_text_3);
-}
-
-GPIOSimpleMotor* gpio_simple_motor_alloc(FBP* fbp) {
-    furi_assert(fbp);
-    GPIOSimpleMotor* motor = malloc(sizeof(GPIOSimpleMotor));
-    motor->view = view_alloc();
-    motor->fbp = fbp;
-    view_set_context(motor->view, motor);
-    view_allocate_model(motor->view, ViewModelTypeLocking, sizeof(GPIOSimpleMotorModel));
-    view_set_draw_callback(motor->view, draw_callback);
-    view_set_input_callback(motor->view, input_callback);
-
-    with_view_model(
-        motor->view,
-        GPIOSimpleMotorModel * model,
-        {
-            model->display_text_1 = "Please, connect the";
-            model->display_text_2 = "transistor base to pin A7!";
-            model->display_text_3 = "Press OK to start";
-        },
-        true);
-
-    return motor;
-}
-
-void gpio_simple_motor_free(GPIOSimpleMotor* motor) {
-    furi_assert(motor);
-    if(furi_hal_pwm_is_running(DEFAULT_PWM_OUTPUT_ID)) {
-        furi_hal_pwm_stop(DEFAULT_PWM_OUTPUT_ID);
-    }
-    view_free(motor->view);
-    free(motor);
-}
-
-View* gpio_simple_motor_get_view(GPIOSimpleMotor* motor) {
-    furi_assert(motor);
-    return motor->view;
-}

+ 0 - 13
non_catalog_apps/flipper-bp/views/gpio_simple_motor.h

@@ -1,13 +0,0 @@
-#pragma once
-#include <gui/view.h>
-#include <furi_hal_gpio.h>
-#include <furi_hal_pwm.h>
-
-typedef struct FBP FBP;
-typedef struct GPIOSimpleMotor GPIOSimpleMotor;
-
-GPIOSimpleMotor* gpio_simple_motor_alloc(FBP* fbp);
-
-void gpio_simple_motor_free(GPIOSimpleMotor* motor_app);
-
-View* gpio_simple_motor_get_view(GPIOSimpleMotor* motor_app);

+ 0 - 138
non_catalog_apps/flipper-bp/views/internal.c

@@ -1,138 +0,0 @@
-#include "internal.h"
-#include "../fbp.h"
-
-static const uint16_t BT_SERIAL_BUFFER_SIZE = 128;
-
-struct FlipperVibrator {
-    View* view;
-    FBP* fbp;
-};
-
-typedef struct {
-    char* display_text;
-} FlipperVibratorModel;
-
-static void process_general_command(TCodeCommand command) {
-    if(command.command_type == Magnitude &&
-       command.data.magnitude_command.motion_type == Vibrate &&
-       command.data.magnitude_command.channel_id == 0) {
-        furi_hal_vibro_on(command.data.magnitude_command.magnitude > 0.1f);
-        return;
-    }
-
-    if(command.command_type == MagnitudeSpeed &&
-       command.data.magnitude_speed_command.motion_type == Vibrate &&
-       command.data.magnitude_speed_command.channel_id == 0) {
-        furi_hal_vibro_on(command.data.magnitude_speed_command.magnitude > 0.1f);
-        return;
-    }
-
-    if(command.command_type == MagnitudeTimeInterval &&
-       command.data.magnitude_time_interval_command.motion_type == Vibrate &&
-       command.data.magnitude_time_interval_command.channel_id == 0) {
-        furi_hal_vibro_on(command.data.magnitude_time_interval_command.magnitude > 0.1f);
-        return;
-    }
-}
-
-static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context) {
-    furi_assert(context);
-    FlipperVibrator* flipper_vibrator = context;
-    UNUSED(flipper_vibrator);
-
-    if(event.event == SerialServiceEventTypeDataReceived) {
-        FURI_LOG_D(TAG, "SerialServiceEventTypeDataReceived");
-        FURI_LOG_D(TAG, "Size: %u", event.data.size);
-        FURI_LOG_D(TAG, "Data: ");
-        for(size_t i = 0; i < event.data.size; i++) {
-            printf("%X ", event.data.buffer[i]);
-        }
-        printf("\r\n");
-
-        TCodeCommandArray commands = tcode_decode(event.data.buffer, event.data.size);
-        FURI_LOG_D(TAG, "Decoded commands array size: %u", commands.size);
-        for(uint16_t i = 0; i < commands.size; i++) {
-            FURI_LOG_D(TAG, "Command #%u, type: %u\n", i, commands.commands[i].command_type);
-        }
-        for(uint16_t i = 0; i < commands.size; i++) {
-            // looking for first vibro command to execute
-            TCodeCommand current_command = commands.commands[i];
-            TCodeCommandType type = current_command.command_type;
-            if((type == Magnitude || type == MagnitudeSpeed || type == MagnitudeTimeInterval)) {
-                process_general_command(current_command);
-            }
-        }
-    }
-    return 0;
-}
-
-static bool input_callback(InputEvent* event, void* ctx) {
-    furi_assert(ctx);
-    FlipperVibrator* flipper_vibrator = ctx;
-    if(event->key == InputKeyBack) {
-        furi_hal_bt_serial_set_event_callback(0, NULL, NULL);
-        return false;
-    }
-
-    if(event->key == InputKeyOk) {
-        if(furi_hal_bt_is_active()) {
-            FURI_LOG_D(TAG, "BT is working, hijacking the serial connection...");
-            furi_hal_bt_start_advertising();
-            furi_hal_bt_serial_set_event_callback(
-                BT_SERIAL_BUFFER_SIZE, bt_serial_event_callback, flipper_vibrator);
-
-            with_view_model(
-                flipper_vibrator->view,
-                FlipperVibratorModel * model,
-                { model->display_text = "Ready ^_^"; },
-                true);
-
-        } else {
-            FURI_LOG_E(TAG, "Please, enable the Bluetooth and restart the app");
-
-            with_view_model(
-                flipper_vibrator->view,
-                FlipperVibratorModel * model,
-                { model->display_text = "Error: Bluetooth not enabled"; },
-                true);
-        }
-    }
-    return true;
-}
-
-static void draw_callback(Canvas* canvas, void* ctx) {
-    furi_assert(ctx);
-    FlipperVibratorModel* app = ctx;
-    canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, (char*)app->display_text);
-}
-
-FlipperVibrator* flipper_vibrator_alloc(FBP* fbp) {
-    furi_assert(fbp);
-    FlipperVibrator* flipper_vibrator = malloc(sizeof(FlipperVibrator));
-    flipper_vibrator->view = view_alloc();
-    flipper_vibrator->fbp = fbp;
-    view_set_context(flipper_vibrator->view, flipper_vibrator);
-    view_allocate_model(
-        flipper_vibrator->view, ViewModelTypeLocking, sizeof(FlipperVibratorModel));
-    view_set_draw_callback(flipper_vibrator->view, draw_callback);
-    view_set_input_callback(flipper_vibrator->view, input_callback);
-
-    with_view_model(
-        flipper_vibrator->view,
-        FlipperVibratorModel * model,
-        { model->display_text = "Press OK to start"; },
-        true);
-
-    return flipper_vibrator;
-}
-
-void flipper_vibrator_free(FlipperVibrator* flipper_vibrator) {
-    furi_assert(flipper_vibrator);
-    view_free(flipper_vibrator->view);
-    free(flipper_vibrator);
-}
-
-View* flipper_vibrator_get_view(FlipperVibrator* flipper_vibrator) {
-    furi_assert(flipper_vibrator);
-    return flipper_vibrator->view;
-}

+ 0 - 12
non_catalog_apps/flipper-bp/views/internal.h

@@ -1,12 +0,0 @@
-#pragma once
-#include <gui/view.h>
-#include <furi_hal_vibro.h>
-
-typedef struct FBP FBP;
-typedef struct FlipperVibrator FlipperVibrator;
-
-FlipperVibrator* flipper_vibrator_alloc(FBP* fbp);
-
-void flipper_vibrator_free(FlipperVibrator* flipper_vibrator);
-
-View* flipper_vibrator_get_view(FlipperVibrator* flipper_vibrator);