Просмотр исходного кода

FlipSocial - v0.7 development

Work in progress. To do:
- Fix freezing after accessing the Friends view
- Add Derek's generis_view_model for the Feed, Login, and Registration views
jblanked 1 год назад
Родитель
Сommit
80e41c83a7

+ 2 - 2
README.md

@@ -90,6 +90,6 @@ This is a big project, and I welcome all contributors, especially developers int
 5. Out of memory when starting the app or after visiting the feed and post views back-to-back.
 5. Out of memory when starting the app or after visiting the feed and post views back-to-back.
 - **Solution:** Restart your Flipper device.
 - **Solution:** Restart your Flipper device.
 
 
-6. I can no longer access my Direct Messages.
+6. I can no longer access the Messages.
 - **Solution 1:** Uppdate the app to version 0.6.3 (or higher)
 - **Solution 1:** Uppdate the app to version 0.6.3 (or higher)
-- **Solution 2:** Click the logout button then login again.
+- **Solution 2:** Click the logout button then login again. Make sure your password is correct before clicking "Login".

+ 18 - 18
alloc/flip_social_alloc.c

@@ -165,11 +165,11 @@ FlipSocialApp *flip_social_app_alloc()
     }
     }
 
 
     // Allocate Submenu(s)
     // Allocate Submenu(s)
-    if (!easy_flipper_set_submenu(&app->submenu_logged_out, FlipSocialViewLoggedOutSubmenu, "FlipSocial v0.6", flip_social_callback_exit_app, &app->view_dispatcher))
+    if (!easy_flipper_set_submenu(&app->submenu_logged_out, FlipSocialViewLoggedOutSubmenu, "FlipSocial v0.7", flip_social_callback_exit_app, &app->view_dispatcher))
     {
     {
         return NULL;
         return NULL;
     }
     }
-    if (!easy_flipper_set_submenu(&app->submenu_logged_in, FlipSocialViewLoggedInSubmenu, "FlipSocial v0.6", flip_social_callback_exit_app, &app->view_dispatcher))
+    if (!easy_flipper_set_submenu(&app->submenu_logged_in, FlipSocialViewLoggedInSubmenu, "FlipSocial v0.7", flip_social_callback_exit_app, &app->view_dispatcher))
     {
     {
         return NULL;
         return NULL;
     }
     }
@@ -266,27 +266,27 @@ FlipSocialApp *flip_social_app_alloc()
         return NULL;
         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_wifi_settings_ssid = variable_item_list_add(app->variable_item_list_logged_out_wifi_settings, "SSID", 1, NULL, app);
+    app->variable_item_logged_out_wifi_settings_password = variable_item_list_add(app->variable_item_list_logged_out_wifi_settings, "Password", 1, NULL, app);
     //
     //
-    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_login_username = variable_item_list_add(app->variable_item_list_logged_out_login, "Username", 1, NULL, app);
+    app->variable_item_logged_out_login_password = variable_item_list_add(app->variable_item_list_logged_out_login, "Password", 1, NULL, app);
+    app->variable_item_logged_out_login_button = variable_item_list_add(app->variable_item_list_logged_out_login, "Login", 0, NULL, app);
     //
     //
-    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_out_register_username = variable_item_list_add(app->variable_item_list_logged_out_register, "Username", 1, NULL, app);
+    app->variable_item_logged_out_register_password = variable_item_list_add(app->variable_item_list_logged_out_register, "Password", 1, NULL, app);
+    app->variable_item_logged_out_register_password_2 = variable_item_list_add(app->variable_item_list_logged_out_register, "Confirm Password", 1, NULL, app);
+    app->variable_item_logged_out_register_button = variable_item_list_add(app->variable_item_list_logged_out_register, "Register", 0, NULL, app);
     //
     //
-    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_profile_username = variable_item_list_add(app->variable_item_list_logged_in_profile, "Username", 1, NULL, app);
+    app->variable_item_logged_in_profile_change_password = variable_item_list_add(app->variable_item_list_logged_in_profile, "Change Password", 1, NULL, app);
+    app->variable_item_logged_in_profile_friends = variable_item_list_add(app->variable_item_list_logged_in_profile, "Friends", 0, NULL, app);
     //
     //
-    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_settings_about = variable_item_list_add(app->variable_item_list_logged_in_settings, "About", 0, NULL, app);
+    app->variable_item_logged_in_settings_wifi = variable_item_list_add(app->variable_item_list_logged_in_settings, "WiFi", 0, NULL, app);
     //
     //
-    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);
+    app->variable_item_logged_in_wifi_settings_ssid = variable_item_list_add(app->variable_item_list_logged_in_settings_wifi, "SSID", 1, NULL, app);
+    app->variable_item_logged_in_wifi_settings_password = variable_item_list_add(app->variable_item_list_logged_in_settings_wifi, "Password", 1, NULL, app);
 
 
     // Setup Text Input(s)
     // 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))
     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))

+ 1 - 1
application.fam

@@ -9,6 +9,6 @@ App(
     fap_icon_assets="assets",
     fap_icon_assets="assets",
     fap_author="jblanked",
     fap_author="jblanked",
     fap_weburl="https://github.com/jblanked/FlipSocial",
     fap_weburl="https://github.com/jblanked/FlipSocial",
-    fap_version="0.6.3",
+    fap_version="0.7",
     fap_description="Social media platform for the Flipper Zero.",
     fap_description="Social media platform for the Flipper Zero.",
 )
 )

+ 6 - 0
assets/CHANGELOG.md

@@ -1,3 +1,9 @@
+## 0.7
+- Improved memory allocation
+- Increased the max explore users from 50 to 100
+- Increased the max feed posts from 40 to 50.
+- Added loading screens.
+
 ## 0.6
 ## 0.6
 - Improved memory allocation
 - Improved memory allocation
 - Fixed bugs in Direct Messaging View
 - Fixed bugs in Direct Messaging View

+ 96 - 54
callback/flip_social_callback.c

@@ -20,10 +20,15 @@ uint32_t flip_social_callback_to_submenu_logged_in(void *context)
 {
 {
     UNUSED(context);
     UNUSED(context);
     flip_social_free_explore();
     flip_social_free_explore();
-    flip_social_free_feed();
     flip_social_free_friends();
     flip_social_free_friends();
     flip_social_free_message_users();
     flip_social_free_message_users();
     flip_social_free_messages();
     flip_social_free_messages();
+    flip_feed_info_free();
+    if (flip_feed_item)
+    {
+        free(flip_feed_item);
+        flip_feed_item = NULL;
+    }
     return FlipSocialViewLoggedInSubmenu;
     return FlipSocialViewLoggedInSubmenu;
 }
 }
 
 
