Files
Momentum-Firmware/applications/main/archive/helpers/archive_browser.h
T
Alexander Bays 0e3e1b352b Desktop / MNTM Settings: Directories and generic files support for Keybinds / Main Menu (#331)
* feat(Desktop): Directories support for keybinds

- Adds *RIGHT* button select in the file browser dialogs and changing the `Open File` action to `Open File/Directory` in `Settings > Desktop > Keybinds Setup`. This adds the ability to open to any directory in the Archive app, in addition to the default behavior of opening a file in it's default app.

* line order mixup

* Main Menu: Allow adding JS files (or any file)

- Normal files and directories are now able to be added to then main menu and are run in their appropriate apps.
- e.g. .txt files shown in text viewer, .js files are run in the JS Runner app, and folders are navigated to by the Archive app. All similar to the desktop keybinds functionality.
- Icons are also assigned appropriately based on the extensions, though more could probably be added to the `loader_menu_get_ext_icon` function.
- Also replaced some of the long arduous is_dir checks and just used the `storage_dir_exists` function since its already there and does the same.

* should be checking `ext` for NULL

* Move select_right at end of structs for binary compatibility

apps may blindly reach into these structs so need to keep the basics in same structure

for DialogsFileBrowserOptions this is even in public api and after compilation this would be incompatible with other firmwares even without reaching into private structs

* Select menu item / folder for directories too

* Move api below too

* Keep ofw order here too

* Refactor starting archive into desktop, less FuriString passing around

* Dont leave main menu when launching archive

* Simplify/fix a few things

* Handle folders in run_with_default_app()

* Update App -> Item naming in MNTM settings

* Fix build

* Explain pressing right

* Update changelog

---------

Co-authored-by: WillyJL <me@willyjl.dev>
2025-07-22 01:51:33 +00:00

118 lines
4.6 KiB
C

#pragma once
#include "../archive_i.h"
#include <storage/storage.h>
#define TAB_LEFT InputKeyLeft // Default tab switch direction
#define TAB_DEFAULT ArchiveTabFavorites // Start tab
#define FILE_LIST_BUF_LEN 50
static const char* const tab_default_paths[] = {
[ArchiveTabFavorites] = "/app:favorites",
[ArchiveTabIButton] = EXT_PATH("ibutton"),
[ArchiveTabNFC] = EXT_PATH("nfc"),
[ArchiveTabSubGhz] = EXT_PATH("subghz"),
[ArchiveTabLFRFID] = EXT_PATH("lfrfid"),
[ArchiveTabInfrared] = EXT_PATH("infrared"),
[ArchiveTabBadUsb] = EXT_PATH("badusb"),
[ArchiveTabU2f] = "/app:u2f",
[ArchiveTabApplications] = EXT_PATH("apps"),
[ArchiveTabSearch] = "/app:search",
[ArchiveTabDiskImage] = STORAGE_MNT_PATH_PREFIX,
[ArchiveTabInternal] = STORAGE_INT_PATH_PREFIX,
[ArchiveTabBrowser] = STORAGE_EXT_PATH_PREFIX,
};
static const char* const known_ext[] = {
[ArchiveFileTypeIButton] = ".ibtn",
[ArchiveFileTypeNFC] = ".nfc",
[ArchiveFileTypeSubGhz] = ".sub",
[ArchiveFileTypeLFRFID] = ".rfid",
[ArchiveFileTypeInfrared] = ".ir",
[ArchiveFileTypeSubghzPlaylist] = ".txt",
[ArchiveFileTypeSubghzRemote] = ".txt",
[ArchiveFileTypeInfraredRemote] = ".txt",
[ArchiveFileTypeBadUsb] = ".txt",
[ArchiveFileTypeWAV] = ".wav",
[ArchiveFileTypeMag] = ".mag",
[ArchiveFileTypeCrossRemote] = ".xr",
[ArchiveFileTypeU2f] = "?",
[ArchiveFileTypeApplication] = ".fap",
[ArchiveFileTypeJS] = ".js",
[ArchiveFileTypeSearch] = "*",
[ArchiveFileTypeUpdateManifest] = ".fuf",
[ArchiveFileTypeDiskImage] = ".img",
[ArchiveFileTypeFolder] = "?",
[ArchiveFileTypeUnknown] = "*",
[ArchiveFileTypeAppOrJs] = ".fap|.js",
[ArchiveFileTypeSetting] = "?",
};
static const ArchiveFileTypeEnum known_type[] = {
[ArchiveTabFavorites] = ArchiveFileTypeUnknown,
[ArchiveTabIButton] = ArchiveFileTypeIButton,
[ArchiveTabNFC] = ArchiveFileTypeNFC,
[ArchiveTabSubGhz] = ArchiveFileTypeSubGhz,
[ArchiveTabLFRFID] = ArchiveFileTypeLFRFID,
[ArchiveTabInfrared] = ArchiveFileTypeInfrared,
[ArchiveTabBadUsb] = ArchiveFileTypeBadUsb,
[ArchiveTabU2f] = ArchiveFileTypeU2f,
[ArchiveTabApplications] = ArchiveFileTypeAppOrJs,
[ArchiveTabSearch] = ArchiveFileTypeSearch,
[ArchiveTabDiskImage] = ArchiveFileTypeUnknown,
[ArchiveTabInternal] = ArchiveFileTypeUnknown,
[ArchiveTabBrowser] = ArchiveFileTypeUnknown,
};
static inline ArchiveFileTypeEnum archive_get_tab_filetype(ArchiveTabEnum tab) {
return known_type[tab];
}
static inline const char* archive_get_tab_ext(ArchiveTabEnum tab) {
return known_ext[archive_get_tab_filetype(tab)];
}
static inline const char* archive_get_default_path(ArchiveTabEnum tab) {
return tab_default_paths[tab];
}
inline bool archive_is_known_app(ArchiveFileTypeEnum type) {
return type < ArchiveFileTypeUnknown;
}
void archive_file_browser_set_path(
ArchiveBrowserView* browser,
FuriString* path,
const char* filter_ext,
bool skip_assets,
bool hide_dot_files);
bool archive_is_item_in_array(ArchiveBrowserViewModel* model, uint32_t idx);
bool archive_is_file_list_load_required(ArchiveBrowserViewModel* model);
void archive_update_offset(ArchiveBrowserView* browser);
void archive_update_focus(ArchiveBrowserView* browser, const char* target);
void archive_file_array_load(ArchiveBrowserView* browser, int8_t dir);
size_t archive_file_get_array_size(ArchiveBrowserView* browser);
void archive_file_array_rm_selected(ArchiveBrowserView* browser);
void archive_file_array_swap(ArchiveBrowserView* browser, int8_t dir);
void archive_file_array_rm_all(ArchiveBrowserView* browser);
void archive_set_item_count(ArchiveBrowserView* browser, uint32_t count);
ArchiveFile_t* archive_get_current_file(ArchiveBrowserView* browser);
ArchiveFile_t* archive_get_file_at(ArchiveBrowserView* browser, size_t idx);
ArchiveTabEnum archive_get_tab(ArchiveBrowserView* browser);
bool archive_is_home(ArchiveBrowserView* browser);
const char* archive_get_name(ArchiveBrowserView* browser);
void archive_add_app_item(ArchiveBrowserView* browser, const char* name);
void archive_add_file_item(ArchiveBrowserView* browser, bool is_folder, const char* name);
void archive_show_file_menu(ArchiveBrowserView* browser, bool show, bool manage);
void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active);
void archive_set_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab);
void archive_switch_tab(ArchiveBrowserView* browser, InputKey key);
void archive_enter_dir(ArchiveBrowserView* browser, FuriString* name);
void archive_leave_dir(ArchiveBrowserView* browser);
void archive_refresh_dir(ArchiveBrowserView* browser);