jblanked пре 1 година
родитељ
комит
ea5fcd33f1
15 измењених фајлова са 0 додато и 7962 уклоњено
  1. BIN
      app.png
  2. 0 596
      easy_flipper.h
  3. 0 1062
      flip_social_callback.h
  4. 0 1008
      flip_social_draw.h
  5. 0 310
      flip_social_e.h
  6. 0 141
      flip_social_explore.h
  7. 0 209
      flip_social_feed.h
  8. 0 294
      flip_social_free.h
  9. 0 158
      flip_social_friends.h
  10. 0 542
      flip_social_i.h
  11. 0 396
      flip_social_messages.h
  12. 0 381
      flip_social_storage.h
  13. 0 1197
      flipper_http.h
  14. 0 865
      jsmn.h
  15. 0 803
      uart_text_input.h

+ 0 - 596
easy_flipper.h

@@ -1,596 +0,0 @@
-#ifndef EASY_FLIPPER_H
-#define EASY_FLIPPER_H
-
-#include <malloc.h>
-#include <furi.h>
-#include <furi_hal.h>
-#include <gui/gui.h>
-#include <gui/view.h>
-#include <gui/modules/submenu.h>
-#include <gui/view_dispatcher.h>
-#include <gui/modules/menu.h>
-#include <gui/modules/submenu.h>
-#include <gui/modules/widget.h>
-#include <gui/modules/text_input.h>
-#include <gui/modules/text_box.h>
-#include <gui/modules/variable_item_list.h>
-#include <gui/modules/dialog_ex.h>
-#include <gui/modules/popup.h>
-#include <gui/modules/loading.h>
-#include <uart_text_input.h>
-#include <stdio.h>
-#include <string.h>
-#include <jsmn.h>
-
-#define EASY_TAG "EasyFlipper"
-
-/**
- * @brief Navigation callback for exiting the application
- * @param context The context - unused
- * @return next view id (VIEW_NONE to exit the app)
- */
-uint32_t easy_flipper_callback_exit_app(void *context)
-{
-    // Exit the application
-    if (!context)
-    {
-        FURI_LOG_E(EASY_TAG, "Context is NULL");
-        return VIEW_NONE;
-    }
-    UNUSED(context);
-    return VIEW_NONE; // Return VIEW_NONE to exit the app
-}
-
-/**
- * @brief Initialize a buffer
- * @param buffer The buffer to initialize
- * @param buffer_size The size of the buffer
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_buffer(char **buffer, uint32_t buffer_size)
-{
-    if (!buffer)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_buffer");
-        return false;
-    }
-    *buffer = (char *)malloc(buffer_size);
-    if (!*buffer)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate buffer");
-        return false;
-    }
-    *buffer[0] = '\0';
-    return true;
-}
-
-/**
- * @brief Initialize a View object
- * @param view The View object to initialize
- * @param view_id The ID/Index of the view
- * @param draw_callback The draw callback function (set to NULL if not needed)
- * @param input_callback The input callback function (set to NULL if not needed)
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_view(
-    View **view,
-    int32_t view_id,
-    void draw_callback(Canvas *, void *),
-    bool input_callback(InputEvent *, void *),
-    uint32_t (*previous_callback)(void *),
-    ViewDispatcher **view_dispatcher,
-    void *context)
-{
-    if (!view || !view_dispatcher)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_view");
-        return false;
-    }
-    *view = view_alloc();
-    if (!*view)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate View");
-        return false;
-    }
-    if (draw_callback)
-    {
-        view_set_draw_callback(*view, draw_callback);
-    }
-    if (input_callback)
-    {
-        view_set_input_callback(*view, input_callback);
-    }
-    if (context)
-    {
-        view_set_context(*view, context);
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(*view, previous_callback);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, *view);
-    return true;
-}
-
-/**
- * @brief Initialize a ViewDispatcher object
- * @param view_dispatcher The ViewDispatcher object to initialize
- * @param gui The GUI object
- * @param context The context to pass to the event callback
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_view_dispatcher(ViewDispatcher **view_dispatcher, Gui *gui, void *context)
-{
-    if (!view_dispatcher)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_view_dispatcher");
-        return false;
-    }
-    *view_dispatcher = view_dispatcher_alloc();
-    if (!*view_dispatcher)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate ViewDispatcher");
-        return false;
-    }
-    view_dispatcher_attach_to_gui(*view_dispatcher, gui, ViewDispatcherTypeFullscreen);
-    if (context)
-    {
-        view_dispatcher_set_event_callback_context(*view_dispatcher, context);
-    }
-    return true;
-}
-
-/**
- * @brief Initialize a Submenu object
- * @note This does not set the items in the submenu
- * @param submenu The Submenu object to initialize
- * @param view_id The ID/Index of the view
- * @param title The title/header of the submenu
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_submenu(
-    Submenu **submenu,
-    int32_t view_id,
-    char *title,
-    uint32_t(previous_callback)(void *),
-    ViewDispatcher **view_dispatcher)
-{
-    if (!submenu)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_submenu");
-        return false;
-    }
-    *submenu = submenu_alloc();
-    if (!*submenu)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate Submenu");
-        return false;
-    }
-    if (title)
-    {
-        submenu_set_header(*submenu, title);
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(submenu_get_view(*submenu), previous_callback);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, submenu_get_view(*submenu));
-    return true;
-}
-/**
- * @brief Initialize a Menu object
- * @note This does not set the items in the menu
- * @param menu The Menu object to initialize
- * @param view_id The ID/Index of the view
- * @param item_callback The item callback function
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_menu(
-    Menu **menu,
-    int32_t view_id,
-    uint32_t(previous_callback)(void *),
-    ViewDispatcher **view_dispatcher)
-{
-    if (!menu)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_menu");
-        return false;
-    }
-    *menu = menu_alloc();
-    if (!*menu)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate Menu");
-        return false;
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(menu_get_view(*menu), previous_callback);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, menu_get_view(*menu));
-    return true;
-}
-
-/**
- * @brief Initialize a Widget object
- * @param widget The Widget object to initialize
- * @param view_id The ID/Index of the view
- * @param text The text to display in the widget
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_widget(
-    Widget **widget,
-    int32_t view_id,
-    char *text,
-    uint32_t(previous_callback)(void *),
-    ViewDispatcher **view_dispatcher)
-{
-    if (!widget)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_widget");
-        return false;
-    }
-    *widget = widget_alloc();
-    if (!*widget)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate Widget");
-        return false;
-    }
-    if (text)
-    {
-        widget_add_text_scroll_element(*widget, 0, 0, 128, 64, text);
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(widget_get_view(*widget), previous_callback);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, widget_get_view(*widget));
-    return true;
-}
-
-/**
- * @brief Initialize a VariableItemList object
- * @note This does not set the items in the VariableItemList
- * @param variable_item_list The VariableItemList object to initialize
- * @param view_id The ID/Index of the view
- * @param enter_callback The enter callback function (can be set to NULL)
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @param context The context to pass to the enter callback (usually the app)
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_variable_item_list(
-    VariableItemList **variable_item_list,
-    int32_t view_id,
-    void (*enter_callback)(void *, uint32_t),
-    uint32_t(previous_callback)(void *),
-    ViewDispatcher **view_dispatcher,
-    void *context)
-{
-    if (!variable_item_list)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_variable_item_list");
-        return false;
-    }
-    *variable_item_list = variable_item_list_alloc();
-    if (!*variable_item_list)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate VariableItemList");
-        return false;
-    }
-    if (enter_callback)
-    {
-        variable_item_list_set_enter_callback(*variable_item_list, enter_callback, context);
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(variable_item_list_get_view(*variable_item_list), previous_callback);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, variable_item_list_get_view(*variable_item_list));
-    return true;
-}
-
-/**
- * @brief Initialize a TextInput object
- * @param text_input The TextInput object to initialize
- * @param view_id The ID/Index of the view
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_text_input(
-    TextInput **text_input,
-    int32_t view_id,
-    char *header_text,
-    char *text_input_temp_buffer,
-    uint32_t text_input_buffer_size,
-    void (*result_callback)(void *),
-    uint32_t(previous_callback)(void *),
-    ViewDispatcher **view_dispatcher,
-    void *context)
-{
-    if (!text_input)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_text_input");
-        return false;
-    }
-    *text_input = text_input_alloc();
-    if (!*text_input)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate TextInput");
-        return false;
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(text_input_get_view(*text_input), previous_callback);
-    }
-    if (header_text)
-    {
-        text_input_set_header_text(*text_input, header_text);
-    }
-    if (text_input_temp_buffer && text_input_buffer_size && result_callback)
-    {
-        text_input_set_result_callback(*text_input, result_callback, context, text_input_temp_buffer, text_input_buffer_size, false);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, text_input_get_view(*text_input));
-    return true;
-}
-
-/**
- * @brief Initialize a UART_TextInput object
- * @param uart_text_input The UART_TextInput object to initialize
- * @param view_id The ID/Index of the view
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_uart_text_input(
-    UART_TextInput **uart_text_input,
-    int32_t view_id,
-    char *header_text,
-    char *uart_text_input_temp_buffer,
-    uint32_t uart_text_input_buffer_size,
-    void (*result_callback)(void *),
-    uint32_t(previous_callback)(void *),
-    ViewDispatcher **view_dispatcher,
-    void *context)
-{
-    if (!uart_text_input)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_uart_text_input");
-        return false;
-    }
-    *uart_text_input = uart_text_input_alloc();
-    if (!*uart_text_input)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate UART_TextInput");
-        return false;
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(uart_text_input_get_view(*uart_text_input), previous_callback);
-    }
-    if (header_text)
-    {
-        uart_text_input_set_header_text(*uart_text_input, header_text);
-    }
-    if (uart_text_input_temp_buffer && uart_text_input_buffer_size && result_callback)
-    {
-        uart_text_input_set_result_callback(*uart_text_input, result_callback, context, uart_text_input_temp_buffer, uart_text_input_buffer_size, false);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, uart_text_input_get_view(*uart_text_input));
-    return true;
-}
-
-/**
- * @brief Initialize a DialogEx object
- * @param dialog_ex The DialogEx object to initialize
- * @param view_id The ID/Index of the view
- * @param header The header of the dialog
- * @param header_x The x coordinate of the header
- * @param header_y The y coordinate of the header
- * @param text The text of the dialog
- * @param text_x The x coordinate of the dialog
- * @param text_y The y coordinate of the dialog
- * @param left_button_text The text of the left button
- * @param right_button_text The text of the right button
- * @param center_button_text The text of the center button
- * @param result_callback The result callback function
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @param context The context to pass to the result callback
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_dialog_ex(
-    DialogEx **dialog_ex,
-    int32_t view_id,
-    char *header,
-    uint16_t header_x,
-    uint16_t header_y,
-    char *text,
-    uint16_t text_x,
-    uint16_t text_y,
-    char *left_button_text,
-    char *right_button_text,
-    char *center_button_text,
-    void (*result_callback)(DialogExResult, void *),
-    uint32_t(previous_callback)(void *),
-    ViewDispatcher **view_dispatcher,
-    void *context)
-{
-    if (!dialog_ex)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_dialog_ex");
-        return false;
-    }
-    *dialog_ex = dialog_ex_alloc();
-    if (!*dialog_ex)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate DialogEx");
-        return false;
-    }
-    if (header)
-    {
-        dialog_ex_set_header(*dialog_ex, header, header_x, header_y, AlignLeft, AlignTop);
-    }
-    if (text)
-    {
-        dialog_ex_set_text(*dialog_ex, text, text_x, text_y, AlignLeft, AlignTop);
-    }
-    if (left_button_text)
-    {
-        dialog_ex_set_left_button_text(*dialog_ex, left_button_text);
-    }
-    if (right_button_text)
-    {
-        dialog_ex_set_right_button_text(*dialog_ex, right_button_text);
-    }
-    if (center_button_text)
-    {
-        dialog_ex_set_center_button_text(*dialog_ex, center_button_text);
-    }
-    if (result_callback)
-    {
-        dialog_ex_set_result_callback(*dialog_ex, result_callback);
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(dialog_ex_get_view(*dialog_ex), previous_callback);
-    }
-    if (context)
-    {
-        dialog_ex_set_context(*dialog_ex, context);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, dialog_ex_get_view(*dialog_ex));
-    return true;
-}
-
-/**
- * @brief Initialize a Popup object
- * @param popup The Popup object to initialize
- * @param view_id The ID/Index of the view
- * @param header The header of the dialog
- * @param header_x The x coordinate of the header
- * @param header_y The y coordinate of the header
- * @param text The text of the dialog
- * @param text_x The x coordinate of the dialog
- * @param text_y The y coordinate of the dialog
- * @param result_callback The result callback function
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @param context The context to pass to the result callback
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_popup(
-    Popup **popup,
-    int32_t view_id,
-    char *header,
-    uint16_t header_x,
-    uint16_t header_y,
-    char *text,
-    uint16_t text_x,
-    uint16_t text_y,
-    void (*result_callback)(void *),
-    uint32_t(previous_callback)(void *),
-    ViewDispatcher **view_dispatcher,
-    void *context)
-{
-    if (!popup)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_popup");
-        return false;
-    }
-    *popup = popup_alloc();
-    if (!*popup)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate Popup");
-        return false;
-    }
-    if (header)
-    {
-        popup_set_header(*popup, header, header_x, header_y, AlignLeft, AlignTop);
-    }
-    if (text)
-    {
-        popup_set_text(*popup, text, text_x, text_y, AlignLeft, AlignTop);
-    }
-    if (result_callback)
-    {
-        popup_set_callback(*popup, result_callback);
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(popup_get_view(*popup), previous_callback);
-    }
-    if (context)
-    {
-        popup_set_context(*popup, context);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, popup_get_view(*popup));
-    return true;
-}
-
-/**
- * @brief Initialize a Loading object
- * @param loading The Loading object to initialize
- * @param view_id The ID/Index of the view
- * @param previous_callback The previous callback function (can be set to NULL)
- * @param view_dispatcher The ViewDispatcher object
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_loading(
-    Loading **loading,
-    int32_t view_id,
-    uint32_t(previous_callback)(void *),
-    ViewDispatcher **view_dispatcher)
-{
-    if (!loading)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_loading");
-        return false;
-    }
-    *loading = loading_alloc();
-    if (!*loading)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate Loading");
-        return false;
-    }
-    if (previous_callback)
-    {
-        view_set_previous_callback(loading_get_view(*loading), previous_callback);
-    }
-    view_dispatcher_add_view(*view_dispatcher, view_id, loading_get_view(*loading));
-    return true;
-}
-
-/**
- * @brief Set a char butter to a FuriString
- * @param furi_string The FuriString object
- * @param buffer The buffer to copy the string to
- * @return true if successful, false otherwise
- */
-bool easy_flipper_set_char_to_furi_string(FuriString **furi_string, char *buffer)
-{
-    if (!furi_string)
-    {
-        FURI_LOG_E(EASY_TAG, "Invalid arguments provided to set_buffer_to_furi_string");
-        return false;
-    }
-    *furi_string = furi_string_alloc();
-    if (!furi_string)
-    {
-        FURI_LOG_E(EASY_TAG, "Failed to allocate FuriString");
-        return false;
-    }
-    furi_string_set_str(*furi_string, buffer);
-    return true;
-}
-
-#endif // EASY_FLIPPER_H

+ 0 - 1062
flip_social_callback.h

@@ -1,1062 +0,0 @@
-// flip_social_callback.h
-#ifndef FLIP_SOCIAL_CALLBACK_H
-#define FLIP_SOCIAL_CALLBACK_H
-
-/**
- * @brief Navigation callback to go back to the submenu Logged out.
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedOutSubmenu)
- */
-static uint32_t flip_social_callback_to_submenu_logged_out(void *context)
-{
-    UNUSED(context);
-    return FlipSocialViewLoggedOutSubmenu;
-}
-
-/**
- * @brief Navigation callback to go back to the submenu Logged in.
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedInSubmenu)
- */
-static uint32_t flip_social_callback_to_submenu_logged_in(void *context)
-{
-    UNUSED(context);
-    flip_social_free_explore();
-    flip_social_free_feed();
-    flip_social_free_friends();
-    flip_social_free_message_users();
-    flip_social_free_messages();
-    return FlipSocialViewLoggedInSubmenu;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the (Logged out) Login screen
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedOutLogin)
- */
-static uint32_t flip_social_callback_to_login_logged_out(void *context)
-{
-    UNUSED(context);
-    flip_social_sent_login_request = false;
-    flip_social_login_success = false;
-    return FlipSocialViewLoggedOutLogin;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the (Logged out) Register screen
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedOutRegister)
- */
-static uint32_t flip_social_callback_to_register_logged_out(void *context)
-{
-    UNUSED(context);
-    flip_social_sent_register_request = false;
-    flip_social_register_success = false;
-    return FlipSocialViewLoggedOutRegister;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the (Logged out) Wifi Settings screen
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedOutWifiSettings)
- */
-static uint32_t flip_social_callback_to_wifi_settings_logged_out(void *context)
-{
-    UNUSED(context);
-    return FlipSocialViewLoggedOutWifiSettings;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the (Logged in) Wifi Settings screen
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedInSettingsWifi)
- */
-static uint32_t flip_social_callback_to_wifi_settings_logged_in(void *context)
-{
-    UNUSED(context);
-    return FlipSocialViewLoggedInSettingsWifi;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the (Logged in) Settings screen
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedInSettingsWifi)
- */
-static uint32_t flip_social_callback_to_settings_logged_in(void *context)
-{
-    UNUSED(context);
-    return FlipSocialViewLoggedInSettings;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the (Logged in) Compose screen
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedInCompose)
- */
-static uint32_t flip_social_callback_to_compose_logged_in(void *context)
-{
-    UNUSED(context);
-    return FlipSocialViewLoggedInCompose;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the (Logged in) Profile screen
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedInProfile)
- */
-static uint32_t flip_social_callback_to_profile_logged_in(void *context)
-{
-    UNUSED(context);
-    return FlipSocialViewLoggedInProfile;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the Explore submenu
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedInExploreSubmenu)
- */
-static uint32_t flip_social_callback_to_explore_logged_in(void *context)
-{
-    UNUSED(context);
-    flip_social_dialog_stop = true;
-    last_explore_response = "";
-    flip_social_dialog_shown = false;
-    flip_social_explore->index = 0;
-    action = ActionNone;
-    return FlipSocialViewLoggedInExploreSubmenu;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the Friends submenu
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedInFriendsSubmenu)
- */
-static uint32_t flip_social_callback_to_friends_logged_in(void *context)
-{
-    UNUSED(context);
-    flip_social_dialog_stop = true;
-    last_explore_response = "";
-    flip_social_dialog_shown = false;
-    flip_social_friends->index = 0;
-    action = ActionNone;
-    return FlipSocialViewLoggedInFriendsSubmenu;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the Messages submenu
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedInMessagesSubmenu)
- */
-static uint32_t flip_social_callback_to_messages_logged_in(void *context)
-{
-    UNUSED(context);
-    return FlipSocialViewLoggedInMessagesSubmenu;
-}
-
-/**
- * @brief Navigation callback to bring the user back to the User Choices screen
- * @param context The context - unused
- * @return next view id (FlipSocialViewLoggedInMessagesUserChoices)
- */
-static uint32_t flip_social_callback_to_messages_user_choices(void *context)
-{
-    UNUSED(context);
-    return FlipSocialViewLoggedInMessagesUserChoices;
-}
-
-/**
- * @brief Navigation callback for exiting the application
- * @param context The context - unused
- * @return next view id (VIEW_NONE to exit the app)
- */
-static uint32_t flip_social_callback_exit_app(void *context)
-{
-    // Exit the application
-    if (!context)
-    {
-        FURI_LOG_E(TAG, "Context is NULL");
-        return VIEW_NONE;
-    }
-    UNUSED(context);
-    return VIEW_NONE; // Return VIEW_NONE to exit the app
-}
-
-/**
- * @brief Handle ALL submenu item selections.
- * @param context The context - FlipSocialApp object.
- * @param index The FlipSocialSubmenuIndex item that was clicked.
- * @return void
- */
-static void flip_social_callback_submenu_choices(void *context, uint32_t index)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    switch (index)
-    {
-    case FlipSocialSubmenuLoggedOutIndexLogin:
-        flip_social_sent_login_request = false;
-        flip_social_login_success = false;
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutLogin);
-        break;
-    case FlipSocialSubmenuLoggedOutIndexRegister:
-        flip_social_sent_register_request = false;
-        flip_social_register_success = false;
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutRegister);
-        break;
-    case FlipSocialSubmenuLoggedOutIndexAbout:
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutAbout);
-        break;
-    case FlipSocialSubmenuLoggedOutIndexWifiSettings:
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettings);
-        break;
-    case FlipSocialSubmenuLoggedInIndexProfile:
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInProfile);
-        break;
-    case FlipSocialSubmenuLoggedInIndexMessages:
-        if (flipper_http_process_response_async(flip_social_get_message_users, flip_social_parse_json_message_users))
-        {
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesSubmenu);
-        }
-        break;
-    case FlipSocialSubmenuLoggedInIndexMessagesNewMessage:
-        if (flipper_http_process_response_async(flip_social_get_explore, flip_social_parse_json_message_user_choices))
-        {
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesUserChoices);
-        }
-        break;
-    case FlipSocialSubmenuLoggedInIndexFeed:
-        if (flipper_http_process_response_async(flip_social_get_feed, flip_social_parse_json_feed))
-        {
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInFeed);
-        }
-        else
-        {
-            // Set failure FlipSocialFeed object
-            if (!flip_social_temp_feed())
-            {
-                return;
-            }
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInFeed);
-        }
-        break;
-    case FlipSocialSubmenuExploreIndex:
-        if (flipper_http_process_response_async(flip_social_get_explore, flip_social_parse_json_explore))
-        {
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInExploreSubmenu);
-        }
-        break;
-    case FlipSocialSubmenuLoggedInIndexCompose:
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInCompose);
-        break;
-    case FlipSocialSubmenuLoggedInIndexSettings:
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSettings);
-        break;
-    case FlipSocialSubmenuLoggedInSignOutButton:
-        app->is_logged_in = "false";
-
-        save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutSubmenu);
-        break;
-    case FlipSocialSubmenuComposeIndexAddPreSave:
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInComposeAddPreSaveInput);
-        break;
-    default:
-        // Handle the pre-saved message selection (has a max of 25 items)
-        if (index >= FlipSocialSubemnuComposeIndexStartIndex && index < FlipSocialSubemnuComposeIndexStartIndex + MAX_PRE_SAVED_MESSAGES)
-        {
-            flip_social_feed->index = index - FlipSocialSubemnuComposeIndexStartIndex;
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInProcessCompose);
-        }
-
-        // Handle the explore selection
-        else if (index >= FlipSocialSubmenuExploreIndexStartIndex && index < FlipSocialSubmenuExploreIndexStartIndex + MAX_EXPLORE_USERS)
-        {
-            flip_social_explore->index = index - FlipSocialSubmenuExploreIndexStartIndex;
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInExploreProccess);
-        }
-
-        // handle the friends selection
-        else if (index >= FlipSocialSubmenuLoggedInIndexFriendsStart && index < FlipSocialSubmenuLoggedInIndexFriendsStart + MAX_FRIENDS)
-        {
-            flip_social_friends->index = index - FlipSocialSubmenuLoggedInIndexFriendsStart;
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInFriendsProcess);
-        }
-
-        // handle the messages selection
-        else if (index >= FlipSocialSubmenuLoggedInIndexMessagesUsersStart && index < FlipSocialSubmenuLoggedInIndexMessagesUsersStart + MAX_MESSAGE_USERS)
-        {
-            flip_social_message_users->index = index - FlipSocialSubmenuLoggedInIndexMessagesUsersStart;
-            if (flipper_http_process_response_async(flip_social_get_messages_with_user, flip_social_parse_json_messages))
-            {
-                view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesProcess);
-            }
-        }
-
-        // handle the messages user choices selection
-        else if (index >= FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart && index < FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart + MAX_EXPLORE_USERS)
-        {
-            flip_social_explore->index = index - FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart;
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesNewMessageUserChoicesInput);
-        }
-        else
-        {
-            FURI_LOG_E(TAG, "Unknown submenu index");
-        }
-
-        break;
-    }
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their SSID on the wifi settings (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_out_wifi_settings_ssid_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Store the entered name
-    strncpy(app->wifi_ssid_logged_out, app->wifi_ssid_logged_out_temp_buffer, app->wifi_ssid_logged_out_temp_buffer_size);
-
-    // Store the entered name in the logged in name field
-    strncpy(app->wifi_ssid_logged_in, app->wifi_ssid_logged_out_temp_buffer, app->wifi_ssid_logged_out_temp_buffer_size);
-    strncpy(app->wifi_ssid_logged_in_temp_buffer, app->wifi_ssid_logged_out_temp_buffer, app->wifi_ssid_logged_out_temp_buffer_size);
-
-    // Ensure null-termination
-    app->wifi_ssid_logged_out[app->wifi_ssid_logged_out_temp_buffer_size - 1] = '\0';
-
-    // Update the name item text
-    if (app->variable_item_logged_out_wifi_settings_ssid)
-    {
-        variable_item_set_current_value_text(app->variable_item_logged_out_wifi_settings_ssid, app->wifi_ssid_logged_out);
-    }
-
-    // update the wifi settings
-    if (!flipper_http_save_wifi(app->wifi_ssid_logged_out, app->wifi_password_logged_out))
-    {
-        FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
-        FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
-    }
-
-    // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettings);
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their password on the wifi settings (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_out_wifi_settings_password_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Store the entered WiFi password
-    strncpy(app->wifi_password_logged_out, app->wifi_password_logged_out_temp_buffer, app->wifi_password_logged_out_temp_buffer_size);
-
-    // Store the entered WiFi password in the logged in password field
-    strncpy(app->wifi_password_logged_in, app->wifi_password_logged_out_temp_buffer, app->wifi_password_logged_out_temp_buffer_size);
-    strncpy(app->wifi_password_logged_in_temp_buffer, app->wifi_password_logged_out_temp_buffer, app->wifi_password_logged_out_temp_buffer_size);
-
-    // Ensure null-termination
-    app->wifi_password_logged_out[app->wifi_password_logged_out_temp_buffer_size - 1] = '\0';
-
-    // Update the password item text
-    if (app->variable_item_logged_out_wifi_settings_password)
-    {
-        variable_item_set_current_value_text(app->variable_item_logged_out_wifi_settings_password, app->wifi_password_logged_out);
-    }
-
-    // update the wifi settings
-    if (!flipper_http_save_wifi(app->wifi_ssid_logged_out, app->wifi_password_logged_out))
-    {
-        FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
-        FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
-    }
-
-    // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettings);
-}
-
-/**
- * @brief Callback when the user selects a menu item in the wifi settings (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @param index The index of the selected item.
- * @return void
- */
-static void flip_social_text_input_logged_out_wifi_settings_item_selected(void *context, uint32_t index)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    switch (index)
-    {
-    case 0: // Input SSID
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettingsSSIDInput);
-        break;
-    case 1: // Input Password
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettingsPasswordInput);
-        break;
-    default:
-        FURI_LOG_E(TAG, "Unknown configuration item index");
-        break;
-    }
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their username on the login (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_out_login_username_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Store the entered name
-    strncpy(app->login_username_logged_out, app->login_username_logged_out_temp_buffer, app->login_username_logged_out_temp_buffer_size);
-
-    // Store the entered name in the logged in username field
-    strncpy(app->login_username_logged_in, app->login_username_logged_out_temp_buffer, app->login_username_logged_out_temp_buffer_size);
-    strncpy(app->login_username_logged_in_temp_buffer, app->login_username_logged_out_temp_buffer, app->login_username_logged_out_temp_buffer_size);
-
-    // Ensure null-termination
-    app->login_username_logged_out[app->login_username_logged_out_temp_buffer_size - 1] = '\0';
-
-    // Update the name item text
-    if (app->variable_item_logged_out_login_username)
-    {
-        variable_item_set_current_value_text(app->variable_item_logged_out_login_username, app->login_username_logged_out);
-    }
-
-    // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutLogin);
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their password on the login (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-
-static void flip_social_logged_out_login_password_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Store the entered password
-    strncpy(app->login_password_logged_out, app->login_password_logged_out_temp_buffer, app->login_password_logged_out_temp_buffer_size);
-
-    // Store the entered password in the change password field
-    strncpy(app->change_password_logged_in, app->login_password_logged_out_temp_buffer, app->login_password_logged_out_temp_buffer_size);
-    strncpy(app->change_password_logged_in_temp_buffer, app->login_password_logged_out_temp_buffer, app->login_password_logged_out_temp_buffer_size);
-
-    // Ensure null-termination
-    app->login_password_logged_out[app->login_password_logged_out_temp_buffer_size - 1] = '\0';
-
-    // Update the password item text
-    if (app->variable_item_logged_out_login_password)
-    {
-        // dont show the password on the screen (version 0.2)
-        // variable_item_set_current_value_text(app->variable_item_logged_out_login_password, app->login_password_logged_out);
-    }
-
-    // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutLogin);
-}
-
-/**
- * @brief Callback when the user selects a menu item in the login (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @param index The index of the selected item.
- * @return void
- */
-static void flip_social_text_input_logged_out_login_item_selected(void *context, uint32_t index)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    switch (index)
-    {
-    case 0: // Input Username
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutLoginUsernameInput);
-        break;
-    case 1: // Input Password
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutLoginPasswordInput);
-        break;
-    case 2: // Login Button
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutProcessLogin);
-        break;
-    default:
-        FURI_LOG_E(TAG, "Unknown configuration item index");
-        break;
-    }
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their username on the register (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_out_register_username_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Store the entered name
-    strncpy(app->register_username_logged_out, app->register_username_logged_out_temp_buffer, app->register_username_logged_out_temp_buffer_size);
-
-    // Ensure null-termination
-    app->register_username_logged_out[app->register_username_logged_out_temp_buffer_size - 1] = '\0';
-
-    // Update the name item text
-    if (app->variable_item_logged_out_register_username)
-    {
-        variable_item_set_current_value_text(app->variable_item_logged_out_register_username, app->register_username_logged_out);
-    }
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutRegister);
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their password on the register (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_out_register_password_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Store the entered password
-    strncpy(app->register_password_logged_out, app->register_password_logged_out_temp_buffer, app->register_password_logged_out_temp_buffer_size);
-
-    // Ensure null-termination
-    app->register_password_logged_out[app->register_password_logged_out_temp_buffer_size - 1] = '\0';
-
-    // Update the password item text
-    if (app->variable_item_logged_out_register_password)
-    {
-        variable_item_set_current_value_text(app->variable_item_logged_out_register_password, app->register_password_logged_out);
-    }
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutRegister);
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their password 2 on the register (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_out_register_password_2_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Store the entered password
-    strncpy(app->register_password_2_logged_out, app->register_password_2_logged_out_temp_buffer, app->register_password_2_logged_out_temp_buffer_size);
-
-    // Ensure null-termination
-    app->register_password_2_logged_out[app->register_password_2_logged_out_temp_buffer_size - 1] = '\0';
-
-    // Update the password item text
-    if (app->variable_item_logged_out_register_password_2)
-    {
-        variable_item_set_current_value_text(app->variable_item_logged_out_register_password_2, app->register_password_2_logged_out);
-    }
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutRegister);
-}
-
-/**
- * @brief Callback when the user selects a menu item in the register (logged out) screen.
- * @param context The context - FlipSocialApp object.
- * @param index The index of the selected item.
- * @return void
- */
-static void flip_social_text_input_logged_out_register_item_selected(void *context, uint32_t index)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    switch (index)
-    {
-    case 0: // Input Username
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutRegisterUsernameInput);
-        break;
-    case 1: // Input Password
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutRegisterPasswordInput);
-        break;
-    case 2: // Input Password 2
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutRegisterPassword2Input);
-        break;
-    case 3: // Register button
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutProcessRegister);
-        break;
-    default:
-        FURI_LOG_E(TAG, "Unknown configuration item index");
-        break;
-    }
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their SSID on the wifi settings (logged in) screen.
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_in_wifi_settings_ssid_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Store the entered SSID
-    strncpy(app->wifi_ssid_logged_in, app->wifi_ssid_logged_in_temp_buffer, app->wifi_ssid_logged_in_temp_buffer_size);
-
-    // Store the entered SSID in the logged out SSID
-    strncpy(app->wifi_ssid_logged_out, app->wifi_ssid_logged_in, app->wifi_ssid_logged_in_temp_buffer_size);
-    strncpy(app->wifi_ssid_logged_out_temp_buffer, app->wifi_ssid_logged_in, app->wifi_ssid_logged_in_temp_buffer_size);
-
-    // Ensure null-termination
-    app->wifi_ssid_logged_in[app->wifi_ssid_logged_in_temp_buffer_size - 1] = '\0';
-
-    // Update the name item text
-    if (app->variable_item_logged_in_wifi_settings_ssid)
-    {
-        variable_item_set_current_value_text(app->variable_item_logged_in_wifi_settings_ssid, app->wifi_ssid_logged_in);
-    }
-
-    // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_in, app_instance->wifi_password_logged_in, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-    // update the wifi settings
-    if (strlen(app->wifi_ssid_logged_in) > 0 && strlen(app->wifi_password_logged_in) > 0)
-    {
-        if (!flipper_http_save_wifi(app->wifi_ssid_logged_in, app->wifi_password_logged_in))
-        {
-            FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
-            FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
-        }
-    }
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSettingsWifi);
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their password on the wifi settings (logged in) screen.
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_in_wifi_settings_password_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Store the entered password
-    strncpy(app->wifi_password_logged_in, app->wifi_password_logged_in_temp_buffer, app->wifi_password_logged_in_temp_buffer_size);
-
-    // Store the entered password in the logged out password
-    strncpy(app->login_password_logged_out, app->wifi_password_logged_in, app->wifi_password_logged_in_temp_buffer_size);
-    strncpy(app->login_password_logged_out_temp_buffer, app->wifi_password_logged_in, app->wifi_password_logged_in_temp_buffer_size);
-
-    // Ensure null-termination
-    app->wifi_password_logged_in[app->wifi_password_logged_in_temp_buffer_size - 1] = '\0';
-
-    // Update the password item text
-    if (app->variable_item_logged_in_wifi_settings_password)
-    {
-        // dont show the password on the screen (version 0.2)
-        // variable_item_set_current_value_text(app->variable_item_logged_in_wifi_settings_password, app->wifi_password_logged_in);
-    }
-
-    // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_in, app_instance->wifi_password_logged_in, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-    // update the wifi settings
-    if (strlen(app->wifi_ssid_logged_in) > 0 && strlen(app->wifi_password_logged_in) > 0)
-    {
-        if (!flipper_http_save_wifi(app->wifi_ssid_logged_in, app->wifi_password_logged_in))
-        {
-            FURI_LOG_E(TAG, "Failed to save wifi settings via UART");
-            FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
-        }
-    }
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSettingsWifi);
-}
-
-/**
- * @brief Callback when the user selects a menu item in the wifi settings (logged in) screen.
- * @param context The context - FlipSocialApp object.
- * @param index The index of the selected item.
- * @return void
- */
-static void flip_social_text_input_logged_in_wifi_settings_item_selected(void *context, uint32_t index)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    switch (index)
-    {
-    case 0: // Input SSID
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInWifiSettingsSSIDInput);
-        break;
-    case 1: // Input Password
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInWifiSettingsPasswordInput);
-        break;
-    default:
-        FURI_LOG_E(TAG, "Unknown configuration item index");
-        break;
-    }
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their message on the compose (logged in) screen for Add Text
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_in_compose_pre_save_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-
-    // check if the message is empty or if adding in the message would exceed the MAX_PRE_SAVED_MESSAGES
-    if (app->compose_pre_save_logged_in_temp_buffer_size == 0 || app->pre_saved_messages.count >= MAX_PRE_SAVED_MESSAGES)
-    {
-        FURI_LOG_E(TAG, "Message is empty or would exceed the maximum number of pre-saved messages");
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInCompose);
-        return;
-    }
-
-    // Store the entered message
-    strncpy(app->compose_pre_save_logged_in, app->compose_pre_save_logged_in_temp_buffer, app->compose_pre_save_logged_in_temp_buffer_size);
-
-    // Ensure null-termination
-    app->compose_pre_save_logged_in[app->compose_pre_save_logged_in_temp_buffer_size - 1] = '\0';
-
-    // add the item to the submenu
-    submenu_reset(app->submenu_compose);
-
-    // loop through the items and add them to the submenu
-    app->pre_saved_messages.messages[app->pre_saved_messages.count] = app->compose_pre_save_logged_in;
-    app->pre_saved_messages.count++;
-
-    submenu_add_item(app->submenu_compose, "Add Pre-Save", FlipSocialSubmenuComposeIndexAddPreSave, flip_social_callback_submenu_choices, app);
-    for (uint32_t i = 0; i < app->pre_saved_messages.count; i++)
-    {
-        submenu_add_item(app->submenu_compose, app->pre_saved_messages.messages[i], FlipSocialSubemnuComposeIndexStartIndex + i, flip_social_callback_submenu_choices, app);
-    }
-
-    // save playlist
-    save_playlist(&app->pre_saved_messages);
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInCompose);
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their message on the profile (logged in) screen for change password
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_in_profile_change_password_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    // Correct type: old_pass should be a pointer to a string (char *)
-    const char *old_password = app->login_password_logged_out;
-
-    // Store the entered message
-    strncpy(app->change_password_logged_in, app->change_password_logged_in_temp_buffer, app->change_password_logged_in_temp_buffer_size);
-
-    // store the entered password in the logged out password
-    strncpy(app->login_password_logged_out, app->change_password_logged_in, app->login_password_logged_out_temp_buffer_size);
-    strncpy(app->login_password_logged_out_temp_buffer, app->change_password_logged_in, app->login_password_logged_out_temp_buffer_size);
-
-    // Ensure null-termination
-    app->change_password_logged_in[app->change_password_logged_in_temp_buffer_size - 1] = '\0';
-
-    // Update the message item text
-    if (app->variable_item_logged_in_profile_change_password)
-    {
-        // dont show the password on the screen (version 0.2)
-        // variable_item_set_current_value_text(app->variable_item_logged_in_profile_change_password, app->change_password_logged_in);
-    }
-
-    // send post request to change password
-    char payload[256];
-    snprintf(payload, sizeof(payload), "{\"username\":\"%s\",\"old_password\":\"%s\",\"new_password\":\"%s\"}", app->login_username_logged_out, old_password, app->change_password_logged_in);
-    char *headers = jsmn("Content-Type", "application/json");
-    if (!flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/change-password/", headers, payload))
-    {
-        FURI_LOG_E(TAG, "Failed to send post request to change password");
-        FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
-        free(headers);
-        return;
-    }
-    free(headers);
-    // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInProfile);
-}
-
-/**
- * @brief Callback when a user selects a menu item in the profile (logged in) screen.
- * @param context The context - FlipSocialApp object.
- * @param index The index of the selected item.
- * @return void
- */
-static void flip_social_text_input_logged_in_profile_item_selected(void *context, uint32_t index)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    switch (index)
-    {
-    case 0: // Change Username
-        // do nothing since username cannot be changed
-        break;
-    case 1: // Change Password
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInChangePasswordInput);
-        break;
-    case 2: // Friends
-        // get friends then switch to the friends screen
-        if (flip_social_get_friends()) // start the async friends request
-        {
-            furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        }
-        while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
-        {
-            // Wait for the friends to be received
-            furi_delay_ms(100);
-        }
-        furi_timer_stop(fhttp.get_timeout_timer);
-        if (!flip_social_parse_json_friends()) // parse the JSON before switching to the friends (synchonous)
-        {
-            FURI_LOG_E(TAG, "Failed to parse the JSON friends...");
-            return; // just return for now, no temporary friends yet
-            // show a popup message saving wifi is disconnected
-        }
-        furi_timer_stop(fhttp.get_timeout_timer);
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInFriendsSubmenu);
-        break;
-    default:
-        FURI_LOG_E(TAG, "Unknown configuration item index");
-        break;
-    }
-}
-
-/**
- * @brief Callback when a user selects a menu item in the settings (logged in) screen.
- * @param context The context - FlipSocialApp object.
- * @param index The index of the selected item.
- * @return void
- */
-static void flip_social_text_input_logged_in_settings_item_selected(void *context, uint32_t index)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    switch (index)
-    {
-    case 0: // About
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSettingsAbout);
-        break;
-    case 1: // Wifi
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSettingsWifi);
-        break;
-    default:
-        break;
-    }
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their message to send to the selected user choice (user choice messages view)
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_in_messages_user_choice_message_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-
-    // check if the message is empty
-    if (app->message_user_choice_logged_in_temp_buffer_size == 0)
-    {
-        FURI_LOG_E(TAG, "Message is empty");
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesNewMessageUserChoicesInput);
-        return;
-    }
-
-    // Store the entered message
-    strncpy(app->message_user_choice_logged_in, app->message_user_choice_logged_in_temp_buffer, app->message_user_choice_logged_in_temp_buffer_size);
-
-    // Ensure null-termination
-    app->message_user_choice_logged_in[app->message_user_choice_logged_in_temp_buffer_size - 1] = '\0';
-
-    // send post request to send message
-    char url[128];
-    char payload[256];
-    snprintf(url, sizeof(url), "https://www.flipsocial.net/api/messages/%s/post/", app->login_username_logged_in);
-    snprintf(payload, sizeof(payload), "{\"receiver\":\"%s\",\"content\":\"%s\"}", flip_social_explore->usernames[flip_social_explore->index], app->message_user_choice_logged_in);
-    char *headers = jsmn("Content-Type", "application/json");
-
-    if (flipper_http_post_request_with_headers(url, headers, payload)) // start the async request
-    {
-        furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        fhttp.state = RECEIVING;
-        free(headers);
-    }
-    else
-    {
-        FURI_LOG_E(TAG, "Failed to send post request to send message");
-        FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
-        free(headers);
-        return;
-    }
-    while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
-    {
-        // Wait for the request to be received
-        furi_delay_ms(100);
-    }
-    furi_timer_stop(fhttp.get_timeout_timer);
-
-    // add user to the message list
-    strncpy(flip_social_message_users->usernames[flip_social_message_users->count], flip_social_explore->usernames[flip_social_explore->index], strlen(flip_social_explore->usernames[flip_social_explore->index]));
-    flip_social_message_users->count++;
-
-    // redraw submenu
-    flip_social_update_messages_submenu();
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesSubmenu);
-}
-
-/**
- * @brief Text input callback for when the user finishes entering their message to the selected user (messages view)
- * @param context The context - FlipSocialApp object.
- * @return void
- */
-static void flip_social_logged_in_messages_new_message_updated(void *context)
-{
-    FlipSocialApp *app = (FlipSocialApp *)context;
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-
-    // check if the message is empty
-    if (app->messages_new_message_logged_in_temp_buffer_size == 0)
-    {
-        FURI_LOG_E(TAG, "Message is empty");
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesNewMessageInput);
-        return;
-    }
-
-    // Store the entered message
-    strncpy(app->messages_new_message_logged_in, app->messages_new_message_logged_in_temp_buffer, app->messages_new_message_logged_in_temp_buffer_size);
-
-    // Ensure null-termination
-    app->messages_new_message_logged_in[app->messages_new_message_logged_in_temp_buffer_size - 1] = '\0';
-
-    // send post request to send message
-    char url[128];
-    char payload[256];
-    snprintf(url, sizeof(url), "https://www.flipsocial.net/api/messages/%s/post/", app->login_username_logged_in);
-    snprintf(payload, sizeof(payload), "{\"receiver\":\"%s\",\"content\":\"%s\"}", flip_social_message_users->usernames[flip_social_message_users->index], app->messages_new_message_logged_in);
-    char *headers = jsmn("Content-Type", "application/json");
-
-    if (flipper_http_post_request_with_headers(url, headers, payload)) // start the async request
-    {
-        furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        fhttp.state = RECEIVING;
-        free(headers);
-    }
-    else
-    {
-        FURI_LOG_E(TAG, "Failed to send post request to send message");
-        FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
-        free(headers);
-        return;
-    }
-    while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
-    {
-        // Wait for the request to be received
-        furi_delay_ms(100);
-    }
-    furi_timer_stop(fhttp.get_timeout_timer);
-    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesSubmenu);
-}
-
-#endif // FLIP_SOCIAL_CALLBACK_H