@@ -116,7 +121,7 @@ uint32_t flip_social_callback_to_profile_logged_in(void *context)
 uint32_t flip_social_callback_to_explore_logged_in(void *context)
 uint32_t flip_social_callback_to_explore_logged_in(void *context)
 {
 {
     UNUSED(context);
     UNUSED(context);
-    flip_social_dialog_stop = true;
+    flip_social_dialog_stop = false;
     last_explore_response = "";
     last_explore_response = "";
     flip_social_dialog_shown = false;
     flip_social_dialog_shown = false;
     flip_social_explore->index = 0;
     flip_social_explore->index = 0;
@@ -132,7 +137,7 @@ uint32_t flip_social_callback_to_explore_logged_in(void *context)
 uint32_t flip_social_callback_to_friends_logged_in(void *context)
 uint32_t flip_social_callback_to_friends_logged_in(void *context)
 {
 {
     UNUSED(context);
     UNUSED(context);
-    flip_social_dialog_stop = true;
+    flip_social_dialog_stop = false;
     last_explore_response = "";
     last_explore_response = "";
     flip_social_dialog_shown = false;
     flip_social_dialog_shown = false;
     flip_social_friends->index = 0;
     flip_social_friends->index = 0;
@@ -215,37 +220,82 @@ void flip_social_callback_submenu_choices(void *context, uint32_t index)
         view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInProfile);
         view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInProfile);
         break;
         break;
     case FlipSocialSubmenuLoggedInIndexMessages:
     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);
-        }
+        flipper_http_loading_task(
+            flip_social_get_message_users,         // get the message users
+            flip_social_parse_json_message_users,  // parse the message users
+            FlipSocialViewLoggedInMessagesSubmenu, // switch to the messages submenu if successful
+            FlipSocialViewLoggedInSubmenu,         // switch back to the main submenu if failed
+            &app->view_dispatcher);                // view dispatcher
         break;
         break;
     case FlipSocialSubmenuLoggedInIndexMessagesNewMessage:
     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);
-        }
+        flipper_http_loading_task(
+            flip_social_get_explore,                     // get the explore users
+            flip_social_parse_json_message_user_choices, // parse the explore users
+            FlipSocialViewLoggedInMessagesUserChoices,   // switch to the user choices if successful
+            FlipSocialViewLoggedInSubmenu,               // switch back to the main submenu if failed
+            &app->view_dispatcher);                      // view dispatcher
         break;
         break;
     case FlipSocialSubmenuLoggedInIndexFeed:
     case FlipSocialSubmenuLoggedInIndexFeed:
-        if (flipper_http_process_response_async(flip_social_get_feed, flip_social_parse_json_feed))
+        if (!easy_flipper_set_loading(&app->loading, FlipSocialViewLoading, flip_social_callback_to_submenu_logged_in, &app->view_dispatcher))
         {
         {
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInFeed);
+            FURI_LOG_E(TAG, "Failed to set loading screen");
+            return; // already on the submenu
+        }
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoading);
+        if (flip_social_get_feed()) // start the async request
+        {
+            furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
+            fhttp.state = RECEIVING;
         }
         }
         else
         else
         {
         {
-            // Set failure FlipSocialFeed object
-            if (!flip_social_temp_feed())
-            {
-                return;
-            }
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInFeed);
+            FURI_LOG_E(HTTP_TAG, "Failed to send request");
+            fhttp.state = ISSUE;
+            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSubmenu);
+            view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoading);
+            loading_free(app->loading);
+            return;
         }
         }
-        break;
-    case FlipSocialSubmenuExploreIndex:
-        if (flipper_http_process_response_async(flip_social_get_explore, flip_social_parse_json_explore))
+        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);
+
+        // load feed info
+        flip_feed_info = flip_social_parse_json_feed();
+        if (!flip_feed_info || flip_feed_info->count < 1)
+        {
+            FURI_LOG_E(TAG, "Failed to parse JSON feed");
+            fhttp.state = ISSUE;
+            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSubmenu);
+            view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoading);
+            loading_free(app->loading);
+            return;
+        }
+
+        // load the current feed post
+        if (!flip_social_load_feed_post(flip_feed_info->ids[flip_feed_info->index]))
         {
         {
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInExploreSubmenu);
+            FURI_LOG_E(TAG, "Failed to load feed post");
+            fhttp.state = ISSUE;
+            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSubmenu);
+            view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoading);
+            loading_free(app->loading);
+            return;
         }
         }
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInFeed);
+        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoading);
+        loading_free(app->loading);
+        break;
+    case FlipSocialSubmenuExploreIndex:
+        flipper_http_loading_task(
+            flip_social_get_explore,              // get the explore users
+            flip_social_parse_json_explore,       // parse the explore users
+            FlipSocialViewLoggedInExploreSubmenu, // switch to the explore submenu if successful
+            FlipSocialViewLoggedInSubmenu,        // switch back to the main submenu if failed
+            &app->view_dispatcher);               // view dispatcher
         break;
         break;
     case FlipSocialSubmenuLoggedInIndexCompose:
     case FlipSocialSubmenuLoggedInIndexCompose:
         view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInCompose);
         view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInCompose);
@@ -311,10 +361,12 @@ void flip_social_callback_submenu_choices(void *context, uint32_t index)
                 return;
                 return;
             }
             }
             flip_social_message_users->index = index - FlipSocialSubmenuLoggedInIndexMessagesUsersStart;
             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);
-            }
+            flipper_http_loading_task(
+                flip_social_get_messages_with_user,    // get the messages with the selected user
+                flip_social_parse_json_messages,       // parse the messages
+                FlipSocialViewLoggedInMessagesProcess, // switch to the messages process if successful
+                FlipSocialViewLoggedInMessagesSubmenu, // switch back to the messages submenu if failed
+                &app->view_dispatcher);                // view dispatcher
         }
         }
 
 
         // handle the messages user choices selection
         // handle the messages user choices selection
@@ -367,10 +419,13 @@ void flip_social_logged_out_wifi_settings_ssid_updated(void *context)
     }
     }
 
 
     // update the wifi settings
     // update the wifi settings
-    if (!flipper_http_save_wifi(app->wifi_ssid_logged_out, app->wifi_password_logged_out))
+    if (strlen(app->wifi_ssid_logged_out) > 0 && strlen(app->wifi_password_logged_out) > 0)
     {
     {
-        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");
+        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 the settings
@@ -409,10 +464,13 @@ void flip_social_logged_out_wifi_settings_password_updated(void *context)
     }
     }
 
 
     // update the wifi settings
     // update the wifi settings
-    if (!flipper_http_save_wifi(app->wifi_ssid_logged_out, app->wifi_password_logged_out))
+    if (strlen(app->wifi_ssid_logged_out) > 0 && strlen(app->wifi_password_logged_out) > 0)
     {
     {
-        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");
+        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 the settings
@@ -908,25 +966,7 @@ void flip_social_text_input_logged_in_profile_item_selected(void *context, uint3
         view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInChangePasswordInput);
         view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInChangePasswordInput);
         break;
         break;
     case 2: // Friends
     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);
+        flipper_http_loading_task(flip_social_get_friends, flip_social_parse_json_friends, FlipSocialViewLoggedInFriendsSubmenu, FlipSocialViewLoggedInProfile, &app->view_dispatcher);
         break;
         break;
     default:
     default:
         FURI_LOG_E(TAG, "Unknown configuration item index");
         FURI_LOG_E(TAG, "Unknown configuration item index");
@@ -1005,12 +1045,13 @@ void flip_social_logged_in_messages_user_choice_message_updated(void *context)
     {
     {
         FURI_LOG_E(TAG, "Failed to send post request to send message");
         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");
         FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
+        fhttp.state = ISSUE;
         return;
         return;
     }
     }
     while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
     while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
     {
     {
         // Wait for the request to be received
         // Wait for the request to be received
-        furi_delay_ms(100);
+        furi_delay_ms(10);
     }
     }
     furi_timer_stop(fhttp.get_timeout_timer);
     furi_timer_stop(fhttp.get_timeout_timer);
 
 
@@ -1067,12 +1108,13 @@ void flip_social_logged_in_messages_new_message_updated(void *context)
     {
     {
         FURI_LOG_E(TAG, "Failed to send post request to send message");
         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");
         FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
+        fhttp.state = ISSUE;
         return;
         return;
     }
     }
     while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
     while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
     {
     {
         // Wait for the request to be received
         // Wait for the request to be received
-        furi_delay_ms(100);
+        furi_delay_ms(10);
     }
     }
     furi_timer_stop(fhttp.get_timeout_timer);
     furi_timer_stop(fhttp.get_timeout_timer);
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesSubmenu);
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesSubmenu);

