flip_library_callback.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. #include <callback/flip_library_callback.h>
  2. uint32_t random_facts_index = 0;
  3. bool sent_random_fact_request = false;
  4. bool random_fact_request_success = false;
  5. bool random_fact_request_success_all = false;
  6. char* random_fact = NULL;
  7. // Parse JSON to find the "text" key
  8. char* flip_library_parse_random_fact() {
  9. return get_json_value("text", fhttp.last_response, 128);
  10. }
  11. char* flip_library_parse_cat_fact() {
  12. return get_json_value("fact", fhttp.last_response, 128);
  13. }
  14. char* flip_library_parse_dog_fact() {
  15. return get_json_array_value("facts", 0, fhttp.last_response, 256);
  16. }
  17. char* flip_library_parse_quote() {
  18. // remove [ and ] from the start and end of the string
  19. char* response = fhttp.last_response;
  20. if(response[0] == '[') {
  21. response++;
  22. }
  23. if(response[strlen(response) - 1] == ']') {
  24. response[strlen(response) - 1] = '\0';
  25. }
  26. // remove white space from both sides
  27. while(response[0] == ' ') {
  28. response++;
  29. }
  30. while(response[strlen(response) - 1] == ' ') {
  31. response[strlen(response) - 1] = '\0';
  32. }
  33. return get_json_value("q", response, 128);
  34. }
  35. char* flip_library_parse_dictionary() {
  36. return get_json_value("definition", fhttp.last_response, 16);
  37. }
  38. void flip_library_request_error(Canvas* canvas) {
  39. if(fhttp.last_response == NULL) {
  40. if(fhttp.last_response != NULL) {
  41. if(strstr(fhttp.last_response, "[ERROR] Not connected to Wifi. Failed to reconnect.") !=
  42. NULL) {
  43. canvas_clear(canvas);
  44. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  45. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  46. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  47. } else if(strstr(fhttp.last_response, "[ERROR] Failed to connect to Wifi.") != NULL) {
  48. canvas_clear(canvas);
  49. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  50. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  51. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  52. } else {
  53. canvas_clear(canvas);
  54. FURI_LOG_E(TAG, "Received an error: %s", fhttp.last_response);
  55. canvas_draw_str(canvas, 0, 10, "[ERROR] Unusual error...");
  56. canvas_draw_str(canvas, 0, 60, "Press BACK and retry.");
  57. }
  58. } else {
  59. canvas_clear(canvas);
  60. canvas_draw_str(canvas, 0, 10, "[ERROR] Unknown error.");
  61. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  62. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  63. }
  64. } else {
  65. canvas_clear(canvas);
  66. canvas_draw_str(canvas, 0, 10, "Failed to receive data.");
  67. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  68. }
  69. }
  70. void flip_library_draw_fact(char* message, Widget** widget) {
  71. if(app_instance == NULL) {
  72. FURI_LOG_E(TAG, "App instance is NULL");
  73. return;
  74. }
  75. widget_reset(*widget);
  76. uint32_t fact_length = strlen(message); // Length of the message
  77. uint32_t i = 0; // Index tracker
  78. uint32_t formatted_index = 0; // Tracker for where we are in the formatted message
  79. char* formatted_message; // Buffer to hold the final formatted message
  80. if(!easy_flipper_set_buffer(&formatted_message, fact_length * 2 + 1)) {
  81. return;
  82. }
  83. while(i < fact_length) {
  84. uint32_t max_line_length = 29; // Maximum characters per line
  85. uint32_t remaining_length = fact_length - i; // Remaining characters
  86. uint32_t line_length = (remaining_length < max_line_length) ? remaining_length :
  87. max_line_length;
  88. // Temporary buffer to hold the current line
  89. char fact_line[30];
  90. strncpy(fact_line, message + i, line_length);
  91. fact_line[line_length] = '\0';
  92. // Check if the line ends in the middle of a word and adjust accordingly
  93. if(line_length == 29 && message[i + line_length] != '\0' &&
  94. message[i + line_length] != ' ') {
  95. // Find the last space within the 30-character segment
  96. char* last_space = strrchr(fact_line, ' ');
  97. if(last_space != NULL) {
  98. // Adjust the line length to avoid cutting the word
  99. line_length = last_space - fact_line;
  100. fact_line[line_length] = '\0'; // Null-terminate at the space
  101. }
  102. }
  103. // Manually copy the fixed line into the formatted_message buffer
  104. for(uint32_t j = 0; j < line_length; j++) {
  105. formatted_message[formatted_index++] = fact_line[j];
  106. }
  107. // Add a newline character for line spacing
  108. formatted_message[formatted_index++] = '\n';
  109. // Move i forward to the start of the next word
  110. i += line_length;
  111. // Skip spaces at the beginning of the next line
  112. while(message[i] == ' ') {
  113. i++;
  114. }
  115. }
  116. // Add the formatted message to the widget
  117. widget_add_text_scroll_element(*widget, 0, 0, 128, 64, formatted_message);
  118. }
  119. // Callback for drawing the main screen
  120. void view_draw_callback_random_facts(Canvas* canvas, void* model) {
  121. if(!canvas || !app_instance) {
  122. return;
  123. }
  124. UNUSED(model);
  125. canvas_set_font(canvas, FontSecondary);
  126. if(fhttp.state == INACTIVE) {
  127. canvas_draw_str(canvas, 0, 7, "Wifi Dev Board disconnected.");
  128. canvas_draw_str(canvas, 0, 17, "Please connect to the board.");
  129. canvas_draw_str(canvas, 0, 32, "If your board is connected,");
  130. canvas_draw_str(canvas, 0, 42, "make sure you have flashed");
  131. canvas_draw_str(canvas, 0, 52, "your WiFi Devboard with the");
  132. canvas_draw_str(canvas, 0, 62, "latest FlipperHTTP flash.");
  133. return;
  134. }
  135. // Cats
  136. if(random_facts_index == FlipLibrarySubmenuIndexRandomFactsCats) {
  137. canvas_draw_str(canvas, 0, 7, "Random Cat Fact");
  138. canvas_draw_str(canvas, 0, 15, "Loading...");
  139. if(!sent_random_fact_request) {
  140. sent_random_fact_request = true;
  141. random_fact_request_success = flipper_http_get_request_with_headers(
  142. "https://catfact.ninja/fact", "{\"Content-Type\":\"application/json\"}");
  143. if(!random_fact_request_success) {
  144. FURI_LOG_E(TAG, "Failed to send request");
  145. flip_library_request_error(canvas);
  146. return;
  147. }
  148. fhttp.state = RECEIVING;
  149. } else {
  150. if(fhttp.state == RECEIVING) {
  151. canvas_draw_str(canvas, 0, 22, "Receiving...");
  152. return;
  153. }
  154. // check status
  155. else if(fhttp.state == ISSUE || !random_fact_request_success) {
  156. flip_library_request_error(canvas);
  157. } else if(
  158. fhttp.state == IDLE && fhttp.last_response != NULL &&
  159. !random_fact_request_success_all) {
  160. canvas_draw_str(canvas, 0, 22, "Processing...");
  161. // success
  162. // check status
  163. // unnecessary check
  164. if(fhttp.state == ISSUE || fhttp.last_response == NULL) {
  165. flip_library_request_error(canvas);
  166. FURI_LOG_E(TAG, "HTTP request failed or received data is NULL");
  167. return;
  168. } else if(!random_fact_request_success_all) {
  169. random_fact = flip_library_parse_cat_fact();
  170. if(random_fact == NULL) {
  171. flip_library_request_error(canvas);
  172. fhttp.state = ISSUE;
  173. return;
  174. }
  175. // Mark success
  176. random_fact_request_success_all = true;
  177. // draw random facts
  178. flip_library_draw_fact(random_fact, &app_instance->widget_random_fact);
  179. // go to random facts widget
  180. view_dispatcher_switch_to_view(
  181. app_instance->view_dispatcher, FlipLibraryViewRandomFactWidget);
  182. }
  183. }
  184. // likely redundant but just in case
  185. else if(fhttp.state == IDLE && random_fact_request_success_all && random_fact != NULL) {
  186. flip_library_draw_fact(random_fact, &app_instance->widget_random_fact);
  187. // go to random facts widget
  188. view_dispatcher_switch_to_view(
  189. app_instance->view_dispatcher, FlipLibraryViewRandomFactWidget);
  190. } else // handle weird scenarios
  191. {
  192. // if received data isnt NULL
  193. if(fhttp.last_response != NULL) {
  194. // parse json to find the text key
  195. random_fact = flip_library_parse_cat_fact();
  196. if(random_fact == NULL) {
  197. flip_library_request_error(canvas);
  198. fhttp.state = ISSUE;
  199. return;
  200. }
  201. }
  202. }
  203. }
  204. }
  205. // Dogs
  206. else if(random_facts_index == FlipLibrarySubmenuIndexRandomFactsDogs) {
  207. canvas_draw_str(canvas, 0, 7, "Random Dog Fact");
  208. canvas_draw_str(canvas, 0, 15, "Loading...");
  209. if(!sent_random_fact_request) {
  210. sent_random_fact_request = true;
  211. random_fact_request_success = flipper_http_get_request_with_headers(
  212. "https://dog-api.kinduff.com/api/facts",
  213. "{\"Content-Type\":\"application/json\"}");
  214. if(!random_fact_request_success) {
  215. FURI_LOG_E(TAG, "Failed to send request");
  216. flip_library_request_error(canvas);
  217. fhttp.state = ISSUE;
  218. return;
  219. }
  220. fhttp.state = RECEIVING;
  221. } else {
  222. if(fhttp.state == RECEIVING) {
  223. canvas_draw_str(canvas, 0, 22, "Receiving...");
  224. return;
  225. }
  226. // check status
  227. else if(fhttp.state == ISSUE || !random_fact_request_success) {
  228. flip_library_request_error(canvas);
  229. } else if(
  230. fhttp.state == IDLE && fhttp.last_response != NULL &&
  231. !random_fact_request_success_all) {
  232. canvas_draw_str(canvas, 0, 22, "Processing...");
  233. // success
  234. // check status
  235. // unnecessary check
  236. if(fhttp.state == ISSUE || fhttp.last_response == NULL) {
  237. flip_library_request_error(canvas);
  238. FURI_LOG_E(TAG, "HTTP request failed or received data is NULL");
  239. return;
  240. } else if(!random_fact_request_success_all) {
  241. random_fact = flip_library_parse_dog_fact();
  242. if(random_fact == NULL) {
  243. flip_library_request_error(canvas);
  244. fhttp.state = ISSUE;
  245. return;
  246. }
  247. // Mark success
  248. random_fact_request_success_all = true;
  249. // draw random facts
  250. flip_library_draw_fact(random_fact, &app_instance->widget_random_fact);
  251. // go to random facts widget
  252. view_dispatcher_switch_to_view(
  253. app_instance->view_dispatcher, FlipLibraryViewRandomFactWidget);
  254. }
  255. }
  256. // likely redundant but just in case
  257. else if(fhttp.state == IDLE && random_fact_request_success_all && random_fact != NULL) {
  258. flip_library_draw_fact(random_fact, &app_instance->widget_random_fact);
  259. // go to random facts widget
  260. view_dispatcher_switch_to_view(
  261. app_instance->view_dispatcher, FlipLibraryViewRandomFactWidget);
  262. } else // handle weird scenarios
  263. {
  264. // if received data isnt NULL
  265. if(fhttp.last_response != NULL) {
  266. // parse json to find the text key
  267. random_fact = flip_library_parse_cat_fact();
  268. if(random_fact == NULL) {
  269. flip_library_request_error(canvas);
  270. fhttp.state = ISSUE;
  271. return;
  272. }
  273. }
  274. }
  275. }
  276. }
  277. // Quotes
  278. else if(random_facts_index == FlipLibrarySubmenuIndexRandomFactsQuotes) {
  279. canvas_draw_str(canvas, 0, 7, "Random Quote");
  280. canvas_draw_str(canvas, 0, 15, "Loading...");
  281. if(!sent_random_fact_request) {
  282. sent_random_fact_request = true;
  283. random_fact_request_success =
  284. flipper_http_get_request("https://zenquotes.io/api/random");
  285. if(!random_fact_request_success) {
  286. FURI_LOG_E(TAG, "Failed to send request");
  287. flip_library_request_error(canvas);
  288. return;
  289. }
  290. fhttp.state = RECEIVING;
  291. } else {
  292. if(fhttp.state == RECEIVING) {
  293. canvas_draw_str(canvas, 0, 22, "Receiving...");
  294. return;
  295. }
  296. // check status
  297. else if(fhttp.state == ISSUE || !random_fact_request_success) {
  298. flip_library_request_error(canvas);
  299. } else if(
  300. fhttp.state == IDLE && fhttp.last_response != NULL &&
  301. !random_fact_request_success_all) {
  302. canvas_draw_str(canvas, 0, 22, "Processing...");
  303. // success
  304. // check status
  305. // unnecessary check
  306. if(fhttp.state == ISSUE || fhttp.last_response == NULL) {
  307. flip_library_request_error(canvas);
  308. FURI_LOG_E(TAG, "HTTP request failed or received data is NULL");
  309. return;
  310. } else if(!random_fact_request_success_all) {
  311. random_fact = flip_library_parse_quote();
  312. if(random_fact == NULL) {
  313. flip_library_request_error(canvas);
  314. fhttp.state = ISSUE;
  315. return;
  316. }
  317. // Mark success
  318. random_fact_request_success_all = true;
  319. // draw random facts
  320. flip_library_draw_fact(random_fact, &app_instance->widget_random_fact);
  321. // go to random facts widget
  322. view_dispatcher_switch_to_view(
  323. app_instance->view_dispatcher, FlipLibraryViewRandomFactWidget);
  324. }
  325. }
  326. // likely redundant but just in case
  327. else if(fhttp.state == IDLE && random_fact_request_success_all && random_fact != NULL) {
  328. flip_library_draw_fact(random_fact, &app_instance->widget_random_fact);
  329. // go to random facts widget
  330. view_dispatcher_switch_to_view(
  331. app_instance->view_dispatcher, FlipLibraryViewRandomFactWidget);
  332. } else // handle weird scenarios
  333. {
  334. // if received data isnt NULL
  335. if(fhttp.last_response != NULL) {
  336. // parse json to find the text key
  337. random_fact = flip_library_parse_quote();
  338. if(random_fact == NULL) {
  339. flip_library_request_error(canvas);
  340. fhttp.state = ISSUE;
  341. return;
  342. }
  343. }
  344. }
  345. }
  346. }
  347. // All Random Facts
  348. else if(random_facts_index == FlipLibrarySubmenuIndexRandomFactsAll) {
  349. canvas_draw_str(canvas, 0, 10, "Random Fact");
  350. canvas_set_font(canvas, FontSecondary);
  351. canvas_draw_str(canvas, 0, 20, "Loading...");
  352. if(!sent_random_fact_request) {
  353. sent_random_fact_request = true;
  354. random_fact_request_success =
  355. flipper_http_get_request("https://uselessfacts.jsph.pl/api/v2/facts/random");
  356. if(!random_fact_request_success) {
  357. FURI_LOG_E(TAG, "Failed to send request");
  358. fhttp.state = ISSUE;
  359. return;
  360. }
  361. fhttp.state = RECEIVING;
  362. } else {
  363. // check status
  364. if(fhttp.state == RECEIVING) {
  365. canvas_draw_str(canvas, 0, 30, "Receiving...");
  366. return;
  367. }
  368. // check status
  369. else if(fhttp.state == ISSUE || !random_fact_request_success) {
  370. flip_library_request_error(canvas);
  371. return;
  372. } else if(
  373. fhttp.state == IDLE && fhttp.last_response != NULL &&
  374. !random_fact_request_success_all) {
  375. canvas_draw_str(canvas, 0, 30, "Processing...");
  376. // success
  377. // check status
  378. if(fhttp.state == ISSUE || fhttp.last_response == NULL) {
  379. flip_library_request_error(canvas);
  380. FURI_LOG_E(TAG, "HTTP request failed or received data is NULL");
  381. return;
  382. }
  383. // parse json to find the text key
  384. random_fact = flip_library_parse_random_fact();
  385. if(random_fact == NULL) {
  386. flip_library_request_error(canvas);
  387. fhttp.state = ISSUE;
  388. return;
  389. }
  390. // Mark success
  391. random_fact_request_success_all = true;
  392. // draw random facts
  393. flip_library_draw_fact(random_fact, &app_instance->widget_random_fact);
  394. // go to random facts widget
  395. view_dispatcher_switch_to_view(
  396. app_instance->view_dispatcher, FlipLibraryViewRandomFactWidget);
  397. }
  398. // likely redundant but just in case
  399. else if(fhttp.state == IDLE && random_fact_request_success_all && random_fact != NULL) {
  400. // draw random facts
  401. flip_library_draw_fact(random_fact, &app_instance->widget_random_fact);
  402. // go to random facts widget
  403. view_dispatcher_switch_to_view(
  404. app_instance->view_dispatcher, FlipLibraryViewRandomFactWidget);
  405. } else // handle weird scenarios
  406. {
  407. // if received data isnt NULL
  408. if(fhttp.last_response != NULL) {
  409. // parse json to find the text key
  410. random_fact = flip_library_parse_random_fact();
  411. if(random_fact == NULL) {
  412. flip_library_request_error(canvas);
  413. fhttp.state = ISSUE;
  414. return;
  415. }
  416. }
  417. }
  418. }
  419. } else {
  420. canvas_draw_str(canvas, 0, 7, "Random Fact");
  421. }
  422. }
  423. void view_draw_callback_dictionary_run(Canvas* canvas, void* model) {
  424. if(!canvas || !app_instance || app_instance->uart_text_input_buffer_dictionary == NULL) {
  425. return;
  426. }
  427. UNUSED(model);
  428. canvas_set_font(canvas, FontSecondary);
  429. if(fhttp.state == INACTIVE) {
  430. canvas_draw_str(canvas, 0, 7, "Wifi Dev Board disconnected.");
  431. canvas_draw_str(canvas, 0, 17, "Please connect to the board.");
  432. canvas_draw_str(canvas, 0, 32, "If your board is connected,");
  433. canvas_draw_str(canvas, 0, 42, "make sure you have flashed");
  434. canvas_draw_str(canvas, 0, 52, "your WiFi Devboard with the");
  435. canvas_draw_str(canvas, 0, 62, "latest FlipperHTTP flash.");
  436. return;
  437. }
  438. canvas_draw_str(canvas, 0, 10, "Defining, please wait...");
  439. if(!sent_random_fact_request) {
  440. sent_random_fact_request = true;
  441. char payload[128];
  442. snprintf(
  443. payload,
  444. sizeof(payload),
  445. "{\"word\":\"%s\"}",
  446. app_instance->uart_text_input_buffer_dictionary);
  447. random_fact_request_success = flipper_http_post_request_with_headers(
  448. "https://www.flipsocial.net/api/define/",
  449. "{\"Content-Type\":\"application/json\"}",
  450. payload);
  451. if(!random_fact_request_success) {
  452. FURI_LOG_E(TAG, "Failed to send request");
  453. flip_library_request_error(canvas);
  454. fhttp.state = ISSUE;
  455. return;
  456. }
  457. fhttp.state = RECEIVING;
  458. } else {
  459. // check status
  460. if(fhttp.state == RECEIVING) {
  461. canvas_draw_str(canvas, 0, 20, "Receiving...");
  462. return;
  463. }
  464. // check status
  465. else if(fhttp.state == ISSUE || !random_fact_request_success) {
  466. flip_library_request_error(canvas);
  467. return;
  468. } else if(
  469. fhttp.state == IDLE && fhttp.last_response != NULL &&
  470. !random_fact_request_success_all) {
  471. canvas_draw_str(canvas, 0, 20, "Processing...");
  472. // success
  473. // check status
  474. if(fhttp.state == ISSUE || fhttp.last_response == NULL) {
  475. flip_library_request_error(canvas);
  476. FURI_LOG_E(TAG, "HTTP request failed or received data is NULL");
  477. return;
  478. }
  479. // parse json to find the text key
  480. char* definition = flip_library_parse_dictionary();
  481. if(definition == NULL) {
  482. flip_library_request_error(canvas);
  483. fhttp.state = ISSUE;
  484. return;
  485. }
  486. // Mark success
  487. random_fact_request_success_all = true;
  488. // draw random facts
  489. flip_library_draw_fact(definition, &app_instance->widget_dictionary);
  490. // go to random facts widget
  491. view_dispatcher_switch_to_view(
  492. app_instance->view_dispatcher, FlipLibraryViewDictionaryWidget);
  493. }
  494. // likely redundant but just in case
  495. else if(fhttp.state == IDLE && random_fact_request_success_all && random_fact != NULL) {
  496. // draw random facts
  497. flip_library_draw_fact(random_fact, &app_instance->widget_dictionary);
  498. // go to random facts widget
  499. view_dispatcher_switch_to_view(
  500. app_instance->view_dispatcher, FlipLibraryViewDictionaryWidget);
  501. } else // handle weird scenarios
  502. {
  503. // if received data isnt NULL
  504. if(fhttp.last_response != NULL) {
  505. // parse json to find the text key
  506. char* definition = flip_library_parse_dictionary();
  507. if(definition == NULL) {
  508. flip_library_request_error(canvas);
  509. fhttp.state = ISSUE;
  510. return;
  511. }
  512. // draw random facts
  513. flip_library_draw_fact(definition, &app_instance->widget_dictionary);
  514. // go to random facts widget
  515. view_dispatcher_switch_to_view(
  516. app_instance->view_dispatcher, FlipLibraryViewDictionaryWidget);
  517. free(definition);
  518. return;
  519. }
  520. }
  521. }
  522. }
  523. // Input callback for the view (async input handling)
  524. bool view_input_callback_random_facts(InputEvent* event, void* context) {
  525. if(!event || !context) {
  526. return false;
  527. }
  528. FlipLibraryApp* app = (FlipLibraryApp*)context;
  529. if(event->type == InputTypePress && event->key == InputKeyBack) {
  530. // Exit the app when the back button is pressed
  531. view_dispatcher_stop(app->view_dispatcher);
  532. return true;
  533. }
  534. return false;
  535. }
  536. void callback_submenu_choices(void* context, uint32_t index) {
  537. FlipLibraryApp* app = (FlipLibraryApp*)context;
  538. if(!app) {
  539. FURI_LOG_E(TAG, "FlipLibraryApp is NULL");
  540. return;
  541. }
  542. switch(index) {
  543. case FlipLibrarySubmenuIndexRandomFacts:
  544. random_facts_index = 0;
  545. sent_random_fact_request = false;
  546. random_fact = NULL;
  547. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewRandomFacts);
  548. break;
  549. case FlipLibrarySubmenuIndexAbout:
  550. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewAbout);
  551. break;
  552. case FlipLibrarySubmenuIndexSettings:
  553. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewSettings);
  554. break;
  555. case FlipLibrarySubmenuIndexDictionary:
  556. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewDictionaryTextInput);
  557. break;
  558. case FlipLibrarySubmenuIndexRandomFactsCats:
  559. random_facts_index = FlipLibrarySubmenuIndexRandomFactsCats;
  560. sent_random_fact_request = false;
  561. random_fact = NULL;
  562. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewRandomFactsRun);
  563. break;
  564. case FlipLibrarySubmenuIndexRandomFactsDogs:
  565. random_facts_index = FlipLibrarySubmenuIndexRandomFactsDogs;
  566. sent_random_fact_request = false;
  567. random_fact = NULL;
  568. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewRandomFactsRun);
  569. break;
  570. case FlipLibrarySubmenuIndexRandomFactsQuotes:
  571. random_facts_index = FlipLibrarySubmenuIndexRandomFactsQuotes;
  572. sent_random_fact_request = false;
  573. random_fact = NULL;
  574. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewRandomFactsRun);
  575. break;
  576. case FlipLibrarySubmenuIndexRandomFactsAll:
  577. random_facts_index = FlipLibrarySubmenuIndexRandomFactsAll;
  578. sent_random_fact_request = false;
  579. random_fact = NULL;
  580. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewRandomFactsRun);
  581. break;
  582. default:
  583. break;
  584. }
  585. }
  586. void text_updated_ssid(void* context) {
  587. FlipLibraryApp* app = (FlipLibraryApp*)context;
  588. if(!app) {
  589. FURI_LOG_E(TAG, "FlipLibraryApp is NULL");
  590. return;
  591. }
  592. // store the entered text
  593. strncpy(
  594. app->uart_text_input_buffer_ssid,
  595. app->uart_text_input_temp_buffer_ssid,
  596. app->uart_text_input_buffer_size_ssid);
  597. // Ensure null-termination
  598. app->uart_text_input_buffer_ssid[app->uart_text_input_buffer_size_ssid - 1] = '\0';
  599. // update the variable item text
  600. if(app->variable_item_ssid) {
  601. variable_item_set_current_value_text(
  602. app->variable_item_ssid, app->uart_text_input_buffer_ssid);
  603. }
  604. // save settings
  605. save_settings(app->uart_text_input_buffer_ssid, app->uart_text_input_buffer_password);
  606. // save wifi settings to devboard
  607. if(strlen(app->uart_text_input_buffer_ssid) > 0 &&
  608. strlen(app->uart_text_input_buffer_password) > 0) {
  609. if(!flipper_http_save_wifi(
  610. app->uart_text_input_buffer_ssid, app->uart_text_input_buffer_password)) {
  611. FURI_LOG_E(TAG, "Failed to save wifi settings");
  612. }
  613. }
  614. // switch to the settings view
  615. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewSettings);
  616. }
  617. void text_updated_password(void* context) {
  618. FlipLibraryApp* app = (FlipLibraryApp*)context;
  619. if(!app) {
  620. FURI_LOG_E(TAG, "FlipLibraryApp is NULL");
  621. return;
  622. }
  623. // store the entered text
  624. strncpy(
  625. app->uart_text_input_buffer_password,
  626. app->uart_text_input_temp_buffer_password,
  627. app->uart_text_input_buffer_size_password);
  628. // Ensure null-termination
  629. app->uart_text_input_buffer_password[app->uart_text_input_buffer_size_password - 1] = '\0';
  630. // update the variable item text
  631. if(app->variable_item_password) {
  632. variable_item_set_current_value_text(
  633. app->variable_item_password, app->uart_text_input_buffer_password);
  634. }
  635. // save settings
  636. save_settings(app->uart_text_input_buffer_ssid, app->uart_text_input_buffer_password);
  637. // save wifi settings to devboard
  638. if(strlen(app->uart_text_input_buffer_ssid) > 0 &&
  639. strlen(app->uart_text_input_buffer_password) > 0) {
  640. if(!flipper_http_save_wifi(
  641. app->uart_text_input_buffer_ssid, app->uart_text_input_buffer_password)) {
  642. FURI_LOG_E(TAG, "Failed to save wifi settings");
  643. }
  644. }
  645. // switch to the settings view
  646. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewSettings);
  647. }
  648. void text_updated_dictionary(void* context) {
  649. FlipLibraryApp* app = (FlipLibraryApp*)context;
  650. if(!app) {
  651. FURI_LOG_E(TAG, "FlipLibraryApp is NULL");
  652. return;
  653. }
  654. // store the entered text
  655. strncpy(
  656. app->uart_text_input_buffer_dictionary,
  657. app->uart_text_input_temp_buffer_dictionary,
  658. app->uart_text_input_buffer_size_dictionary);
  659. // Ensure null-termination
  660. app->uart_text_input_buffer_dictionary[app->uart_text_input_buffer_size_dictionary - 1] = '\0';
  661. // switch to the dictionary view
  662. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewDictionaryRun);
  663. }
  664. uint32_t callback_to_submenu(void* context) {
  665. if(!context) {
  666. FURI_LOG_E(TAG, "Context is NULL");
  667. return VIEW_NONE;
  668. }
  669. UNUSED(context);
  670. random_facts_index = 0;
  671. sent_random_fact_request = false;
  672. random_fact_request_success = false;
  673. random_fact_request_success_all = false;
  674. random_fact = NULL;
  675. return FlipLibraryViewSubmenuMain;
  676. }
  677. uint32_t callback_to_wifi_settings(void* context) {
  678. if(!context) {
  679. FURI_LOG_E(TAG, "Context is NULL");
  680. return VIEW_NONE;
  681. }
  682. UNUSED(context);
  683. return FlipLibraryViewSettings;
  684. }
  685. uint32_t callback_to_random_facts(void* context) {
  686. if(!context) {
  687. FURI_LOG_E(TAG, "Context is NULL");
  688. return VIEW_NONE;
  689. }
  690. UNUSED(context);
  691. return FlipLibraryViewRandomFacts;
  692. }
  693. void settings_item_selected(void* context, uint32_t index) {
  694. FlipLibraryApp* app = (FlipLibraryApp*)context;
  695. if(!app) {
  696. FURI_LOG_E(TAG, "FlipLibraryApp is NULL");
  697. return;
  698. }
  699. switch(index) {
  700. case 0: // Input SSID
  701. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewTextInputSSID);
  702. break;
  703. case 1: // Input Password
  704. view_dispatcher_switch_to_view(app->view_dispatcher, FlipLibraryViewTextInputPassword);
  705. break;
  706. default:
  707. FURI_LOG_E(TAG, "Unknown configuration item index");
  708. break;
  709. }
  710. }
  711. /**
  712. * @brief Navigation callback for exiting the application
  713. * @param context The context - unused
  714. * @return next view id (VIEW_NONE to exit the app)
  715. */
  716. uint32_t callback_exit_app(void* context) {
  717. // Exit the application
  718. if(!context) {
  719. FURI_LOG_E(TAG, "Context is NULL");
  720. return VIEW_NONE;
  721. }
  722. UNUSED(context);
  723. return VIEW_NONE; // Return VIEW_NONE to exit the app
  724. }