فهرست منبع

upd nfc playlist

and apply patch for missing api funcs
MX 1 سال پیش
والد
کامیت
7d3deb8f2b

+ 4 - 1
README.md

@@ -13,7 +13,6 @@ An example file can be found in the repository
 This app was design, built and tested using the <a href="https://github.com/Next-Flip/Momentum-Firmware">Momentum</a> so keep that in mind when building the FAP for yourself
 This app was design, built and tested using the <a href="https://github.com/Next-Flip/Momentum-Firmware">Momentum</a> so keep that in mind when building the FAP for yourself
 ## Supported Firmwares
 ## Supported Firmwares
 As i know these firmwares are supported and working if you know any more please let me know
 As i know these firmwares are supported and working if you know any more please let me know
-- <a href="https://github.com/Flipper-XFW/Xtreme-Firmware">Xtreme</a>
 - <a href="https://github.com/Next-Flip/Momentum-Firmware">Momentum</a>
 - <a href="https://github.com/Next-Flip/Momentum-Firmware">Momentum</a>
 - <a href="https://github.com/RogueMaster/flipperzero-firmware-wPlugins">RogueMaster</a>
 - <a href="https://github.com/RogueMaster/flipperzero-firmware-wPlugins">RogueMaster</a>
 ## Settings:
 ## Settings:
@@ -28,6 +27,10 @@ As i know these firmwares are supported and working if you know any more please
 - Rename playlist (Renames the selected playlist to the new name provided)
 - Rename playlist (Renames the selected playlist to the new name provided)
 - Add NFC Item (Adds the selected nfc item to the currently selected playlist)
 - Add NFC Item (Adds the selected nfc item to the currently selected playlist)
 - Remove NFC Item (Opens a menu allowing you to select a line to remove from the playlist)
 - Remove NFC Item (Opens a menu allowing you to select a line to remove from the playlist)
+- Move NFC Item (Allows you to change the order of the NFC items in the playlist)
 - View playlist content (Allows you to view the contents of the playlist)
 - View playlist content (Allows you to view the contents of the playlist)
+## Feature ideas:
+- A function to allow you to add multiple nfc items to a playlist at once
+- A view playlist function which only shows the name of the playlist items excluding the file path
 
 
 Any feedback is welcome and would be very much appreciated
 Any feedback is welcome and would be very much appreciated

+ 1 - 1
application.fam

