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

FlipSocial - v0.5

- Improved memory allocation
- Improved Feed Page
- Raspberry Pi Pico W Support
jblanked 1 год назад
Родитель
Сommit
36b04d3e09
16 измененных файлов с 427 добавлено и 284 удалено
  1. BIN
      .DS_Store
  2. 2 1
      README.md
  3. 4 4
      app.c
  4. 1 1
      application.fam
  5. 5 0
      assets/CHANGELOG.md
  6. 2 1
      assets/README.md
  7. 25 12
      flip_social_callback.h
  8. 129 60
      flip_social_draw.h
  9. 10 11
      flip_social_e.h
  10. 31 22
      flip_social_explore.h
  11. 82 47
      flip_social_feed.h
  12. 0 8
      flip_social_free.h
  13. 31 22
      flip_social_friends.h
  14. 4 34
      flip_social_i.h
  15. 98 58
      flip_social_messages.h
  16. 3 3
      flipper_http.h

+ 2 - 1
README.md

@@ -46,7 +46,8 @@ FlipSocial uses the FlipperHTTP flash for the WiFi Devboard, first introduced in
 
 **v0.5**
 - Improved memory allocation
-- Improved Feed Page (Flip count, report, block)
+- Improved Feed Page
+- Raspberry Pi Pico W Support
 
 **v0.6**
 - Improved User Profile (Bio, friend count, block)

+ 4 - 4
app.c

@@ -23,8 +23,8 @@ int32_t main_flip_social(void *p)
     UNUSED(p);
 
     // Initialize the Hello World application
-    FlipSocialApp *app = flip_social_app_alloc();
-    if (!app)
+    app_instance = flip_social_app_alloc();
+    if (!app_instance)
     {
         // Allocation failed
         return -1; // Indicate failure
@@ -44,10 +44,10 @@ int32_t main_flip_social(void *p)
     }
 
     // Run the view dispatcher
-    view_dispatcher_run(app->view_dispatcher);
+    view_dispatcher_run(app_instance->view_dispatcher);
 
     // Free the resources used by the Hello World application
-    flip_social_app_free(app);
+    flip_social_app_free(app_instance);
 
     // Return 0 to indicate success
     return 0;

+ 1 - 1
application.fam

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

+ 5 - 0
assets/CHANGELOG.md

@@ -1,3 +1,8 @@
+## 0.5
+- Improved memory allocation
+- Improved Feed Page
+- Raspberry Pi Pico W Support
+
 ## 0.4
 - Added direct messaging.
 - Updated app flow for a smoother user experience.

+ 2 - 1
assets/README.md

@@ -46,7 +46,8 @@ FlipSocial uses the FlipperHTTP flash for the WiFi Devboard, first introduced in
 
 **v0.5**
 - Improved memory allocation
-- Improved Feed Page (Flip count, report, block)
+- Improved Feed Page
+- Raspberry Pi Pico W Support
 
 **v0.6**
 - Improved User Profile (Bio, friend count, block)

+ 25 - 12
flip_social_callback.h

@@ -21,7 +21,11 @@ static uint32_t flip_social_callback_to_submenu_logged_out(void *context)
 static uint32_t flip_social_callback_to_submenu_logged_in(void *context)
 {
     UNUSED(context);
-    // flip_social_get_feed(); // start the feed request
+    flip_social_free_explore();
+    flip_social_free_feed();
+    flip_social_free_friends();
+    flip_social_free_message_users();
+    flip_social_free_messages();
     return FlipSocialViewLoggedInSubmenu;
 }
 
@@ -117,7 +121,7 @@ static uint32_t flip_social_callback_to_explore_logged_in(void *context)
     flip_social_dialog_stop = true;
     last_explore_response = "";
     flip_social_dialog_shown = false;
-    app_instance->flip_social_explore.index = 0;
+    flip_social_explore->index = 0;
     action = ActionNone;
     return FlipSocialViewLoggedInExploreSubmenu;
 }
@@ -133,7 +137,7 @@ static uint32_t flip_social_callback_to_friends_logged_in(void *context)
     flip_social_dialog_stop = true;
     last_explore_response = "";
     flip_social_dialog_shown = false;
-    app_instance->flip_social_friends.index = 0;
+    flip_social_friends->index = 0;
     action = ActionNone;
     return FlipSocialViewLoggedInFriendsSubmenu;
 }
@@ -229,6 +233,15 @@ static void flip_social_callback_submenu_choices(void *context, uint32_t index)
         {
             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))
@@ -256,28 +269,28 @@ static void flip_social_callback_submenu_choices(void *context, uint32_t index)
         // Handle the pre-saved message selection (has a max of 25 items)
         if (index >= FlipSocialSubemnuComposeIndexStartIndex && index < FlipSocialSubemnuComposeIndexStartIndex + MAX_PRE_SAVED_MESSAGES)
         {
-            app->flip_social_feed.index = index - FlipSocialSubemnuComposeIndexStartIndex;
+            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)
         {
-            app->flip_social_explore.index = index - FlipSocialSubmenuExploreIndexStartIndex;
+            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)
         {
-            app->flip_social_friends.index = index - FlipSocialSubmenuLoggedInIndexFriendsStart;
+            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)
         {
-            app->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);
@@ -287,7 +300,7 @@ static void flip_social_callback_submenu_choices(void *context, uint32_t index)
         // handle the messages user choices selection
         else if (index >= FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart && index < FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart + MAX_EXPLORE_USERS)
         {
-            app->flip_social_explore.index = index - FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart;
+            flip_social_explore->index = index - FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart;
             view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesNewMessageUserChoicesInput);
         }
         else
