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

FlipSocial - v0.8 new features

- Introduced a bio feature in the Profile section: View and update your bio.
- Enhanced the Explore view: Clicking on a user now displays their bio and friend count. You can also search for users.
- Improved the Messages view: Users can now search for a contact to send messages.
jblanked 1 год назад
Родитель
Сommit
3c8b188d64

+ 2 - 2
README.md

@@ -6,7 +6,7 @@ The highlight of this app is customizable pre-saves, which, as explained below,
 FlipSocial uses the FlipperHTTP flash for the WiFi Devboard, first introduced in the WebCrawler app: https://github.com/jblanked/WebCrawler-FlipperZero/tree/main/assets/FlipperHTTP
 
 ## Requirements
-- WiFi Developer Board or Raspberry Pi Pico W with FlipperHTTP Flash: https://github.com/jblanked/FlipperHTTP
+- WiFi Developer Board, Raspberry Pi, or ESP32 Device with FlipperHTTP Flash: https://github.com/jblanked/FlipperHTTP
 - WiFi Access Point
 
 
@@ -60,7 +60,7 @@ FlipSocial uses the FlipperHTTP flash for the WiFi Devboard, first introduced in
 - Loading screens.
 
 **v0.8**
-- Improve User Profile (Bio, friend count, block)
+- Improve User Profile
 - Improve Explore Page
 
 **v1.0**

+ 50 - 2
alloc/flip_social_alloc.c

@@ -41,6 +41,7 @@ FlipSocialApp *flip_social_app_alloc()
     app->register_password_logged_out_temp_buffer_size = MAX_USER_LENGTH;
     app->register_password_2_logged_out_temp_buffer_size = MAX_USER_LENGTH;
     app->change_password_logged_in_temp_buffer_size = MAX_USER_LENGTH;
+    app->change_bio_logged_in_temp_buffer_size = MAX_MESSAGE_LENGTH;
     app->compose_pre_save_logged_in_temp_buffer_size = MAX_MESSAGE_LENGTH;
     app->wifi_ssid_logged_in_temp_buffer_size = MAX_USER_LENGTH;
     app->wifi_password_logged_in_temp_buffer_size = MAX_USER_LENGTH;
@@ -48,6 +49,8 @@ FlipSocialApp *flip_social_app_alloc()
     app->login_username_logged_in_temp_buffer_size = MAX_USER_LENGTH;
     app->messages_new_message_logged_in_temp_buffer_size = MAX_MESSAGE_LENGTH;
     app->message_user_choice_logged_in_temp_buffer_size = MAX_MESSAGE_LENGTH;
+    app->explore_logged_in_temp_buffer_size = MAX_USER_LENGTH;
+    app->message_users_logged_in_temp_buffer_size = MAX_USER_LENGTH;
     if (!easy_flipper_set_buffer(&app->wifi_ssid_logged_out_temp_buffer, app->wifi_ssid_logged_out_temp_buffer_size))
     {
         return NULL;
@@ -80,6 +83,10 @@ FlipSocialApp *flip_social_app_alloc()
     {
         return NULL;
     }
+    if (!easy_flipper_set_buffer(&app->change_bio_logged_in_temp_buffer, app->change_bio_logged_in_temp_buffer_size))
+    {
+        return NULL;
+    }
     if (!easy_flipper_set_buffer(&app->compose_pre_save_logged_in_temp_buffer, app->compose_pre_save_logged_in_temp_buffer_size))
     {
         return NULL;
@@ -133,6 +140,10 @@ FlipSocialApp *flip_social_app_alloc()
     {
         return NULL;
     }
+    if (!easy_flipper_set_buffer(&app->change_bio_logged_in, app->change_bio_logged_in_temp_buffer_size))
+    {
+        return NULL;
+    }
     if (!easy_flipper_set_buffer(&app->compose_pre_save_logged_in, app->compose_pre_save_logged_in_temp_buffer_size))
     {
         return NULL;
@@ -174,6 +185,22 @@ FlipSocialApp *flip_social_app_alloc()
     {
         return NULL;
     }
+    if (!easy_flipper_set_buffer(&app->explore_logged_in, app->explore_logged_in_temp_buffer_size))
+    {
+        return NULL;
+    }
+    if (!easy_flipper_set_buffer(&app->explore_logged_in_temp_buffer, app->explore_logged_in_temp_buffer_size))
+    {
+        return NULL;
+    }
+    if (!easy_flipper_set_buffer(&app->message_users_logged_in, app->message_users_logged_in_temp_buffer_size))
+    {
+        return NULL;
+    }
+    if (!easy_flipper_set_buffer(&app->message_users_logged_in_temp_buffer, app->message_users_logged_in_temp_buffer_size))
+    {
+        return NULL;
+    }
 
     // Allocate Submenu(s)
     if (!easy_flipper_set_submenu(&app->submenu_logged_out, FlipSocialViewLoggedOutSubmenu, "FlipSocial v0.8", flip_social_callback_exit_app, &app->view_dispatcher))
@@ -242,7 +269,8 @@ FlipSocialApp *flip_social_app_alloc()
     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", 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_change_password = variable_item_list_add(app->variable_item_list_logged_in_profile, "Password", 1, NULL, app);
+    app->variable_item_logged_in_profile_change_bio = variable_item_list_add(app->variable_item_list_logged_in_profile, "Bio", 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, app);
@@ -281,7 +309,11 @@ FlipSocialApp *flip_social_app_alloc()
         return NULL;
     }
     //
-    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_change_password, FlipSocialViewLoggedInChangePasswordInput, "Enter New Password", app->change_password_logged_in_temp_buffer, app->change_password_logged_in_temp_buffer_size, flip_social_logged_in_profile_change_password_updated, flip_social_callback_to_profile_logged_in, &app->view_dispatcher, app))
+    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_change_password, FlipSocialViewLoggedInChangePasswordInput, "Password", app->change_password_logged_in_temp_buffer, app->change_password_logged_in_temp_buffer_size, flip_social_logged_in_profile_change_password_updated, flip_social_callback_to_profile_logged_in, &app->view_dispatcher, app))
+    {
+        return NULL;
+    }
+    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_change_bio, FlipSocialViewLoggedInChangeBioInput, "Bio", app->change_bio_logged_in_temp_buffer, app->change_bio_logged_in_temp_buffer_size, flip_social_logged_in_profile_change_bio_updated, flip_social_callback_to_profile_logged_in, &app->view_dispatcher, app))
     {
         return NULL;
     }
@@ -306,6 +338,14 @@ FlipSocialApp *flip_social_app_alloc()
     {
         return NULL;
     }
+    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_explore, FlipSocialViewLoggedInExploreInput, "Enter Username or Keyword", app->explore_logged_in_temp_buffer, app->explore_logged_in_temp_buffer_size, flip_social_logged_in_explore_updated, flip_social_callback_to_submenu_logged_in, &app->view_dispatcher, app))
+    {
+        return NULL;
+    }
+    if (!easy_flipper_set_uart_text_input(&app->text_input_logged_in_message_users, FlipSocialViewLoggedInMessageUsersInput, "Enter Username or Keyword", app->message_users_logged_in_temp_buffer, app->message_users_logged_in_temp_buffer_size, flip_social_logged_in_message_users_updated, flip_social_callback_to_submenu_logged_in, &app->view_dispatcher, app))
+    {
+        return NULL;
+    }
 
     // Load the settings
     if (!load_settings(app->wifi_ssid_logged_out,
@@ -320,6 +360,8 @@ FlipSocialApp *flip_social_app_alloc()
                        app->login_password_logged_out_temp_buffer_size,
                        app->change_password_logged_in,
                        app->change_password_logged_in_temp_buffer_size,
+                       app->change_bio_logged_in,
+                       app->change_bio_logged_in_temp_buffer_size,
                        app->is_logged_in,
                        app->is_logged_in_size))
 
@@ -377,6 +419,11 @@ FlipSocialApp *flip_social_app_alloc()
             strncpy(app->change_password_logged_in_temp_buffer, app->change_password_logged_in, app->change_password_logged_in_temp_buffer_size - 1);
             app->change_password_logged_in_temp_buffer[app->change_password_logged_in_temp_buffer_size - 1] = '\0';
         }
+        if (app->change_bio_logged_in && app->change_bio_logged_in_temp_buffer)
+        {
+            strncpy(app->change_bio_logged_in_temp_buffer, app->change_bio_logged_in, app->change_bio_logged_in_temp_buffer_size - 1);
+            app->change_bio_logged_in_temp_buffer[app->change_bio_logged_in_temp_buffer_size - 1] = '\0';
+        }
         if (app->compose_pre_save_logged_in && app->compose_pre_save_logged_in_temp_buffer)
         {
             strncpy(app->compose_pre_save_logged_in_temp_buffer, app->compose_pre_save_logged_in, app->compose_pre_save_logged_in_temp_buffer_size - 1);
@@ -470,6 +517,7 @@ FlipSocialApp *flip_social_app_alloc()
         variable_item_set_current_value_text(app->variable_item_logged_out_wifi_settings_ssid, app->wifi_ssid_logged_out);
         variable_item_set_current_value_text(app->variable_item_logged_out_login_username, app->login_username_logged_out);
         variable_item_set_current_value_text(app->variable_item_logged_in_profile_username, app->login_username_logged_in);
+        variable_item_set_current_value_text(app->variable_item_logged_in_profile_change_bio, app->change_bio_logged_in);
         //
 
         if (app->is_logged_in != NULL && strcmp(app->is_logged_in, "true") == 0)

+ 5 - 2
assets/CHANGELOG.md

@@ -1,5 +1,8 @@
-## 0.8
-- Add support for RPC_KEYBOARD
+## 0.8 - New Features
+- Added support for RPC_KEYBOARD (thanks to Derek Jamison).
+- Introduced a bio feature in the Profile section: View and update your bio.
+- Enhanced the Explore view: Clicking on a user now displays their bio and friend count. You can also search for users.
+- Improved the Messages view: Users can now search for a contact to send messages.
 
 ## 0.7
 - Improved memory allocation

+ 2 - 2
assets/README.md

@@ -6,7 +6,7 @@ The highlight of this app is customizable pre-saves, which, as explained below,
 FlipSocial uses the FlipperHTTP flash for the WiFi Devboard, first introduced in the WebCrawler app: https://github.com/jblanked/WebCrawler-FlipperZero/tree/main/assets/FlipperHTTP
 
 ## Requirements
-- WiFi Developer Board or Raspberry Pi Pico W with FlipperHTTP Flash: https://github.com/jblanked/FlipperHTTP
+- WiFi Developer Board, Raspberry Pi, or ESP32 Device with FlipperHTTP Flash: https://github.com/jblanked/FlipperHTTP
 - WiFi Access Point
 
 
@@ -60,7 +60,7 @@ FlipSocial uses the FlipperHTTP flash for the WiFi Devboard, first introduced in
 - Loading screens.
 
 **v0.8**
-- Improve User Profile (Bio, friend count, block)
+- Improve User Profile
 - Improve Explore Page
 
 **v1.0**

+ 219 - 44
callback/flip_social_callback.c

@@ -106,7 +106,7 @@ static void flip_social_free_friends(void)
     }
 }
 