@@ -8,7 +8,7 @@ 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.3",
+    fap_version="2.5",
     fap_icon_assets="assets",
     fap_icon_assets="assets",
     fap_icon="assets/Playlist_10px.png",
     fap_icon="assets/Playlist_10px.png",
     fap_private_libs=[
     fap_private_libs=[

+ 46 - 57
lib/emulation_worker/nfc_playlist_emulation_worker.c

@@ -1,84 +1,73 @@
 #include "nfc_playlist_emulation_worker.h"
 #include "nfc_playlist_emulation_worker.h"
 
 
 NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker_alloc() {
 NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker_alloc() {
-    NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker =
-        malloc(sizeof(NfcPlaylistEmulationWorker));
-    nfc_playlist_emulation_worker->thread = furi_thread_alloc_ex(
-        "NfcPlaylistEmulationWorker",
-        4096,
-        nfc_playlist_emulation_worker_task,
-        nfc_playlist_emulation_worker);
-    nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Stopped;
-    nfc_playlist_emulation_worker->nfc = nfc_alloc();
-    nfc_playlist_emulation_worker->nfc_device = nfc_device_alloc();
-    return nfc_playlist_emulation_worker;
+   NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker = malloc(sizeof(NfcPlaylistEmulationWorker));
+   nfc_playlist_emulation_worker->thread = furi_thread_alloc_ex("NfcPlaylistEmulationWorker", 4096, nfc_playlist_emulation_worker_task, nfc_playlist_emulation_worker);
+   nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Stopped;
+   nfc_playlist_emulation_worker->nfc = nfc_alloc();
+   nfc_playlist_emulation_worker->nfc_device = nfc_device_alloc();
+   return nfc_playlist_emulation_worker;
 }
 }
 
 
 void nfc_playlist_emulation_worker_free(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
 void nfc_playlist_emulation_worker_free(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
-    furi_assert(nfc_playlist_emulation_worker);
-    furi_thread_free(nfc_playlist_emulation_worker->thread);
-    nfc_free(nfc_playlist_emulation_worker->nfc);
-    nfc_device_free(nfc_playlist_emulation_worker->nfc_device);
-    free(nfc_playlist_emulation_worker);
+   furi_assert(nfc_playlist_emulation_worker);
+   furi_thread_free(nfc_playlist_emulation_worker->thread);
+   nfc_free(nfc_playlist_emulation_worker->nfc);
+   nfc_device_free(nfc_playlist_emulation_worker->nfc_device);
+   free(nfc_playlist_emulation_worker);
 }
 }
 
 
 void nfc_playlist_emulation_worker_stop(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
 void nfc_playlist_emulation_worker_stop(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
-    furi_assert(nfc_playlist_emulation_worker);
-    if(nfc_playlist_emulation_worker->state != NfcPlaylistEmulationWorkerState_Stopped) {
-        nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Stopped;
-        furi_thread_join(nfc_playlist_emulation_worker->thread);
-    }
+   furi_assert(nfc_playlist_emulation_worker);
+   if (nfc_playlist_emulation_worker->state != NfcPlaylistEmulationWorkerState_Stopped) {
+      nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Stopped;
+      furi_thread_join(nfc_playlist_emulation_worker->thread);
+   }
 }
 }
 
 
-void nfc_playlist_emulation_worker_start(
-    NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
-    furi_assert(nfc_playlist_emulation_worker);
-    nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Emulating;
-    furi_thread_start(nfc_playlist_emulation_worker->thread);
+void nfc_playlist_emulation_worker_start(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
+   furi_assert(nfc_playlist_emulation_worker);
+   nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Emulating;
+   furi_thread_start(nfc_playlist_emulation_worker->thread);
 }
 }
 
 
 int32_t nfc_playlist_emulation_worker_task(void* context) {
 int32_t nfc_playlist_emulation_worker_task(void* context) {
-    NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker = context;
+   NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker = context;
 
 
-    if(nfc_playlist_emulation_worker->state == NfcPlaylistEmulationWorkerState_Emulating) {
-        nfc_playlist_emulation_worker->nfc_listener = nfc_listener_alloc(
-            nfc_playlist_emulation_worker->nfc,
+   if (nfc_playlist_emulation_worker->state == NfcPlaylistEmulationWorkerState_Emulating) {
+
+      nfc_playlist_emulation_worker->nfc_listener =
+         nfc_listener_alloc(nfc_playlist_emulation_worker->nfc,
             nfc_playlist_emulation_worker->nfc_protocol,
             nfc_playlist_emulation_worker->nfc_protocol,
-            nfc_device_get_data(
-                nfc_playlist_emulation_worker->nfc_device,
-                nfc_playlist_emulation_worker->nfc_protocol));
-        nfc_listener_start(nfc_playlist_emulation_worker->nfc_listener, NULL, NULL);
+            nfc_device_get_data(nfc_playlist_emulation_worker->nfc_device, nfc_playlist_emulation_worker->nfc_protocol)
+         );
+      nfc_listener_start(nfc_playlist_emulation_worker->nfc_listener, NULL, NULL);
 
 
-        while(nfc_playlist_emulation_worker->state == NfcPlaylistEmulationWorkerState_Emulating) {
-            furi_delay_ms(50);
-        }
+      while(nfc_playlist_emulation_worker->state == NfcPlaylistEmulationWorkerState_Emulating) {
+         furi_delay_ms(50);
+      }
 
 
-        nfc_listener_stop(nfc_playlist_emulation_worker->nfc_listener);
-        nfc_listener_free(nfc_playlist_emulation_worker->nfc_listener);
-    }
+      nfc_listener_stop(nfc_playlist_emulation_worker->nfc_listener);
+      nfc_listener_free(nfc_playlist_emulation_worker->nfc_listener);
+   }
 
 
-    nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Stopped;
+   nfc_playlist_emulation_worker->state = NfcPlaylistEmulationWorkerState_Stopped;
 
 
-    return 0;
+   return 0;
 }
 }
 
 
-bool nfc_playlist_emulation_worker_is_emulating(
-    NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
-    furi_assert(nfc_playlist_emulation_worker);
-    return nfc_playlist_emulation_worker->state == NfcPlaylistEmulationWorkerState_Emulating;
+bool nfc_playlist_emulation_worker_is_emulating(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
+   furi_assert(nfc_playlist_emulation_worker);
+   return nfc_playlist_emulation_worker->state == NfcPlaylistEmulationWorkerState_Emulating;
 }
 }
 
 
-void nfc_playlist_emulation_worker_set_nfc_data(
-    NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker,
-    char* file_path) {
-    furi_assert(nfc_playlist_emulation_worker);
-    nfc_device_load(nfc_playlist_emulation_worker->nfc_device, file_path);
-    nfc_playlist_emulation_worker->nfc_protocol =
-        nfc_device_get_protocol(nfc_playlist_emulation_worker->nfc_device);
+void nfc_playlist_emulation_worker_set_nfc_data(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker, char* file_path) {
+   furi_assert(nfc_playlist_emulation_worker);
+   nfc_device_load(nfc_playlist_emulation_worker->nfc_device, file_path);
+   nfc_playlist_emulation_worker->nfc_protocol = nfc_device_get_protocol(nfc_playlist_emulation_worker->nfc_device);
 }
 }
 
 
-void nfc_playlist_emulation_worker_clear_nfc_data(
-    NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
-    furi_assert(nfc_playlist_emulation_worker);
-    nfc_device_clear(nfc_playlist_emulation_worker->nfc_device);
+void nfc_playlist_emulation_worker_clear_nfc_data(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker) {
+   furi_assert(nfc_playlist_emulation_worker);
+   nfc_device_clear(nfc_playlist_emulation_worker->nfc_device);
 }
 }

+ 11 - 15
lib/emulation_worker/nfc_playlist_emulation_worker.h

@@ -6,17 +6,17 @@
 #include <nfc/nfc_listener.h>
 #include <nfc/nfc_listener.h>
 
 
 typedef enum NfcPlaylistEmulationWorkerState {
 typedef enum NfcPlaylistEmulationWorkerState {
-    NfcPlaylistEmulationWorkerState_Emulating,
-    NfcPlaylistEmulationWorkerState_Stopped
+   NfcPlaylistEmulationWorkerState_Emulating,
+   NfcPlaylistEmulationWorkerState_Stopped
 } NfcPlaylistEmulationWorkerState;
 } NfcPlaylistEmulationWorkerState;
 
 
 typedef struct NfcPlaylistEmulationWorker {
 typedef struct NfcPlaylistEmulationWorker {
-    FuriThread* thread;
-    NfcPlaylistEmulationWorkerState state;
-    NfcListener* nfc_listener;
-    NfcDevice* nfc_device;
-    NfcProtocol nfc_protocol;
-    Nfc* nfc;
+   FuriThread* thread;
+   NfcPlaylistEmulationWorkerState state;
+   NfcListener* nfc_listener;
+   NfcDevice* nfc_device;
+   NfcProtocol nfc_protocol;
+   Nfc* nfc;
 } NfcPlaylistEmulationWorker;
 } NfcPlaylistEmulationWorker;
 
 
 NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker_alloc();
 NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker_alloc();
@@ -26,10 +26,6 @@ void nfc_playlist_emulation_worker_start(NfcPlaylistEmulationWorker* nfc_playlis
 
 
 int32_t nfc_playlist_emulation_worker_task(void* context);
 int32_t nfc_playlist_emulation_worker_task(void* context);
 
 
-bool nfc_playlist_emulation_worker_is_emulating(
-    NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker);
-void nfc_playlist_emulation_worker_set_nfc_data(
-    NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker,
-    char* file_path);
-void nfc_playlist_emulation_worker_clear_nfc_data(
-    NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker);
+bool nfc_playlist_emulation_worker_is_emulating(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker);
+void nfc_playlist_emulation_worker_set_nfc_data(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker, char* file_path);
+void nfc_playlist_emulation_worker_clear_nfc_data(NfcPlaylistEmulationWorker* nfc_playlist_emulation_worker);

+ 1 - 2
nfc_playlist.c

@@ -23,7 +23,6 @@ static NfcPlaylist* nfc_playlist_alloc() {
 
 
     nfc_playlist->settings.playlist_path = furi_string_alloc();
     nfc_playlist->settings.playlist_path = furi_string_alloc();
     nfc_playlist->file_browser_output = furi_string_alloc();
     nfc_playlist->file_browser_output = furi_string_alloc();
-    nfc_playlist->settings.playlist_selected = false;
     nfc_playlist->settings.emulate_timeout = default_emulate_timeout;
     nfc_playlist->settings.emulate_timeout = default_emulate_timeout;
     nfc_playlist->settings.emulate_delay = default_emulate_delay;
     nfc_playlist->settings.emulate_delay = default_emulate_delay;
     nfc_playlist->settings.emulate_led_indicator = default_emulate_led_indicator;
     nfc_playlist->settings.emulate_led_indicator = default_emulate_led_indicator;
@@ -165,4 +164,4 @@ void stop_blink(NfcPlaylist* nfc_playlist) {
     if(nfc_playlist->settings.emulate_led_indicator) {
     if(nfc_playlist->settings.emulate_led_indicator) {
         notification_message_block(nfc_playlist->notification, &sequence_blink_stop);
         notification_message_block(nfc_playlist->notification, &sequence_blink_stop);
     }
     }
-}
+}

+ 5 - 5
nfc_playlist.h

@@ -29,8 +29,9 @@
 
 
 #include "scenes/nfc_playlist_scene.h"
 #include "scenes/nfc_playlist_scene.h"
 
 
-#define PLAYLIST_LOCATION "/ext/apps_data/nfc_playlist/"
-#define PLAYLIST_DIR "/ext/apps_data/nfc_playlist"
+#define PLAYLIST_LOCATION     "/ext/apps_data/nfc_playlist/"
+#define PLAYLIST_DIR          "/ext/apps_data/nfc_playlist"
+#define NFC_ITEM_LOCATION     "/ext/nfc/"
 #define MAX_PLAYLIST_NAME_LEN 50
 #define MAX_PLAYLIST_NAME_LEN 50
 
 
 typedef enum {
 typedef enum {
@@ -45,7 +46,6 @@ typedef enum {
 typedef struct {
 typedef struct {
     FuriString* playlist_path;
     FuriString* playlist_path;
     uint8_t playlist_length;
     uint8_t playlist_length;
-    bool playlist_selected;
     uint8_t emulate_timeout;
     uint8_t emulate_timeout;
     uint8_t emulate_delay;
     uint8_t emulate_delay;
     bool emulate_led_indicator;
     bool emulate_led_indicator;
@@ -71,7 +71,7 @@ typedef struct {
 
 
 static const int options_emulate_timeout[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
 static const int options_emulate_timeout[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
 static const int default_emulate_timeout = 4;
 static const int default_emulate_timeout = 4;
-static const int options_emulate_delay[] = {0, 1, 2, 3, 4, 5, 6};
+static const int options_emulate_delay[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
 static const int default_emulate_delay = 0;
 static const int default_emulate_delay = 0;
 static const bool default_emulate_led_indicator = true;
 static const bool default_emulate_led_indicator = true;
 static const bool default_skip_error = false;
 static const bool default_skip_error = false;
@@ -82,4 +82,4 @@ typedef enum NfcPlaylistLedState {
 } NfcPlaylistLedState;
 } NfcPlaylistLedState;
 
 
 void start_blink(NfcPlaylist* nfc_playlist, int state);
 void start_blink(NfcPlaylist* nfc_playlist, int state);
-void stop_blink(NfcPlaylist* nfc_playlist);
+void stop_blink(NfcPlaylist* nfc_playlist);

+ 1 - 1
scenes/nfc_playlist_scene.c

@@ -27,4 +27,4 @@ const SceneManagerHandlers nfc_playlist_scene_handlers = {
     .on_event_handlers = nfc_playlist_on_event_handlers,
     .on_event_handlers = nfc_playlist_on_event_handlers,
     .on_exit_handlers = nfc_playlist_on_exit_handlers,
     .on_exit_handlers = nfc_playlist_on_exit_handlers,
     .scene_num = NfcPlaylistScene_Count,
     .scene_num = NfcPlaylistScene_Count,
-};
+};

+ 1 - 1
scenes/nfc_playlist_scene.h

@@ -26,4 +26,4 @@ extern const SceneManagerHandlers nfc_playlist_scene_handlers;
 // Generate scene on_exit handlers declaration
 // Generate scene on_exit handlers declaration
 #define ADD_SCENE(prefix, name, id) void prefix##_##name##_scene_on_exit(void* context);
 #define ADD_SCENE(prefix, name, id) void prefix##_##name##_scene_on_exit(void* context);
 #include "nfc_playlist_scene_config.h"
 #include "nfc_playlist_scene_config.h"
-#undef ADD_SCENE
+#undef ADD_SCENE

+ 4 - 3
scenes/nfc_playlist_scene_config.h

@@ -1,11 +1,12 @@
 ADD_SCENE(nfc_playlist, confirm_delete, ConfirmDelete)
 ADD_SCENE(nfc_playlist, confirm_delete, ConfirmDelete)
 ADD_SCENE(nfc_playlist, emulation, Emulation)
 ADD_SCENE(nfc_playlist, emulation, Emulation)
-ADD_SCENE(nfc_playlist, playlist_edit, PlaylistEdit)
-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_add, NfcAdd)
 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, nfc_move_item, NfcMoveItem)
+ADD_SCENE(nfc_playlist, playlist_edit, PlaylistEdit)
+ADD_SCENE(nfc_playlist, playlist_rename, PlaylistRename)
 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)
-ADD_SCENE(nfc_playlist, view_playlist_content, ViewPlaylistContent)
+ADD_SCENE(nfc_playlist, view_playlist_content, ViewPlaylistContent)

+ 5 - 3
scenes/nfc_playlist_scene_confirm_delete.c

@@ -54,7 +54,6 @@ bool nfc_playlist_confirm_delete_scene_on_event(void* context, SceneManagerEvent
             Storage* storage = furi_record_open(RECORD_STORAGE);
             Storage* storage = furi_record_open(RECORD_STORAGE);
             if(storage_simply_remove(
             if(storage_simply_remove(
                    storage, furi_string_get_cstr(nfc_playlist->settings.playlist_path))) {
                    storage, furi_string_get_cstr(nfc_playlist->settings.playlist_path))) {
-                nfc_playlist->settings.playlist_selected = false;
                 furi_string_reset(nfc_playlist->settings.playlist_path);
                 furi_string_reset(nfc_playlist->settings.playlist_path);
             }
             }
             furi_record_close(RECORD_STORAGE);
             furi_record_close(RECORD_STORAGE);
@@ -62,8 +61,11 @@ bool nfc_playlist_confirm_delete_scene_on_event(void* context, SceneManagerEvent
                 nfc_playlist->scene_manager, NfcPlaylistScene_MainMenu);
                 nfc_playlist->scene_manager, NfcPlaylistScene_MainMenu);
             consumed = true;
             consumed = true;
             break;
             break;
-        default:
+        case GuiButtonTypeLeft:
             scene_manager_previous_scene(nfc_playlist->scene_manager);
             scene_manager_previous_scene(nfc_playlist->scene_manager);
+            consumed = true;
+            break;
+        default:
             break;
             break;
         }
         }
     }
     }
@@ -73,4 +75,4 @@ bool nfc_playlist_confirm_delete_scene_on_event(void* context, SceneManagerEvent
 void nfc_playlist_confirm_delete_scene_on_exit(void* context) {
 void nfc_playlist_confirm_delete_scene_on_exit(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     widget_reset(nfc_playlist->widget);
     widget_reset(nfc_playlist->widget);
-}
+}

+ 11 - 10
scenes/nfc_playlist_scene_emulation.c

@@ -13,11 +13,8 @@ int32_t nfc_playlist_emulation_task(void* context) {
 
 
     Storage* storage = furi_record_open(RECORD_STORAGE);
     Storage* storage = furi_record_open(RECORD_STORAGE);
     Stream* stream = file_stream_alloc(storage);
     Stream* stream = file_stream_alloc(storage);
-    bool skip_delay = false;
 
 
-    popup_reset(nfc_playlist->popup);
     popup_set_context(nfc_playlist->popup, nfc_playlist);
     popup_set_context(nfc_playlist->popup, nfc_playlist);
-
     view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup);
     view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup);
 
 
     if(nfc_playlist->settings.playlist_length == 0) {
     if(nfc_playlist->settings.playlist_length == 0) {
@@ -43,12 +40,13 @@ int32_t nfc_playlist_emulation_task(void* context) {
 
 
         bool delay_setting_on = nfc_playlist->settings.emulate_delay > 0;
         bool delay_setting_on = nfc_playlist->settings.emulate_delay > 0;
         bool delay_active = false;
         bool delay_active = false;
+        bool skip_delay = 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);
+            furi_string_trim(line);
 
 
-            if(strspn(file_path, " \t\n\r") == strlen(file_path)) {
+            if(furi_string_empty(line)) {
                 continue;
                 continue;
             }
             }
 
 
@@ -96,7 +94,7 @@ int32_t nfc_playlist_emulation_task(void* context) {
                 }
                 }
                 furi_string_printf(
                 furi_string_printf(
                     tmp_header_str,
                     tmp_header_str,
-                    "ERROR invalid file:\n%s",
+                    "ERROR invalid file type:\n%s",
                     furi_string_get_cstr(tmp_file_name));
                     furi_string_get_cstr(tmp_file_name));
                 popup_set_header(
                 popup_set_header(
                     nfc_playlist->popup,
                     nfc_playlist->popup,
@@ -119,13 +117,15 @@ int32_t nfc_playlist_emulation_task(void* context) {
                     furi_delay_ms(50);
                     furi_delay_ms(50);
                     time_counter_ms -= 50;
                     time_counter_ms -= 50;
                 };
                 };
-            } else if(!storage_file_exists(storage, file_path)) {
+            } else if(!storage_file_exists(storage, furi_string_get_cstr(line))) {
                 if(nfc_playlist->settings.skip_error) {
                 if(nfc_playlist->settings.skip_error) {
                     skip_delay = true;
                     skip_delay = true;
                     continue;
                     continue;
                 }
                 }
                 furi_string_printf(
                 furi_string_printf(
-                    tmp_header_str, "ERROR not found:\n%s", furi_string_get_cstr(tmp_file_name));
+                    tmp_header_str,
+                    "ERROR file not found:\n%s",
+                    furi_string_get_cstr(tmp_file_name));
                 popup_set_header(
                 popup_set_header(
                     nfc_playlist->popup,
                     nfc_playlist->popup,
                     furi_string_get_cstr(tmp_header_str),
                     furi_string_get_cstr(tmp_header_str),
@@ -158,7 +158,8 @@ int32_t nfc_playlist_emulation_task(void* context) {
                     AlignCenter,
                     AlignCenter,
                     AlignTop);
                     AlignTop);
                 nfc_playlist_emulation_worker_set_nfc_data(
                 nfc_playlist_emulation_worker_set_nfc_data(
-                    nfc_playlist->nfc_playlist_emulation_worker, file_path);
+                    nfc_playlist->nfc_playlist_emulation_worker,
+                    (char*)furi_string_get_cstr(line));
                 nfc_playlist_emulation_worker_start(nfc_playlist->nfc_playlist_emulation_worker);
                 nfc_playlist_emulation_worker_start(nfc_playlist->nfc_playlist_emulation_worker);
                 start_blink(nfc_playlist, NfcPlaylistLedState_Normal);
                 start_blink(nfc_playlist, NfcPlaylistLedState_Normal);
                 while(nfc_playlist_emulation_worker_is_emulating(
                 while(nfc_playlist_emulation_worker_is_emulating(
@@ -259,4 +260,4 @@ void nfc_playlist_emulation_scene_on_exit(void* context) {
     nfc_playlist_emulation_stop(nfc_playlist);
     nfc_playlist_emulation_stop(nfc_playlist);
     nfc_playlist_emulation_free(nfc_playlist);
     nfc_playlist_emulation_free(nfc_playlist);
     popup_reset(nfc_playlist->popup);
     popup_reset(nfc_playlist->popup);
-}
+}

+ 13 - 18
scenes/nfc_playlist_scene_main_menu.c

@@ -1,10 +1,10 @@
 #include "../nfc_playlist.h"
 #include "../nfc_playlist.h"
 
 
 typedef enum {
 typedef enum {
-    NfcPlaylistMenuSelection_Start,
-    NfcPlaylistMenuSelection_PlaylistSelect,
-    NfcPlaylistMenuSelection_FileEdit,
-    NfcPlaylistMenuSelection_Settings
+    NfcPlaylistMainMenu_Start,
+    NfcPlaylistMainMenu_PlaylistSelect,
+    NfcPlaylistMainMenu_FileEdit,
+    NfcPlaylistMainMenu_Settings
 } NfcPlaylistMainMenuMenuSelection;
 } NfcPlaylistMainMenuMenuSelection;
 
 
 void nfc_playlist_main_menu_menu_callback(void* context, uint32_t index) {
 void nfc_playlist_main_menu_menu_callback(void* context, uint32_t index) {
@@ -14,11 +14,6 @@ void nfc_playlist_main_menu_menu_callback(void* context, uint32_t index) {
 
 
 void nfc_playlist_main_menu_scene_on_enter(void* context) {
 void nfc_playlist_main_menu_scene_on_enter(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
-    if(!nfc_playlist->settings.playlist_selected) {
-        nfc_playlist->settings.playlist_selected = true;
-        scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_PlaylistSelect);
-        return;
-    }
 
 
     FuriString* header = furi_string_alloc_printf("NFC Playlist v%s", FAP_VERSION);
     FuriString* header = furi_string_alloc_printf("NFC Playlist v%s", FAP_VERSION);
     submenu_set_header(nfc_playlist->submenu, furi_string_get_cstr(header));
     submenu_set_header(nfc_playlist->submenu, furi_string_get_cstr(header));
@@ -27,7 +22,7 @@ void nfc_playlist_main_menu_scene_on_enter(void* context) {
     submenu_add_lockable_item(
     submenu_add_lockable_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "Start",
         "Start",
-        NfcPlaylistMenuSelection_Start,
+        NfcPlaylistMainMenu_Start,
         nfc_playlist_main_menu_menu_callback,
         nfc_playlist_main_menu_menu_callback,
         nfc_playlist,
         nfc_playlist,
         furi_string_empty(nfc_playlist->settings.playlist_path),
         furi_string_empty(nfc_playlist->settings.playlist_path),
@@ -36,21 +31,21 @@ void nfc_playlist_main_menu_scene_on_enter(void* context) {
     submenu_add_item(
     submenu_add_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "Select playlist",
         "Select playlist",
-        NfcPlaylistMenuSelection_PlaylistSelect,
+        NfcPlaylistMainMenu_PlaylistSelect,
         nfc_playlist_main_menu_menu_callback,
         nfc_playlist_main_menu_menu_callback,
         nfc_playlist);
         nfc_playlist);
 
 
     submenu_add_item(
     submenu_add_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "Edit playlist",
         "Edit playlist",
-        NfcPlaylistMenuSelection_FileEdit,
+        NfcPlaylistMainMenu_FileEdit,
         nfc_playlist_main_menu_menu_callback,
         nfc_playlist_main_menu_menu_callback,
         nfc_playlist);
         nfc_playlist);
 
 
     submenu_add_item(
     submenu_add_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "Settings",
         "Settings",
-        NfcPlaylistMenuSelection_Settings,
+        NfcPlaylistMainMenu_Settings,
         nfc_playlist_main_menu_menu_callback,
         nfc_playlist_main_menu_menu_callback,
         nfc_playlist);
         nfc_playlist);
 
 
@@ -62,19 +57,19 @@ bool nfc_playlist_main_menu_scene_on_event(void* context, SceneManagerEvent even
     bool consumed = false;
     bool consumed = false;
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
         switch(event.event) {
         switch(event.event) {
-        case NfcPlaylistMenuSelection_Start:
+        case NfcPlaylistMainMenu_Start:
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_Emulation);
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_Emulation);
             consumed = true;
             consumed = true;
             break;
             break;
-        case NfcPlaylistMenuSelection_PlaylistSelect:
+        case NfcPlaylistMainMenu_PlaylistSelect:
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_PlaylistSelect);
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_PlaylistSelect);
             consumed = true;
             consumed = true;
             break;
             break;
-        case NfcPlaylistMenuSelection_FileEdit:
+        case NfcPlaylistMainMenu_FileEdit:
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_PlaylistEdit);
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_PlaylistEdit);
             consumed = true;
             consumed = true;
             break;
             break;
-        case NfcPlaylistMenuSelection_Settings:
+        case NfcPlaylistMainMenu_Settings:
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_Settings);
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_Settings);
             consumed = true;
             consumed = true;
             break;
             break;
@@ -88,4 +83,4 @@ bool nfc_playlist_main_menu_scene_on_event(void* context, SceneManagerEvent even
 void nfc_playlist_main_menu_scene_on_exit(void* context) {
 void nfc_playlist_main_menu_scene_on_exit(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     submenu_reset(nfc_playlist->submenu);
     submenu_reset(nfc_playlist->submenu);
-}
+}

+ 3 - 3
scenes/nfc_playlist_scene_name_new_playlist.c

@@ -3,8 +3,8 @@
 int32_t nfc_playlist_name_new_playlist_thread_task(void* context) {
 int32_t nfc_playlist_name_new_playlist_thread_task(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
 
 
-    FuriString* file_name = furi_string_alloc_printf(
-        "/ext/apps_data/nfc_playlist/%s.txt", nfc_playlist->text_input_output);
+    FuriString* file_name =
+        furi_string_alloc_printf("%s%s.txt", PLAYLIST_LOCATION, nfc_playlist->text_input_output);
     char const* file_name_cstr = furi_string_get_cstr(file_name);
     char const* file_name_cstr = furi_string_get_cstr(file_name);
 
 
     Storage* storage = furi_record_open(RECORD_STORAGE);
     Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -72,4 +72,4 @@ void nfc_playlist_name_new_playlist_scene_on_exit(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     free(nfc_playlist->text_input_output);
     free(nfc_playlist->text_input_output);
     text_input_reset(nfc_playlist->text_input);
     text_input_reset(nfc_playlist->text_input);
-}
+}

+ 6 - 8
scenes/nfc_playlist_scene_nfc_add.c

@@ -19,12 +19,10 @@ void nfc_playlist_nfc_add_menu_callback(void* context) {
         furi_string_free(line);
         furi_string_free(line);
 
 
         if(!furi_string_empty(tmp_str)) {
         if(!furi_string_empty(tmp_str)) {
-            furi_string_cat_printf(
-                tmp_str, "\n%s", furi_string_get_cstr(nfc_playlist->file_browser_output));
-        } else {
-            furi_string_printf(
-                tmp_str, "%s", furi_string_get_cstr(nfc_playlist->file_browser_output));
+            furi_string_cat_printf(tmp_str, "\n");
         }
         }
+        furi_string_cat_printf(
+            tmp_str, "%s", furi_string_get_cstr(nfc_playlist->file_browser_output));
 
 
         stream_clean(stream);
         stream_clean(stream);
         stream_write_string(stream, tmp_str);
         stream_write_string(stream, tmp_str);
@@ -43,10 +41,10 @@ void nfc_playlist_nfc_add_menu_callback(void* context) {
 void nfc_playlist_nfc_add_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", NFC_ITEM_LOCATION, true, true, &I_Nfc_10px, true);
     file_browser_set_callback(
     file_browser_set_callback(
         nfc_playlist->file_browser, nfc_playlist_nfc_add_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(NFC_ITEM_LOCATION);
     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);
 
 
@@ -62,4 +60,4 @@ bool nfc_playlist_nfc_add_scene_on_event(void* context, SceneManagerEvent event)
 void nfc_playlist_nfc_add_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);
-}
+}

+ 179 - 0
scenes/nfc_playlist_scene_nfc_move_item.c

@@ -0,0 +1,179 @@
+#include "../nfc_playlist.h"
+
+typedef enum {
+    NfcPlaylistNfcMoveItem_TargetSelector,
+    NfcPlaylistNfcMoveItem_DestinationSelector,
+    NfcPlaylistNfcMoveItem_MoveItem
+} NfcPlaylistNfcMoveItemMenuSelection;
+
+uint8_t selected_target;
+uint8_t selected_destination;
+
+void nfc_playlist_nfc_move_item_menu_callback(void* context, uint32_t index) {
+    NfcPlaylist* nfc_playlist = context;
+    scene_manager_handle_custom_event(nfc_playlist->scene_manager, index);
+}
+
+void nfc_playlist_nfc_move_item_options_change_callback(VariableItem* item) {
+    NfcPlaylist* nfc_playlist = variable_item_get_context(item);
+
+    uint8_t current_option =
+        variable_item_list_get_selected_item_index(nfc_playlist->variable_item_list);
+    uint8_t option_value_index = variable_item_get_current_value_index(item);
+
+    switch(current_option) {
+    case NfcPlaylistNfcMoveItem_TargetSelector: {
+        selected_target = option_value_index + 1;
+        FuriString* tmp_str = furi_string_alloc_printf("%d", selected_target);
+        variable_item_set_current_value_text(item, furi_string_get_cstr(tmp_str));
+        furi_string_free(tmp_str);
+        break;
+    }
+    case NfcPlaylistNfcMoveItem_DestinationSelector: {
+        selected_destination = option_value_index + 1;
+        FuriString* tmp_str = furi_string_alloc_printf("%d", selected_destination);
+        variable_item_set_current_value_text(item, furi_string_get_cstr(tmp_str));
+        furi_string_free(tmp_str);
+        break;
+    }
+    default:
+        break;
+    }
+
+    variable_item_set_locked(
+        variable_item_list_get(nfc_playlist->variable_item_list, NfcPlaylistNfcMoveItem_MoveItem),
+        (selected_target == selected_destination),
+        "Target\nand\nDestination\nare the same");
+}
+
+void nfc_playlist_nfc_move_item_scene_on_enter(void* context) {
+    NfcPlaylist* nfc_playlist = context;
+
+    selected_target = 1;
+    selected_destination = 1;
+
+    //variable_item_list_set_header(nfc_playlist->variable_item_list, "Move NFC Item");
+
+    VariableItem* target_selector = variable_item_list_add(
+        nfc_playlist->variable_item_list,
+        "Select Target",
+        nfc_playlist->settings.playlist_length,
+        nfc_playlist_nfc_move_item_options_change_callback,
+        nfc_playlist);
+    variable_item_set_current_value_index(target_selector, 0);
+    variable_item_set_current_value_text(target_selector, "1");
+
+    VariableItem* destination_selector = variable_item_list_add(
+        nfc_playlist->variable_item_list,
+        "Select Destination",
+        nfc_playlist->settings.playlist_length,
+        nfc_playlist_nfc_move_item_options_change_callback,
+        nfc_playlist);
+    variable_item_set_current_value_index(destination_selector, 0);
+    variable_item_set_current_value_text(destination_selector, "1");
+
+    VariableItem* move_button =
+        variable_item_list_add(nfc_playlist->variable_item_list, "Move Item", 0, NULL, NULL);
+    variable_item_set_locked(
+        move_button,
+        (selected_target == selected_destination),
+        "Target\nand\nDestination\nare the same");
+
+    variable_item_list_set_enter_callback(
+        nfc_playlist->variable_item_list, nfc_playlist_nfc_move_item_menu_callback, nfc_playlist);
+
+    view_dispatcher_switch_to_view(
+        nfc_playlist->view_dispatcher, NfcPlaylistView_VariableItemList);
+}
+
+bool nfc_playlist_nfc_move_item_scene_on_event(void* context, SceneManagerEvent event) {
+    NfcPlaylist* nfc_playlist = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        switch(event.event) {
+        case NfcPlaylistNfcMoveItem_MoveItem: {
+            Storage* storage = furi_record_open(RECORD_STORAGE);
+            Stream* stream = file_stream_alloc(storage);
+
+            if(file_stream_open(
+                   stream,
+                   furi_string_get_cstr(nfc_playlist->settings.playlist_path),
+                   FSAM_READ_WRITE,
+                   FSOM_OPEN_EXISTING)) {
+                FuriString* tmp_target_str = furi_string_alloc();
+                FuriString* line = furi_string_alloc();
+                uint8_t counter = 0;
+
+                while(stream_read_line(stream, line)) {
+                    counter++;
+                    if(counter == selected_target) {
+                        furi_string_trim(line);
+                        furi_string_cat_printf(tmp_target_str, "%s", furi_string_get_cstr(line));
+                        stream_rewind(stream);
+                        counter = 0;
+                        break;
+                    }
+                }
+
+                FuriString* tmp_new_order_str = furi_string_alloc();
+
+                while(stream_read_line(stream, line)) {
+                    counter++;
+
+                    if(counter == selected_target) {
+                        continue;
+                    }
+
+                    if(!furi_string_empty(tmp_new_order_str)) {
+                        furi_string_cat_printf(tmp_new_order_str, "%s", "\n");
+                    }
+
+                    furi_string_trim(line);
+
+                    if(counter == selected_destination) {
+                        if(counter == 1) {
+                            furi_string_cat_printf(
+                                tmp_new_order_str,
+                                "%s\n%s",
+                                furi_string_get_cstr(tmp_target_str),
+                                furi_string_get_cstr(line));
+                        } else {
+                            furi_string_cat_printf(
+                                tmp_new_order_str,
+                                "%s\n%s",
+                                furi_string_get_cstr(line),
+                                furi_string_get_cstr(tmp_target_str));
+                        }
+                        furi_string_free(tmp_target_str);
+                    } else {
+                        furi_string_cat_printf(
+                            tmp_new_order_str, "%s", furi_string_get_cstr(line));
+                    }
+                }
+
+                furi_string_free(line);
+                stream_clean(stream);
+                stream_write_string(stream, tmp_new_order_str);
+                furi_string_free(tmp_new_order_str);
+                file_stream_close(stream);
+            }
+
+            stream_free(stream);
+            furi_record_close(RECORD_STORAGE);
+
+            consumed = true;
+            break;
+        }
+        default:
+            break;
+        }
+    }
+
+    return consumed;
+}
+
+void nfc_playlist_nfc_move_item_scene_on_exit(void* context) {
+    NfcPlaylist* nfc_playlist = context;
+    variable_item_list_reset(nfc_playlist->variable_item_list);
+}

+ 19 - 19
scenes/nfc_playlist_scene_nfc_remove.c

@@ -1,9 +1,9 @@
 #include "../nfc_playlist.h"
 #include "../nfc_playlist.h"
 
 
 typedef enum {
 typedef enum {
-    NfcPlaylistSettings_LineSelector,
-    NfcPlaylistSettings_RemoveLine
-} NfcPlaylistSettingsMenuSelection;
+    NfcPlaylistNfcRemove_LineSelector,
+    NfcPlaylistNfcRemove_RemoveLine
+} NfcPlaylistNfcRemoveMenuSelection;
 
 
 uint8_t selected_line;
 uint8_t selected_line;
 
 
@@ -20,7 +20,7 @@ void nfc_playlist_nfc_remove_options_change_callback(VariableItem* item) {
     uint8_t option_value_index = variable_item_get_current_value_index(item);
     uint8_t option_value_index = variable_item_get_current_value_index(item);
 
 
     switch(current_option) {
     switch(current_option) {
-    case NfcPlaylistSettings_LineSelector: {
+    case NfcPlaylistNfcRemove_LineSelector: {
         selected_line = option_value_index + 1;
         selected_line = option_value_index + 1;
         FuriString* tmp_str = furi_string_alloc_printf("%d", selected_line);
         FuriString* tmp_str = furi_string_alloc_printf("%d", selected_line);
         variable_item_set_current_value_text(item, furi_string_get_cstr(tmp_str));
         variable_item_set_current_value_text(item, furi_string_get_cstr(tmp_str));
@@ -37,29 +37,30 @@ void nfc_playlist_nfc_remove_scene_on_enter(void* context) {
 
 
     selected_line = nfc_playlist->settings.playlist_length;
     selected_line = nfc_playlist->settings.playlist_length;
 
 
-    //variable_item_list_set_header(nfc_playlist->variable_item_list, "Settings");
+    //variable_item_list_set_header(nfc_playlist->variable_item_list, "Remove Nfc Item");
 
 
-    VariableItem* Line_selector = variable_item_list_add(
+    VariableItem* line_selector = variable_item_list_add(
         nfc_playlist->variable_item_list,
         nfc_playlist->variable_item_list,
         "Select Line",
         "Select Line",
         nfc_playlist->settings.playlist_length,
         nfc_playlist->settings.playlist_length,
         nfc_playlist_nfc_remove_options_change_callback,
         nfc_playlist_nfc_remove_options_change_callback,
         nfc_playlist);
         nfc_playlist);
     variable_item_set_current_value_index(
     variable_item_set_current_value_index(
-        Line_selector, nfc_playlist->settings.playlist_length - 1);
+        line_selector, nfc_playlist->settings.playlist_length - 1);
 
 
     FuriString* tmp_str = furi_string_alloc_printf("%d", selected_line);
     FuriString* tmp_str = furi_string_alloc_printf("%d", selected_line);
-    variable_item_set_current_value_text(Line_selector, furi_string_get_cstr(tmp_str));
+    variable_item_set_current_value_text(line_selector, furi_string_get_cstr(tmp_str));
     furi_string_free(tmp_str);
     furi_string_free(tmp_str);
 
 
     variable_item_set_locked(
     variable_item_set_locked(
-        Line_selector,
+        line_selector,
         nfc_playlist->settings.playlist_length == 0 ? true : false,
         nfc_playlist->settings.playlist_length == 0 ? true : false,
         "Playlist\nis empty");
         "Playlist\nis empty");
 
 
-    variable_item_list_add(nfc_playlist->variable_item_list, "Remove Line", 0, NULL, NULL);
+    VariableItem* remove_button =
+        variable_item_list_add(nfc_playlist->variable_item_list, "Remove Line", 0, NULL, NULL);
     variable_item_set_locked(
     variable_item_set_locked(
-        variable_item_list_get(nfc_playlist->variable_item_list, NfcPlaylistSettings_RemoveLine),
+        remove_button,
         nfc_playlist->settings.playlist_length == 0 ? true : false,
         nfc_playlist->settings.playlist_length == 0 ? true : false,
         "Playlist\nis empty");
         "Playlist\nis empty");
 
 
@@ -75,7 +76,7 @@ bool nfc_playlist_nfc_remove_scene_on_event(void* context, SceneManagerEvent eve
     bool consumed = false;
     bool consumed = false;
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
         switch(event.event) {
         switch(event.event) {
-        case NfcPlaylistSettings_RemoveLine:
+        case NfcPlaylistNfcRemove_RemoveLine:
             Storage* storage = furi_record_open(RECORD_STORAGE);
             Storage* storage = furi_record_open(RECORD_STORAGE);
             Stream* stream = file_stream_alloc(storage);
             Stream* stream = file_stream_alloc(storage);
 
 
@@ -90,12 +91,11 @@ bool nfc_playlist_nfc_remove_scene_on_event(void* context, SceneManagerEvent eve
                 while(stream_read_line(stream, line)) {
                 while(stream_read_line(stream, line)) {
                     current_line++;
                     current_line++;
                     if(current_line != selected_line) {
                     if(current_line != selected_line) {
-                        furi_string_replace_all(line, "\n", "");
-                        if(furi_string_empty(tmp_str)) {
-                            furi_string_cat_printf(tmp_str, "%s", furi_string_get_cstr(line));
-                        } else {
-                            furi_string_cat_printf(tmp_str, "\n%s", furi_string_get_cstr(line));
+                        furi_string_trim(line);
+                        if(!furi_string_empty(tmp_str)) {
+                            furi_string_cat_printf(tmp_str, "\n");
                         }
                         }
+                        furi_string_cat_printf(tmp_str, "%s", furi_string_get_cstr(line));
                     }
                     }
                 }
                 }
 
 
@@ -114,7 +114,7 @@ bool nfc_playlist_nfc_remove_scene_on_event(void* context, SceneManagerEvent eve
                 scene_manager_previous_scene(nfc_playlist->scene_manager);
                 scene_manager_previous_scene(nfc_playlist->scene_manager);
             } else {
             } else {
                 VariableItem* Line_selector = variable_item_list_get(
                 VariableItem* Line_selector = variable_item_list_get(
-                    nfc_playlist->variable_item_list, NfcPlaylistSettings_LineSelector);
+                    nfc_playlist->variable_item_list, NfcPlaylistNfcRemove_LineSelector);
                 variable_item_set_values_count(
                 variable_item_set_values_count(
                     Line_selector, nfc_playlist->settings.playlist_length);
                     Line_selector, nfc_playlist->settings.playlist_length);
                 variable_item_set_current_value_index(Line_selector, selected_line - 1);
                 variable_item_set_current_value_index(Line_selector, selected_line - 1);
@@ -136,4 +136,4 @@ bool nfc_playlist_nfc_remove_scene_on_event(void* context, SceneManagerEvent eve
 void nfc_playlist_nfc_remove_scene_on_exit(void* context) {
 void nfc_playlist_nfc_remove_scene_on_exit(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     variable_item_list_reset(nfc_playlist->variable_item_list);
     variable_item_list_reset(nfc_playlist->variable_item_list);
-}
+}

+ 34 - 20
scenes/nfc_playlist_scene_playlist_edit.c

@@ -1,13 +1,14 @@
 #include "../nfc_playlist.h"
 #include "../nfc_playlist.h"
 
 
 typedef enum {
 typedef enum {
-    NfcPlaylistMenuSelection_CreatePlaylist,
-    NfcPlaylistMenuSelection_DeletePlaylist,
-    NfcPlaylistMenuSelection_RenamePlaylist,
-    NfcPlaylistMenuSelection_AddNfcItem,
-    NfcPlaylistMenuSelection_RemoveNfcItem,
-    NfcPlaylistMenuSelection_ViewPlaylistContent
-} NfcPlaylistFileEditMenuSelection;
+    NfcPlaylistPlaylistEdit_CreatePlaylist,
+    NfcPlaylistPlaylistEdit_DeletePlaylist,
+    NfcPlaylistPlaylistEdit_RenamePlaylist,
+    NfcPlaylistPlaylistEdit_AddNfcItem,
+    NfcPlaylistPlaylistEdit_RemoveNfcItem,
+    NfcPlaylistPlaylistEdit_MoveNfcItem,
+    NfcPlaylistPlaylistEdit_ViewPlaylistContent
+} NfcPlaylistPlaylistEditMenuSelection;
 
 
 void nfc_playlist_playlist_edit_menu_callback(void* context, uint32_t index) {
 void nfc_playlist_playlist_edit_menu_callback(void* context, uint32_t index) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
@@ -24,14 +25,14 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) {
     submenu_add_item(
     submenu_add_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "Create Playlist",
         "Create Playlist",
-        NfcPlaylistMenuSelection_CreatePlaylist,
+        NfcPlaylistPlaylistEdit_CreatePlaylist,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist);
         nfc_playlist);
 
 
     submenu_add_lockable_item(
     submenu_add_lockable_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "Delete Playlist",
         "Delete Playlist",
-        NfcPlaylistMenuSelection_DeletePlaylist,
+        NfcPlaylistPlaylistEdit_DeletePlaylist,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist,
         nfc_playlist,
         playlist_path_empty,
         playlist_path_empty,
@@ -40,7 +41,7 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) {
     submenu_add_lockable_item(
     submenu_add_lockable_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "Rename Playlist",
         "Rename Playlist",
-        NfcPlaylistMenuSelection_RenamePlaylist,
+        NfcPlaylistPlaylistEdit_RenamePlaylist,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist,
         nfc_playlist,
         playlist_path_empty,
         playlist_path_empty,
@@ -49,7 +50,7 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) {
     submenu_add_lockable_item(
     submenu_add_lockable_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "Add NFC Item",
         "Add NFC Item",
-        NfcPlaylistMenuSelection_AddNfcItem,
+        NfcPlaylistPlaylistEdit_AddNfcItem,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist,
         nfc_playlist,
         playlist_path_empty,
         playlist_path_empty,
@@ -58,7 +59,16 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) {
     submenu_add_lockable_item(
     submenu_add_lockable_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "Remove NFC Item",
         "Remove NFC Item",
-        NfcPlaylistMenuSelection_RemoveNfcItem,
+        NfcPlaylistPlaylistEdit_RemoveNfcItem,
+        nfc_playlist_playlist_edit_menu_callback,
+        nfc_playlist,
+        playlist_path_empty,
+        "No\nplaylist\nselected");
+
+    submenu_add_lockable_item(
+        nfc_playlist->submenu,
+        "Move NFC Item",
+        NfcPlaylistPlaylistEdit_MoveNfcItem,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist,
         nfc_playlist,
         playlist_path_empty,
         playlist_path_empty,
@@ -67,7 +77,7 @@ void nfc_playlist_playlist_edit_scene_on_enter(void* context) {
     submenu_add_lockable_item(
     submenu_add_lockable_item(
         nfc_playlist->submenu,
         nfc_playlist->submenu,
         "View Playlist Content",
         "View Playlist Content",
-        NfcPlaylistMenuSelection_ViewPlaylistContent,
+        NfcPlaylistPlaylistEdit_ViewPlaylistContent,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist_playlist_edit_menu_callback,
         nfc_playlist,
         nfc_playlist,
         playlist_path_empty,
         playlist_path_empty,
@@ -81,28 +91,32 @@ bool nfc_playlist_playlist_edit_scene_on_event(void* context, SceneManagerEvent
     bool consumed = false;
     bool consumed = false;
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
         switch(event.event) {
         switch(event.event) {
-        case NfcPlaylistMenuSelection_CreatePlaylist:
+        case NfcPlaylistPlaylistEdit_CreatePlaylist:
             scene_manager_next_scene(
             scene_manager_next_scene(
                 nfc_playlist->scene_manager, NfcPlaylistScene_NameNewPlaylist);
                 nfc_playlist->scene_manager, NfcPlaylistScene_NameNewPlaylist);
             consumed = true;
             consumed = true;
             break;
             break;
-        case NfcPlaylistMenuSelection_DeletePlaylist:
+        case NfcPlaylistPlaylistEdit_DeletePlaylist:
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_ConfirmDelete);
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_ConfirmDelete);
             consumed = true;
             consumed = true;
             break;
             break;
-        case NfcPlaylistMenuSelection_RenamePlaylist:
+        case NfcPlaylistPlaylistEdit_RenamePlaylist:
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_PlaylistRename);
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_PlaylistRename);
             consumed = true;
             consumed = true;
             break;
             break;
-        case NfcPlaylistMenuSelection_AddNfcItem:
+        case NfcPlaylistPlaylistEdit_AddNfcItem:
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_NfcAdd);
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_NfcAdd);
             consumed = true;
             consumed = true;
             break;
             break;
-        case NfcPlaylistMenuSelection_RemoveNfcItem:
+        case NfcPlaylistPlaylistEdit_RemoveNfcItem:
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_NfcRemove);
             scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_NfcRemove);
             consumed = true;
             consumed = true;
             break;
             break;
-        case NfcPlaylistMenuSelection_ViewPlaylistContent:
+        case NfcPlaylistPlaylistEdit_MoveNfcItem:
+            scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_NfcMoveItem);
+            consumed = true;
+            break;
+        case NfcPlaylistPlaylistEdit_ViewPlaylistContent:
             scene_manager_next_scene(
             scene_manager_next_scene(
                 nfc_playlist->scene_manager, NfcPlaylistScene_ViewPlaylistContent);
                 nfc_playlist->scene_manager, NfcPlaylistScene_ViewPlaylistContent);
             consumed = true;
             consumed = true;
@@ -117,4 +131,4 @@ bool nfc_playlist_playlist_edit_scene_on_event(void* context, SceneManagerEvent
 void nfc_playlist_playlist_edit_scene_on_exit(void* context) {
 void nfc_playlist_playlist_edit_scene_on_exit(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     submenu_reset(nfc_playlist->submenu);
     submenu_reset(nfc_playlist->submenu);
-}
+}

+ 1 - 2
scenes/nfc_playlist_scene_playlist_rename.c

@@ -24,7 +24,6 @@ int32_t nfc_playlist_playlist_rename_thread_task(void* context) {
     }
     }
 
 
     furi_string_free(new_file_path);
     furi_string_free(new_file_path);
-
     furi_record_close(RECORD_STORAGE);
     furi_record_close(RECORD_STORAGE);
 
 
     return 0;
     return 0;
@@ -84,4 +83,4 @@ void nfc_playlist_playlist_rename_scene_on_exit(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     free(nfc_playlist->text_input_output);
     free(nfc_playlist->text_input_output);
     text_input_reset(nfc_playlist->text_input);
     text_input_reset(nfc_playlist->text_input);
-}
+}

+ 1 - 1
scenes/nfc_playlist_scene_playlist_select.c

@@ -50,4 +50,4 @@ bool nfc_playlist_playlist_select_scene_on_event(void* context, SceneManagerEven
 void nfc_playlist_playlist_select_scene_on_exit(void* context) {
 void nfc_playlist_playlist_select_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
scenes/nfc_playlist_scene_settings.c

@@ -179,4 +179,4 @@ bool nfc_playlist_settings_scene_on_event(void* context, SceneManagerEvent event
 void nfc_playlist_settings_scene_on_exit(void* context) {
 void nfc_playlist_settings_scene_on_exit(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     variable_item_list_reset(nfc_playlist->variable_item_list);
     variable_item_list_reset(nfc_playlist->variable_item_list);
-}
+}

+ 1 - 1
scenes/nfc_playlist_scene_view_playlist_content.c

@@ -54,4 +54,4 @@ bool nfc_playlist_view_playlist_content_scene_on_event(void* context, SceneManag
 void nfc_playlist_view_playlist_content_scene_on_exit(void* context) {
 void nfc_playlist_view_playlist_content_scene_on_exit(void* context) {
     NfcPlaylist* nfc_playlist = context;
     NfcPlaylist* nfc_playlist = context;
     widget_reset(nfc_playlist->widget);
     widget_reset(nfc_playlist->widget);
-}
+}