Selaa lähdekoodia

Merge pull request #8 from acegoal07/dev

Dev 08/02/2024
acegoal07 2 vuotta sitten
vanhempi
commit
e2af6ccf4b
11 muutettua tiedostoa jossa 213 lisäystä ja 20 poistoa
  1. 10 4
      README.md
  2. 1 1
      application.fam
  3. 16 3
      nfc_playlist.c
  4. 8 1
      nfc_playlist.h
  5. 3 1
      nfc_playlist_i.h
  6. 6 7
      scences/emulation.c
  7. 70 0
      scences/file_edit.c
  8. 13 0
      scences/file_edit.h
  9. 21 3
      scences/main_menu.c
  10. 52 0
      scences/text_input.c
  11. 13 0
      scences/text_input.h

+ 10 - 4
README.md

@@ -12,8 +12,14 @@ All the playlists should be placed in ext/apps_data/nfc_playlist and an example
 An example file can be found in the repository
 
 ## How to build
-This app was design, built and tested using the <a href="https://github.com/Flipper-XFW/Xtreme-Firmware">Xtreme firmware</a> i don't see why it wont work with other firmwares but do keep this in mind when building it with FBT/uFBT
+This app was design, built and tested using the <a href="https://github.com/Flipper-XFW/Xtreme-Firmware">Xtreme firmware</a> so keep that in mind when building the FAP for yourself
 
-## Ideas
-- [X] Add the ability to change playlist
-- [ ] Make it so changed settings are saved (maybe make it so settings can be specified for each playlist changing the settings based on the playlist selected)
+## Settings
+- Emulate time (How long the NFC card will be emulated for)
+- Delay time (How long the gap between the cards will be)
+- LED indicator (Whether or not the LED's will be on)
+- Reset settings (Puts all the settings back to the defaults)
+
+## Playlist editor
+- Delete playlist (Deletes the selected playlist)
+- Rename playlist (Renames the selected playlist the new name provided)

+ 1 - 1
application.fam

@@ -8,7 +8,7 @@ App(
     fap_category="NFC",
     fap_author="@acegoal07",
     fap_weburl="https://github.com/acegoal07/FlipperZero_NFC_Playlist/tree/main",
-    fap_version="1.1",
+    fap_version="1.3",
     fap_icon="assets/icon.png",
     fap_private_libs=[
         Lib(

+ 16 - 3
nfc_playlist.c

@@ -5,21 +5,27 @@ static void (*const nfc_playlist_scene_on_enter_handlers[])(void*) = {
     nfc_playlist_main_menu_scene_on_enter,
     nfc_playlist_settings_scene_on_enter,
     nfc_playlist_emulation_scene_on_enter,
-    nfc_playlist_file_select_scene_on_enter
+    nfc_playlist_file_select_scene_on_enter,
+    nfc_playlist_file_edit_scene_on_enter,
+    nfc_playlist_text_input_scene_on_enter
 };
 
 static bool (*const nfc_playlist_scene_on_event_handlers[])(void*, SceneManagerEvent) = {
     nfc_playlist_main_menu_scene_on_event,
     nfc_playlist_settings_scene_on_event,
     nfc_playlist_emulation_scene_on_event,
-    nfc_playlist_file_select_scene_on_event
+    nfc_playlist_file_select_scene_on_event,
+    nfc_playlist_file_edit_scene_on_event,
+    nfc_playlist_text_input_scene_on_event
 };
 
 static void (*const nfc_playlist_scene_on_exit_handlers[])(void*) = {
     nfc_playlist_main_menu_scene_on_exit,
     nfc_playlist_settings_scene_on_exit,
     nfc_playlist_emulation_scene_on_exit,
-    nfc_playlist_file_select_scene_on_exit
+    nfc_playlist_file_select_scene_on_exit,
+    nfc_playlist_file_edit_scene_on_exit,
+    nfc_playlist_text_input_scene_on_exit
 };
 
 static const SceneManagerHandlers nfc_playlist_scene_manager_handlers = {
@@ -54,6 +60,7 @@ static NfcPlaylist* nfc_playlist_alloc() {
     nfc_playlist->file_selected = false;
     nfc_playlist->file_selected_check = false;
     nfc_playlist->file_browser = file_browser_alloc(nfc_playlist->file_path);
+    nfc_playlist->text_input = text_input_alloc();
     nfc_playlist->popup = popup_alloc();
     nfc_playlist->emulate_timeout = default_emulate_timeout;
     nfc_playlist->emulate_delay = default_emulate_delay;
@@ -66,6 +73,8 @@ static NfcPlaylist* nfc_playlist_alloc() {
     view_dispatcher_add_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Settings, variable_item_list_get_view(nfc_playlist->variable_item_list));
     view_dispatcher_add_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup, popup_get_view(nfc_playlist->popup));
     view_dispatcher_add_view(nfc_playlist->view_dispatcher, NfcPlaylistView_FileSelect, file_browser_get_view(nfc_playlist->file_browser));
+    view_dispatcher_add_view(nfc_playlist->view_dispatcher, NfcPlaylistView_FileEdit, submenu_get_view(nfc_playlist->submenu));
+    view_dispatcher_add_view(nfc_playlist->view_dispatcher, NfcPlaylistView_TextInput, text_input_get_view(nfc_playlist->text_input));
     return nfc_playlist;
 }
 
@@ -76,14 +85,18 @@ static void nfc_playlist_free(NfcPlaylist* nfc_playlist) {
     view_dispatcher_remove_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Settings);
     view_dispatcher_remove_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Popup);
     view_dispatcher_remove_view(nfc_playlist->view_dispatcher, NfcPlaylistView_FileSelect);
+    view_dispatcher_remove_view(nfc_playlist->view_dispatcher, NfcPlaylistView_FileEdit);
+    view_dispatcher_remove_view(nfc_playlist->view_dispatcher, NfcPlaylistView_TextInput);
     view_dispatcher_free(nfc_playlist->view_dispatcher);
     variable_item_list_free(nfc_playlist->variable_item_list);
     submenu_free(nfc_playlist->submenu);
     file_browser_free(nfc_playlist->file_browser);
+    text_input_free(nfc_playlist->text_input);
     popup_free(nfc_playlist->popup);
     furi_record_close(RECORD_NOTIFICATION);
     furi_string_free(nfc_playlist->base_file_path);
     furi_string_free(nfc_playlist->file_path);
+    free(nfc_playlist->playlist_name);
     free(nfc_playlist);
 }
 

+ 8 - 1
nfc_playlist.h

@@ -10,6 +10,7 @@
 #include <gui/modules/variable_item_list.h>
 #include <gui/modules/submenu.h>
 #include <gui/modules/file_browser.h>
+#include <gui/modules/text_input.h>
 #include <notification/notification_messages.h>
 #include <nfc_playlist_worker.h>
 
@@ -17,7 +18,9 @@ typedef enum {
    NfcPlaylistView_Menu,
    NfcPlaylistView_Settings,
    NfcPlaylistView_Popup,
-   NfcPlaylistView_FileSelect
+   NfcPlaylistView_FileSelect,
+   NfcPlaylistView_FileEdit,
+   NfcPlaylistView_TextInput,
 } NfcPlayScenesView;
 
 typedef enum {
@@ -25,6 +28,8 @@ typedef enum {
    NfcPlaylistScene_Settings,
    NfcPlaylistScene_EmulatingPopup,
    NfcPlaylistScene_FileSelect,
+   NfcPlaylistScene_FileEdit,
+   NfcPlaylistScene_TextInput,
    NfcPlaylistScene_count
 } NfcPlaylistScene;
 
@@ -33,6 +38,7 @@ typedef struct {
    ViewDispatcher* view_dispatcher;
    VariableItemList* variable_item_list;
    FileBrowser* file_browser;
+   TextInput* text_input;
    Submenu* submenu;
    Popup* popup;
    NotificationApp* notification;
@@ -45,6 +51,7 @@ typedef struct {
    uint8_t emulate_delay;
    bool emulate_led_indicator;
    FuriString* file_path;
+   char* playlist_name;
 } NfcPlaylist;
 
 static const int options_emulate_timeout[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

+ 3 - 1
nfc_playlist_i.h

@@ -2,4 +2,6 @@
 #include "scences/main_menu.h"
 #include "scences/settings.h"
 #include "scences/emulation.h"
-#include "scences/file_select.h"
+#include "scences/file_select.h"
+#include "scences/file_edit.h"
+#include "scences/text_input.h"

+ 6 - 7
scences/emulation.c

@@ -90,7 +90,10 @@ int32_t nfc_playlist_emulation_task(void* context) {
 
             if (EmulationState != NfcPlaylistEmulationState_Emulating) {break;}
 
-            char* file_name = strchr(file_path, '/') != NULL ? &strrchr(file_path, '/')[1] : file_path;
+            char const* full_file_name = strchr(file_path, '/') != NULL ? &strrchr(file_path, '/')[1] : file_path;
+            char file_name[sizeof(full_file_name)];
+            strcpy(file_name, full_file_name);
+            strtok(file_name, ".");
             char const* file_ext = &strrchr(file_path, '.')[1];
             int time_counter_ms = (options_emulate_timeout[nfc_playlist->emulate_timeout]*1000);
 
@@ -147,12 +150,7 @@ int32_t nfc_playlist_emulation_task(void* context) {
         popup_set_text(nfc_playlist->popup, "Press back", 64, 50, AlignCenter, AlignTop);
         stop_blink(nfc_playlist);
         EmulationState = NfcPlaylistEmulationState_Stopped;
-    } 
-    
-    else if (!nfc_playlist->file_selected_check) {
-        popup_set_header(nfc_playlist->popup, "No playlist selected", 64, 10, AlignCenter, AlignTop);
-        popup_set_text(nfc_playlist->popup, "Press back", 64, 50, AlignCenter, AlignTop);
-    } 
+    }
     
     else {
         popup_set_header(nfc_playlist->popup, "Failed to open playlist", 64, 10, AlignCenter, AlignTop);
@@ -161,6 +159,7 @@ int32_t nfc_playlist_emulation_task(void* context) {
 
     furi_string_free(line);
     file_stream_close(stream);
+    furi_record_close(RECORD_STORAGE);
     stream_free(stream);
 
     return 0;

+ 70 - 0
scences/file_edit.c

@@ -0,0 +1,70 @@
+#include "nfc_playlist.h"
+#include "scences/file_edit.h"
+
+typedef enum {
+   NfcPlaylistMenuSelection_DeletePlaylist,
+   NfcPlaylistMenuSelection_RenamePlaylist,
+   NfcPlaylistMenuSelection_EditList
+} NfcPlaylistMenuSelection;
+
+void nfc_playlist_file_edit_menu_callback(void* context, uint32_t index) {
+   NfcPlaylist* nfc_playlist = context;
+   Storage* storage = furi_record_open(RECORD_STORAGE);
+   switch(index) {
+      case NfcPlaylistMenuSelection_DeletePlaylist: {
+         storage_simply_remove(storage, furi_string_get_cstr(nfc_playlist->file_path));
+         nfc_playlist->file_selected = false;
+         nfc_playlist->file_selected_check = false;
+         nfc_playlist->file_path = nfc_playlist->base_file_path;
+         scene_manager_previous_scene(nfc_playlist->scene_manager);
+         break;
+      }
+      case NfcPlaylistMenuSelection_RenamePlaylist: {
+         scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_TextInput);
+         break;
+      }
+      case NfcPlaylistMenuSelection_EditList: {
+         break;
+      }
+      default:
+         break;
+   }
+   furi_record_close(RECORD_STORAGE);
+}
+
+void nfc_playlist_file_edit_scene_on_enter(void* context) {
+   NfcPlaylist* nfc_playlist = context;
+
+   submenu_set_header(nfc_playlist->submenu, "Edit Playlist");
+
+   submenu_add_lockable_item(
+      nfc_playlist->submenu,
+      "Delete Playlist",
+      NfcPlaylistMenuSelection_DeletePlaylist,
+      nfc_playlist_file_edit_menu_callback,
+      nfc_playlist,
+      !nfc_playlist->file_selected_check,
+      "No\nplaylist\nselected");
+
+   submenu_add_lockable_item(
+      nfc_playlist->submenu,
+      "Rename Playlist",
+      NfcPlaylistMenuSelection_RenamePlaylist,
+      nfc_playlist_file_edit_menu_callback,
+      nfc_playlist,
+      !nfc_playlist->file_selected_check,
+      "No\nplaylist\nselected");
+
+   view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_FileEdit);
+}
+
+bool nfc_playlist_file_edit_scene_on_event(void* context, SceneManagerEvent event) {
+   UNUSED(event);
+   UNUSED(context);
+   return false;
+}
+
+void nfc_playlist_file_edit_scene_on_exit(void* context) {
+   NfcPlaylist* nfc_playlist = context;
+   submenu_reset(nfc_playlist->submenu);
+}

+ 13 - 0
scences/file_edit.h

@@ -0,0 +1,13 @@
+#pragma once
+#include <furi.h>
+#include <gui/gui.h>
+#include <gui/view_dispatcher.h>
+#include <gui/scene_manager.h>
+#include <gui/modules/submenu.h>
+#include <storage/storage.h>
+#include <toolbox/stream/stream.h>
+#include <toolbox/stream/file_stream.h>
+
+void nfc_playlist_file_edit_scene_on_enter(void* context);
+bool nfc_playlist_file_edit_scene_on_event(void* context, SceneManagerEvent event);
+void nfc_playlist_file_edit_scene_on_exit(void* context);

+ 21 - 3
scences/main_menu.c

@@ -4,13 +4,15 @@
 typedef enum {
     NfcPlaylistEvent_ShowEmulatingPopup,
     NfcPlaylistEvent_ShowFileSelect,
+    NfcPlaylistEvent_ShowFileEdit,
     NfcPlaylistEvent_ShowSettings
 } NfcPlaylistMainMenuEvent;
 
 typedef enum {
     NfcPlaylistMenuSelection_Start,
     NfcPlaylistMenuSelection_FileSelect,
-    NfcPlaylistMenuSelection_Settings
+    NfcPlaylistMenuSelection_FileEdit,
+    NfcPlaylistMenuSelection_Settings,
 } NfcPlaylistMenuSelection;
 
 void nfc_playlist_main_menu_menu_callback(void* context, uint32_t index) {
@@ -22,6 +24,9 @@ void nfc_playlist_main_menu_menu_callback(void* context, uint32_t index) {
         case NfcPlaylistMenuSelection_FileSelect:
             scene_manager_handle_custom_event(nfc_playlist->scene_manager, NfcPlaylistEvent_ShowFileSelect);
             break;
+        case NfcPlaylistMenuSelection_FileEdit:
+            scene_manager_handle_custom_event(nfc_playlist->scene_manager, NfcPlaylistEvent_ShowFileEdit);
+            break;
         case NfcPlaylistMenuSelection_Settings:
             scene_manager_handle_custom_event(nfc_playlist->scene_manager, NfcPlaylistEvent_ShowSettings);
             break;
@@ -40,12 +45,14 @@ void nfc_playlist_main_menu_scene_on_enter(void* context) {
 
     submenu_set_header(nfc_playlist->submenu, "NFC Playlist");
 
-    submenu_add_item(
+    submenu_add_lockable_item(
         nfc_playlist->submenu,
         "Start",
         NfcPlaylistMenuSelection_Start,
         nfc_playlist_main_menu_menu_callback,
-        nfc_playlist);
+        nfc_playlist,
+        !nfc_playlist->file_selected_check,
+        "No\nplaylist\nselected");
 
     submenu_add_item(
         nfc_playlist->submenu,
@@ -53,6 +60,13 @@ void nfc_playlist_main_menu_scene_on_enter(void* context) {
         NfcPlaylistMenuSelection_FileSelect,
         nfc_playlist_main_menu_menu_callback,
         nfc_playlist);
+    
+    submenu_add_item(
+        nfc_playlist->submenu,
+        "Edit playlist",
+        NfcPlaylistMenuSelection_FileEdit,
+        nfc_playlist_main_menu_menu_callback,
+        nfc_playlist);
 
     submenu_add_item(
         nfc_playlist->submenu,
@@ -77,6 +91,10 @@ bool nfc_playlist_main_menu_scene_on_event(void* context, SceneManagerEvent even
                 scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_FileSelect);
                 consumed = true;
                 break;
+            case NfcPlaylistEvent_ShowFileEdit:
+                scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_FileEdit);
+                consumed = true;
+                break;
             case NfcPlaylistEvent_ShowSettings:
                 scene_manager_next_scene(nfc_playlist->scene_manager, NfcPlaylistScene_Settings);
                 consumed = true;

+ 52 - 0
scences/text_input.c

@@ -0,0 +1,52 @@
+#include "nfc_playlist.h"
+#include "scences/text_input.h"
+
+void nfc_playlist_text_input_menu_callback(void* context) {
+   NfcPlaylist* nfc_playlist = context;
+   Storage* storage = furi_record_open(RECORD_STORAGE);
+
+   char const* old_file_path = (char*)furi_string_get_cstr(nfc_playlist->file_path);
+   char const* old_file_name = strchr(old_file_path, '/') != NULL ? &strrchr(old_file_path, '/')[1] : old_file_path;
+
+   int file_path_size = (strlen(old_file_path) - strlen(old_file_name) + 1);
+
+   char* file_path = (char*)malloc(file_path_size);
+   snprintf(file_path, file_path_size, "%s", old_file_path);
+
+   int new_file_path_size = (strlen(nfc_playlist->playlist_name) + strlen(".txt") + file_path_size + 1);
+
+   char* new_file_name = (char*)malloc(new_file_path_size);
+   snprintf(new_file_name, new_file_path_size, "%s%s%s", file_path, nfc_playlist->playlist_name, ".txt");
+
+   if (!storage_file_exists(storage, new_file_name)) {
+      storage_common_rename_safe(storage, furi_string_get_cstr(nfc_playlist->file_path), new_file_name);
+      nfc_playlist->file_path = furi_string_alloc_set_str(new_file_name);
+   }
+
+   free(new_file_name);
+   free(file_path);
+   free(nfc_playlist->playlist_name);
+   furi_record_close(RECORD_STORAGE);
+
+   scene_manager_previous_scene(nfc_playlist->scene_manager);
+}
+
+void nfc_playlist_text_input_scene_on_enter(void* context) {
+   NfcPlaylist* nfc_playlist = context;
+   nfc_playlist->playlist_name = (char*)malloc(50);
+   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_result_callback(nfc_playlist->text_input, nfc_playlist_text_input_menu_callback, nfc_playlist, nfc_playlist->playlist_name, 50, true);
+   view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_TextInput);
+}
+
+bool nfc_playlist_text_input_scene_on_event(void* context, SceneManagerEvent event) {
+   UNUSED(context);
+   UNUSED(event);
+   return false;
+}
+
+void nfc_playlist_text_input_scene_on_exit(void* context) {
+   NfcPlaylist* nfc_playlist = context;
+   text_input_reset(nfc_playlist->text_input);
+}

+ 13 - 0
scences/text_input.h

@@ -0,0 +1,13 @@
+#pragma once
+#include <furi.h>
+#include <string.h>
+#include <gui/gui.h>
+#include <gui/view_dispatcher.h>
+#include <gui/scene_manager.h>
+#include <gui/modules/file_browser.h>
+#include <gui/modules/text_input.h>
+#include <storage/storage.h>
+
+void nfc_playlist_text_input_scene_on_enter(void* context);
+bool nfc_playlist_text_input_scene_on_event(void* context, SceneManagerEvent event);
+void nfc_playlist_text_input_scene_on_exit(void* context);