flip_social_explore.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #ifndef FLIP_SOCIAL_EXPLORE_H
  2. #define FLIP_SOCIAL_EXPLORE_H
  3. static bool flip_social_explore_alloc()
  4. {
  5. // Allocate memory for each username only if not already allocated
  6. for (size_t i = 0; i < MAX_EXPLORE_USERS; i++)
  7. {
  8. if (app_instance->flip_social_explore.usernames[i] == NULL)
  9. {
  10. app_instance->flip_social_explore.usernames[i] = malloc(MAX_USER_LENGTH);
  11. if (app_instance->flip_social_explore.usernames[i] == NULL)
  12. {
  13. FURI_LOG_E(TAG, "Failed to allocate memory for username %zu", i);
  14. return false; // Return false on memory allocation failure
  15. }
  16. }
  17. }
  18. return true;
  19. }
  20. static void flip_social_free_explore()
  21. {
  22. if (!app_instance)
  23. {
  24. FURI_LOG_E(TAG, "App instance is NULL");
  25. return;
  26. }
  27. for (int i = 0; i < app_instance->flip_social_explore.count; i++)
  28. {
  29. free(app_instance->flip_social_explore.usernames[i]);
  30. }
  31. }
  32. // for now we're just listing the current users
  33. // as the feed is upgraded, then we can port more to the explore view
  34. static bool flip_social_get_explore()
  35. {
  36. // will return true unless the devboard is not connected
  37. bool success = flipper_http_get_request_with_headers("https://www.flipsocial.net/api/user/users/", jsmn("Content-Type", "application/json"));
  38. if (!success)
  39. {
  40. FURI_LOG_E(TAG, "Failed to send HTTP request for explore");
  41. return false;
  42. }
  43. fhttp.state = RECEIVING;
  44. return true;
  45. }
  46. static bool flip_social_parse_json_explore()
  47. {
  48. if (fhttp.received_data == NULL)
  49. {
  50. FURI_LOG_E(TAG, "No data received.");
  51. return false;
  52. }
  53. // Allocate memory for each username only if not already allocated
  54. if (!flip_social_explore_alloc())
  55. {
  56. FURI_LOG_E(TAG, "Failed to allocate memory for explore usernames.");
  57. return false;
  58. }
  59. // Remove newlines
  60. char *pos = fhttp.received_data;
  61. while ((pos = strchr(pos, '\n')) != NULL)
  62. {
  63. *pos = ' ';
  64. }
  65. // Initialize explore count
  66. app_instance->flip_social_explore.count = 0;
  67. // Extract the users array from the JSON
  68. char *json_users = get_json_value("users", fhttp.received_data, MAX_TOKENS);
  69. if (json_users == NULL)
  70. {
  71. FURI_LOG_E(TAG, "Failed to parse users array.");
  72. return false;
  73. }
  74. // Manual tokenization for comma-separated values
  75. char *start = json_users + 1; // Skip the opening bracket
  76. char *end;
  77. while ((end = strchr(start, ',')) != NULL && app_instance->flip_social_explore.count < MAX_EXPLORE_USERS)
  78. {
  79. *end = '\0'; // Null-terminate the current token
  80. // Remove quotes
  81. if (*start == '"')
  82. start++;
  83. if (*(end - 1) == '"')
  84. *(end - 1) = '\0';
  85. // Copy username to pre-allocated memory
  86. strncpy(app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count], start, MAX_USER_LENGTH - 1);
  87. app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
  88. app_instance->flip_social_explore.count++;
  89. start = end + 1;
  90. }
  91. // Handle the last token
  92. if (*start != '\0' && app_instance->flip_social_explore.count < MAX_EXPLORE_USERS)
  93. {
  94. if (*start == '"')
  95. start++;
  96. if (*(start + strlen(start) - 1) == ']')
  97. *(start + strlen(start) - 1) = '\0';
  98. if (*(start + strlen(start) - 1) == '"')
  99. *(start + strlen(start) - 1) = '\0';
  100. strncpy(app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count], start, MAX_USER_LENGTH - 1);
  101. app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.count][MAX_USER_LENGTH - 1] = '\0'; // Ensure null termination
  102. app_instance->flip_social_explore.count++;
  103. }
  104. // Add submenu items for the users
  105. submenu_reset(app_instance->submenu_explore);
  106. submenu_set_header(app_instance->submenu_explore, "Explore");
  107. for (int i = 0; i < app_instance->flip_social_explore.count; i++)
  108. {
  109. submenu_add_item(app_instance->submenu_explore, app_instance->flip_social_explore.usernames[i], FlipSocialSubmenuExploreIndexStartIndex + i, flip_social_callback_submenu_choices, app_instance);
  110. }
  111. // Free the json_users
  112. free(json_users);
  113. return true;
  114. }
  115. #endif // FLIP_SOCIAL_EXPLORE_H