Skip to content

Commit 881391a

Browse files
committed
Menu tweaks
- Refactoring - Adds error message popup if its unable to open the playlist file for any reason - Changes how the delay and timeout settings are stored - Adds enums for new menu - Renamed settings on menu - Reshuffled the layout - Improves emulation count down
1 parent 816c0d9 commit 881391a

File tree

2 files changed

+57
-66
lines changed

2 files changed

+57
-66
lines changed

application.fam

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ App(
66
requires=["gui", "nfc"],
77
stack_size=4 * 1024,
88
fap_category="NFC",
9+
fap_author="@acegoal07",
10+
fap_weburl="https://github.com/acegoal07/FlipperZero_NFC_Playlist/tree/main",
11+
fap_version="1.0",
912
)

nfc_playlist.c

Lines changed: 54 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -20,38 +20,35 @@ typedef enum {
2020
NfcPlaylistScene_count
2121
} NfcPlaylistScene;
2222

23-
// IDs for the view used by the app
24-
typedef enum { NfcPlaylistView_Menu, NfcPlaylistView_Popup } NfcPlaylistView;
25-
2623
// The app context struct
2724
typedef struct {
2825
SceneManager* scene_manager;
2926
ViewDispatcher* view_dispatcher;
3027
VariableItemList* variable_item_list;
3128
Popup* popup;
3229
NfcPlaylistWorker* nfc_worker;
33-
int emulate_timeout; uint8_t emulate_timeout_index;
34-
int emulate_delay; uint8_t emulate_delay_index;
30+
uint8_t emulate_timeout;
31+
uint8_t emulate_delay;
3532
} NfcPlaylist;
3633

37-
// All custom events
38-
typedef enum { NfcPlaylistEvent_ShowEmulatingPopup } NfcPlaylistEvent;
39-
4034
// All options for the emulate timeout and delay
4135
const int options_emulate_timeout[] = { 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000 };
4236
const int options_emulate_delay[] = { 0000, 1000, 2000, 3000, 4000, 5000 };
4337

4438
/* main menu scene */
45-
4639
// Indices for menu items
47-
typedef enum { NfcPlaylistMenuSelection_Start, NfcPlaylistMenuSelection_Settings } NfcPlaylistMenuSelection;
40+
typedef enum { NfcPlaylistSettings_Timeout, NfcPlaylistSettings_Delay, NfcPlaylistMenuSelection_Start } NfcPlaylistMenuSelection;
41+
// All custom events
42+
typedef enum { NfcPlaylistEvent_ShowEmulatingPopup } NfcPlaylistEvent;
43+
// IDs for the view used by the app
44+
typedef enum { NfcPlaylistView_Menu, NfcPlaylistView_Popup } NfcPlaylistView;
4845

