mirror of
https://github.com/flipperdevices/flipperzero-firmware.git
synced 2025-12-12 04:41:26 +04:00
[FL-3947] Pinning of settings options (#4077)
* feat: pinning settings in favorites * include archive in unit tests fw * change settings icon * update text with suggestions from the ui team * Small touch of constness --------- Co-authored-by: あく <alleteam@gmail.com> Co-authored-by: hedger <hedger@users.noreply.github.com> Co-authored-by: hedger <hedger@nanode.su>
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
#include "archive_apps.h"
|
||||
#include "archive_browser.h"
|
||||
|
||||
static const char* known_apps[] = {
|
||||
static const char* const known_apps[] = {
|
||||
[ArchiveAppTypeU2f] = "u2f",
|
||||
[ArchiveAppTypeSetting] = "setting",
|
||||
};
|
||||
|
||||
ArchiveAppTypeEnum archive_get_app_type(const char* path) {
|
||||
@@ -36,6 +37,8 @@ bool archive_app_is_available(void* context, const char* path) {
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
return file_exists;
|
||||
} else if(app == ArchiveAppTypeSetting) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -53,6 +56,9 @@ bool archive_app_read_dir(void* context, const char* path) {
|
||||
if(app == ArchiveAppTypeU2f) {
|
||||
archive_add_app_item(browser, "/app:u2f/U2F Token");
|
||||
return true;
|
||||
} else if(app == ArchiveAppTypeSetting) {
|
||||
archive_add_app_item(browser, path);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -75,6 +81,8 @@ void archive_app_delete_file(void* context, const char* path) {
|
||||
if(archive_is_favorite("/app:u2f/U2F Token")) {
|
||||
archive_favorites_delete("/app:u2f/U2F Token");
|
||||
}
|
||||
} else if(app == ArchiveAppTypeSetting) {
|
||||
// can't delete a setting!
|
||||
}
|
||||
|
||||
if(res) {
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
|
||||
typedef enum {
|
||||
ArchiveAppTypeU2f,
|
||||
ArchiveAppTypeSetting,
|
||||
ArchiveAppTypeUnknown,
|
||||
ArchiveAppsTotal,
|
||||
} ArchiveAppTypeEnum;
|
||||
|
||||
static const ArchiveFileTypeEnum app_file_types[] = {
|
||||
[ArchiveAppTypeU2f] = ArchiveFileTypeU2f,
|
||||
[ArchiveAppTypeSetting] = ArchiveFileTypeSetting,
|
||||
[ArchiveAppTypeUnknown] = ArchiveFileTypeUnknown,
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#define TAB_DEFAULT ArchiveTabFavorites // Start tab
|
||||
#define FILE_LIST_BUF_LEN 50
|
||||
|
||||
static const char* tab_default_paths[] = {
|
||||
static const char* const tab_default_paths[] = {
|
||||
[ArchiveTabFavorites] = "/app:favorites",
|
||||
[ArchiveTabIButton] = EXT_PATH("ibutton"),
|
||||
[ArchiveTabNFC] = EXT_PATH("nfc"),
|
||||
@@ -20,7 +20,7 @@ static const char* tab_default_paths[] = {
|
||||
[ArchiveTabBrowser] = STORAGE_EXT_PATH_PREFIX,
|
||||
};
|
||||
|
||||
static const char* known_ext[] = {
|
||||
static const char* const known_ext[] = {
|
||||
[ArchiveFileTypeIButton] = ".ibtn",
|
||||
[ArchiveFileTypeNFC] = ".nfc",
|
||||
[ArchiveFileTypeSubGhz] = ".sub",
|
||||
@@ -34,6 +34,7 @@ static const char* known_ext[] = {
|
||||
[ArchiveFileTypeFolder] = "?",
|
||||
[ArchiveFileTypeUnknown] = "*",
|
||||
[ArchiveFileTypeAppOrJs] = ".fap|.js",
|
||||
[ArchiveFileTypeSetting] = "?",
|
||||
};
|
||||
|
||||
static const ArchiveFileTypeEnum known_type[] = {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
#include "archive_favorites.h"
|
||||
#include "archive_files.h"
|
||||
#include "archive_apps.h"
|
||||
#include "archive_browser.h"
|
||||
|
||||
#include <dialogs/dialogs.h>
|
||||
|
||||
#define ARCHIVE_FAV_FILE_BUF_LEN 32
|
||||
|
||||
static bool archive_favorites_read_line(File* file, FuriString* str_result) {
|
||||
@@ -337,3 +338,46 @@ void archive_favorites_save(void* context) {
|
||||
storage_file_free(file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
void archive_favorites_handle_setting_pin_unpin(const char* app_name, const char* setting) {
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
|
||||
FuriString* setting_path = furi_string_alloc_set_str(app_name);
|
||||
if(setting) {
|
||||
furi_string_push_back(setting_path, '/');
|
||||
furi_string_cat_str(setting_path, setting);
|
||||
}
|
||||
const char* setting_path_str = furi_string_get_cstr(setting_path);
|
||||
|
||||
bool is_favorite = archive_is_favorite("/app:setting/%s", setting_path_str);
|
||||
dialog_message_set_header(
|
||||
message,
|
||||
is_favorite ? "Unpin This Setting?" : "Pin This Setting?",
|
||||
64,
|
||||
0,
|
||||
AlignCenter,
|
||||
AlignTop);
|
||||
dialog_message_set_text(
|
||||
message,
|
||||
is_favorite ? "It will no longer be\naccessible from the\nFavorites menu" :
|
||||
"It will be accessible from the\nFavorites menu",
|
||||
64,
|
||||
32,
|
||||
AlignCenter,
|
||||
AlignCenter);
|
||||
dialog_message_set_buttons(
|
||||
message, is_favorite ? "Unpin" : "Go back", NULL, is_favorite ? "Keep pinned" : "Pin");
|
||||
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
DialogMessageButton button = dialog_message_show(dialogs, message);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
|
||||
if(is_favorite && button == DialogMessageButtonLeft) {
|
||||
archive_favorites_delete("/app:setting/%s", setting_path_str);
|
||||
} else if(!is_favorite && button == DialogMessageButtonRight) {
|
||||
archive_file_append(ARCHIVE_FAV_PATH, "/app:setting/%s\n", setting_path_str);
|
||||
}
|
||||
|
||||
furi_string_free(setting_path);
|
||||
dialog_message_free(message);
|
||||
}
|
||||
|
||||
@@ -12,3 +12,13 @@ bool archive_is_favorite(const char* format, ...) _ATTRIBUTE((__format__(__print
|
||||
bool archive_favorites_rename(const char* src, const char* dst);
|
||||
void archive_add_to_favorites(const char* file_path);
|
||||
void archive_favorites_save(void* context);
|
||||
|
||||
/**
|
||||
* Intended to be called by settings apps to handle long presses, as well as
|
||||
* internally from within the archive
|
||||
*
|
||||
* @param app_name name of the referring application
|
||||
* @param setting name of the setting, which will be both displayed to the user
|
||||
* and passed to the application as an argument upon recall
|
||||
*/
|
||||
void archive_favorites_handle_setting_pin_unpin(const char* app_name, const char* setting);
|
||||
|
||||
@@ -20,6 +20,7 @@ typedef enum {
|
||||
ArchiveFileTypeFolder,
|
||||
ArchiveFileTypeUnknown,
|
||||
ArchiveFileTypeAppOrJs,
|
||||
ArchiveFileTypeSetting,
|
||||
ArchiveFileTypeLoading,
|
||||
} ArchiveFileTypeEnum;
|
||||
|
||||
|
||||
@@ -52,20 +52,37 @@ static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selec
|
||||
UNUSED(browser);
|
||||
Loader* loader = furi_record_open(RECORD_LOADER);
|
||||
|
||||
const char* app_name = archive_get_flipper_app_name(selected->type);
|
||||
|
||||
if(app_name) {
|
||||
if(selected->is_app) {
|
||||
char* param = strrchr(furi_string_get_cstr(selected->path), '/');
|
||||
if(param != NULL) {
|
||||
param++;
|
||||
}
|
||||
loader_start_with_gui_error(loader, app_name, param);
|
||||
if(selected->type == ArchiveFileTypeSetting) {
|
||||
FuriString* app_name = furi_string_alloc_set(selected->path);
|
||||
furi_string_right(app_name, furi_string_search_char(app_name, '/', 1) + 1);
|
||||
size_t slash = furi_string_search_char(app_name, '/', 1);
|
||||
if(slash != FURI_STRING_FAILURE) {
|
||||
furi_string_left(app_name, slash);
|
||||
FuriString* app_args =
|
||||
furi_string_alloc_set_str(furi_string_get_cstr(app_name) + slash + 1);
|
||||
loader_start_with_gui_error(
|
||||
loader, furi_string_get_cstr(app_name), furi_string_get_cstr(app_args));
|
||||
furi_string_free(app_args);
|
||||
} else {
|
||||
loader_start_with_gui_error(loader, app_name, furi_string_get_cstr(selected->path));
|
||||
loader_start_with_gui_error(loader, furi_string_get_cstr(app_name), NULL);
|
||||
}
|
||||
furi_string_free(app_name);
|
||||
} else {
|
||||
loader_start_with_gui_error(loader, furi_string_get_cstr(selected->path), NULL);
|
||||
const char* app_name = archive_get_flipper_app_name(selected->type);
|
||||
if(app_name) {
|
||||
if(selected->is_app) {
|
||||
char* param = strrchr(furi_string_get_cstr(selected->path), '/');
|
||||
if(param != NULL) {
|
||||
param++;
|
||||
}
|
||||
loader_start_with_gui_error(loader, app_name, param);
|
||||
} else {
|
||||
loader_start_with_gui_error(
|
||||
loader, app_name, furi_string_get_cstr(selected->path));
|
||||
}
|
||||
} else {
|
||||
loader_start_with_gui_error(loader, furi_string_get_cstr(selected->path), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
furi_record_close(RECORD_LOADER);
|
||||
|
||||
@@ -28,6 +28,7 @@ static const Icon* ArchiveItemIcons[] = {
|
||||
[ArchiveFileTypeInfrared] = &I_ir_10px,
|
||||
[ArchiveFileTypeBadUsb] = &I_badusb_10px,
|
||||
[ArchiveFileTypeU2f] = &I_u2f_10px,
|
||||
[ArchiveFileTypeSetting] = &I_settings_10px,
|
||||
[ArchiveFileTypeUpdateManifest] = &I_update_10px,
|
||||
[ArchiveFileTypeFolder] = &I_dir_10px,
|
||||
[ArchiveFileTypeUnknown] = &I_unknown_10px,
|
||||
|
||||
Reference in New Issue
Block a user