+ 0 - 1008
flip_social_draw.h

@@ -1,1008 +0,0 @@
-#ifndef FLIP_SOCIAL_DRAW_H
-#define FLIP_SOCIAL_DRAW_H
-
-bool flip_social_sent_login_request = false;
-bool flip_social_sent_register_request = false;
-bool flip_social_login_success = false;
-bool flip_social_register_success = false;
-bool flip_social_dialog_shown = false;
-bool flip_social_dialog_stop = false;
-char *last_explore_response = "";
-static bool flip_social_update_friends();
-
-bool flip_social_board_is_active(Canvas *canvas)
-{
-    if (fhttp.state == INACTIVE)
-    {
-        canvas_draw_str(canvas, 0, 7, "Wifi Dev Board disconnected.");
-        canvas_draw_str(canvas, 0, 17, "Please connect to the board.");
-        canvas_draw_str(canvas, 0, 32, "If your board is connected,");
-        canvas_draw_str(canvas, 0, 42, "make sure you have flashed");
-        canvas_draw_str(canvas, 0, 52, "your WiFi Devboard with the");
-        canvas_draw_str(canvas, 0, 62, "latest FlipperHTTP flash.");
-        return false;
-    }
-    return true;
-}
-
-void flip_social_handle_error(Canvas *canvas)
-{
-    if (fhttp.received_data != NULL)
-    {
-        if (strstr(fhttp.received_data, "[ERROR] Not connected to Wifi. Failed to reconnect.") != NULL)
-        {
-            canvas_clear(canvas);
-            canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
-            canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
-            canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
-        }
-        else if (strstr(fhttp.received_data, "[ERROR] Failed to connect to Wifi.") != NULL)
-        {
-            canvas_clear(canvas);
-            canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
-            canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
-            canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
-        }
-        else
-        {
-            canvas_draw_str(canvas, 0, 42, "Failed...");
-            canvas_draw_str(canvas, 0, 52, "Update your credentials.");
-            canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
-        }
-    }
-    else
-    {
-        canvas_draw_str(canvas, 0, 42, "Failed...");
-        canvas_draw_str(canvas, 0, 52, "Update your credentials.");
-        canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
-    }
-}
-
-static void on_input(const void *event, void *ctx)
-{
-    UNUSED(ctx);
-
-    InputKey key = ((InputEvent *)event)->key;
-    InputType type = ((InputEvent *)event)->type;
-
-    if (type != InputTypeRelease)
-    {
-        return;
-    }
-
-    switch (key)
-    {
-    case InputKeyOk:
-        action = ActionFlip;
-        break;
-    case InputKeyBack:
-        action = ActionBack;
-        break;
-    case InputKeyRight:
-        action = ActionNext;
-        break;
-    case InputKeyLeft:
-        action = ActionPrev;
-        break;
-    case InputKeyUp:
-        action = ActionPrev;
-        break;
-    case InputKeyDown:
-        action = ActionNext;
-        break;
-    default:
-        action = ActionNone;
-        break;
-    }
-}
-
-// Function to draw the message on the canvas with word wrapping
-void draw_user_message(Canvas *canvas, const char *user_message, int x, int y)
-{
-    if (user_message == NULL)
-    {
-        FURI_LOG_E(TAG, "User message is NULL.");
-        return;
-    }
-
-    size_t msg_length = strlen(user_message);
-    size_t start = 0;
-    int line_num = 0;
-    char line[MAX_LINE_LENGTH + 1]; // Buffer for the current line (+1 for null terminator)
-
-    while (start < msg_length && line_num < 4)
-    {
-        size_t remaining = msg_length - start;
-        size_t len = (remaining > MAX_LINE_LENGTH) ? MAX_LINE_LENGTH : remaining;
-
-        if (remaining > MAX_LINE_LENGTH)
-        {
-            // Find the last space within the first 'len' characters
-            size_t last_space = len;
-            while (last_space > 0 && user_message[start + last_space - 1] != ' ')
-            {
-                last_space--;
-            }
-
-            if (last_space > 0)
-            {
-                len = last_space; // Adjust len to the position of the last space
-            }
-        }
-
-        // Copy the substring to 'line' and null-terminate it
-        memcpy(line, user_message + start, len);
-        line[len] = '\0'; // Ensure the string is null-terminated
-
-        // Draw the string on the canvas
-        // Adjust the y-coordinate based on the line number
-        canvas_draw_str_aligned(canvas, x, y + line_num * 10, AlignLeft, AlignTop, line);
-
-        // Update the start position for the next line
-        start += len;
-
-        // Skip any spaces to avoid leading spaces on the next line
-        while (start < msg_length && user_message[start] == ' ')
-        {
-            start++;
-        }
-
-        // Increment the line number
-        line_num++;
-    }
-}
-
-static void flip_social_callback_draw_compose(Canvas *canvas, void *model)
-{
-    UNUSED(model);
-    if (!canvas)
-    {
-        FURI_LOG_E(TAG, "Canvas is NULL");
-        return;
-    }
-    if (!app_instance)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-
-    char *message = app_instance->pre_saved_messages.messages[flip_social_feed->index];
-
-    if (!flip_social_dialog_shown)
-    {
-        flip_social_dialog_shown = true;
-        app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
-        app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
-    }
-
-    draw_user_message(canvas, message, 0, 2);
-
-    canvas_draw_icon(canvas, 0, 53, &I_ButtonLeft_4x7);
-    canvas_draw_str_aligned(canvas, 7, 54, AlignLeft, AlignTop, "Delete");
-    canvas_draw_icon(canvas, 52, 53, &I_ButtonBACK_10x8);
-    canvas_draw_str_aligned(canvas, 64, 54, AlignLeft, AlignTop, "Back");
-    canvas_draw_icon(canvas, 100, 53, &I_ButtonRight_4x7);
-    canvas_draw_str_aligned(canvas, 107, 54, AlignLeft, AlignTop, "Post");
-
-    // handle action
-    switch (action)
-    {
-    case ActionNone:
-        break;
-    case ActionBack:
-        flip_social_dialog_stop = true;
-        break;
-    case ActionNext:
-        // send message
-        if (message && app_instance->login_username_logged_in)
-        {
-            // Send the message
-            char command[128];
-            snprintf(command, sizeof(command), "{\"username\":\"%s\",\"content\":\"%s\"}",
-                     app_instance->login_username_logged_in, message);
-
-            bool success = flipper_http_post_request_with_headers(
-                "https://www.flipsocial.net/api/feed/post/",
-                "{\"Content-Type\":\"application/json\"}",
-                command);
-
-            if (!success)
-            {
-                FURI_LOG_E(TAG, "Failed to send HTTP request for feed");
-                furi_check(success); // Log the error with furi_check
-                return;              // Exit early to avoid further errors
-            }
-
-            fhttp.state = RECEIVING;
-            furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        }
-        else
-        {
-            FURI_LOG_E(TAG, "Message or username is NULL");
-            furi_check(false); // Log as an error and return
-            return;
-        }
-
-        int i = 0;
-        while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
-        {
-            // Wait for the feed to be received
-            furi_delay_ms(100);
-
-            char dots_str[64] = "Receiving";
-
-            // Append dots to the string based on the value of i
-            int dot_count = i % 4;
-            int len = strlen(dots_str);
-            snprintf(dots_str + len, sizeof(dots_str) - len, "%.*s", dot_count, "....");
-
-            // Draw the resulting string on the canvas
-            canvas_draw_str(canvas, 0, 30, dots_str);
-
-            i++;
-        }
-        flip_social_dialog_stop = true;
-        furi_timer_stop(fhttp.get_timeout_timer);
-        break;
-    case ActionPrev:
-        // delete message
-        app_instance->pre_saved_messages.messages[flip_social_feed->index] = NULL;
-
-        for (uint32_t i = flip_social_feed->index; i < app_instance->pre_saved_messages.count - 1; i++)
-        {
-            app_instance->pre_saved_messages.messages[i] = app_instance->pre_saved_messages.messages[i + 1];
-        }
-        app_instance->pre_saved_messages.count--;
-
-        // add the item to the submenu
-        submenu_reset(app_instance->submenu_compose);
-
-        submenu_add_item(app_instance->submenu_compose, "Add Pre-Save", FlipSocialSubmenuComposeIndexAddPreSave, flip_social_callback_submenu_choices, app_instance);
-
-        for (uint32_t i = 0; i < app_instance->pre_saved_messages.count; i++)
-        {
-            submenu_add_item(app_instance->submenu_compose, app_instance->pre_saved_messages.messages[i], FlipSocialSubemnuComposeIndexStartIndex + i, flip_social_callback_submenu_choices, app_instance);
-        }
-
-        // save playlist
-        save_playlist(&app_instance->pre_saved_messages);
-
-        flip_social_dialog_stop = true;
-        break;
-    default:
-        action = ActionNone;
-        break;
-    }
-
-    if (flip_social_dialog_stop)
-    {
-        furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
-        flip_social_dialog_shown = false;
-        flip_social_dialog_stop = false;
-        if (action == ActionNext)
-        {
-            action = ActionNone;
-            view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInFeed);
-        }
-        else if (action == ActionBack)
-        {
-            action = ActionNone;
-            view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
-        }
-        else
-        {
-            action = ActionNone;
-            view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInCompose);
-        }
-    }
-}
-// function to draw the dialog canvas
-static void flip_social_canvas_draw_message(Canvas *canvas, char *user_username, char *user_message, bool is_flipped, bool show_prev, bool show_next, int flip_count)
-{
-    canvas_set_color(canvas, ColorBlack);
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, user_username);
-    canvas_set_font(canvas, FontSecondary);
-
-    char flip_count_str[12];
-    if (flip_count == 1)
-    {
-        snprintf(flip_count_str, sizeof(flip_count_str), "%d Flip", flip_count);
-        canvas_draw_str_aligned(canvas, 106, 54, AlignLeft, AlignTop, flip_count_str);
-    }
-    else
-    {
-        snprintf(flip_count_str, sizeof(flip_count_str), "%d Flips", flip_count);
-
-        if (flip_count < 10)
-        {
-            canvas_draw_str_aligned(canvas, 100, 54, AlignLeft, AlignTop, flip_count_str);
-        }
-        else if (flip_count < 100)
-        {
-            canvas_draw_str_aligned(canvas, 94, 54, AlignLeft, AlignTop, flip_count_str);
-        }
-        else
-        {
-            canvas_draw_str_aligned(canvas, 88, 54, AlignLeft, AlignTop, flip_count_str);
-        }
-    }
-
-    draw_user_message(canvas, user_message, 0, 12);
-
-    // combine and shift icons/labels around if not show_prev or show_next
-    if (show_prev && show_next && !is_flipped)
-    {
-        canvas_draw_icon(canvas, 0, 54, &I_ButtonLeft_4x7);
-        canvas_draw_str_aligned(canvas, 6, 54, AlignLeft, AlignTop, "Prev");
-        canvas_draw_icon(canvas, 30, 54, &I_ButtonRight_4x7);
-        canvas_draw_str_aligned(canvas, 36, 54, AlignLeft, AlignTop, "Next");
-        canvas_draw_icon(canvas, 58, 54, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 67, 54, AlignLeft, AlignTop, "Flip");
-    }
-    else if (show_prev && !show_next && !is_flipped)
-    {
-        canvas_draw_icon(canvas, 0, 54, &I_ButtonLeft_4x7);
-        canvas_draw_str_aligned(canvas, 6, 54, AlignLeft, AlignTop, "Prev");
-        canvas_draw_icon(canvas, 28, 54, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 37, 54, AlignLeft, AlignTop, "Flip");
-    }
-    else if (!show_prev && show_next && !is_flipped)
-    {
-        canvas_draw_icon(canvas, 0, 54, &I_ButtonRight_4x7);
-        canvas_draw_str_aligned(canvas, 6, 54, AlignLeft, AlignTop, "Next");
-        canvas_draw_icon(canvas, 28, 54, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 37, 54, AlignLeft, AlignTop, "Flip");
-    }
-    else if (show_prev && show_next && is_flipped)
-    {
-        canvas_draw_icon(canvas, 0, 54, &I_ButtonLeft_4x7);
-        canvas_draw_str_aligned(canvas, 6, 54, AlignLeft, AlignTop, "Prev");
-        canvas_draw_icon(canvas, 28, 54, &I_ButtonRight_4x7);
-        canvas_draw_str_aligned(canvas, 34, 54, AlignLeft, AlignTop, "Next");
-        canvas_draw_icon(canvas, 54, 54, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 63, 54, AlignLeft, AlignTop, "UnFlip");
-    }
-    else if (show_prev && !show_next && is_flipped)
-    {
-        canvas_draw_icon(canvas, 0, 54, &I_ButtonLeft_4x7);
-        canvas_draw_str_aligned(canvas, 6, 54, AlignLeft, AlignTop, "Prev");
-        canvas_draw_icon(canvas, 28, 54, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 37, 54, AlignLeft, AlignTop, "UnFlip");
-    }
-    else if (!show_prev && show_next && is_flipped)
-    {
-        canvas_draw_icon(canvas, 0, 54, &I_ButtonRight_4x7);
-        canvas_draw_str_aligned(canvas, 6, 54, AlignLeft, AlignTop, "Next");
-        canvas_draw_icon(canvas, 28, 54, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 37, 54, AlignLeft, AlignTop, "UnFlip");
-    }
-    else if (!show_prev && !show_next && is_flipped)
-    {
-        canvas_draw_icon(canvas, 0, 54, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 9, 54, AlignLeft, AlignTop, "UnFlip");
-    }
-    else
-    {
-        canvas_draw_icon(canvas, 0, 54, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 9, 54, AlignLeft, AlignTop, "Flip");
-    }
-}
-// Callback function to handle the feed dialog
-static void flip_social_callback_draw_feed(Canvas *canvas, void *model)
-{
-    UNUSED(model);
-    if (!canvas)
-    {
-        FURI_LOG_E(TAG, "Canvas is NULL");
-        return;
-    }
-    if (!app_instance)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-
-    if (!flip_social_dialog_shown)
-    {
-        flip_social_dialog_shown = true;
-        app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
-        app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
-    }
-
-    // handle action
-    switch (action)
-    {
-    case ActionNone:
-        flip_social_canvas_draw_message(canvas, flip_social_feed->usernames[flip_social_feed->index], flip_social_feed->messages[flip_social_feed->index], flip_social_feed->is_flipped[flip_social_feed->index], flip_social_feed->index > 0, flip_social_feed->index < flip_social_feed->count - 1, flip_social_feed->flips[flip_social_feed->index]);
-        break;
-    case ActionNext:
-        canvas_clear(canvas);
-        if (flip_social_feed->index < flip_social_feed->count - 1)
-        {
-            flip_social_feed->index++;
-        }
-        flip_social_canvas_draw_message(canvas, flip_social_feed->usernames[flip_social_feed->index], flip_social_feed->messages[flip_social_feed->index], flip_social_feed->is_flipped[flip_social_feed->index], flip_social_feed->index > 0, flip_social_feed->index < flip_social_feed->count - 1, flip_social_feed->flips[flip_social_feed->index]);
-        action = ActionNone;
-        break;
-    case ActionPrev:
-        canvas_clear(canvas);
-        if (flip_social_feed->index > 0)
-        {
-            flip_social_feed->index--;
-        }
-        flip_social_canvas_draw_message(canvas, flip_social_feed->usernames[flip_social_feed->index], flip_social_feed->messages[flip_social_feed->index], flip_social_feed->is_flipped[flip_social_feed->index], flip_social_feed->index > 0, flip_social_feed->index < flip_social_feed->count - 1, flip_social_feed->flips[flip_social_feed->index]);
-        action = ActionNone;
-        break;
-    case ActionFlip:
-        canvas_clear(canvas);
-        // Moved to above the is_flipped check
-        if (!flip_social_feed->is_flipped[flip_social_feed->index])
-        {
-            // increase the flip count
-            flip_social_feed->flips[flip_social_feed->index]++;
-        }
-        else
-        {
-            // decrease the flip count
-            flip_social_feed->flips[flip_social_feed->index]--;
-        }
-        // change the flip status
-        flip_social_feed->is_flipped[flip_social_feed->index] = !flip_social_feed->is_flipped[flip_social_feed->index];
-        // send post request to flip the message
-        if (app_instance->login_username_logged_in == NULL)
-        {
-            FURI_LOG_E(TAG, "Username is NULL");
-            return;
-        }
-        char payload[256];
-        snprintf(payload, sizeof(payload), "{\"username\":\"%s\",\"post_id\":\"%u\"}", app_instance->login_username_logged_in, flip_social_feed->ids[flip_social_feed->index]);
-        flipper_http_post_request_with_headers("https://www.flipsocial.net/api/feed/flip/", "{\"Content-Type\":\"application/json\"}", payload);
-        flip_social_canvas_draw_message(canvas, flip_social_feed->usernames[flip_social_feed->index], flip_social_feed->messages[flip_social_feed->index], flip_social_feed->is_flipped[flip_social_feed->index], flip_social_feed->index > 0, flip_social_feed->index < flip_social_feed->count - 1, flip_social_feed->flips[flip_social_feed->index]);
-        action = ActionNone;
-        break;
-    case ActionBack:
-        canvas_clear(canvas);
-        flip_social_dialog_stop = true;
-        flip_social_feed->index = 0;
-        action = ActionNone;
-        break;
-    default:
-        break;
-    }
-
-    if (flip_social_dialog_stop)
-    {
-        furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
-        flip_social_dialog_shown = false;
-        flip_social_dialog_stop = false;
-        action = ActionNone;
-    }
-}
-/**
- * @brief Navigation callback for asynchonously handling the login process.
- * @param canvas The canvas to draw on.
- * @param model The model - unused
- * @return void
- */
-static void flip_social_callback_draw_login(Canvas *canvas, void *model)
-{
-    UNUSED(model);
-    if (!canvas)
-    {
-        FURI_LOG_E(TAG, "Canvas is NULL");
-        return;
-    }
-
-    canvas_set_font(canvas, FontSecondary);
-
-    if (!flip_social_board_is_active(canvas))
-    {
-        return;
-    }
-
-    canvas_draw_str(canvas, 0, 7, "Logging in...");
-
-    // Perform login request
-    if (!flip_social_sent_login_request)
-    {
-
-        if (!app_instance->login_username_logged_out || !app_instance->login_password_logged_out || strlen(app_instance->login_username_logged_out) == 0 || strlen(app_instance->login_password_logged_out) == 0)
-        {
-            canvas_clear(canvas);
-            canvas_draw_str(canvas, 0, 10, "Please enter your credentials.");
-            canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
-            return;
-        }
-
-        flip_social_sent_login_request = true;
-
-        char buffer[256];
-        snprintf(buffer, sizeof(buffer), "{\"username\":\"%s\",\"password\":\"%s\"}", app_instance->login_username_logged_out, app_instance->login_password_logged_out);
-        flip_social_login_success = flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/login/", "{\"Content-Type\":\"application/json\"}", buffer);
-        if (flip_social_login_success)
-        {
-            fhttp.state = RECEIVING;
-            return;
-        }
-        else
-        {
-            fhttp.state = ISSUE;
-            return;
-        }
-    }
-    // handle response
-    if (flip_social_sent_login_request && flip_social_login_success)
-    {
-        canvas_set_font(canvas, FontSecondary);
-        canvas_draw_str(canvas, 0, 17, "Request Sent!");
-        canvas_draw_str(canvas, 0, 32, "Awaiting reponse...");
-
-        if (fhttp.state == IDLE && fhttp.received_data != NULL)
-        {
-            // read response
-            if (strstr(fhttp.received_data, "[SUCCESS]") != NULL || strstr(fhttp.received_data, "User found") != NULL)
-            {
-                canvas_draw_str(canvas, 0, 42, "Login successful!");
-                canvas_draw_str(canvas, 0, 62, "Welcome back!");
-
-                app_instance->is_logged_in = "true";
-
-                // set the logged_in_username and change_password_logged_in
-                if (app_instance->login_username_logged_out)
-                {
-                    strcpy(app_instance->login_username_logged_in, app_instance->login_username_logged_out);
-                }
-                if (app_instance->login_password_logged_out)
-                {
-                    app_instance->change_password_logged_in = app_instance->login_password_logged_out;
-                }
-
-                save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-                // send user to the logged in submenu
-                view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
-            }
-            else if (strstr(fhttp.received_data, "User not found") != NULL)
-            {
-                canvas_clear(canvas);
-                canvas_draw_str(canvas, 0, 10, "Account not found...");
-                canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
-            }
-            else
-            {
-                flip_social_handle_error(canvas);
-            }
-        }
-        else if ((fhttp.state == ISSUE || fhttp.state == INACTIVE) && fhttp.received_data != NULL)
-        {
-            flip_social_handle_error(canvas);
-        }
-        else if (fhttp.state == IDLE && fhttp.received_data == NULL)
-        {
-            flip_social_handle_error(canvas);
-        }
-    }
-    else if (flip_social_sent_login_request && !flip_social_login_success)
-    {
-        canvas_clear(canvas);
-        canvas_draw_str(canvas, 0, 10, "Failed sending request.");
-        canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
-        canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
-    }
-}
-
-/**
- * @brief Navigation callback for asynchonously handling the register process.
- * @param canvas The canvas to draw on.
- * @param model The model - unused
- * @return void
- */
-static void flip_social_callback_draw_register(Canvas *canvas, void *model)
-{
-    UNUSED(model);
-    if (!canvas)
-    {
-        FURI_LOG_E(TAG, "Canvas is NULL");
-        return;
-    }
-
-    canvas_set_font(canvas, FontSecondary);
-
-    if (!flip_social_board_is_active(canvas))
-    {
-        return;
-    }
-
-    canvas_draw_str(canvas, 0, 7, "Registering...");
-
-    // Perform login request
-    if (!flip_social_sent_register_request)
-    {
-        // check if the username and password are valid
-        if (!app_instance->register_username_logged_out || !app_instance->register_password_logged_out || strlen(app_instance->register_username_logged_out) == 0 || strlen(app_instance->register_password_logged_out) == 0)
-        {
-            canvas_clear(canvas);
-            canvas_draw_str(canvas, 0, 10, "Please enter your credentials.");
-            canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
-            return;
-        }
-
-        // check if both passwords match
-        if (strcmp(app_instance->register_password_logged_out, app_instance->register_password_2_logged_out) != 0)
-        {
-            canvas_clear(canvas);
-            canvas_draw_str(canvas, 0, 10, "Passwords do not match.");
-            canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
-            return;
-        }
-
-        char buffer[128];
-        snprintf(buffer, sizeof(buffer), "{\"username\":\"%s\",\"password\":\"%s\"}", app_instance->register_username_logged_out, app_instance->register_password_logged_out);
-        flip_social_register_success = flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/register/", "{\"Content-Type\":\"application/json\"}", buffer);
-
-        flip_social_sent_register_request = true;
-        if (flip_social_register_success)
-        {
-            // Set the state to RECEIVING to ensure we continue to see the receiving message
-            fhttp.state = RECEIVING;
-        }
-        else
-        {
-            fhttp.state = ISSUE;
-        }
-    }
-    // handle response
-    if (flip_social_sent_register_request && flip_social_register_success)
-    {
-        canvas_set_font(canvas, FontSecondary);
-        canvas_draw_str(canvas, 0, 17, "Request Sent!");
-        canvas_draw_str(canvas, 0, 32, "Awaiting reponse...");
-
-        if (fhttp.state == IDLE)
-        {
-            // read response
-            if (fhttp.received_data != NULL && (strstr(fhttp.received_data, "[SUCCESS]") != NULL || strstr(fhttp.received_data, "User created") != NULL))
-            {
-                canvas_draw_str(canvas, 0, 42, "Registeration successful!");
-                canvas_draw_str(canvas, 0, 62, "Welcome to FlipSocial!");
-
-                // set the login credentials
-                if (app_instance->login_username_logged_out)
-                {
-                    app_instance->login_username_logged_out = app_instance->register_username_logged_out;
-                }
-                if (app_instance->login_password_logged_out)
-                {
-                    app_instance->login_password_logged_out = app_instance->register_password_logged_out;
-                    app_instance->change_password_logged_in = app_instance->register_password_logged_out;
-                }
-                if (app_instance->login_username_logged_in)
-                {
-                    app_instance->login_username_logged_in = app_instance->register_username_logged_out;
-                }
-
-                app_instance->is_logged_in = "true";
-
-                // save the credentials
-                save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
-
-                // send user to the logged in submenu
-                view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
-            }
-            else if (strstr(fhttp.received_data, "Username or password not provided") != NULL)
-            {
-                canvas_clear(canvas);
-                canvas_draw_str(canvas, 0, 10, "Please enter your credentials.");
-                canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
-            }
-            else if (strstr(fhttp.received_data, "User already exists") != NULL || strstr(fhttp.received_data, "Multiple users found") != NULL)
-            {
-                canvas_draw_str(canvas, 0, 42, "Registration failed...");
-                canvas_draw_str(canvas, 0, 52, "Username already exists.");
-                canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
-            }
-            else
-            {
-                canvas_draw_str(canvas, 0, 42, "Registration failed...");
-                canvas_draw_str(canvas, 0, 52, "Update your credentials.");
-                canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
-            }
-        }
-        else if (fhttp.state == ISSUE || fhttp.state == INACTIVE)
-        {
-            flip_social_handle_error(canvas);
-        }
-    }
-    else if (flip_social_sent_register_request && !flip_social_register_success)
-    {
-        canvas_clear(canvas);
-        canvas_draw_str(canvas, 0, 10, "Failed sending request.");
-        canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
-        canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
-    }
-}
-
-// function to draw the dialog canvas
-static void flip_social_canvas_draw_explore(Canvas *canvas, char *user_username, char *content)
-{
-    canvas_set_color(canvas, ColorBlack);
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, user_username);
-    canvas_set_font(canvas, FontSecondary);
-
-    draw_user_message(canvas, content, 0, 12);
-
-    canvas_set_font(canvas, FontSecondary);
-    canvas_draw_icon(canvas, 0, 53, &I_ButtonLeft_4x7);
-    canvas_draw_str_aligned(canvas, 9, 54, AlignLeft, AlignTop, "Remove");
-    canvas_draw_icon(canvas, 98, 53, &I_ButtonRight_4x7);
-    canvas_draw_str_aligned(canvas, 107, 54, AlignLeft, AlignTop, "Add");
-
-    if (strlen(content) > 0)
-    {
-        last_explore_response = content;
-    }
-}
-
-// Callback function to handle the explore dialog
-static void flip_social_callback_draw_explore(Canvas *canvas, void *model)
-{
-    UNUSED(model);
-    if (!canvas)
-    {
-        FURI_LOG_E(TAG, "Canvas is NULL");
-        return;
-    }
-    if (!app_instance)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-
-    if (!flip_social_dialog_shown)
-    {
-        flip_social_dialog_shown = true;
-        app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
-        app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
-    }
-    flip_social_canvas_draw_explore(canvas, flip_social_explore->usernames[flip_social_explore->index], last_explore_response);
-
-    // handle action
-    switch (action)
-    {
-    case ActionNext:
-        // add friend
-        char add_payload[128];
-        snprintf(add_payload, sizeof(add_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, flip_social_explore->usernames[flip_social_explore->index]);
-        flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/add-friend/", "{\"Content-Type\":\"application/json\"}", add_payload);
-        canvas_clear(canvas);
-        flip_social_canvas_draw_explore(canvas, flip_social_explore->usernames[flip_social_explore->index], "Added!");
-        action = ActionNone;
-        break;
-    case ActionPrev:
-        // remove friend
-        char remove_payload[128];
-        snprintf(remove_payload, sizeof(remove_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, flip_social_explore->usernames[flip_social_explore->index]);
-        flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/remove-friend/", "{\"Content-Type\":\"application/json\"}", remove_payload);
-        canvas_clear(canvas);
-        flip_social_canvas_draw_explore(canvas, flip_social_explore->usernames[flip_social_explore->index], "Removed!");
-        action = ActionNone;
-        break;
-    case ActionBack:
-        canvas_clear(canvas);
-        flip_social_dialog_stop = true;
-        last_explore_response = "";
-        flip_social_dialog_shown = false;
-        flip_social_explore->index = 0;
-        action = ActionNone;
-        break;
-    default:
-        break;
-    }
-
-    if (flip_social_dialog_stop)
-    {
-        furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
-        flip_social_dialog_shown = false;
-        flip_social_dialog_stop = false;
-        action = ActionNone;
-    }
-}
-
-// Callback function to handle the friends dialog
-static void flip_social_callback_draw_friends(Canvas *canvas, void *model)
-{
-    UNUSED(model);
-    if (!canvas)
-    {
-        FURI_LOG_E(TAG, "Canvas is NULL");
-        return;
-    }
-    if (!app_instance)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-
-    if (!flip_social_dialog_shown)
-    {
-        flip_social_dialog_shown = true;
-        app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
-        app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
-    }
-    flip_social_canvas_draw_explore(canvas, flip_social_friends->usernames[flip_social_friends->index], last_explore_response);
-
-    // handle action
-    switch (action)
-    {
-    case ActionNext:
-        // add friend
-        char add_payload[128];
-        snprintf(add_payload, sizeof(add_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, flip_social_friends->usernames[flip_social_friends->index]);
-        if (flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/add-friend/", "{\"Content-Type\":\"application/json\"}", add_payload))
-        {
-            canvas_clear(canvas);
-            flip_social_canvas_draw_explore(canvas, flip_social_friends->usernames[flip_social_friends->index], "Added!");
-
-            // add the friend to the friends list
-            flip_social_friends->usernames[flip_social_friends->count] = flip_social_friends->usernames[flip_social_friends->index];
-            flip_social_friends->count++;
-            if (!flip_social_update_friends())
-            {
-                FURI_LOG_E(TAG, "Failed to update friends");
-            }
-        }
-        action = ActionNone;
-        break;
-    case ActionPrev:
-        // remove friend
-        char remove_payload[128];
-        snprintf(remove_payload, sizeof(remove_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, flip_social_friends->usernames[flip_social_friends->index]);
-        if (flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/remove-friend/", "{\"Content-Type\":\"application/json\"}", remove_payload))
-        {
-            canvas_clear(canvas);
-            flip_social_canvas_draw_explore(canvas, flip_social_friends->usernames[flip_social_friends->index], "Removed!");
-
-            // remove the friend from the friends list
-            for (int i = flip_social_friends->index; i < flip_social_friends->count - 1; i++)
-            {
-                flip_social_friends->usernames[i] = flip_social_friends->usernames[i + 1];
-            }
-            flip_social_friends->count--;
-            if (!flip_social_update_friends())
-            {
-                FURI_LOG_E(TAG, "Failed to update friends");
-            }
-        }
-        action = ActionNone;
-        break;
-    case ActionBack:
-        canvas_clear(canvas);
-        flip_social_dialog_stop = true;
-        last_explore_response = "";
-        flip_social_dialog_shown = false;
-        flip_social_friends->index = 0;
-        action = ActionNone;
-        break;
-    default:
-        break;
-    }
-
-    if (flip_social_dialog_stop)
-    {
-        furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
-        flip_social_dialog_shown = false;
-        flip_social_dialog_stop = false;
-        action = ActionNone;
-    }
-}
-
-static void flip_social_canvas_draw_user_message(Canvas *canvas, char *user_username, char *user_message, bool show_prev, bool show_next)
-{
-    canvas_set_color(canvas, ColorBlack);
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, user_username);
-    canvas_set_font(canvas, FontSecondary);
-
-    draw_user_message(canvas, user_message, 0, 12);
-
-    canvas_set_font(canvas, FontSecondary);
-    if (show_prev)
-    {
-        canvas_draw_icon(canvas, 0, 53, &I_ButtonLeft_4x7);
-        canvas_draw_str_aligned(canvas, 9, 54, AlignLeft, AlignTop, "Prev");
-    }
-
-    canvas_draw_icon(canvas, 47, 53, &I_ButtonOK_7x7);
-    canvas_draw_str_aligned(canvas, 56, 54, AlignLeft, AlignTop, "Create");
-
-    if (show_next)
-    {
-        canvas_draw_icon(canvas, 98, 53, &I_ButtonRight_4x7);
-        canvas_draw_str_aligned(canvas, 107, 54, AlignLeft, AlignTop, "Next");
-    }
-}
-
-// Callback function to handle the messages dialog
-static void flip_social_callback_draw_messages(Canvas *canvas, void *model)
-{
-    UNUSED(model);
-    if (!canvas)
-    {
-        FURI_LOG_E(TAG, "Canvas is NULL");
-        return;
-    }
-    if (!app_instance)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-
-    if (!flip_social_dialog_shown)
-    {
-        flip_social_dialog_shown = true;
-        app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
-        app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
-    }
-
-    // handle action
-    switch (action)
-    {
-    case ActionNone:
-        flip_social_canvas_draw_user_message(canvas, flip_social_messages->usernames[flip_social_messages->index], flip_social_messages->messages[flip_social_messages->index], flip_social_messages->index > 0, flip_social_messages->index < flip_social_messages->count - 1);
-        action = ActionNone;
-        break;
-    case ActionNext:
-        // view next message (if any)
-        canvas_clear(canvas);
-        if (flip_social_messages->index < flip_social_messages->count - 1)
-        {
-            flip_social_messages->index++;
-        }
-        flip_social_canvas_draw_user_message(canvas, flip_social_messages->usernames[flip_social_messages->index], flip_social_messages->messages[flip_social_messages->index], flip_social_messages->index > 0, flip_social_messages->index < flip_social_messages->count - 1);
-        action = ActionNone;
-        break;
-    case ActionPrev:
-        // view previous message (if any)
-        canvas_clear(canvas);
-        if (flip_social_messages->index > 0)
-        {
-            flip_social_messages->index--;
-        }
-        flip_social_canvas_draw_user_message(canvas, flip_social_messages->usernames[flip_social_messages->index], flip_social_messages->messages[flip_social_messages->index], flip_social_messages->index > 0, flip_social_messages->index < flip_social_messages->count - 1);
-        action = ActionNone;
-        break;
-    case ActionBack:
-        //  go back to the previous view
-        flip_social_dialog_stop = true;
-        action = ActionNone;
-        break;
-    case ActionFlip:
-        // go to the input view
-        flip_social_dialog_stop = true;
-        break;
-    default:
-        action = ActionNone;
-        break;
-    }
-
-    if (flip_social_dialog_stop)
-    {
-        furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
-        flip_social_dialog_shown = false;
-        flip_social_dialog_stop = false;
-        if (action == ActionFlip)
-        {
-            action = ActionNone;
-            view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInMessagesNewMessageInput);
-        }
-        else
-        {
-            action = ActionNone;
-            view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInMessagesSubmenu);
-        }
-    }
-}
-
-#endif // FLIP_SOCIAL_DRAW_H

+ 0 - 310
flip_social_e.h

@@ -1,310 +0,0 @@
-// flip_social_e.h
-#ifndef FLIP_SOCIAL_E
-#define FLIP_SOCIAL_E
-#include <easy_flipper.h>
-#include <dialogs/dialogs.h>
-#include <storage/storage.h>
-#include <flipper_http.h>
-#include <input/input.h>
-#include <flip_social_icons.h>
-#define TAG "FlipSocial"
-
-#define MAX_PRE_SAVED_MESSAGES 25 // Maximum number of pre-saved messages
-#define MAX_MESSAGE_LENGTH 100    // Maximum length of a message in the feed
-#define MAX_EXPLORE_USERS 50      // Maximum number of users to explore
-#define MAX_USER_LENGTH 32        // Maximum length of a username
-#define MAX_FRIENDS 50            // Maximum number of friends
-#define MAX_TOKENS 450            // Adjust based on expected JSON tokens
-#define MAX_FEED_ITEMS 41         // Maximum number of feed items
-#define MAX_LINE_LENGTH 30
-#define MAX_MESSAGE_USERS 20 // Maximum number of users to display in the submenu
-#define MAX_MESSAGES 20      // Maximum number of meesages between each user
-
-// Define the submenu items for our Hello World application
-typedef enum
-{
-    FlipSocialSubmenuLoggedOutIndexLogin,        // click to go to the login screen
-    FlipSocialSubmenuLoggedOutIndexRegister,     // click to go to the register screen
-    FlipSocialSubmenuLoggedOutIndexAbout,        // click to go to the about screen
-    FlipSocialSubmenuLoggedOutIndexWifiSettings, // click to go to the wifi settings screen
-    //
-    FlipSocialSubmenuLoggedInIndexProfile,  // click to go to the profile screen
-    FlipSocialSubmenuExploreIndex,          // click to go to the explore
-    FlipSocialSubmenuLoggedInIndexFeed,     // click to go to the feed screen
-    FlipSocialSubmenuLoggedInIndexMessages, // click to go to the messages screen
-    FlipSocialSubmenuLoggedInIndexCompose,  // click to go to the compose screen
-    FlipSocialSubmenuLoggedInIndexSettings, // click to go to the settings screen
-    FlipSocialSubmenuLoggedInSignOutButton, // click to sign out
-    //
-    FlipSocialSubmenuLoggedInIndexMessagesNewMessage, // click to add a new message
-    //
-    FlipSocialSubmenuComposeIndexAddPreSave,       // click to add a pre-saved message
-    FlipSocialSubemnuComposeIndexStartIndex = 100, // starting index for the first pre saved message
-    //
-    FlipSocialSubmenuExploreIndexStartIndex = 150, // starting index for the users to explore
-    //
-    FlipSocialSubmenuLoggedInIndexFriendsStart = 200, // starting index for the friends
-    //
-    FlipSocialSubmenuLoggedInIndexMessagesUsersStart = 250, // starting index for the messages
-    //
-    FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart = 300, // click to select a user to message
-} FlipSocialSubmenuIndex;
-
-typedef enum
-{
-    ActionNone,
-    ActionBack,
-    ActionNext,
-    ActionPrev,
-    ActionFlip,
-} Action;
-
-static Action action = ActionNone;
-
-// Define the ScriptPlaylist structure
-typedef struct
-{
-    char *messages[MAX_PRE_SAVED_MESSAGES];
-    size_t count;
-} PreSavedPlaylist;
-
-typedef struct
-{
-    char *usernames[MAX_FEED_ITEMS];
-    char *messages[MAX_FEED_ITEMS];
-    bool is_flipped[MAX_FEED_ITEMS];
-    int ids[MAX_FEED_ITEMS];
-    int flips[MAX_FEED_ITEMS];
-    size_t count;
-    size_t index;
-} FlipSocialFeed;
-
-typedef struct
-{
-    char *usernames[MAX_EXPLORE_USERS];
-    int count;
-    int index;
-} FlipSocialModel;
-
-typedef struct
-{
-    char *usernames[MAX_MESSAGE_USERS];
-    int count;
-    int index;
-} FlipSocialModel2;
-
-typedef struct
-{
-    char *usernames[MAX_MESSAGES];
-    char *messages[MAX_MESSAGES];
-    int count;
-    int index;
-} FlipSocialMessage;
-
-// Define views for our Hello World application
-typedef enum
-{
-    FlipSocialViewLoggedOutSubmenu,      // The menu if the user is not logged in
-    FlipSocialViewLoggedOutLogin,        // The login screen
-    FlipSocialViewLoggedOutRegister,     // The register screen
-    FlipSocialViewLoggedOutAbout,        // The about screen
-    FlipSocialViewLoggedOutWifiSettings, // The wifi settings screen
-    //
-    FlipSocialViewLoggedOutLoginUsernameInput,        // Text input screen for username input on login screen
-    FlipSocialViewLoggedOutLoginPasswordInput,        // Text input screen for password input on login screen
-    FlipSocialViewLoggedOutRegisterUsernameInput,     // Text input screen for username input on register screen
-    FlipSocialViewLoggedOutRegisterPasswordInput,     // Text input screen for password input on register screen
-    FlipSocialViewLoggedOutRegisterPassword2Input,    // Text input screen for password 2 input on register screen
-    FlipSocialViewLoggedOutWifiSettingsSSIDInput,     // Text input screen for SSID input on wifi screen
-    FlipSocialViewLoggedOutWifiSettingsPasswordInput, // Text input screen for Password input on wifi screen
-    FlipSocialViewLoggedOutProcessLogin,              // The screen displayed after clicking login
-    FlipSocialViewLoggedOutProcessRegister,           // The screen displayed after clicking register
-    //
-    FlipSocialViewLoggedInSubmenu,  // The menu if the user is logged in
-    FlipSocialViewLoggedInProfile,  // The profile screen
-    FlipSocialViewLoggedInFeed,     // The feed screen
-    FlipSocialViewLoggedInCompose,  // The compose screen
-    FlipSocialViewLoggedInSettings, // The settings screen
-    //
-    FlipSocialViewLoggedInChangePasswordInput,    // Text input screen for password input on change password screen
-    FlipSocialViewLoggedInComposeAddPreSaveInput, // Text input screen for add text input on compose screen
-    //
-    FlipSocialViewLoggedInMessagesNewMessageInput,            // Text input screen for new message input on messages screen
-    FlipSocialViewLoggedInMessagesNewMessageUserChoicesInput, // Text input screen for new message input on messages screen
-    FlipSocialViewLoggedInMessagesUserChoices,                // the view after clicking [New Message] - select a user to message, then direct to input view
-    //
-    FlipSocialViewLoggedInSettingsAbout,             // The about screen
-    FlipSocialViewLoggedInSettingsWifi,              // The wifi settings screen
-    FlipSocialViewLoggedInWifiSettingsSSIDInput,     // Text input screen for SSID input on wifi screen
-    FlipSocialViewLoggedInWifiSettingsPasswordInput, // Text input screen for Password input on wifi screen
-    FlipSocialViewLoggedInProcessCompose,            // The dialog view to delete or send the clicked pre-saved text
-    //
-    FlipSocialViewLoggedInSignOut, // The view after clicking the sign out button
-    //
-    FlipSocialViewLoggedInExploreSubmenu,  // The view after clicking the explore button
-    FlipSocialViewLoggedInExploreProccess, // The view after clicking on a user in the explore screen
-    FlipSocialViewLoggedInFriendsSubmenu,  // The view after clicking the friends button on the profile screen
-    FlipSocialViewLoggedInFriendsProcess,  // The view after clicking on a friend in the friends screen
-    FlipSocialViewLoggedInMessagesSubmenu, // The view after clicking the messages button on the profile screen
-    FlipSocialViewLoggedInMessagesProcess, // The view after clicking on a user in the messages screen
-} FlipSocialView;
-
-// Define the application structure
-typedef struct
-{
-    ViewDispatcher *view_dispatcher;        // Switches between our views
-    Submenu *submenu_logged_out;            // The application submenu (logged out)
-    Submenu *submenu_logged_in;             // The application submenu (logged in)
-    Submenu *submenu_compose;               // The application submenu (compose)
-    Submenu *submenu_explore;               // The application submenu (explore)
-    Submenu *submenu_friends;               // The application submenu (friends)
-    Submenu *submenu_messages;              // The application submenu (messages)
-    Submenu *submenu_messages_user_choices; // The application submenu (messages user choices)
-    Widget *widget_logged_out_about;        // The about screen (logged out)
-    Widget *widget_logged_in_about;         // The about screen (logged in)
-
-    View *view_process_login;    // The screen displayed after clicking login
-    View *view_process_register; // The screen displayed after clicking register
-    View *view_process_feed;     // Dialog for the feed screen
-    View *view_process_compose;  // Dialog for the compose screen (delete or send)
-    View *view_process_explore;  // Dialog for the explore screen (view user profile - add or delete friend)
-    View *view_process_friends;  // Dialog for the friends screen (view user profile - add or delete friend)
-    View *view_process_messages; // Dialog for the messages screen (next, previous, send message)
-
-    VariableItemList *variable_item_list_logged_out_wifi_settings; // The wifi settings menu
-    VariableItemList *variable_item_list_logged_out_login;         // The login menu
-    VariableItemList *variable_item_list_logged_out_register;      // The register menu
-    //
-    VariableItemList *variable_item_list_logged_in_profile;       // The profile menu
-    VariableItemList *variable_item_list_logged_in_settings;      // The settings menu
-    VariableItemList *variable_item_list_logged_in_settings_wifi; // The wifi settings menu
-
-    UART_TextInput *text_input_logged_out_wifi_settings_ssid;     // Text input for ssid input on wifi settings screen
-    UART_TextInput *text_input_logged_out_wifi_settings_password; // Text input for password input on wifi settings screen
-    UART_TextInput *text_input_logged_out_login_username;         // Text input for username input on login screen
-    UART_TextInput *text_input_logged_out_login_password;         // Text input for password input on login screen
-    UART_TextInput *text_input_logged_out_register_username;      // Text input for username input on register screen
-    UART_TextInput *text_input_logged_out_register_password;      // Text input for password input on register screen
-    UART_TextInput *text_input_logged_out_register_password_2;    // Text input for password 2 input on register screen
-    //
-    UART_TextInput *text_input_logged_in_change_password;        // Text input for password input on change password screen
-    UART_TextInput *text_input_logged_in_compose_pre_save_input; // Text input for pre save input on compose screen
-    UART_TextInput *text_input_logged_in_wifi_settings_ssid;     // Text input for ssid input on wifi settings screen
-    UART_TextInput *text_input_logged_in_wifi_settings_password; // Text input for password input on wifi settings screen
-    //
-    UART_TextInput *text_input_logged_in_messages_new_message;              // Text input for new message input on messages screen
-    UART_TextInput *text_input_logged_in_messages_new_message_user_choices; //
-
-    VariableItem *variable_item_logged_out_wifi_settings_ssid;     // Reference to the ssid configuration item
-    VariableItem *variable_item_logged_out_wifi_settings_password; // Reference to the password configuration item
-    VariableItem *variable_item_logged_out_login_username;         // Reference to the username configuration item
-    VariableItem *variable_item_logged_out_login_password;         // Reference to the password configuration item
-    VariableItem *variable_item_logged_out_login_button;           // Reference to the login button configuration item
-    VariableItem *variable_item_logged_out_register_username;      // Reference to the username configuration item
-    VariableItem *variable_item_logged_out_register_password;      // Reference to the password configuration item
-    VariableItem *variable_item_logged_out_register_password_2;    // Reference to the password 2 configuration item
-    VariableItem *variable_item_logged_out_register_button;        // Reference to the register button configuration item
-    //
-    VariableItem *variable_item_logged_in_profile_username;        // Reference to the username configuration item
-    VariableItem *variable_item_logged_in_profile_change_password; // Reference to the change password configuration item
-    VariableItem *variable_item_logged_in_settings_about;          // Reference to the about configuration item
-    VariableItem *variable_item_logged_in_settings_wifi;           // Reference to the wifi settings configuration item
-    VariableItem *variable_item_logged_in_wifi_settings_ssid;      // Reference to the ssid configuration item
-    VariableItem *variable_item_logged_in_wifi_settings_password;  // Reference to the password configuration item
-    //
-    VariableItem *variable_item_logged_in_profile_friends; // Reference to the friends configuration item
-    //
-    FuriPubSub *input_event_queue;
-    FuriPubSubSubscription *input_event;
-
-    PreSavedPlaylist pre_saved_messages; // Pre-saved messages for the feed screen
-
-    char *is_logged_in;         // Store the login status
-    uint32_t is_logged_in_size; // Size of the login status buffer
-
-    char *login_username_logged_in;                     // Store the entered login username
-    char *login_username_logged_in_temp_buffer;         // Temporary buffer for login username text input
-    uint32_t login_username_logged_in_temp_buffer_size; // Size of the login username temporary buffer
-
-    char *wifi_ssid_logged_out;                     // Store the entered wifi ssid
-    char *wifi_ssid_logged_out_temp_buffer;         // Temporary buffer for wifi ssid text input
-    uint32_t wifi_ssid_logged_out_temp_buffer_size; // Size of the wifi ssid temporary buffer
-
-    char *wifi_password_logged_out;                     // Store the entered wifi password
-    char *wifi_password_logged_out_temp_buffer;         // Temporary buffer for wifi_password text input
-    uint32_t wifi_password_logged_out_temp_buffer_size; // Size of the wifi_password temporary buffer
-
-    char *login_username_logged_out;                     // Store the entered login username
-    char *login_username_logged_out_temp_buffer;         // Temporary buffer for login username text input
-    uint32_t login_username_logged_out_temp_buffer_size; // Size of the login username temporary buffer
-
-    char *login_password_logged_out;                     // Store the entered login password
-    char *login_password_logged_out_temp_buffer;         // Temporary buffer for login password text input
-    uint32_t login_password_logged_out_temp_buffer_size; // Size of the login password temporary buffer
-
-    char *register_username_logged_out;                     // Store the entered register username
-    char *register_username_logged_out_temp_buffer;         // Temporary buffer for register username text input
-    uint32_t register_username_logged_out_temp_buffer_size; // Size of the register username temporary buffer
-
-    char *register_password_logged_out;                     // Store the entered register password
-    char *register_password_logged_out_temp_buffer;         // Temporary buffer for register password text input
-    uint32_t register_password_logged_out_temp_buffer_size; // Size of the register password temporary buffer
-
-    char *register_password_2_logged_out;                     // Store the entered register password 2
-    char *register_password_2_logged_out_temp_buffer;         // Temporary buffer for register password 2 text input
-    uint32_t register_password_2_logged_out_temp_buffer_size; // Size of the register password 2 temporary buffer
-
-    //
-    char *change_password_logged_in;                     // Store the entered change password
-    char *change_password_logged_in_temp_buffer;         // Temporary buffer for change password text input
-    uint32_t change_password_logged_in_temp_buffer_size; // Size of the change password temporary buffer
-
-    char *compose_pre_save_logged_in;                     // Store the entered add text
-    char *compose_pre_save_logged_in_temp_buffer;         // Temporary buffer for add text text input
-    uint32_t compose_pre_save_logged_in_temp_buffer_size; // Size of the add text temporary buffer
-
-    char *wifi_ssid_logged_in;                     // Store the entered wifi ssid
-    char *wifi_ssid_logged_in_temp_buffer;         // Temporary buffer for wifi ssid text input
-    uint32_t wifi_ssid_logged_in_temp_buffer_size; // Size of the wifi ssid temporary buffer
-
-    char *wifi_password_logged_in;                     // Store the entered wifi password
-    char *wifi_password_logged_in_temp_buffer;         // Temporary buffer for wifi_password text input
-    uint32_t wifi_password_logged_in_temp_buffer_size; // Size of the wifi_password temporary buffer
-
-    //
-    char *messages_new_message_logged_in;                     // Store the entered new message
-    char *messages_new_message_logged_in_temp_buffer;         // Temporary buffer for new message text input
-    uint32_t messages_new_message_logged_in_temp_buffer_size; // Size of the new message temporary buffer
-
-    char *message_user_choice_logged_in;                     // Store the entered message to send to the selected user
-    char *message_user_choice_logged_in_temp_buffer;         // Temporary buffer for message to send to the selected user
-    uint32_t message_user_choice_logged_in_temp_buffer_size; // Size of the message to send to the selected user temporary buffer
-} FlipSocialApp;
-
-static FlipSocialFeed *flip_social_feed = NULL;            // Store the feed
-static FlipSocialModel *flip_social_friends = NULL;        // Store the friends
-static FlipSocialModel2 *flip_social_message_users = NULL; // Store the users that have sent messages to the logged in user
-static FlipSocialModel *flip_social_explore = NULL;        // Store the users to explore
-static FlipSocialMessage *flip_social_messages = NULL;     // Store the messages between the logged in user and the selected user
-
-// include strndup (otherwise NULL pointer dereference)
-char *strndup(const char *s, size_t n)
-{
-    char *result;
-    size_t len = strlen(s);
-
-    if (n < len)
-        len = n;
-
-    result = (char *)malloc(len + 1);
-    if (!result)
-        return NULL;
-
-    result[len] = '\0';
-    return (char *)memcpy(result, s, len);
-}
-
-static FlipSocialApp *app_instance = NULL;
-static void flip_social_logged_in_compose_pre_save_updated(void *context);
-static void flip_social_callback_submenu_choices(void *context, uint32_t index);
-#endif

+ 0 - 141
flip_social_explore.h

@@ -1,141 +0,0 @@
-#ifndef FLIP_SOCIAL_EXPLORE_H
-#define FLIP_SOCIAL_EXPLORE_H
-
-static FlipSocialModel *flip_social_explore_alloc()
-{
-    // Allocate memory for each username only if not already allocated
-    FlipSocialModel *explore = malloc(sizeof(FlipSocialModel));
-    if (explore == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to allocate memory for explore model.");
-        return NULL;
-    }
-    for (size_t i = 0; i < MAX_EXPLORE_USERS; i++)
-    {
-        if (explore->usernames[i] == NULL)
-        {
-            explore->usernames[i] = malloc(MAX_USER_LENGTH);
-            if (explore->usernames[i] == NULL)
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for username %zu", i);
-                return NULL; // Return false on memory allocation failure
-            }
-        }
-    }
-    return explore;
-}
-
-static void flip_social_free_explore()
-{
-    if (!flip_social_explore)
-    {
-        FURI_LOG_E(TAG, "Explore model is NULL");
-        return;
-    }
-    for (int i = 0; i < flip_social_explore->count; i++)
-    {
-        free(flip_social_explore->usernames[i]);
-    }
-}
-
-// for now we're just listing the current users
-// as the feed is upgraded, then we can port more to the explore view
-static bool flip_social_get_explore()
-{
-    // will return true unless the devboard is not connected
-    bool success = flipper_http_get_request_with_headers("https://www.flipsocial.net/api/user/users/", jsmn("Content-Type", "application/json"));
-    if (!success)
-    {
-        FURI_LOG_E(TAG, "Failed to send HTTP request for explore");
-        return false;
-    }
-    fhttp.state = RECEIVING;
-    return true;
-}
-
-static bool flip_social_parse_json_explore()
-{
-    if (fhttp.received_data == NULL)
-    {
-        FURI_LOG_E(TAG, "No data received.");
-        return false;
-    }
-
-    // Allocate memory for each username only if not already allocated
-    flip_social_explore = flip_social_explore_alloc();
-    if (flip_social_explore == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to allocate memory for explore usernames.");
-        return false;
-    }
-
-    // Remove newlines
-    char *pos = fhttp.received_data;
-    while ((pos = strchr(pos, '\n')) != NULL)
-    {
-        *pos = ' ';
-    }
-
-    // Initialize explore count
-    flip_social_explore->count = 0;
-
-    // Extract the users array from the JSON
-    char *json_users = get_json_value("users", fhttp.received_data, MAX_TOKENS);
-    if (json_users == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to parse users array.");
-        return false;
-    }
-
-    // Manual tokenization for comma-separated values
-    char *start = json_users + 1; // Skip the opening bracket
-    char *end;
-    while ((end = strchr(start, ',')) != NULL && flip_social_explore->count < MAX_EXPLORE_USERS)
-    {
-        *end = '\0'; // Null-terminate the current token
-
-        // Remove quotes
-        if (*start == '"')
-            start++;
-        if (*(end - 1) == '"')
-            *(end - 1) = '\0';
-
-        // Copy username to pre-allocated memory
-        strncpy(flip_social_explore->usernames[flip_social_explore->count], start, MAX_USER_LENGTH - 1);
-        flip_social_explore->usernames[flip_social_explore->count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        flip_social_explore->count++;
-        start = end + 1;
-    }
-
-    // Handle the last token
-    if (*start != '\0' && flip_social_explore->count < MAX_EXPLORE_USERS)
-    {
-        if (*start == '"')
-            start++;
-        if (*(start + strlen(start) - 1) == ']')
-            *(start + strlen(start) - 1) = '\0';
-        if (*(start + strlen(start) - 1) == '"')
-            *(start + strlen(start) - 1) = '\0';
-
-        strncpy(flip_social_explore->usernames[flip_social_explore->count], start, MAX_USER_LENGTH - 1);
-        flip_social_explore->usernames[flip_social_explore->count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        flip_social_explore->count++;
-    }
-
-    // Add submenu items for the users
-    submenu_reset(app_instance->submenu_explore);
-    submenu_set_header(app_instance->submenu_explore, "Explore");
-    for (int i = 0; i < flip_social_explore->count; i++)
-    {
-        submenu_add_item(app_instance->submenu_explore, flip_social_explore->usernames[i], FlipSocialSubmenuExploreIndexStartIndex + i, flip_social_callback_submenu_choices, app_instance);
-    }
-
-    // Free the json_users
-    free(json_users);
-    free(start);
-    free(end);
-
-    return true;
-}
-
-#endif // FLIP_SOCIAL_EXPLORE_H

+ 0 - 209
flip_social_feed.h

@@ -1,209 +0,0 @@
-#ifndef FLIP_SOCIAL_FEED_H
-#define FLIP_SOCIAL_FEED_H
-
-// Set failure FlipSocialFeed object
-static bool flip_social_temp_feed()
-{
-    if (flip_social_feed == NULL)
-    {
-        flip_social_feed = malloc(sizeof(FlipSocialFeed));
-        if (flip_social_feed == NULL)
-        {
-            FURI_LOG_E(TAG, "Failed to allocate memory for feed");
-            return false;
-        }
-    }
-    for (int i = 0; i < 3; i++)
-    {
-        if (flip_social_feed->usernames[i] == NULL)
-        {
-            flip_social_feed->usernames[i] = malloc(MAX_USER_LENGTH);
-            if (flip_social_feed->usernames[i] == NULL)
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for username %zu", i);
-                return false;
-            }
-        }
-        if (flip_social_feed->messages[i] == NULL)
-        {
-            flip_social_feed->messages[i] = malloc(MAX_MESSAGE_LENGTH);
-            if (flip_social_feed->messages[i] == NULL)
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for message %zu", i);
-                return false;
-            }
-        }
-    }
-    flip_social_feed->usernames[0] = "JBlanked";
-    flip_social_feed->usernames[1] = "FlipperKing";
-    flip_social_feed->usernames[2] = "FlipperQueen";
-    //
-    flip_social_feed->messages[0] = "Welcome. This is a temp message. Either the feed didn't load or there was a server error.";
-    flip_social_feed->messages[1] = "I am the Chosen Flipper.";
-    flip_social_feed->messages[2] = "No one can flip like me.";
-    //
-    flip_social_feed->is_flipped[0] = true;
-    flip_social_feed->is_flipped[1] = false;
-    flip_social_feed->is_flipped[2] = true;
-    //
-    flip_social_feed->ids[0] = 0;
-    flip_social_feed->ids[1] = 1;
-    flip_social_feed->ids[2] = 2;
-    //
-    flip_social_feed->flips[0] = 51;
-    flip_social_feed->flips[1] = 8;
-    flip_social_feed->flips[2] = 23;
-    //
-    flip_social_feed->count = 3;
-    flip_social_feed->index = 0;
-
-    return true;
-}
-
-// Allocate memory for each feed item if not already allocated
-static FlipSocialFeed *flip_social_feed_alloc()
-{
-    // Initialize the feed
-    FlipSocialFeed *feed = (FlipSocialFeed *)malloc(sizeof(FlipSocialFeed));
-    if (!feed)
-    {
-        FURI_LOG_E(TAG, "Failed to allocate memory for feed");
-        return feed;
-    }
-    for (size_t i = 0; i < MAX_FEED_ITEMS; i++)
-    {
-        if (feed->usernames[i] == NULL)
-        {
-            feed->usernames[i] = malloc(MAX_USER_LENGTH);
-            if (feed->usernames[i] == NULL)
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for username %zu", i);
-                return NULL;
-            }
-        }
-        if (feed->messages[i] == NULL)
-        {
-            feed->messages[i] = malloc(MAX_MESSAGE_LENGTH);
-            if (feed->messages[i] == NULL)
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for message %zu", i);
-                return NULL;
-            }
-        }
-    }
-    return feed;
-}
-
-static void flip_social_free_feed()
-{
-    if (!flip_social_feed)
-    {
-        FURI_LOG_E(TAG, "Feed model is NULL");
-        return;
-    }
-    for (uint32_t i = 0; i < flip_social_feed->count; i++)
-    {
-        free(flip_social_feed->usernames[i]);
-    }
-}
-
-static bool flip_social_get_feed()
-{
-    // Get the feed from the server
-    if (app_instance->login_username_logged_out == NULL)
-    {
-        FURI_LOG_E(TAG, "Username is NULL");
-        return false;
-    }
-    char command[128];
-    snprintf(command, 128, "https://www.flipsocial.net/api/feed/40/%s/extended/", app_instance->login_username_logged_out);
-    bool success = flipper_http_get_request_with_headers(command, jsmn("Content-Type", "application/json"));
-    if (!success)
-    {
-        FURI_LOG_E(TAG, "Failed to send HTTP request for feed");
-        return false;
-    }
-    fhttp.state = RECEIVING;
-    return true;
-}
-
-static bool flip_social_parse_json_feed()
-{
-    if (fhttp.received_data == NULL)
-    {
-        FURI_LOG_E(TAG, "No data received.");
-        return false;
-    }
-
-    // Allocate memory for each feed item if not already allocated
-    flip_social_feed = flip_social_feed_alloc();
-    if (flip_social_feed == NULL)
-    {
-        return false;
-    }
-    // Remove newlines
-    char *pos = fhttp.received_data;
-    while ((pos = strchr(pos, '\n')) != NULL)
-    {
-        *pos = ' ';
-    }
-
-    // Initialize feed count
-    flip_social_feed->count = 0;
-
-    // Iterate through the feed array
-    for (int i = 0; i < MAX_FEED_ITEMS; i++)
-    {
-        // Parse each item in the array
-        char *item = get_json_array_value("feed", i, fhttp.received_data, MAX_TOKENS);
-        if (item == NULL)
-        {
-            break;
-        }
-
-        // Extract individual fields from the JSON object
-        char *username = get_json_value("username", item, MAX_TOKENS);
-        char *message = get_json_value("message", item, MAX_TOKENS);
-        char *flipped = get_json_value("flipped", item, MAX_TOKENS);
-        char *flips = get_json_value("flip_count", item, MAX_TOKENS);
-        char *id = get_json_value("id", item, MAX_TOKENS);
-
-        if (username == NULL || message == NULL || flipped == NULL || id == NULL)
-        {
-            FURI_LOG_E(TAG, "Failed to parse item fields.");
-            free(item);
-            free(username);
-            free(message);
-            free(flipped);
-            free(flips);
-            free(id);
-            continue;
-        }
-
-        // Safely copy strings with bounds checking
-        strncpy(flip_social_feed->usernames[i], username, MAX_USER_LENGTH - 1);
-        flip_social_feed->usernames[i][MAX_USER_LENGTH - 1] = '\0';
-
-        strncpy(flip_social_feed->messages[i], message, MAX_MESSAGE_LENGTH - 1);
-        flip_social_feed->messages[i][MAX_MESSAGE_LENGTH - 1] = '\0';
-
-        // Store boolean and integer values
-        flip_social_feed->is_flipped[i] = strstr(flipped, "true") != NULL;
-        flip_social_feed->ids[i] = atoi(id);
-        flip_social_feed->flips[i] = atoi(flips);
-
-        flip_social_feed->count++;
-
-        // Free allocated memory
-        free(item);
-        free(username);
-        free(message);
-        free(flipped);
-        free(flips);
-        free(id);
-    }
-
-    return flip_social_feed->count > 0;
-}
-
-#endif // FLIP_SOCIAL_FEED_H

