Просмотр исходного кода

Merge nfc_playlist from https://github.com/acegoal07/FlipperZero_NFC_Playlist

Willy-JL 1 год назад
Родитель
Сommit
fe76bafcd8

+ 2 - 2
nfc_playlist/application.fam

@@ -8,9 +8,9 @@ App(
     fap_category="NFC",
     fap_category="NFC",
     fap_author="@acegoal07",
     fap_author="@acegoal07",
     fap_weburl="https://github.com/acegoal07/FlipperZero_NFC_Playlist/tree/main",
     fap_weburl="https://github.com/acegoal07/FlipperZero_NFC_Playlist/tree/main",
-    fap_version="2.2",
+    fap_version="2.3",
     fap_icon_assets="assets",
     fap_icon_assets="assets",
-    fap_icon="icon.png",
+    fap_icon="assets/Playlist_10px.png",
     fap_private_libs=[
     fap_private_libs=[
         Lib(
         Lib(
             name="emulation_worker",
             name="emulation_worker",

BIN
nfc_playlist/assets/Playlist_10px.png


BIN
nfc_playlist/assets/unknown_10px.png


BIN
nfc_playlist/icon.png


+ 7 - 2
nfc_playlist/nfc_playlist.c

@@ -149,10 +149,15 @@ const NotificationSequence blink_sequence_error = {
 
 
 void start_blink(NfcPlaylist* nfc_playlist, int state) {
 void start_blink(NfcPlaylist* nfc_playlist, int state) {
     if(nfc_playlist->settings.emulate_led_indicator) {
     if(nfc_playlist->settings.emulate_led_indicator) {
-        if(state == NfcPlaylistLedState_Normal) {
+        switch(state) {
+        case NfcPlaylistLedState_Normal:
             notification_message_block(nfc_playlist->notification, &blink_sequence_normal);
             notification_message_block(nfc_playlist->notification, &blink_sequence_normal);
-        } else if(state == NfcPlaylistLedState_Error) {
+            break;
+        case NfcPlaylistLedState_Error:
             notification_message_block(nfc_playlist->notification, &blink_sequence_error);
             notification_message_block(nfc_playlist->notification, &blink_sequence_error);
+            break;
+        default:
+            break;
         }
         }
     }
     }
 }
 }

+ 1 - 1
nfc_playlist/scenes/nfc_playlist_scene_config.h

@@ -4,7 +4,7 @@ ADD_SCENE(nfc_playlist, playlist_edit, PlaylistEdit)
 ADD_SCENE(nfc_playlist, playlist_rename, PlaylistRename)
 ADD_SCENE(nfc_playlist, playlist_rename, PlaylistRename)
 ADD_SCENE(nfc_playlist, main_menu, MainMenu)
 ADD_SCENE(nfc_playlist, main_menu, MainMenu)
 ADD_SCENE(nfc_playlist, name_new_playlist, NameNewPlaylist)
 ADD_SCENE(nfc_playlist, name_new_playlist, NameNewPlaylist)
-ADD_SCENE(nfc_playlist, nfc_select, NfcSelect)
+ADD_SCENE(nfc_playlist, nfc_add, NfcAdd)
 ADD_SCENE(nfc_playlist, nfc_remove, NfcRemove)
 ADD_SCENE(nfc_playlist, nfc_remove, NfcRemove)
 ADD_SCENE(nfc_playlist, playlist_select, PlaylistSelect)
 ADD_SCENE(nfc_playlist, playlist_select, PlaylistSelect)
 ADD_SCENE(nfc_playlist, settings, Settings)
 ADD_SCENE(nfc_playlist, settings, Settings)

+ 1 - 1
nfc_playlist/scenes/nfc_playlist_scene_confirm_delete.c

@@ -15,6 +15,7 @@ void nfc_playlist_confirm_delete_scene_on_enter(void* context) {
         furi_string_get_cstr(nfc_playlist->settings.playlist_path), file_name);
         furi_string_get_cstr(nfc_playlist->settings.playlist_path), file_name);
     FuriString* temp_str =
     FuriString* temp_str =
         furi_string_alloc_printf("\e#Delete %s?\e#", furi_string_get_cstr(file_name));
         furi_string_alloc_printf("\e#Delete %s?\e#", furi_string_get_cstr(file_name));
+    furi_string_free(file_name);
 
 
     widget_add_text_box_element(
     widget_add_text_box_element(
         nfc_playlist->widget,
         nfc_playlist->widget,
@@ -40,7 +41,6 @@ void nfc_playlist_confirm_delete_scene_on_enter(void* context) {
         nfc_playlist);
         nfc_playlist);
 
 
     furi_string_free(temp_str);
     furi_string_free(temp_str);
-    furi_string_free(file_name);
 
 
     view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Widget);
     view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Widget);
 }
 }

+ 56 - 46
nfc_playlist/scenes/nfc_playlist_scene_emulation.c

@@ -20,13 +20,20 @@ int32_t nfc_playlist_emulation_task(void* context) {
 
 
     view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup);
     view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup);
 
 
-    if(file_stream_open(
-           stream,
-           furi_string_get_cstr(nfc_playlist->settings.playlist_path),
-           FSAM_READ,
-           FSOM_OPEN_EXISTING)) {
+    if(nfc_playlist->settings.playlist_length == 0) {
+        popup_set_header(
+            nfc_playlist->popup,
+            "The playlist you have\nselected is empty",
+            64,
+            10,
+            AlignCenter,
+            AlignTop);
+    } else if(file_stream_open(
+                  stream,
+                  furi_string_get_cstr(nfc_playlist->settings.playlist_path),
+                  FSAM_READ,
+                  FSOM_OPEN_EXISTING)) {
         EmulationState = NfcPlaylistEmulationState_Emulating;
         EmulationState = NfcPlaylistEmulationState_Emulating;
-        int file_position = 0;
 
 
         FuriString* line = furi_string_alloc();
         FuriString* line = furi_string_alloc();
         FuriString* tmp_header_str = furi_string_alloc();
         FuriString* tmp_header_str = furi_string_alloc();
@@ -34,6 +41,9 @@ int32_t nfc_playlist_emulation_task(void* context) {
         FuriString* tmp_file_name = furi_string_alloc();
         FuriString* tmp_file_name = furi_string_alloc();
         FuriString* tmp_file_ext = furi_string_alloc();
         FuriString* tmp_file_ext = furi_string_alloc();
 
 
+        bool delay_setting_on = nfc_playlist->settings.emulate_delay > 0;
+        bool delay_active = false;
+
         while(stream_read_line(stream, line) &&
         while(stream_read_line(stream, line) &&
               EmulationState == NfcPlaylistEmulationState_Emulating) {
               EmulationState == NfcPlaylistEmulationState_Emulating) {
             char* file_path = (char*)furi_string_get_cstr(line);
             char* file_path = (char*)furi_string_get_cstr(line);
@@ -42,28 +52,31 @@ int32_t nfc_playlist_emulation_task(void* context) {
                 continue;
                 continue;
             }
             }
 
 
-            if(nfc_playlist->settings.emulate_delay > 0 && file_position != 0 && !skip_delay) {
-                popup_set_header(nfc_playlist->popup, "Delaying", 64, 10, AlignCenter, AlignTop);
-                start_blink(nfc_playlist, NfcPlaylistLedState_Error);
-                int time_counter_delay_ms =
-                    (options_emulate_delay[nfc_playlist->settings.emulate_delay] * 1000);
-                while(time_counter_delay_ms > 0 &&
-                      EmulationState == NfcPlaylistEmulationState_Emulating) {
-                    furi_string_printf(tmp_counter_str, "%ds", (time_counter_delay_ms / 1000));
-                    popup_set_text(
-                        nfc_playlist->popup,
-                        furi_string_get_cstr(tmp_counter_str),
-                        64,
-                        50,
-                        AlignCenter,
-                        AlignTop);
-                    furi_delay_ms(50);
-                    time_counter_delay_ms -= 50;
-                    furi_string_reset(tmp_counter_str);
-                };
-            } else if(nfc_playlist->settings.emulate_delay > 0) {
-                skip_delay = false;
-                file_position++;
+            if(delay_setting_on) {
+                if(delay_active && !skip_delay) {
+                    popup_set_header(
+                        nfc_playlist->popup, "Delaying", 64, 10, AlignCenter, AlignTop);
+                    start_blink(nfc_playlist, NfcPlaylistLedState_Error);
+                    int time_counter_delay_ms =
+                        (options_emulate_delay[nfc_playlist->settings.emulate_delay] * 1000);
+                    while(time_counter_delay_ms > 0 &&
+                          EmulationState == NfcPlaylistEmulationState_Emulating) {
+                        furi_string_printf(tmp_counter_str, "%ds", (time_counter_delay_ms / 1000));
+                        popup_set_text(
+                            nfc_playlist->popup,
+                            furi_string_get_cstr(tmp_counter_str),
+                            64,
+                            50,
+                            AlignCenter,
+                            AlignTop);
+                        furi_delay_ms(50);
+                        time_counter_delay_ms -= 50;
+                    };
+                } else if(!delay_active) {
+                    delay_active = true;
+                } else if(skip_delay) {
+                    skip_delay = false;
+                }
             }
             }
 
 
             if(EmulationState != NfcPlaylistEmulationState_Emulating) {
             if(EmulationState != NfcPlaylistEmulationState_Emulating) {
@@ -76,7 +89,7 @@ int32_t nfc_playlist_emulation_task(void* context) {
             int time_counter_ms =
             int time_counter_ms =
                 (options_emulate_timeout[nfc_playlist->settings.emulate_timeout] * 1000);
                 (options_emulate_timeout[nfc_playlist->settings.emulate_timeout] * 1000);
 
 
-            if(!furi_string_cmpi_str(tmp_file_ext, "nfc")) {
+            if(!strcasestr(furi_string_get_cstr(tmp_file_ext), ".nfc")) {
                 if(nfc_playlist->settings.skip_error) {
                 if(nfc_playlist->settings.skip_error) {
                     skip_delay = true;
                     skip_delay = true;
                     continue;
                     continue;
@@ -168,38 +181,35 @@ int32_t nfc_playlist_emulation_task(void* context) {
                     nfc_playlist->nfc_playlist_emulation_worker);
                     nfc_playlist->nfc_playlist_emulation_worker);
             }
             }
         }
         }
-        popup_reset(nfc_playlist->popup);
-        if(nfc_playlist->settings.playlist_length == 0) {
-            popup_set_header(nfc_playlist->popup, "Empty playlist", 64, 10, AlignCenter, AlignTop);
-        } else {
-            popup_set_header(
-                nfc_playlist->popup,
-                EmulationState == NfcPlaylistEmulationState_Canceled ? "Emulation stopped" :
-                                                                       "Emulation finished",
-                64,
-                10,
-                AlignCenter,
-                AlignTop);
-        }
-        popup_set_text(nfc_playlist->popup, "Press back", 64, 50, AlignCenter, AlignTop);
         stop_blink(nfc_playlist);
         stop_blink(nfc_playlist);
 
 
-        EmulationState = NfcPlaylistEmulationState_Stopped;
         furi_string_free(line);
         furi_string_free(line);
         furi_string_free(tmp_header_str);
         furi_string_free(tmp_header_str);
         furi_string_free(tmp_counter_str);
         furi_string_free(tmp_counter_str);
         furi_string_free(tmp_file_name);
         furi_string_free(tmp_file_name);
         furi_string_free(tmp_file_ext);
         furi_string_free(tmp_file_ext);
+        file_stream_close(stream);
+
+        popup_reset(nfc_playlist->popup);
+        popup_set_header(
+            nfc_playlist->popup,
+            EmulationState == NfcPlaylistEmulationState_Canceled ? "Emulation stopped" :
+                                                                   "Emulation finished",
+            64,
+            10,
+            AlignCenter,
+            AlignTop);
     } else {
     } else {
         popup_set_header(
         popup_set_header(
             nfc_playlist->popup, "Failed to open playlist", 64, 10, AlignCenter, AlignTop);
             nfc_playlist->popup, "Failed to open playlist", 64, 10, AlignCenter, AlignTop);
-        popup_set_text(nfc_playlist->popup, "Press back", 64, 50, AlignCenter, AlignTop);
     }
     }
+    popup_set_text(nfc_playlist->popup, "Press back", 64, 50, AlignCenter, AlignTop);
 
 
-    file_stream_close(stream);
     furi_record_close(RECORD_STORAGE);
     furi_record_close(RECORD_STORAGE);
     stream_free(stream);
     stream_free(stream);
 
 
+    EmulationState = NfcPlaylistEmulationState_Stopped;
+
     return 0;
     return 0;
 }
 }
 
 

+ 6 - 6
nfc_playlist/scenes/nfc_playlist_scene_nfc_select.c → nfc_playlist/scenes/nfc_playlist_scene_nfc_add.c

@@ -1,6 +1,6 @@
 #include "../nfc_playlist.h"
 #include "../nfc_playlist.h"
 
 
-void nfc_playlist_nfc_select_menu_callback(void* context) {
+void nfc_playlist_nfc_add_menu_callback(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
 
 
     Storage* storage = furi_record_open(RECORD_STORAGE);
     Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -16,6 +16,7 @@ void nfc_playlist_nfc_select_menu_callback(void* context) {
         while(stream_read_line(stream, line)) {
         while(stream_read_line(stream, line)) {
             furi_string_cat_printf(tmp_str, "%s", furi_string_get_cstr(line));
             furi_string_cat_printf(tmp_str, "%s", furi_string_get_cstr(line));
         }
         }
+        furi_string_free(line);
 
 
         if(!furi_string_empty(tmp_str)) {
         if(!furi_string_empty(tmp_str)) {
             furi_string_cat_printf(
             furi_string_cat_printf(
@@ -26,7 +27,6 @@ void nfc_playlist_nfc_select_menu_callback(void* context) {
         }
         }
 
 
         stream_clean(stream);
         stream_clean(stream);
-        furi_string_free(line);
         stream_write_string(stream, tmp_str);
         stream_write_string(stream, tmp_str);
         file_stream_close(stream);
         file_stream_close(stream);
         furi_string_free(tmp_str);
         furi_string_free(tmp_str);
@@ -40,12 +40,12 @@ void nfc_playlist_nfc_select_menu_callback(void* context) {
     scene_manager_previous_scene(nfc_playlist->scene_manager);
     scene_manager_previous_scene(nfc_playlist->scene_manager);
 }
 }
 
 
-void nfc_playlist_nfc_select_scene_on_enter(void* context) {
+void nfc_playlist_nfc_add_scene_on_enter(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     file_browser_configure(
     file_browser_configure(
         nfc_playlist->file_browser, ".nfc", "/ext/nfc/", true, true, &I_Nfc_10px, true);
         nfc_playlist->file_browser, ".nfc", "/ext/nfc/", true, true, &I_Nfc_10px, true);
     file_browser_set_callback(
     file_browser_set_callback(
-        nfc_playlist->file_browser, nfc_playlist_nfc_select_menu_callback, nfc_playlist);
+        nfc_playlist->file_browser, nfc_playlist_nfc_add_menu_callback, nfc_playlist);
     FuriString* tmp_str = furi_string_alloc_set_str("/ext/nfc/");
     FuriString* tmp_str = furi_string_alloc_set_str("/ext/nfc/");
     file_browser_start(nfc_playlist->file_browser, tmp_str);
     file_browser_start(nfc_playlist->file_browser, tmp_str);
     furi_string_free(tmp_str);
     furi_string_free(tmp_str);
@@ -53,13 +53,13 @@ void nfc_playlist_nfc_select_scene_on_enter(void* context) {
     view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_FileBrowser);
     view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_FileBrowser);
 }
 }
 
 
-bool nfc_playlist_nfc_select_scene_on_event(void* context, SceneManagerEvent event) {
+bool nfc_playlist_nfc_add_scene_on_event(void* context, SceneManagerEvent event) {
     UNUSED(event);
     UNUSED(event);
     UNUSED(context);
     UNUSED(context);
     return false;
     return false;
 }
 }
 
 
-void nfc_playlist_nfc_select_scene_on_exit(void* context) {
+void nfc_playlist_nfc_add_scene_on_exit(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     file_browser_stop(nfc_playlist->file_browser);
     file_browser_stop(nfc_playlist->file_browser);
 }
 }

+ 1 - 1
nfc_playlist/scenes/nfc_playlist_scene_nfc_remove.c

@@ -99,8 +99,8 @@ bool nfc_playlist_nfc_remove_scene_on_event(void* context, SceneManagerEvent eve
                     }
                     }
                 }
                 }
 
 
-                stream_clean(stream);
                 furi_string_free(line);
                 furi_string_free(line);
+                stream_clean(stream);
                 stream_write_string(stream, tmp_str);
                 stream_write_string(stream, tmp_str);
                 furi_string_free(tmp_str);
                 furi_string_free(tmp_str);
                 file_stream_close(stream);
                 file_stream_close(stream);

+ 1 - 1
nfc_playlist/scenes/nfc_playlist_scene_playlist_edit.c

@@ -95,7 +95,7 @@ bool nfc_playlist_playlist_edit_scene_on_event(void* context, SceneManagerEvent
             consumed = true;
             consumed = true;
             break;
             break;
         case NfcPlaylistMenuSelection_AddNfcItem:
         case NfcPlaylistMenuSelection_AddNfcItem:
-            scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_NfcSelect);
+            scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_NfcAdd);
             consumed = true;
             consumed = true;
             break;
             break;
         case NfcPlaylistMenuSelection_RemoveNfcItem:
         case NfcPlaylistMenuSelection_RemoveNfcItem:

+ 19 - 15
nfc_playlist/scenes/nfc_playlist_scene_playlist_rename.c

@@ -3,22 +3,28 @@
 int32_t nfc_playlist_playlist_rename_thread_task(void* context) {
 int32_t nfc_playlist_playlist_rename_thread_task(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
 
 
-    char const* old_file_path = furi_string_get_cstr(nfc_playlist->settings.playlist_path);
-    char const* old_file_name =
-        strchr(old_file_path, '/') != NULL ? &strrchr(old_file_path, '/')[1] : old_file_path;
-    FuriString* new_file_path = furi_string_alloc_set_str(old_file_path);
-    furi_string_replace(new_file_path, old_file_name, nfc_playlist->text_input_output);
+    FuriString* old_file_path = furi_string_alloc();
+    path_extract_dirname(
+        furi_string_get_cstr(nfc_playlist->settings.playlist_path), old_file_path);
+    FuriString* new_file_path = furi_string_alloc_set(old_file_path);
+    path_concat(
+        furi_string_get_cstr(old_file_path), nfc_playlist->text_input_output, new_file_path);
+    furi_string_free(old_file_path);
     furi_string_cat_str(new_file_path, ".txt");
     furi_string_cat_str(new_file_path, ".txt");
 
 
     Storage* storage = furi_record_open(RECORD_STORAGE);
     Storage* storage = furi_record_open(RECORD_STORAGE);
 
 
     if(!storage_file_exists(storage, furi_string_get_cstr(new_file_path))) {
     if(!storage_file_exists(storage, furi_string_get_cstr(new_file_path))) {
-        if(storage_common_rename(storage, old_file_path, furi_string_get_cstr(new_file_path)) ==
-           0) {
-            furi_string_move(nfc_playlist->settings.playlist_path, new_file_path);
+        if(storage_common_rename(
+               storage,
+               furi_string_get_cstr(nfc_playlist->settings.playlist_path),
+               furi_string_get_cstr(new_file_path)) == FSE_OK) {
+            furi_string_swap(nfc_playlist->settings.playlist_path, new_file_path);
         }
         }
     }
     }
 
 
+    furi_string_free(new_file_path);
+
     furi_record_close(RECORD_STORAGE);
     furi_record_close(RECORD_STORAGE);
 
 
     return 0;
     return 0;
@@ -47,15 +53,13 @@ void nfc_playlist_playlist_rename_menu_callback(void* context) {
 void nfc_playlist_playlist_rename_scene_on_enter(void* context) {
 void nfc_playlist_playlist_rename_scene_on_enter(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
 
 
-    char const* tmp_file_path = furi_string_get_cstr(nfc_playlist->settings.playlist_path);
-    char const* tmp_file_name =
-        strchr(tmp_file_path, '/') != NULL ? &strrchr(tmp_file_path, '/')[1] : tmp_file_path;
-    FuriString* tmp_file_name_furi = furi_string_alloc_set_str(tmp_file_name);
-    furi_string_replace(tmp_file_name_furi, ".txt", "");
+    FuriString* tmp_file_name = furi_string_alloc();
+    path_extract_filename_no_ext(
+        furi_string_get_cstr(nfc_playlist->settings.playlist_path), tmp_file_name);
 
 
     nfc_playlist->text_input_output = malloc(MAX_PLAYLIST_NAME_LEN + 1);
     nfc_playlist->text_input_output = malloc(MAX_PLAYLIST_NAME_LEN + 1);
-    strcpy(nfc_playlist->text_input_output, furi_string_get_cstr(tmp_file_name_furi));
-    furi_string_free(tmp_file_name_furi);
+    strcpy(nfc_playlist->text_input_output, furi_string_get_cstr(tmp_file_name));
+    furi_string_free(tmp_file_name);
 
 
     text_input_set_header_text(nfc_playlist->text_input, "Enter new file name");
     text_input_set_header_text(nfc_playlist->text_input, "Enter new file name");
     text_input_set_minimum_length(nfc_playlist->text_input, 1);
     text_input_set_minimum_length(nfc_playlist->text_input, 1);

+ 1 - 1
nfc_playlist/scenes/nfc_playlist_scene_playlist_select.c

@@ -31,7 +31,7 @@ void nfc_playlist_playlist_select_menu_callback(void* context) {
 void nfc_playlist_playlist_select_scene_on_enter(void* context) {
 void nfc_playlist_playlist_select_scene_on_enter(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     file_browser_configure(
     file_browser_configure(
-        nfc_playlist->file_browser, ".txt", PLAYLIST_LOCATION, true, true, &I_unknown_10px, true);
+        nfc_playlist->file_browser, ".txt", PLAYLIST_LOCATION, true, true, &I_Playlist_10px, true);
     file_browser_set_callback(
     file_browser_set_callback(
         nfc_playlist->file_browser, nfc_playlist_playlist_select_menu_callback, nfc_playlist);
         nfc_playlist->file_browser, nfc_playlist_playlist_select_menu_callback, nfc_playlist);
     FuriString* tmp_str = furi_string_alloc_set_str(PLAYLIST_LOCATION);
     FuriString* tmp_str = furi_string_alloc_set_str(PLAYLIST_LOCATION);

+ 4 - 2
nfc_playlist/scenes/nfc_playlist_scene_settings.c

@@ -82,6 +82,8 @@ void nfc_playlist_settings_scene_on_enter(void* context) {
         tmp_str, "%ds", options_emulate_delay[nfc_playlist->settings.emulate_delay]);
         tmp_str, "%ds", options_emulate_delay[nfc_playlist->settings.emulate_delay]);
     variable_item_set_current_value_text(emulation_delay_setting, furi_string_get_cstr(tmp_str));
     variable_item_set_current_value_text(emulation_delay_setting, furi_string_get_cstr(tmp_str));
 
 
+    furi_string_free(tmp_str);
+
     VariableItem* emulation_led_indicator_setting = variable_item_list_add(
     VariableItem* emulation_led_indicator_setting = variable_item_list_add(
         nfc_playlist->variable_item_list,
         nfc_playlist->variable_item_list,
         "LED Indicator",
         "LED Indicator",
@@ -113,7 +115,6 @@ void nfc_playlist_settings_scene_on_enter(void* context) {
 
 
     variable_item_list_set_enter_callback(
     variable_item_list_set_enter_callback(
         nfc_playlist->variable_item_list, nfc_playlist_settings_menu_callback, nfc_playlist);
         nfc_playlist->variable_item_list, nfc_playlist_settings_menu_callback, nfc_playlist);
-    furi_string_free(tmp_str);
 
 
     view_dispatcher_switch_to_view(
     view_dispatcher_switch_to_view(
         nfc_playlist->view_dispatcher, NfcPlaylistView_VariableItemList);
         nfc_playlist->view_dispatcher, NfcPlaylistView_VariableItemList);
@@ -147,6 +148,8 @@ bool nfc_playlist_settings_scene_on_event(void* context, SceneManagerEvent event
             variable_item_set_current_value_text(
             variable_item_set_current_value_text(
                 emulation_delay_setting, furi_string_get_cstr(tmp_str));
                 emulation_delay_setting, furi_string_get_cstr(tmp_str));
 
 
+            furi_string_free(tmp_str);
+
             nfc_playlist->settings.emulate_led_indicator = default_emulate_led_indicator;
             nfc_playlist->settings.emulate_led_indicator = default_emulate_led_indicator;
             VariableItem* emulation_led_indicator_setting = variable_item_list_get(
             VariableItem* emulation_led_indicator_setting = variable_item_list_get(
                 nfc_playlist->variable_item_list, NfcPlaylistSettings_LedIndicator);
                 nfc_playlist->variable_item_list, NfcPlaylistSettings_LedIndicator);
@@ -164,7 +167,6 @@ bool nfc_playlist_settings_scene_on_event(void* context, SceneManagerEvent event
             variable_item_set_current_value_text(
             variable_item_set_current_value_text(
                 emulation_skip_error_setting, nfc_playlist->settings.skip_error ? "ON" : "OFF");
                 emulation_skip_error_setting, nfc_playlist->settings.skip_error ? "ON" : "OFF");
 
 
-            furi_string_free(tmp_str);
             consumed = true;
             consumed = true;
             break;
             break;
         default:
         default: