flip_social_draw.h 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. #ifndef FLIP_SOCIAL_DRAW_H
  2. #define FLIP_SOCIAL_DRAW_H
  3. bool flip_social_sent_login_request = false;
  4. bool flip_social_sent_register_request = false;
  5. bool flip_social_login_success = false;
  6. bool flip_social_register_success = false;
  7. bool flip_social_dialog_shown = false;
  8. bool flip_social_dialog_stop = false;
  9. char *last_explore_response = "";
  10. static bool flip_social_update_friends();
  11. bool flip_social_board_is_active(Canvas *canvas)
  12. {
  13. if (fhttp.state == INACTIVE)
  14. {
  15. canvas_draw_str(canvas, 0, 7, "Wifi Dev Board disconnected.");
  16. canvas_draw_str(canvas, 0, 17, "Please connect to the board.");
  17. canvas_draw_str(canvas, 0, 32, "If your board is connected,");
  18. canvas_draw_str(canvas, 0, 42, "make sure you have flashed");
  19. canvas_draw_str(canvas, 0, 52, "your WiFi Devboard with the");
  20. canvas_draw_str(canvas, 0, 62, "latest FlipperHTTP flash.");
  21. return false;
  22. }
  23. return true;
  24. }
  25. void flip_social_handle_error(Canvas *canvas)
  26. {
  27. if (fhttp.received_data != NULL)
  28. {
  29. if (strstr(fhttp.received_data, "[ERROR] Not connected to Wifi. Failed to reconnect.") != 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 if (strstr(fhttp.received_data, "[ERROR] Failed to connect to Wifi.") != NULL)
  37. {
  38. canvas_clear(canvas);
  39. canvas_draw_str(canvas, 0, 10, "[ERROR] Not connected to Wifi.");
  40. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  41. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  42. }
  43. else
  44. {
  45. canvas_draw_str(canvas, 0, 42, "Failed...");
  46. canvas_draw_str(canvas, 0, 52, "Update your credentials.");
  47. canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
  48. }
  49. }
  50. else
  51. {
  52. canvas_draw_str(canvas, 0, 42, "Failed...");
  53. canvas_draw_str(canvas, 0, 52, "Update your credentials.");
  54. canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
  55. }
  56. }
  57. static void on_input(const void *event, void *ctx)
  58. {
  59. UNUSED(ctx);
  60. InputKey key = ((InputEvent *)event)->key;
  61. InputType type = ((InputEvent *)event)->type;
  62. if (type != InputTypeRelease)
  63. {
  64. return;
  65. }
  66. switch (key)
  67. {
  68. case InputKeyOk:
  69. action = ActionFlip;
  70. break;
  71. case InputKeyBack:
  72. action = ActionBack;
  73. break;
  74. case InputKeyRight:
  75. action = ActionNext;
  76. break;
  77. case InputKeyLeft:
  78. action = ActionPrev;
  79. break;
  80. case InputKeyUp:
  81. action = ActionPrev;
  82. break;
  83. case InputKeyDown:
  84. action = ActionNext;
  85. break;
  86. default:
  87. action = ActionNone;
  88. break;
  89. }
  90. }
  91. // Function to draw the message on the canvas with word wrapping
  92. void draw_user_message(Canvas *canvas, const char *user_message, int x)
  93. {
  94. if (user_message == NULL)
  95. {
  96. FURI_LOG_E(TAG, "User message is NULL.");
  97. return;
  98. }
  99. size_t msg_length = strlen(user_message);
  100. size_t start = 0;
  101. int line_num = 0;
  102. char line[MAX_LINE_LENGTH + 1]; // Buffer for the current line (+1 for null terminator)
  103. while (start < msg_length && line_num < 4)
  104. {
  105. size_t remaining = msg_length - start;
  106. size_t len = (remaining > MAX_LINE_LENGTH) ? MAX_LINE_LENGTH : remaining;
  107. if (remaining > MAX_LINE_LENGTH)
  108. {
  109. // Find the last space within the first 'len' characters
  110. size_t last_space = len;
  111. while (last_space > 0 && user_message[start + last_space - 1] != ' ')
  112. {
  113. last_space--;
  114. }
  115. if (last_space > 0)
  116. {
  117. len = last_space; // Adjust len to the position of the last space
  118. }
  119. }
  120. // Copy the substring to 'line' and null-terminate it
  121. memcpy(line, user_message + start, len);
  122. line[len] = '\0'; // Ensure the string is null-terminated
  123. // Draw the string on the canvas
  124. // Adjust the y-coordinate based on the line number
  125. canvas_draw_str_aligned(canvas, 0, x + line_num * 10, AlignLeft, AlignTop, line);
  126. // Update the start position for the next line
  127. start += len;
  128. // Skip any spaces to avoid leading spaces on the next line
  129. while (start < msg_length && user_message[start] == ' ')
  130. {
  131. start++;
  132. }
  133. // Increment the line number
  134. line_num++;
  135. }
  136. }
  137. static void flip_social_callback_draw_compose(Canvas *canvas, void *model)
  138. {
  139. UNUSED(model);
  140. if (!canvas)
  141. {
  142. FURI_LOG_E(TAG, "Canvas is NULL");
  143. return;
  144. }
  145. if (!app_instance)
  146. {
  147. FURI_LOG_E(TAG, "FlipSocialApp is NULL");
  148. return;
  149. }
  150. char *message = app_instance->pre_saved_messages.messages[app_instance->flip_social_feed.index];
  151. if (!flip_social_dialog_shown)
  152. {
  153. flip_social_dialog_shown = true;
  154. app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
  155. app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
  156. }
  157. draw_user_message(canvas, message, 2);
  158. canvas_draw_icon(canvas, 0, 53, &I_ButtonLeft_4x7);
  159. canvas_draw_str_aligned(canvas, 7, 54, AlignLeft, AlignTop, "Delete");
  160. canvas_draw_icon(canvas, 52, 53, &I_ButtonBACK_10x8);
  161. canvas_draw_str_aligned(canvas, 64, 54, AlignLeft, AlignTop, "Back");
  162. canvas_draw_icon(canvas, 100, 53, &I_ButtonRight_4x7);
  163. canvas_draw_str_aligned(canvas, 107, 54, AlignLeft, AlignTop, "Post");
  164. // handle action
  165. switch (action)
  166. {
  167. case ActionNone:
  168. break;
  169. case ActionBack:
  170. flip_social_dialog_stop = true;
  171. break;
  172. case ActionNext:
  173. // send message
  174. if (message && app_instance->login_username_logged_in)
  175. {
  176. // Send the message
  177. char command[128];
  178. snprintf(command, sizeof(command), "{\"username\":\"%s\",\"content\":\"%s\"}",
  179. app_instance->login_username_logged_in, message);
  180. bool success = flipper_http_post_request_with_headers(
  181. "https://www.flipsocial.net/api/feed/post/",
  182. "{\"Content-Type\":\"application/json\"}",
  183. command);
  184. if (!success)
  185. {
  186. FURI_LOG_E(TAG, "Failed to send HTTP request for feed");
  187. furi_check(success); // Log the error with furi_check
  188. return; // Exit early to avoid further errors
  189. }
  190. fhttp.state = RECEIVING;
  191. furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
  192. }
  193. else
  194. {
  195. FURI_LOG_E(TAG, "Message or username is NULL");
  196. furi_check(false); // Log as an error and return
  197. return;
  198. }
  199. int i = 0;
  200. while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
  201. {
  202. // Wait for the feed to be received
  203. furi_delay_ms(100);
  204. char dots_str[64] = "Receiving";
  205. // Append dots to the string based on the value of i
  206. int dot_count = i % 4;
  207. int len = strlen(dots_str);
  208. snprintf(dots_str + len, sizeof(dots_str) - len, "%.*s", dot_count, "....");
  209. // Draw the resulting string on the canvas
  210. canvas_draw_str(canvas, 0, 30, dots_str);
  211. i++;
  212. }
  213. flip_social_dialog_stop = true;
  214. furi_timer_stop(fhttp.get_timeout_timer);
  215. break;
  216. case ActionPrev:
  217. // delete message
  218. // remove the message from app_instance->pre_saved_messages
  219. app_instance->pre_saved_messages.messages[app_instance->flip_social_feed.index] = NULL;
  220. for (uint32_t i = app_instance->flip_social_feed.index; i < app_instance->pre_saved_messages.count - 1; i++)
  221. {
  222. app_instance->pre_saved_messages.messages[i] = app_instance->pre_saved_messages.messages[i + 1];
  223. }
  224. app_instance->pre_saved_messages.count--;
  225. // add the item to the submenu
  226. submenu_reset(app_instance->submenu_compose);
  227. submenu_add_item(app_instance->submenu_compose, "Add Pre-Save", FlipSocialSubmenuComposeIndexAddPreSave, flip_social_callback_submenu_choices, app_instance);
  228. for (uint32_t i = 0; i < app_instance->pre_saved_messages.count; i++)
  229. {
  230. submenu_add_item(app_instance->submenu_compose, app_instance->pre_saved_messages.messages[i], FlipSocialSubemnuComposeIndexStartIndex + i, flip_social_callback_submenu_choices, app_instance);
  231. }
  232. // save playlist
  233. save_playlist(&app_instance->pre_saved_messages);
  234. flip_social_dialog_stop = true;
  235. break;
  236. default:
  237. action = ActionNone;
  238. break;
  239. }
  240. if (flip_social_dialog_stop)
  241. {
  242. furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
  243. flip_social_dialog_shown = false;
  244. flip_social_dialog_stop = false;
  245. if (action == ActionNext)
  246. {
  247. action = ActionNone;
  248. view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInFeed);
  249. }
  250. else if (action == ActionBack)
  251. {
  252. action = ActionNone;
  253. view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
  254. }
  255. else
  256. {
  257. action = ActionNone;
  258. view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInCompose);
  259. }
  260. }
  261. }
  262. // function to draw the dialog canvas
  263. static void flip_social_canvas_draw_message(Canvas *canvas, char *user_username, char *user_message, bool is_flipped, bool show_prev, bool show_next)
  264. {
  265. canvas_set_color(canvas, ColorBlack);
  266. canvas_set_font(canvas, FontPrimary);
  267. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, user_username);
  268. canvas_set_font(canvas, FontSecondary);
  269. draw_user_message(canvas, user_message, 12);
  270. canvas_set_font(canvas, FontSecondary);
  271. if (show_prev)
  272. {
  273. canvas_draw_icon(canvas, 0, 53, &I_ButtonLeft_4x7);
  274. canvas_draw_str_aligned(canvas, 9, 54, AlignLeft, AlignTop, "Prev");
  275. }
  276. if (!is_flipped)
  277. {
  278. canvas_draw_icon(canvas, 52, 53, &I_ButtonOK_7x7);
  279. canvas_draw_str_aligned(canvas, 61, 54, AlignLeft, AlignTop, "Flip");
  280. }
  281. else
  282. {
  283. canvas_draw_icon(canvas, 47, 53, &I_ButtonOK_7x7);
  284. canvas_draw_str_aligned(canvas, 56, 54, AlignLeft, AlignTop, "UnFlip");
  285. }
  286. if (show_next)
  287. {
  288. canvas_draw_icon(canvas, 98, 53, &I_ButtonRight_4x7);
  289. canvas_draw_str_aligned(canvas, 107, 54, AlignLeft, AlignTop, "Next");
  290. }
  291. }
  292. // Callback function to handle the feed dialog
  293. static void flip_social_callback_draw_feed(Canvas *canvas, void *model)
  294. {
  295. UNUSED(model);
  296. if (!canvas)
  297. {
  298. FURI_LOG_E(TAG, "Canvas is NULL");
  299. return;
  300. }
  301. if (!app_instance)
  302. {
  303. FURI_LOG_E(TAG, "FlipSocialApp is NULL");
  304. return;
  305. }
  306. if (!flip_social_dialog_shown)
  307. {
  308. flip_social_dialog_shown = true;
  309. app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
  310. app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
  311. }
  312. // handle action
  313. switch (action)
  314. {
  315. case ActionNone:
  316. flip_social_canvas_draw_message(canvas, app_instance->flip_social_feed.usernames[app_instance->flip_social_feed.index], app_instance->flip_social_feed.messages[app_instance->flip_social_feed.index], app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index], app_instance->flip_social_feed.index > 0, app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1);
  317. break;
  318. case ActionNext:
  319. canvas_clear(canvas);
  320. if (app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1)
  321. {
  322. app_instance->flip_social_feed.index++;
  323. }
  324. flip_social_canvas_draw_message(canvas, app_instance->flip_social_feed.usernames[app_instance->flip_social_feed.index], app_instance->flip_social_feed.messages[app_instance->flip_social_feed.index], app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index], app_instance->flip_social_feed.index > 0, app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1);
  325. action = ActionNone;
  326. break;
  327. case ActionPrev:
  328. canvas_clear(canvas);
  329. if (app_instance->flip_social_feed.index > 0)
  330. {
  331. app_instance->flip_social_feed.index--;
  332. }
  333. flip_social_canvas_draw_message(canvas, app_instance->flip_social_feed.usernames[app_instance->flip_social_feed.index], app_instance->flip_social_feed.messages[app_instance->flip_social_feed.index], app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index], app_instance->flip_social_feed.index > 0, app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1);
  334. action = ActionNone;
  335. break;
  336. case ActionFlip:
  337. canvas_clear(canvas);
  338. app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index] = !app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index];
  339. flip_social_canvas_draw_message(canvas, app_instance->flip_social_feed.usernames[app_instance->flip_social_feed.index], app_instance->flip_social_feed.messages[app_instance->flip_social_feed.index], app_instance->flip_social_feed.is_flipped[app_instance->flip_social_feed.index], app_instance->flip_social_feed.index > 0, app_instance->flip_social_feed.index < app_instance->flip_social_feed.count - 1);
  340. action = ActionNone;
  341. // send post request to flip the message
  342. if (app_instance->login_username_logged_in == NULL)
  343. {
  344. FURI_LOG_E(TAG, "Username is NULL");
  345. return;
  346. }
  347. char payload[256];
  348. snprintf(payload, sizeof(payload), "{\"username\":\"%s\",\"post_id\":\"%lu\"}", app_instance->login_username_logged_in, app_instance->flip_social_feed.ids[app_instance->flip_social_feed.index]);
  349. flipper_http_post_request_with_headers("https://www.flipsocial.net/api/feed/flip/", "{\"Content-Type\":\"application/json\"}", payload);
  350. break;
  351. case ActionBack:
  352. canvas_clear(canvas);
  353. flip_social_dialog_stop = true;
  354. app_instance->flip_social_feed.index = 0;
  355. action = ActionNone;
  356. break;
  357. default:
  358. break;
  359. }
  360. if (flip_social_dialog_stop)
  361. {
  362. furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
  363. flip_social_dialog_shown = false;
  364. flip_social_dialog_stop = false;
  365. action = ActionNone;
  366. }
  367. }
  368. /**
  369. * @brief Navigation callback for asynchonously handling the login process.
  370. * @param canvas The canvas to draw on.
  371. * @param model The model - unused
  372. * @return void
  373. */
  374. static void flip_social_callback_draw_login(Canvas *canvas, void *model)
  375. {
  376. UNUSED(model);
  377. if (!canvas)
  378. {
  379. FURI_LOG_E(TAG, "Canvas is NULL");
  380. return;
  381. }
  382. canvas_set_font(canvas, FontSecondary);
  383. if (!flip_social_board_is_active(canvas))
  384. {
  385. return;
  386. }
  387. canvas_draw_str(canvas, 0, 7, "Logging in...");
  388. // Perform login request
  389. if (!flip_social_sent_login_request)
  390. {
  391. if (!app_instance->login_username_logged_out || !app_instance->login_password_logged_out || strlen(app_instance->login_username_logged_out) == 0 || strlen(app_instance->login_password_logged_out) == 0)
  392. {
  393. canvas_clear(canvas);
  394. canvas_draw_str(canvas, 0, 10, "Please enter your credentials.");
  395. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  396. return;
  397. }
  398. flip_social_sent_login_request = true;
  399. char buffer[256];
  400. snprintf(buffer, sizeof(buffer), "{\"username\":\"%s\",\"password\":\"%s\"}", app_instance->login_username_logged_out, app_instance->login_password_logged_out);
  401. flip_social_login_success = flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/login/", "{\"Content-Type\":\"application/json\"}", buffer);
  402. if (flip_social_login_success)
  403. {
  404. fhttp.state = RECEIVING;
  405. return;
  406. }
  407. else
  408. {
  409. fhttp.state = ISSUE;
  410. return;
  411. }
  412. }
  413. // handle response
  414. if (flip_social_sent_login_request && flip_social_login_success)
  415. {
  416. canvas_set_font(canvas, FontSecondary);
  417. canvas_draw_str(canvas, 0, 17, "Request Sent!");
  418. canvas_draw_str(canvas, 0, 32, "Awaiting reponse...");
  419. if (fhttp.state == IDLE && fhttp.received_data != NULL)
  420. {
  421. // read response
  422. if (strstr(fhttp.received_data, "[SUCCESS]") != NULL || strstr(fhttp.received_data, "User found") != NULL)
  423. {
  424. canvas_draw_str(canvas, 0, 42, "Login successful!");
  425. canvas_draw_str(canvas, 0, 62, "Welcome back!");
  426. app_instance->is_logged_in = "true";
  427. // set the logged_in_username and change_password_logged_in
  428. if (app_instance->login_username_logged_out)
  429. {
  430. strcpy(app_instance->login_username_logged_in, app_instance->login_username_logged_out);
  431. }
  432. if (app_instance->login_password_logged_out)
  433. {
  434. app_instance->change_password_logged_in = app_instance->login_password_logged_out;
  435. }
  436. 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);
  437. // send user to the logged in submenu
  438. view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
  439. }
  440. else if (strstr(fhttp.received_data, "User not found") != NULL)
  441. {
  442. canvas_clear(canvas);
  443. canvas_draw_str(canvas, 0, 10, "Account not found...");
  444. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  445. }
  446. else
  447. {
  448. flip_social_handle_error(canvas);
  449. }
  450. }
  451. else if ((fhttp.state == ISSUE || fhttp.state == INACTIVE) && fhttp.received_data != NULL)
  452. {
  453. flip_social_handle_error(canvas);
  454. }
  455. else if (fhttp.state == IDLE && fhttp.received_data == NULL)
  456. {
  457. flip_social_handle_error(canvas);
  458. }
  459. }
  460. else if (flip_social_sent_login_request && !flip_social_login_success)
  461. {
  462. canvas_clear(canvas);
  463. canvas_draw_str(canvas, 0, 10, "Failed sending request.");
  464. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  465. canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
  466. }
  467. }
  468. /**
  469. * @brief Navigation callback for asynchonously handling the register process.
  470. * @param canvas The canvas to draw on.
  471. * @param model The model - unused
  472. * @return void
  473. */
  474. static void flip_social_callback_draw_register(Canvas *canvas, void *model)
  475. {
  476. UNUSED(model);
  477. if (!canvas)
  478. {
  479. FURI_LOG_E(TAG, "Canvas is NULL");
  480. return;
  481. }
  482. canvas_set_font(canvas, FontSecondary);
  483. if (!flip_social_board_is_active(canvas))
  484. {
  485. return;
  486. }
  487. canvas_draw_str(canvas, 0, 7, "Registering...");
  488. // Perform login request
  489. if (!flip_social_sent_register_request)
  490. {
  491. // check if the username and password are valid
  492. if (!app_instance->register_username_logged_out || !app_instance->register_password_logged_out || strlen(app_instance->register_username_logged_out) == 0 || strlen(app_instance->register_password_logged_out) == 0)
  493. {
  494. canvas_clear(canvas);
  495. canvas_draw_str(canvas, 0, 10, "Please enter your credentials.");
  496. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  497. return;
  498. }
  499. // check if both passwords match
  500. if (strcmp(app_instance->register_password_logged_out, app_instance->register_password_2_logged_out) != 0)
  501. {
  502. canvas_clear(canvas);
  503. canvas_draw_str(canvas, 0, 10, "Passwords do not match.");
  504. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  505. return;
  506. }
  507. char buffer[128];
  508. snprintf(buffer, sizeof(buffer), "{\"username\":\"%s\",\"password\":\"%s\"}", app_instance->register_username_logged_out, app_instance->register_password_logged_out);
  509. flip_social_register_success = flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/register/", "{\"Content-Type\":\"application/json\"}", buffer);
  510. flip_social_sent_register_request = true;
  511. if (flip_social_register_success)
  512. {
  513. // Set the state to RECEIVING to ensure we continue to see the receiving message
  514. fhttp.state = RECEIVING;
  515. }
  516. else
  517. {
  518. fhttp.state = ISSUE;
  519. }
  520. }
  521. // handle response
  522. if (flip_social_sent_register_request && flip_social_register_success)
  523. {
  524. canvas_set_font(canvas, FontSecondary);
  525. canvas_draw_str(canvas, 0, 17, "Request Sent!");
  526. canvas_draw_str(canvas, 0, 32, "Awaiting reponse...");
  527. if (fhttp.state == IDLE)
  528. {
  529. // read response
  530. if (fhttp.received_data != NULL && (strstr(fhttp.received_data, "[SUCCESS]") != NULL || strstr(fhttp.received_data, "User created") != NULL))
  531. {
  532. canvas_draw_str(canvas, 0, 42, "Registeration successful!");
  533. canvas_draw_str(canvas, 0, 62, "Welcome to FlipSocial!");
  534. // set the login credentials
  535. if (app_instance->login_username_logged_out)
  536. {
  537. app_instance->login_username_logged_out = app_instance->register_username_logged_out;
  538. }
  539. if (app_instance->login_password_logged_out)
  540. {
  541. app_instance->login_password_logged_out = app_instance->register_password_logged_out;
  542. app_instance->change_password_logged_in = app_instance->register_password_logged_out;
  543. }
  544. if (app_instance->login_username_logged_in)
  545. {
  546. app_instance->login_username_logged_in = app_instance->register_username_logged_out;
  547. }
  548. app_instance->is_logged_in = "true";
  549. // save the credentials
  550. 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);
  551. // send user to the logged in submenu
  552. view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
  553. }
  554. else if (strstr(fhttp.received_data, "Username or password not provided") != NULL)
  555. {
  556. canvas_clear(canvas);
  557. canvas_draw_str(canvas, 0, 10, "Please enter your credentials.");
  558. canvas_draw_str(canvas, 0, 60, "Press BACK to return.");
  559. }
  560. else if (strstr(fhttp.received_data, "User already exists") != NULL || strstr(fhttp.received_data, "Multiple users found") != NULL)
  561. {
  562. canvas_draw_str(canvas, 0, 42, "Registration failed...");
  563. canvas_draw_str(canvas, 0, 52, "Username already exists.");
  564. canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
  565. }
  566. else
  567. {
  568. canvas_draw_str(canvas, 0, 42, "Registration failed...");
  569. canvas_draw_str(canvas, 0, 52, "Update your credentials.");
  570. canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
  571. }
  572. }
  573. else if (fhttp.state == ISSUE || fhttp.state == INACTIVE)
  574. {
  575. flip_social_handle_error(canvas);
  576. }
  577. }
  578. else if (flip_social_sent_register_request && !flip_social_register_success)
  579. {
  580. canvas_clear(canvas);
  581. canvas_draw_str(canvas, 0, 10, "Failed sending request.");
  582. canvas_draw_str(canvas, 0, 50, "Update your WiFi settings.");
  583. canvas_draw_str(canvas, 0, 62, "Press BACK to return.");
  584. }
  585. }
  586. // function to draw the dialog canvas
  587. static void flip_social_canvas_draw_explore(Canvas *canvas, char *user_username, char *content)
  588. {
  589. canvas_set_color(canvas, ColorBlack);
  590. canvas_set_font(canvas, FontPrimary);
  591. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, user_username);
  592. canvas_set_font(canvas, FontSecondary);
  593. draw_user_message(canvas, content, 12);
  594. canvas_set_font(canvas, FontSecondary);
  595. canvas_draw_icon(canvas, 0, 53, &I_ButtonLeft_4x7);
  596. canvas_draw_str_aligned(canvas, 9, 54, AlignLeft, AlignTop, "Remove");
  597. canvas_draw_icon(canvas, 98, 53, &I_ButtonRight_4x7);
  598. canvas_draw_str_aligned(canvas, 107, 54, AlignLeft, AlignTop, "Add");
  599. if (strlen(content) > 0)
  600. {
  601. last_explore_response = content;
  602. }
  603. }
  604. // Callback function to handle the explore dialog
  605. static void flip_social_callback_draw_explore(Canvas *canvas, void *model)
  606. {
  607. UNUSED(model);
  608. if (!canvas)
  609. {
  610. FURI_LOG_E(TAG, "Canvas is NULL");
  611. return;
  612. }
  613. if (!app_instance)
  614. {
  615. FURI_LOG_E(TAG, "FlipSocialApp is NULL");
  616. return;
  617. }
  618. if (!flip_social_dialog_shown)
  619. {
  620. flip_social_dialog_shown = true;
  621. app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
  622. app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
  623. }
  624. flip_social_canvas_draw_explore(canvas, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index], last_explore_response);
  625. // handle action
  626. switch (action)
  627. {
  628. case ActionNext:
  629. // add friend
  630. char add_payload[128];
  631. snprintf(add_payload, sizeof(add_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index]);
  632. flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/add-friend/", "{\"Content-Type\":\"application/json\"}", add_payload);
  633. canvas_clear(canvas);
  634. flip_social_canvas_draw_explore(canvas, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index], "Added!");
  635. action = ActionNone;
  636. break;
  637. case ActionPrev:
  638. // remove friend
  639. char remove_payload[128];
  640. snprintf(remove_payload, sizeof(remove_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index]);
  641. flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/remove-friend/", "{\"Content-Type\":\"application/json\"}", remove_payload);
  642. canvas_clear(canvas);
  643. flip_social_canvas_draw_explore(canvas, app_instance->flip_social_explore.usernames[app_instance->flip_social_explore.index], "Removed!");
  644. action = ActionNone;
  645. break;
  646. case ActionBack:
  647. canvas_clear(canvas);
  648. flip_social_dialog_stop = true;
  649. last_explore_response = "";
  650. flip_social_dialog_shown = false;
  651. app_instance->flip_social_explore.index = 0;
  652. action = ActionNone;
  653. break;
  654. default:
  655. break;
  656. }
  657. if (flip_social_dialog_stop)
  658. {
  659. furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
  660. flip_social_dialog_shown = false;
  661. flip_social_dialog_stop = false;
  662. action = ActionNone;
  663. }
  664. }
  665. // Callback function to handle the friends dialog
  666. static void flip_social_callback_draw_friends(Canvas *canvas, void *model)
  667. {
  668. UNUSED(model);
  669. if (!canvas)
  670. {
  671. FURI_LOG_E(TAG, "Canvas is NULL");
  672. return;
  673. }
  674. if (!app_instance)
  675. {
  676. FURI_LOG_E(TAG, "FlipSocialApp is NULL");
  677. return;
  678. }
  679. if (!flip_social_dialog_shown)
  680. {
  681. flip_social_dialog_shown = true;
  682. app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
  683. app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
  684. }
  685. flip_social_canvas_draw_explore(canvas, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index], last_explore_response);
  686. // handle action
  687. switch (action)
  688. {
  689. case ActionNext:
  690. // add friend
  691. char add_payload[128];
  692. snprintf(add_payload, sizeof(add_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index]);
  693. if (flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/add-friend/", "{\"Content-Type\":\"application/json\"}", add_payload))
  694. {
  695. canvas_clear(canvas);
  696. flip_social_canvas_draw_explore(canvas, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index], "Added!");
  697. // add the friend to the friends list
  698. app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.count] = app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index];
  699. app_instance->flip_social_friends.count++;
  700. if (!flip_social_update_friends())
  701. {
  702. FURI_LOG_E(TAG, "Failed to update friends");
  703. }
  704. }
  705. action = ActionNone;
  706. break;
  707. case ActionPrev:
  708. // remove friend
  709. char remove_payload[128];
  710. snprintf(remove_payload, sizeof(remove_payload), "{\"username\":\"%s\",\"friend\":\"%s\"}", app_instance->login_username_logged_in, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index]);
  711. if (flipper_http_post_request_with_headers("https://www.flipsocial.net/api/user/remove-friend/", "{\"Content-Type\":\"application/json\"}", remove_payload))
  712. {
  713. canvas_clear(canvas);
  714. flip_social_canvas_draw_explore(canvas, app_instance->flip_social_friends.usernames[app_instance->flip_social_friends.index], "Removed!");
  715. // remove the friend from the friends list
  716. for (int i = app_instance->flip_social_friends.index; i < app_instance->flip_social_friends.count - 1; i++)
  717. {
  718. app_instance->flip_social_friends.usernames[i] = app_instance->flip_social_friends.usernames[i + 1];
  719. }
  720. app_instance->flip_social_friends.count--;
  721. if (!flip_social_update_friends())
  722. {
  723. FURI_LOG_E(TAG, "Failed to update friends");
  724. }
  725. }
  726. action = ActionNone;
  727. break;
  728. case ActionBack:
  729. canvas_clear(canvas);
  730. flip_social_dialog_stop = true;
  731. last_explore_response = "";
  732. flip_social_dialog_shown = false;
  733. app_instance->flip_social_friends.index = 0;
  734. action = ActionNone;
  735. break;
  736. default:
  737. break;
  738. }
  739. if (flip_social_dialog_stop)
  740. {
  741. furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
  742. flip_social_dialog_shown = false;
  743. flip_social_dialog_stop = false;
  744. action = ActionNone;
  745. }
  746. }
  747. static void flip_social_canvas_draw_user_message(Canvas *canvas, char *user_username, char *user_message, bool show_prev, bool show_next)
  748. {
  749. canvas_set_color(canvas, ColorBlack);
  750. canvas_set_font(canvas, FontPrimary);
  751. canvas_draw_str_aligned(canvas, 64, 5, AlignCenter, AlignCenter, user_username);
  752. canvas_set_font(canvas, FontSecondary);
  753. draw_user_message(canvas, user_message, 12);
  754. canvas_set_font(canvas, FontSecondary);
  755. if (show_prev)
  756. {
  757. canvas_draw_icon(canvas, 0, 53, &I_ButtonLeft_4x7);
  758. canvas_draw_str_aligned(canvas, 9, 54, AlignLeft, AlignTop, "Prev");
  759. }
  760. canvas_draw_icon(canvas, 47, 53, &I_ButtonOK_7x7);
  761. canvas_draw_str_aligned(canvas, 56, 54, AlignLeft, AlignTop, "Create");
  762. if (show_next)
  763. {
  764. canvas_draw_icon(canvas, 98, 53, &I_ButtonRight_4x7);
  765. canvas_draw_str_aligned(canvas, 107, 54, AlignLeft, AlignTop, "Next");
  766. }
  767. }
  768. // Callback function to handle the messages dialog
  769. static void flip_social_callback_draw_messages(Canvas *canvas, void *model)
  770. {
  771. UNUSED(model);
  772. if (!canvas)
  773. {
  774. FURI_LOG_E(TAG, "Canvas is NULL");
  775. return;
  776. }
  777. if (!app_instance)
  778. {
  779. FURI_LOG_E(TAG, "FlipSocialApp is NULL");
  780. return;
  781. }
  782. if (!flip_social_dialog_shown)
  783. {
  784. flip_social_dialog_shown = true;
  785. app_instance->input_event_queue = furi_record_open(RECORD_INPUT_EVENTS);
  786. app_instance->input_event = furi_pubsub_subscribe(app_instance->input_event_queue, on_input, NULL);
  787. }
  788. // handle action
  789. switch (action)
  790. {
  791. case ActionNone:
  792. flip_social_canvas_draw_user_message(canvas, app_instance->flip_social_messages.usernames[app_instance->flip_social_messages.index], app_instance->flip_social_messages.messages[app_instance->flip_social_messages.index], app_instance->flip_social_messages.index > 0, app_instance->flip_social_messages.index < app_instance->flip_social_messages.count - 1);
  793. action = ActionNone;
  794. break;
  795. case ActionNext:
  796. // view next message (if any)
  797. canvas_clear(canvas);
  798. if (app_instance->flip_social_messages.index < app_instance->flip_social_messages.count - 1)
  799. {
  800. app_instance->flip_social_messages.index++;
  801. }
  802. flip_social_canvas_draw_user_message(canvas, app_instance->flip_social_messages.usernames[app_instance->flip_social_messages.index], app_instance->flip_social_messages.messages[app_instance->flip_social_messages.index], app_instance->flip_social_messages.index > 0, app_instance->flip_social_messages.index < app_instance->flip_social_messages.count - 1);
  803. action = ActionNone;
  804. break;
  805. case ActionPrev:
  806. // view previous message (if any)
  807. canvas_clear(canvas);
  808. if (app_instance->flip_social_messages.index > 0)
  809. {
  810. app_instance->flip_social_messages.index--;
  811. }
  812. flip_social_canvas_draw_user_message(canvas, app_instance->flip_social_messages.usernames[app_instance->flip_social_messages.index], app_instance->flip_social_messages.messages[app_instance->flip_social_messages.index], app_instance->flip_social_messages.index > 0, app_instance->flip_social_messages.index < app_instance->flip_social_messages.count - 1);
  813. action = ActionNone;
  814. break;
  815. case ActionBack:
  816. // go back to the previous view
  817. flip_social_dialog_stop = true;
  818. action = ActionNone;
  819. break;
  820. case ActionFlip:
  821. // go to the input view
  822. flip_social_dialog_stop = true;
  823. break;
  824. default:
  825. action = ActionNone;
  826. break;
  827. }
  828. if (flip_social_dialog_stop)
  829. {
  830. furi_pubsub_unsubscribe(app_instance->input_event_queue, app_instance->input_event);
  831. flip_social_dialog_shown = false;
  832. flip_social_dialog_stop = false;
  833. if (action == ActionFlip)
  834. {
  835. action = ActionNone;
  836. view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInMessagesNewMessageInput);
  837. }
  838. else
  839. {
  840. action = ActionNone;
  841. view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInMessagesSubmenu);
  842. }
  843. }
  844. }
  845. #endif // FLIP_SOCIAL_DRAW_H