+ 0 - 294
flip_social_free.h

@@ -1,294 +0,0 @@
-// flip_social_free.h
-#ifndef FLIP_SOCIAL_FREE_H
-#define FLIP_SOCIAL_FREE_H
-
-/**
- * @brief Function to free the resources used by FlipSocialApp.
- * @details Cleans up all allocated resources before exiting the application.
- * @param app The FlipSocialApp object to free.
- * @return void
- */
-static void flip_social_app_free(FlipSocialApp *app)
-{
-    if (!app)
-    {
-        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
-        return;
-    }
-    if (!app->view_dispatcher)
-    {
-        FURI_LOG_E(TAG, "ViewDispatcher is NULL");
-        return;
-    }
-
-    // Free Submenu(s)
-    if (app->submenu_logged_out)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutSubmenu);
-        submenu_free(app->submenu_logged_out);
-    }
-    if (app->submenu_logged_in)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInSubmenu);
-        submenu_free(app->submenu_logged_in);
-    }
-    if (app->submenu_compose)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInCompose);
-        submenu_free(app->submenu_compose);
-    }
-    if (app->submenu_explore)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInExploreSubmenu);
-        submenu_free(app->submenu_explore);
-    }
-    if (app->submenu_friends)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInFriendsSubmenu);
-        submenu_free(app->submenu_friends);
-    }
-    if (app->submenu_messages)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesSubmenu);
-        submenu_free(app->submenu_messages);
-    }
-    if (app->submenu_messages_user_choices)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesUserChoices);
-        submenu_free(app->submenu_messages_user_choices);
-    }
-
-    // Free Variable Item List(s)
-    if (app->variable_item_list_logged_out_wifi_settings)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettings);
-        variable_item_list_free(app->variable_item_list_logged_out_wifi_settings);
-    }
-    if (app->variable_item_list_logged_out_login)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutLogin);
-        variable_item_list_free(app->variable_item_list_logged_out_login);
-    }
-    if (app->variable_item_list_logged_out_register)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutRegister);
-        variable_item_list_free(app->variable_item_list_logged_out_register);
-    }
-    if (app->variable_item_list_logged_in_profile)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInProfile);
-        variable_item_list_free(app->variable_item_list_logged_in_profile);
-    }
-    if (app->variable_item_list_logged_in_settings)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInSettings);
-        variable_item_list_free(app->variable_item_list_logged_in_settings);
-    }
-    if (app->variable_item_list_logged_in_settings_wifi)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInSettingsWifi);
-        variable_item_list_free(app->variable_item_list_logged_in_settings_wifi);
-    }
-
-    // Free Text Input(s)
-    if (app->text_input_logged_out_wifi_settings_ssid)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettingsSSIDInput);
-        uart_text_input_free(app->text_input_logged_out_wifi_settings_ssid);
-    }
-    if (app->text_input_logged_out_wifi_settings_password)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettingsPasswordInput);
-        uart_text_input_free(app->text_input_logged_out_wifi_settings_password);
-    }
-    if (app->text_input_logged_out_login_username)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutLoginUsernameInput);
-        uart_text_input_free(app->text_input_logged_out_login_username);
-    }
-    if (app->text_input_logged_out_login_password)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutLoginPasswordInput);
-        uart_text_input_free(app->text_input_logged_out_login_password);
-    }
-    if (app->text_input_logged_out_register_username)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutRegisterUsernameInput);
-        uart_text_input_free(app->text_input_logged_out_register_username);
-    }
-    if (app->text_input_logged_out_register_password)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutRegisterPasswordInput);
-        uart_text_input_free(app->text_input_logged_out_register_password);
-    }
-    if (app->text_input_logged_out_register_password_2)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutRegisterPassword2Input);
-        uart_text_input_free(app->text_input_logged_out_register_password_2);
-    }
-    if (app->text_input_logged_in_change_password)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInChangePasswordInput);
-        uart_text_input_free(app->text_input_logged_in_change_password);
-    }
-    if (app->text_input_logged_in_compose_pre_save_input)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInComposeAddPreSaveInput);
-        uart_text_input_free(app->text_input_logged_in_compose_pre_save_input);
-    }
-    if (app->text_input_logged_in_wifi_settings_ssid)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInWifiSettingsSSIDInput);
-        uart_text_input_free(app->text_input_logged_in_wifi_settings_ssid);
-    }
-    if (app->text_input_logged_in_wifi_settings_password)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInWifiSettingsPasswordInput);
-        uart_text_input_free(app->text_input_logged_in_wifi_settings_password);
-    }
-    if (app->text_input_logged_in_messages_new_message)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesNewMessageInput);
-        uart_text_input_free(app->text_input_logged_in_messages_new_message);
-    }
-    if (app->text_input_logged_in_messages_new_message_user_choices)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesNewMessageUserChoicesInput);
-        uart_text_input_free(app->text_input_logged_in_messages_new_message_user_choices);
-    }
-
-    // Free Widget(s)
-    if (app->widget_logged_out_about)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutAbout);
-        widget_free(app->widget_logged_out_about);
-    }
-    if (app->widget_logged_in_about)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInSettingsAbout);
-        widget_free(app->widget_logged_in_about);
-    }
-
-    // Free View(s)
-    if (app->view_process_login)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutProcessLogin);
-        view_free(app->view_process_login);
-    }
-    if (app->view_process_register)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedOutProcessRegister);
-        view_free(app->view_process_register);
-    }
-    if (app->view_process_feed)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInFeed);
-        view_free(app->view_process_feed);
-    }
-    if (app->view_process_compose)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInProcessCompose);
-        view_free(app->view_process_compose);
-    }
-    if (app->view_process_explore)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInExploreProccess);
-        view_free(app->view_process_explore);
-    }
-    if (app->view_process_friends)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInFriendsProcess);
-        view_free(app->view_process_friends);
-    }
-    if (app->view_process_messages)
-    {
-        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesProcess);
-        view_free(app->view_process_messages);
-    }
-
-    if (app->view_dispatcher)
-        view_dispatcher_free(app->view_dispatcher);
-
-    // Free the app structure members
-    if (app->wifi_ssid_logged_out)
-        free(app->wifi_ssid_logged_out);
-    if (app->wifi_ssid_logged_out_temp_buffer)
-        free(app->wifi_ssid_logged_out_temp_buffer);
-    if (app->wifi_password_logged_out)
-        free(app->wifi_password_logged_out);
-    if (app->wifi_password_logged_out_temp_buffer)
-        free(app->wifi_password_logged_out_temp_buffer);
-    if (app->login_username_logged_out)
-        free(app->login_username_logged_out);
-    if (app->login_username_logged_out_temp_buffer)
-        free(app->login_username_logged_out_temp_buffer);
-    if (app->login_password_logged_out)
-        free(app->login_password_logged_out);
-    if (app->login_password_logged_out_temp_buffer)
-        free(app->login_password_logged_out_temp_buffer);
-    if (app->register_username_logged_out)
-        free(app->register_username_logged_out);
-    if (app->register_username_logged_out_temp_buffer)
-        free(app->register_username_logged_out_temp_buffer);
-    if (app->register_password_logged_out)
-        free(app->register_password_logged_out);
-    if (app->register_password_logged_out_temp_buffer)
-        free(app->register_password_logged_out_temp_buffer);
-    if (app->register_password_2_logged_out)
-        free(app->register_password_2_logged_out);
-    if (app->register_password_2_logged_out_temp_buffer)
-        free(app->register_password_2_logged_out_temp_buffer);
-    if (app->change_password_logged_in)
-        free(app->change_password_logged_in);
-    if (app->change_password_logged_in_temp_buffer)
-        free(app->change_password_logged_in_temp_buffer);
-    if (app->compose_pre_save_logged_in)
-        free(app->compose_pre_save_logged_in);
-    if (app->compose_pre_save_logged_in_temp_buffer)
-        free(app->compose_pre_save_logged_in_temp_buffer);
-    if (app->wifi_ssid_logged_in)
-        free(app->wifi_ssid_logged_in);
-    if (app->wifi_ssid_logged_in_temp_buffer)
-        free(app->wifi_ssid_logged_in_temp_buffer);
-    if (app->wifi_password_logged_in)
-        free(app->wifi_password_logged_in);
-    if (app->wifi_password_logged_in_temp_buffer)
-        free(app->wifi_password_logged_in_temp_buffer);
-    if (app->is_logged_in)
-        free(app->is_logged_in);
-    if (app->login_username_logged_in)
-        free(app->login_username_logged_in);
-    if (app->login_username_logged_in_temp_buffer)
-        free(app->login_username_logged_in_temp_buffer);
-    if (app->messages_new_message_logged_in)
-        free(app->messages_new_message_logged_in);
-    if (app->messages_new_message_logged_in_temp_buffer)
-        free(app->messages_new_message_logged_in_temp_buffer);
-    if (app->message_user_choice_logged_in)
-        free(app->message_user_choice_logged_in);
-    if (app->message_user_choice_logged_in_temp_buffer)
-        free(app->message_user_choice_logged_in_temp_buffer);
-
-    if (app->input_event && app->input_event_queue)
-        furi_pubsub_unsubscribe(app->input_event_queue, app->input_event);
-
-    // free received_data
-    if (fhttp.received_data)
-        free(fhttp.received_data);
-
-    // free playlist and explore page
-    flip_social_free_explore();
-    flip_social_free_feed();
-    flip_social_free_friends();
-    flip_social_free_message_users();
-    flip_social_free_messages();
-
-    // DeInit UART
-    flipper_http_deinit();
-
-    // Free the app structure
-    if (app_instance)
-        free(app_instance);
-}
-
-#endif // FLIP_SOCIAL_FREE_H