+ 79 - 24
draw/flip_social_draw.c

@@ -205,7 +205,6 @@ void flip_social_callback_draw_compose(Canvas *canvas, void *model)
             char command[256];
             char command[256];
             snprintf(command, sizeof(command), "{\"username\":\"%s\",\"content\":\"%s\"}",
             snprintf(command, sizeof(command), "{\"username\":\"%s\",\"content\":\"%s\"}",
                      app_instance->login_username_logged_in, selected_message);
                      app_instance->login_username_logged_in, selected_message);
-
             if (!flipper_http_post_request_with_headers(
             if (!flipper_http_post_request_with_headers(
                     "https://www.flipsocial.net/api/feed/post/",
                     "https://www.flipsocial.net/api/feed/post/",
                     auth_headers,
                     auth_headers,
@@ -277,19 +276,60 @@ void flip_social_callback_draw_compose(Canvas *canvas, void *model)
             canvas_draw_str(canvas, 0, 50, "Loading feed :D");
             canvas_draw_str(canvas, 0, 50, "Loading feed :D");
             canvas_draw_str(canvas, 0, 60, "Please wait...");
             canvas_draw_str(canvas, 0, 60, "Please wait...");
             action = ActionNone;
             action = ActionNone;
-            if (flipper_http_process_response_async(flip_social_get_feed, flip_social_parse_json_feed))
+            // Send the user to the feed
+
+            if (!easy_flipper_set_loading(&app_instance->loading, FlipSocialViewLoading, flip_social_callback_to_submenu_logged_in, &app_instance->view_dispatcher))
+            {
+                FURI_LOG_E(TAG, "Failed to set loading screen");
+                return; // already on the submenu
+            }
+            view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoading);
+            if (flip_social_get_feed()) // start the async request
             {
             {
-                view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInFeed);
+                furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
+                fhttp.state = RECEIVING;
             }
             }
             else
             else
             {
             {
-                // Set failure FlipSocialFeed object
-                if (!flip_social_temp_feed())
-                {
-                    return;
-                }
-                view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInFeed);
+                FURI_LOG_E(HTTP_TAG, "Failed to send request");
+                fhttp.state = ISSUE;
+                view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
+                view_dispatcher_remove_view(app_instance->view_dispatcher, FlipSocialViewLoading);
+                loading_free(app_instance->loading);
+                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);
+
+            // load feed info
+            flip_feed_info = flip_social_parse_json_feed();
+            if (!flip_feed_info || flip_feed_info->count < 1)
+            {
+                FURI_LOG_E(TAG, "Failed to parse JSON feed");
+                fhttp.state = ISSUE;
+                view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
+                view_dispatcher_remove_view(app_instance->view_dispatcher, FlipSocialViewLoading);
+                loading_free(app_instance->loading);
+                return;
+            }
+
+            // load the current feed post
+            if (!flip_social_load_feed_post(flip_feed_info->ids[flip_feed_info->index]))
+            {
+                FURI_LOG_E(TAG, "Failed to load feed post");
+                fhttp.state = ISSUE;
+                view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
+                view_dispatcher_remove_view(app_instance->view_dispatcher, FlipSocialViewLoading);
+                loading_free(app_instance->loading);
+                return;
             }
             }
+            view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInFeed);
+            view_dispatcher_remove_view(app_instance->view_dispatcher, FlipSocialViewLoading);
+            loading_free(app_instance->loading);
         }
         }
         else if (action == ActionBack)
         else if (action == ActionBack)
         {
         {
@@ -422,41 +462,55 @@ void flip_social_callback_draw_feed(Canvas *canvas, void *model)
     switch (action)
     switch (action)
     {
     {
     case ActionNone:
     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]);
+        flip_social_canvas_draw_message(canvas, flip_feed_item->username, flip_feed_item->message, flip_feed_item->is_flipped, flip_feed_info->index > 0, flip_feed_info->index < flip_feed_info->count - 1, flip_feed_item->flips);
         break;
         break;
     case ActionNext:
     case ActionNext:
         canvas_clear(canvas);
         canvas_clear(canvas);
-        if (flip_social_feed->index < flip_social_feed->count - 1)
+        if (flip_feed_info->index < flip_feed_info->count - 1)
+        {
+            flip_feed_info->index++;
+        }
+        // load the next feed item
+        if (!flip_social_load_feed_post(flip_feed_info->ids[flip_feed_info->index]))
         {
         {
-            flip_social_feed->index++;
+            FURI_LOG_E(TAG, "Failed to load nexy feed post");
+            fhttp.state = ISSUE;
+            return;
         }
         }
-        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]);
+        flip_social_canvas_draw_message(canvas, flip_feed_item->username, flip_feed_item->message, flip_feed_item->is_flipped, flip_feed_info->index > 0, flip_feed_info->index < flip_feed_info->count - 1, flip_feed_item->flips);
         action = ActionNone;
         action = ActionNone;
         break;
         break;
     case ActionPrev:
     case ActionPrev:
         canvas_clear(canvas);
         canvas_clear(canvas);
-        if (flip_social_feed->index > 0)
+        if (flip_feed_info->index > 0)
+        {
+            flip_feed_info->index--;
+        }
+        // load the previous feed item
+        if (!flip_social_load_feed_post(flip_feed_info->ids[flip_feed_info->index]))
         {
         {
-            flip_social_feed->index--;
+            FURI_LOG_E(TAG, "Failed to load nexy feed post");
+            fhttp.state = ISSUE;
+            return;
         }
         }
-        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]);
+        flip_social_canvas_draw_message(canvas, flip_feed_item->username, flip_feed_item->message, flip_feed_item->is_flipped, flip_feed_info->index > 0, flip_feed_info->index < flip_feed_info->count - 1, flip_feed_item->flips);
         action = ActionNone;
         action = ActionNone;
         break;
         break;
     case ActionFlip:
     case ActionFlip:
         canvas_clear(canvas);
         canvas_clear(canvas);
         // Moved to above the is_flipped check
         // Moved to above the is_flipped check
-        if (!flip_social_feed->is_flipped[flip_social_feed->index])
+        if (!flip_feed_item->is_flipped)
         {
         {
             // increase the flip count
             // increase the flip count
-            flip_social_feed->flips[flip_social_feed->index]++;
+            flip_feed_item->flips++;
         }
         }
         else
         else
         {
         {
             // decrease the flip count
             // decrease the flip count
-            flip_social_feed->flips[flip_social_feed->index]--;
+            flip_feed_item->flips--;
         }
         }
         // change the flip status
         // change the flip status
-        flip_social_feed->is_flipped[flip_social_feed->index] = !flip_social_feed->is_flipped[flip_social_feed->index];
+        flip_feed_item->is_flipped = !flip_feed_item->is_flipped;
         // send post request to flip the message
         // send post request to flip the message
         if (app_instance->login_username_logged_in == NULL)
         if (app_instance->login_username_logged_in == NULL)
         {
         {
@@ -464,15 +518,15 @@ void flip_social_callback_draw_feed(Canvas *canvas, void *model)
             return;
             return;
         }
         }
         char payload[256];
         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]);
+        snprintf(payload, sizeof(payload), "{\"username\":\"%s\",\"post_id\":\"%u\"}", app_instance->login_username_logged_in, flip_feed_item->id);
         flipper_http_post_request_with_headers("https://www.flipsocial.net/api/feed/flip/", auth_headers, payload);
         flipper_http_post_request_with_headers("https://www.flipsocial.net/api/feed/flip/", auth_headers, 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]);
