flip_trader_callback.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #ifndef FLIP_TRADER_CALLBACK_H
  2. #define FLIP_TRADER_CALLBACK_H
  3. #define MAX_TOKENS 32 // Adjust based on expected JSON size (25)
  4. // hold the price of the asset
  5. static char asset_price[64];
  6. static bool sent_get_request = false;
  7. static bool get_request_success = false;
  8. static bool request_processed = false;
  9. void flip_trader_request_error(Canvas *canvas)
  10. {
  11. if (fhttp.received_data == NULL)
  12. {
  13. if (fhttp.last_response != NULL)
  14. {
  15. if (strstr(fhttp.last_response, "[ERROR] Not connected to Wifi. Failed to reconnect.") != NULL)
  16. {
  17. canvas_clear(canvas);
  18. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  19. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  20. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  21. }
  22. else if (strstr(fhttp.last_response, "[ERROR] Failed to connect to Wifi.") != NULL)
  23. {
  24. canvas_clear(canvas);
  25. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  26. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  27. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  28. }
  29. else if (strstr(fhttp.last_response, "[ERROR] WiFi SSID or Password is empty") != NULL)
  30. {
  31. canvas_clear(canvas);
  32. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  33. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  34. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  35. }
  36. else
  37. {
  38. canvas_clear(canvas);
  39. FURI_LOG_E(TAG, "Received an error: %s", fhttp.last_response);
  40. canvas_draw_str(canvas, 0, 10, "[ERROR] Unusual error...");
  41. canvas_draw_str(canvas, 0, 60, "Press BACK and retry.");
  42. }
  43. }
  44. else
  45. {
  46. canvas_clear(canvas);
  47. canvas_draw_str(canvas, 0, 10, "[ERROR] Unknown error.");
  48. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  49. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  50. }
  51. }
  52. else
  53. {
  54. canvas_clear(canvas);
  55. canvas_draw_str(canvas, 0, 10, "Failed to receive data.");
  56. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  57. }
  58. }
  59. static bool send_price_request()
  60. {
  61. if (!sent_get_request && fhttp.state == IDLE)
  62. {
  63. sent_get_request = true;
  64. char url[128] = {0};
  65. snprintf(url, 128, "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=%s&apikey=2X90WLEFMP43OJKE", asset_names[asset_index]);
  66. get_request_success = flipper_http_get_request_with_headers(url, "{\"Content-Type\": \"application/json\"}");
  67. if (!get_request_success)
  68. {
  69. FURI_LOG_E(TAG, "Failed to send GET request");
  70. return false;
  71. }
  72. fhttp.state = RECEIVING;
  73. }
  74. return true;
  75. }
  76. static void process_asset_price()
  77. {
  78. if (!request_processed && fhttp.received_data != NULL)
  79. {
  80. request_processed = true;
  81. char *global_quote = get_json_value("Global Quote", fhttp.received_data, MAX_TOKENS);
  82. if (global_quote == NULL)
  83. {
  84. FURI_LOG_E(TAG, "Failed to get Global Quote");
  85. return;
  86. }
  87. char *price = get_json_value("05. price", global_quote, MAX_TOKENS);
  88. if (price == NULL)
  89. {
  90. FURI_LOG_E(TAG, "Failed to get price");
  91. return;
  92. }
  93. // store the price "Asset: $price"
  94. snprintf(asset_price, 64, "%s: $%s", asset_names[asset_index], price);
  95. fhttp.state = IDLE;
  96. }
  97. else if (!request_processed && fhttp.received_data == NULL)
  98. {
  99. request_processed = true;
  100. // store an error message instead of the price
  101. snprintf(asset_price, 64, "Failed. Update WiFi settings.");
  102. fhttp.state = ISSUE;
  103. }
  104. }
  105. // Callback for drawing the main screen
  106. static void flip_trader_view_draw_callback(Canvas *canvas, void *model)
  107. {
  108. if (!canvas)
  109. {
  110. return;
  111. }
  112. UNUSED(model);
  113. canvas_set_font(canvas, FontSecondary);
  114. if (fhttp.state == INACTIVE)
  115. {
  116. canvas_draw_str(canvas, 0, 7, "Wifi Dev Board disconnected.");
  117. canvas_draw_str(canvas, 0, 17, "Please connect to the board.");
  118. canvas_draw_str(canvas, 0, 32, "If your board is connected,");
  119. canvas_draw_str(canvas, 0, 42, "make sure you have flashed");
  120. canvas_draw_str(canvas, 0, 52, "your WiFi Devboard with the");
  121. canvas_draw_str(canvas, 0, 62, "latest FlipperHTTP flash.");
  122. return;
  123. }
  124. canvas_draw_str(canvas, 0, 10, "Loading...");
  125. // canvas_draw_str(canvas, 0, 10, asset_names[asset_index]);
  126. // start the process
  127. if (!send_price_request())
  128. {
  129. flip_trader_request_error(canvas);
  130. }
  131. // wait until the request is processed
  132. if (!sent_get_request || !get_request_success || fhttp.state == RECEIVING)
  133. {
  134. return;
  135. }
  136. // check status
  137. if (fhttp.state == ISSUE || fhttp.received_data == NULL)
  138. {
  139. flip_trader_request_error(canvas);
  140. }
  141. // success, process the data
  142. process_asset_price();
  143. canvas_clear(canvas);
  144. canvas_draw_str(canvas, 0, 10, asset_price);
  145. }
  146. // Input callback for the view (async input handling)
  147. bool flip_trader_view_input_callback(InputEvent *event, void *context)
  148. {
  149. FlipTraderApp *app = (FlipTraderApp *)context;
  150. if (event->type == InputTypePress && event->key == InputKeyBack)
  151. {
  152. // Exit the app when the back button is pressed
  153. view_dispatcher_stop(app->view_dispatcher);
  154. return true;
  155. }
  156. return false;
  157. }
  158. static void callback_submenu_choices(void *context, uint32_t index)
  159. {
  160. FlipTraderApp *app = (FlipTraderApp *)context;
  161. if (!app)
  162. {
  163. FURI_LOG_E(TAG, "FlipTraderApp is NULL");
  164. return;
  165. }
  166. switch (index)
  167. {
  168. // view the assets submenu
  169. case FlipTradeSubmenuIndexAssets:
  170. view_dispatcher_switch_to_view(app->view_dispatcher, FlipTraderViewAssetsSubmenu);
  171. break;
  172. // view the about screen
  173. case FlipTraderSubmenuIndexAbout:
  174. view_dispatcher_switch_to_view(app->view_dispatcher, FlipTraderViewAbout);
  175. break;
  176. // view the wifi settings screen
  177. case FlipTraderSubmenuIndexSettings:
  178. view_dispatcher_switch_to_view(app->view_dispatcher, FlipTraderViewWiFiSettings);
  179. break;
  180. default:
  181. // handle FlipTraderSubmenuIndexAssetStartIndex + index
  182. if (index >= FlipTraderSubmenuIndexAssetStartIndex)
  183. {
  184. asset_index = index - FlipTraderSubmenuIndexAssetStartIndex;
  185. view_dispatcher_switch_to_view(app->view_dispatcher, FlipTraderViewMain);
  186. }
  187. else
  188. {
  189. FURI_LOG_E(TAG, "Unknown submenu index");
  190. }
  191. break;
  192. }
  193. }
  194. static void text_updated_ssid(void *context)
  195. {
  196. FlipTraderApp *app = (FlipTraderApp *)context;
  197. if (!app)
  198. {
  199. FURI_LOG_E(TAG, "FlipTraderApp is NULL");
  200. return;
  201. }
  202. // store the entered text
  203. strncpy(app->uart_text_input_buffer_ssid, app->uart_text_input_temp_buffer_ssid, app->uart_text_input_buffer_size_ssid);
  204. // Ensure null-termination
  205. app->uart_text_input_buffer_ssid[app->uart_text_input_buffer_size_ssid - 1] = '\0';
  206. // update the variable item text
  207. if (app->variable_item_ssid)
  208. {
  209. variable_item_set_current_value_text(app->variable_item_ssid, app->uart_text_input_buffer_ssid);
  210. }
  211. // save settings
  212. save_settings(app->uart_text_input_buffer_ssid, app->uart_text_input_buffer_password);
  213. // save wifi settings to devboard
  214. if (strlen(app->uart_text_input_buffer_ssid) > 0 && strlen(app->uart_text_input_buffer_password) > 0)
  215. {
  216. if (!flipper_http_save_wifi(app->uart_text_input_buffer_ssid, app->uart_text_input_buffer_password))
  217. {
  218. FURI_LOG_E(TAG, "Failed to save wifi settings");
  219. }
  220. }
  221. // switch to the settings view
  222. view_dispatcher_switch_to_view(app->view_dispatcher, FlipTraderViewWiFiSettings);
  223. }
  224. static void text_updated_password(void *context)
  225. {
  226. FlipTraderApp *app = (FlipTraderApp *)context;
  227. if (!app)
  228. {
  229. FURI_LOG_E(TAG, "FlipTraderApp is NULL");
  230. return;
  231. }
  232. // store the entered text
  233. strncpy(app->uart_text_input_buffer_password, app->uart_text_input_temp_buffer_password, app->uart_text_input_buffer_size_password);
  234. // Ensure null-termination
  235. app->uart_text_input_buffer_password[app->uart_text_input_buffer_size_password - 1] = '\0';
  236. // update the variable item text
  237. if (app->variable_item_password)
  238. {
  239. variable_item_set_current_value_text(app->variable_item_password, app->uart_text_input_buffer_password);
  240. }
  241. // save settings
  242. save_settings(app->uart_text_input_buffer_ssid, app->uart_text_input_buffer_password);
  243. // save wifi settings to devboard
  244. if (strlen(app->uart_text_input_buffer_ssid) > 0 && strlen(app->uart_text_input_buffer_password) > 0)
  245. {
  246. if (!flipper_http_save_wifi(app->uart_text_input_buffer_ssid, app->uart_text_input_buffer_password))
  247. {
  248. FURI_LOG_E(TAG, "Failed to save wifi settings");
  249. }
  250. }
  251. // switch to the settings view
  252. view_dispatcher_switch_to_view(app->view_dispatcher, FlipTraderViewWiFiSettings);
  253. }
  254. static uint32_t callback_to_submenu(void *context)
  255. {
  256. if (!context)
  257. {
  258. FURI_LOG_E(TAG, "Context is NULL");
  259. return VIEW_NONE;
  260. }
  261. UNUSED(context);
  262. sent_get_request = false;
  263. get_request_success = false;
  264. request_processed = false;
  265. asset_index = 0;
  266. return FlipTraderViewMainSubmenu;
  267. }
  268. static uint32_t callback_to_wifi_settings(void *context)
  269. {
  270. if (!context)
  271. {
  272. FURI_LOG_E(TAG, "Context is NULL");
  273. return VIEW_NONE;
  274. }
  275. UNUSED(context);
  276. return FlipTraderViewWiFiSettings;
  277. }
  278. static uint32_t callback_to_assets_submenu(void *context)
  279. {
  280. if (!context)
  281. {
  282. FURI_LOG_E(TAG, "Context is NULL");
  283. return VIEW_NONE;
  284. }
  285. UNUSED(context);
  286. sent_get_request = false;
  287. get_request_success = false;
  288. request_processed = false;
  289. asset_index = 0;
  290. return FlipTraderViewAssetsSubmenu;
  291. }
  292. static void settings_item_selected(void *context, uint32_t index)
  293. {
  294. FlipTraderApp *app = (FlipTraderApp *)context;
  295. if (!app)
  296. {
  297. FURI_LOG_E(TAG, "FlipTraderApp is NULL");
  298. return;
  299. }
  300. switch (index)
  301. {
  302. case 0: // Input SSID
  303. view_dispatcher_switch_to_view(app->view_dispatcher, FlipTraderViewTextInputSSID);
  304. break;
  305. case 1: // Input Password
  306. view_dispatcher_switch_to_view(app->view_dispatcher, FlipTraderViewTextInputPassword);
  307. break;
  308. default:
  309. FURI_LOG_E(TAG, "Unknown configuration item index");
  310. break;
  311. }
  312. }
  313. #endif // FLIP_TRADER_CALLBACK_H