+ 0 - 158
flip_social_friends.h

@@ -1,158 +0,0 @@
-#ifndef FLIP_SOCIAL_FRIENDS
-#define FLIP_SOCIAL_FRIENDS
-
-static FlipSocialModel *flip_social_friends_alloc()
-{
-    // Allocate memory for each username only if not already allocated
-    FlipSocialModel *friends = malloc(sizeof(FlipSocialModel));
-    for (size_t i = 0; i < MAX_FRIENDS; i++)
-    {
-        if (friends->usernames[i] == NULL)
-        {
-            friends->usernames[i] = malloc(MAX_USER_LENGTH);
-            if (friends->usernames[i] == NULL)
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for username %zu", i);
-                return NULL; // Return false on memory allocation failure
-            }
-        }
-    }
-    return friends;
-}
-
-static void flip_social_free_friends()
-{
-    if (!flip_social_friends)
-    {
-        FURI_LOG_E(TAG, "Friends model is NULL");
-        return;
-    }
-    for (int i = 0; i < flip_social_friends->count; i++)
-    {
-        free(flip_social_friends->usernames[i]);
-    }
-}
-
-// for now we're just listing the current users
-// as the feed is upgraded, then we can port more to the friends view
-static bool flip_social_get_friends()
-{
-    // will return true unless the devboard is not connected
-    char url[100];
-    snprintf(url, 100, "https://www.flipsocial.net/api/user/friends/%s/", app_instance->login_username_logged_in);
-    bool success = flipper_http_get_request_with_headers(url, jsmn("Content-Type", "application/json"));
-    if (!success)
-    {
-        FURI_LOG_E(TAG, "Failed to send HTTP request for friends");
-        return false;
-    }
-    fhttp.state = RECEIVING;
-    return true;
-}
-
-static bool flip_social_update_friends()
-{
-    if (!app_instance->submenu_friends)
-    {
-        FURI_LOG_E(TAG, "Friends submenu is NULL");
-        return false;
-    }
-    if (!flip_social_friends)
-    {
-        FURI_LOG_E(TAG, "Friends model is NULL");
-        return false;
-    }
-    // Add submenu items for the users
-    submenu_reset(app_instance->submenu_friends);
-    submenu_set_header(app_instance->submenu_friends, "Friends");
-    for (int i = 0; i < flip_social_friends->count; i++)
-    {
-        submenu_add_item(app_instance->submenu_friends, flip_social_friends->usernames[i], FlipSocialSubmenuLoggedInIndexFriendsStart + i, flip_social_callback_submenu_choices, app_instance);
-    }
-    return true;
-}
-
-static bool flip_social_parse_json_friends()
-{
-    if (fhttp.received_data == NULL)
-    {
-        FURI_LOG_E(TAG, "No data received.");
-        return false;
-    }
-
-    // Allocate memory for each username only if not already allocated
-    flip_social_friends = flip_social_friends_alloc();
-    if (flip_social_friends == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to allocate memory for friends usernames.");
-        return false;
-    }
-
-    // Remove newlines
-    char *pos = fhttp.received_data;
-    while ((pos = strchr(pos, '\n')) != NULL)
-    {
-        *pos = ' ';
-    }
-
-    // Initialize friends count
-    flip_social_friends->count = 0;
-
-    // Extract the users array from the JSON
-    char *json_users = get_json_value("friends", fhttp.received_data, MAX_TOKENS);
-    if (json_users == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to parse friends array.");
-        return false;
-    }
-
-    // Manual tokenization for comma-separated values
-    char *start = json_users + 1; // Skip the opening bracket
-    char *end;
-    while ((end = strchr(start, ',')) != NULL && flip_social_friends->count < MAX_FRIENDS)
-    {
-        *end = '\0'; // Null-terminate the current token
-
-        // Remove quotes
-        if (*start == '"')
-            start++;
-        if (*(end - 1) == '"')
-            *(end - 1) = '\0';
-
-        // Copy username to pre-allocated memory
-        strncpy(flip_social_friends->usernames[flip_social_friends->count], start, MAX_USER_LENGTH - 1);
-        flip_social_friends->usernames[flip_social_friends->count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        flip_social_friends->count++;
-        start = end + 1;
-    }
-
-    // Handle the last token
-    if (*start != '\0' && flip_social_friends->count < MAX_FRIENDS)
-    {
-        if (*start == '"')
-            start++;
-        if (*(start + strlen(start) - 1) == ']')
-            *(start + strlen(start) - 1) = '\0';
-        if (*(start + strlen(start) - 1) == '"')
-            *(start + strlen(start) - 1) = '\0';
-
-        strncpy(flip_social_friends->usernames[flip_social_friends->count], start, MAX_USER_LENGTH - 1);
-        flip_social_friends->usernames[flip_social_friends->count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        flip_social_friends->count++;
-    }
-
-    // Add submenu items for the friends
-    if (!flip_social_update_friends())
-    {
-        FURI_LOG_E(TAG, "Failed to update friends submenu");
-        return false;
-    }
-
-    // Free the json_users
-    free(json_users);
-    free(start);
-    free(end);
-
-    return true;
-}
-#endif // FLIP_SOCIAL_FRIENDS

+ 0 - 542
flip_social_i.h

@@ -1,542 +0,0 @@
-// flip_social.i.h
-#ifndef FLIP_SOCIAL_I
-#define FLIP_SOCIAL_I
-
-/**
- * @brief Function to allocate resources for the FlipSocialApp.
- * @details Initializes all components and views of the application.
- * @return Pointer to the initialized FlipSocialApp, or NULL on failure.
- */
-static FlipSocialApp *flip_social_app_alloc()
-{
-    // Initiailize the app
-    FlipSocialApp *app = (FlipSocialApp *)malloc(sizeof(FlipSocialApp));
-
-    // Initialize gui
-    Gui *gui = furi_record_open(RECORD_GUI);
-
-    // Initialize UART
-    if (!flipper_http_init(flipper_http_rx_callback, app))
-    {
-        FURI_LOG_E(TAG, "Failed to initialize UART");
-        return NULL;
-    }
-
-    // Allocate ViewDispatcher
-    if (!easy_flipper_set_view_dispatcher(&app->view_dispatcher, gui, app))
-    {
-        return NULL;
-    }
-
-    // Allocate the text input buffers
-    app->wifi_ssid_logged_out_temp_buffer_size = MAX_USER_LENGTH;
-    app->wifi_password_logged_out_temp_buffer_size = MAX_USER_LENGTH;
-    app->login_username_logged_out_temp_buffer_size = MAX_USER_LENGTH;
-    app->login_password_logged_out_temp_buffer_size = MAX_USER_LENGTH;
-    app->register_username_logged_out_temp_buffer_size = MAX_USER_LENGTH;
-    app->register_password_logged_out_temp_buffer_size = MAX_USER_LENGTH;
-    app->register_password_2_logged_out_temp_buffer_size = MAX_USER_LENGTH;
-    app->change_password_logged_in_temp_buffer_size = MAX_USER_LENGTH;
-    app->compose_pre_save_logged_in_temp_buffer_size = 100;
-    app->wifi_ssid_logged_in_temp_buffer_size = MAX_USER_LENGTH;
-    app->wifi_password_logged_in_temp_buffer_size = MAX_USER_LENGTH;
-    app->is_logged_in_size = 8;
-    app->login_username_logged_in_temp_buffer_size = MAX_USER_LENGTH;
-    app->messages_new_message_logged_in_temp_buffer_size = 100;
-    app->message_user_choice_logged_in_temp_buffer_size = 100;
-    if (!easy_flipper_set_buffer(&app->wifi_ssid_logged_out_temp_buffer, app->wifi_ssid_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->wifi_password_logged_out_temp_buffer, app->wifi_password_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->login_username_logged_out_temp_buffer, app->login_username_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->login_password_logged_out_temp_buffer, app->login_password_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->register_username_logged_out_temp_buffer, app->register_username_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->register_password_logged_out_temp_buffer, app->register_password_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->register_password_2_logged_out_temp_buffer, app->register_password_2_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->change_password_logged_in_temp_buffer, app->change_password_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->compose_pre_save_logged_in_temp_buffer, app->compose_pre_save_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->wifi_ssid_logged_in_temp_buffer, app->wifi_ssid_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->wifi_password_logged_in_temp_buffer, app->wifi_password_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->is_logged_in, app->is_logged_in_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->login_username_logged_in_temp_buffer, app->login_username_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-
-    if (!easy_flipper_set_buffer(&app->wifi_ssid_logged_out, app->wifi_ssid_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->wifi_password_logged_out, app->wifi_password_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->login_username_logged_out, app->login_username_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->login_password_logged_out, app->login_password_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->register_username_logged_out, app->register_username_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->register_password_logged_out, app->register_password_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->register_password_2_logged_out, app->register_password_2_logged_out_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->change_password_logged_in, app->change_password_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->compose_pre_save_logged_in, app->compose_pre_save_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->wifi_ssid_logged_in, app->wifi_ssid_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->wifi_password_logged_in, app->wifi_password_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->login_username_logged_in, app->login_username_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    //
-    if (!easy_flipper_set_buffer(&app->messages_new_message_logged_in, app->messages_new_message_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->messages_new_message_logged_in_temp_buffer, app->messages_new_message_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->message_user_choice_logged_in, app->message_user_choice_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_buffer(&app->message_user_choice_logged_in_temp_buffer, app->message_user_choice_logged_in_temp_buffer_size))
-    {
-        return NULL;
-    }
-
-    // Allocate Submenu(s)
-    if (!easy_flipper_set_submenu(&app->submenu_logged_out, FlipSocialViewLoggedOutSubmenu, "FlipSocial v0.5", flip_social_callback_exit_app, &app->view_dispatcher))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_submenu(&app->submenu_logged_in, FlipSocialViewLoggedInSubmenu, "FlipSocial v0.5", flip_social_callback_exit_app, &app->view_dispatcher))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_submenu(&app->submenu_compose, FlipSocialViewLoggedInCompose, "Create A Post", flip_social_callback_to_submenu_logged_in, &app->view_dispatcher))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_submenu(&app->submenu_explore, FlipSocialViewLoggedInExploreSubmenu, "Explore", flip_social_callback_to_submenu_logged_in, &app->view_dispatcher))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_submenu(&app->submenu_friends, FlipSocialViewLoggedInFriendsSubmenu, "Friends", flip_social_callback_to_profile_logged_in, &app->view_dispatcher))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_submenu(&app->submenu_messages, FlipSocialViewLoggedInMessagesSubmenu, "Messages", flip_social_callback_to_submenu_logged_in, &app->view_dispatcher))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_submenu(&app->submenu_messages_user_choices, FlipSocialViewLoggedInMessagesUserChoices, "Users", flip_social_callback_to_messages_logged_in, &app->view_dispatcher))
-    {
-        return NULL;
-    }
-
-    submenu_add_item(app->submenu_logged_out, "Login", FlipSocialSubmenuLoggedOutIndexLogin, flip_social_callback_submenu_choices, app);
-    submenu_add_item(app->submenu_logged_out, "Register", FlipSocialSubmenuLoggedOutIndexRegister, flip_social_callback_submenu_choices, app);
-    submenu_add_item(app->submenu_logged_out, "About", FlipSocialSubmenuLoggedOutIndexAbout, flip_social_callback_submenu_choices, app);
-    submenu_add_item(app->submenu_logged_out, "Settings", FlipSocialSubmenuLoggedOutIndexWifiSettings, flip_social_callback_submenu_choices, app);
-    //
-    submenu_add_item(app->submenu_logged_in, "Explore", FlipSocialSubmenuExploreIndex, flip_social_callback_submenu_choices, app);
-    submenu_add_item(app->submenu_logged_in, "Feed", FlipSocialSubmenuLoggedInIndexFeed, flip_social_callback_submenu_choices, app);
-    submenu_add_item(app->submenu_logged_in, "Post", FlipSocialSubmenuLoggedInIndexCompose, flip_social_callback_submenu_choices, app);
-    submenu_add_item(app->submenu_logged_in, "Messages", FlipSocialSubmenuLoggedInIndexMessages, flip_social_callback_submenu_choices, app);
-    submenu_add_item(app->submenu_logged_in, "Profile", FlipSocialSubmenuLoggedInIndexProfile, flip_social_callback_submenu_choices, app);
-    submenu_add_item(app->submenu_logged_in, "Settings", FlipSocialSubmenuLoggedInIndexSettings, flip_social_callback_submenu_choices, app);
-    submenu_add_item(app->submenu_logged_in, "Sign Out", FlipSocialSubmenuLoggedInSignOutButton, flip_social_callback_submenu_choices, app);
-    //
-    submenu_add_item(app->submenu_compose, "Add Pre-Save", FlipSocialSubmenuComposeIndexAddPreSave, flip_social_callback_submenu_choices, app);
-    //
-
-    // Allocate View(s)
-    if (!easy_flipper_set_view(&app->view_process_login, FlipSocialViewLoggedOutProcessLogin, flip_social_callback_draw_login, NULL, flip_social_callback_to_login_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_view(&app->view_process_register, FlipSocialViewLoggedOutProcessRegister, flip_social_callback_draw_register, NULL, flip_social_callback_to_register_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_view(&app->view_process_feed, FlipSocialViewLoggedInFeed, flip_social_callback_draw_feed, NULL, flip_social_callback_to_submenu_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_view(&app->view_process_compose, FlipSocialViewLoggedInProcessCompose, flip_social_callback_draw_compose, NULL, flip_social_callback_to_compose_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_view(&app->view_process_explore, FlipSocialViewLoggedInExploreProccess, flip_social_callback_draw_explore, NULL, flip_social_callback_to_explore_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_view(&app->view_process_friends, FlipSocialViewLoggedInFriendsProcess, flip_social_callback_draw_friends, NULL, flip_social_callback_to_friends_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_view(&app->view_process_messages, FlipSocialViewLoggedInMessagesProcess, flip_social_callback_draw_messages, NULL, flip_social_callback_to_messages_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-
-    // Setup Variable Item List(s)
-    if (!easy_flipper_set_variable_item_list(&app->variable_item_list_logged_out_wifi_settings, FlipSocialViewLoggedOutWifiSettings, flip_social_text_input_logged_out_wifi_settings_item_selected, flip_social_callback_to_submenu_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_variable_item_list(&app->variable_item_list_logged_out_login, FlipSocialViewLoggedOutLogin, flip_social_text_input_logged_out_login_item_selected, flip_social_callback_to_submenu_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_variable_item_list(&app->variable_item_list_logged_out_register, FlipSocialViewLoggedOutRegister, flip_social_text_input_logged_out_register_item_selected, flip_social_callback_to_submenu_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_variable_item_list(&app->variable_item_list_logged_in_profile, FlipSocialViewLoggedInProfile, flip_social_text_input_logged_in_profile_item_selected, flip_social_callback_to_submenu_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_variable_item_list(&app->variable_item_list_logged_in_settings, FlipSocialViewLoggedInSettings, flip_social_text_input_logged_in_settings_item_selected, flip_social_callback_to_submenu_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_variable_item_list(&app->variable_item_list_logged_in_settings_wifi, FlipSocialViewLoggedInSettingsWifi, flip_social_text_input_logged_in_wifi_settings_item_selected, flip_social_callback_to_settings_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-
-    app->variable_item_logged_out_wifi_settings_ssid = variable_item_list_add(app->variable_item_list_logged_out_wifi_settings, "SSID", 1, NULL, NULL);
-    app->variable_item_logged_out_wifi_settings_password = variable_item_list_add(app->variable_item_list_logged_out_wifi_settings, "Password", 1, NULL, NULL);
-    //
-    app->variable_item_logged_out_login_username = variable_item_list_add(app->variable_item_list_logged_out_login, "Username", 1, NULL, NULL);
-    app->variable_item_logged_out_login_password = variable_item_list_add(app->variable_item_list_logged_out_login, "Password", 1, NULL, NULL);
-    app->variable_item_logged_out_login_button = variable_item_list_add(app->variable_item_list_logged_out_login, "Login", 0, NULL, NULL);
-    //
-    app->variable_item_logged_out_register_username = variable_item_list_add(app->variable_item_list_logged_out_register, "Username", 1, NULL, NULL);
-    app->variable_item_logged_out_register_password = variable_item_list_add(app->variable_item_list_logged_out_register, "Password", 1, NULL, NULL);
-    app->variable_item_logged_out_register_password_2 = variable_item_list_add(app->variable_item_list_logged_out_register, "Confirm Password", 1, NULL, NULL);
-    app->variable_item_logged_out_register_button = variable_item_list_add(app->variable_item_list_logged_out_register, "Register", 0, NULL, NULL);
-    //
-    app->variable_item_logged_in_profile_username = variable_item_list_add(app->variable_item_list_logged_in_profile, "Username", 0, NULL, NULL);
-    app->variable_item_logged_in_profile_change_password = variable_item_list_add(app->variable_item_list_logged_in_profile, "Change Password", 0, NULL, NULL);
-    app->variable_item_logged_in_profile_friends = variable_item_list_add(app->variable_item_list_logged_in_profile, "Friends", 0, NULL, NULL);
-    //
-    app->variable_item_logged_in_settings_about = variable_item_list_add(app->variable_item_list_logged_in_settings, "About", 0, NULL, NULL);
-    app->variable_item_logged_in_settings_wifi = variable_item_list_add(app->variable_item_list_logged_in_settings, "WiFi", 0, NULL, NULL);
-    //
-    app->variable_item_logged_in_wifi_settings_ssid = variable_item_list_add(app->variable_item_list_logged_in_settings_wifi, "SSID", 1, NULL, NULL);
-    app->variable_item_logged_in_wifi_settings_password = variable_item_list_add(app->variable_item_list_logged_in_settings_wifi, "Password", 1, NULL, NULL);
-
-    // Setup Text Input(s)
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_out_wifi_settings_ssid, FlipSocialViewLoggedOutWifiSettingsSSIDInput, "Enter SSID", app->wifi_ssid_logged_out_temp_buffer, app->wifi_ssid_logged_out_temp_buffer_size, flip_social_logged_out_wifi_settings_ssid_updated, flip_social_callback_to_wifi_settings_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_out_wifi_settings_password, FlipSocialViewLoggedOutWifiSettingsPasswordInput, "Enter Password", app->wifi_password_logged_out_temp_buffer, app->wifi_password_logged_out_temp_buffer_size, flip_social_logged_out_wifi_settings_password_updated, flip_social_callback_to_wifi_settings_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_out_login_username, FlipSocialViewLoggedOutLoginUsernameInput, "Enter Username", app->login_username_logged_out_temp_buffer, app->login_username_logged_out_temp_buffer_size, flip_social_logged_out_login_username_updated, flip_social_callback_to_login_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_out_login_password, FlipSocialViewLoggedOutLoginPasswordInput, "Enter Password", app->login_password_logged_out_temp_buffer, app->login_password_logged_out_temp_buffer_size, flip_social_logged_out_login_password_updated, flip_social_callback_to_login_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_out_register_username, FlipSocialViewLoggedOutRegisterUsernameInput, "Enter Username", app->register_username_logged_out_temp_buffer, app->register_username_logged_out_temp_buffer_size, flip_social_logged_out_register_username_updated, flip_social_callback_to_register_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_out_register_password, FlipSocialViewLoggedOutRegisterPasswordInput, "Enter Password", app->register_password_logged_out_temp_buffer, app->register_password_logged_out_temp_buffer_size, flip_social_logged_out_register_password_updated, flip_social_callback_to_register_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_out_register_password_2, FlipSocialViewLoggedOutRegisterPassword2Input, "Confirm Password", app->register_password_2_logged_out_temp_buffer, app->register_password_2_logged_out_temp_buffer_size, flip_social_logged_out_register_password_2_updated, flip_social_callback_to_register_logged_out, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    //
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_change_password, FlipSocialViewLoggedInChangePasswordInput, "Enter New Password", app->change_password_logged_in_temp_buffer, app->change_password_logged_in_temp_buffer_size, flip_social_logged_in_profile_change_password_updated, flip_social_callback_to_profile_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_compose_pre_save_input, FlipSocialViewLoggedInComposeAddPreSaveInput, "Enter Pre-Save Message", app->compose_pre_save_logged_in_temp_buffer, app->compose_pre_save_logged_in_temp_buffer_size, flip_social_logged_in_compose_pre_save_updated, flip_social_callback_to_compose_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_wifi_settings_ssid, FlipSocialViewLoggedInWifiSettingsSSIDInput, "Enter SSID", app->wifi_ssid_logged_in_temp_buffer, app->wifi_ssid_logged_in_temp_buffer_size, flip_social_logged_in_wifi_settings_ssid_updated, flip_social_callback_to_wifi_settings_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_wifi_settings_password, FlipSocialViewLoggedInWifiSettingsPasswordInput, "Enter Password", app->wifi_password_logged_in_temp_buffer, app->wifi_password_logged_in_temp_buffer_size, flip_social_logged_in_wifi_settings_password_updated, flip_social_callback_to_wifi_settings_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    //
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_messages_new_message, FlipSocialViewLoggedInMessagesNewMessageInput, "Enter Message", app->messages_new_message_logged_in_temp_buffer, app->messages_new_message_logged_in_temp_buffer_size, flip_social_logged_in_messages_new_message_updated, flip_social_callback_to_messages_logged_in, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_messages_new_message_user_choices, FlipSocialViewLoggedInMessagesNewMessageUserChoicesInput, "Enter Message", app->message_user_choice_logged_in_temp_buffer, app->message_user_choice_logged_in_temp_buffer_size, flip_social_logged_in_messages_user_choice_message_updated, flip_social_callback_to_messages_user_choices, &app->view_dispatcher, app))
-    {
-        return NULL;
-    }
-
-    // Setup About(s)
-    if (!easy_flipper_set_widget(&app->widget_logged_out_about, FlipSocialViewLoggedOutAbout, "Welcome to FlipSocial\n---\nThe social media app for\nFlipper Zero, created by\nJBlanked: www.flipsocial.net\n---\nPress BACK to return.", flip_social_callback_to_submenu_logged_out, &app->view_dispatcher))
-    {
-        return NULL;
-    }
-    if (!easy_flipper_set_widget(&app->widget_logged_in_about, FlipSocialViewLoggedInSettingsAbout, "Welcome to FlipSocial\n---\nThe social media app for\nFlipper Zero, created by\nJBlanked: www.flipsocial.net\n---\nPress BACK to return.", flip_social_callback_to_settings_logged_in, &app->view_dispatcher))
-    {
-        return NULL;
-    }
-
-    // load the playlist
-    if (load_playlist(&app->pre_saved_messages))
-    {
-        // Update the playlist submenu
-        for (uint32_t i = 0; i < app->pre_saved_messages.count; i++)
-        {
-            submenu_add_item(app->submenu_compose, app->pre_saved_messages.messages[i], FlipSocialSubemnuComposeIndexStartIndex + i, flip_social_callback_submenu_choices, app);
-        }
-    }
-
-    // Load the settings
-    if (!load_settings(app->wifi_ssid_logged_out,
-                       app->wifi_ssid_logged_out_temp_buffer_size,
-                       app->wifi_password_logged_out,
-                       app->wifi_password_logged_out_temp_buffer_size,
-                       app->login_username_logged_out,
-                       app->login_username_logged_out_temp_buffer_size,
-                       app->login_username_logged_in,
-                       app->login_username_logged_in_temp_buffer_size,
-                       app->login_password_logged_out,
-                       app->login_password_logged_out_temp_buffer_size,
-                       app->change_password_logged_in,
-                       app->change_password_logged_in_temp_buffer_size,
-                       app->is_logged_in,
-                       app->is_logged_in_size))
-
-    {
-        FURI_LOG_E(TAG, "Failed to load settings");
-
-        if (app->is_logged_in == NULL)
-        {
-            app->is_logged_in = (char *)malloc(app->is_logged_in_size);
-            app->is_logged_in = "false";
-        }
-        app_instance = app;
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutSubmenu);
-    }
-    else
-    {
-        // Copy items into their temp buffers with safety checks
-        if (app->wifi_ssid_logged_out && app->wifi_ssid_logged_out_temp_buffer)
-        {
-            strncpy(app->wifi_ssid_logged_out_temp_buffer, app->wifi_ssid_logged_out, app->wifi_ssid_logged_out_temp_buffer_size - 1);
-            app->wifi_ssid_logged_out_temp_buffer[app->wifi_ssid_logged_out_temp_buffer_size - 1] = '\0';
-        }
-        if (app->wifi_password_logged_out && app->wifi_password_logged_out_temp_buffer)
-        {
-            strncpy(app->wifi_password_logged_out_temp_buffer, app->wifi_password_logged_out, app->wifi_password_logged_out_temp_buffer_size - 1);
-            app->wifi_password_logged_out_temp_buffer[app->wifi_password_logged_out_temp_buffer_size - 1] = '\0';
-        }
-        if (app->login_username_logged_out && app->login_username_logged_out_temp_buffer)
-        {
-            strncpy(app->login_username_logged_out_temp_buffer, app->login_username_logged_out, app->login_username_logged_out_temp_buffer_size - 1);
-            app->login_username_logged_out_temp_buffer[app->login_username_logged_out_temp_buffer_size - 1] = '\0';
-        }
-        if (app->login_password_logged_out && app->login_password_logged_out_temp_buffer)
-        {
-            strncpy(app->login_password_logged_out_temp_buffer, app->login_password_logged_out, app->login_password_logged_out_temp_buffer_size - 1);
-            app->login_password_logged_out_temp_buffer[app->login_password_logged_out_temp_buffer_size - 1] = '\0';
-        }
-        if (app->register_username_logged_out && app->register_username_logged_out_temp_buffer)
-        {
-            strncpy(app->register_username_logged_out_temp_buffer, app->register_username_logged_out, app->register_username_logged_out_temp_buffer_size - 1);
-            app->register_username_logged_out_temp_buffer[app->register_username_logged_out_temp_buffer_size - 1] = '\0';
-        }
-        if (app->register_password_logged_out && app->register_password_logged_out_temp_buffer)
-        {
-            strncpy(app->register_password_logged_out_temp_buffer, app->register_password_logged_out, app->register_password_logged_out_temp_buffer_size - 1);
-            app->register_password_logged_out_temp_buffer[app->register_password_logged_out_temp_buffer_size - 1] = '\0';
-        }
-        if (app->register_password_2_logged_out && app->register_password_2_logged_out_temp_buffer)
-        {
-            strncpy(app->register_password_2_logged_out_temp_buffer, app->register_password_2_logged_out, app->register_password_2_logged_out_temp_buffer_size - 1);
-            app->register_password_2_logged_out_temp_buffer[app->register_password_2_logged_out_temp_buffer_size - 1] = '\0';
-        }
-        if (app->change_password_logged_in && app->change_password_logged_in_temp_buffer)
-        {
-            strncpy(app->change_password_logged_in_temp_buffer, app->change_password_logged_in, app->change_password_logged_in_temp_buffer_size - 1);
-            app->change_password_logged_in_temp_buffer[app->change_password_logged_in_temp_buffer_size - 1] = '\0';
-        }
-        if (app->compose_pre_save_logged_in && app->compose_pre_save_logged_in_temp_buffer)
-        {
-            strncpy(app->compose_pre_save_logged_in_temp_buffer, app->compose_pre_save_logged_in, app->compose_pre_save_logged_in_temp_buffer_size - 1);
-            app->compose_pre_save_logged_in_temp_buffer[app->compose_pre_save_logged_in_temp_buffer_size - 1] = '\0';
-        }
-        if (app->wifi_ssid_logged_in && app->wifi_ssid_logged_in_temp_buffer)
-        {
-            strncpy(app->wifi_ssid_logged_in_temp_buffer, app->wifi_ssid_logged_in, app->wifi_ssid_logged_in_temp_buffer_size - 1);
-            app->wifi_ssid_logged_in_temp_buffer[app->wifi_ssid_logged_in_temp_buffer_size - 1] = '\0';
-        }
-        if (app->wifi_password_logged_in && app->wifi_password_logged_in_temp_buffer)
-        {
-            strncpy(app->wifi_password_logged_in_temp_buffer, app->wifi_password_logged_in, app->wifi_password_logged_in_temp_buffer_size - 1);
-            app->wifi_password_logged_in_temp_buffer[app->wifi_password_logged_in_temp_buffer_size - 1] = '\0';
-        }
-        if (app->login_username_logged_in && app->login_username_logged_in_temp_buffer)
-        {
-            strncpy(app->login_username_logged_in_temp_buffer, app->login_username_logged_in, app->login_username_logged_in_temp_buffer_size - 1);
-            app->login_username_logged_in_temp_buffer[app->login_username_logged_in_temp_buffer_size - 1] = '\0';
-        }
-
-        // if login username is empty but logged out isnt, copy it over
-        if (strlen(app->login_username_logged_out) > 0 && strlen(app->login_username_logged_in) == 0)
-        {
-            strncpy(app->login_username_logged_in, app->login_username_logged_out, app->login_username_logged_in_temp_buffer_size - 1);
-            strncpy(app->login_username_logged_in_temp_buffer, app->login_username_logged_out, app->login_username_logged_in_temp_buffer_size - 1);
-            app->login_username_logged_in[app->login_username_logged_in_temp_buffer_size - 1] = '\0';
-            app->login_username_logged_in_temp_buffer[app->login_username_logged_in_temp_buffer_size - 1] = '\0';
-        }
-        // logout username is empty but logged in isnt, copy it over
-        if (strlen(app->login_username_logged_in) > 0 && strlen(app->login_username_logged_out) == 0)
-        {
-            strncpy(app->login_username_logged_out, app->login_username_logged_in, app->login_username_logged_in_temp_buffer_size - 1);
-            strncpy(app->login_username_logged_out_temp_buffer, app->login_username_logged_in, app->login_username_logged_in_temp_buffer_size - 1);
-            app->login_username_logged_out[app->login_username_logged_in_temp_buffer_size - 1] = '\0';
-            app->login_username_logged_out_temp_buffer[app->login_username_logged_in_temp_buffer_size - 1] = '\0';
-        }
-        // if login password is empty but logged out isnt, copy it over
-        if (strlen(app->login_password_logged_out) > 0 && strlen(app->change_password_logged_in) == 0)
-        {
-            strncpy(app->change_password_logged_in, app->login_password_logged_out, app->login_password_logged_out_temp_buffer_size - 1);
-            strncpy(app->change_password_logged_in_temp_buffer, app->login_password_logged_out, app->login_password_logged_out_temp_buffer_size - 1);
-            app->change_password_logged_in[app->login_password_logged_out_temp_buffer_size - 1] = '\0';
-            app->change_password_logged_in_temp_buffer[app->login_password_logged_out_temp_buffer_size - 1] = '\0';
-        }
-        // if logout password is empty but logged in isnt, copy it over
-        if (strlen(app->change_password_logged_in) > 0 && strlen(app->login_password_logged_out) == 0)
-        {
-            strncpy(app->login_password_logged_out, app->change_password_logged_in, app->login_password_logged_out_temp_buffer_size - 1);
-            strncpy(app->login_password_logged_out_temp_buffer, app->change_password_logged_in, app->login_password_logged_out_temp_buffer_size - 1);
-            app->login_password_logged_out[app->login_password_logged_out_temp_buffer_size - 1] = '\0';
-            app->login_password_logged_out_temp_buffer[app->login_password_logged_out_temp_buffer_size - 1] = '\0';
-        }
-        // if wifi password is empty but logged out isnt, copy it over
-        if (strlen(app->wifi_password_logged_out) > 0 && strlen(app->wifi_password_logged_in) == 0)
-        {
-            strncpy(app->wifi_password_logged_in, app->wifi_password_logged_out, app->wifi_password_logged_in_temp_buffer_size - 1);
-            strncpy(app->wifi_password_logged_in_temp_buffer, app->wifi_password_logged_out, app->wifi_password_logged_in_temp_buffer_size - 1);
-            app->wifi_password_logged_in[app->wifi_password_logged_in_temp_buffer_size - 1] = '\0';
-            app->wifi_password_logged_in_temp_buffer[app->wifi_password_logged_in_temp_buffer_size - 1] = '\0';
-        }
-        // ifi wifi password is empty but logged in isnt, copy it over
-        if (strlen(app->wifi_password_logged_in) > 0 && strlen(app->wifi_password_logged_out) == 0)
-        {
-            strncpy(app->wifi_password_logged_out, app->wifi_password_logged_in, app->wifi_password_logged_in_temp_buffer_size - 1);
-            strncpy(app->wifi_password_logged_out_temp_buffer, app->wifi_password_logged_in, app->wifi_password_logged_in_temp_buffer_size - 1);
-            app->wifi_password_logged_out[app->wifi_password_logged_in_temp_buffer_size - 1] = '\0';
-            app->wifi_password_logged_out_temp_buffer[app->wifi_password_logged_in_temp_buffer_size - 1] = '\0';
-        }
-        // if wifi ssid is empty but logged out isnt, copy it over
-        if (strlen(app->wifi_ssid_logged_out) > 0 && strlen(app->wifi_ssid_logged_in) == 0)
-        {
-            strncpy(app->wifi_ssid_logged_in, app->wifi_ssid_logged_out, app->wifi_ssid_logged_in_temp_buffer_size - 1);
-            strncpy(app->wifi_ssid_logged_in_temp_buffer, app->wifi_ssid_logged_out, app->wifi_ssid_logged_in_temp_buffer_size - 1);
-            app->wifi_ssid_logged_in[app->wifi_ssid_logged_in_temp_buffer_size - 1] = '\0';
-            app->wifi_ssid_logged_in_temp_buffer[app->wifi_ssid_logged_in_temp_buffer_size - 1] = '\0';
-        }
-        // if wifi ssid is empty but logged in isnt, copy it over
-        if (strlen(app->wifi_ssid_logged_in) > 0 && strlen(app->wifi_ssid_logged_out) == 0)
-        {
-            strncpy(app->wifi_ssid_logged_out, app->wifi_ssid_logged_in, app->wifi_ssid_logged_in_temp_buffer_size - 1);
-            strncpy(app->wifi_ssid_logged_out_temp_buffer, app->wifi_ssid_logged_in, app->wifi_ssid_logged_in_temp_buffer_size - 1);
-            app->wifi_ssid_logged_out[app->wifi_ssid_logged_in_temp_buffer_size - 1] = '\0';
-            app->wifi_ssid_logged_out_temp_buffer[app->wifi_ssid_logged_in_temp_buffer_size - 1] = '\0';
-        }
-
-        // set variable item text (ommit the passwords)
-        variable_item_set_current_value_text(app->variable_item_logged_in_wifi_settings_ssid, app->wifi_ssid_logged_in);
-        variable_item_set_current_value_text(app->variable_item_logged_out_wifi_settings_ssid, app->wifi_ssid_logged_out);
-        variable_item_set_current_value_text(app->variable_item_logged_out_login_username, app->login_username_logged_out);
-        variable_item_set_current_value_text(app->variable_item_logged_in_profile_username, app->login_username_logged_in);
-        //
-
-        if (app->is_logged_in != NULL && strcmp(app->is_logged_in, "true") == 0)
-        {
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSubmenu);
-        }
-        else
-        {
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutSubmenu);
-        }
-    }
-
-    return app;
-}
-
-#endif // FLIP_SOCIAL_I

+ 0 - 396
flip_social_messages.h

@@ -1,396 +0,0 @@
-#ifndef FLIP_SOCIAL_MESSAGES_H
-#define FLIP_SOCIAL_MESSAGES_H
-
-static FlipSocialModel2 *flip_social_messages_alloc()
-{
-    // Allocate memory for each username only if not already allocated
-    FlipSocialModel2 *users = malloc(sizeof(FlipSocialModel2));
-    if (users == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to allocate memory for message users");
-        return NULL;
-    }
-    for (size_t i = 0; i < MAX_MESSAGE_USERS; i++)
-    {
-        if (users->usernames[i] == NULL)
-        {
-            users->usernames[i] = malloc(MAX_USER_LENGTH);
-            if (users->usernames[i] == NULL)
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for username %zu", i);
-                return NULL; // Return false on memory allocation failure
-            }
-        }
-    }
-    return users;
-}
-
-static FlipSocialMessage *flip_social_user_messages_alloc()
-{
-    // Allocate memory for each username only if not already allocated
-    FlipSocialMessage *messages = malloc(sizeof(FlipSocialMessage));
-    if (messages == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to allocate memory for messages");
-        return NULL;
-    }
-    for (size_t i = 0; i < MAX_MESSAGE_USERS; i++)
-    {
-        if (messages->usernames[i] == NULL)
-        {
-            messages->usernames[i] = malloc(MAX_USER_LENGTH);
-            if (messages->usernames[i] == NULL)
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for username %zu", i);
-                return NULL; // Return false on memory allocation failure
-            }
-        }
-        if (messages->messages[i] == NULL)
-        {
-            messages->messages[i] = malloc(MAX_MESSAGE_LENGTH);
-            if (messages->messages[i] == NULL)
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for message %zu", i);
-                return NULL; // Return false on memory allocation failure
-            }
-        }
-    }
-    return messages;
-}
-
-static void flip_social_free_message_users()
-{
-    if (flip_social_message_users == NULL)
-    {
-        FURI_LOG_E(TAG, "Message users model is NULL");
-        return;
-    }
-    for (int i = 0; i < flip_social_message_users->count; i++)
-    {
-        free(flip_social_message_users->usernames[i]);
-    }
-}
-
-static void flip_social_free_messages()
-{
-    if (flip_social_messages == NULL)
-    {
-        FURI_LOG_E(TAG, "Messages model is NULL");
-        return;
-    }
-    for (int i = 0; i < flip_social_messages->count; i++)
-    {
-        free(flip_social_messages->usernames[i]);
-        free(flip_social_messages->messages[i]);
-    }
-}
-
-static bool flip_social_update_messages_submenu()
-{
-    if (app_instance->submenu_messages == NULL)
-    {
-        FURI_LOG_E(TAG, "Submenu is NULL");
-        return false;
-    }
-    if (flip_social_message_users == NULL)
-    {
-        FURI_LOG_E(TAG, "Message users model is NULL");
-        return false;
-    }
-    submenu_reset(app_instance->submenu_messages);
-    submenu_set_header(app_instance->submenu_messages, "Messages");
-    submenu_add_item(app_instance->submenu_messages, "[New Message]", FlipSocialSubmenuLoggedInIndexMessagesNewMessage, flip_social_callback_submenu_choices, app_instance);
-    for (int i = 0; i < flip_social_message_users->count; i++)
-    {
-        submenu_add_item(app_instance->submenu_messages, flip_social_message_users->usernames[i], FlipSocialSubmenuLoggedInIndexMessagesUsersStart + i, flip_social_callback_submenu_choices, app_instance);
-    }
-    return true;
-}
-
-static bool flip_social_update_submenu_user_choices()
-{
-    if (app_instance->submenu_messages_user_choices == NULL)
-    {
-        FURI_LOG_E(TAG, "Submenu is NULL");
-        return false;
-    }
-    if (flip_social_explore == NULL)
-    {
-        FURI_LOG_E(TAG, "Explore model is NULL");
-        return false;
-    }
-    submenu_reset(app_instance->submenu_messages_user_choices);
-    submenu_set_header(app_instance->submenu_messages_user_choices, "Users");
-    for (int i = 0; i < flip_social_explore->count; i++)
-    {
-        submenu_add_item(app_instance->submenu_messages_user_choices, flip_social_explore->usernames[i], FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart + i, flip_social_callback_submenu_choices, app_instance);
-    }
-    return true;
-}
-
-// Get all the users that have sent messages to the logged in user
-static bool flip_social_get_message_users()
-{
-    if (app_instance->login_username_logged_out == NULL)
-    {
-        FURI_LOG_E(TAG, "Username is NULL");
-        return false;
-    }
-    char command[128];
-    snprintf(command, 128, "https://www.flipsocial.net/api/messages/%s/get/list/", app_instance->login_username_logged_out);
-    bool success = flipper_http_get_request_with_headers(command, "{\"Content-Type\":\"application/json\"}");
-    if (!success)
-    {
-        FURI_LOG_E(TAG, "Failed to send HTTP request for messages");
-        return false;
-    }
-    fhttp.state = RECEIVING;
-    return true;
-}
-
-// Get all the messages between the logged in user and the selected user
-static bool flip_social_get_messages_with_user()
-{
-    if (app_instance->login_username_logged_out == NULL)
-    {
-        FURI_LOG_E(TAG, "Username is NULL");
-        return false;
-    }
-    char command[128];
-    snprintf(command, 128, "https://www.flipsocial.net/api/messages/%s/get/%s/", app_instance->login_username_logged_out, flip_social_message_users->usernames[flip_social_message_users->index]);
-    bool success = flipper_http_get_request_with_headers(command, "{\"Content-Type\":\"application/json\"}");
-    if (!success)
-    {
-        FURI_LOG_E(TAG, "Failed to send HTTP request for messages");
-        return false;
-    }
-    fhttp.state = RECEIVING;
-    return true;
-}
-
-// Parse the users that have sent messages to the logged-in user
-static bool flip_social_parse_json_message_users()
-{
-    if (fhttp.received_data == NULL)
-    {
-        FURI_LOG_E(TAG, "No data received.");
-        return false;
-    }
-
-    // Allocate memory for each username only if not already allocated
-    flip_social_message_users = flip_social_messages_alloc();
-    if (flip_social_message_users == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to allocate memory for message users.");
-        return false;
-    }
-
-    // Remove newlines
-    char *pos = fhttp.received_data;
-    while ((pos = strchr(pos, '\n')) != NULL)
-    {
-        *pos = ' ';
-    }
-
-    // Initialize message users count
-    flip_social_message_users->count = 0;
-
-    // Extract the users array from the JSON
-    char *json_users = get_json_value("users", fhttp.received_data, MAX_TOKENS);
-    if (json_users == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to parse users array.");
-        return false;
-    }
-
-    // Manual tokenization for comma-separated values
-    char *start = json_users + 1; // Skip the opening bracket
-    char *end;
-    while ((end = strchr(start, ',')) != NULL && flip_social_message_users->count < MAX_MESSAGE_USERS)
-    {
-        *end = '\0'; // Null-terminate the current token
-
-        // Remove quotes
-        if (*start == '"')
-            start++;
-        if (*(end - 1) == '"')
-            *(end - 1) = '\0';
-
-        // Copy username to pre-allocated memory
-        strncpy(flip_social_message_users->usernames[flip_social_message_users->count], start, MAX_USER_LENGTH - 1);
-        flip_social_message_users->usernames[flip_social_message_users->count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        flip_social_message_users->count++;
-        start = end + 1;
-    }
-
-    // Handle the last token
-    if (*start != '\0' && flip_social_message_users->count < MAX_MESSAGE_USERS)
-    {
-        if (*start == '"')
-            start++;
-        if (*(start + strlen(start) - 1) == ']')
-            *(start + strlen(start) - 1) = '\0';
-        if (*(start + strlen(start) - 1) == '"')
-            *(start + strlen(start) - 1) = '\0';
-
-        strncpy(flip_social_message_users->usernames[flip_social_message_users->count], start, MAX_USER_LENGTH - 1);
-        flip_social_message_users->usernames[flip_social_message_users->count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        flip_social_message_users->count++;
-    }
-
-    // Add submenu items for the users
-    flip_social_update_messages_submenu();
-
-    // Free the JSON data
-    free(json_users);
-    free(start);
-    free(end);
-
-    return true;
-}
-
-// Parse the users that the logged in user can message
-static bool flip_social_parse_json_message_user_choices()
-{
-    if (fhttp.received_data == NULL)
-    {
-        FURI_LOG_E(TAG, "No data received.");
-        return false;
-    }
-
-    // Allocate memory for each username only if not already allocated
-    flip_social_explore = flip_social_explore_alloc();
-    if (flip_social_explore == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to allocate memory for explore usernames.");
-        return false;
-    }
-
-    // Remove newlines
-    char *pos = fhttp.received_data;
-    while ((pos = strchr(pos, '\n')) != NULL)
-    {
-        *pos = ' ';
-    }
-
-    // Initialize explore count
-    flip_social_explore->count = 0;
-
-    // Extract the users array from the JSON
-    char *json_users = get_json_value("users", fhttp.received_data, MAX_TOKENS);
-    if (json_users == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to parse users array.");
-        return false;
-    }
-
-    // Manual tokenization for comma-separated values
-    char *start = json_users + 1; // Skip the opening bracket
-    char *end;
-    while ((end = strchr(start, ',')) != NULL && flip_social_explore->count < MAX_EXPLORE_USERS)
-    {
-        *end = '\0'; // Null-terminate the current token
-
-        // Remove quotes
-        if (*start == '"')
-            start++;
-        if (*(end - 1) == '"')
-            *(end - 1) = '\0';
-
-        // Copy username to pre-allocated memory
-        strncpy(flip_social_explore->usernames[flip_social_explore->count], start, MAX_USER_LENGTH - 1);
-        flip_social_explore->usernames[flip_social_explore->count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        flip_social_explore->count++;
-        start = end + 1;
-    }
-
-    // Handle the last token
-    if (*start != '\0' && flip_social_explore->count < MAX_EXPLORE_USERS)
-    {
-        if (*start == '"')
-            start++;
-        if (*(start + strlen(start) - 1) == ']')
-            *(start + strlen(start) - 1) = '\0';
-        if (*(start + strlen(start) - 1) == '"')
-            *(start + strlen(start) - 1) = '\0';
-
-        strncpy(flip_social_explore->usernames[flip_social_explore->count], start, MAX_USER_LENGTH - 1);
-        flip_social_explore->usernames[flip_social_explore->count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        flip_social_explore->count++;
-    }
-
-    // Add submenu items for the users
-    flip_social_update_submenu_user_choices();
-
-    // Free the JSON data
-    free(json_users);
-    free(start);
-    free(end);
-
-    return true;
-}
-
-// parse messages between the logged in user and the selected user
-static bool flip_social_parse_json_messages()
-{
-    if (fhttp.received_data == NULL)
-    {
-        FURI_LOG_E(TAG, "No data received.");
-        return false;
-    }
-
-    // Allocate memory for each message only if not already allocated
-    flip_social_messages = flip_social_user_messages_alloc();
-    if (!flip_social_messages)
-    {
-        FURI_LOG_E(TAG, "Failed to allocate memory for messages.");
-        return false;
-    }
-
-    // Remove newlines
-    char *pos = fhttp.received_data;
-    while ((pos = strchr(pos, '\n')) != NULL)
-    {
-        *pos = ' ';
-    }
-
-    // Initialize messages count
-    flip_social_messages->count = 0;
-
-    // Iterate through the messages array
-    for (int i = 0; i < MAX_MESSAGES; i++)
-    {
-        // Parse each item in the array
-        char *item = get_json_array_value("conversations", i, fhttp.received_data, MAX_TOKENS);
-        if (item == NULL)
-        {
-            break;
-        }
-
-        // Extract individual fields from the JSON object
-        char *sender = get_json_value("sender", item, MAX_TOKENS);
-        char *content = get_json_value("content", item, MAX_TOKENS);
-
-        if (sender == NULL || content == NULL)
-        {
-            FURI_LOG_E(TAG, "Failed to parse item fields.");
-            free(item);
-            continue;
-        }
-
-        // Store parsed values
-        strncpy(flip_social_messages->usernames[i], sender, MAX_USER_LENGTH - 1);
-        flip_social_messages->usernames[i][MAX_USER_LENGTH - 1] = '\0';
-        strncpy(flip_social_messages->messages[i], content, MAX_MESSAGE_LENGTH - 1);
-        flip_social_messages->messages[i][MAX_MESSAGE_LENGTH - 1] = '\0';
-        flip_social_messages->count++;
-
-        free(item);
-        free(sender);
-        free(content);
-    }
-
-    return true;
-}
-
-#endif // FLIP_SOCIAL_MESSAGES_H

+ 0 - 381
flip_social_storage.h

@@ -1,381 +0,0 @@
-// flip_social_storage.h
-#ifndef FLIP_SOCIAL_STORAGE_H
-#define FLIP_SOCIAL_STORAGE_H
-
-#include <furi.h>
-#include <storage/storage.h>
-
-#define SETTINGS_PATH STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/settings.bin"
-#define PRE_SAVED_MESSAGES_PATH STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/pre_saved_messages.txt"
-
-// Function to save the playlist
-void save_playlist(const PreSavedPlaylist *playlist)
-{
-    if (!playlist)
-    {
-        FURI_LOG_E(TAG, "Playlist is NULL");
-        return;
-    }
-    // Create the directory for saving settings
-    char directory_path[128];
-    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social");
-
-    // Create the directory
-    Storage *storage = furi_record_open(RECORD_STORAGE);
-    storage_common_mkdir(storage, directory_path);
-
-    // Open the settings file
-    File *file = storage_file_alloc(storage);
-    if (!storage_file_open(file, PRE_SAVED_MESSAGES_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS))
-    {
-        FURI_LOG_E(TAG, "Failed to open settings file for writing: %s", PRE_SAVED_MESSAGES_PATH);
-        storage_file_free(file);
-        furi_record_close(RECORD_STORAGE);
-        return;
-    }
-
-    // Write each playlist message on a separate line
-    for (size_t i = 0; i < playlist->count; ++i)
-    {
-        // Add a newline character after each message
-        if (storage_file_write(file, playlist->messages[i], strlen(playlist->messages[i])) != strlen(playlist->messages[i]))
-        {
-            FURI_LOG_E(TAG, "Failed to write playlist message %zu", i);
-        }
-
-        // Write a newline after each message
-        if (storage_file_write(file, "\n", 1) != 1)
-        {
-            FURI_LOG_E(TAG, "Failed to write newline after message %zu", i);
-        }
-    }
-
-    storage_file_close(file);
-    storage_file_free(file);
-    furi_record_close(RECORD_STORAGE);
-}
-
-// Function to load the playlist
-// Function to load the playlist
-bool load_playlist(PreSavedPlaylist *playlist)
-{
-    // Ensure playlist is not NULL
-    if (!playlist)
-    {
-        FURI_LOG_E(TAG, "Playlist is NULL");
-        return false;
-    }
-
-    // Ensure playlist->messages is not NULL and allocate memory for each message
-    for (size_t i = 0; i < MAX_PRE_SAVED_MESSAGES; ++i)
-    {
-        if (!playlist->messages[i]) // Check if memory is already allocated
-        {
-            playlist->messages[i] = (char *)malloc(MAX_MESSAGE_LENGTH * sizeof(char));
-            if (!playlist->messages[i])
-            {
-                FURI_LOG_E(TAG, "Failed to allocate memory for message %zu", i);
-                return false; // Return false on memory allocation failure
-            }
-        }
-    }
-
-    // Open the storage
-    Storage *storage = furi_record_open(RECORD_STORAGE);
-    File *file = storage_file_alloc(storage);
-
-    if (!storage_file_open(file, PRE_SAVED_MESSAGES_PATH, FSAM_READ, FSOM_OPEN_EXISTING))
-    {
-        FURI_LOG_E(TAG, "Failed to open pre-saved messages file for reading: %s", PRE_SAVED_MESSAGES_PATH);
-        storage_file_free(file);
-        furi_record_close(RECORD_STORAGE);
-        return false; // Return false if the file does not exist
-    }
-
-    // Initialize the playlist count
-    playlist->count = 0;
-
-    // Read the file byte by byte to simulate reading lines
-    char ch;
-    size_t message_pos = 0;
-    bool message_started = false;
-
-    while (storage_file_read(file, &ch, 1) == 1) // Read one character at a time
-    {
-        message_started = true;
-
-        if (ch == '\n' || message_pos >= (MAX_MESSAGE_LENGTH - 1)) // End of line or message is too long
-        {
-            playlist->messages[playlist->count][message_pos] = '\0'; // Null-terminate the message
-            playlist->count++;                                       // Move to the next message
-            message_pos = 0;                                         // Reset for the next message
-            message_started = false;
-
-            // Ensure the playlist count does not exceed the maximum
-            if (playlist->count >= MAX_PRE_SAVED_MESSAGES)
-            {
-                FURI_LOG_W(TAG, "Reached maximum playlist messages");
-                break;
-            }
-        }
-        else
-        {
-            playlist->messages[playlist->count][message_pos++] = ch; // Add character to current message
-        }
-    }
-
-    // Handle the case where the last message does not end with a newline
-    if (message_started && message_pos > 0)
-    {
-        playlist->messages[playlist->count][message_pos] = '\0'; // Null-terminate the last message
-        playlist->count++;                                       // Increment the count for the last message
-
-        // Ensure the playlist count does not exceed the maximum
-        if (playlist->count >= MAX_PRE_SAVED_MESSAGES)
-        {
-            FURI_LOG_W(TAG, "Reached maximum playlist messages");
-        }
-    }
-
-    // Close the file and storage
-    storage_file_close(file);
-    storage_file_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return true;
-}
-static void save_settings(
-    const char *ssid,
-    const char *password,
-    const char *login_username_logged_out,
-    const char *login_username_logged_in,
-    const char *login_password_logged_out,
-    const char *change_password_logged_in,
-    const char *is_logged_in)
-{
-    // Create the directory for saving settings
-    char directory_path[128];
-    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social");
-
-    // Create the directory
-    Storage *storage = furi_record_open(RECORD_STORAGE);
-    storage_common_mkdir(storage, directory_path);
-
-    // Open the settings file
-    File *file = storage_file_alloc(storage);
-    if (!storage_file_open(file, SETTINGS_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS))
-    {
-        FURI_LOG_E(TAG, "Failed to open settings file for writing: %s", SETTINGS_PATH);
-        storage_file_free(file);
-        furi_record_close(RECORD_STORAGE);
-        return;
-    }
-
-    // Save the ssid length and data
-    size_t ssid_length = strlen(ssid) + 1; // Include null terminator
-    if (storage_file_write(file, &ssid_length, sizeof(size_t)) != sizeof(size_t) ||
-        storage_file_write(file, ssid, ssid_length) != ssid_length)
-    {
-        FURI_LOG_E(TAG, "Failed to write SSID");
-    }
-
-    // Save the password length and data
-    size_t password_length = strlen(password) + 1; // Include null terminator
-    if (storage_file_write(file, &password_length, sizeof(size_t)) != sizeof(size_t) ||
-        storage_file_write(file, password, password_length) != password_length)
-    {
-        FURI_LOG_E(TAG, "Failed to write password");
-    }
-
-    // Save the login_username_logged_out length and data
-    size_t username_out_length = strlen(login_username_logged_out) + 1; // Include null terminator
-    if (storage_file_write(file, &username_out_length, sizeof(size_t)) != sizeof(size_t) ||
-        storage_file_write(file, login_username_logged_out, username_out_length) != username_out_length)
-    {
-        FURI_LOG_E(TAG, "Failed to write login_username_logged_out");
-    }
-
-    // Save the login_username_logged_in length and data
-    size_t username_in_length = strlen(login_username_logged_in) + 1; // Include null terminator
-    if (storage_file_write(file, &username_in_length, sizeof(size_t)) != sizeof(size_t) ||
-        storage_file_write(file, login_username_logged_in, username_in_length) != username_in_length)
-    {
-        FURI_LOG_E(TAG, "Failed to write login_username_logged_in");
-    }
-
-    // Save the login_password_logged_out length and data
-    size_t password_out_length = strlen(login_password_logged_out) + 1; // Include null terminator
-    if (storage_file_write(file, &password_out_length, sizeof(size_t)) != sizeof(size_t) ||
-        storage_file_write(file, login_password_logged_out, password_out_length) != password_out_length)
-    {
-        FURI_LOG_E(TAG, "Failed to write login_password_logged_out");
-    }
-
-    // Save the change_password_logged_in length and data
-    size_t change_password_length = strlen(change_password_logged_in) + 1; // Include null terminator
-    if (storage_file_write(file, &change_password_length, sizeof(size_t)) != sizeof(size_t) ||
-        storage_file_write(file, change_password_logged_in, change_password_length) != change_password_length)
-    {
-        FURI_LOG_E(TAG, "Failed to write change_password_logged_in");
-    }
-
-    // Save the is_logged_in length and data
-    size_t is_logged_in_length = strlen(is_logged_in) + 1; // Include null terminator
-    if (storage_file_write(file, &is_logged_in_length, sizeof(size_t)) != sizeof(size_t) ||
-        storage_file_write(file, is_logged_in, is_logged_in_length) != is_logged_in_length)
-    {
-        FURI_LOG_E(TAG, "Failed to write is_logged_in");
-    }
-
-    storage_file_close(file);
-    storage_file_free(file);
-    furi_record_close(RECORD_STORAGE);
-}
-
-static bool load_settings(
-    char *ssid,
-    size_t ssid_size,
-    char *password,
-    size_t password_size,
-    char *login_username_logged_out,
-    size_t username_out_size,
-    char *login_username_logged_in,
-    size_t username_in_size,
-    char *login_password_logged_out,
-    size_t password_out_size,
-    char *change_password_logged_in,
-    size_t change_password_size,
-    char *is_logged_in,
-    size_t is_logged_in_size)
-{
-    Storage *storage = furi_record_open(RECORD_STORAGE);
-    File *file = storage_file_alloc(storage);
-
-    if (!storage_file_open(file, SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING))
-    {
-        FURI_LOG_E(TAG, "Failed to open settings file for reading: %s", SETTINGS_PATH);
-        storage_file_free(file);
-        furi_record_close(RECORD_STORAGE);
-        return false; // Return false if the file does not exist
-    }
-
-    // Load the ssid
-    size_t ssid_length;
-    if (storage_file_read(file, &ssid_length, sizeof(size_t)) != sizeof(size_t) || ssid_length > ssid_size ||
-        storage_file_read(file, ssid, ssid_length) != ssid_length)
-    {
-        FURI_LOG_E(TAG, "Failed to read SSID");
-        storage_file_close(file);
-        storage_file_free(file);
-        furi_record_close(RECORD_STORAGE);
-        return false;
-    }
-    else
-    {
-        ssid[ssid_length - 1] = '\0'; // Ensure null-termination
-    }
-
-    // Load the password
-    size_t password_length;
-    if (storage_file_read(file, &password_length, sizeof(size_t)) != sizeof(size_t) || password_length > password_size ||
-        storage_file_read(file, password, password_length) != password_length)
-    {
-        FURI_LOG_E(TAG, "Failed to read password");
-        storage_file_close(file);
-        storage_file_free(file);
-        furi_record_close(RECORD_STORAGE);
-        return false;
-    }
-    else
-    {
-        password[password_length - 1] = '\0'; // Ensure null-termination
-    }
-
-    // Load the login_username_logged_out
-    size_t username_out_length;
-    if (storage_file_read(file, &username_out_length, sizeof(size_t)) != sizeof(size_t) || username_out_length > username_out_size ||
-        storage_file_read(file, login_username_logged_out, username_out_length) != username_out_length)
-    {
-        FURI_LOG_E(TAG, "Failed to read login_username_logged_out");
-        // storage_file_close(file);
-        // storage_file_free(file);
-        // furi_record_close(RECORD_STORAGE);
-        // return false;
-    }
-    else
-    {
-        login_username_logged_out[username_out_length - 1] = '\0'; // Ensure null-termination
-    }
-
-    // Load the login_username_logged_in
-    size_t username_in_length;
-    if (storage_file_read(file, &username_in_length, sizeof(size_t)) != sizeof(size_t) || username_in_length > username_in_size ||
-        storage_file_read(file, login_username_logged_in, username_in_length) != username_in_length)
-    {
-        FURI_LOG_E(TAG, "Failed to read login_username_logged_in");
-        // storage_file_close(file);
-        // storage_file_free(file);
-        // furi_record_close(RECORD_STORAGE);
-        // return false;
-    }
-    else
-    {
-        login_username_logged_in[username_in_length - 1] = '\0'; // Ensure null-termination
-    }
-
-    // Load the login_password_logged_out
-    size_t password_out_length;
-    if (storage_file_read(file, &password_out_length, sizeof(size_t)) != sizeof(size_t) || password_out_length > password_out_size ||
-        storage_file_read(file, login_password_logged_out, password_out_length) != password_out_length)
-    {
-        FURI_LOG_E(TAG, "Failed to read login_password_logged_out");
-        // storage_file_close(file);
-        // storage_file_free(file);
-        // furi_record_close(RECORD_STORAGE);
-        // return false;
-    }
-    else
-    {
-        login_password_logged_out[password_out_length - 1] = '\0'; // Ensure null-termination
-    }
-
-    // Load the change_password_logged_in
-    size_t change_password_length;
-    if (storage_file_read(file, &change_password_length, sizeof(size_t)) != sizeof(size_t) || change_password_length > change_password_size ||
-        storage_file_read(file, change_password_logged_in, change_password_length) != change_password_length)
-    {
-        FURI_LOG_E(TAG, "Failed to read change_password_logged_in");
-        // storage_file_close(file);
-        // storage_file_free(file);
-        // furi_record_close(RECORD_STORAGE);
-        //  return false;
-    }
-    else
-    {
-        change_password_logged_in[change_password_length - 1] = '\0'; // Ensure null-termination
-    }
-
-    // Load the is_logged_in
-    size_t is_logged_in_length;
-    if (storage_file_read(file, &is_logged_in_length, sizeof(size_t)) != sizeof(size_t) || is_logged_in_length > is_logged_in_size ||
-        storage_file_read(file, is_logged_in, is_logged_in_length) != is_logged_in_length)
-    {
-        FURI_LOG_E(TAG, "Failed to read is_logged_in");
-        // storage_file_close(file);
-        // storage_file_free(file);
-        // furi_record_close(RECORD_STORAGE);
-        //  return false;
-    }
-    else
-    {
-        is_logged_in[is_logged_in_length - 1] = '\0'; // Ensure null-termination
-    }
-
-    storage_file_close(file);
-    storage_file_free(file);
-    furi_record_close(RECORD_STORAGE);
-
-    return true;
-}
-
-#endif // FLIP_SOCIAL_STORAGE_H

+ 0 - 1197
flipper_http.h

@@ -1,1197 +0,0 @@
-// flipper_http.h
-#ifndef FLIPPER_HTTP_H
-#define FLIPPER_HTTP_H
-
-#include <furi.h>
-#include <furi_hal.h>
-#include <furi_hal_gpio.h>
-#include <furi_hal_serial.h>
-#include <storage/storage.h>
-
-// STORAGE_EXT_PATH_PREFIX is defined in the Furi SDK as /ext
-
-#define HTTP_TAG "FlipSocial"             // change this to your app name
-#define http_tag "flip_social"            // change this to your app id
-#define UART_CH (FuriHalSerialIdUsart)    // UART channel
-#define TIMEOUT_DURATION_TICKS (6 * 1000) // 6 seconds
-#define BAUDRATE (115200)                 // UART baudrate
-#define RX_BUF_SIZE 128                   // UART RX buffer size
-#define RX_LINE_BUFFER_SIZE 8192          // UART RX line buffer size (increase for large responses)
-
-// Forward declaration for callback
-typedef void (*FlipperHTTP_Callback)(const char *line, void *context);
-
-// Functions
-bool flipper_http_init(FlipperHTTP_Callback callback, void *context);
-void flipper_http_deinit();
-//---
-void flipper_http_rx_callback(const char *line, void *context);
-bool flipper_http_send_data(const char *data);
-//---
-bool flipper_http_connect_wifi();
-bool flipper_http_disconnect_wifi();
-bool flipper_http_ping();
-bool flipper_http_scan_wifi();
-bool flipper_http_save_wifi(const char *ssid, const char *password);
-//---
-bool flipper_http_get_request(const char *url);
-bool flipper_http_get_request_with_headers(const char *url, const char *headers);
-bool flipper_http_post_request_with_headers(const char *url, const char *headers, const char *payload);
-bool flipper_http_put_request_with_headers(const char *url, const char *headers, const char *payload);
-bool flipper_http_delete_request_with_headers(const char *url, const char *headers, const char *payload);
-//---
-bool flipper_http_save_received_data(size_t bytes_received, const char line_buffer[]);
-static char *trim(const char *str);
-//
-bool flipper_http_process_response_async(
-    bool (*http_request)(void),
-    bool (*parse_json)(void));
-
-// State variable to track the UART state
-typedef enum
-{
-    INACTIVE,  // Inactive state
-    IDLE,      // Default state
-    RECEIVING, // Receiving data
-    SENDING,   // Sending data
-    ISSUE,     // Issue with connection
-} SerialState;
-
-// Event Flags for UART Worker Thread
-typedef enum
-{
-    WorkerEvtStop = (1 << 0),
-    WorkerEvtRxDone = (1 << 1),
-} WorkerEvtFlags;
-
-// FlipperHTTP Structure
-typedef struct
-{
-    FuriStreamBuffer *flipper_http_stream;  // Stream buffer for UART communication
-    FuriHalSerialHandle *serial_handle;     // Serial handle for UART communication
-    FuriThread *rx_thread;                  // Worker thread for UART
-    uint8_t rx_buf[RX_BUF_SIZE];            // Buffer for received data
-    FuriThreadId rx_thread_id;              // Worker thread ID
-    FlipperHTTP_Callback handle_rx_line_cb; // Callback for received lines
-    void *callback_context;                 // Context for the callback
-    SerialState state;                      // State of the UART
-
-    // variable to store the last received data from the UART
-    char *last_response;
-
-    // Timer-related members
-    FuriTimer *get_timeout_timer; // Timer for HTTP request timeout
-    char *received_data;          // Buffer to store received data
-
-    bool started_receiving_get; // Indicates if a GET request has started
-    bool just_started_get;      // Indicates if GET data reception has just started
-
-    bool started_receiving_post; // Indicates if a POST request has started
-    bool just_started_post;      // Indicates if POST data reception has just started
-
-    bool started_receiving_put; // Indicates if a PUT request has started
-    bool just_started_put;      // Indicates if PUT data reception has just started
-
-    bool started_receiving_delete; // Indicates if a DELETE request has started
-    bool just_started_delete;      // Indicates if DELETE data reception has just started
-} FlipperHTTP;
-
-FlipperHTTP fhttp;
-
-// fhttp.received_data holds the received data from HTTP requests
-// fhttp.last_response holds the last received data from the UART, which could be [GET/END], [POST/END], [PUT/END], [DELETE/END], etc
-
-// Timer callback function
-/**
- * @brief      Callback function for the GET timeout timer.
- * @return     0
- * @param      context   The context to pass to the callback.
- * @note       This function will be called when the GET request times out.
- */
-void get_timeout_timer_callback(void *context)
-{
-    UNUSED(context);
-    FURI_LOG_E(HTTP_TAG, "Timeout reached: 2 seconds without receiving the end.");
-
-    // Reset the state
-    fhttp.started_receiving_get = false;
-    fhttp.started_receiving_post = false;
-    fhttp.started_receiving_put = false;
-    fhttp.started_receiving_delete = false;
-
-    // Free received data if any
-    if (fhttp.received_data)
-    {
-        free(fhttp.received_data);
-        fhttp.received_data = NULL;
-    }
-
-    // Update UART state
-    fhttp.state = ISSUE;
-}
-
-// UART RX Handler Callback (Interrupt Context)
-/**
- * @brief      A private callback function to handle received data asynchronously.
- * @return     void
- * @param      handle    The UART handle.
- * @param      event     The event type.
- * @param      context   The context to pass to the callback.
- * @note       This function will handle received data asynchronously via the callback.
- */
-static void _flipper_http_rx_callback(FuriHalSerialHandle *handle, FuriHalSerialRxEvent event, void *context)
-{
-    UNUSED(context);
-    if (event == FuriHalSerialRxEventData)
-    {
-        uint8_t data = furi_hal_serial_async_rx(handle);
-        furi_stream_buffer_send(fhttp.flipper_http_stream, &data, 1, 0);
-        furi_thread_flags_set(fhttp.rx_thread_id, WorkerEvtRxDone);
-    }
-}
-
-// UART worker thread
-/**
- * @brief      Worker thread to handle UART data asynchronously.
- * @return     0
- * @param      context   The context to pass to the callback.
- * @note       This function will handle received data asynchronously via the callback.
- */
-static int32_t flipper_http_worker(void *context)
-{
-    UNUSED(context);
-    size_t rx_line_pos = 0;
-    char *rx_line_buffer = (char *)malloc(RX_LINE_BUFFER_SIZE);
-
-    if (!rx_line_buffer)
-    {
-        // Handle malloc failure
-        FURI_LOG_E(HTTP_TAG, "Failed to allocate memory for rx_line_buffer");
-        return -1;
-    }
-
-    while (1)
-    {
-        uint32_t events = furi_thread_flags_wait(WorkerEvtStop | WorkerEvtRxDone, FuriFlagWaitAny, FuriWaitForever);
-        if (events & WorkerEvtStop)
-            break;
-        if (events & WorkerEvtRxDone)
-        {
-            size_t len = furi_stream_buffer_receive(fhttp.flipper_http_stream, fhttp.rx_buf, RX_BUF_SIZE + 1, 0);
-            for (size_t i = 0; i < len; i++)
-            {
-                char c = fhttp.rx_buf[i];
-                if (c == '\n' || rx_line_pos >= RX_LINE_BUFFER_SIZE - 1)
-                {
-                    rx_line_buffer[rx_line_pos] = '\0';
-                    // Invoke the callback with the complete line
-                    if (fhttp.handle_rx_line_cb)
-                    {
-                        fhttp.handle_rx_line_cb(rx_line_buffer, fhttp.callback_context);
-                    }
-                    // Reset the line buffer
-                    rx_line_pos = 0;
-                }
-                else
-                {
-                    rx_line_buffer[rx_line_pos++] = c;
-                }
-            }
-        }
-    }
-
-    // Free the allocated memory before exiting the thread
-    free(rx_line_buffer);
-
-    return 0;
-}
-
-// UART initialization function
-/**
- * @brief      Initialize UART.
- * @return     true if the UART was initialized successfully, false otherwise.
- * @param      callback  The callback function to handle received data (ex. flipper_http_rx_callback).
- * @param      context   The context to pass to the callback.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_init(FlipperHTTP_Callback callback, void *context)
-{
-    if (!context)
-    {
-        FURI_LOG_E(HTTP_TAG, "Invalid context provided to flipper_http_init.");
-        return false;
-    }
-    if (!callback)
-    {
-        FURI_LOG_E(HTTP_TAG, "Invalid callback provided to flipper_http_init.");
-        return false;
-    }
-    fhttp.flipper_http_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
-    if (!fhttp.flipper_http_stream)
-    {
-        FURI_LOG_E(HTTP_TAG, "Failed to allocate UART stream buffer.");
-        return false;
-    }
-
-    fhttp.rx_thread = furi_thread_alloc();
-    if (!fhttp.rx_thread)
-    {
-        FURI_LOG_E(HTTP_TAG, "Failed to allocate UART thread.");
-        furi_stream_buffer_free(fhttp.flipper_http_stream);
-        return false;
-    }
-
-    furi_thread_set_name(fhttp.rx_thread, "FlipperHTTP_RxThread");
-    furi_thread_set_stack_size(fhttp.rx_thread, 1024);
-    furi_thread_set_context(fhttp.rx_thread, &fhttp);
-    furi_thread_set_callback(fhttp.rx_thread, flipper_http_worker);
-
-    fhttp.handle_rx_line_cb = callback;
-    fhttp.callback_context = context;
-
-    furi_thread_start(fhttp.rx_thread);
-    fhttp.rx_thread_id = furi_thread_get_id(fhttp.rx_thread);
-
-    // handle when the UART control is busy to avoid furi_check failed
-    if (furi_hal_serial_control_is_busy(UART_CH))
-    {
-        FURI_LOG_E(HTTP_TAG, "UART control is busy.");
-        return false;
-    }
-
-    fhttp.serial_handle = furi_hal_serial_control_acquire(UART_CH);
-    if (!fhttp.serial_handle)
-    {
-        FURI_LOG_E(HTTP_TAG, "Failed to acquire UART control - handle is NULL");
-        // Cleanup resources
-        furi_thread_free(fhttp.rx_thread);
-        furi_stream_buffer_free(fhttp.flipper_http_stream);
-        return false;
-    }
-
-    // Initialize UART with acquired handle
-    furi_hal_serial_init(fhttp.serial_handle, BAUDRATE);
-
-    // Enable RX direction
-    furi_hal_serial_enable_direction(fhttp.serial_handle, FuriHalSerialDirectionRx);
-
-    // Start asynchronous RX with the callback
-    furi_hal_serial_async_rx_start(fhttp.serial_handle, _flipper_http_rx_callback, &fhttp, false);
-
-    // Wait for the TX to complete to ensure UART is ready
-    furi_hal_serial_tx_wait_complete(fhttp.serial_handle);
-
-    // Allocate the timer for handling timeouts
-    fhttp.get_timeout_timer = furi_timer_alloc(
-        get_timeout_timer_callback, // Callback function
-        FuriTimerTypeOnce,          // One-shot timer
-        &fhttp                      // Context passed to callback
-    );
-
-    if (!fhttp.get_timeout_timer)
-    {
-        FURI_LOG_E(HTTP_TAG, "Failed to allocate HTTP request timeout timer.");
-        // Cleanup resources
-        furi_hal_serial_async_rx_stop(fhttp.serial_handle);
-        furi_hal_serial_disable_direction(fhttp.serial_handle, FuriHalSerialDirectionRx);
-        furi_hal_serial_control_release(fhttp.serial_handle);
-        furi_hal_serial_deinit(fhttp.serial_handle);
-        furi_thread_flags_set(fhttp.rx_thread_id, WorkerEvtStop);
-        furi_thread_join(fhttp.rx_thread);
-        furi_thread_free(fhttp.rx_thread);
-        furi_stream_buffer_free(fhttp.flipper_http_stream);
-        return false;
-    }
-
-    // Set the timer thread priority if needed
-    furi_timer_set_thread_priority(FuriTimerThreadPriorityElevated);
-
-    // FURI_LOG_I(HTTP_TAG, "UART initialized successfully.");
-    return true;
-}
-
-// Deinitialize UART
-/**
- * @brief      Deinitialize UART.
- * @return     void
- * @note       This function will stop the asynchronous RX, release the serial handle, and free the resources.
- */
-void flipper_http_deinit()
-{
-    if (fhttp.serial_handle == NULL)
-    {
-        FURI_LOG_E(HTTP_TAG, "UART handle is NULL. Already deinitialized?");
-        return;
-    }
-    // Stop asynchronous RX
-    furi_hal_serial_async_rx_stop(fhttp.serial_handle);
-
-    // Release and deinitialize the serial handle
-    furi_hal_serial_disable_direction(fhttp.serial_handle, FuriHalSerialDirectionRx);
-    furi_hal_serial_control_release(fhttp.serial_handle);
-    furi_hal_serial_deinit(fhttp.serial_handle);
-
-    // Signal the worker thread to stop
-    furi_thread_flags_set(fhttp.rx_thread_id, WorkerEvtStop);
-    // Wait for the thread to finish
-    furi_thread_join(fhttp.rx_thread);
-    // Free the thread resources
-    furi_thread_free(fhttp.rx_thread);
-
-    // Free the stream buffer
-    furi_stream_buffer_free(fhttp.flipper_http_stream);
-
-    // Free the timer
-    if (fhttp.get_timeout_timer)
-    {
-        furi_timer_free(fhttp.get_timeout_timer);
-        fhttp.get_timeout_timer = NULL;
-    }
-
-    // Free received data if any
-    if (fhttp.received_data)
-    {
-        free(fhttp.received_data);
-        fhttp.received_data = NULL;
-    }
-
-    // Free the last response
-    if (fhttp.last_response)
-    {
-        free(fhttp.last_response);
-        fhttp.last_response = NULL;
-    }
-
-    // FURI_LOG_I("FlipperHTTP", "UART deinitialized successfully.");
-}
-
-// Function to send data over UART with newline termination
-/**
- * @brief      Send data over UART with newline termination.
- * @return     true if the data was sent successfully, false otherwise.
- * @param      data  The data to send over UART.
- * @note       The data will be sent over UART with a newline character appended.
- */
-bool flipper_http_send_data(const char *data)
-{
-    size_t data_length = strlen(data);
-    if (data_length == 0)
-    {
-        FURI_LOG_E("FlipperHTTP", "Attempted to send empty data.");
-        return false;
-    }
-
-    // Create a buffer with data + '\n'
-    size_t send_length = data_length + 1; // +1 for '\n'
-    if (send_length > 256)
-    { // Ensure buffer size is sufficient
-        FURI_LOG_E("FlipperHTTP", "Data too long to send over FHTTP.");
-        return false;
-    }
-
-    char send_buffer[257]; // 256 + 1 for safety
-    strncpy(send_buffer, data, 256);
-    send_buffer[data_length] = '\n';     // Append newline
-    send_buffer[data_length + 1] = '\0'; // Null-terminate
-
-    if (fhttp.state == INACTIVE && ((strstr(send_buffer, "[PING]") == NULL) && (strstr(send_buffer, "[WIFI/CONNECT]") == NULL)))
-    {
-        FURI_LOG_E("FlipperHTTP", "Cannot send data while INACTIVE.");
-        fhttp.last_response = "Cannot send data while INACTIVE.";
-        return false;
-    }
-
-    fhttp.state = SENDING;
-    furi_hal_serial_tx(fhttp.serial_handle, (const uint8_t *)send_buffer, send_length);
-
-    // Uncomment below line to log the data sent over UART
-    // FURI_LOG_I("FlipperHTTP", "Sent data over UART: %s", send_buffer);
-    fhttp.state = IDLE;
-    return true;
-}
-
-// Function to send a PING request
-/**
- * @brief      Send a PING request to check if the Wifi Dev Board is connected.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- * @note       This is best used to check if the Wifi Dev Board is connected.
- * @note       The state will remain INACTIVE until a PONG is received.
- */
-bool flipper_http_ping()
-{
-    const char *command = "[PING]";
-    if (!flipper_http_send_data(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send PING command.");
-        return false;
-    }
-    // set state as INACTIVE to be made IDLE if PONG is received
-    fhttp.state = INACTIVE;
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-
-// Function to scan for WiFi networks
-/**
- * @brief      Send a command to scan for WiFi networks.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_scan_wifi()
-{
-    const char *command = "[WIFI/SCAN]";
-    if (!flipper_http_send_data(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send WiFi scan command.");
-        return false;
-    }
-
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-
-// Function to save WiFi settings (returns true if successful)
-/**
- * @brief      Send a command to save WiFi settings.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_save_wifi(const char *ssid, const char *password)
-{
-    if (!ssid || !password)
-    {
-        FURI_LOG_E("FlipperHTTP", "Invalid arguments provided to flipper_http_save_wifi.");
-        return false;
-    }
-    char buffer[256];
-    int ret = snprintf(buffer, sizeof(buffer), "[WIFI/SAVE]{\"ssid\":\"%s\",\"password\":\"%s\"}", ssid, password);
-    if (ret < 0 || ret >= (int)sizeof(buffer))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to format WiFi save command.");
-        return false;
-    }
-
-    if (!flipper_http_send_data(buffer))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send WiFi save command.");
-        return false;
-    }
-
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-
-// Function to disconnect from WiFi (returns true if successful)
-/**
- * @brief      Send a command to disconnect from WiFi.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_disconnect_wifi()
-{
-    const char *command = "[WIFI/DISCONNECT]";
-    if (!flipper_http_send_data(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send WiFi disconnect command.");
-        return false;
-    }
-
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-
-// Function to connect to WiFi (returns true if successful)
-/**
- * @brief      Send a command to connect to WiFi.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_connect_wifi()
-{
-    const char *command = "[WIFI/CONNECT]";
-    if (!flipper_http_send_data(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send WiFi connect command.");
-        return false;
-    }
-
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-
-// Function to send a GET request
-/**
- * @brief      Send a GET request to the specified URL.
- * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the GET request to.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_get_request(const char *url)
-{
-    if (!url)
-    {
-        FURI_LOG_E("FlipperHTTP", "Invalid arguments provided to flipper_http_get_request.");
-        return false;
-    }
-
-    // Prepare GET request command
-    char command[256];
-    int ret = snprintf(command, sizeof(command), "[GET]%s", url);
-    if (ret < 0 || ret >= (int)sizeof(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to format GET request command.");
-        return false;
-    }
-
-    // Send GET request via UART
-    if (!flipper_http_send_data(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send GET request command.");
-        return false;
-    }
-
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-// Function to send a GET request with headers
-/**
- * @brief      Send a GET request to the specified URL.
- * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the GET request to.
- * @param      headers  The headers to send with the GET request.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_get_request_with_headers(const char *url, const char *headers)
-{
-    if (!url || !headers)
-    {
-        FURI_LOG_E("FlipperHTTP", "Invalid arguments provided to flipper_http_get_request_with_headers.");
-        return false;
-    }
-
-    // Prepare GET request command with headers
-    char command[256];
-    int ret = snprintf(command, sizeof(command), "[GET/HTTP]{\"url\":\"%s\",\"headers\":%s}", url, headers);
-    if (ret < 0 || ret >= (int)sizeof(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to format GET request command with headers.");
-        return false;
-    }
-
-    // Send GET request via UART
-    if (!flipper_http_send_data(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send GET request command with headers.");
-        return false;
-    }
-
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-// Function to send a POST request with headers
-/**
- * @brief      Send a POST request to the specified URL.
- * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the POST request to.
- * @param      headers  The headers to send with the POST request.
- * @param      data  The data to send with the POST request.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_post_request_with_headers(const char *url, const char *headers, const char *payload)
-{
-    if (!url || !headers || !payload)
-    {
-        FURI_LOG_E("FlipperHTTP", "Invalid arguments provided to flipper_http_post_request_with_headers.");
-        return false;
-    }
-
-    // Prepare POST request command with headers and data
-    char command[256];
-    int ret = snprintf(command, sizeof(command), "[POST/HTTP]{\"url\":\"%s\",\"headers\":%s,\"payload\":%s}", url, headers, payload);
-    if (ret < 0 || ret >= (int)sizeof(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to format POST request command with headers and data.");
-        return false;
-    }
-
-    // Send POST request via UART
-    if (!flipper_http_send_data(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send POST request command with headers and data.");
-        return false;
-    }
-
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-// Function to send a PUT request with headers
-/**
- * @brief      Send a PUT request to the specified URL.
- * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the PUT request to.
- * @param      headers  The headers to send with the PUT request.
- * @param      data  The data to send with the PUT request.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_put_request_with_headers(const char *url, const char *headers, const char *payload)
-{
-    if (!url || !headers || !payload)
-    {
-        FURI_LOG_E("FlipperHTTP", "Invalid arguments provided to flipper_http_put_request_with_headers.");
-        return false;
-    }
-
-    // Prepare PUT request command with headers and data
-    char command[256];
-    int ret = snprintf(command, sizeof(command), "[PUT/HTTP]{\"url\":\"%s\",\"headers\":%s,\"payload\":%s}", url, headers, payload);
-    if (ret < 0 || ret >= (int)sizeof(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to format PUT request command with headers and data.");
-        return false;
-    }
-
-    // Send PUT request via UART
-    if (!flipper_http_send_data(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send PUT request command with headers and data.");
-        return false;
-    }
-
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-// Function to send a DELETE request with headers
-/**
- * @brief      Send a DELETE request to the specified URL.
- * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the DELETE request to.
- * @param      headers  The headers to send with the DELETE request.
- * @param      data  The data to send with the DELETE request.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_delete_request_with_headers(const char *url, const char *headers, const char *payload)
-{
-    if (!url || !headers || !payload)
-    {
-        FURI_LOG_E("FlipperHTTP", "Invalid arguments provided to flipper_http_delete_request_with_headers.");
-        return false;
-    }
-
-    // Prepare DELETE request command with headers and data
-    char command[256];
-    int ret = snprintf(command, sizeof(command), "[DELETE/HTTP]{\"url\":\"%s\",\"headers\":%s,\"payload\":%s}", url, headers, payload);
-    if (ret < 0 || ret >= (int)sizeof(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to format DELETE request command with headers and data.");
-        return false;
-    }
-
-    // Send DELETE request via UART
-    if (!flipper_http_send_data(command))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send DELETE request command with headers and data.");
-        return false;
-    }
-
-    // The response will be handled asynchronously via the callback
-    return true;
-}
-// Function to handle received data asynchronously
-/**
- * @brief      Callback function to handle received data asynchronously.
- * @return     void
- * @param      line     The received line.
- * @param      context  The context passed to the callback.
- * @note       The received data will be handled asynchronously via the callback and handles the state of the UART.
- */
-void flipper_http_rx_callback(const char *line, void *context)
-{
-
-    if (!line || !context)
-    {
-        FURI_LOG_E(HTTP_TAG, "Invalid arguments provided to flipper_http_rx_callback.");
-        return;
-    }
-
-    // Trim the received line to check if it's empty
-    char *trimmed_line = trim(line);
-    if (trimmed_line != NULL && trimmed_line[0] != '\0')
-    {
-        fhttp.last_response = (char *)line;
-    }
-    free(trimmed_line); // Free the allocated memory for trimmed_line
-
-    if (fhttp.state != INACTIVE && fhttp.state != ISSUE)
-    {
-        fhttp.state = RECEIVING;
-    }
-
-    // Uncomment below line to log the data received over UART
-    FURI_LOG_I(HTTP_TAG, "Received UART line: %s", line);
-
-    // Check if we've started receiving data from a GET request
-    if (fhttp.started_receiving_get)
-    {
-        // Restart the timeout timer each time new data is received
-        furi_timer_restart(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-
-        if (strstr(line, "[GET/END]") != NULL)
-        {
-            FURI_LOG_I(HTTP_TAG, "GET request completed.");
-            // Stop the timer since we've completed the GET request
-            furi_timer_stop(fhttp.get_timeout_timer);
-
-            if (fhttp.received_data)
-            {
-                // uncomment if you want to save the received data to the external storage
-                // flipper_http_save_received_data(strlen(fhttp.received_data), fhttp.received_data);
-                fhttp.started_receiving_get = false;
-                fhttp.just_started_get = false;
-                fhttp.state = IDLE;
-                return;
-            }
-            else
-            {
-                FURI_LOG_E(HTTP_TAG, "No data received.");
-                fhttp.started_receiving_get = false;
-                fhttp.just_started_get = false;
-                fhttp.state = IDLE;
-                return;
-            }
-        }
-
-        // Append the new line to the existing data
-        if (fhttp.received_data == NULL)
-        {
-            fhttp.received_data = (char *)malloc(strlen(line) + 2); // +2 for newline and null terminator
-            if (fhttp.received_data)
-            {
-                strcpy(fhttp.received_data, line);
-                fhttp.received_data[strlen(line)] = '\n';     // Add newline
-                fhttp.received_data[strlen(line) + 1] = '\0'; // Null terminator
-            }
-        }
-        else
-        {
-            size_t current_len = strlen(fhttp.received_data);
-            size_t new_size = current_len + strlen(line) + 2; // +2 for newline and null terminator
-            fhttp.received_data = (char *)realloc(fhttp.received_data, new_size);
-            if (fhttp.received_data)
-            {
-                memcpy(fhttp.received_data + current_len, line, strlen(line)); // Copy line at the end of the current data
-                fhttp.received_data[current_len + strlen(line)] = '\n';        // Add newline
-                fhttp.received_data[current_len + strlen(line) + 1] = '\0';    // Null terminator
-            }
-        }
-
-        if (!fhttp.just_started_get)
-        {
-            fhttp.just_started_get = true;
-        }
-        return;
-    }
-
-    // Check if we've started receiving data from a POST request
-    else if (fhttp.started_receiving_post)
-    {
-        // Restart the timeout timer each time new data is received
-        furi_timer_restart(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-
-        if (strstr(line, "[POST/END]") != NULL)
-        {
-            FURI_LOG_I(HTTP_TAG, "POST request completed.");
-            // Stop the timer since we've completed the POST request
-            furi_timer_stop(fhttp.get_timeout_timer);
-
-            if (fhttp.received_data)
-            {
-                // uncomment if you want to save the received data to the external storage
-                // flipper_http_save_received_data(strlen(fhttp.received_data), fhttp.received_data);
-                fhttp.started_receiving_post = false;
-                fhttp.just_started_post = false;
-                fhttp.state = IDLE;
-                return;
-            }
-            else
-            {
-                FURI_LOG_E(HTTP_TAG, "No data received.");
-                fhttp.started_receiving_post = false;
-                fhttp.just_started_post = false;
-                fhttp.state = IDLE;
-                return;
-            }
-        }
-
-        // Append the new line to the existing data
-        if (fhttp.received_data == NULL)
-        {
-            fhttp.received_data = (char *)malloc(strlen(line) + 2); // +2 for newline and null terminator
-            if (fhttp.received_data)
-            {
-                strcpy(fhttp.received_data, line);
-                fhttp.received_data[strlen(line)] = '\n';     // Add newline
-                fhttp.received_data[strlen(line) + 1] = '\0'; // Null terminator
-            }
-        }
-        else
-        {
-            size_t current_len = strlen(fhttp.received_data);
-            size_t new_size = current_len + strlen(line) + 2; // +2 for newline and null terminator
-            fhttp.received_data = (char *)realloc(fhttp.received_data, new_size);
-            if (fhttp.received_data)
-            {
-                memcpy(fhttp.received_data + current_len, line, strlen(line)); // Copy line at the end of the current data
-                fhttp.received_data[current_len + strlen(line)] = '\n';        // Add newline
-                fhttp.received_data[current_len + strlen(line) + 1] = '\0';    // Null terminator
-            }
-        }
-
-        if (!fhttp.just_started_post)
-        {
-            fhttp.just_started_post = true;
-        }
-        return;
-    }
-
-    // Check if we've started receiving data from a PUT request
-    else if (fhttp.started_receiving_put)
-    {
-        // Restart the timeout timer each time new data is received
-        furi_timer_restart(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-
-        if (strstr(line, "[PUT/END]") != NULL)
-        {
-            FURI_LOG_I(HTTP_TAG, "PUT request completed.");
-            // Stop the timer since we've completed the PUT request
-            furi_timer_stop(fhttp.get_timeout_timer);
-
-            if (fhttp.received_data)
-            {
-                // uncomment if you want to save the received data to the external storage
-                // flipper_http_save_received_data(strlen(fhttp.received_data), fhttp.received_data);
-                fhttp.started_receiving_put = false;
-                fhttp.just_started_put = false;
-                fhttp.state = IDLE;
-                return;
-            }
-            else
-            {
-                FURI_LOG_E(HTTP_TAG, "No data received.");
-                fhttp.started_receiving_put = false;
-                fhttp.just_started_put = false;
-                fhttp.state = IDLE;
-                return;
-            }
-        }
-
-        // Append the new line to the existing data
-        if (fhttp.received_data == NULL)
-        {
-            fhttp.received_data = (char *)malloc(strlen(line) + 2); // +2 for newline and null terminator
-            if (fhttp.received_data)
-            {
-                strcpy(fhttp.received_data, line);
-                fhttp.received_data[strlen(line)] = '\n';     // Add newline
-                fhttp.received_data[strlen(line) + 1] = '\0'; // Null terminator
-            }
-        }
-        else
-        {
-            size_t current_len = strlen(fhttp.received_data);
-            size_t new_size = current_len + strlen(line) + 2; // +2 for newline and null terminator
-            fhttp.received_data = (char *)realloc(fhttp.received_data, new_size);
-            if (fhttp.received_data)
-            {
-                memcpy(fhttp.received_data + current_len, line, strlen(line)); // Copy line at the end of the current data
-                fhttp.received_data[current_len + strlen(line)] = '\n';        // Add newline
-                fhttp.received_data[current_len + strlen(line) + 1] = '\0';    // Null terminator
-            }
-        }
-
-        if (!fhttp.just_started_put)
-        {
-            fhttp.just_started_put = true;
-        }
-        return;
-    }
-
-    // Check if we've started receiving data from a DELETE request
-    else if (fhttp.started_receiving_delete)
-    {
-        // Restart the timeout timer each time new data is received
-        furi_timer_restart(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-
-        if (strstr(line, "[DELETE/END]") != NULL)
-        {
-            FURI_LOG_I(HTTP_TAG, "DELETE request completed.");
-            // Stop the timer since we've completed the DELETE request
-            furi_timer_stop(fhttp.get_timeout_timer);
-
-            if (fhttp.received_data)
-            {
-                // uncomment if you want to save the received data to the external storage
-                // flipper_http_save_received_data(strlen(fhttp.received_data), fhttp.received_data);
-                fhttp.started_receiving_delete = false;
-                fhttp.just_started_delete = false;
-                fhttp.state = IDLE;
-                return;
-            }
-            else
-            {
-                FURI_LOG_E(HTTP_TAG, "No data received.");
-                fhttp.started_receiving_delete = false;
-                fhttp.just_started_delete = false;
-                fhttp.state = IDLE;
-                return;
-            }
-        }
-
-        // Append the new line to the existing data
-        if (fhttp.received_data == NULL)
-        {
-            fhttp.received_data = (char *)malloc(strlen(line) + 2); // +2 for newline and null terminator
-            if (fhttp.received_data)
-            {
-                strcpy(fhttp.received_data, line);
-                fhttp.received_data[strlen(line)] = '\n';     // Add newline
-                fhttp.received_data[strlen(line) + 1] = '\0'; // Null terminator
-            }
-        }
-        else
-        {
-            size_t current_len = strlen(fhttp.received_data);
-            size_t new_size = current_len + strlen(line) + 2; // +2 for newline and null terminator
-            fhttp.received_data = (char *)realloc(fhttp.received_data, new_size);
-            if (fhttp.received_data)
-            {
-                memcpy(fhttp.received_data + current_len, line, strlen(line)); // Copy line at the end of the current data
-                fhttp.received_data[current_len + strlen(line)] = '\n';        // Add newline
-                fhttp.received_data[current_len + strlen(line) + 1] = '\0';    // Null terminator
-            }
-        }
-
-        if (!fhttp.just_started_delete)
-        {
-            fhttp.just_started_delete = true;
-        }
-        return;
-    }
-
-    // Handle different types of responses
-    if (strstr(line, "[SUCCESS]") != NULL || strstr(line, "[CONNECTED]") != NULL)
-    {
-        // FURI_LOG_I(HTTP_TAG, "Operation succeeded.");
-    }
-    else if (strstr(line, "[INFO]") != NULL)
-    {
-        FURI_LOG_I(HTTP_TAG, "Received info: %s", line);
-
-        if (fhttp.state == INACTIVE && strstr(line, "[INFO] Already connected to Wifi.") != NULL)
-        {
-            fhttp.state = IDLE;
-        }
-    }
-    else if (strstr(line, "[GET/SUCCESS]") != NULL)
-    {
-        FURI_LOG_I(HTTP_TAG, "GET request succeeded.");
-        fhttp.started_receiving_get = true;
-        furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        fhttp.state = RECEIVING;
-        fhttp.received_data = NULL;
-        return;
-    }
-    else if (strstr(line, "[POST/SUCCESS]") != NULL)
-    {
-        FURI_LOG_I(HTTP_TAG, "POST request succeeded.");
-        fhttp.started_receiving_post = true;
-        furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        fhttp.state = RECEIVING;
-        fhttp.received_data = NULL;
-        return;
-    }
-    else if (strstr(line, "[PUT/SUCCESS]") != NULL)
-    {
-        FURI_LOG_I(HTTP_TAG, "PUT request succeeded.");
-        fhttp.started_receiving_put = true;
-        furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        fhttp.state = RECEIVING;
-        fhttp.received_data = NULL;
-        return;
-    }
-    else if (strstr(line, "[DELETE/SUCCESS]") != NULL)
-    {
-        FURI_LOG_I(HTTP_TAG, "DELETE request succeeded.");
-        fhttp.started_receiving_delete = true;
-        furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        fhttp.state = RECEIVING;
-        fhttp.received_data = NULL;
-        return;
-    }
-    else if (strstr(line, "[DISCONNECTED]") != NULL)
-    {
-        FURI_LOG_I(HTTP_TAG, "WiFi disconnected successfully.");
-    }
-    else if (strstr(line, "[ERROR]") != NULL)
-    {
-        FURI_LOG_E(HTTP_TAG, "Received error: %s", line);
-        fhttp.state = ISSUE;
-        return;
-    }
-    else if (strstr(line, "[PONG]") != NULL)
-    {
-        FURI_LOG_I(HTTP_TAG, "Received PONG response: Wifi Dev Board is still alive.");
-
-        // send command to connect to WiFi
-        if (fhttp.state == INACTIVE)
-        {
-            fhttp.state = IDLE;
-            return;
-        }
-    }
-
-    if (fhttp.state == INACTIVE && strstr(line, "[PONG]") != NULL)
-    {
-        fhttp.state = IDLE;
-    }
-    else if (fhttp.state == INACTIVE && strstr(line, "[PONG]") == NULL)
-    {
-        fhttp.state = INACTIVE;
-    }
-    else
-    {
-        fhttp.state = IDLE;
-    }
-}
-// Function to save received data to a file
-/**
- * @brief      Save the received data to a file.
- * @return     true if the data was saved successfully, false otherwise.
- * @param      bytes_received  The number of bytes received.
- * @param      line_buffer     The buffer containing the received data.
- * @note       The data will be saved to a file in the STORAGE_EXT_PATH_PREFIX "/apps_data/" http_tag "/received_data.txt" directory.
- */
-bool flipper_http_save_received_data(size_t bytes_received, const char line_buffer[])
-{
-    const char *output_file_path = STORAGE_EXT_PATH_PREFIX "/apps_data/" http_tag "/received_data.txt";
-
-    // Ensure the directory exists
-    char directory_path[128];
-    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/" http_tag);
-
-    Storage *_storage = NULL;
-    File *_file = NULL;
-    // Open the storage if not opened already
-    // Initialize storage and create the directory if it doesn't exist
-    _storage = furi_record_open(RECORD_STORAGE);
-    storage_common_mkdir(_storage, directory_path); // Create directory if it doesn't exist
-    _file = storage_file_alloc(_storage);
-
-    // Open file for writing and append data line by line
-    if (!storage_file_open(_file, output_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS))
-    {
-        FURI_LOG_E(HTTP_TAG, "Failed to open output file for writing.");
-        storage_file_free(_file);
-        furi_record_close(RECORD_STORAGE);
-        return false;
-    }
-
-    // Write each line received from the UART to the file
-    if (bytes_received > 0 && _file)
-    {
-        storage_file_write(_file, line_buffer, bytes_received);
-        storage_file_write(_file, "\n", 1); // Add a newline after each line
-    }
-    else
-    {
-        FURI_LOG_E(HTTP_TAG, "No data received.");
-        return false;
-    }
-
-    if (_file)
-    {
-        storage_file_close(_file);
-        storage_file_free(_file);
-        _file = NULL;
-    }
-    if (_storage)
-    {
-        furi_record_close(RECORD_STORAGE);
-        _storage = NULL;
-    }
-
-    return true;
-}
-// Function to trim leading and trailing spaces and newlines from a constant string
-char *trim(const char *str)
-{
-    const char *end;
-    char *trimmed_str;
-    size_t len;
-
-    // Trim leading space
-    while (isspace((unsigned char)*str))
-        str++;
-
-    // All spaces?
-    if (*str == 0)
-        return strdup(""); // Return an empty string if all spaces
-
-    // Trim trailing space
-    end = str + strlen(str) - 1;
-    while (end > str && isspace((unsigned char)*end))
-        end--;
-
-    // Set length for the trimmed string
-    len = end - str + 1;
-
-    // Allocate space for the trimmed string and null terminator
-    trimmed_str = (char *)malloc(len + 1);
-    if (trimmed_str == NULL)
-    {
-        return NULL; // Handle memory allocation failure
-    }
-
-    // Copy the trimmed part of the string into trimmed_str
-    strncpy(trimmed_str, str, len);
-    trimmed_str[len] = '\0'; // Null terminate the string
-
-    return trimmed_str;
-}
-
-/**
- * @brief Process requests and parse JSON data asynchronously
- * @param http_request The function to send the request
- * @param parse_json The function to parse the JSON
- * @return true if successful, false otherwise
- */
-bool flipper_http_process_response_async(
-    bool (*http_request)(void),
-    bool (*parse_json)(void))
-{
-    if (http_request()) // start the async request
-    {
-        furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        fhttp.state = RECEIVING;
-    }
-    else
-    {
-        FURI_LOG_E(HTTP_TAG, "Failed to send request");
-        return false;
-    }
-    while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
-    {
-        // Wait for the request to be received
-        furi_delay_ms(100);
-    }
-    furi_timer_stop(fhttp.get_timeout_timer);
-    if (!parse_json()) // parse the JSON before switching to the view (synchonous)
-    {
-        FURI_LOG_E(HTTP_TAG, "Failed to parse the JSON...");
-        return false;
-    }
-    furi_timer_stop(fhttp.get_timeout_timer);
-    return true;
-}
-
-#endif // FLIPPER_HTTP_H

+ 0 - 865
jsmn.h

@@ -1,865 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2010 Serge Zaitsev
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-#ifndef JSMN_H
-#define JSMN_H
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#ifdef JSMN_STATIC
-#define JSMN_API static
-#else
-#define JSMN_API extern
-#endif
-
-  /**
-   * JSON type identifier. Basic types are:
-   * 	o Object
-   * 	o Array
-   * 	o String
-   * 	o Other primitive: number, boolean (true/false) or null
-   */
-  typedef enum
-  {
-    JSMN_UNDEFINED = 0,
-    JSMN_OBJECT = 1 << 0,
-    JSMN_ARRAY = 1 << 1,
-    JSMN_STRING = 1 << 2,
-    JSMN_PRIMITIVE = 1 << 3
-  } jsmntype_t;
-
-  enum jsmnerr
-  {
-    /* Not enough tokens were provided */
-    JSMN_ERROR_NOMEM = -1,
-    /* Invalid character inside JSON string */
-    JSMN_ERROR_INVAL = -2,
-    /* The string is not a full JSON packet, more bytes expected */
-    JSMN_ERROR_PART = -3
-  };
-
-  /**
-   * JSON token description.
-   * type		type (object, array, string etc.)
-   * start	start position in JSON data string
-   * end		end position in JSON data string
-   */
-  typedef struct jsmntok
-  {
-    jsmntype_t type;
-    int start;
-    int end;
-    int size;
-#ifdef JSMN_PARENT_LINKS
-    int parent;
-#endif
-  } jsmntok_t;
-
-  /**
-   * JSON parser. Contains an array of token blocks available. Also stores
-   * the string being parsed now and current position in that string.
-   */
-  typedef struct jsmn_parser
-  {
-    unsigned int pos;     /* offset in the JSON string */
-    unsigned int toknext; /* next token to allocate */
-    int toksuper;         /* superior token node, e.g. parent object or array */
-  } jsmn_parser;
-
-  /**
-   * Create JSON parser over an array of tokens
-   */
-  JSMN_API void jsmn_init(jsmn_parser *parser);
-
-  /**
-   * Run JSON parser. It parses a JSON data string into and array of tokens, each
-   * describing
-   * a single JSON object.
-   */
-  JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len,
-                          jsmntok_t *tokens, const unsigned int num_tokens);
-
-#ifndef JSMN_HEADER
-  /**
-   * Allocates a fresh unused token from the token pool.
-   */
-  static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens,
-                                     const size_t num_tokens)
-  {
-    jsmntok_t *tok;
-    if (parser->toknext >= num_tokens)
-    {
-      return NULL;
-    }
-    tok = &tokens[parser->toknext++];
-    tok->start = tok->end = -1;
-    tok->size = 0;
-#ifdef JSMN_PARENT_LINKS
-    tok->parent = -1;
-#endif
-    return tok;
-  }
-
-  /**
-   * Fills token type and boundaries.
-   */
-  static void jsmn_fill_token(jsmntok_t *token, const jsmntype_t type,
-                              const int start, const int end)
-  {
-    token->type = type;
-    token->start = start;
-    token->end = end;
-    token->size = 0;
-  }
-
-  /**
-   * Fills next available token with JSON primitive.
-   */
-  static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
-                                  const size_t len, jsmntok_t *tokens,
-                                  const size_t num_tokens)
-  {
-    jsmntok_t *token;
-    int start;
-
-    start = parser->pos;
-
-    for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++)
-    {
-      switch (js[parser->pos])
-      {
-#ifndef JSMN_STRICT
-      /* In strict mode primitive must be followed by "," or "}" or "]" */
-      case ':':
-#endif
-      case '\t':
-      case '\r':
-      case '\n':
-      case ' ':
-      case ',':
-      case ']':
-      case '}':
-        goto found;
-      default:
-        /* to quiet a warning from gcc*/
-        break;
-      }
-      if (js[parser->pos] < 32 || js[parser->pos] >= 127)
-      {
-        parser->pos = start;
-        return JSMN_ERROR_INVAL;
-      }
-    }
-#ifdef JSMN_STRICT
-    /* In strict mode primitive must be followed by a comma/object/array */
-    parser->pos = start;
-    return JSMN_ERROR_PART;
-#endif
-
-  found:
-    if (tokens == NULL)
-    {
-      parser->pos--;
-      return 0;
-    }
-    token = jsmn_alloc_token(parser, tokens, num_tokens);
-    if (token == NULL)
-    {
-      parser->pos = start;
-      return JSMN_ERROR_NOMEM;
-    }
-    jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
-#ifdef JSMN_PARENT_LINKS
-    token->parent = parser->toksuper;
-#endif
-    parser->pos--;
-    return 0;
-  }
-
-  /**
-   * Fills next token with JSON string.
-   */
-  static int jsmn_parse_string(jsmn_parser *parser, const char *js,
-                               const size_t len, jsmntok_t *tokens,
-                               const size_t num_tokens)
-  {
-    jsmntok_t *token;
-
-    int start = parser->pos;
-
-    /* Skip starting quote */
-    parser->pos++;
-
-    for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++)
-    {
-      char c = js[parser->pos];
-
-      /* Quote: end of string */
-      if (c == '\"')
-      {
-        if (tokens == NULL)
-        {
-          return 0;
-        }
-        token = jsmn_alloc_token(parser, tokens, num_tokens);
-        if (token == NULL)
-        {
-          parser->pos = start;
-          return JSMN_ERROR_NOMEM;
-        }
-        jsmn_fill_token(token, JSMN_STRING, start + 1, parser->pos);
-#ifdef JSMN_PARENT_LINKS
-        token->parent = parser->toksuper;
-#endif
-        return 0;
-      }
-
-      /* Backslash: Quoted symbol expected */
-      if (c == '\\' && parser->pos + 1 < len)
-      {
-        int i;
-        parser->pos++;
-        switch (js[parser->pos])
-        {
-        /* Allowed escaped symbols */
-        case '\"':
-        case '/':
-        case '\\':
-        case 'b':
-        case 'f':
-        case 'r':
-        case 'n':
-        case 't':
-          break;
-        /* Allows escaped symbol \uXXXX */
-        case 'u':
-          parser->pos++;
-          for (i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0';
-               i++)
-          {
-            /* If it isn't a hex character we have an error */
-            if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
-                  (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
-                  (js[parser->pos] >= 97 && js[parser->pos] <= 102)))
-            { /* a-f */
-              parser->pos = start;
-              return JSMN_ERROR_INVAL;
-            }
-            parser->pos++;
-          }
-          parser->pos--;
-          break;
-        /* Unexpected symbol */
-        default:
-          parser->pos = start;
-          return JSMN_ERROR_INVAL;
-        }
-      }
-    }
-    parser->pos = start;
-    return JSMN_ERROR_PART;
-  }
-
-  /**
-   * Parse JSON string and fill tokens.
-   */
-  JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len,
-                          jsmntok_t *tokens, const unsigned int num_tokens)
-  {
-    int r;
-    int i;
-    jsmntok_t *token;
-    int count = parser->toknext;
-
-    for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++)
-    {
-      char c;
-      jsmntype_t type;
-
-      c = js[parser->pos];
-      switch (c)
-      {
-      case '{':
-      case '[':
-        count++;
-        if (tokens == NULL)
-        {
-          break;
-        }
-        token = jsmn_alloc_token(parser, tokens, num_tokens);
-        if (token == NULL)
-        {
-          return JSMN_ERROR_NOMEM;
-        }
-        if (parser->toksuper != -1)
-        {
-          jsmntok_t *t = &tokens[parser->toksuper];
-#ifdef JSMN_STRICT
-          /* In strict mode an object or array can't become a key */
-          if (t->type == JSMN_OBJECT)
-          {
-            return JSMN_ERROR_INVAL;
-          }
-#endif
-          t->size++;
-#ifdef JSMN_PARENT_LINKS
-          token->parent = parser->toksuper;
-#endif
-        }
-        token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
-        token->start = parser->pos;
-        parser->toksuper = parser->toknext - 1;
-        break;
-      case '}':
-      case ']':
-        if (tokens == NULL)
-        {
-          break;
-        }
-        type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
-#ifdef JSMN_PARENT_LINKS
-        if (parser->toknext < 1)
-        {
-          return JSMN_ERROR_INVAL;
-        }
-        token = &tokens[parser->toknext - 1];
-        for (;;)
-        {
-          if (token->start != -1 && token->end == -1)
-          {
-            if (token->type != type)
-            {
-              return JSMN_ERROR_INVAL;
-            }
-            token->end = parser->pos + 1;
-            parser->toksuper = token->parent;
-            break;
-          }
-          if (token->parent == -1)
-          {
-            if (token->type != type || parser->toksuper == -1)
-            {
-              return JSMN_ERROR_INVAL;
-            }
-            break;
-          }
-          token = &tokens[token->parent];
-        }
-#else
-        for (i = parser->toknext - 1; i >= 0; i--)
-        {
-          token = &tokens[i];
-          if (token->start != -1 && token->end == -1)
-          {
-            if (token->type != type)
-            {
-              return JSMN_ERROR_INVAL;
-            }
-            parser->toksuper = -1;
-            token->end = parser->pos + 1;
-            break;
-          }
-        }
-        /* Error if unmatched closing bracket */
-        if (i == -1)
-        {
-          return JSMN_ERROR_INVAL;
-        }
-        for (; i >= 0; i--)
-        {
-          token = &tokens[i];
-          if (token->start != -1 && token->end == -1)
-          {
-            parser->toksuper = i;
-            break;
-          }
-        }
-#endif
-        break;
-      case '\"':
-        r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
-        if (r < 0)
-        {
-          return r;
-        }
-        count++;
-        if (parser->toksuper != -1 && tokens != NULL)
-        {
-          tokens[parser->toksuper].size++;
-        }
-        break;
-      case '\t':
-      case '\r':
-      case '\n':
-      case ' ':
-        break;
-      case ':':
-        parser->toksuper = parser->toknext - 1;
-        break;
-      case ',':
-        if (tokens != NULL && parser->toksuper != -1 &&
-            tokens[parser->toksuper].type != JSMN_ARRAY &&
-            tokens[parser->toksuper].type != JSMN_OBJECT)
-        {
-#ifdef JSMN_PARENT_LINKS
-          parser->toksuper = tokens[parser->toksuper].parent;
-#else
-          for (i = parser->toknext - 1; i >= 0; i--)
-          {
-            if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT)
-            {
-              if (tokens[i].start != -1 && tokens[i].end == -1)
-              {
-                parser->toksuper = i;
-                break;
-              }
-            }
-          }
-#endif
-        }
-        break;
-#ifdef JSMN_STRICT
-      /* In strict mode primitives are: numbers and booleans */
-      case '-':
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9':
-      case 't':
-      case 'f':
-      case 'n':
-        /* And they must not be keys of the object */
-        if (tokens != NULL && parser->toksuper != -1)
-        {
-          const jsmntok_t *t = &tokens[parser->toksuper];
-          if (t->type == JSMN_OBJECT ||
-              (t->type == JSMN_STRING && t->size != 0))
-          {
-            return JSMN_ERROR_INVAL;
-          }
-        }
-#else
-      /* In non-strict mode every unquoted value is a primitive */
-      default:
-#endif
-        r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
-        if (r < 0)
-        {
-          return r;
-        }
-        count++;
-        if (parser->toksuper != -1 && tokens != NULL)
-        {
-          tokens[parser->toksuper].size++;
-        }
-        break;
-
-#ifdef JSMN_STRICT
-      /* Unexpected char in strict mode */
-      default:
-        return JSMN_ERROR_INVAL;
-#endif
-      }
-    }
-
-    if (tokens != NULL)
-    {
-      for (i = parser->toknext - 1; i >= 0; i--)
-      {
-        /* Unmatched opened object or array */
-        if (tokens[i].start != -1 && tokens[i].end == -1)
-        {
-          return JSMN_ERROR_PART;
-        }
-      }
-    }
-
-    return count;
-  }
-
-  /**
-   * Creates a new parser based over a given buffer with an array of tokens
-   * available.
-   */
-  JSMN_API void jsmn_init(jsmn_parser *parser)
-  {
-    parser->pos = 0;
-    parser->toknext = 0;
-    parser->toksuper = -1;
-  }
-
-#endif /* JSMN_HEADER */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* JSMN_H */
-
-#ifndef JB_JSMN_EDIT
-#define JB_JSMN_EDIT
-/* Added in by JBlanked on 2024-10-16 for use in Flipper Zero SDK*/
-
-#include <string.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdio.h>
-#include <string.h>
-#include <furi.h>
-
-// Helper function to create a JSON object
-char *jsmn(const char *key, const char *value)
-{
-  int length = strlen(key) + strlen(value) + 8;         // Calculate required length
-  char *result = (char *)malloc(length * sizeof(char)); // Allocate memory
-  if (result == NULL)
-  {
-    return NULL; // Handle memory allocation failure
-  }
-  snprintf(result, length, "{\"%s\":\"%s\"}", key, value);
-  return result; // Caller is responsible for freeing this memory
-}
-
-// Helper function to compare JSON keys
-int jsoneq(const char *json, jsmntok_t *tok, const char *s)
-{
-  if (tok->type == JSMN_STRING && (int)strlen(s) == tok->end - tok->start &&
-      strncmp(json + tok->start, s, tok->end - tok->start) == 0)
-  {
-    return 0;
-  }
-  return -1;
-}
-
-// return the value of the key in the JSON data
-char *get_json_value(char *key, char *json_data, uint32_t max_tokens)
-{
-  // Parse the JSON feed
-  if (json_data != NULL)
-  {
-    jsmn_parser parser;
-    jsmn_init(&parser);
-
-    // Allocate tokens array on the heap
-    jsmntok_t *tokens = malloc(sizeof(jsmntok_t) * max_tokens);
-    if (tokens == NULL)
-    {
-      FURI_LOG_E("JSMM.H", "Failed to allocate memory for JSON tokens.");
-      return NULL;
-    }
-
-    int ret = jsmn_parse(&parser, json_data, strlen(json_data), tokens, max_tokens);
-    if (ret < 0)
-    {
-      // Handle parsing errors
-      FURI_LOG_E("JSMM.H", "Failed to parse JSON: %d", ret);
-      free(tokens);
-      return NULL;
-    }
-
-    // Ensure that the root element is an object
-    if (ret < 1 || tokens[0].type != JSMN_OBJECT)
-    {
-      FURI_LOG_E("JSMM.H", "Root element is not an object.");
-      free(tokens);
-      return NULL;
-    }
-
-    // Loop through the tokens to find the key
-    for (int i = 1; i < ret; i++)
-    {
-      if (jsoneq(json_data, &tokens[i], key) == 0)
-      {
-        // We found the key. Now, return the associated value.
-        int length = tokens[i + 1].end - tokens[i + 1].start;
-        char *value = malloc(length + 1);
-        if (value == NULL)
-        {
-          FURI_LOG_E("JSMM.H", "Failed to allocate memory for value.");
-          free(tokens);
-          return NULL;
-        }
-        strncpy(value, json_data + tokens[i + 1].start, length);
-        value[length] = '\0'; // Null-terminate the string
-
-        free(tokens); // Free the token array
-        return value; // Return the extracted value
-      }
-    }
-
-    // Free the token array if key was not found
-    free(tokens);
-  }
-  else
-  {
-    FURI_LOG_E("JSMM.H", "JSON data is NULL");
-  }
-  FURI_LOG_E("JSMM.H", "Failed to find the key in the JSON.");
-  return NULL; // Return NULL if something goes wrong
-}
-
-// Revised get_json_array_value function
-char *get_json_array_value(char *key, uint32_t index, char *json_data, uint32_t max_tokens)
-{
-  // Retrieve the array string for the given key
-  char *array_str = get_json_value(key, json_data, max_tokens);
-  if (array_str == NULL)
-  {
-    FURI_LOG_E("JSMM.H", "Failed to get array for key: %s", key);
-    return NULL;
-  }
-
-  // Initialize the JSON parser
-  jsmn_parser parser;
-  jsmn_init(&parser);
-
-  // Allocate memory for JSON tokens
-  jsmntok_t *tokens = malloc(sizeof(jsmntok_t) * max_tokens);
-  if (tokens == NULL)
-  {
-    FURI_LOG_E("JSMM.H", "Failed to allocate memory for JSON tokens.");
-    free(array_str);
-    return NULL;
-  }
-
-  // Parse the JSON array
-  int ret = jsmn_parse(&parser, array_str, strlen(array_str), tokens, max_tokens);
-  if (ret < 0)
-  {
-    FURI_LOG_E("JSMM.H", "Failed to parse JSON array: %d", ret);
-    free(tokens);
-    free(array_str);
-    return NULL;
-  }
-
-  // Ensure the root element is an array
-  if (ret < 1 || tokens[0].type != JSMN_ARRAY)
-  {
-    FURI_LOG_E("JSMM.H", "Value for key '%s' is not an array.", key);
-    free(tokens);
-    free(array_str);
-    return NULL;
-  }
-
-  // Check if the index is within bounds
-  if (index >= (uint32_t)tokens[0].size)
-  {
-    FURI_LOG_E("JSMM.H", "Index %lu out of bounds for array with size %d.", (unsigned long)index, tokens[0].size);
-    free(tokens);
-    free(array_str);
-    return NULL;
-  }
-
-  // Locate the token corresponding to the desired array element
-  int current_token = 1; // Start after the array token
-  for (uint32_t i = 0; i < index; i++)
-  {
-    if (tokens[current_token].type == JSMN_OBJECT)
-    {
-      // For objects, skip all key-value pairs
-      current_token += 1 + 2 * tokens[current_token].size;
-    }
-    else if (tokens[current_token].type == JSMN_ARRAY)
-    {
-      // For nested arrays, skip all elements
-      current_token += 1 + tokens[current_token].size;
-    }
-    else
-    {
-      // For primitive types, simply move to the next token
-      current_token += 1;
-    }
-
-    // Safety check to prevent out-of-bounds
-    if (current_token >= ret)
-    {
-      FURI_LOG_E("JSMM.H", "Unexpected end of tokens while traversing array.");
-      free(tokens);
-      free(array_str);
-      return NULL;
-    }
-  }
-
-  // Extract the array element
-  jsmntok_t element = tokens[current_token];
-  int length = element.end - element.start;
-  char *value = malloc(length + 1);
-  if (value == NULL)
-  {
-    FURI_LOG_E("JSMM.H", "Failed to allocate memory for array element.");
-    free(tokens);
-    free(array_str);
-    return NULL;
-  }
-
-  // Copy the element value to a new string
-  strncpy(value, array_str + element.start, length);
-  value[length] = '\0'; // Null-terminate the string
-
-  // Clean up
-  free(tokens);
-  free(array_str);
-
-  return value;
-}
-
-// Revised get_json_array_values function with correct token skipping
-char **get_json_array_values(char *key, char *json_data, uint32_t max_tokens, int *num_values)
-{
-  // Retrieve the array string for the given key
-  char *array_str = get_json_value(key, json_data, max_tokens);
-  if (array_str == NULL)
-  {
-    FURI_LOG_E("JSMM.H", "Failed to get array for key: %s", key);
-    return NULL;
-  }
-
-  // Initialize the JSON parser
-  jsmn_parser parser;
-  jsmn_init(&parser);
-
-  // Allocate memory for JSON tokens
-  jsmntok_t *tokens = malloc(sizeof(jsmntok_t) * max_tokens); // Allocate on the heap
-  if (tokens == NULL)
-  {
-    FURI_LOG_E("JSMM.H", "Failed to allocate memory for JSON tokens.");
-    free(array_str);
-    return NULL;
-  }
-
-  // Parse the JSON array
-  int ret = jsmn_parse(&parser, array_str, strlen(array_str), tokens, max_tokens);
-  if (ret < 0)
-  {
-    FURI_LOG_E("JSMM.H", "Failed to parse JSON array: %d", ret);
-    free(tokens);
-    free(array_str);
-    return NULL;
-  }
-
-  // Ensure the root element is an array
-  if (tokens[0].type != JSMN_ARRAY)
-  {
-    FURI_LOG_E("JSMM.H", "Value for key '%s' is not an array.", key);
-    free(tokens);
-    free(array_str);
-    return NULL;
-  }
-
-  // Allocate memory for the array of values (maximum possible)
-  int array_size = tokens[0].size;
-  char **values = malloc(array_size * sizeof(char *));
-  if (values == NULL)
-  {
-    FURI_LOG_E("JSMM.H", "Failed to allocate memory for array of values.");
-    free(tokens);
-    free(array_str);
-    return NULL;
-  }
-
-  int actual_num_values = 0;
-
-  // Traverse the array and extract all object values
-  int current_token = 1; // Start after the array token
-  for (int i = 0; i < array_size; i++)
-  {
-    if (current_token >= ret)
-    {
-      FURI_LOG_E("JSMM.H", "Unexpected end of tokens while traversing array.");
-      break;
-    }
-
-    jsmntok_t element = tokens[current_token];
-
-    if (element.type != JSMN_OBJECT)
-    {
-      FURI_LOG_E("JSMM.H", "Array element %d is not an object, skipping.", i);
-      // Skip this element
-      current_token += 1;
-      continue;
-    }
-
-    int length = element.end - element.start;
-
-    // Allocate a new string for the value and copy the data
-    char *value = malloc(length + 1);
-    if (value == NULL)
-    {
-      FURI_LOG_E("JSMM.H", "Failed to allocate memory for array element.");
-      for (int j = 0; j < actual_num_values; j++)
-      {
-        free(values[j]);
-      }
-      free(values);
-      free(tokens);
-      free(array_str);
-      return NULL;
-    }
-
-    strncpy(value, array_str + element.start, length);
-    value[length] = '\0'; // Null-terminate the string
-
-    values[actual_num_values] = value;
-    actual_num_values++;
-
-    // Skip all tokens related to this object to avoid misparsing
-    current_token += 1 + (2 * element.size); // Each key-value pair consumes two tokens
-  }
-
-  *num_values = actual_num_values;
-
-  // Reallocate the values array to actual_num_values if necessary
-  if (actual_num_values < array_size)
-  {
-    char **reduced_values = realloc(values, actual_num_values * sizeof(char *));
-    if (reduced_values != NULL)
-    {
-      values = reduced_values;
-    }
-
-    // Free the remaining values
-    for (int i = actual_num_values; i < array_size; i++)
-    {
-      free(values[i]);
-    }
-  }
-
-  // Clean up
-  free(tokens);
-  free(array_str);
-  return values;
-}
-
-#endif /* JB_JSMN_EDIT */

+ 0 - 803
uart_text_input.h

@@ -1,803 +0,0 @@
-// from https://github.com/xMasterX/all-the-plugins/blob/dev/base_pack/uart_terminal/uart_text_input.c
-// all credits to xMasterX for the code
-#ifndef UART_TEXT_INPUT_H
-#define UART_TEXT_INPUT_H
-
-#include <gui/elements.h>
-#include "flip_social_icons.h"
-#include <furi.h>
-#include <furi.h>
-#include <furi_hal.h>
-#include <gui/gui.h>
-#include <gui/view.h>
-#include <core/common_defines.h>
-
-/** Text input anonymous structure */
-typedef struct UART_TextInput UART_TextInput;
-typedef void (*UART_TextInputCallback)(void *context);
-typedef bool (*UART_TextInputValidatorCallback)(const char *text, FuriString *error, void *context);
-
-UART_TextInputValidatorCallback
-uart_text_input_get_validator_callback(UART_TextInput *uart_text_input);
-
-void uart_text_input_reset(UART_TextInput *uart_text_input);
-
-struct UART_TextInput
-{
-    View *view;
-    FuriTimer *timer;
-};
-
-typedef struct
-{
-    const char text;
-    const uint8_t x;
-    const uint8_t y;
-} UART_TextInputKey;
-
-typedef struct
-{
-    const char *header;
-    char *text_buffer;
-    size_t text_buffer_size;
-    bool clear_default_text;
-
-    UART_TextInputCallback callback;
-    void *callback_context;
-
-    uint8_t selected_row;
-    uint8_t selected_column;
-
-    UART_TextInputValidatorCallback validator_callback;
-    void *validator_callback_context;
-    FuriString *validator_text;
-    bool valadator_message_visible;
-} UART_TextInputModel;
-
-static const uint8_t keyboard_origin_x = 1;
-static const uint8_t keyboard_origin_y = 29;
-static const uint8_t keyboard_row_count = 4;
-
-#define mode_AT "Send AT command to UART"
-
-#define ENTER_KEY '\r'
-#define BACKSPACE_KEY '\b'
-
-static const UART_TextInputKey keyboard_keys_row_1[] = {
-    {'{', 1, 0},
-    {'(', 9, 0},
-    {'[', 17, 0},
-    {'|', 25, 0},
-    {'@', 33, 0},
-    {'&', 41, 0},
-    {'#', 49, 0},
-    {';', 57, 0},
-    {'^', 65, 0},
-    {'*', 73, 0},
-    {'`', 81, 0},
-    {'"', 89, 0},
-    {'~', 97, 0},
-    {'\'', 105, 0},
-    {'.', 113, 0},
-    {'/', 120, 0},
-};
-
-static const UART_TextInputKey keyboard_keys_row_2[] = {
-    {'q', 1, 10},
-    {'w', 9, 10},
-    {'e', 17, 10},
-    {'r', 25, 10},
-    {'t', 33, 10},
-    {'y', 41, 10},
-    {'u', 49, 10},
-    {'i', 57, 10},
-    {'o', 65, 10},
-    {'p', 73, 10},
-    {'0', 81, 10},
-    {'1', 89, 10},
-    {'2', 97, 10},
-    {'3', 105, 10},
-    {'=', 113, 10},
-    {'-', 120, 10},
-};
-
-static const UART_TextInputKey keyboard_keys_row_3[] = {
-    {'a', 1, 21},
-    {'s', 9, 21},
-    {'d', 18, 21},
-    {'f', 25, 21},
-    {'g', 33, 21},
-    {'h', 41, 21},
-    {'j', 49, 21},
-    {'k', 57, 21},
-    {'l', 65, 21},
-    {BACKSPACE_KEY, 72, 13},
-    {'4', 89, 21},
-    {'5', 97, 21},
-    {'6', 105, 21},
-    {'$', 113, 21},
-    {'%', 120, 21},
-
-};
-
-static const UART_TextInputKey keyboard_keys_row_4[] = {
-    {'z', 1, 33},
-    {'x', 9, 33},
-    {'c', 18, 33},
-    {'v', 25, 33},
-    {'b', 33, 33},
-    {'n', 41, 33},
-    {'m', 49, 33},
-    {'_', 57, 33},
-    {ENTER_KEY, 64, 24},
-    {'7', 89, 33},
-    {'8', 97, 33},
-    {'9', 105, 33},
-    {'!', 113, 33},
-    {'+', 120, 33},
-};
-
-static uint8_t get_row_size(uint8_t row_index)
-{
-    uint8_t row_size = 0;
-
-    switch (row_index + 1)
-    {
-    case 1:
-        row_size = sizeof(keyboard_keys_row_1) / sizeof(UART_TextInputKey);
-        break;
-    case 2:
-        row_size = sizeof(keyboard_keys_row_2) / sizeof(UART_TextInputKey);
-        break;
-    case 3:
-        row_size = sizeof(keyboard_keys_row_3) / sizeof(UART_TextInputKey);
-        break;
-    case 4:
-        row_size = sizeof(keyboard_keys_row_4) / sizeof(UART_TextInputKey);
-        break;
-    }
-
-    return row_size;
-}
-
-static const UART_TextInputKey *get_row(uint8_t row_index)
-{
-    const UART_TextInputKey *row = NULL;
-
-    switch (row_index + 1)
-    {
-    case 1:
-        row = keyboard_keys_row_1;
-        break;
-    case 2:
-        row = keyboard_keys_row_2;
-        break;
-    case 3:
-        row = keyboard_keys_row_3;
-        break;
-    case 4:
-        row = keyboard_keys_row_4;
-        break;
-    }
-
-    return row;
-}
-
-static char get_selected_char(UART_TextInputModel *model)
-{
-    return get_row(model->selected_row)[model->selected_column].text;
-}
-
-static bool char_is_lowercase(char letter)
-{
-    return (letter >= 0x61 && letter <= 0x7A);
-}
-
-static bool char_is_uppercase(char letter)
-{
-    return (letter >= 0x41 && letter <= 0x5A);
-}
-
-static char char_to_lowercase(const char letter)
-{
-    switch (letter)
-    {
-    case ' ':
-        return 0x5f;
-        break;
-    case ')':
-        return 0x28;
-        break;
-    case '}':
-        return 0x7b;
-        break;
-    case ']':
-        return 0x5b;
-        break;
-    case '\\':
-        return 0x2f;
-        break;
-    case ':':
-        return 0x3b;
-        break;
-    case ',':
-        return 0x2e;
-        break;
-    case '?':
-        return 0x21;
-        break;
-    case '>':
-        return 0x3c;
-        break;
-    }
-    if (char_is_uppercase(letter))
-    {
-        return (letter + 0x20);
-    }
-    else
-    {
-        return letter;
-    }
-}
-
-static char char_to_uppercase(const char letter)
-{
-    switch (letter)
-    {
-    case '_':
-        return 0x20;
-        break;
-    case '(':
-        return 0x29;
-        break;
-    case '{':
-        return 0x7d;
-        break;
-    case '[':
-        return 0x5d;
-        break;
-    case '/':
-        return 0x5c;
-        break;
-    case ';':
-        return 0x3a;
-        break;
-    case '.':
-        return 0x2c;
-        break;
-    case '!':
-        return 0x3f;
-        break;
-    case '<':
-        return 0x3e;
-        break;
-    }
-    if (char_is_lowercase(letter))
-    {
-        return (letter - 0x20);
-    }
-    else
-    {
-        return letter;
-    }
-}
-
-static void uart_text_input_backspace_cb(UART_TextInputModel *model)
-{
-    uint8_t text_length = model->clear_default_text ? 1 : strlen(model->text_buffer);
-    if (text_length > 0)
-    {
-        model->text_buffer[text_length - 1] = 0;
-    }
-}
-
-static void uart_text_input_view_draw_callback(Canvas *canvas, void *_model)
-{
-    UART_TextInputModel *model = _model;
-    // uint8_t text_length = model->text_buffer ? strlen(model->text_buffer) : 0;
-    uint8_t needed_string_width = canvas_width(canvas) - 8;
-    uint8_t start_pos = 4;
-
-    const char *text = model->text_buffer;
-
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-
-    canvas_draw_str(canvas, 2, 7, model->header);
-    elements_slightly_rounded_frame(canvas, 1, 8, 126, 12);
-
-    if (canvas_string_width(canvas, text) > needed_string_width)
-    {
-        canvas_draw_str(canvas, start_pos, 17, "...");
-        start_pos += 6;
-        needed_string_width -= 8;
-    }
-
-    while (text != 0 && canvas_string_width(canvas, text) > needed_string_width)
-    {
-        text++;
-    }
-
-    if (model->clear_default_text)
-    {
-        elements_slightly_rounded_box(
-            canvas, start_pos - 1, 14, canvas_string_width(canvas, text) + 2, 10);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    else
-    {
-        canvas_draw_str(canvas, start_pos + canvas_string_width(canvas, text) + 1, 18, "|");
-        canvas_draw_str(canvas, start_pos + canvas_string_width(canvas, text) + 2, 18, "|");
-    }
-    canvas_draw_str(canvas, start_pos, 17, text);
-
-    canvas_set_font(canvas, FontKeyboard);
-
-    for (uint8_t row = 0; row <= keyboard_row_count; row++)
-    {
-        const uint8_t column_count = get_row_size(row);
-        const UART_TextInputKey *keys = get_row(row);
-
-        for (size_t column = 0; column < column_count; column++)
-        {
-            if (keys[column].text == ENTER_KEY)
-            {
-                canvas_set_color(canvas, ColorBlack);
-                if (model->selected_row == row && model->selected_column == column)
-                {
-                    canvas_draw_icon(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        &I_KeySaveSelected_24x11);
-                }
-                else
-                {
-                    canvas_draw_icon(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        &I_KeySave_24x11);
-                }
-            }
-            else if (keys[column].text == BACKSPACE_KEY)
-            {
-                canvas_set_color(canvas, ColorBlack);
-                if (model->selected_row == row && model->selected_column == column)
-                {
-                    canvas_draw_icon(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        &I_KeyBackspaceSelected_16x9);
-                }
-                else
-                {
-                    canvas_draw_icon(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        &I_KeyBackspace_16x9);
-                }
-            }
-            else
-            {
-                if (model->selected_row == row && model->selected_column == column)
-                {
-                    canvas_set_color(canvas, ColorBlack);
-                    canvas_draw_box(
-                        canvas,
-                        keyboard_origin_x + keys[column].x - 1,
-                        keyboard_origin_y + keys[column].y - 8,
-                        7,
-                        10);
-                    canvas_set_color(canvas, ColorWhite);
-                }
-                else
-                {
-                    canvas_set_color(canvas, ColorBlack);
-                }
-                if (0 == strcmp(model->header, mode_AT))
-                {
-                    canvas_draw_glyph(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        char_to_uppercase(keys[column].text));
-                }
-                else
-                {
-                    canvas_draw_glyph(
-                        canvas,
-                        keyboard_origin_x + keys[column].x,
-                        keyboard_origin_y + keys[column].y,
-                        keys[column].text);
-                }
-            }
-        }
-    }
-    if (model->valadator_message_visible)
-    {
-        canvas_set_font(canvas, FontSecondary);
-        canvas_set_color(canvas, ColorWhite);
-        canvas_draw_box(canvas, 8, 10, 110, 48);
-        canvas_set_color(canvas, ColorBlack);
-        canvas_draw_icon(canvas, 10, 14, &I_WarningDolphin_45x42);
-        canvas_draw_rframe(canvas, 8, 8, 112, 50, 3);
-        canvas_draw_rframe(canvas, 9, 9, 110, 48, 2);
-        elements_multiline_text(canvas, 62, 20, furi_string_get_cstr(model->validator_text));
-        canvas_set_font(canvas, FontKeyboard);
-    }
-}
-
-static void
-uart_text_input_handle_up(UART_TextInput *uart_text_input, UART_TextInputModel *model)
-{
-    UNUSED(uart_text_input);
-    if (model->selected_row > 0)
-    {
-        model->selected_row--;
-        if (model->selected_column > get_row_size(model->selected_row) - 6)
-        {
-            model->selected_column = model->selected_column + 1;
-        }
-    }
-}
-
-static void
-uart_text_input_handle_down(UART_TextInput *uart_text_input, UART_TextInputModel *model)
-{
-    UNUSED(uart_text_input);
-    if (model->selected_row < keyboard_row_count - 1)
-    {
-        model->selected_row++;
-        if (model->selected_column > get_row_size(model->selected_row) - 4)
-        {
-            model->selected_column = model->selected_column - 1;
-        }
-    }
-}
-
-static void
-uart_text_input_handle_left(UART_TextInput *uart_text_input, UART_TextInputModel *model)
-{
-    UNUSED(uart_text_input);
-    if (model->selected_column > 0)
-    {
-        model->selected_column--;
-    }
-    else
-    {
-        model->selected_column = get_row_size(model->selected_row) - 1;
-    }
-}
-
-static void
-uart_text_input_handle_right(UART_TextInput *uart_text_input, UART_TextInputModel *model)
-{
-    UNUSED(uart_text_input);
-    if (model->selected_column < get_row_size(model->selected_row) - 1)
-    {
-        model->selected_column++;
-    }
-    else
-    {
-        model->selected_column = 0;
-    }
-}
-
-static void uart_text_input_handle_ok(
-    UART_TextInput *uart_text_input,
-    UART_TextInputModel *model,
-    bool shift)
-{
-    char selected = get_selected_char(model);
-    uint8_t text_length = strlen(model->text_buffer);
-
-    if (0 == strcmp(model->header, mode_AT))
-    {
-        selected = char_to_uppercase(selected);
-    }
-
-    if (shift)
-    {
-        if (0 == strcmp(model->header, mode_AT))
-        {
-            selected = char_to_lowercase(selected);
-        }
-        else
-        {
-            selected = char_to_uppercase(selected);
-        }
-    }
-
-    if (selected == ENTER_KEY)
-    {
-        if (model->validator_callback &&
-            (!model->validator_callback(
-                model->text_buffer, model->validator_text, model->validator_callback_context)))
-        {
-            model->valadator_message_visible = true;
-            furi_timer_start(uart_text_input->timer, furi_kernel_get_tick_frequency() * 4);
-        }
-        else if (model->callback != 0 && text_length > 0)
-        {
-            model->callback(model->callback_context);
-        }
-    }
-    else if (selected == BACKSPACE_KEY)
-    {
-        uart_text_input_backspace_cb(model);
-    }
-    else
-    {
-        if (model->clear_default_text)
-        {
-            text_length = 0;
-        }
-        if (text_length < (model->text_buffer_size - 1))
-        {
-            model->text_buffer[text_length] = selected;
-            model->text_buffer[text_length + 1] = 0;
-        }
-    }
-    model->clear_default_text = false;
-}
-
-static bool uart_text_input_view_input_callback(InputEvent *event, void *context)
-{
-    UART_TextInput *uart_text_input = context;
-    furi_assert(uart_text_input);
-
-    bool consumed = false;
-
-    // Acquire model
-    UART_TextInputModel *model = view_get_model(uart_text_input->view);
-
-    if ((!(event->type == InputTypePress) && !(event->type == InputTypeRelease)) &&
-        model->valadator_message_visible)
-    {
-        model->valadator_message_visible = false;
-        consumed = true;
-    }
-    else if (event->type == InputTypeShort)
-    {
-        consumed = true;
-        switch (event->key)
-        {
-        case InputKeyUp:
-            uart_text_input_handle_up(uart_text_input, model);
-            break;
-        case InputKeyDown:
-            uart_text_input_handle_down(uart_text_input, model);
-            break;
-        case InputKeyLeft:
-            uart_text_input_handle_left(uart_text_input, model);
-            break;
-        case InputKeyRight:
-            uart_text_input_handle_right(uart_text_input, model);
-            break;
-        case InputKeyOk:
-            uart_text_input_handle_ok(uart_text_input, model, false);
-            break;
-        default:
-            consumed = false;
-            break;
-        }
-    }
-    else if (event->type == InputTypeLong)
-    {
-        consumed = true;
-        switch (event->key)
-        {
-        case InputKeyUp:
-            uart_text_input_handle_up(uart_text_input, model);
-            break;
-        case InputKeyDown:
-            uart_text_input_handle_down(uart_text_input, model);
-            break;
-        case InputKeyLeft:
-            uart_text_input_handle_left(uart_text_input, model);
-            break;
-        case InputKeyRight:
-            uart_text_input_handle_right(uart_text_input, model);
-            break;
-        case InputKeyOk:
-            uart_text_input_handle_ok(uart_text_input, model, true);
-            break;
-        case InputKeyBack:
-            uart_text_input_backspace_cb(model);
-            break;
-        default:
-            consumed = false;
-            break;
-        }
-    }
-    else if (event->type == InputTypeRepeat)
-    {
-        consumed = true;
-        switch (event->key)
-        {
-        case InputKeyUp:
-            uart_text_input_handle_up(uart_text_input, model);
-            break;
-        case InputKeyDown:
-            uart_text_input_handle_down(uart_text_input, model);
-            break;
-        case InputKeyLeft:
-            uart_text_input_handle_left(uart_text_input, model);
-            break;
-        case InputKeyRight:
-            uart_text_input_handle_right(uart_text_input, model);
-            break;
-        case InputKeyBack:
-            uart_text_input_backspace_cb(model);
-            break;
-        default:
-            consumed = false;
-            break;
-        }
-    }
-
-    // Commit model
-    view_commit_model(uart_text_input->view, consumed);
-
-    return consumed;
-}
-
-void uart_text_input_timer_callback(void *context)
-{
-    furi_assert(context);
-    UART_TextInput *uart_text_input = context;
-
-    with_view_model(
-        uart_text_input->view,
-        UART_TextInputModel * model,
-        { model->valadator_message_visible = false; },
-        true);
-}
-
-UART_TextInput *uart_text_input_alloc()
-{
-    UART_TextInput *uart_text_input = malloc(sizeof(UART_TextInput));
-    uart_text_input->view = view_alloc();
-    view_set_context(uart_text_input->view, uart_text_input);
-    view_allocate_model(uart_text_input->view, ViewModelTypeLocking, sizeof(UART_TextInputModel));
-    view_set_draw_callback(uart_text_input->view, uart_text_input_view_draw_callback);
-    view_set_input_callback(uart_text_input->view, uart_text_input_view_input_callback);
-
-    uart_text_input->timer =
-        furi_timer_alloc(uart_text_input_timer_callback, FuriTimerTypeOnce, uart_text_input);
-
-    with_view_model(
-        uart_text_input->view,
-        UART_TextInputModel * model,
-        { model->validator_text = furi_string_alloc(); },
-        false);
-
-    uart_text_input_reset(uart_text_input);
-
-    return uart_text_input;
-}
-
-void uart_text_input_free(UART_TextInput *uart_text_input)
-{
-    furi_assert(uart_text_input);
-    with_view_model(
-        uart_text_input->view,
-        UART_TextInputModel * model,
-        { furi_string_free(model->validator_text); },
-        false);
-
-    // Send stop command
-    furi_timer_stop(uart_text_input->timer);
-    // Release allocated memory
-    furi_timer_free(uart_text_input->timer);
-
-    view_free(uart_text_input->view);
-
-    free(uart_text_input);
-}
-
-void uart_text_input_reset(UART_TextInput *uart_text_input)
-{
-    furi_assert(uart_text_input);
-    with_view_model(
-        uart_text_input->view,
-        UART_TextInputModel * model,
-        {
-            model->text_buffer_size = 0;
-            model->header = "";
-            model->selected_row = 0;
-            model->selected_column = 0;
-            model->clear_default_text = false;
-            model->text_buffer = NULL;
-            model->text_buffer_size = 0;
-            model->callback = NULL;
-            model->callback_context = NULL;
-            model->validator_callback = NULL;
-            model->validator_callback_context = NULL;
-            furi_string_reset(model->validator_text);
-            model->valadator_message_visible = false;
-        },
-        true);
-}
-
-View *uart_text_input_get_view(UART_TextInput *uart_text_input)
-{
-    furi_assert(uart_text_input);
-    return uart_text_input->view;
-}
-
-void uart_text_input_set_result_callback(
-    UART_TextInput *uart_text_input,
-    UART_TextInputCallback callback,
-    void *callback_context,
-    char *text_buffer,
-    size_t text_buffer_size,
-    bool clear_default_text)
-{
-    with_view_model(
-        uart_text_input->view,
-        UART_TextInputModel * model,
-        {
-            model->callback = callback;
-            model->callback_context = callback_context;
-            model->text_buffer = text_buffer;
-            model->text_buffer_size = text_buffer_size;
-            model->clear_default_text = clear_default_text;
-            if (text_buffer && text_buffer[0] != '\0')
-            {
-                // Set focus on Save
-                model->selected_row = 2;
-                model->selected_column = 8;
-            }
-        },
-        true);
-}
-
-void uart_text_input_set_validator(
-    UART_TextInput *uart_text_input,
-    UART_TextInputValidatorCallback callback,
-    void *callback_context)
-{
-    with_view_model(
-        uart_text_input->view,
-        UART_TextInputModel * model,
-        {
-            model->validator_callback = callback;
-            model->validator_callback_context = callback_context;
-        },
-        true);
-}
-
-UART_TextInputValidatorCallback
-uart_text_input_get_validator_callback(UART_TextInput *uart_text_input)
-{
-    UART_TextInputValidatorCallback validator_callback = NULL;
-    with_view_model(
-        uart_text_input->view,
-        UART_TextInputModel * model,
-        { validator_callback = model->validator_callback; },
-        false);
-    return validator_callback;
-}
-
-void *uart_text_input_get_validator_callback_context(UART_TextInput *uart_text_input)
-{
-    void *validator_callback_context = NULL;
-    with_view_model(
-        uart_text_input->view,
-        UART_TextInputModel * model,
-        { validator_callback_context = model->validator_callback_context; },
-        false);
-    return validator_callback_context;
-}
-
-void uart_text_input_set_header_text(UART_TextInput *uart_text_input, const char *text)
-{
-    with_view_model(
-        uart_text_input->view, UART_TextInputModel * model, { model->header = text; }, true);
-}
-
-#endif // UART_TEXT_INPUT_H