-void flip_social_request_error_draw(Canvas *canvas)
+static void flip_social_request_error_draw(Canvas *canvas)
 {
     if (canvas == NULL)
     {
@@ -200,7 +200,7 @@ static char *flip_social_login_parse(DataLoaderModel *model)
             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->change_bio_logged_in, app_instance->is_logged_in);
 
         // send user to the logged in submenu
         view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
@@ -281,7 +281,7 @@ static char *flip_social_register_parse(DataLoaderModel *model)
         auth_headers_alloc();
 
         // save the credentials
-        save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
+        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->change_bio_logged_in, app_instance->is_logged_in);
 
         // send user to the logged in submenu
         view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
@@ -980,6 +980,48 @@ bool feed_dialog_alloc()
     }
     return false;
 }
+static bool flip_social_get_user_info()
+{
+    char url[256];
+    snprintf(url, sizeof(url), "https://www.flipsocial.net/api/user/users/%s/extended/", flip_social_explore->usernames[flip_social_explore->index]);
+    if (!flipper_http_get_request_with_headers(url, auth_headers))
+    {
+        FURI_LOG_E(TAG, "Failed to send HTTP request for user info");
+        fhttp.state = ISSUE;
+        return false;
+    }
+    fhttp.state = RECEIVING;
+    return true;
+}
+static bool flip_social_parse_user_info()
+{
+    if (fhttp.last_response == NULL)
+    {
+        FURI_LOG_E(TAG, "Response is NULL");
+        return false;
+    }
+    if (!app_instance->explore_user_bio)
+    {
+        FURI_LOG_E(TAG, "App instance is NULL");
+        return false;
+    }
+    char *bio = get_json_value("bio", fhttp.last_response, 32);
+    char *friends = get_json_value("friends", fhttp.last_response, 32);
+    if (bio && friends)
+    {
+        if (strlen(bio) != 0)
+        {
+            snprintf(app_instance->explore_user_bio, MAX_MESSAGE_LENGTH, "%s (%s friends)", bio, friends);
+        }
+        else
+        {
+            snprintf(app_instance->explore_user_bio, MAX_MESSAGE_LENGTH, "%s friends", friends);
+        }
+        free(bio);
+        return true;
+    }
+    return false;
+}
 
 /**
  * @brief Handle ALL submenu item selections.
@@ -1030,12 +1072,7 @@ void flip_social_callback_submenu_choices(void *context, uint32_t index)
             &app->view_dispatcher);                // view dispatcher
         break;
     case FlipSocialSubmenuLoggedInIndexMessagesNewMessage:
-        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
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessageUsersInput);
         break;
     case FlipSocialSubmenuLoggedInIndexFeed:
         free_flip_social_group();
@@ -1048,12 +1085,7 @@ void flip_social_callback_submenu_choices(void *context, uint32_t index)
         break;
     case FlipSocialSubmenuExploreIndex:
         free_flip_social_group();
-        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
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInExploreInput);
         break;
     case FlipSocialSubmenuLoggedInIndexCompose:
         free_pre_saved_messages();
@@ -1071,7 +1103,7 @@ void flip_social_callback_submenu_choices(void *context, uint32_t index)
         free_flip_social_group();
         app->is_logged_in = "false";
 
-        save_settings(app->wifi_ssid_logged_out, app->wifi_password_logged_out, app->login_username_logged_out, app->login_username_logged_in, app->login_password_logged_out, app->change_password_logged_in, app->is_logged_in);
+        save_settings(app->wifi_ssid_logged_out, app->wifi_password_logged_out, app->login_username_logged_out, app->login_username_logged_in, app->login_password_logged_out, app->change_password_logged_in, app->change_bio_logged_in, app->is_logged_in);
 
         view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutSubmenu);
         break;
@@ -1124,30 +1156,70 @@ void flip_social_callback_submenu_choices(void *context, uint32_t index)
                 return;
             }
             flip_social_explore->index = index - FlipSocialSubmenuExploreIndexStartIndex;
-            flip_social_free_explore_dialog();
-            if (!app->dialog_explore)
+            // loading task to get the user info
+            if (app->explore_user_bio)
             {
-                if (!easy_flipper_set_dialog_ex(
-                        &app->dialog_explore,
-                        FlipSocialViewExploreDialog,
-                        "User Options",
-                        0,
-                        0,
-                        flip_social_explore->usernames[flip_social_explore->index],
-                        0,
-                        10,
-                        "Remove",
-                        "Add",
-                        NULL,
-                        explore_dialog_callback,
-                        flip_social_callback_to_explore_logged_in,
-                        &app->view_dispatcher,
-                        app))
+                free(app->explore_user_bio);
+                app->explore_user_bio = NULL;
+            }
+            if (!easy_flipper_set_buffer(&app->explore_user_bio, MAX_MESSAGE_LENGTH))
+            {
+                return;
+            }
+            if (flipper_http_process_response_async(flip_social_get_user_info, flip_social_parse_user_info))
+            {
+                flip_social_free_explore_dialog();
+                if (!app->dialog_explore)
                 {
-                    return;
+                    if (!easy_flipper_set_dialog_ex(
+                            &app->dialog_explore,
+                            FlipSocialViewExploreDialog,
+                            flip_social_explore->usernames[flip_social_explore->index],
+                            0,
+                            0,
+                            app->explore_user_bio,
+                            0,
+                            10,
+                            "Remove", // remove if user is a friend (future update)
+                            "Add",    // add if user is not a friend (future update)
+                            NULL,
+                            explore_dialog_callback,
+                            flip_social_callback_to_explore_logged_in,
+                            &app->view_dispatcher,
+                            app))
+                    {
+                        return;
+                    }
                 }
+                view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewExploreDialog);
+            }
+            else
+            {
+                flip_social_free_explore_dialog();
+                if (!app->dialog_explore)
+                {
+                    if (!easy_flipper_set_dialog_ex(
+                            &app->dialog_explore,
+                            FlipSocialViewExploreDialog,
+                            flip_social_explore->usernames[flip_social_explore->index],
+                            0,
+                            0,
+                            "",
+                            0,
+                            10,
+                            "Remove", // remove if user is a friend (future update)
+                            "Add",    // add if user is not a friend (future update)
+                            NULL,
+                            explore_dialog_callback,
+                            flip_social_callback_to_explore_logged_in,
+                            &app->view_dispatcher,
+                            app))
+                    {
+                        return;
+                    }
+                }
+                view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewExploreDialog);
             }
-            view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewExploreDialog);
         }
 
         // handle the friends selection
@@ -1263,7 +1335,7 @@ void flip_social_logged_out_wifi_settings_ssid_updated(void *context)
     }
 
     // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
+    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->change_bio_logged_in, app_instance->is_logged_in);
 
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettings);
 }
@@ -1308,7 +1380,7 @@ void flip_social_logged_out_wifi_settings_password_updated(void *context)
     }
 
     // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
+    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->change_bio_logged_in, app_instance->is_logged_in);
 
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutWifiSettings);
 }
@@ -1371,7 +1443,7 @@ void flip_social_logged_out_login_username_updated(void *context)
     }
 
     // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
+    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->change_bio_logged_in, app_instance->is_logged_in);
 
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutLogin);
 }
@@ -1408,7 +1480,7 @@ void flip_social_logged_out_login_password_updated(void *context)
     }
 
     // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
+    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->change_bio_logged_in, app_instance->is_logged_in);
 
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedOutLogin);
 }
@@ -1592,7 +1664,7 @@ void flip_social_logged_in_wifi_settings_ssid_updated(void *context)
     }
 
     // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_in, app_instance->wifi_password_logged_in, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
+    save_settings(app_instance->wifi_ssid_logged_in, app_instance->wifi_password_logged_in, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->change_bio_logged_in, app_instance->is_logged_in);
 
     // update the wifi settings
     if (strlen(app->wifi_ssid_logged_in) > 0 && strlen(app->wifi_password_logged_in) > 0)
@@ -1638,7 +1710,7 @@ void flip_social_logged_in_wifi_settings_password_updated(void *context)
     }
 
     // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_in, app_instance->wifi_password_logged_in, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
+    save_settings(app_instance->wifi_ssid_logged_in, app_instance->wifi_password_logged_in, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->change_bio_logged_in, app_instance->is_logged_in);
 
     // update the wifi settings
     if (strlen(app->wifi_ssid_logged_in) > 0 && strlen(app->wifi_password_logged_in) > 0)
@@ -1772,7 +1844,44 @@ void flip_social_logged_in_profile_change_password_updated(void *context)
         return;
     }
     // Save the settings
-    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->is_logged_in);
+    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->change_bio_logged_in, app_instance->is_logged_in);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInProfile);
+}
+
+void flip_social_logged_in_profile_change_bio_updated(void *context)
+{
+    FlipSocialApp *app = (FlipSocialApp *)context;
+    if (!app)
+    {
+        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
+        return;
+    }
+
+    // Store the entered message
+    strncpy(app->change_bio_logged_in, app->change_bio_logged_in_temp_buffer, app->change_bio_logged_in_temp_buffer_size);
+
+    // Ensure null-termination
+    app->change_bio_logged_in[app->change_bio_logged_in_temp_buffer_size - 1] = '\0';
+
+    // Update the message item text
+    if (app->variable_item_logged_in_profile_change_bio)
+    {
+        variable_item_set_current_value_text(app->variable_item_logged_in_profile_change_bio, app->change_bio_logged_in);
+    }
+
+    // send post request to change bio
+    auth_headers_alloc();
+    char payload[256];
+    snprintf(payload, sizeof(payload), "{\"username\":\"%s\",\"bio\":\"%s\"}", app->login_username_logged_out, app->change_bio_logged_in);
+    if (!flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/change-bio/", auth_headers, payload))
+    {
+        FURI_LOG_E(TAG, "Failed to send post request to change bio");
+        FURI_LOG_E(TAG, "Make sure the Flipper is connected to the Wifi Dev Board");
+        return;
+    }
+    // Save the settings
+    save_settings(app_instance->wifi_ssid_logged_out, app_instance->wifi_password_logged_out, app_instance->login_username_logged_out, app_instance->login_username_logged_in, app_instance->login_password_logged_out, app_instance->change_password_logged_in, app_instance->change_bio_logged_in, app_instance->is_logged_in);
 
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInProfile);
 }
@@ -1799,7 +1908,10 @@ void flip_social_text_input_logged_in_profile_item_selected(void *context, uint3
     case 1: // Change Password
         view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInChangePasswordInput);
         break;
-    case 2: // Friends
+    case 2: // Change Bio
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInChangeBioInput);
+        break;
+    case 3: // Friends
         flip_social_free_friends();
         free_flip_social_group();
         if (!app->submenu_friends)
@@ -1968,6 +2080,69 @@ void flip_social_logged_in_messages_new_message_updated(void *context)
     view_dispatcher_switch_to_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesSubmenu);
 }
 
+void flip_social_logged_in_explore_updated(void *context)
+{
+    FlipSocialApp *app = (FlipSocialApp *)context;
+    if (!app)
+    {
+        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
+        return;
+    }
+
+    // check if the message is empty
+    if (app->explore_logged_in_temp_buffer_size == 0)
+    {
+        FURI_LOG_E(TAG, "Message is empty");
+        strncpy(app->explore_logged_in, "a", 2);
+    }
+    else
+    {
+        // Store the entered message
+        strncpy(app->explore_logged_in, app->explore_logged_in_temp_buffer, app->explore_logged_in_temp_buffer_size);
+    }
+
+    // Ensure null-termination
+    app->explore_logged_in[app->explore_logged_in_temp_buffer_size - 1] = '\0';
+
+    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
+}
+void flip_social_logged_in_message_users_updated(void *context)
+{
+    FlipSocialApp *app = (FlipSocialApp *)context;
+    if (!app)
+    {
+        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
+        return;
+    }
+
+    // check if the message is empty
+    if (app->message_users_logged_in_temp_buffer_size == 0)
+    {
+        FURI_LOG_E(TAG, "Message is empty");
+        strncpy(app->message_users_logged_in, "a", 2);
+    }
+    else
+    {
+        // Store the entered message
+        strncpy(app->message_users_logged_in, app->message_users_logged_in_temp_buffer, app->message_users_logged_in_temp_buffer_size);
+    }
+
+    // Ensure null-termination
+    app->message_users_logged_in[app->message_users_logged_in_temp_buffer_size - 1] = '\0';
+
+    flipper_http_loading_task(
+        flip_social_get_explore_2,                   // 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
+}
+
 static void flip_social_widget_set_text(char *message, Widget **widget)
 {
     if (widget == NULL)

+ 3 - 2
callback/flip_social_callback.h

@@ -8,8 +8,6 @@
 #include <feed/flip_social_feed.h>
 #include <flip_storage/flip_social_storage.h>
 
-void flip_social_request_error_draw(Canvas *canvas);
-
 /**
  * @brief Navigation callback to go back to the submenu Logged out.
  * @param context The context - unused
@@ -223,6 +221,7 @@ void flip_social_logged_in_profile_change_password_updated(void *context);
  * @param index The index of the selected item.
  * @return void
  */
