totp_scene_token_menu.c 7.5 KB

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