4946
// Main menu callback - sends a custom event to the scene manager based on the menu selection
5047
void nfc_playlist_menu_callback_main_menu(void* context, uint32_t index) {
5148
FURI_LOG_T(TAG, "nfc_playlist_menu_callback_main_menu");
5249
NfcPlaylist* app = context;
5350
switch(index) {
54-
case 0:
51+
case NfcPlaylistMenuSelection_Start:
5552
scene_manager_handle_custom_event(app->scene_manager, NfcPlaylistEvent_ShowEmulatingPopup);
5653
break;
5754
default:
@@ -66,55 +63,47 @@ static void nfc_playlist_settings_change_callback(VariableItem* item) {
6663
uint8_t option_value_index = variable_item_get_current_value_index(item);
6764

6865
switch(current_option) {
69-
case 1: ;
70-
app->emulate_timeout = options_emulate_timeout[option_value_index];
71-
app->emulate_timeout_index = option_value_index;
72-
char emulate_timeout_text[9];
73-
snprintf(emulate_timeout_text, 9, "%d", (app->emulate_timeout/1000));
74-
variable_item_set_current_value_text(item, (char*)emulate_timeout_text);
75-
76-
break;
77-
case 2: ;
78-
app->emulate_delay = options_emulate_delay[option_value_index];
79-
app->emulate_delay_index = option_value_index;
80-
char emulate_delay_text[9];
81-
snprintf(emulate_delay_text, 9, "%d", (app->emulate_delay/1000));
82-
variable_item_set_current_value_text(item, (char*)emulate_delay_text);
83-
break;
66+
case NfcPlaylistSettings_Timeout: ;
67+
app->emulate_timeout = option_value_index;
68+
char emulate_timeout_text[9];
69+
snprintf(emulate_timeout_text, 9, "%d", (options_emulate_timeout[option_value_index]/1000));
70+
variable_item_set_current_value_text(item, (char*)emulate_timeout_text);
71+
break;
72+
case NfcPlaylistSettings_Delay: ;
73+
app->emulate_delay = option_value_index;
74+
char emulate_delay_text[9];
75+
snprintf(emulate_delay_text, 9, "%d", (options_emulate_delay[option_value_index]/1000));
76+
variable_item_set_current_value_text(item, (char*)emulate_delay_text);
77+
break;
8478
}
8579
}
8680

8781
// Resets the menu, gives it content, callbacks and selection enums
8882
void nfc_playlist_scene_on_enter_main_menu(void* context) {
8983
FURI_LOG_T(TAG, "nfc_playlist_scene_on_enter_main_menu");
9084
NfcPlaylist* app = context;
91-
92-
// make a variable item list that goes up in 2
93-
9485
variable_item_list_set_header(app->variable_item_list, "NFC Playlist");
95-
variable_item_list_add(app->variable_item_list, "Start", 0, NULL, NULL);
9686
VariableItem* emulation_timeout_settings = variable_item_list_add(
9787
app->variable_item_list,
98-
"Emulation timeout",
88+
"Timeout",
9989
10,
10090
nfc_playlist_settings_change_callback,
10191
app);
102-
variable_item_set_current_value_index(emulation_timeout_settings, app->emulate_timeout_index);
92+
variable_item_set_current_value_index(emulation_timeout_settings, app->emulate_timeout);
10393
char emulation_timeout_settings_text[9];
104-
snprintf(emulation_timeout_settings_text, 9, "%d", (app->emulate_timeout/1000));
94+
snprintf(emulation_timeout_settings_text, 9, "%d", (options_emulate_timeout[app->emulate_timeout]/1000));
10595
variable_item_set_current_value_text(emulation_timeout_settings, (char*)emulation_timeout_settings_text);
106-
10796
VariableItem* emulation_delay_settings = variable_item_list_add(
10897
app->variable_item_list,
109-
"Emulation delay",
98+
"Delay",
11099
6,
111100
nfc_playlist_settings_change_callback,
112101
app);
113-
variable_item_set_current_value_index(emulation_delay_settings, app->emulate_delay_index);
102+
variable_item_set_current_value_index(emulation_delay_settings, app->emulate_delay);
114103
char emulation_delay_settings_text[9];
115-
snprintf(emulation_delay_settings_text, 9, "%d", (app->emulate_delay/1000));
104+
snprintf(emulation_delay_settings_text, 9, "%d", (options_emulate_delay[app->emulate_delay]/1000));
116105
variable_item_set_current_value_text(emulation_delay_settings, (char*)emulation_delay_settings_text);
117-
106+
variable_item_list_add(app->variable_item_list, "Start", 0, NULL, NULL);
118107
variable_item_list_set_enter_callback(app->variable_item_list, nfc_playlist_menu_callback_main_menu, app);
119108
view_dispatcher_switch_to_view(app->view_dispatcher, NfcPlaylistView_Menu);
120109
}
@@ -162,13 +151,13 @@ void nfc_playlist_scene_on_enter_popup_emulating(void* context) {
162151
popup_set_context(app->popup, app);
163152
popup_set_header(app->popup, "Emulating:", 64, 10, AlignCenter, AlignTop);
164153
view_dispatcher_switch_to_view(app->view_dispatcher, NfcPlaylistView_Popup);
165-
154+
166155
int file_position = 0;
167156
// read the file line by line and print the text
168157
while(stream_read_line(stream, line)) {
169-
if (app->emulate_delay > 0) {
158+
if (options_emulate_delay[app->emulate_delay] > 0) {
170159
if (file_position > 0) {
171-
int time_counter_delay_ms = app->emulate_delay;
160+
int time_counter_delay_ms = options_emulate_timeout[app->emulate_delay];
172161
do {
173162
char display_text[30];
174163
snprintf(display_text, 30, "%s\n\n%ds", "Delaying...", (time_counter_delay_ms/1000));
@@ -178,47 +167,51 @@ void nfc_playlist_scene_on_enter_popup_emulating(void* context) {
178167
} while(time_counter_delay_ms > 0);
179168
} else {
180169
file_position++;
181-
}
170+
}
182171
}
183-
172+
184173
char* file_path = (char*)furi_string_get_cstr(line);
185174
char* file_name = &strrchr(file_path, '/')[1];
186-
int time_counter_ms = app->emulate_timeout;
175+
int time_counter_ms = options_emulate_timeout[app->emulate_timeout];
187176

188177
if (storage_file_exists(storage, file_path) == false) {
189-
char* text = strcat(file_name, "\nnot found");
190-
int size = (strlen(text) + 4);
191-
char display_text[size];
178+
char* popup_text_unformatted = strcat(file_name, "\nnot found");
179+
int popup_text_size = (strlen(popup_text_unformatted) + 4);
180+
char popup_text[popup_text_size];
192181

193182
do {
194-
snprintf(display_text, size, "%s\n%ds", file_name, (time_counter_ms/1000));
195-
popup_set_text(app->popup, display_text, 64, 25, AlignCenter, AlignTop);
183+
snprintf(popup_text, popup_text_size, "%s\n%ds", file_name, (time_counter_ms/1000));
184+
popup_set_text(app->popup, popup_text, 64, 25, AlignCenter, AlignTop);
196185
furi_delay_ms(500);
197186
time_counter_ms -= 500;
198187
} while(time_counter_ms > 0);
199188
} else {
200189
nfc_playlist_worker_set_nfc_data(app->nfc_worker, file_path);
201190
nfc_playlist_worker_start(app->nfc_worker);
202-
203-
int size = (strlen(file_name) + 4);
204-
char display_text[size];
205-
191+
192+
int popup_text_size = (strlen(file_name) + 4);
193+
char popup_text[popup_text_size];
194+
206195
do {
207-
snprintf(display_text, size, "%s\n%ds", file_name, (time_counter_ms/1000));
208-
popup_set_text(app->popup, display_text, 64, 25, AlignCenter, AlignTop);
196+
snprintf(popup_text, popup_text_size, "%s\n%ds", file_name, (time_counter_ms/1000));
197+
popup_set_text(app->popup, popup_text, 64, 25, AlignCenter, AlignTop);
209198
furi_delay_ms(500);
210199
time_counter_ms -= 500;
211-
if (time_counter_ms <= 0) {
212-
break;
213-
}
214-
} while(nfc_playlist_worker_is_emulating(app->nfc_worker));
200+
} while(nfc_playlist_worker_is_emulating(app->nfc_worker) && time_counter_ms > 0);
215201

216202
if (nfc_playlist_worker_is_emulating(app->nfc_worker)) {
217203
nfc_playlist_worker_stop(app->nfc_worker);
218204
}
219205
}
220206
}
207+
popup_reset(app->popup);
208+
scene_manager_previous_scene(app->scene_manager);
221209
} else {
210+
popup_reset(app->popup);
211+
popup_set_context(app->popup, app);
212+
popup_set_header(app->popup, "Error:", 64, 10, AlignCenter, AlignTop);
213+
popup_set_text(app->popup, "Failed to open file\n/ext/apps_data/nfc_playlist/playlist.txt", 64, 25, AlignCenter, AlignTop);
214+
view_dispatcher_switch_to_view(app->view_dispatcher, NfcPlaylistView_Popup);
222215
FURI_LOG_E(TAG, "Failed to open file");
223216
}
224217
// Free/close resources
@@ -229,9 +222,6 @@ void nfc_playlist_scene_on_enter_popup_emulating(void* context) {
229222
app->nfc_worker = NULL;
230223
// Close storage
231224
furi_record_close(RECORD_STORAGE);
232-
233-
popup_reset(app->popup);
234-
scene_manager_previous_scene(app->scene_manager);
235225
}
236226

237227
bool nfc_playlist_scene_on_event_popup_emulating(void* context, SceneManagerEvent event) {
@@ -301,10 +291,8 @@ void nfc_playlist_view_dispatcher_init(NfcPlaylist* app) {
301291
FURI_LOG_D(TAG, "nfc_playlist_view_dispatcher_init allocating views");
302292
app->variable_item_list = variable_item_list_alloc();
303293
app->popup = popup_alloc();
304-
app->emulate_timeout = 5000;
305-
app->emulate_timeout_index = 4;
306-
app->emulate_delay = 0000;
307-
app->emulate_delay_index = 0;
294+
app->emulate_timeout = 4;
295+
app->emulate_delay = 0;
308296

309297
// assign callback that pass events from views to the scene manager
310298
FURI_LOG_D(TAG, "nfc_playlist_view_dispatcher_init setting callbacks");

0 commit comments

Comments
 (0)