totp_scene_token_menu.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include "totp_scene_token_menu.h"
  2. #include <gui/gui.h>
  3. #include <dialogs/dialogs.h>
  4. #include "../../ui_controls.h"
  5. #include "../../common_dialogs.h"
  6. #include "../../constants.h"
  7. #include "../../scene_director.h"
  8. #include "../../../services/config/config.h"
  9. #include <linked_list.h>
  10. #include "../../../types/token_info.h"
  11. #include "../generate_token/totp_scene_generate_token.h"
  12. #include "../add_new_token/totp_scene_add_new_token.h"
  13. #include "../app_settings/totp_app_settings.h"
  14. #include "../../../types/nullable.h"
  15. #include <roll_value.h>
  16. #define SCREEN_HEIGHT_THIRD (SCREEN_HEIGHT / 3)
  17. #define SCREEN_HEIGHT_THIRD_CENTER (SCREEN_HEIGHT_THIRD >> 1)
  18. typedef enum { AddNewToken, DeleteToken, AppSettings } Control;
  19. typedef struct {
  20. Control selected_control;
  21. TotpNullable_uint16_t current_token_index;
  22. } SceneState;
  23. void totp_scene_token_menu_activate(
  24. PluginState* plugin_state,
  25. const TokenMenuSceneContext* context) {
  26. SceneState* scene_state = malloc(sizeof(SceneState));
  27. furi_check(scene_state != NULL);
  28. plugin_state->current_scene_state = scene_state;
  29. if(context != NULL) {
  30. TOTP_NULLABLE_VALUE(scene_state->current_token_index, context->current_token_index);
  31. } else {
  32. TOTP_NULLABLE_NULL(scene_state->current_token_index);
  33. }
  34. }
  35. void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_state) {
  36. const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
  37. if(scene_state->current_token_index.is_null) {
  38. ui_control_button_render(
  39. canvas,
  40. SCREEN_WIDTH_CENTER - 36,
  41. 5,
  42. 72,
  43. 21,
  44. "Add new token",
  45. scene_state->selected_control == AddNewToken);
  46. ui_control_button_render(
  47. canvas,
  48. SCREEN_WIDTH_CENTER - 36,
  49. 39,
  50. 72,
  51. 21,
  52. "Settings",
  53. scene_state->selected_control == AppSettings);
  54. } else {
  55. ui_control_button_render(
  56. canvas,
  57. SCREEN_WIDTH_CENTER - 36,
  58. SCREEN_HEIGHT_THIRD_CENTER - 8,
  59. 72,
  60. 16,
  61. "Add new token",
  62. scene_state->selected_control == AddNewToken);
  63. ui_control_button_render(
  64. canvas,
  65. SCREEN_WIDTH_CENTER - 36,
  66. SCREEN_HEIGHT_THIRD + SCREEN_HEIGHT_THIRD_CENTER - 8,
  67. 72,
  68. 16,
  69. "Delete token",
  70. scene_state->selected_control == DeleteToken);
  71. ui_control_button_render(
  72. canvas,
  73. SCREEN_WIDTH_CENTER - 36,
  74. SCREEN_HEIGHT_THIRD + SCREEN_HEIGHT_THIRD + SCREEN_HEIGHT_THIRD_CENTER - 8,
  75. 72,
  76. 16,
  77. "Settings",
  78. scene_state->selected_control == AppSettings);
  79. }
  80. }
  81. bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginState* plugin_state) {
  82. if(event->type != EventTypeKey) {
  83. return true;
  84. }
  85. SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
  86. if(event->input.type != InputTypePress) {
  87. return true;
  88. }
  89. switch(event->input.key) {
  90. case InputKeyUp:
  91. totp_roll_value_uint8_t(
  92. &scene_state->selected_control, -1, AddNewToken, AppSettings, RollOverflowBehaviorRoll);
  93. if(scene_state->selected_control == DeleteToken &&
  94. scene_state->current_token_index.is_null) {
  95. scene_state->selected_control--;
  96. }
  97. break;
  98. case InputKeyDown:
  99. totp_roll_value_uint8_t(
  100. &scene_state->selected_control, 1, AddNewToken, AppSettings, RollOverflowBehaviorRoll);
  101. if(scene_state->selected_control == DeleteToken &&
  102. scene_state->current_token_index.is_null) {
  103. scene_state->selected_control++;
  104. }
  105. break;
  106. case InputKeyRight:
  107. break;
  108. case InputKeyLeft:
  109. break;
  110. case InputKeyOk:
  111. switch(scene_state->selected_control) {
  112. case AddNewToken: {
  113. if(scene_state->current_token_index.is_null) {
  114. totp_scene_director_activate_scene(plugin_state, TotpSceneAddNewToken, NULL);
  115. } else {
  116. TokenAddEditSceneContext add_new_token_scene_context = {
  117. .current_token_index = scene_state->current_token_index.value};
  118. totp_scene_director_activate_scene(
  119. plugin_state, TotpSceneAddNewToken, &add_new_token_scene_context);
  120. }
  121. break;
  122. }
  123. case DeleteToken: {
  124. DialogMessage* message = dialog_message_alloc();
  125. dialog_message_set_buttons(message, "No", NULL, "Yes");
  126. dialog_message_set_header(message, "Confirmation", 0, 0, AlignLeft, AlignTop);
  127. dialog_message_set_text(
  128. message,
  129. "Are you sure want to delete?",
  130. SCREEN_WIDTH_CENTER,
  131. SCREEN_HEIGHT_CENTER,
  132. AlignCenter,
  133. AlignCenter);
  134. DialogMessageButton dialog_result =
  135. dialog_message_show(plugin_state->dialogs_app, message);
  136. dialog_message_free(message);
  137. if(dialog_result == DialogMessageButtonRight &&
  138. !scene_state->current_token_index.is_null) {
  139. TokenInfo* tokenInfo = NULL;
  140. plugin_state->tokens_list = list_remove_at(
  141. plugin_state->tokens_list,
  142. scene_state->current_token_index.value,
  143. (void**)&tokenInfo);
  144. plugin_state->tokens_count--;
  145. furi_check(tokenInfo != NULL);
  146. token_info_free(tokenInfo);
  147. if(totp_full_save_config_file(plugin_state) != TotpConfigFileUpdateSuccess) {
  148. totp_dialogs_config_updating_error(plugin_state);
  149. return false;
  150. }
  151. totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
  152. }
  153. break;
  154. }
  155. case AppSettings: {
  156. if(!scene_state->current_token_index.is_null) {
  157. AppSettingsSceneContext app_settings_context = {
  158. .current_token_index = scene_state->current_token_index.value};
  159. totp_scene_director_activate_scene(
  160. plugin_state, TotpSceneAppSettings, &app_settings_context);
  161. } else {
  162. totp_scene_director_activate_scene(plugin_state, TotpSceneAppSettings, NULL);
  163. }
  164. break;
  165. }
  166. default:
  167. break;
  168. }
  169. break;
  170. case InputKeyBack: {
  171. if(!scene_state->current_token_index.is_null) {
  172. GenerateTokenSceneContext generate_scene_context = {
  173. .current_token_index = scene_state->current_token_index.value};
  174. totp_scene_director_activate_scene(
  175. plugin_state, TotpSceneGenerateToken, &generate_scene_context);
  176. } else {
  177. totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
  178. }
  179. break;
  180. }
  181. default:
  182. break;
  183. }
  184. return true;
  185. }
  186. void totp_scene_token_menu_deactivate(PluginState* plugin_state) {
  187. if(plugin_state->current_scene_state == NULL) return;
  188. free(plugin_state->current_scene_state);
  189. plugin_state->current_scene_state = NULL;
  190. }