+void flip_social_logged_in_profile_change_bio_updated(void *context);
 void flip_social_text_input_logged_in_profile_item_selected(void *context, uint32_t index);
 
 /**
@@ -253,6 +252,8 @@ void flip_social_logged_in_messages_new_message_updated(void *context);
  * @return void
  */
 void flip_social_text_input_logged_out_register_item_selected(void *context, uint32_t index);
+void flip_social_logged_in_explore_updated(void *context);
+void flip_social_logged_in_message_users_updated(void *context);
 
 // Add edits by Derek Jamison
 typedef enum DataState DataState;

+ 33 - 3
explore/flip_social_explore.c

@@ -66,14 +66,45 @@ bool flip_social_get_explore(void)
         FURI_LOG_E(TAG, "HTTP state is INACTIVE");
         return false;
     }
+    char *keyword = !app_instance->explore_logged_in || strlen(app_instance->explore_logged_in) == 0 ? "a" : app_instance->explore_logged_in;
     snprintf(
         fhttp.file_path,
         sizeof(fhttp.file_path),
-        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/users.json");
+        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/%s.json",
+        keyword);
 
     fhttp.save_received_data = true;
     auth_headers_alloc();
-    if (!flipper_http_get_request_with_headers("https://www.flipsocial.net/api/user/users/", auth_headers))
+    char url[256];
+    snprintf(url, sizeof(url), "https://www.flipsocial.net/api/user/explore/%s/%d/", keyword, MAX_EXPLORE_USERS);
+    if (!flipper_http_get_request_with_headers(url, auth_headers))
+    {
+        FURI_LOG_E(TAG, "Failed to send HTTP request for explore");
+        fhttp.state = ISSUE;
+        return false;
+    }
+    fhttp.state = RECEIVING;
+    return true;
+}
+bool flip_social_get_explore_2(void)
+{
+    if (fhttp.state == INACTIVE)
+    {
+        FURI_LOG_E(TAG, "HTTP state is INACTIVE");
+        return false;
+    }
+    char *keyword = !app_instance->message_users_logged_in || strlen(app_instance->message_users_logged_in) == 0 ? "a" : app_instance->message_users_logged_in;
+    snprintf(
+        fhttp.file_path,
+        sizeof(fhttp.file_path),
+        STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/%s.json",
+        keyword);
+
+    fhttp.save_received_data = true;
+    auth_headers_alloc();
+    char url[256];
+    snprintf(url, sizeof(url), "https://www.flipsocial.net/api/user/explore/%s/%d/", keyword, MAX_EXPLORE_USERS);
+    if (!flipper_http_get_request_with_headers(url, auth_headers))
     {
         FURI_LOG_E(TAG, "Failed to send HTTP request for explore");
         fhttp.state = ISSUE;
@@ -116,7 +147,6 @@ bool flip_social_parse_json_explore()
     // set submenu
     submenu_reset(app_instance->submenu_explore);
     submenu_set_header(app_instance->submenu_explore, "Explore");
-
     // Parse the JSON array of usernames
     for (size_t i = 0; i < MAX_EXPLORE_USERS; i++)
     {

+ 1 - 0
explore/flip_social_explore.h

@@ -5,5 +5,6 @@
 FlipSocialModel *flip_social_explore_alloc();
 void flip_social_free_explore();
 bool flip_social_get_explore();
+bool flip_social_get_explore_2(void);
 bool flip_social_parse_json_explore();
 #endif

+ 27 - 0
flip_social.c

@@ -132,6 +132,11 @@ void flip_social_app_free(FlipSocialApp *app)
         view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInChangePasswordInput);
         uart_text_input_free(app->text_input_logged_in_change_password);
     }
+    if (app->text_input_logged_in_change_bio)
+    {
+        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInChangeBioInput);
+        uart_text_input_free(app->text_input_logged_in_change_bio);
+    }
     if (app->text_input_logged_in_compose_pre_save_input)
     {
         view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInComposeAddPreSaveInput);
@@ -157,6 +162,16 @@ void flip_social_app_free(FlipSocialApp *app)
         view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInMessagesNewMessageUserChoicesInput);
         uart_text_input_free(app->text_input_logged_in_messages_new_message_user_choices);
     }
+    if (app->text_input_logged_in_explore)
+    {
+        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInExploreInput);
+        uart_text_input_free(app->text_input_logged_in_explore);
+    }
+    if (app->text_input_logged_in_message_users)
+    {
+        view_dispatcher_remove_view(app->view_dispatcher, FlipSocialViewLoggedInMessageUsersInput);
+        uart_text_input_free(app->text_input_logged_in_message_users);
+    }
 
     // Free Widget(s)
     if (app->widget_result)
@@ -209,10 +224,20 @@ void flip_social_app_free(FlipSocialApp *app)
         free(app->change_password_logged_in);
     if (app->change_password_logged_in_temp_buffer)
         free(app->change_password_logged_in_temp_buffer);
+    if (app->change_bio_logged_in)
+        free(app->change_bio_logged_in);
     if (app->compose_pre_save_logged_in)
         free(app->compose_pre_save_logged_in);
     if (app->compose_pre_save_logged_in_temp_buffer)
         free(app->compose_pre_save_logged_in_temp_buffer);
+    if (app->explore_logged_in)
+        free(app->explore_logged_in);
+    if (app->explore_logged_in_temp_buffer)
+        free(app->explore_logged_in_temp_buffer);
+    if (app->message_users_logged_in)
+        free(app->message_users_logged_in);
+    if (app->message_users_logged_in_temp_buffer)
+        free(app->message_users_logged_in_temp_buffer);
     if (app->wifi_ssid_logged_in)
         free(app->wifi_ssid_logged_in);
     if (app->wifi_ssid_logged_in_temp_buffer)