+        flip_social_canvas_draw_message(canvas, flip_feed_item->username, flip_feed_item->message, flip_feed_item->is_flipped, flip_feed_info->index > 0, flip_feed_info->index < flip_feed_info->count - 1, flip_feed_item->flips);
         action = ActionNone;
         action = ActionNone;
         break;
         break;
     case ActionBack:
     case ActionBack:
         canvas_clear(canvas);
         canvas_clear(canvas);
         flip_social_dialog_stop = true;
         flip_social_dialog_stop = true;
-        flip_social_feed->index = 0;
+        flip_feed_info->index = 0;
         action = ActionNone;
         action = ActionNone;
         break;
         break;
     default:
     default:
@@ -564,7 +618,7 @@ void flip_social_callback_draw_login(Canvas *canvas, void *model)
                 }
                 }
                 if (app_instance->login_password_logged_out)
                 if (app_instance->login_password_logged_out)
                 {
                 {
-                    app_instance->change_password_logged_in = app_instance->login_password_logged_out;
+                    strcpy(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);
                 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);
@@ -628,6 +682,7 @@ void flip_social_callback_draw_register(Canvas *canvas, void *model)
     // Perform login request
     // Perform login request
     if (!flip_social_sent_register_request)
     if (!flip_social_sent_register_request)
     {
     {
+
         // check if the username and password are valid
         // 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)
         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)
         {
         {

+ 4 - 3
explore/flip_social_explore.c

@@ -28,7 +28,6 @@ void flip_social_free_explore()
 {
 {
     if (!flip_social_explore)
     if (!flip_social_explore)
     {
     {
-        FURI_LOG_E(TAG, "Explore model is NULL");
         return;
         return;
     }
     }
     for (int i = 0; i < flip_social_explore->count; i++)
     for (int i = 0; i < flip_social_explore->count; i++)
@@ -38,6 +37,8 @@ void flip_social_free_explore()
             free(flip_social_explore->usernames[i]);
             free(flip_social_explore->usernames[i]);
         }
         }
     }
     }
+    free(flip_social_explore);
+    flip_social_explore = NULL;
 }
 }
 
 
 // for now we're just listing the current users
 // for now we're just listing the current users
@@ -47,7 +48,7 @@ bool flip_social_get_explore()
     snprintf(
     snprintf(
         fhttp.file_path,
         fhttp.file_path,
         sizeof(fhttp.file_path),
         sizeof(fhttp.file_path),
-        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/users.txt");
+        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/users.json");
 
 
     fhttp.save_received_data = true;
     fhttp.save_received_data = true;
     auth_headers_alloc();
     auth_headers_alloc();
@@ -99,7 +100,7 @@ bool flip_social_parse_json_explore()
     flip_social_explore->count = 0;
     flip_social_explore->count = 0;
 
 
     // Extract the users array from the JSON
     // Extract the users array from the JSON
-    char *json_users = get_json_value("users", data_cstr, MAX_TOKENS);
+    char *json_users = get_json_value("users", data_cstr, MAX_TOKENS); // currently it's about 480 tokens
     if (json_users == NULL)
     if (json_users == NULL)
     {
     {
         FURI_LOG_E(TAG, "Failed to parse users array.");
         FURI_LOG_E(TAG, "Failed to parse users array.");

+ 111 - 136
feed/flip_social_feed.c

@@ -1,114 +1,5 @@
 #include "flip_social_feed.h"
 #include "flip_social_feed.h"
 
 
-// Set failure FlipSocialFeed object
-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
-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;
-}
-
-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++)
-    {
-        if (flip_social_feed->usernames[i])
-        {
-            free(flip_social_feed->usernames[i]);
-        }
-    }
-}
-
 bool flip_social_get_feed()
 bool flip_social_get_feed()
 {
 {
     if (!app_instance)
     if (!app_instance)
@@ -125,12 +16,12 @@ bool flip_social_get_feed()
     snprintf(
     snprintf(
         fhttp.file_path,
         fhttp.file_path,
         sizeof(fhttp.file_path),
         sizeof(fhttp.file_path),
-        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/feed.txt");
+        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/feed.json");
 
 
     fhttp.save_received_data = true;
     fhttp.save_received_data = true;
     auth_headers_alloc();
     auth_headers_alloc();
     char command[96];
     char command[96];
-    snprintf(command, 96, "https://www.flipsocial.net/api/feed/40/%s/extended/", app_instance->login_username_logged_out);
+    snprintf(command, 96, "https://www.flipsocial.net/api/feed/50/%s/extended/", app_instance->login_username_logged_out);
     if (!flipper_http_get_request_with_headers(command, auth_headers))
     if (!flipper_http_get_request_with_headers(command, auth_headers))
     {
     {
         FURI_LOG_E(TAG, "Failed to send HTTP request for feed");
         FURI_LOG_E(TAG, "Failed to send HTTP request for feed");
@@ -141,29 +32,30 @@ bool flip_social_get_feed()
     return true;
     return true;
 }
 }
 
 
-bool flip_social_parse_json_feed()
+FlipSocialFeedMini *flip_social_parse_json_feed()
 {
 {
     // load the received data from the saved file
     // load the received data from the saved file
     FuriString *feed_data = flipper_http_load_from_file(fhttp.file_path);
     FuriString *feed_data = flipper_http_load_from_file(fhttp.file_path);
     if (feed_data == NULL)
     if (feed_data == NULL)
     {
     {
         FURI_LOG_E(TAG, "Failed to load received data from file.");
         FURI_LOG_E(TAG, "Failed to load received data from file.");
-        return false;
+        return NULL;
     }
     }
     char *data_cstr = (char *)furi_string_get_cstr(feed_data);
     char *data_cstr = (char *)furi_string_get_cstr(feed_data);
     if (data_cstr == NULL)
     if (data_cstr == NULL)
     {
     {
         FURI_LOG_E(TAG, "Failed to get C-string from FuriString.");
         FURI_LOG_E(TAG, "Failed to get C-string from FuriString.");
         furi_string_free(feed_data);
         furi_string_free(feed_data);
-        return false;
+        return NULL;
     }
     }
 
 
-    // Allocate memory for each feed item if not already allocated
-    flip_social_feed = flip_social_feed_alloc();
-    if (flip_social_feed == NULL)
+    FlipSocialFeedMini *feed_info = (FlipSocialFeedMini *)malloc(sizeof(FlipSocialFeedMini));
+    if (!feed_info)
     {
     {
-        return false;
+        FURI_LOG_E(TAG, "Failed to allocate memory for feed_info");
+        return NULL;
     }
     }
+
     // Remove newlines
     // Remove newlines
     char *pos = data_cstr;
     char *pos = data_cstr;
     while ((pos = strchr(pos, '\n')) != NULL)
     while ((pos = strchr(pos, '\n')) != NULL)
@@ -171,8 +63,7 @@ bool flip_social_parse_json_feed()
         *pos = ' ';
         *pos = ' ';
     }
     }
 
 
-    // Initialize feed count
-    flip_social_feed->count = 0;
+    int feed_count = 0;
 
 
     // Iterate through the feed array
     // Iterate through the feed array
     for (int i = 0; i < MAX_FEED_ITEMS; i++)
     for (int i = 0; i < MAX_FEED_ITEMS; i++)
@@ -185,11 +76,11 @@ bool flip_social_parse_json_feed()
         }
         }
 
 
         // Extract individual fields from the JSON object
         // 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);
+        char *username = get_json_value("username", item, 64);
+        char *message = get_json_value("message", item, 64);
+        char *flipped = get_json_value("flipped", item, 64);
+        char *flips = get_json_value("flip_count", item, 64);
+        char *id = get_json_value("id", item, 64);
 
 
         if (username == NULL || message == NULL || flipped == NULL || id == NULL)
         if (username == NULL || message == NULL || flipped == NULL || id == NULL)
         {
         {
@@ -203,16 +94,19 @@ bool flip_social_parse_json_feed()
             continue;
             continue;
         }
         }
 
 
-        // Safely copy strings with bounds checking
-        snprintf(flip_social_feed->usernames[i], MAX_USER_LENGTH, "%s", username);
-        snprintf(flip_social_feed->messages[i], MAX_MESSAGE_LENGTH, "%s", message);
-
-        // 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++;
+        if (!flip_social_save_post(id, item))
+        {
+            FURI_LOG_E(TAG, "Failed to save post.");
+            free(item);
+            free(username);
+            free(message);
+            free(flipped);
+            free(flips);
+            free(id);
+            continue;
+        }
+        feed_count++;
+        feed_info->ids[i] = atoi(id);
 
 
         // Free allocated memory
         // Free allocated memory
         free(item);
         free(item);
@@ -223,7 +117,88 @@ bool flip_social_parse_json_feed()
         free(id);
         free(id);
     }
     }
 
 
+    // Store the number of feed items
+    feed_info->count = feed_count;
+    feed_info->index = 0;
+
     furi_string_free(feed_data);
     furi_string_free(feed_data);
     free(data_cstr);
     free(data_cstr);
-    return flip_social_feed->count > 0;
+    return feed_info;
 }
 }
