Desktop: Set external apps as favorites (#1816)

* MVP
* Display app name and icon in browser
* Pre-select favorites in submenu and browser
* Show animation while external favorite is loading
* A little birdie told me... (Missing record_close)
* DesktopSettings: reset submenu before running dialog

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
David
2022-10-13 13:09:37 -05:00
committed by GitHub
parent 55f8beef9f
commit d5b239595f
6 changed files with 130 additions and 23 deletions

View File

@@ -1,6 +1,28 @@
#include "../desktop_settings_app.h"
#include "applications.h"
#include "desktop_settings_scene.h"
#include <storage/storage.h>
#include <dialogs/dialogs.h>
#include <fap_loader/fap_loader_app.h>
static bool favorite_fap_selector_item_callback(
FuriString* file_path,
void* context,
uint8_t** icon_ptr,
FuriString* item_name) {
UNUSED(context);
Storage* storage = furi_record_open(RECORD_STORAGE);
bool success = fap_loader_load_name_and_icon(file_path, storage, icon_ptr, item_name);
furi_record_close(RECORD_STORAGE);
return success;
}
static bool favorite_fap_selector_file_exists(char* file_path) {
Storage* storage = furi_record_open(RECORD_STORAGE);
bool exists = storage_file_exists(storage, file_path);
furi_record_close(RECORD_STORAGE);
return exists;
}
static void desktop_settings_scene_favorite_submenu_callback(void* context, uint32_t index) {
DesktopSettingsApp* app = context;
@@ -12,6 +34,10 @@ void desktop_settings_scene_favorite_on_enter(void* context) {
Submenu* submenu = app->submenu;
submenu_reset(submenu);
uint32_t primary_favorite =
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite);
uint32_t pre_select_item = 0;
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
submenu_add_item(
submenu,
@@ -19,38 +45,96 @@ void desktop_settings_scene_favorite_on_enter(void* context) {
i,
desktop_settings_scene_favorite_submenu_callback,
app);
}
uint32_t primary_favorite =
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite);
if(primary_favorite) { // 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 {
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;
}
}
}
submenu_set_header(
app->submenu, primary_favorite ? "Primary favorite app:" : "Secondary favorite app:");
submenu, primary_favorite ? "Primary favorite app:" : "Secondary favorite app:");
submenu_set_selected_item(submenu, pre_select_item); // If set during loop, visual glitch.
if(primary_favorite) {
submenu_set_selected_item(app->submenu, app->settings.favorite_primary);
} else {
submenu_set_selected_item(app->submenu, app->settings.favorite_secondary);
}
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
}
bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent event) {
DesktopSettingsApp* app = context;
bool consumed = false;
FuriString* temp_path = furi_string_alloc_set_str(EXT_PATH("apps"));
uint32_t primary_favorite =
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite);
if(event.type == SceneManagerEventTypeCustom) {
if(primary_favorite) {
app->settings.favorite_primary = event.event;
if(strcmp(FLIPPER_APPS[event.event].name, FAP_LOADER_APP_NAME)) {
if(primary_favorite) {
app->settings.favorite_primary.is_external = false;
strncpy(
app->settings.favorite_primary.name_or_path,
FLIPPER_APPS[event.event].name,
MAX_APP_LENGTH);
} else {
app->settings.favorite_secondary.is_external = false;
strncpy(
app->settings.favorite_secondary.name_or_path,
FLIPPER_APPS[event.event].name,
MAX_APP_LENGTH);
}
} else {
app->settings.favorite_secondary = event.event;
const DialogsFileBrowserOptions browser_options = {
.extension = ".fap",
.icon = &I_unknown_10px,
.skip_assets = true,
.hide_ext = true,
.item_loader_callback = favorite_fap_selector_item_callback,
.item_loader_context = app,
};
if(primary_favorite) { // 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 {
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);
}
}
submenu_reset(app->submenu);
if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) {
if(primary_favorite) {
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 {
app->settings.favorite_secondary.is_external = true;
strncpy(
app->settings.favorite_secondary.name_or_path,
furi_string_get_cstr(temp_path),
MAX_APP_LENGTH);
}
}
}
scene_manager_previous_scene(app->scene_manager);
consumed = true;
}
furi_string_free(temp_path);
return consumed;
}