MNTM: Consistent display of main menu apps when adding new ones

This commit is contained in:
WillyJL
2025-08-23 23:35:29 +02:00
parent 934ccec91b
commit d6c6d7d850
4 changed files with 42 additions and 52 deletions

View File

@@ -158,7 +158,8 @@ static bool momentum_app_back_event_callback(void* context) {
return scene_manager_handle_back_event(app->scene_manager);
}
static void momentum_app_push_mainmenu_app(MomentumApp* app, FuriString* label, FuriString* exe) {
static void
momentum_app_push_mainmenu_app_raw(MomentumApp* app, FuriString* label, FuriString* exe) {
CharList_push_back(app->mainmenu_app_exes, strdup(furi_string_get_cstr(exe)));
// Display logic mimics applications/services/gui/modules/menu.c
if(furi_string_equal(label, "Momentum")) {
@@ -176,6 +177,38 @@ static void momentum_app_push_mainmenu_app(MomentumApp* app, FuriString* label,
CharList_push_back(app->mainmenu_app_labels, strdup(furi_string_get_cstr(label)));
}
void momentum_app_push_mainmenu_app(MomentumApp* app, FuriString* exe) {
FuriString* label = furi_string_alloc();
if(furi_string_start_with(exe, "/")) {
uint8_t unused_icon[FAP_MANIFEST_MAX_ICON_SIZE];
uint8_t* unused_icon_ptr = unused_icon;
if(!flipper_application_load_name_and_icon(exe, app->storage, &unused_icon_ptr, label)) {
const char* end = strrchr(furi_string_get_cstr(exe), '/');
furi_string_set(label, end ? end + 1 : furi_string_get_cstr(exe));
}
momentum_app_push_mainmenu_app_raw(app, label, exe);
} else {
bool found = false;
for(size_t i = 0; !found && i < FLIPPER_APPS_COUNT; i++) {
if(!strcmp(furi_string_get_cstr(exe), FLIPPER_APPS[i].name)) {
furi_string_set(label, FLIPPER_APPS[i].name);
found = true;
}
}
for(size_t i = 0; !found && i < FLIPPER_EXTERNAL_APPS_COUNT; i++) {
if(!strcmp(furi_string_get_cstr(exe), FLIPPER_EXTERNAL_APPS[i].name)) {
furi_string_set(label, FLIPPER_EXTERNAL_APPS[i].name);
found = true;
}
}
// Ignore unknown apps just like in main menu, prevents "ghost" apps when saving
if(!furi_string_empty(label)) {
momentum_app_push_mainmenu_app_raw(app, label, exe);
}
}
furi_string_free(label);
}
void momentum_app_load_mainmenu_apps(MomentumApp* app) {
// Loading logic mimics applications/services/loader/loader_menu.c
Stream* stream = file_stream_alloc(app->storage);
@@ -198,45 +231,19 @@ void momentum_app_load_mainmenu_apps(MomentumApp* app) {
furi_string_set(line, "Momentum");
}
}
if(furi_string_start_with(line, "/")) {
if(!flipper_application_load_name_and_icon(
line, app->storage, &unused_icon, label)) {
const char* end = strrchr(furi_string_get_cstr(line), '/');
furi_string_set(label, end ? end + 1 : furi_string_get_cstr(line));
}
momentum_app_push_mainmenu_app(app, label, line);
continue;
}
bool found = false;
for(size_t i = 0; !found && i < FLIPPER_APPS_COUNT; i++) {
if(!strcmp(furi_string_get_cstr(line), FLIPPER_APPS[i].name)) {
furi_string_set(label, FLIPPER_APPS[i].name);
found = true;
}
}
for(size_t i = 0; !found && i < FLIPPER_EXTERNAL_APPS_COUNT; i++) {
if(!strcmp(furi_string_get_cstr(line), FLIPPER_EXTERNAL_APPS[i].name)) {
furi_string_set(label, FLIPPER_EXTERNAL_APPS[i].name);
found = true;
}
}
if(furi_string_empty(label)) {
// Ignore unknown apps just like in main menu, prevents "ghost" apps when saving
continue;
}
momentum_app_push_mainmenu_app(app, label, line);
momentum_app_push_mainmenu_app(app, line);
}
} else {
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
furi_string_set(label, FLIPPER_APPS[i].name);
furi_string_set(line, FLIPPER_APPS[i].name);
momentum_app_push_mainmenu_app(app, label, line);
momentum_app_push_mainmenu_app_raw(app, label, line);
}
// Until count - 1 because last app is hardcoded below
for(size_t i = 0; i < FLIPPER_EXTERNAL_APPS_COUNT - 1; i++) {
furi_string_set(label, FLIPPER_EXTERNAL_APPS[i].name);
furi_string_set(line, FLIPPER_EXTERNAL_APPS[i].name);
momentum_app_push_mainmenu_app(app, label, line);
momentum_app_push_mainmenu_app_raw(app, label, line);
}
}
free(unused_icon);

View File

@@ -111,5 +111,6 @@ typedef enum {
bool momentum_app_apply(MomentumApp* app);
void momentum_app_push_mainmenu_app(MomentumApp* app, FuriString* exe);
void momentum_app_load_mainmenu_apps(MomentumApp* app);
void momentum_app_empty_mainmenu_apps(MomentumApp* app);

View File

@@ -43,26 +43,7 @@ static void
FuriString* temp_path = furi_string_alloc_set_str(browser_options.base_path);
if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) {
CharList_push_back(app->mainmenu_app_exes, strdup(furi_string_get_cstr(temp_path)));
if(is_file_dir) {
const char* path = furi_string_get_cstr(temp_path);
const char* end = strrchr(path, '/');
furi_string_set_str(temp_path, end ? end + 1 : path);
} else {
Storage* storage = furi_record_open(RECORD_STORAGE);
uint8_t* unused_icon = malloc(FAP_MANIFEST_MAX_ICON_SIZE);
flipper_application_load_name_and_icon(
temp_path, storage, &unused_icon, temp_path);
free(unused_icon);
furi_record_close(RECORD_STORAGE);
if(furi_string_start_with_str(temp_path, "[")) {
size_t trim = furi_string_search_str(temp_path, "] ", 1);
if(trim != FURI_STRING_FAILURE) {
furi_string_right(temp_path, trim + 2);
}
}
}
CharList_push_back(app->mainmenu_app_labels, strdup(furi_string_get_cstr(temp_path)));
momentum_app_push_mainmenu_app(app, temp_path);
app->mainmenu_app_index = CharList_size(app->mainmenu_app_labels) - 1;
app->save_mainmenu_apps = true;
scene_manager_search_and_switch_to_previous_scene(

View File

@@ -5,8 +5,9 @@ static void
MomentumApp* app = context;
const char* name = (const char*)index;
CharList_push_back(app->mainmenu_app_exes, strdup(name));
CharList_push_back(app->mainmenu_app_labels, strdup(name));
FuriString* exe = furi_string_alloc_set(name);
momentum_app_push_mainmenu_app(app, exe);
furi_string_free(exe);
app->mainmenu_app_index = CharList_size(app->mainmenu_app_labels) - 1;
app->save_mainmenu_apps = true;
scene_manager_search_and_switch_to_previous_scene(