+
+bool flip_social_load_feed_post(int post_id)
+{
+    char file_path[128];
+    snprintf(file_path, sizeof(file_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/feed_post_%d.json", post_id);
+
+    // load the received data from the saved file
+    FuriString *feed_data = flipper_http_load_from_file(file_path);
+    if (feed_data == NULL)
+    {
+        FURI_LOG_E(TAG, "Failed to load received data from file.");
+        return false;
+    }
+    char *data_cstr = (char *)furi_string_get_cstr(feed_data);
+    if (data_cstr == NULL)
+    {
+        FURI_LOG_E(TAG, "Failed to get C-string from FuriString.");
+        furi_string_free(feed_data);
+        return false;
+    }
+
+    // Parse the feed post
+    if (!flip_feed_item)
+    {
+        flip_feed_item = (FlipSocialFeedItem *)malloc(sizeof(FlipSocialFeedItem));
+        if (flip_feed_item == NULL)
+        {
+            FURI_LOG_E(TAG, "Failed to allocate memory for feed post.");
+            furi_string_free(feed_data);
+            free(data_cstr);
+            return false;
+        }
+        flip_feed_item->username = malloc(MAX_USER_LENGTH);
+        flip_feed_item->message = malloc(MAX_MESSAGE_LENGTH);
+    }
+
+    // Extract individual fields from the JSON object
+    char *username = get_json_value("username", data_cstr, 64);
+    char *message = get_json_value("message", data_cstr, 64);
+    char *flipped = get_json_value("flipped", data_cstr, 64);
+    char *flips = get_json_value("flip_count", data_cstr, 64);
+    char *id = get_json_value("id", data_cstr, 64);
+
+    if (username == NULL || message == NULL || flipped == NULL || id == NULL)
+    {
+        FURI_LOG_E(TAG, "Failed to parse item fields.");
+        free(username);
+        free(message);
+        free(flipped);
+        free(flips);
+        free(id);
+        free(data_cstr);
+        furi_string_free(feed_data);
+        return false;
+    }
+
+    // Safely copy strings with bounds checking
+    snprintf(flip_feed_item->username, MAX_USER_LENGTH, "%s", username);
+    snprintf(flip_feed_item->message, MAX_MESSAGE_LENGTH, "%s", message);
+
+    // Store boolean and integer values
+    flip_feed_item->is_flipped = strstr(flipped, "true") != NULL;
+    flip_feed_item->id = atoi(id);
+    flip_feed_item->flips = atoi(flips);
+
+    // Free allocated memory
+    free(username);
+    free(message);
+    free(flipped);
+    free(flips);
+    free(id);
+
+    furi_string_free(feed_data);
+    free(data_cstr);
+
+    return true;
+}

+ 4 - 5
feed/flip_social_feed.h

@@ -2,10 +2,9 @@
 #define FLIP_SOCIAL_FEED_H
 #define FLIP_SOCIAL_FEED_H
 #include "flip_social.h"
 #include "flip_social.h"
 #include <callback/flip_social_callback.h>
 #include <callback/flip_social_callback.h>
+#include <flip_storage/flip_social_storage.h>
 
 
-bool flip_social_temp_feed();
-FlipSocialFeed *flip_social_feed_alloc();
-void flip_social_free_feed();
 bool flip_social_get_feed();
 bool flip_social_get_feed();
-bool flip_social_parse_json_feed();
-#endif
+bool flip_social_load_feed_post(int post_id);
+FlipSocialFeedMini *flip_social_parse_json_feed();
+#endif

+ 28 - 4
flip_social.c

@@ -1,11 +1,11 @@
 #include "flip_social.h"
 #include "flip_social.h"
 
 
-FlipSocialFeed *flip_social_feed = NULL;            // Store the feed
 FlipSocialModel *flip_social_friends = NULL;        // Store the friends
 FlipSocialModel *flip_social_friends = NULL;        // Store the friends
 FlipSocialModel2 *flip_social_message_users = NULL; // Store the users that have sent messages to the logged in user
 FlipSocialModel2 *flip_social_message_users = NULL; // Store the users that have sent messages to the logged in user
 FlipSocialModel *flip_social_explore = NULL;        // Store the users to explore
 FlipSocialModel *flip_social_explore = NULL;        // Store the users to explore
 FlipSocialMessage *flip_social_messages = NULL;     // Store the messages between the logged in user and the selected user
 FlipSocialMessage *flip_social_messages = NULL;     // Store the messages between the logged in user and the selected user
-
+FlipSocialFeedMini *flip_feed_info = NULL;          // Store the feed info
+FlipSocialFeedItem *flip_feed_item = NULL;          // Store a feed item
 FlipSocialApp *app_instance = NULL;
 FlipSocialApp *app_instance = NULL;
 
 
 bool flip_social_sent_login_request = false;
 bool flip_social_sent_login_request = false;
@@ -306,14 +306,15 @@ void auth_headers_alloc(void)
 {
 {
     if (!app_instance)
     if (!app_instance)
     {
     {
+        snprintf(auth_headers, sizeof(auth_headers), "{\"Content-Type\":\"application/json\"}");
         return;
         return;
     }
     }
 
 
-    if (app_instance->login_username_logged_out && app_instance->login_password_logged_out)
+    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)
     {
     {
         snprintf(auth_headers, sizeof(auth_headers), "{\"Content-Type\":\"application/json\",\"username\":\"%s\",\"password\":\"%s\"}", app_instance->login_username_logged_out, app_instance->login_password_logged_out);
         snprintf(auth_headers, sizeof(auth_headers), "{\"Content-Type\":\"application/json\",\"username\":\"%s\",\"password\":\"%s\"}", app_instance->login_username_logged_out, app_instance->login_password_logged_out);
     }
     }
-    else if (app_instance->login_username_logged_in && app_instance->change_password_logged_in)
+    else if (app_instance->login_username_logged_in && app_instance->change_password_logged_in && strlen(app_instance->login_username_logged_in) > 0 && strlen(app_instance->change_password_logged_in) > 0)
     {
     {
         snprintf(auth_headers, sizeof(auth_headers), "{\"Content-Type\":\"application/json\",\"username\":\"%s\",\"password\":\"%s\"}", app_instance->login_username_logged_in, app_instance->change_password_logged_in);
         snprintf(auth_headers, sizeof(auth_headers), "{\"Content-Type\":\"application/json\",\"username\":\"%s\",\"password\":\"%s\"}", app_instance->login_username_logged_in, app_instance->change_password_logged_in);
     }
     }
@@ -321,4 +322,27 @@ void auth_headers_alloc(void)
     {
     {
         snprintf(auth_headers, sizeof(auth_headers), "{\"Content-Type\":\"application/json\"}");
         snprintf(auth_headers, sizeof(auth_headers), "{\"Content-Type\":\"application/json\"}");
     }
     }
+}
+
+FlipSocialFeedMini *flip_feed_info_alloc(void)
+{
+    FlipSocialFeedMini *feed_info = (FlipSocialFeedMini *)malloc(sizeof(FlipSocialFeedMini));
+    if (!feed_info)
+    {
+        FURI_LOG_E(TAG, "Failed to allocate memory for feed_info");
+        return NULL;
+    }
+    feed_info->count = 0;
+    feed_info->index = 0;
+    return feed_info;
+}
+
+void flip_feed_info_free(void)
+{
+    if (!flip_feed_info)
+    {
+        return;
+    }
+    free(flip_feed_info);
+    flip_feed_info = NULL;
 }
 }

+ 26 - 14
flip_social.h

@@ -11,11 +11,11 @@
 
 
 #define MAX_PRE_SAVED_MESSAGES 25 // Maximum number of pre-saved messages
 #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_MESSAGE_LENGTH 100    // Maximum length of a message in the feed
-#define MAX_EXPLORE_USERS 50      // Maximum number of users to explore
+#define MAX_EXPLORE_USERS 100     // Maximum number of users to explore
 #define MAX_USER_LENGTH 32        // Maximum length of a username
 #define MAX_USER_LENGTH 32        // Maximum length of a username
 #define MAX_FRIENDS 50            // Maximum number of friends
 #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_TOKENS 640            // Adjust based on expected JSON tokens
+#define MAX_FEED_ITEMS 50         // Maximum number of feed items
 #define MAX_LINE_LENGTH 30
 #define MAX_LINE_LENGTH 30
 #define MAX_MESSAGE_USERS 20 // Maximum number of users to display in the submenu
 #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 MAX_MESSAGES 20      // Maximum number of meesages between each user
@@ -44,13 +44,13 @@ typedef enum
     FlipSocialSubmenuComposeIndexAddPreSave,       // click to add a pre-saved message
     FlipSocialSubmenuComposeIndexAddPreSave,       // click to add a pre-saved message
     FlipSocialSubemnuComposeIndexStartIndex = 100, // starting index for the first pre saved message
     FlipSocialSubemnuComposeIndexStartIndex = 100, // starting index for the first pre saved message
     //
     //
-    FlipSocialSubmenuExploreIndexStartIndex = 150, // starting index for the users to explore
+    FlipSocialSubmenuExploreIndexStartIndex = 200, // starting index for the users to explore
     //
     //
-    FlipSocialSubmenuLoggedInIndexFriendsStart = 200, // starting index for the friends
+    FlipSocialSubmenuLoggedInIndexFriendsStart = 400, // starting index for the friends
     //
     //
-    FlipSocialSubmenuLoggedInIndexMessagesUsersStart = 250, // starting index for the messages
+    FlipSocialSubmenuLoggedInIndexMessagesUsersStart = 600, // starting index for the messages
     //
     //
-    FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart = 300, // click to select a user to message
+    FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart = 800, // click to select a user to message
 } FlipSocialSubmenuIndex;
 } FlipSocialSubmenuIndex;
 
 
 // Define the ScriptPlaylist structure
 // Define the ScriptPlaylist structure