@@ -239,6 +264,8 @@ void flip_social_app_free(FlipSocialApp *app)
         free(last_explore_response);
     if (selected_message)
         free(selected_message);
+    if (app->explore_user_bio)
+        free(app->explore_user_bio);
 
     if (app->input_event && app->input_event_queue)
         furi_pubsub_unsubscribe(app->input_event_queue, app->input_event);

+ 28 - 5
flip_social.h

@@ -11,7 +11,7 @@
 
 #define MAX_PRE_SAVED_MESSAGES 20 // Maximum number of pre-saved messages
 #define MAX_MESSAGE_LENGTH 100    // Maximum length of a message in the feed
-#define MAX_EXPLORE_USERS 100     // Maximum number of users to explore
+#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 640            // Adjust based on expected JSON tokens
@@ -125,12 +125,15 @@ typedef enum
     FlipSocialViewLoggedInCompose,  // The compose screen
     FlipSocialViewLoggedInSettings, // The settings screen
     //
+    FlipSocialViewLoggedInChangeBioInput,         // Text input screen for bio input on profile screen
     FlipSocialViewLoggedInChangePasswordInput,    // Text input screen for password input on change password screen
     FlipSocialViewLoggedInComposeAddPreSaveInput, // Text input screen for add text input on compose screen
     //
     FlipSocialViewLoggedInMessagesNewMessageInput,            // Text input screen for new message input on messages screen
     FlipSocialViewLoggedInMessagesNewMessageUserChoicesInput, // Text input screen for new message input on messages screen
     FlipSocialViewLoggedInMessagesUserChoices,                // the view after clicking [New Message] - select a user to message, then direct to input view
