diff --git a/applications/main/archive/helpers/favorite_timeout.c b/applications/main/archive/helpers/favorite_timeout.c new file mode 100644 index 000000000..703f6c796 --- /dev/null +++ b/applications/main/archive/helpers/favorite_timeout.c @@ -0,0 +1,34 @@ +#include "favorite_timeout.h" +#include + +bool process_favorite_launch(char** args) { + if(*args && strlen(*args) > 4 && strncmp(*args, "fav/", 4) == 0) { + *args += 3; + return true; + } + return false; +} + +void favorite_timeout_callback(void* _ctx) { + FavoriteTImeoutCtx* ctx = _ctx; + while(scene_manager_handle_back_event(ctx->scene_manager)); + view_dispatcher_stop(ctx->view_dispatcher); +} + +void favorite_timeout_run(ViewDispatcher* view_dispatcher, SceneManager* scene_manager) { + int32_t timeout = XTREME_SETTINGS()->favorite_timeout; + if(timeout == 0) { + view_dispatcher_run(view_dispatcher); + return; + } + + FavoriteTImeoutCtx ctx = { + .view_dispatcher = view_dispatcher, + .scene_manager = scene_manager + }; + FuriTimer* timer = furi_timer_alloc(favorite_timeout_callback, FuriTimerTypeOnce, &ctx); + furi_timer_start(timer, timeout * furi_kernel_get_tick_frequency()); + view_dispatcher_run(view_dispatcher); + furi_timer_stop(timer); + furi_timer_free(timer); +} diff --git a/applications/main/archive/helpers/favorite_timeout.h b/applications/main/archive/helpers/favorite_timeout.h new file mode 100644 index 000000000..aded05708 --- /dev/null +++ b/applications/main/archive/helpers/favorite_timeout.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +bool process_favorite_launch(char** p); + +typedef struct { + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; +} FavoriteTImeoutCtx; + +void favorite_timeout_callback(void* _ctx); + +void favorite_timeout_run(ViewDispatcher* view_dispatcher, SceneManager* scene_manager); diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index 3154fbec6..0f4d48db1 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -36,7 +36,7 @@ static void archive_loader_callback(const void* message, void* context) { } } -static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) { +static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected, bool favorites) { UNUSED(browser); Loader* loader = furi_record_open(RECORD_LOADER); @@ -48,8 +48,14 @@ static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selec } status = loader_start(loader, flipper_app_name[selected->type], param); } else { - status = loader_start( - loader, flipper_app_name[selected->type], furi_string_get_cstr(selected->path)); + if(favorites) { + const char* str = furi_string_get_cstr(selected->path); + char arg[strlen(str) + 4]; + snprintf(arg, sizeof(arg), "fav%s", str); + status = loader_start(loader, flipper_app_name[selected->type], arg); + } else { + status = loader_start(loader, flipper_app_name[selected->type], furi_string_get_cstr(selected->path)); + } } if(status != LoaderStatusOk) { @@ -113,7 +119,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { archive_show_file_menu(browser, false); archive_enter_dir(browser, selected->path); } else if(archive_is_known_app(selected->type)) { - archive_run_in_app(browser, selected); + archive_run_in_app(browser, selected, favorites); archive_show_file_menu(browser, false); } consumed = true; diff --git a/applications/main/bad_kb/bad_kb_app.c b/applications/main/bad_kb/bad_kb_app.c index 94a74aa92..e8b29b837 100644 --- a/applications/main/bad_kb/bad_kb_app.c +++ b/applications/main/bad_kb/bad_kb_app.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -204,6 +205,7 @@ BadKbApp* bad_kb_app_alloc(char* arg) { app->file_path = furi_string_alloc(); app->keyboard_layout = furi_string_alloc(); + process_favorite_launch(&arg); if(arg && strlen(arg)) { furi_string_set(app->file_path, arg); } @@ -336,8 +338,8 @@ void bad_kb_app_free(BadKbApp* app) { free(app); } -int32_t bad_kb_app(void* p) { - BadKbApp* bad_kb_app = bad_kb_app_alloc((char*)p); +int32_t bad_kb_app(char* p) { + BadKbApp* bad_kb_app = bad_kb_app_alloc(p); view_dispatcher_run(bad_kb_app->view_dispatcher); diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index b313d67ad..87eafaecd 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -12,6 +12,7 @@ #include #include #include +#include #define TAG "FapLoader" @@ -241,8 +242,9 @@ static void fap_loader_free(FapLoader* loader) { free(loader); } -int32_t fap_loader_app(void* p) { +int32_t fap_loader_app(char* p) { FapLoader* loader; + process_favorite_launch(&p); if(p) { loader = fap_loader_alloc((const char*)p); view_dispatcher_switch_to_view(loader->view_dispatcher, 0); diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index 79999adb2..3fea2d2f6 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -2,6 +2,7 @@ #include #include +#include #define TAG "iButtonApp" @@ -258,13 +259,14 @@ void ibutton_widget_callback(GuiButtonType result, InputType type, void* context } } -int32_t ibutton_app(void* arg) { +int32_t ibutton_app(char* arg) { iButton* ibutton = ibutton_alloc(); ibutton_make_app_folder(ibutton); bool key_loaded = false; + bool is_favorite = process_favorite_launch(&arg); if((arg != NULL) && (strlen(arg) != 0)) { if(sscanf(arg, "RPC %lX", (uint32_t*)&ibutton->rpc) == 1) { FURI_LOG_D(TAG, "Running in RPC mode"); @@ -295,7 +297,11 @@ int32_t ibutton_app(void* arg) { } } - view_dispatcher_run(ibutton->view_dispatcher); + if(is_favorite) { + favorite_timeout_run(ibutton->view_dispatcher, ibutton->scene_manager); + } else { + view_dispatcher_run(ibutton->view_dispatcher); + } if(ibutton->rpc) { rpc_system_app_set_callback(ibutton->rpc, NULL, NULL); diff --git a/applications/main/infrared/infrared.c b/applications/main/infrared/infrared.c index b8195941b..0abd6c709 100644 --- a/applications/main/infrared/infrared.c +++ b/applications/main/infrared/infrared.c @@ -2,6 +2,7 @@ #include #include +#include #define INFRARED_TX_MIN_INTERVAL_MS 50U @@ -435,7 +436,7 @@ void infrared_popup_closed_callback(void* context) { infrared->view_dispatcher, InfraredCustomEventTypePopupClosed); } -int32_t infrared_app(void* p) { +int32_t infrared_app(char* p) { Infrared* infrared = infrared_alloc(); infrared_make_app_folder(infrared); @@ -443,6 +444,7 @@ int32_t infrared_app(void* p) { bool is_remote_loaded = false; bool is_rpc_mode = false; + process_favorite_launch(&p); if(p && strlen(p)) { uint32_t rpc_ctx = 0; if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index a2bcdcf52..eacb05614 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -1,5 +1,6 @@ #include "lfrfid_i.h" #include +#include static bool lfrfid_debug_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -168,12 +169,12 @@ static void lfrfid_free(LfRfid* lfrfid) { free(lfrfid); } -int32_t lfrfid_app(void* p) { +int32_t lfrfid_app(char* args) { LfRfid* app = lfrfid_alloc(); - char* args = p; lfrfid_make_app_folder(app); + bool is_favorite = process_favorite_launch(&args); if(args && strlen(args)) { uint32_t rpc_ctx_ptr = 0; if(sscanf(args, "RPC %lX", &rpc_ctx_ptr) == 1) { @@ -199,7 +200,11 @@ int32_t lfrfid_app(void* p) { scene_manager_next_scene(app->scene_manager, LfRfidSceneStart); } - view_dispatcher_run(app->view_dispatcher); + if(is_favorite) { + favorite_timeout_run(app->view_dispatcher, app->scene_manager); + } else { + view_dispatcher_run(app->view_dispatcher); + } lfrfid_free(app); diff --git a/applications/main/nfc/nfc.c b/applications/main/nfc/nfc.c index f68b7f2f2..9ff82eaa4 100644 --- a/applications/main/nfc/nfc.c +++ b/applications/main/nfc/nfc.c @@ -1,6 +1,7 @@ #include "nfc_i.h" #include #include +#include bool nfc_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -263,14 +264,14 @@ static bool nfc_is_hal_ready() { } } -int32_t nfc_app(void* p) { +int32_t nfc_app(char* p) { if(!nfc_is_hal_ready()) return 0; Nfc* nfc = nfc_alloc(); - char* args = p; // Check argument and run corresponding scene - if(args && strlen(args)) { + bool is_favorite = process_favorite_launch(&p); + if(p && strlen(p)) { nfc_device_set_loading_callback(nfc->dev, nfc_show_loading_popup, nfc); uint32_t rpc_ctx = 0; if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { @@ -311,7 +312,11 @@ int32_t nfc_app(void* p) { scene_manager_next_scene(nfc->scene_manager, NfcSceneStart); } - view_dispatcher_run(nfc->view_dispatcher); + if(is_favorite) { + favorite_timeout_run(nfc->view_dispatcher, nfc->scene_manager); + } else { + view_dispatcher_run(nfc->view_dispatcher); + } nfc_free(nfc); diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 47da7ae40..a092fa6f6 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -4,6 +4,7 @@ #include #include "subghz_i.h" #include +#include #define TAG "SubGhzApp" @@ -423,7 +424,7 @@ void subghz_free(SubGhz* subghz, bool alloc_for_tx_only) { free(subghz); } -int32_t subghz_app(void* p) { +int32_t subghz_app(char* p) { bool alloc_for_tx; if(p && strlen(p)) { alloc_for_tx = true; @@ -455,6 +456,7 @@ int32_t subghz_app(void* p) { furi_hal_subghz_init_radio_type(SubGhzRadioInternal); } // Check argument and run corresponding scene + process_favorite_launch(&p); if(p && strlen(p)) { uint32_t rpc_ctx = 0; diff --git a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_common.c b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_common.c index 259d8a260..08b7425f6 100644 --- a/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_common.c +++ b/applications/main/xtreme_app/scenes/xtreme_app_scene_interface_common.c @@ -37,6 +37,16 @@ static void xtreme_app_scene_interface_common_left_handed_changed(VariableItem* } } +static void xtreme_app_scene_interface_common_favorite_timeout_changed(VariableItem* item) { + XtremeApp* app = variable_item_get_context(item); + uint32_t value = variable_item_get_current_value_index(item); + char text[6]; + snprintf(text, sizeof(text), "%lu S", value); + variable_item_set_current_value_text(item, value ? text : "OFF"); + XTREME_SETTINGS()->favorite_timeout = value; + app->save_settings = true; +} + void xtreme_app_scene_interface_common_on_enter(void* context) { XtremeApp* app = context; XtremeSettings* xtreme_settings = XTREME_SETTINGS(); @@ -67,6 +77,13 @@ void xtreme_app_scene_interface_common_on_enter(void* context) { variable_item_set_current_value_index(item, value); variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + item = variable_item_list_add( + var_item_list, "Favorite Timeout", 61, xtreme_app_scene_interface_common_favorite_timeout_changed, app); + variable_item_set_current_value_index(item, xtreme_settings->favorite_timeout); + char text[4]; + snprintf(text, sizeof(text), "%lu S", xtreme_settings->favorite_timeout); + variable_item_set_current_value_text(item, xtreme_settings->favorite_timeout ? text : "OFF"); + variable_item_list_set_enter_callback( var_item_list, xtreme_app_scene_interface_common_var_item_list_callback, app); diff --git a/applications/system/updater/application.fam b/applications/system/updater/application.fam index ae6914eb7..4d62c1d48 100644 --- a/applications/system/updater/application.fam +++ b/applications/system/updater/application.fam @@ -7,6 +7,7 @@ App( "gui", "storage", "rgb_backlight", + "archive", ], conflicts=["desktop"], entry_point="updater_srv", @@ -23,6 +24,7 @@ App( "gui", "storage", "bt", + "archive", ], conflicts=["updater"], provides=["updater_start"], diff --git a/applications/system/updater/updater.c b/applications/system/updater/updater.c index e749f3ce6..e0b723270 100644 --- a/applications/system/updater/updater.c +++ b/applications/system/updater/updater.c @@ -7,6 +7,7 @@ #include #include #include +#include static bool updater_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -34,6 +35,7 @@ static void Updater* updater_alloc(const char* arg) { Updater* updater = malloc(sizeof(Updater)); + process_favorite_launch(&arg); if(arg && strlen(arg)) { updater->startup_arg = furi_string_alloc_set(arg); furi_string_replace(updater->startup_arg, ANY_PATH(""), EXT_PATH("")); @@ -118,10 +120,8 @@ void updater_free(Updater* updater) { free(updater); } -int32_t updater_srv(void* p) { - const char* cfgpath = p; - - Updater* updater = updater_alloc(cfgpath); +int32_t updater_srv(char* p) { + Updater* updater = updater_alloc(p); view_dispatcher_run(updater->view_dispatcher); updater_free(updater); diff --git a/lib/xtreme/settings.c b/lib/xtreme/settings.c index 1cafa6f59..fe6520808 100644 --- a/lib/xtreme/settings.c +++ b/lib/xtreme/settings.c @@ -24,6 +24,7 @@ XtremeSettings xtreme_settings = { .bar_background = false, // OFF .sort_dirs_first = true, // ON .dark_mode = false, // OFF + .favorite_timeout = 0, // OFF .bad_bt = false, // USB .bad_bt_remember = false, // OFF .butthurt_timer = 43200, // 12 H @@ -75,6 +76,8 @@ void XTREME_SETTINGS_LOAD() { flipper_format_rewind(file); flipper_format_read_bool(file, "dark_mode", &x->dark_mode, 1); flipper_format_rewind(file); + flipper_format_read_uint32(file, "favorite_timeout", &x->favorite_timeout, 1); + flipper_format_rewind(file); flipper_format_read_bool(file, "bad_bt", &x->bad_bt, 1); flipper_format_rewind(file); flipper_format_read_bool(file, "bad_bt_remember", &x->bad_bt_remember, 1); @@ -112,6 +115,7 @@ void XTREME_SETTINGS_SAVE() { flipper_format_write_bool(file, "bar_background", &x->bar_background, 1); flipper_format_write_bool(file, "sort_dirs_first", &x->sort_dirs_first, 1); flipper_format_write_bool(file, "dark_mode", &x->dark_mode, 1); + flipper_format_write_uint32(file, "favorite_timeout", &x->favorite_timeout, 1); flipper_format_write_bool(file, "bad_bt", &x->bad_bt, 1); flipper_format_write_bool(file, "bad_bt_remember", &x->bad_bt_remember, 1); flipper_format_write_int32(file, "butthurt_timer", &x->butthurt_timer, 1); diff --git a/lib/xtreme/xtreme.h b/lib/xtreme/xtreme.h index 63f457c27..54c208ae7 100644 --- a/lib/xtreme/xtreme.h +++ b/lib/xtreme/xtreme.h @@ -31,6 +31,7 @@ typedef struct { bool bar_background; bool sort_dirs_first; bool dark_mode; + uint32_t favorite_timeout; bool bad_bt; bool bad_bt_remember; int32_t butthurt_timer;