totp_scene_token_menu.c 7.3 KB

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