@@ -61,16 +61,22 @@ typedef struct
     size_t index;
     size_t index;
 } PreSavedPlaylist;
 } PreSavedPlaylist;
 
 
+// Define a FlipSocialFeed individual item
+typedef struct
+{
+    char *username;
+    char *message;
+    bool is_flipped;
+    int id;
+    int flips;
+} FlipSocialFeedItem;
+
 typedef struct
 typedef struct
 {
 {
-    char *usernames[MAX_FEED_ITEMS];
-    char *messages[MAX_FEED_ITEMS];
-    bool is_flipped[MAX_FEED_ITEMS];
     int ids[MAX_FEED_ITEMS];
     int ids[MAX_FEED_ITEMS];
-    int flips[MAX_FEED_ITEMS];
     size_t count;
     size_t count;
     size_t index;
     size_t index;
-} FlipSocialFeed;
+} FlipSocialFeedMini;
 
 
 typedef struct
 typedef struct
 {
 {
@@ -140,6 +146,8 @@ typedef enum
     FlipSocialViewLoggedInFriendsProcess,  // The view after clicking on a friend in the friends 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
     FlipSocialViewLoggedInMessagesSubmenu, // The view after clicking the messages button on the profile screen
     FlipSocialViewLoggedInMessagesProcess, // The view after clicking on a user in the messages screen
     FlipSocialViewLoggedInMessagesProcess, // The view after clicking on a user in the messages screen
+    //
+    FlipSocialViewLoading, // The loading screen
 } FlipSocialView;
 } FlipSocialView;
 
 
 // Define the application structure
 // Define the application structure
@@ -272,16 +280,18 @@ typedef struct
     char *message_user_choice_logged_in;                     // Store the entered message to send to the selected user
     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
     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
     uint32_t message_user_choice_logged_in_temp_buffer_size; // Size of the message to send to the selected user temporary buffer
+
+    Loading *loading; // The loading screen
 } FlipSocialApp;
 } FlipSocialApp;
 
 
 void flip_social_app_free(FlipSocialApp *app);
 void flip_social_app_free(FlipSocialApp *app);
 
 
-extern FlipSocialFeed *flip_social_feed;            // Store the feed
 extern FlipSocialModel *flip_social_friends;        // Store the friends
 extern FlipSocialModel *flip_social_friends;        // Store the friends
 extern FlipSocialModel2 *flip_social_message_users; // Store the users that have sent messages to the logged in user
 extern FlipSocialModel2 *flip_social_message_users; // Store the users that have sent messages to the logged in user
 extern FlipSocialModel *flip_social_explore;        // Store the users to explore
 extern FlipSocialModel *flip_social_explore;        // Store the users to explore
 extern FlipSocialMessage *flip_social_messages;     // Store the messages between the logged in user and the selected user
 extern FlipSocialMessage *flip_social_messages;     // Store the messages between the logged in user and the selected user
-
+extern FlipSocialFeedMini *flip_feed_info;          // Store the feed info
+extern FlipSocialFeedItem *flip_feed_item;          // Store a feed item
 extern FlipSocialApp *app_instance;
 extern FlipSocialApp *app_instance;
 
 
 extern bool flip_social_sent_login_request;
 extern bool flip_social_sent_login_request;
@@ -296,4 +306,6 @@ extern char *selected_message;
 extern char auth_headers[256];
 extern char auth_headers[256];
 
 
 void auth_headers_alloc(void);
 void auth_headers_alloc(void);
+FlipSocialFeedMini *flip_feed_info_alloc(void);
+void flip_feed_info_free(void);
 #endif
 #endif

+ 31 - 0
flip_storage/flip_social_storage.c

@@ -369,3 +369,34 @@ bool load_settings(
 
 
     return true;
     return true;
 }
 }
