diff --git a/application.fam b/application.fam index 50bce34514e..952ebddd75b 100644 --- a/application.fam +++ b/application.fam @@ -8,8 +8,9 @@ App( fap_category="NFC", fap_author="@acegoal07", fap_weburl="https://github.com/acegoal07/FlipperZero_NFC_Playlist/tree/main", - fap_version="2.2", - fap_icon="assets/icon.png", + fap_version="2.3", + fap_icon_assets="assets", + fap_icon="assets/Playlist_10px.png", fap_private_libs=[ Lib( name="emulation_worker", diff --git a/assets/icon.png b/assets/Nfc_10px.png similarity index 100% rename from assets/icon.png rename to assets/Nfc_10px.png diff --git a/assets/Playlist_10px.png b/assets/Playlist_10px.png new file mode 100644 index 00000000000..baa8785923a Binary files /dev/null and b/assets/Playlist_10px.png differ diff --git a/nfc_playlist.c b/nfc_playlist.c index b658a02d093..6980bfbc9fd 100644 --- a/nfc_playlist.c +++ b/nfc_playlist.c @@ -134,10 +134,15 @@ const NotificationSequence blink_sequence_error = { void start_blink(NfcPlaylist* nfc_playlist, int state) { if (nfc_playlist->settings.emulate_led_indicator) { - if (state == NfcPlaylistLedState_Normal) { - notification_message_block(nfc_playlist->notification, &blink_sequence_normal); - } else if (state == NfcPlaylistLedState_Error) { - notification_message_block(nfc_playlist->notification, &blink_sequence_error); + switch (state) { + case NfcPlaylistLedState_Normal: + notification_message_block(nfc_playlist->notification, &blink_sequence_normal); + break; + case NfcPlaylistLedState_Error: + notification_message_block(nfc_playlist->notification, &blink_sequence_error); + break; + default: + break; } } } diff --git a/nfc_playlist.h b/nfc_playlist.h index 449efb6662b..41de068f27c 100644 --- a/nfc_playlist.h +++ b/nfc_playlist.h @@ -4,7 +4,7 @@ #include -#include +#include "nfc_playlist_icons.h" #include #include diff --git a/scenes/nfc_playlist_scene_config.h b/scenes/nfc_playlist_scene_config.h index 37d4215c82d..043dc64634e 100644 --- a/scenes/nfc_playlist_scene_config.h +++ b/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, main_menu, MainMenu) 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, playlist_select, PlaylistSelect) ADD_SCENE(nfc_playlist, settings, Settings) diff --git a/scenes/nfc_playlist_scene_confirm_delete.c b/scenes/nfc_playlist_scene_confirm_delete.c index 0c8cd5e6d32..82dad023f42 100644 --- a/scenes/nfc_playlist_scene_confirm_delete.c +++ b/scenes/nfc_playlist_scene_confirm_delete.c @@ -13,13 +13,13 @@ void nfc_playlist_confirm_delete_scene_on_enter(void* context) { FuriString* file_name = furi_string_alloc(); path_extract_filename_no_ext(furi_string_get_cstr(nfc_playlist->settings.playlist_path), file_name); FuriString* temp_str = furi_string_alloc_printf("\e#Delete %s?\e#", furi_string_get_cstr(file_name)); + furi_string_free(file_name); widget_add_text_box_element(nfc_playlist->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, furi_string_get_cstr(temp_str), false); widget_add_button_element(nfc_playlist->widget, GuiButtonTypeLeft, "Cancel", nfc_playlist_confirm_delete_menu_callback, nfc_playlist); widget_add_button_element(nfc_playlist->widget, GuiButtonTypeRight, "Delete", nfc_playlist_confirm_delete_menu_callback, nfc_playlist); furi_string_free(temp_str); - furi_string_free(file_name); view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_Widget); } diff --git a/scenes/nfc_playlist_scene_emulation.c b/scenes/nfc_playlist_scene_emulation.c index ad46068d3ba..bf97dcdb898 100644 --- a/scenes/nfc_playlist_scene_emulation.c +++ b/scenes/nfc_playlist_scene_emulation.c @@ -20,9 +20,10 @@ int32_t nfc_playlist_emulation_task(void* context) { 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; - int file_position = 0; FuriString* line = furi_string_alloc(); FuriString* tmp_header_str = furi_string_alloc(); @@ -30,6 +31,9 @@ int32_t nfc_playlist_emulation_task(void* context) { FuriString* tmp_file_name = 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) && EmulationState == NfcPlaylistEmulationState_Emulating) { char* file_path = (char*)furi_string_get_cstr(line); @@ -38,20 +42,23 @@ int32_t nfc_playlist_emulation_task(void* context) { 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_string_reset(tmp_counter_str); + 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) {break;} @@ -105,30 +112,27 @@ int32_t nfc_playlist_emulation_task(void* context) { nfc_playlist_emulation_worker_clear_nfc_data(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); - EmulationState = NfcPlaylistEmulationState_Stopped; furi_string_free(line); furi_string_free(tmp_header_str); furi_string_free(tmp_counter_str); furi_string_free(tmp_file_name); 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 { popup_set_header(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); stream_free(stream); + EmulationState = NfcPlaylistEmulationState_Stopped; + return 0; } diff --git a/scenes/nfc_playlist_scene_nfc_select.c b/scenes/nfc_playlist_scene_nfc_add.c similarity index 85% rename from scenes/nfc_playlist_scene_nfc_select.c rename to scenes/nfc_playlist_scene_nfc_add.c index 83602a9d9d8..5e2b7f14aa0 100644 --- a/scenes/nfc_playlist_scene_nfc_select.c +++ b/scenes/nfc_playlist_scene_nfc_add.c @@ -1,6 +1,6 @@ #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; Storage* storage = furi_record_open(RECORD_STORAGE); @@ -12,6 +12,7 @@ void nfc_playlist_nfc_select_menu_callback(void* context) { while(stream_read_line(stream, line)) { furi_string_cat_printf(tmp_str, "%s", furi_string_get_cstr(line)); } + furi_string_free(line); if (!furi_string_empty(tmp_str)) { furi_string_cat_printf(tmp_str, "\n%s", furi_string_get_cstr(nfc_playlist->file_browser_output)); @@ -20,7 +21,6 @@ void nfc_playlist_nfc_select_menu_callback(void* context) { } stream_clean(stream); - furi_string_free(line); stream_write_string(stream, tmp_str); file_stream_close(stream); furi_string_free(tmp_str); @@ -34,7 +34,7 @@ void nfc_playlist_nfc_select_menu_callback(void* context) { 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; file_browser_configure( nfc_playlist->file_browser, @@ -44,7 +44,7 @@ void nfc_playlist_nfc_select_scene_on_enter(void* context) { true, &I_Nfc_10px, true); - file_browser_set_callback(nfc_playlist->file_browser, nfc_playlist_nfc_select_menu_callback, nfc_playlist); + file_browser_set_callback(nfc_playlist->file_browser, nfc_playlist_nfc_add_menu_callback, nfc_playlist); FuriString* tmp_str = furi_string_alloc_set_str("/ext/nfc/"); file_browser_start(nfc_playlist->file_browser, tmp_str); furi_string_free(tmp_str); @@ -52,13 +52,13 @@ void nfc_playlist_nfc_select_scene_on_enter(void* context) { 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(context); 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; file_browser_stop(nfc_playlist->file_browser); } \ No newline at end of file diff --git a/scenes/nfc_playlist_scene_nfc_remove.c b/scenes/nfc_playlist_scene_nfc_remove.c index 69a0890d006..0811086aaac 100644 --- a/scenes/nfc_playlist_scene_nfc_remove.c +++ b/scenes/nfc_playlist_scene_nfc_remove.c @@ -85,8 +85,8 @@ bool nfc_playlist_nfc_remove_scene_on_event(void* context, SceneManagerEvent eve } } - stream_clean(stream); furi_string_free(line); + stream_clean(stream); stream_write_string(stream, tmp_str); furi_string_free(tmp_str); file_stream_close(stream); diff --git a/scenes/nfc_playlist_scene_playlist_edit.c b/scenes/nfc_playlist_scene_playlist_edit.c index e9a66f43630..0c8dbf41130 100644 --- a/scenes/nfc_playlist_scene_playlist_edit.c +++ b/scenes/nfc_playlist_scene_playlist_edit.c @@ -94,7 +94,7 @@ bool nfc_playlist_playlist_edit_scene_on_event(void* context, SceneManagerEvent consumed = true; break; 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; break; case NfcPlaylistMenuSelection_RemoveNfcItem: diff --git a/scenes/nfc_playlist_scene_playlist_rename.c b/scenes/nfc_playlist_scene_playlist_rename.c index f02750f6faf..2787cbf4a0d 100644 --- a/scenes/nfc_playlist_scene_playlist_rename.c +++ b/scenes/nfc_playlist_scene_playlist_rename.c @@ -3,20 +3,23 @@ int32_t nfc_playlist_playlist_rename_thread_task(void* 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"); - + Storage* storage = furi_record_open(RECORD_STORAGE); 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); return 0; @@ -42,14 +45,12 @@ void nfc_playlist_playlist_rename_menu_callback(void* context) { void nfc_playlist_playlist_rename_scene_on_enter(void* 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); - 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_minimum_length(nfc_playlist->text_input, 1); diff --git a/scenes/nfc_playlist_scene_playlist_select.c b/scenes/nfc_playlist_scene_playlist_select.c index c03622a12a1..c81f8db341e 100644 --- a/scenes/nfc_playlist_scene_playlist_select.c +++ b/scenes/nfc_playlist_scene_playlist_select.c @@ -17,7 +17,7 @@ void nfc_playlist_playlist_select_menu_callback(void* context) { furi_string_free(line); file_stream_close(stream); } - + stream_free(stream); furi_record_close(RECORD_STORAGE); @@ -32,7 +32,7 @@ void nfc_playlist_playlist_select_scene_on_enter(void* context) { PLAYLIST_LOCATION, true, true, - &I_unknown_10px, + &I_Playlist_10px, true); file_browser_set_callback(nfc_playlist->file_browser, nfc_playlist_playlist_select_menu_callback, nfc_playlist); FuriString* tmp_str = furi_string_alloc_set_str(PLAYLIST_LOCATION); diff --git a/scenes/nfc_playlist_scene_settings.c b/scenes/nfc_playlist_scene_settings.c index 880ca530709..afb06540193 100644 --- a/scenes/nfc_playlist_scene_settings.c +++ b/scenes/nfc_playlist_scene_settings.c @@ -73,6 +73,8 @@ void nfc_playlist_settings_scene_on_enter(void* context) { furi_string_printf(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)); + furi_string_free(tmp_str); + VariableItem* emulation_led_indicator_setting = variable_item_list_add( nfc_playlist->variable_item_list, "LED Indicator", @@ -97,7 +99,6 @@ void nfc_playlist_settings_scene_on_enter(void* context) { variable_item_set_current_value_text(credits, "Credits"); variable_item_list_set_enter_callback(nfc_playlist->variable_item_list, nfc_playlist_settings_menu_callback, nfc_playlist); - furi_string_free(tmp_str); view_dispatcher_switch_to_view(nfc_playlist->view_dispatcher, NfcPlaylistView_VariableItemList); } @@ -121,6 +122,8 @@ bool nfc_playlist_settings_scene_on_event(void* context, SceneManagerEvent event variable_item_set_current_value_index(emulation_delay_setting, nfc_playlist->settings.emulate_delay); furi_string_printf(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)); + + furi_string_free(tmp_str); nfc_playlist->settings.emulate_led_indicator = default_emulate_led_indicator; VariableItem* emulation_led_indicator_setting = variable_item_list_get(nfc_playlist->variable_item_list, NfcPlaylistSettings_LedIndicator); @@ -132,7 +135,6 @@ bool nfc_playlist_settings_scene_on_event(void* context, SceneManagerEvent event variable_item_set_current_value_index(emulation_skip_error_setting, nfc_playlist->settings.skip_error); variable_item_set_current_value_text(emulation_skip_error_setting, nfc_playlist->settings.skip_error ? "ON" : "OFF"); - furi_string_free(tmp_str); consumed = true; break; default: