Skip to content

Commit 46bfac4

Browse files
authored
Merge pull request #58 from acegoal07/dev
Dev
2 parents bf7c90b + 8dd0f05 commit 46bfac4

5 files changed

Lines changed: 228 additions & 71 deletions

File tree

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ The idea behind this app is to allow for you to test multiple copies of NFC's at
33
## How it works:
44
When starting the app you are greeted by a select file option where you choose the playlist you wanna run.
55

6-
All playlists should be placed in `ext/apps_data/nfc_playlist`, but they can also be stored in other file locations. An example of the data format is shown below, and you can find an example file in the repository: [file](./playlist.txt). You are able to create your own playlists using the playlist editor in the app.
6+
All playlists should be placed in `ext/apps_data/playlists/nfc_playlist`, but they can also be stored in other file locations. An example of the data format is shown below, and you can find an example file in the repository: [file](./playlist.txt). You are able to create your own playlists using the playlist editor in the app.
77
```txt
88
/ext/nfc/link.nfc
99
/ext/nfc/link2.nfc
@@ -24,9 +24,12 @@ As i know these firmwares are supported and working if you know any more please
2424
- Skip errors (Makes it so you can make the emulation screen hide errors and skip delays between errors and emulation)
2525
- Loop (Makes it so the playlist will loop back to the start when it reaches the end)
2626
- User controls (Allows you to control the position of the playlist using the buttons on the flipper skipping and rewinding the playlist)
27-
- Reset settings (Puts all the settings back to the defaults)
27+
- Back to defaults (Resets all settings to their default values)
28+
- Save settings (Saves the current settings so they persist after reopening the app)
29+
- Reload settings (Reloads the settings from the saved configuration)
30+
- Delete settings (Deletes the saved settings)
2831
## Playlist editor:
29-
- Create PLaylist (Creates a new playlist with the given name)
32+
- Create playlist (Creates a new playlist with the given name)
3033
- Delete playlist (Deletes the selected playlist)
3134
- Rename playlist (Renames the selected playlist to the new name provided)
3235
- Add NFC Item (Adds the selected nfc item to the currently selected playlist)

application.fam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ App(
77
fap_category="NFC",
88
fap_author="@acegoal07",
99
fap_weburl="https://github.com/acegoal07/FlipperZero_NFC_Playlist/tree/main",
10-
fap_version="3.2",
10+
fap_version="3.3",
1111
fap_icon_assets="assets",
1212
fap_icon="assets/Playlist_10px.png",
1313
fap_description="A Tool used to running through a list of NFC cards",

nfc_playlist.c

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,113 @@ static void nfc_playlist_tick_event_callback(void* context) {
1818
scene_manager_handle_tick_event(nfc_playlist->scene_manager);
1919
}
2020

21+
void nfc_playlist_load_settings(void* context) {
22+
furi_assert(context);
23+
NfcPlaylist* nfc_playlist = context;
24+
25+
nfc_playlist->worker_info.settings->emulate_timeout = default_emulate_timeout;
26+
nfc_playlist->worker_info.settings->emulate_delay = default_emulate_delay;
27+
nfc_playlist->worker_info.settings->emulate_led_indicator = default_emulate_led_indicator;
28+
nfc_playlist->worker_info.settings->skip_error = default_skip_error;
29+
nfc_playlist->worker_info.settings->loop = default_loop;
30+
nfc_playlist->worker_info.settings->user_controls = default_user_controls;
31+
32+
Storage* storage = furi_record_open(RECORD_STORAGE);
33+
34+
if(storage_file_exists(storage, SETTINGS_LOCATION)) {
35+
Stream* stream = file_stream_alloc(storage);
36+
37+
if(file_stream_open(stream, SETTINGS_LOCATION, FSAM_READ, FSOM_OPEN_EXISTING)) {
38+
FuriString* line = furi_string_alloc();
39+
FuriString* key = furi_string_alloc();
40+
FuriString* value = furi_string_alloc();
41+
42+
while(stream_read_line(stream, line)) {
43+
if(furi_string_empty(line) || furi_string_start_with_str(line, "#")) continue;
44+
45+
size_t equal_index = furi_string_search_char(line, '=');
46+
if(equal_index <= 0) continue;
47+
48+
furi_string_set_strn(key, furi_string_get_cstr(line), equal_index);
49+
furi_string_set_str(value, furi_string_get_cstr(line) + equal_index + 1);
50+
51+
furi_string_trim(key);
52+
furi_string_trim(value);
53+
54+
const char* k = furi_string_get_cstr(key);
55+
const char* v = furi_string_get_cstr(value);
56+
57+
if(strcmp(k, "emulate_timeout") == 0) {
58+
nfc_playlist->worker_info.settings->emulate_timeout = atoi(v);
59+
} else if(strcmp(k, "emulate_delay") == 0) {
60+
nfc_playlist->worker_info.settings->emulate_delay = atoi(v);
61+
} else if(strcmp(k, "emulate_led_indicator") == 0) {
62+
nfc_playlist->worker_info.settings->emulate_led_indicator =
63+
(strcasecmp(v, "true") == 0);
64+
} else if(strcmp(k, "skip_error") == 0) {
65+
nfc_playlist->worker_info.settings->skip_error = (strcasecmp(v, "true") == 0);
66+
} else if(strcmp(k, "loop") == 0) {
67+
nfc_playlist->worker_info.settings->loop = (strcasecmp(v, "true") == 0);
68+
} else if(strcmp(k, "user_controls") == 0) {
69+
nfc_playlist->worker_info.settings->user_controls = (strcasecmp(v, "true") == 0);
70+
}
71+
}
72+
73+
file_stream_close(stream);
74+
furi_string_free(line);
75+
furi_string_free(key);
76+
furi_string_free(value);
77+
}
78+
stream_free(stream);
79+
}
80+
81+
furi_record_close(RECORD_STORAGE);
82+
}
83+
84+
void nfc_playlist_save_settings(void* context) {
85+
furi_assert(context);
86+
NfcPlaylist* nfc_playlist = context;
87+
88+
FuriString* tmp_str = furi_string_alloc();
89+
90+
furi_string_printf(
91+
tmp_str,
92+
"emulate_timeout=%d\nemulate_delay=%d\nemulate_led_indicator=%s\nskip_error=%s\nloop=%s\nuser_controls=%s",
93+
nfc_playlist->worker_info.settings->emulate_timeout,
94+
nfc_playlist->worker_info.settings->emulate_delay,
95+
nfc_playlist->worker_info.settings->emulate_led_indicator ? "true" : "false",
96+
nfc_playlist->worker_info.settings->skip_error ? "true" : "false",
97+
nfc_playlist->worker_info.settings->loop ? "true" : "false",
98+
nfc_playlist->worker_info.settings->user_controls ? "true" : "false");
99+
100+
Storage* storage = furi_record_open(RECORD_STORAGE);
101+
Stream* stream = file_stream_alloc(storage);
102+
103+
file_stream_open(stream, SETTINGS_LOCATION, FSAM_READ_WRITE, FSOM_OPEN_ALWAYS);
104+
stream_clean(stream);
105+
stream_write_string(stream, tmp_str);
106+
file_stream_close(stream);
107+
stream_free(stream);
108+
furi_record_close(RECORD_STORAGE);
109+
110+
furi_string_free(tmp_str);
111+
}
112+
113+
void nfc_playlist_delete_settings(void* context) {
114+
furi_assert(context);
115+
NfcPlaylist* nfc_playlist = context;
116+
117+
Storage* storage = furi_record_open(RECORD_STORAGE);
118+
119+
if(storage_file_exists(storage, SETTINGS_LOCATION)) {
120+
storage_simply_remove(storage, SETTINGS_LOCATION);
121+
}
122+
123+
furi_record_close(RECORD_STORAGE);
124+
125+
nfc_playlist_load_settings(nfc_playlist);
126+
}
127+
21128
static NfcPlaylist* nfc_playlist_alloc() {
22129
NfcPlaylist* nfc_playlist = malloc(sizeof(NfcPlaylist));
23130
furi_assert(nfc_playlist);
@@ -44,12 +151,11 @@ static NfcPlaylist* nfc_playlist_alloc() {
44151
furi_assert(nfc_playlist->worker_info.settings);
45152

46153
nfc_playlist->worker_info.settings->playlist_path = furi_string_alloc();
47-
nfc_playlist->worker_info.settings->emulate_timeout = default_emulate_timeout;
48-
nfc_playlist->worker_info.settings->emulate_delay = default_emulate_delay;
49-
nfc_playlist->worker_info.settings->emulate_led_indicator = default_emulate_led_indicator;
50-
nfc_playlist->worker_info.settings->skip_error = default_skip_error;
51-
nfc_playlist->worker_info.settings->loop = default_loop;
52-
nfc_playlist->worker_info.settings->user_controls = default_user_controls;
154+
nfc_playlist_load_settings(nfc_playlist);
155+
156+
if(!storage_dir_exists(storage, PLAYLIST_DIR)) {
157+
storage_simply_mkdir(storage, PLAYLIST_DIR);
158+
}
53159

54160
view_dispatcher_set_event_callback_context(nfc_playlist->view_dispatcher, nfc_playlist);
55161
view_dispatcher_set_custom_event_callback(

nfc_playlist.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727
extern "C" {
2828
#endif
2929

30-
#define PLAYLIST_LOCATION "/ext/apps_data/nfc_playlist/"
31-
#define PLAYLIST_DIR "/ext/apps_data/nfc_playlist"
30+
#define PLAYLIST_LOCATION "/ext/apps_data/nfc_playlist/playlists/"
31+
#define PLAYLIST_DIR "/ext/apps_data/nfc_playlist/playlists"
32+
#define SETTINGS_LOCATION "/ext/apps_data/nfc_playlist/settings.txt"
3233
#define NFC_ITEM_LOCATION "/ext/nfc/"
3334
#define MAX_PLAYLIST_NAME_LEN 50
3435

@@ -73,6 +74,24 @@ typedef struct {
7374
NfcPlaylistWorkerInfo worker_info;
7475
} NfcPlaylist;
7576

77+
/**
78+
* Load the NFC playlist settings from persistent storage.
79+
* @param context The context pointer to the NfcPlaylist instance.
80+
*/
81+
void nfc_playlist_load_settings(void* context);
82+
83+
/**
84+
* Save the NFC playlist settings to persistent storage.
85+
* @param context The context pointer to the NfcPlaylist instance.
86+
*/
87+
void nfc_playlist_save_settings(void* context);
88+
89+
/**
90+
* Delete the NFC playlist settings from persistent storage.
91+
* @param context The context pointer to the NfcPlaylist instance.
92+
*/
93+
void nfc_playlist_delete_settings(void* context);
94+
7695
#ifdef __cplusplus
7796
}
7897
#endif

scenes/nfc_playlist_scene_settings.c

Lines changed: 88 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ typedef enum {
77
NfcPlaylistSettings_SkipError,
88
NfcPlaylistSettings_Loop,
99
NfcPlaylistSettings_UserControls,
10-
NfcPlaylistSettings_Reset
10+
NfcPlaylistSettings_Reset,
11+
NfcPlaylistSettings_SaveSettings,
12+
NfcPlaylistSettings_ReloadSettings,
13+
NfcPlaylistSettings_DeleteSettings,
1114
} NfcPlaylistSettingsMenuSelection;
1215

1316
static void nfc_playlist_settings_menu_callback(void* context, uint32_t index) {
@@ -144,7 +147,16 @@ void nfc_playlist_settings_scene_on_enter(void* context) {
144147
variable_item_set_current_value_text(
145148
user_controls_setting, nfc_playlist->worker_info.settings->user_controls ? "ON" : "OFF");
146149

147-
variable_item_list_add(nfc_playlist->views.variable_item_list, "Reset settings", 0, NULL, NULL);
150+
variable_item_list_add(
151+
nfc_playlist->views.variable_item_list, "Back to defaults", 0, NULL, NULL);
152+
153+
variable_item_list_add(nfc_playlist->views.variable_item_list, "Save settings", 0, NULL, NULL);
154+
155+
variable_item_list_add(
156+
nfc_playlist->views.variable_item_list, "Reload settings", 0, NULL, NULL);
157+
158+
variable_item_list_add(
159+
nfc_playlist->views.variable_item_list, "Delete saved settings", 0, NULL, NULL);
148160

149161
VariableItem* credits = variable_item_list_add(
150162
nfc_playlist->views.variable_item_list, "acegoal07, xtruan, WillyJL", 1, NULL, NULL);
@@ -156,76 +168,93 @@ void nfc_playlist_settings_scene_on_enter(void* context) {
156168
view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_VariableItemList);
157169
}
158170

171+
static void nfc_playlist_settings_update_view(void* context) {
172+
furi_assert(context);
173+
NfcPlaylist* nfc_playlist = context;
174+
175+
FuriString* tmp_str = furi_string_alloc();
176+
177+
VariableItem* emulation_timeout_setting =
178+
variable_item_list_get(nfc_playlist->views.variable_item_list, NfcPlaylistSettings_Timeout);
179+
variable_item_set_current_value_index(
180+
emulation_timeout_setting, nfc_playlist->worker_info.settings->emulate_timeout);
181+
furi_string_printf(
182+
tmp_str,
183+
"%ds",
184+
options_emulate_timeout[nfc_playlist->worker_info.settings->emulate_timeout]);
185+
variable_item_set_current_value_text(emulation_timeout_setting, furi_string_get_cstr(tmp_str));
186+
187+
VariableItem* emulation_delay_setting =
188+
variable_item_list_get(nfc_playlist->views.variable_item_list, NfcPlaylistSettings_Delay);
189+
variable_item_set_current_value_index(
190+
emulation_delay_setting, nfc_playlist->worker_info.settings->emulate_delay);
191+
furi_string_printf(
192+
tmp_str, "%ds", options_emulate_delay[nfc_playlist->worker_info.settings->emulate_delay]);
193+
variable_item_set_current_value_text(emulation_delay_setting, furi_string_get_cstr(tmp_str));
194+
195+
furi_string_free(tmp_str);
196+
197+
VariableItem* emulation_led_indicator_setting = variable_item_list_get(
198+
nfc_playlist->views.variable_item_list, NfcPlaylistSettings_LedIndicator);
199+
variable_item_set_current_value_index(
200+
emulation_led_indicator_setting, nfc_playlist->worker_info.settings->emulate_led_indicator);
201+
variable_item_set_current_value_text(
202+
emulation_led_indicator_setting,
203+
nfc_playlist->worker_info.settings->emulate_led_indicator ? "ON" : "OFF");
204+
205+
VariableItem* emulation_skip_error_setting = variable_item_list_get(
206+
nfc_playlist->views.variable_item_list, NfcPlaylistSettings_SkipError);
207+
variable_item_set_current_value_index(
208+
emulation_skip_error_setting, nfc_playlist->worker_info.settings->skip_error);
209+
variable_item_set_current_value_text(
210+
emulation_skip_error_setting, nfc_playlist->worker_info.settings->skip_error ? "ON" : "OFF");
211+
212+
VariableItem* loop_setting =
213+
variable_item_list_get(nfc_playlist->views.variable_item_list, NfcPlaylistSettings_Loop);
214+
variable_item_set_current_value_index(loop_setting, nfc_playlist->worker_info.settings->loop);
215+
variable_item_set_current_value_text(
216+
loop_setting, nfc_playlist->worker_info.settings->loop ? "ON" : "OFF");
217+
218+
VariableItem* user_controls_setting = variable_item_list_get(
219+
nfc_playlist->views.variable_item_list, NfcPlaylistSettings_UserControls);
220+
variable_item_set_current_value_index(
221+
user_controls_setting, nfc_playlist->worker_info.settings->user_controls);
222+
variable_item_set_current_value_text(
223+
user_controls_setting, nfc_playlist->worker_info.settings->user_controls ? "ON" : "OFF");
224+
}
225+
159226
bool nfc_playlist_settings_scene_on_event(void* context, SceneManagerEvent event) {
160227
furi_assert(context);
161228
NfcPlaylist* nfc_playlist = context;
162229
bool consumed = false;
163230
if(event.type == SceneManagerEventTypeCustom) {
164231
switch(event.event) {
232+
case NfcPlaylistSettings_SaveSettings: {
233+
nfc_playlist_save_settings(nfc_playlist);
234+
consumed = true;
235+
break;
236+
}
237+
case NfcPlaylistSettings_ReloadSettings: {
238+
nfc_playlist_load_settings(nfc_playlist);
239+
nfc_playlist_settings_update_view(nfc_playlist);
240+
consumed = true;
241+
break;
242+
}
243+
case NfcPlaylistSettings_DeleteSettings: {
244+
nfc_playlist_delete_settings(nfc_playlist);
245+
nfc_playlist_settings_update_view(nfc_playlist);
246+
consumed = true;
247+
break;
248+
}
165249
case NfcPlaylistSettings_Reset: {
166-
FuriString* tmp_str = furi_string_alloc();
167-
168250
nfc_playlist->worker_info.settings->emulate_timeout = default_emulate_timeout;
169-
VariableItem* emulation_timeout_setting = variable_item_list_get(
170-
nfc_playlist->views.variable_item_list, NfcPlaylistSettings_Timeout);
171-
variable_item_set_current_value_index(
172-
emulation_timeout_setting, nfc_playlist->worker_info.settings->emulate_timeout);
173-
furi_string_printf(
174-
tmp_str,
175-
"%ds",
176-
options_emulate_timeout[nfc_playlist->worker_info.settings->emulate_timeout]);
177-
variable_item_set_current_value_text(
178-
emulation_timeout_setting, furi_string_get_cstr(tmp_str));
179-
180251
nfc_playlist->worker_info.settings->emulate_delay = default_emulate_delay;
181-
VariableItem* emulation_delay_setting = variable_item_list_get(
182-
nfc_playlist->views.variable_item_list, NfcPlaylistSettings_Delay);
183-
variable_item_set_current_value_index(
184-
emulation_delay_setting, nfc_playlist->worker_info.settings->emulate_delay);
185-
furi_string_printf(
186-
tmp_str,
187-
"%ds",
188-
options_emulate_delay[nfc_playlist->worker_info.settings->emulate_delay]);
189-
variable_item_set_current_value_text(
190-
emulation_delay_setting, furi_string_get_cstr(tmp_str));
191-
192-
furi_string_free(tmp_str);
193-
194252
nfc_playlist->worker_info.settings->emulate_led_indicator = default_emulate_led_indicator;
195-
VariableItem* emulation_led_indicator_setting = variable_item_list_get(
196-
nfc_playlist->views.variable_item_list, NfcPlaylistSettings_LedIndicator);
197-
variable_item_set_current_value_index(
198-
emulation_led_indicator_setting,
199-
nfc_playlist->worker_info.settings->emulate_led_indicator);
200-
variable_item_set_current_value_text(
201-
emulation_led_indicator_setting,
202-
nfc_playlist->worker_info.settings->emulate_led_indicator ? "ON" : "OFF");
203-
204253
nfc_playlist->worker_info.settings->skip_error = default_skip_error;
205-
VariableItem* emulation_skip_error_setting = variable_item_list_get(
206-
nfc_playlist->views.variable_item_list, NfcPlaylistSettings_SkipError);
207-
variable_item_set_current_value_index(
208-
emulation_skip_error_setting, nfc_playlist->worker_info.settings->skip_error);
209-
variable_item_set_current_value_text(
210-
emulation_skip_error_setting,
211-
nfc_playlist->worker_info.settings->skip_error ? "ON" : "OFF");
212-
213254
nfc_playlist->worker_info.settings->loop = default_loop;
214-
VariableItem* loop_setting = variable_item_list_get(
215-
nfc_playlist->views.variable_item_list, NfcPlaylistSettings_Loop);
216-
variable_item_set_current_value_index(
217-
loop_setting, nfc_playlist->worker_info.settings->loop);
218-
variable_item_set_current_value_text(
219-
loop_setting, nfc_playlist->worker_info.settings->loop ? "ON" : "OFF");
220-
221255
nfc_playlist->worker_info.settings->user_controls = default_user_controls;
222-
VariableItem* user_controls_setting = variable_item_list_get(
223-
nfc_playlist->views.variable_item_list, NfcPlaylistSettings_UserControls);
224-
variable_item_set_current_value_index(
225-
user_controls_setting, nfc_playlist->worker_info.settings->user_controls);
226-
variable_item_set_current_value_text(
227-
user_controls_setting,
228-
nfc_playlist->worker_info.settings->user_controls ? "ON" : "OFF");
256+
257+
nfc_playlist_settings_update_view(nfc_playlist);
229258

230259
consumed = true;
231260
break;

0 commit comments

Comments
 (0)