diff --git a/CHANGELOG.md b/CHANGELOG.md index cfb0d4fe7..7e88bc878 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,35 +1,6 @@ ### New changes -* SubGHz: New protocols support: CAME Space, Stilmatic / Schellenberg -* SubGHz: Add Manually - new protocols -> Beninca, Sommer(FSK), IronLogic, DTM Neo, Gibidi, Elmes Electronic (Elmes Poland), CAME Space -* SubGHz: Security+ 2.0 -> Ability to send custom buttons codes (0x80, 0x81, 0xE2) -* SubGHz: Remember last external module setting and power setting, so if you turn off flipper it will remember last external module settings (only for subghz app) -* SubGHz: Fix issues when external module is not found but plugins tries to use it, now they will fallback to internal in that case -* SubGHz: Fixed external CC1101 module power issues, added more checks, fixed issues when launching subghz favourites -* SubGHz: Removed 330MHz from default freq hopper to make it faster, to change freq hopper settings and remove/add your freqs see -> [Instruction](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzSettings.md) -* SubGHz: Small UI text fixes -* GUI: Fix submenu elements text size, now we can fit more symbols -* Plugins: Added delay and retries to avoid power issues in plugins -> WiFi Scanner, ESP8266 Deauther -* Plugins: Update for WiFi Marauder companion -> `sniff` saves pcaps in `YourFlippersMicroSD/apps_data/marauder/` -> Only with custom marauder build (It is necessary to uncomment "#define WRITE_PACKETS_SERIAL" in configs.h (in marauder fw) and compile the firmware for the wifi board.) Or download precompiled build -> [Download esp32_marauder_ver_flipper_sd_serial.bin](https://github.com/justcallmekoko/ESP32Marauder/releases/latest) - [(by tcpassos)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion/pull/7) -* Plugins: Removed `cdefines` from external plugins as it was not used in any way -* Plugins: Updated **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) (fixed issue #379) -* Plugins: Update for SubGHz Bruteforcer, added - Holtek HT12X 12bit AM 433.920MHz/315MHz/868MHz/915MHz (TE: 433us) -* OFW: iButton: Add support for Dallas DS1971 -* OFW: fbt: explicitly set dist suffix length, not depending on environment settings -* OFW: NFC -> Skip the read when the card is not present -* OFW: NFC -> Mark keys as not found when they couldn't auth successfully -* OFW: Storage -> Require the trailing slash for root paths -* OFW: gh: use shallow clones whenever possible -* OFW: Add new nfc apdu cli command -* OFW: Picopass standard KDF dictionary -* OFW: Nfc: fixes for latest PVS-studio 7.23 -* OFW: Dolphin: new spring animation, weight adjust, drop winter animation. -* OFW: fbt, faploader: minimal app module implementation -> **All plugins now should have** `apptype=FlipperAppType.EXTERNAL` -* OFW: Fbt: fix broken resource deployment -* OFW: NFC: Fix 0 block write possibility in Mifare Classic emulation -* OFW: BadUSB: updated parser and added stringln, hold and release -* OFW: Upside down / left handed orientation support -* OFW: Embed assets in elf file -* OFW: Dumb mode menu freeze fix +* Desktop: Option to set Tertiary favourite app (Hold right arrow on desktop) - **Desktop settings (pin code, favourite app, autolock time) will be resetted!!! Only one time after installing - due to changes in settings structure, after installing of this release desktop settings will not be reset with next release** +* OFW: Optimize trailing slash check #### [🎲 Download latest extra apps pack](https://github.com/xMasterX/unleashed-extra-pack/archive/refs/heads/main.zip) diff --git a/applications/services/desktop/animations/views/bubble_animation_view.c b/applications/services/desktop/animations/views/bubble_animation_view.c index 607862d11..bd13bd34a 100644 --- a/applications/services/desktop/animations/views/bubble_animation_view.c +++ b/applications/services/desktop/animations/views/bubble_animation_view.c @@ -126,13 +126,11 @@ static bool bubble_animation_input_callback(InputEvent* event, void* context) { bubble_animation_activate(animation_view, false); } - if(event->key == InputKeyRight) { + if(event->key == InputKeyRight && event->type == InputTypeShort) { /* Right button reserved for animation activation, so consume */ consumed = true; - if(event->type == InputTypeShort) { - if(animation_view->interact_callback) { - animation_view->interact_callback(animation_view->interact_callback_context); - } + if(animation_view->interact_callback) { + animation_view->interact_callback(animation_view->interact_callback_context); } } diff --git a/applications/services/desktop/desktop_settings.h b/applications/services/desktop/desktop_settings.h index 26c39f611..4b4bca000 100644 --- a/applications/services/desktop/desktop_settings.h +++ b/applications/services/desktop/desktop_settings.h @@ -8,7 +8,7 @@ #include #include -#define DESKTOP_SETTINGS_VER (7) +#define DESKTOP_SETTINGS_VER (8) #define DESKTOP_SETTINGS_PATH INT_PATH(DESKTOP_SETTINGS_FILE_NAME) #define DESKTOP_SETTINGS_MAGIC (0x17) @@ -58,6 +58,7 @@ typedef struct { typedef struct { FavoriteApp favorite_primary; FavoriteApp favorite_secondary; + FavoriteApp favorite_tertiary; PinCode pin_code; uint8_t is_locked; uint32_t auto_lock_delay_ms; diff --git a/applications/services/desktop/scenes/desktop_scene_main.c b/applications/services/desktop/scenes/desktop_scene_main.c index 129270dc3..fd04ff917 100644 --- a/applications/services/desktop/scenes/desktop_scene_main.c +++ b/applications/services/desktop/scenes/desktop_scene_main.c @@ -170,6 +170,25 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { } consumed = true; break; + case DesktopMainEventOpenFavoriteTertiary: + DESKTOP_SETTINGS_LOAD(&desktop->settings); + if(desktop->settings.favorite_tertiary.is_external) { + LoaderStatus status = loader_start( + desktop->loader, + FAP_LOADER_APP_NAME, + desktop->settings.favorite_tertiary.name_or_path); + if(status != LoaderStatusOk) { + FURI_LOG_E(TAG, "loader_start failed: %d", status); + } + } else { + LoaderStatus status = loader_start( + desktop->loader, desktop->settings.favorite_tertiary.name_or_path, NULL); + if(status != LoaderStatusOk) { + FURI_LOG_E(TAG, "loader_start failed: %d", status); + } + } + consumed = true; + break; case DesktopAnimationEventCheckAnimation: animation_manager_check_blocking_process(desktop->animation_manager); consumed = true; diff --git a/applications/services/desktop/views/desktop_events.h b/applications/services/desktop/views/desktop_events.h index 6917dbe73..f0200ca80 100644 --- a/applications/services/desktop/views/desktop_events.h +++ b/applications/services/desktop/views/desktop_events.h @@ -5,6 +5,7 @@ typedef enum { DesktopMainEventOpenArchive, DesktopMainEventOpenFavoritePrimary, DesktopMainEventOpenFavoriteSecondary, + DesktopMainEventOpenFavoriteTertiary, DesktopMainEventOpenMenu, DesktopMainEventOpenDebug, DesktopMainEventOpenPassport, diff --git a/applications/services/desktop/views/desktop_view_main.c b/applications/services/desktop/views/desktop_view_main.c index 7e68cd4ca..0a1c72ca6 100644 --- a/applications/services/desktop/views/desktop_view_main.c +++ b/applications/services/desktop/views/desktop_view_main.c @@ -67,6 +67,8 @@ bool desktop_main_input_callback(InputEvent* event, void* context) { main_view->callback(DesktopMainEventOpenDebug, main_view->context); } else if(event->key == InputKeyLeft) { main_view->callback(DesktopMainEventOpenFavoriteSecondary, main_view->context); + } else if(event->key == InputKeyRight) { + main_view->callback(DesktopMainEventOpenFavoriteTertiary, main_view->context); } else if(event->key == InputKeyUp) { main_view->callback(DesktopMainEventLock, main_view->context); } else if(event->key == InputKeyOk) { diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c index 94c5ee9f0..822c6c7a9 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c @@ -53,23 +53,34 @@ void desktop_settings_scene_favorite_on_enter(void* context) { desktop_settings_scene_favorite_submenu_callback, app); - if(primary_favorite) { // Select favorite item in submenu + if(primary_favorite == 0) { // Select favorite item in submenu if((app->settings.favorite_primary.is_external && !strcmp(FLIPPER_APPS[i].name, FAP_LOADER_APP_NAME)) || (!strcmp(FLIPPER_APPS[i].name, app->settings.favorite_primary.name_or_path))) { pre_select_item = i; } - } else { + } else if(primary_favorite == 1) { if((app->settings.favorite_secondary.is_external && !strcmp(FLIPPER_APPS[i].name, FAP_LOADER_APP_NAME)) || (!strcmp(FLIPPER_APPS[i].name, app->settings.favorite_secondary.name_or_path))) { pre_select_item = i; } + } else if(primary_favorite == 2) { + if((app->settings.favorite_tertiary.is_external && + !strcmp(FLIPPER_APPS[i].name, FAP_LOADER_APP_NAME)) || + (!strcmp(FLIPPER_APPS[i].name, app->settings.favorite_tertiary.name_or_path))) { + pre_select_item = i; + } } } - submenu_set_header( - submenu, primary_favorite ? "Primary favorite app:" : "Secondary favorite app:"); + if(primary_favorite == 0) { + submenu_set_header(submenu, "Primary favorite app:"); + } else if(primary_favorite == 1) { + submenu_set_header(submenu, "Secondary favorite app:"); + } else if(primary_favorite == 2) { + submenu_set_header(submenu, "Tertiary favorite app:"); + } submenu_set_selected_item(submenu, pre_select_item); // If set during loop, visual glitch. view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu); @@ -85,18 +96,24 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e if(event.type == SceneManagerEventTypeCustom) { if(strcmp(FLIPPER_APPS[event.event].name, FAP_LOADER_APP_NAME) != 0) { - if(primary_favorite) { + if(primary_favorite == 0) { app->settings.favorite_primary.is_external = false; strncpy( app->settings.favorite_primary.name_or_path, FLIPPER_APPS[event.event].name, MAX_APP_LENGTH); - } else { + } else if(primary_favorite == 1) { app->settings.favorite_secondary.is_external = false; strncpy( app->settings.favorite_secondary.name_or_path, FLIPPER_APPS[event.event].name, MAX_APP_LENGTH); + } else if(primary_favorite == 2) { + app->settings.favorite_tertiary.is_external = false; + strncpy( + app->settings.favorite_tertiary.name_or_path, + FLIPPER_APPS[event.event].name, + MAX_APP_LENGTH); } } else { const DialogsFileBrowserOptions browser_options = { @@ -109,32 +126,43 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e .base_path = EXT_PATH("apps"), }; - if(primary_favorite) { // Select favorite fap in file browser + if(primary_favorite == 0) { // Select favorite fap in file browser if(favorite_fap_selector_file_exists( app->settings.favorite_primary.name_or_path)) { furi_string_set_str(temp_path, app->settings.favorite_primary.name_or_path); } - } else { + } else if(primary_favorite == 1) { if(favorite_fap_selector_file_exists( app->settings.favorite_secondary.name_or_path)) { furi_string_set_str(temp_path, app->settings.favorite_secondary.name_or_path); } + } else if(primary_favorite == 2) { + if(favorite_fap_selector_file_exists( + app->settings.favorite_tertiary.name_or_path)) { + furi_string_set_str(temp_path, app->settings.favorite_tertiary.name_or_path); + } } submenu_reset(app->submenu); if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) { - if(primary_favorite) { + if(primary_favorite == 0) { app->settings.favorite_primary.is_external = true; strncpy( app->settings.favorite_primary.name_or_path, furi_string_get_cstr(temp_path), MAX_APP_LENGTH); - } else { + } else if(primary_favorite == 1) { app->settings.favorite_secondary.is_external = true; strncpy( app->settings.favorite_secondary.name_or_path, furi_string_get_cstr(temp_path), MAX_APP_LENGTH); + } else if(primary_favorite == 2) { + app->settings.favorite_tertiary.is_external = true; + strncpy( + app->settings.favorite_tertiary.name_or_path, + furi_string_get_cstr(temp_path), + MAX_APP_LENGTH); } } } diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c index e3f83d275..49c2e7422 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c @@ -6,9 +6,11 @@ #define SCENE_EVENT_SELECT_FAVORITE_PRIMARY 0 #define SCENE_EVENT_SELECT_FAVORITE_SECONDARY 1 -#define SCENE_EVENT_SELECT_PIN_SETUP 2 -#define SCENE_EVENT_SELECT_AUTO_LOCK_DELAY 3 -#define SCENE_EVENT_SELECT_BATTERY_DISPLAY 4 +#define SCENE_EVENT_SELECT_FAVORITE_TERTIARY 2 +#define SCENE_EVENT_SELECT_PIN_SETUP 3 +#define SCENE_EVENT_SELECT_AUTO_LOCK_DELAY 4 +#define SCENE_EVENT_SELECT_AUTO_LOCK_PIN 5 +#define SCENE_EVENT_SELECT_BATTERY_DISPLAY 6 #define AUTO_LOCK_DELAY_COUNT 9 const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { @@ -79,6 +81,8 @@ void desktop_settings_scene_start_on_enter(void* context) { variable_item_list_add(variable_item_list, "Secondary Favorite App", 1, NULL, NULL); + variable_item_list_add(variable_item_list, "Tertiary Favorite App", 1, NULL, NULL); + variable_item_list_add(variable_item_list, "PIN Setup", 1, NULL, NULL); item = variable_item_list_add( @@ -129,12 +133,17 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { case SCENE_EVENT_SELECT_FAVORITE_PRIMARY: - scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 1); + scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 0); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite); consumed = true; break; case SCENE_EVENT_SELECT_FAVORITE_SECONDARY: - scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 0); + scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 1); + scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite); + consumed = true; + break; + case SCENE_EVENT_SELECT_FAVORITE_TERTIARY: + scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 2); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite); consumed = true; break; @@ -145,6 +154,9 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even case SCENE_EVENT_SELECT_AUTO_LOCK_DELAY: consumed = true; break; + case SCENE_EVENT_SELECT_AUTO_LOCK_PIN: + consumed = true; + break; case SCENE_EVENT_SELECT_BATTERY_DISPLAY: consumed = true; break;