@@ -957,7 +970,7 @@ static void flip_social_logged_in_messages_user_choice_message_updated(void *con
     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\"}", app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index], app->message_user_choice_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
@@ -981,8 +994,8 @@ static void flip_social_logged_in_messages_user_choice_message_updated(void *con
     furi_timer_stop(fhttp.get_timeout_timer);
 
     // add user to the message list
-    strncpy(app_instance->flip_social_message_users.usernames[app_instance->flip_social_message_users.count], app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index], strlen(app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index]));
-    app_instance->flip_social_message_users.count++;
+    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();
@@ -1021,7 +1034,7 @@ static void flip_social_logged_in_messages_new_message_updated(void *context)
     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\"}", app_instance->flip_social_message_users.usernames[app_instance->flip_social_message_users.index], app->messages_new_message_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

+ 129 - 60
flip_social_draw.h

@@ -97,7 +97,7 @@ static void on_input(const void *event, void *ctx)
 }
 
 // Function to draw the message on the canvas with word wrapping
-void draw_user_message(Canvas *canvas, const char *user_message, int x)
+void draw_user_message(Canvas *canvas, const char *user_message, int x, int y)
 {
     if (user_message == NULL)
     {
@@ -136,7 +136,7 @@ void draw_user_message(Canvas *canvas, const char *user_message, int x)
 
         // Draw the string on the canvas
         // Adjust the y-coordinate based on the line number
-        canvas_draw_str_aligned(canvas, 0, x + line_num * 10, AlignLeft, AlignTop, line);
+        canvas_draw_str_aligned(canvas, x, y + line_num * 10, AlignLeft, AlignTop, line);
 
         // Update the start position for the next line
         start += len;
@@ -166,7 +166,7 @@ static void flip_social_callback_draw_compose(Canvas *canvas, void *model)
         return;
     }
 
-    char *message = app_instance->pre_saved_messages.messages[app_instance->flip_social_feed.index];
+    char *message = app_instance->pre_saved_messages.messages[flip_social_feed->index];
 
     if (!flip_social_dialog_shown)
     {
@@ -175,7 +175,7 @@ static void flip_social_callback_draw_compose(Canvas *canvas, void *model)
         app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
     }
 
-    draw_user_message(canvas, message, 2);
+    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");
@@ -246,10 +246,9 @@ static void flip_social_callback_draw_compose(Canvas *canvas, void *model)
         break;
     case ActionPrev:
         // delete message
-        // remove the message from app_instance->pre_saved_messages
-        app_instance->pre_saved_messages.messages[app_instance->flip_social_feed.index] = NULL;
+        app_instance->pre_saved_messages.messages[flip_social_feed->index] = NULL;
 
-        for (uint32_t i = app_instance->flip_social_feed.index; i < app_instance->pre_saved_messages.count - 1; i++)
+        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];
         }
@@ -298,35 +297,95 @@ static void flip_social_callback_draw_compose(Canvas *canvas, void *model)
     }
 }
 // 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)
+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);
 
-    draw_user_message(canvas, user_message, 12);
+    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);
 
-    canvas_set_font(canvas, FontSecondary);
-    if (show_prev)
+        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, 53, &I_ButtonLeft_4x7);
-        canvas_draw_str_aligned(canvas, 9, 54, AlignLeft, AlignTop, "Prev");
+        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");
     }
-    if (!is_flipped)
+    else if (show_prev && !show_next && !is_flipped)
     {
-        canvas_draw_icon(canvas, 52, 53, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 61, 54, AlignLeft, AlignTop, "Flip");
+        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
+    else if (!show_prev && show_next && !is_flipped)
     {
-        canvas_draw_icon(canvas, 47, 53, &I_ButtonOK_7x7);
-        canvas_draw_str_aligned(canvas, 56, 54, AlignLeft, AlignTop, "UnFlip");
+        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");
     }
-    if (show_next)
+    else if (show_prev && show_next && is_flipped)
     {
-        canvas_draw_icon(canvas, 98, 53, &I_ButtonRight_4x7);
-        canvas_draw_str_aligned(canvas, 107, 54, AlignLeft, AlignTop, "Next");
+        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
@@ -355,31 +414,29 @@ static void flip_social_callback_draw_feed(Canvas *canvas, void *model)
     switch (action)
     {
     case ActionNone:
-        flip_social_canvas_draw_message(canvas, app_instance->flip_social_feed.usernames[app_instance->flip_social_feed.index], app_instance->flip_social_feed.messages[app_instance->flip_social_feed.index], app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index], app_instance->flip_social_feed.index > 0, app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1);
+        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 (app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1)
+        if (flip_social_feed->index < flip_social_feed->count - 1)
         {
-            app_instance->flip_social_feed.index++;
+            flip_social_feed->index++;
         }
-        flip_social_canvas_draw_message(canvas, app_instance->flip_social_feed.usernames[app_instance->flip_social_feed.index], app_instance->flip_social_feed.messages[app_instance->flip_social_feed.index], app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index], app_instance->flip_social_feed.index > 0, app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1);
+        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 (app_instance->flip_social_feed.index > 0)
+        if (flip_social_feed->index > 0)
         {
-            app_instance->flip_social_feed.index--;
+            flip_social_feed->index--;
         }
-        flip_social_canvas_draw_message(canvas, app_instance->flip_social_feed.usernames[app_instance->flip_social_feed.index], app_instance->flip_social_feed.messages[app_instance->flip_social_feed.index], app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index], app_instance->flip_social_feed.index > 0, app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1);
+        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);
-        app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index] = !app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index];
-        flip_social_canvas_draw_message(canvas, app_instance->flip_social_feed.usernames[app_instance->flip_social_feed.index], app_instance->flip_social_feed.messages[app_instance->flip_social_feed.index], app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index], app_instance->flip_social_feed.index > 0, app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1);
-        action = ActionNone;
+        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)
         {
@@ -387,13 +444,25 @@ static void flip_social_callback_draw_feed(Canvas *canvas, void *model)
             return;
         }
         char payload[256];
-        snprintf(payload, sizeof(payload), "{\"username\":\"%s\",\"post_id\":\"%lu\"}", app_instance->login_username_logged_in, app_instance->flip_social_feed.ids[app_instance->flip_social_feed.index]);
+        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);
+        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]--;
+        }
+        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;
-        app_instance->flip_social_feed.index = 0;
+        flip_social_feed->index = 0;
         action = ActionNone;
         break;
     default:
@@ -660,7 +729,7 @@ static void flip_social_canvas_draw_explore(Canvas *canvas, char *user_username,
     canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, user_username);
     canvas_set_font(canvas, FontSecondary);
 
-    draw_user_message(canvas, content, 12);
+    draw_user_message(canvas, content, 0, 12);
 
     canvas_set_font(canvas, FontSecondary);
     canvas_draw_icon(canvas, 0, 53, &I_ButtonLeft_4x7);
@@ -695,7 +764,7 @@ static void flip_social_callback_draw_explore(Canvas *canvas, void *model)
         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, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index], last_explore_response);
+    flip_social_canvas_draw_explore(canvas, flip_social_explore->usernames[flip_social_explore->index], last_explore_response);
 
     // handle action
     switch (action)
@@ -703,19 +772,19 @@ static void flip_social_callback_draw_explore(Canvas *canvas, void *model)
     case ActionNext:
         // add friend
         char add_payload[128];
-        snprintf(add_payload, sizeof(add_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index]);
+        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, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index], "Added!");
+        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, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index]);
+        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, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index], "Removed!");
+        flip_social_canvas_draw_explore(canvas, flip_social_explore->usernames[flip_social_explore->index], "Removed!");
         action = ActionNone;
         break;
     case ActionBack:
@@ -723,7 +792,7 @@ static void flip_social_callback_draw_explore(Canvas *canvas, void *model)
         flip_social_dialog_stop = true;
         last_explore_response = "";
         flip_social_dialog_shown = false;
-        app_instance->flip_social_explore.index = 0;
+        flip_social_explore->index = 0;
         action = ActionNone;
         break;
     default:
@@ -760,7 +829,7 @@ static void flip_social_callback_draw_friends(Canvas *canvas, void *model)
         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, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index], last_explore_response);
+    flip_social_canvas_draw_explore(canvas, flip_social_friends->usernames[flip_social_friends->index], last_explore_response);
 
     // handle action
     switch (action)
@@ -768,15 +837,15 @@ static void flip_social_callback_draw_friends(Canvas *canvas, void *model)
     case ActionNext:
         // add friend
         char add_payload[128];
-        snprintf(add_payload, sizeof(add_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index]);
+        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, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index], "Added!");
+            flip_social_canvas_draw_explore(canvas, flip_social_friends->usernames[flip_social_friends->index], "Added!");
 
             // add the friend to the friends list
-            app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.count] = app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index];
-            app_instance->flip_social_friends.count++;
+            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");
@@ -787,18 +856,18 @@ static void flip_social_callback_draw_friends(Canvas *canvas, void *model)
     case ActionPrev:
         // remove friend
         char remove_payload[128];
-        snprintf(remove_payload, sizeof(remove_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index]);
+        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, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index], "Removed!");
+            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 = app_instance->flip_social_friends.index; i < app_instance->flip_social_friends.count - 1; i++)
+            for (int i = flip_social_friends->index; i < flip_social_friends->count - 1; i++)
             {
-                app_instance->flip_social_friends.usernames[i] = app_instance->flip_social_friends.usernames[i + 1];
+                flip_social_friends->usernames[i] = flip_social_friends->usernames[i + 1];
             }
-            app_instance->flip_social_friends.count--;
+            flip_social_friends->count--;
             if (!flip_social_update_friends())
             {
                 FURI_LOG_E(TAG, "Failed to update friends");
@@ -811,7 +880,7 @@ static void flip_social_callback_draw_friends(Canvas *canvas, void *model)
         flip_social_dialog_stop = true;
         last_explore_response = "";
         flip_social_dialog_shown = false;
-        app_instance->flip_social_friends.index = 0;
+        flip_social_friends->index = 0;
         action = ActionNone;
         break;
     default:
@@ -834,7 +903,7 @@ static void flip_social_canvas_draw_user_message(Canvas *canvas, char *user_user
     canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, user_username);
     canvas_set_font(canvas, FontSecondary);
 
-    draw_user_message(canvas, user_message, 12);
+    draw_user_message(canvas, user_message, 0, 12);
 
     canvas_set_font(canvas, FontSecondary);
     if (show_prev)
@@ -879,27 +948,27 @@ static void flip_social_callback_draw_messages(Canvas *canvas, void *model)
     switch (action)
     {
     case ActionNone:
-        flip_social_canvas_draw_user_message(canvas, app_instance->flip_social_messages.usernames[app_instance->flip_social_messages.index], app_instance->flip_social_messages.messages[app_instance->flip_social_messages.index], app_instance->flip_social_messages.index > 0, app_instance->flip_social_messages.index < app_instance->flip_social_messages.count - 1);
+        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 (app_instance->flip_social_messages.index < app_instance->flip_social_messages.count - 1)
+        if (flip_social_messages->index < flip_social_messages->count - 1)
         {
-            app_instance->flip_social_messages.index++;
+            flip_social_messages->index++;
         }
-        flip_social_canvas_draw_user_message(canvas, app_instance->flip_social_messages.usernames[app_instance->flip_social_messages.index], app_instance->flip_social_messages.messages[app_instance->flip_social_messages.index], app_instance->flip_social_messages.index > 0, app_instance->flip_social_messages.index < app_instance->flip_social_messages.count - 1);
+        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 (app_instance->flip_social_messages.index > 0)
+        if (flip_social_messages->index > 0)
         {
-            app_instance->flip_social_messages.index--;
+            flip_social_messages->index--;
         }
-        flip_social_canvas_draw_user_message(canvas, app_instance->flip_social_messages.usernames[app_instance->flip_social_messages.index], app_instance->flip_social_messages.messages[app_instance->flip_social_messages.index], app_instance->flip_social_messages.index > 0, app_instance->flip_social_messages.index < app_instance->flip_social_messages.count - 1);
+        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:

+ 10 - 11
flip_social_e.h

@@ -14,8 +14,8 @@
 #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 500            // Adjust based on expected JSON tokens
-#define MAX_FEED_ITEMS 50         // Maximum number of feed items
+#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
@@ -73,7 +73,8 @@ typedef struct
     char *usernames[MAX_FEED_ITEMS];
     char *messages[MAX_FEED_ITEMS];
     bool is_flipped[MAX_FEED_ITEMS];
-    uint32_t ids[MAX_FEED_ITEMS];
+    int ids[MAX_FEED_ITEMS];
+    int flips[MAX_FEED_ITEMS];
     size_t count;
     size_t index;
 } FlipSocialFeed;
@@ -278,16 +279,14 @@ typedef struct
     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
-
-    //
-    FlipSocialFeed flip_social_feed;            // Store the feed
-    FlipSocialModel flip_social_friends;        // Store the friends
-    FlipSocialModel2 flip_social_message_users; // Store the users that have sent messages to the logged in user
-    FlipSocialModel flip_social_explore;        // Store the users to explore
-    FlipSocialMessage flip_social_messages;     // Store the messages between the logged in user and the selected user
-
 } 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)
 {

+ 31 - 22
flip_social_explore.h

@@ -1,34 +1,40 @@
 #ifndef FLIP_SOCIAL_EXPLORE_H
 #define FLIP_SOCIAL_EXPLORE_H
 
-static bool flip_social_explore_alloc()
+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 (app_instance->flip_social_explore.usernames[i] == NULL)
+        if (explore->usernames[i] == NULL)
         {
-            app_instance->flip_social_explore.usernames[i] = malloc(MAX_USER_LENGTH);
-            if (app_instance->flip_social_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 false; // Return false on memory allocation failure
+                return NULL; // Return false on memory allocation failure
             }
         }
     }
-    return true;
+    return explore;
 }
 
 static void flip_social_free_explore()
 {
-    if (!app_instance)
+    if (!flip_social_explore)
     {
-        FURI_LOG_E(TAG, "App instance is NULL");
+        FURI_LOG_E(TAG, "Explore model is NULL");
         return;
     }
-    for (int i = 0; i < app_instance->flip_social_explore.count; i++)
+    for (int i = 0; i < flip_social_explore->count; i++)
     {
-        free(app_instance->flip_social_explore.usernames[i]);
+        free(flip_social_explore->usernames[i]);
     }
 }
 
@@ -56,7 +62,8 @@ static bool flip_social_parse_json_explore()
     }
 
     // Allocate memory for each username only if not already allocated
-    if (!flip_social_explore_alloc())
+    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;
@@ -70,7 +77,7 @@ static bool flip_social_parse_json_explore()
     }
 
     // Initialize explore count
-    app_instance->flip_social_explore.count = 0;
+    flip_social_explore->count = 0;
 
     // Extract the users array from the JSON
     char *json_users = get_json_value("users", fhttp.received_data, MAX_TOKENS);
@@ -83,7 +90,7 @@ static bool flip_social_parse_json_explore()
     // Manual tokenization for comma-separated values
     char *start = json_users + 1; // Skip the opening bracket
     char *end;
-    while ((end = strchr(start, ',')) != NULL && app_instance->flip_social_explore.count < MAX_EXPLORE_USERS)
+    while ((end = strchr(start, ',')) != NULL && flip_social_explore->count < MAX_EXPLORE_USERS)
     {
         *end = '\0'; // Null-terminate the current token
 
@@ -94,14 +101,14 @@ static bool flip_social_parse_json_explore()
             *(end - 1) = '\0';
 
         // Copy username to pre-allocated memory
-        strncpy(app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count], start, MAX_USER_LENGTH - 1);
-        app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        app_instance->flip_social_explore.count++;
+        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' && app_instance->flip_social_explore.count < MAX_EXPLORE_USERS)
+    if (*start != '\0' && flip_social_explore->count < MAX_EXPLORE_USERS)
     {
         if (*start == '"')
             start++;
@@ -110,21 +117,23 @@ static bool flip_social_parse_json_explore()
         if (*(start + strlen(start) - 1) == '"')
             *(start + strlen(start) - 1) = '\0';
 
-        strncpy(app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count], start, MAX_USER_LENGTH - 1);
-        app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        app_instance->flip_social_explore.count++;
+        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 < app_instance->flip_social_explore.count; i++)
+    for (int i = 0; i < flip_social_explore->count; i++)
     {
-        submenu_add_item(app_instance->submenu_explore, app_instance->flip_social_explore.usernames[i], FlipSocialSubmenuExploreIndexStartIndex + i, flip_social_callback_submenu_choices, app_instance);
+        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;
 }

+ 82 - 47
flip_social_feed.h

@@ -4,86 +4,106 @@
 // Set failure FlipSocialFeed object
 static bool flip_social_temp_feed()
 {
-    if (!app_instance)
+    if (flip_social_feed == NULL)
     {
-        FURI_LOG_E(TAG, "App instance is NULL");
-        return false;
+        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 (app_instance->flip_social_feed.usernames[i] == NULL)
+        if (flip_social_feed->usernames[i] == NULL)
         {
-            app_instance->flip_social_feed.usernames[i] = malloc(MAX_USER_LENGTH);
-            if (app_instance->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 (app_instance->flip_social_feed.messages[i] == NULL)
+        if (flip_social_feed->messages[i] == NULL)
         {
-            app_instance->flip_social_feed.messages[i] = malloc(MAX_MESSAGE_LENGTH);
-            if (app_instance->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;
             }
         }
     }
-    app_instance->flip_social_feed.usernames[0] = "JBlanked";
-    app_instance->flip_social_feed.usernames[1] = "FlipperKing";
-    app_instance->flip_social_feed.usernames[2] = "FlipperQueen";
+    flip_social_feed->usernames[0] = "JBlanked";
+    flip_social_feed->usernames[1] = "FlipperKing";
+    flip_social_feed->usernames[2] = "FlipperQueen";
     //
-    app_instance->flip_social_feed.messages[0] = "Welcome. This is a temp message. Either the feed didn't load or there was a server error.";
-    app_instance->flip_social_feed.messages[1] = "I am the Chosen Flipper.";
-    app_instance->flip_social_feed.messages[2] = "No one can flip like me.";
+    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.";
     //
-    app_instance->flip_social_feed.is_flipped[0] = false;
-    app_instance->flip_social_feed.is_flipped[1] = false;
-    app_instance->flip_social_feed.is_flipped[2] = true;
+    flip_social_feed->is_flipped[0] = true;
+    flip_social_feed->is_flipped[1] = false;
+    flip_social_feed->is_flipped[2] = true;
     //
-    app_instance->flip_social_feed.ids[0] = 0;
-    app_instance->flip_social_feed.ids[1] = 1;
-    app_instance->flip_social_feed.ids[2] = 2;
+    flip_social_feed->ids[0] = 0;
+    flip_social_feed->ids[1] = 1;
+    flip_social_feed->ids[2] = 2;
     //
-    app_instance->flip_social_feed.count = 3;
-    app_instance->flip_social_feed.index = 0;
+    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 bool flip_social_feed_alloc()
+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 (app_instance->flip_social_feed.usernames[i] == NULL)
+        if (feed->usernames[i] == NULL)
         {
-            app_instance->flip_social_feed.usernames[i] = malloc(MAX_USER_LENGTH);
-            if (app_instance->flip_social_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 false;
+                return NULL;
             }
         }
-        if (app_instance->flip_social_feed.messages[i] == NULL)
+        if (feed->messages[i] == NULL)
         {
-            app_instance->flip_social_feed.messages[i] = malloc(MAX_MESSAGE_LENGTH);
-            if (app_instance->flip_social_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 false;
+                return NULL;
             }
         }
     }
-    return true;
+    return feed;
 }
 
 static void flip_social_free_feed()
 {
-    for (uint32_t i = 0; i < app_instance->flip_social_feed.count; i++)
+    if (!flip_social_feed)
     {
-        free(app_instance->flip_social_feed.usernames[i]);
+        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]);
     }
 }
 
@@ -96,7 +116,7 @@ static bool flip_social_get_feed()
         return false;
     }
     char command[128];
-    snprintf(command, 128, "https://www.flipsocial.net/api/feed/50/%s/", app_instance->login_username_logged_out);
+    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)
     {
@@ -106,6 +126,7 @@ static bool flip_social_get_feed()
     fhttp.state = RECEIVING;
     return true;
 }
+
 static bool flip_social_parse_json_feed()
 {
     if (fhttp.received_data == NULL)
@@ -115,11 +136,11 @@ static bool flip_social_parse_json_feed()
     }
 
     // Allocate memory for each feed item if not already allocated
-    if (!flip_social_feed_alloc())
+    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)
@@ -128,7 +149,7 @@ static bool flip_social_parse_json_feed()
     }
 
     // Initialize feed count
-    app_instance->flip_social_feed.count = 0;
+    flip_social_feed->count = 0;
 
     // Iterate through the feed array
     for (int i = 0; i < MAX_FEED_ITEMS; i++)
@@ -144,6 +165,7 @@ static bool flip_social_parse_json_feed()
         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)
@@ -153,22 +175,35 @@ static bool flip_social_parse_json_feed()
             free(username);
             free(message);
             free(flipped);
+            free(flips);
             free(id);
             continue;
         }
 
-        // Copy parsed values into allocated memory
-        app_instance->flip_social_feed.usernames[i] = username;
-        app_instance->flip_social_feed.messages[i] = message;
-        app_instance->flip_social_feed.is_flipped[i] = strstr(flipped, "true") != NULL;
-        app_instance->flip_social_feed.ids[i] = atoi(id);
-        app_instance->flip_social_feed.count++;
+        // 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';
 
-        // Free temporary JSON value
+        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 true;
+    return flip_social_feed->count > 0;
 }
 
 #endif // FLIP_SOCIAL_FEED_H

+ 0 - 8
flip_social_free.h

@@ -21,12 +21,6 @@ static void flip_social_app_free(FlipSocialApp *app)
         return;
     }
 
-    // Disconnect from WiFi
-    if (!flipper_http_disconnect_wifi())
-    {
-        FURI_LOG_E(TAG, "Failed to disconnect from WiFi");
-    }
-
     // Free Submenu(s)
     if (app->submenu_logged_out)
     {
@@ -295,8 +289,6 @@ static void flip_social_app_free(FlipSocialApp *app)
     // Free the app structure
     if (app_instance)
         free(app_instance);
-    if (app)
-        free(app);
 }
 
 #endif // FLIP_SOCIAL_FREE_H

+ 31 - 22
flip_social_friends.h

@@ -1,34 +1,35 @@
 #ifndef FLIP_SOCIAL_FRIENDS
 #define FLIP_SOCIAL_FRIENDS
 
-static bool flip_social_friends_alloc()
+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 (app_instance->flip_social_friends.usernames[i] == NULL)
+        if (friends->usernames[i] == NULL)
         {
-            app_instance->flip_social_friends.usernames[i] = malloc(MAX_USER_LENGTH);
-            if (app_instance->flip_social_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 false; // Return false on memory allocation failure
+                return NULL; // Return false on memory allocation failure
             }
         }
     }
-    return true;
+    return friends;
 }
 
 static void flip_social_free_friends()
 {
-    if (!app_instance)
+    if (!flip_social_friends)
     {
-        FURI_LOG_E(TAG, "App instance is NULL");
+        FURI_LOG_E(TAG, "Friends model is NULL");
         return;
     }
-    for (int i = 0; i < app_instance->flip_social_friends.count; i++)
+    for (int i = 0; i < flip_social_friends->count; i++)
     {
-        free(app_instance->flip_social_friends.usernames[i]);
+        free(flip_social_friends->usernames[i]);
     }
 }
 
@@ -56,12 +57,17 @@ static bool flip_social_update_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 < app_instance->flip_social_friends.count; i++)
+    for (int i = 0; i < flip_social_friends->count; i++)
     {
-        submenu_add_item(app_instance->submenu_friends, app_instance->flip_social_friends.usernames[i], FlipSocialSubmenuLoggedInIndexFriendsStart + i, flip_social_callback_submenu_choices, app_instance);
+        submenu_add_item(app_instance->submenu_friends, flip_social_friends->usernames[i], FlipSocialSubmenuLoggedInIndexFriendsStart + i, flip_social_callback_submenu_choices, app_instance);
     }
     return true;
 }
@@ -75,7 +81,8 @@ static bool flip_social_parse_json_friends()
     }
 
     // Allocate memory for each username only if not already allocated
-    if (!flip_social_friends_alloc())
+    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;
@@ -89,7 +96,7 @@ static bool flip_social_parse_json_friends()
     }
 
     // Initialize friends count
-    app_instance->flip_social_friends.count = 0;
+    flip_social_friends->count = 0;
 
     // Extract the users array from the JSON
     char *json_users = get_json_value("friends", fhttp.received_data, MAX_TOKENS);
@@ -102,7 +109,7 @@ static bool flip_social_parse_json_friends()
     // Manual tokenization for comma-separated values
     char *start = json_users + 1; // Skip the opening bracket
     char *end;
-    while ((end = strchr(start, ',')) != NULL && app_instance->flip_social_friends.count < MAX_FRIENDS)
+    while ((end = strchr(start, ',')) != NULL && flip_social_friends->count < MAX_FRIENDS)
     {
         *end = '\0'; // Null-terminate the current token
 
@@ -113,14 +120,14 @@ static bool flip_social_parse_json_friends()
             *(end - 1) = '\0';
 
         // Copy username to pre-allocated memory
-        strncpy(app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.count], start, MAX_USER_LENGTH - 1);
-        app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        app_instance->flip_social_friends.count++;
+        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' && app_instance->flip_social_friends.count < MAX_FRIENDS)
+    if (*start != '\0' && flip_social_friends->count < MAX_FRIENDS)
     {
         if (*start == '"')
             start++;
@@ -129,9 +136,9 @@ static bool flip_social_parse_json_friends()
         if (*(start + strlen(start) - 1) == '"')
             *(start + strlen(start) - 1) = '\0';
 
-        strncpy(app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.count], start, MAX_USER_LENGTH - 1);
-        app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        app_instance->flip_social_friends.count++;
+        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
@@ -143,6 +150,8 @@ static bool flip_social_parse_json_friends()
 
     // Free the json_users
     free(json_users);
+    free(start);
+    free(end);
 
     return true;
 }

+ 4 - 34
flip_social_i.h

@@ -164,11 +164,11 @@ static FlipSocialApp *flip_social_app_alloc()
     }
 
     // Allocate Submenu(s)
-    if (!easy_flipper_set_submenu(&app->submenu_logged_out, FlipSocialViewLoggedOutSubmenu, "FlipSocial v0.4", flip_social_callback_exit_app, &app->view_dispatcher))
+    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.4", flip_social_callback_exit_app, &app->view_dispatcher))
+    if (!easy_flipper_set_submenu(&app->submenu_logged_in, FlipSocialViewLoggedInSubmenu, "FlipSocial v0.5", flip_social_callback_exit_app, &app->view_dispatcher))
     {
         return NULL;
     }
@@ -344,11 +344,11 @@ static FlipSocialApp *flip_social_app_alloc()
     }
 
     // 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.\n---\nPress BACK to return.", flip_social_callback_to_submenu_logged_out, &app->view_dispatcher))
+    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.\n---\nPress BACK to return.", flip_social_callback_to_settings_logged_in, &app->view_dispatcher))
+    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;
     }