+    FlipSocialViewLoggedInExploreInput,                       // Text input screen for explore input on explore screen
+    FlipSocialViewLoggedInMessageUsersInput,
     //
     FlipSocialViewLoggedInSettingsAbout,             // The about screen
     FlipSocialViewLoggedInSettingsWifi,              // The wifi settings screen
@@ -189,12 +192,16 @@ typedef struct
     UART_TextInput *text_input_logged_out_register_password_2;    // Text input for password 2 input on register screen
     //
     UART_TextInput *text_input_logged_in_change_password;        // Text input for password input on change password screen
+    UART_TextInput *text_input_logged_in_change_bio;             // Text input for bio input on profile screen
     UART_TextInput *text_input_logged_in_compose_pre_save_input; // Text input for pre save input on compose screen
     UART_TextInput *text_input_logged_in_wifi_settings_ssid;     // Text input for ssid input on wifi settings screen
     UART_TextInput *text_input_logged_in_wifi_settings_password; // Text input for password input on wifi settings screen
     //
     UART_TextInput *text_input_logged_in_messages_new_message;              // Text input for new message input on messages screen
     UART_TextInput *text_input_logged_in_messages_new_message_user_choices; //
+    //
+    UART_TextInput *text_input_logged_in_explore; // Text input for explore input on explore screen
+    UART_TextInput *text_input_logged_in_message_users;
 
     VariableItem *variable_item_logged_out_wifi_settings_ssid;     // Reference to the ssid configuration item
     VariableItem *variable_item_logged_out_wifi_settings_password; // Reference to the password configuration item
@@ -208,10 +215,12 @@ typedef struct
     //
     VariableItem *variable_item_logged_in_profile_username;        // Reference to the username configuration item
     VariableItem *variable_item_logged_in_profile_change_password; // Reference to the change password configuration item
-    VariableItem *variable_item_logged_in_settings_about;          // Reference to the about configuration item
-    VariableItem *variable_item_logged_in_settings_wifi;           // Reference to the wifi settings configuration item
-    VariableItem *variable_item_logged_in_wifi_settings_ssid;      // Reference to the ssid configuration item
-    VariableItem *variable_item_logged_in_wifi_settings_password;  // Reference to the password configuration item
+    VariableItem *variable_item_logged_in_profile_change_bio;      // Reference to the change bio configuration item
+    //
+    VariableItem *variable_item_logged_in_settings_about;         // Reference to the about configuration item
+    VariableItem *variable_item_logged_in_settings_wifi;          // Reference to the wifi settings configuration item
+    VariableItem *variable_item_logged_in_wifi_settings_ssid;     // Reference to the ssid configuration item
+    VariableItem *variable_item_logged_in_wifi_settings_password; // Reference to the password configuration item
     //
     VariableItem *variable_item_logged_in_profile_friends; // Reference to the friends configuration item
     //