+
+bool flip_social_save_post(char *post_id, char *json_feed_data)
+{
+    Storage *storage = furi_record_open(RECORD_STORAGE);
+    File *file = storage_file_alloc(storage);
+
+    char file_path[128];
+    snprintf(file_path, sizeof(file_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/feed_post_%s.json", post_id);
+
+    if (!storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS))
+    {
+        FURI_LOG_E(TAG, "Failed to open file for writing: %s", file_path);
+        storage_file_free(file);
+        furi_record_close(RECORD_STORAGE);
+        return false;
+    }
+
+    if (storage_file_write(file, json_feed_data, strlen(json_feed_data)) != strlen(json_feed_data))
+    {
+        FURI_LOG_E(TAG, "Failed to write feed post data");
+        storage_file_close(file);
+        storage_file_free(file);
+        furi_record_close(RECORD_STORAGE);
+        return false;
+    }
+
+    storage_file_close(file);
+    storage_file_free(file);
+    furi_record_close(RECORD_STORAGE);
+    return true;
+}

+ 1 - 0
flip_storage/flip_social_storage.h

@@ -34,4 +34,5 @@ bool load_settings(
     char *is_logged_in,
     char *is_logged_in,
     size_t is_logged_in_size);
     size_t is_logged_in_size);
 
 
+bool flip_social_save_post(char *post_id, char *json_feed_data);
 #endif
 #endif

+ 123 - 0
flipper_http/flipper_http.c

@@ -1466,4 +1466,127 @@ bool flipper_http_process_response_async(bool (*http_request)(void), bool (*pars
         return false;
         return false;
     }
     }
     return true;
     return true;
+}
+bool flipper_http_process_response_async_2(bool (*http_request)(void), int (*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() < 1) // parse the JSON before switching to the view (synchonous)
+    {
+        FURI_LOG_E(HTTP_TAG, "Failed to parse the JSON...");
+        return false;
+    }
+    return true;
+}
+
+/**
+ * @brief Perform a task while displaying a loading screen
+ * @param http_request The function to send the request
+ * @param parse_response The function to parse the response
+ * @param success_view_id The view ID to switch to on success
+ * @param failure_view_id The view ID to switch to on failure
+ * @param view_dispatcher The view dispatcher to use
+ * @return
+ */
+void flipper_http_loading_task(bool (*http_request)(void),
+                               bool (*parse_response)(void),
+                               uint32_t success_view_id,
+                               uint32_t failure_view_id,
+                               ViewDispatcher **view_dispatcher)
+{
+    Loading *loading;
+    int32_t loading_view_id = 987654321; // Random ID
+
+    loading = loading_alloc();
+    if (!loading)
+    {
+        FURI_LOG_E(HTTP_TAG, "Failed to allocate loading");
+        view_dispatcher_switch_to_view(*view_dispatcher, failure_view_id);
+
+        return;
+    }
+
+    view_dispatcher_add_view(*view_dispatcher, loading_view_id, loading_get_view(loading));
+
+    // Switch to the loading view
+    view_dispatcher_switch_to_view(*view_dispatcher, loading_view_id);
+
+    // Make the request
+    if (!flipper_http_process_response_async(http_request, parse_response))
+    {
+        FURI_LOG_E(HTTP_TAG, "Failed to make request");
+        view_dispatcher_switch_to_view(*view_dispatcher, failure_view_id);
+        view_dispatcher_remove_view(*view_dispatcher, loading_view_id);
+        loading_free(loading);
+
+        return;
+    }
+
+    // Switch to the success view
+    view_dispatcher_switch_to_view(*view_dispatcher, success_view_id);
+    view_dispatcher_remove_view(*view_dispatcher, loading_view_id);
+    loading_free(loading);
+}
+
+/**
+ * @brief Perform a task while displaying a loading screen
+ * @param http_request The function to send the request
+ * @param parse_response The function to parse the response
+ * @param success_view_id The view ID to switch to on success
+ * @param failure_view_id The view ID to switch to on failure
+ * @param view_dispatcher The view dispatcher to use
+ * @return
+ */
+void flipper_http_loading_task_2(bool (*http_request)(void),
+                                 int (*parse_response)(void),
+                                 uint32_t success_view_id,
+                                 uint32_t failure_view_id,
+                                 ViewDispatcher **view_dispatcher)
+{
+    Loading *loading;
+    int32_t loading_view_id = 987654321; // Random ID
+
+    loading = loading_alloc();
+    if (!loading)
+    {
+        FURI_LOG_E(HTTP_TAG, "Failed to allocate loading");
+        view_dispatcher_switch_to_view(*view_dispatcher, failure_view_id);
+
+        return;
+    }
+
+    view_dispatcher_add_view(*view_dispatcher, loading_view_id, loading_get_view(loading));
+
+    // Switch to the loading view
+    view_dispatcher_switch_to_view(*view_dispatcher, loading_view_id);
+
+    // Make the request
+    if (!flipper_http_process_response_async_2(http_request, parse_response))
+    {
+        FURI_LOG_E(HTTP_TAG, "Failed to make request");
+        view_dispatcher_switch_to_view(*view_dispatcher, failure_view_id);
+        view_dispatcher_remove_view(*view_dispatcher, loading_view_id);
+        loading_free(loading);
+
+        return;
+    }
+
+    // Switch to the success view
+    view_dispatcher_switch_to_view(*view_dispatcher, success_view_id);
+    view_dispatcher_remove_view(*view_dispatcher, loading_view_id);
+    loading_free(loading);
 }
 }

+ 39 - 4
flipper_http/flipper_http.h

@@ -2,6 +2,10 @@
 #ifndef FLIPPER_HTTP_H
 #ifndef FLIPPER_HTTP_H
 #define FLIPPER_HTTP_H
 #define FLIPPER_HTTP_H
 
 
+#include <gui/gui.h>
+#include <gui/view.h>
+#include <gui/view_dispatcher.h>
+#include <gui/modules/loading.h>
 #include <furi.h>
 #include <furi.h>
 #include <furi_hal.h>
 #include <furi_hal.h>
 #include <furi_hal_gpio.h>
 #include <furi_hal_gpio.h>
@@ -13,11 +17,11 @@
 #define HTTP_TAG "FlipSocial"             // change this to your app name
 #define HTTP_TAG "FlipSocial"             // change this to your app name
 #define http_tag "flip_social"            // change this to your app id
 #define http_tag "flip_social"            // change this to your app id
 #define UART_CH (FuriHalSerialIdUsart)    // UART channel
 #define UART_CH (FuriHalSerialIdUsart)    // UART channel
-#define TIMEOUT_DURATION_TICKS (5 * 1000) // 5 seconds
+#define TIMEOUT_DURATION_TICKS (8 * 1000) // 8 seconds (increased for Pico W)
 #define BAUDRATE (115200)                 // UART baudrate
 #define BAUDRATE (115200)                 // UART baudrate
-#define RX_BUF_SIZE 1024                  // UART RX buffer size
-#define RX_LINE_BUFFER_SIZE 8192          // UART RX line buffer size (increase for large responses)
-#define MAX_FILE_SHOW 8192                // Maximum data from file to show
+#define RX_BUF_SIZE 128                   // UART RX buffer size
+#define RX_LINE_BUFFER_SIZE 7000          // UART RX line buffer size (increase for large responses)
+#define MAX_FILE_SHOW 7000                // Maximum data from file to show
 #define FILE_BUFFER_SIZE 512              // File buffer size
 #define FILE_BUFFER_SIZE 512              // File buffer size
 
 
 // Forward declaration for callback
 // Forward declaration for callback
@@ -362,5 +366,36 @@ char *trim(const char *str);
  * @return true if successful, false otherwise
  * @return true if successful, false otherwise
  */
  */
 bool flipper_http_process_response_async(bool (*http_request)(void), bool (*parse_json)(void));
 bool flipper_http_process_response_async(bool (*http_request)(void), bool (*parse_json)(void));