@@ -526,36 +526,6 @@ static FlipSocialApp *flip_social_app_alloc()
         variable_item_set_current_value_text(app->variable_item_logged_in_profile_username, app->login_username_logged_in);
         //
 
-        app_instance = app;
-
-        // Initialize structs
-        if (!flip_social_feed_alloc())
-        {
-            return NULL;
-        }
-        if (!flip_social_friends_alloc())
-        {
-            return NULL;
-        }
-        if (!flip_social_explore_alloc())
-        {
-            return NULL;
-        }
-        if (!flip_social_messages_alloc())
-        {
-            return NULL;
-        }
-        if (!flip_social_user_messages_alloc())
-        {
-            return NULL;
-        }
-
-        // Set failure FlipSocialFeed object
-        if (!flip_social_temp_feed())
-        {
-            return NULL;
-        }
-
         if (app->is_logged_in != NULL && strcmp(app->is_logged_in, "true") == 0)
         {
             view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInSubmenu);

+ 98 - 58
flip_social_messages.h

@@ -1,75 +1,87 @@
 #ifndef FLIP_SOCIAL_MESSAGES_H
 #define FLIP_SOCIAL_MESSAGES_H
 
-static bool flip_social_messages_alloc()
+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 (app_instance->flip_social_message_users.usernames[i] == NULL)
+        if (users->usernames[i] == NULL)
         {
-            app_instance->flip_social_message_users.usernames[i] = malloc(MAX_USER_LENGTH);
-            if (app_instance->flip_social_message_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 false; // Return false on memory allocation failure
+                return NULL; // Return false on memory allocation failure
             }
         }
     }
-    return true;
+    return users;
 }
 
-static bool flip_social_user_messages_alloc()
+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 (app_instance->flip_social_messages.usernames[i] == NULL)
+        if (messages->usernames[i] == NULL)
         {
-            app_instance->flip_social_messages.usernames[i] = malloc(MAX_USER_LENGTH);
-            if (app_instance->flip_social_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 false; // Return false on memory allocation failure
+                return NULL; // Return false on memory allocation failure
             }
         }
-        if (app_instance->flip_social_messages.messages[i] == NULL)
+        if (messages->messages[i] == NULL)
         {
-            app_instance->flip_social_messages.messages[i] = malloc(MAX_MESSAGE_LENGTH);
-            if (app_instance->flip_social_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 false; // Return false on memory allocation failure
+                return NULL; // Return false on memory allocation failure
             }
         }
     }
-    return true;
+    return messages;
 }
 
 static void flip_social_free_message_users()
 {
-    if (!app_instance)
+    if (flip_social_message_users == NULL)
     {
-        FURI_LOG_E(TAG, "App instance is NULL");
+        FURI_LOG_E(TAG, "Message users model is NULL");
         return;
     }
-    for (int i = 0; i < app_instance->flip_social_message_users.count; i++)
+    for (int i = 0; i < flip_social_message_users->count; i++)
     {
-        free(app_instance->flip_social_message_users.usernames[i]);
+        free(flip_social_message_users->usernames[i]);
     }
 }
 
 static void flip_social_free_messages()
 {
-    if (!app_instance)
+    if (flip_social_messages == NULL)
     {
-        FURI_LOG_E(TAG, "App instance is NULL");
+        FURI_LOG_E(TAG, "Messages model is NULL");
         return;
     }
-    for (int i = 0; i < app_instance->flip_social_messages.count; i++)
+    for (int i = 0; i < flip_social_messages->count; i++)
     {
-        free(app_instance->flip_social_messages.usernames[i]);
-        free(app_instance->flip_social_messages.messages[i]);
+        free(flip_social_messages->usernames[i]);
+        free(flip_social_messages->messages[i]);
     }
 }
 
@@ -80,12 +92,17 @@ static bool flip_social_update_messages_submenu()
         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 < app_instance->flip_social_message_users.count; i++)
+    for (int i = 0; i < flip_social_message_users->count; i++)
     {
-        submenu_add_item(app_instance->submenu_messages, app_instance->flip_social_message_users.usernames[i], FlipSocialSubmenuLoggedInIndexMessagesUsersStart + i, flip_social_callback_submenu_choices, app_instance);
+        submenu_add_item(app_instance->submenu_messages, flip_social_message_users->usernames[i], FlipSocialSubmenuLoggedInIndexMessagesUsersStart + i, flip_social_callback_submenu_choices, app_instance);
     }
     return true;
 }
@@ -97,11 +114,16 @@ static bool flip_social_update_submenu_user_choices()
         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 < app_instance->flip_social_explore.count; i++)
+    for (int i = 0; i < flip_social_explore->count; i++)
     {
-        submenu_add_item(app_instance->submenu_messages_user_choices, app_instance->flip_social_explore.usernames[i], FlipSocialSubmenuLoggedInIndexMessagesUserChoicesIndexStart + i, flip_social_callback_submenu_choices, app_instance);
+        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;
 }
@@ -135,7 +157,7 @@ static bool flip_social_get_messages_with_user()
         return false;
     }
     char command[128];
-    snprintf(command, 128, "https://www.flipsocial.net/api/messages/%s/get/%s/", app_instance->login_username_logged_out, app_instance->flip_social_message_users.usernames[app_instance->flip_social_message_users.index]);
+    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)
     {
@@ -156,7 +178,8 @@ static bool flip_social_parse_json_message_users()
     }
 
     // Allocate memory for each username only if not already allocated
-    if (!flip_social_messages_alloc())
+    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;
@@ -170,7 +193,7 @@ static bool flip_social_parse_json_message_users()
     }
 
     // Initialize message users count