@@ -227,6 +236,10 @@ typedef struct
     char *login_username_logged_in_temp_buffer;         // Temporary buffer for login username text input
     uint32_t login_username_logged_in_temp_buffer_size; // Size of the login username temporary buffer
 
+    char *change_bio_logged_in;                     // Store the entered bio
+    char *change_bio_logged_in_temp_buffer;         // Temporary buffer for bio text input
+    uint32_t change_bio_logged_in_temp_buffer_size; // Size of the bio temporary buffer
+    //
     char *wifi_ssid_logged_out;                     // Store the entered wifi ssid
     char *wifi_ssid_logged_out_temp_buffer;         // Temporary buffer for wifi ssid text input
     uint32_t wifi_ssid_logged_out_temp_buffer_size; // Size of the wifi ssid temporary buffer
@@ -280,6 +293,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
+    //
+    char *explore_logged_in;                     // Store the entered explore
+    char *explore_logged_in_temp_buffer;         // Temporary buffer for explore text input
+    uint32_t explore_logged_in_temp_buffer_size; // Size of the explore temporary buffer
+
+    char *message_users_logged_in;                     // Store the entered message users
+    char *message_users_logged_in_temp_buffer;         // Temporary buffer for message users text input
+    uint32_t message_users_logged_in_temp_buffer_size; // Size of the message users temporary buffer
 
     Loading *loading; // The loading screen
     DialogEx *dialog_explore;
@@ -287,6 +308,8 @@ typedef struct
     DialogEx *dialog_messages;
     DialogEx *dialog_compose;
     DialogEx *dialog_feed;
+
+    char *explore_user_bio; // Store the bio of the selected user
 } FlipSocialApp;
 
 void flip_social_app_free(FlipSocialApp *app);

+ 27 - 1
flip_storage/flip_social_storage.c

@@ -47,7 +47,6 @@ void save_playlist(const PreSavedPlaylist *playlist)
     furi_record_close(RECORD_STORAGE);
 }
 
-// Function to load the playlist
 // Function to load the playlist
 bool load_playlist(PreSavedPlaylist *playlist)
 {
@@ -143,6 +142,7 @@ void save_settings(
     const char *login_username_logged_in,
     const char *login_password_logged_out,
     const char *change_password_logged_in,
+    const char *change_bio_logged_in,
     const char *is_logged_in)
 {
     // Create the directory for saving settings
@@ -219,6 +219,14 @@ void save_settings(
         FURI_LOG_E(TAG, "Failed to write is_logged_in");
     }
 
+    // Save the change_bio_logged_in length and data
+    size_t change_bio_length = strlen(change_bio_logged_in) + 1; // Include null terminator
+    if (storage_file_write(file, &change_bio_length, sizeof(size_t)) != sizeof(size_t) ||
+        storage_file_write(file, change_bio_logged_in, change_bio_length) != change_bio_length)
+    {
+        FURI_LOG_E(TAG, "Failed to write change_bio_logged_in");
+    }
+
     storage_file_close(file);
     storage_file_free(file);
     furi_record_close(RECORD_STORAGE);
@@ -237,6 +245,8 @@ bool load_settings(
     size_t password_out_size,
     char *change_password_logged_in,
     size_t change_password_size,
+    char *change_bio_logged_in,
+    size_t change_bio_size,
     char *is_logged_in,
     size_t is_logged_in_size)
 {
@@ -363,6 +373,22 @@ bool load_settings(
         is_logged_in[is_logged_in_length - 1] = '\0'; // Ensure null-termination
     }
 
+    // Load the change_bio_logged_in
+    size_t change_bio_length;
+    if (storage_file_read(file, &change_bio_length, sizeof(size_t)) != sizeof(size_t) || change_bio_length > change_bio_size ||
+        storage_file_read(file, change_bio_logged_in, change_bio_length) != change_bio_length)
+    {
+        FURI_LOG_E(TAG, "Failed to read change_bio_logged_in");
+        // storage_file_close(file);
+        // storage_file_free(file);
+        // furi_record_close(RECORD_STORAGE);
+        //  return false;
+    }
+    else
+    {
+        change_bio_logged_in[change_bio_length - 1] = '\0'; // Ensure null-termination
+    }
+
     storage_file_close(file);
     storage_file_free(file);
     furi_record_close(RECORD_STORAGE);

+ 3 - 0
flip_storage/flip_social_storage.h

@@ -16,6 +16,7 @@ void save_settings(
     const char *login_username_logged_in,
     const char *login_password_logged_out,
     const char *change_password_logged_in,
+    const char *change_bio_logged_in,
     const char *is_logged_in);
 
 bool load_settings(
@@ -31,6 +32,8 @@ bool load_settings(
     size_t password_out_size,
     char *change_password_logged_in,
     size_t change_password_size,
+    char *change_bio_logged_in,
+    size_t change_bio_size,
     char *is_logged_in,
     size_t is_logged_in_size);