+bool flipper_http_process_response_async_2(bool (*http_request)(void), int (*parse_json)(void));
+
+/**
+ * @brief Perform a task while displaying a loading screen
+ * @param http_request The function to send the request
+ * @param parse_response The function to parse the response
+ * @param success_view_id The view ID to switch to on success
+ * @param failure_view_id The view ID to switch to on failure
+ * @param view_dispatcher The view dispatcher to use
+ * @return
+ */
+void flipper_http_loading_task(bool (*http_request)(void),
+                               bool (*parse_response)(void),
+                               uint32_t success_view_id,
+                               uint32_t failure_view_id,
+                               ViewDispatcher **view_dispatcher);
+
+/**
+ * @brief Perform a task while displaying a loading screen
+ * @param http_request The function to send the request
+ * @param parse_response The function to parse the response
+ * @param success_view_id The view ID to switch to on success
+ * @param failure_view_id The view ID to switch to on failure
+ * @param view_dispatcher The view dispatcher to use
+ * @return
+ */
+void flipper_http_loading_task_2(bool (*http_request)(void),
+                                 int (*parse_response)(void),
+                                 uint32_t success_view_id,
+                                 uint32_t failure_view_id,
+                                 ViewDispatcher **view_dispatcher);
 
 
 #endif // FLIPPER_HTTP_H
 #endif // FLIPPER_HTTP_H

+ 15 - 6
friends/flip_social_friends.c

@@ -23,7 +23,6 @@ void flip_social_free_friends()
 {
 {
     if (!flip_social_friends)
     if (!flip_social_friends)
     {
     {
-        FURI_LOG_E(TAG, "Friends model is NULL");
         return;
         return;
     }
     }
     for (int i = 0; i < flip_social_friends->count; i++)
     for (int i = 0; i < flip_social_friends->count; i++)
@@ -33,22 +32,29 @@ void flip_social_free_friends()
             free(flip_social_friends->usernames[i]);
             free(flip_social_friends->usernames[i]);
         }
         }
     }
     }
+    free(flip_social_friends);
+    flip_social_friends = NULL;
 }
 }
 
 
 // for now we're just listing the current users
 // for now we're just listing the current users
 // as the feed is upgraded, then we can port more to the friends view
 // as the feed is upgraded, then we can port more to the friends view
 bool flip_social_get_friends()
 bool flip_social_get_friends()
 {
 {
+    if (!app_instance)
+    {
+        FURI_LOG_E(TAG, "App instance is NULL");
+        return false;
+    }
     // will return true unless the devboard is not connected
     // will return true unless the devboard is not connected
     char url[100];
     char url[100];
     snprintf(
     snprintf(
         fhttp.file_path,
         fhttp.file_path,
         sizeof(fhttp.file_path),
         sizeof(fhttp.file_path),
-        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/friends.txt");
+        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/friends.json");
 
 
     fhttp.save_received_data = true;
     fhttp.save_received_data = true;
     auth_headers_alloc();
     auth_headers_alloc();
-    snprintf(url, 100, "https://www.flipsocial.net/api/user/friends/%s/", app_instance->login_username_logged_in);
+    snprintf(url, sizeof(url), "https://www.flipsocial.net/api/user/friends/%s/", app_instance->login_username_logged_in);
     if (!flipper_http_get_request_with_headers(url, auth_headers))
     if (!flipper_http_get_request_with_headers(url, auth_headers))
     {
     {
         FURI_LOG_E(TAG, "Failed to send HTTP request for friends");
         FURI_LOG_E(TAG, "Failed to send HTTP request for friends");
@@ -125,6 +131,7 @@ bool flip_social_parse_json_friends()
         FURI_LOG_E(TAG, "Failed to parse friends array.");
         FURI_LOG_E(TAG, "Failed to parse friends array.");
         furi_string_free(friend_data);
         furi_string_free(friend_data);
         free(data_cstr);
         free(data_cstr);
+        flip_social_free_friends();
         return false;
         return false;
     }
     }
 
 
@@ -167,14 +174,16 @@ bool flip_social_parse_json_friends()
         FURI_LOG_E(TAG, "Failed to update friends submenu");
         FURI_LOG_E(TAG, "Failed to update friends submenu");
         furi_string_free(friend_data);
         furi_string_free(friend_data);
         free(data_cstr);
         free(data_cstr);
+        free(json_users);
+        free(start);
+        free(end);
         return false;
         return false;
     }
     }
 
 
-    // Free the json_users
+    furi_string_free(friend_data);
+    free(data_cstr);
     free(json_users);
     free(json_users);
     free(start);
     free(start);
     free(end);
     free(end);
-    furi_string_free(friend_data);
-    free(data_cstr);
     return true;
     return true;
 }
 }

+ 9 - 6
messages/flip_social_messages.c

@@ -61,7 +61,6 @@ void flip_social_free_message_users()
 {
 {
     if (flip_social_message_users == NULL)
     if (flip_social_message_users == NULL)
     {
     {
-        FURI_LOG_E(TAG, "Message users model is NULL");
         return;
         return;
     }
     }
     for (int i = 0; i < flip_social_message_users->count; i++)
     for (int i = 0; i < flip_social_message_users->count; i++)
@@ -71,13 +70,14 @@ void flip_social_free_message_users()
             free(flip_social_message_users->usernames[i]);
             free(flip_social_message_users->usernames[i]);
         }
         }
     }
     }
+    free(flip_social_message_users);
+    flip_social_message_users = NULL;
 }
 }
 
 
 void flip_social_free_messages()
 void flip_social_free_messages()
 {
 {
     if (flip_social_messages == NULL)
     if (flip_social_messages == NULL)
     {
     {
-        FURI_LOG_E(TAG, "Messages model is NULL");
         return;
         return;
     }
     }
     for (int i = 0; i < flip_social_messages->count; i++)
     for (int i = 0; i < flip_social_messages->count; i++)
@@ -91,6 +91,8 @@ void flip_social_free_messages()
             free(flip_social_messages->messages[i]);
             free(flip_social_messages->messages[i]);
         }
         }
     }
     }
+    free(flip_social_messages);
+    flip_social_messages = NULL;
 }
 }
 
 
 bool flip_social_update_messages_submenu()
 bool flip_social_update_messages_submenu()
@@ -148,7 +150,7 @@ bool flip_social_get_message_users()
     snprintf(
     snprintf(
         fhttp.file_path,
         fhttp.file_path,
         sizeof(fhttp.file_path),
         sizeof(fhttp.file_path),
-        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/message_users.txt");
+        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/message_users.json");
 
 
     fhttp.save_received_data = true;
     fhttp.save_received_data = true;
     auth_headers_alloc();
     auth_headers_alloc();
@@ -180,7 +182,8 @@ bool flip_social_get_messages_with_user()
     snprintf(
     snprintf(
         fhttp.file_path,
         fhttp.file_path,
         sizeof(fhttp.file_path),
         sizeof(fhttp.file_path),
-        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/messages.txt");
+        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/%s_messages.json",
+        flip_social_message_users->usernames[flip_social_message_users->index]);
 
 
     fhttp.save_received_data = true;
     fhttp.save_received_data = true;
     auth_headers_alloc();
     auth_headers_alloc();
@@ -430,8 +433,8 @@ bool flip_social_parse_json_messages()
         }
         }
 
 
         // Extract individual fields from the JSON object
         // 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);
+        char *sender = get_json_value("sender", item, 64);
+        char *content = get_json_value("content", item, 64);
 
 
         if (sender == NULL || content == NULL)
         if (sender == NULL || content == NULL)
         {
         {