-    app_instance->flip_social_message_users.count = 0;
+    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);
@@ -183,7 +206,7 @@ static bool flip_social_parse_json_message_users()
     // Manual tokenization for comma-separated values
     char *start = json_users + 1; // Skip the opening bracket
     char *end;
-    while ((end = strchr(start, ',')) != NULL && app_instance->flip_social_message_users.count < MAX_MESSAGE_USERS)
+    while ((end = strchr(start, ',')) != NULL && flip_social_message_users->count < MAX_MESSAGE_USERS)
     {
         *end = '\0'; // Null-terminate the current token
 
@@ -194,14 +217,14 @@ static bool flip_social_parse_json_message_users()
             *(end - 1) = '\0';
 
         // Copy username to pre-allocated memory
-        strncpy(app_instance->flip_social_message_users.usernames[app_instance->flip_social_message_users.count], start, MAX_USER_LENGTH - 1);
-        app_instance->flip_social_message_users.usernames[app_instance->flip_social_message_users.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        app_instance->flip_social_message_users.count++;
+        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' && app_instance->flip_social_message_users.count < MAX_MESSAGE_USERS)
+    if (*start != '\0' && flip_social_message_users->count < MAX_MESSAGE_USERS)
     {
         if (*start == '"')
             start++;
@@ -210,9 +233,9 @@ static bool flip_social_parse_json_message_users()
         if (*(start + strlen(start) - 1) == '"')
             *(start + strlen(start) - 1) = '\0';
 
-        strncpy(app_instance->flip_social_message_users.usernames[app_instance->flip_social_message_users.count], start, MAX_USER_LENGTH - 1);
-        app_instance->flip_social_message_users.usernames[app_instance->flip_social_message_users.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        app_instance->flip_social_message_users.count++;
+        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
@@ -220,6 +243,8 @@ static bool flip_social_parse_json_message_users()
 
     // Free the JSON data
     free(json_users);
+    free(start);
+    free(end);
 
     return true;
 }
@@ -234,7 +259,12 @@ static bool flip_social_parse_json_message_user_choices()
     }
 
     // Allocate memory for each username only if not already allocated
-    flip_social_explore_alloc();
+    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;
@@ -244,7 +274,7 @@ static bool flip_social_parse_json_message_user_choices()
     }
 
     // Initialize explore count
-    app_instance->flip_social_explore.count = 0;
+    flip_social_explore->count = 0;
 
     // Extract the users array from the JSON
     char *json_users = get_json_value("users", fhttp.received_data, MAX_TOKENS);
@@ -257,7 +287,7 @@ static bool flip_social_parse_json_message_user_choices()
     // Manual tokenization for comma-separated values
     char *start = json_users + 1; // Skip the opening bracket
     char *end;
-    while ((end = strchr(start, ',')) != NULL && app_instance->flip_social_explore.count < MAX_EXPLORE_USERS)
+    while ((end = strchr(start, ',')) != NULL && flip_social_explore->count < MAX_EXPLORE_USERS)
     {
         *end = '\0'; // Null-terminate the current token
 
@@ -268,14 +298,14 @@ static bool flip_social_parse_json_message_user_choices()
             *(end - 1) = '\0';
 
         // Copy username to pre-allocated memory
-        strncpy(app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count], start, MAX_USER_LENGTH - 1);
-        app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        app_instance->flip_social_explore.count++;
+        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' && app_instance->flip_social_explore.count < MAX_EXPLORE_USERS)
+    if (*start != '\0' && flip_social_explore->count < MAX_EXPLORE_USERS)
     {
         if (*start == '"')
             start++;
@@ -284,9 +314,9 @@ static bool flip_social_parse_json_message_user_choices()
         if (*(start + strlen(start) - 1) == '"')
             *(start + strlen(start) - 1) = '\0';
 
-        strncpy(app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count], start, MAX_USER_LENGTH - 1);
-        app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
-        app_instance->flip_social_explore.count++;
+        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
@@ -294,6 +324,8 @@ static bool flip_social_parse_json_message_user_choices()
 
     // Free the JSON data
     free(json_users);
+    free(start);
+    free(end);
 
     return true;
 }
@@ -307,6 +339,14 @@ static bool flip_social_parse_json_messages()
         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)
@@ -315,11 +355,7 @@ static bool flip_social_parse_json_messages()
     }
 
     // Initialize messages count
-    app_instance->flip_social_messages.count = 0;
-
-    // example response:
-
-    // {'conversations': [{'sender': 'Zett', 'content': 'Hello JBlanked'}, {'sender': 'Zett', 'content': 'Received bro.'}, {'sender': 'JBlanked', 'content': 'Yoo testing'}]}
+    flip_social_messages->count = 0;
 
     // Iterate through the messages array
     for (int i = 0; i < MAX_MESSAGES; i++)
@@ -343,11 +379,15 @@ static bool flip_social_parse_json_messages()
         }
 
         // Store parsed values
-        app_instance->flip_social_messages.usernames[i] = sender;
-        app_instance->flip_social_messages.messages[i] = content;
-        app_instance->flip_social_messages.count++;
+        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;

+ 3 - 3
flipper_http.h

@@ -13,10 +13,10 @@
 #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 (5 * 1000) // 5 seconds
+#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 4096          // UART RX line buffer size (increase for large responses)
+#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);
@@ -728,7 +728,7 @@ void flipper_http_rx_callback(const char *line, void *context)
     }
 
     // Uncomment below line to log the data received over UART
-    // FURI_LOG_I(HTTP_TAG, "Received UART line: %s", line);
+    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)