mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-19 11:21:39 +03:00
Update browser
This commit is contained in:
parent
11f3464e1b
commit
6b99999566
@ -65,7 +65,13 @@ static void
|
||||
archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path));
|
||||
} else {
|
||||
with_view_model(
|
||||
browser->view, ArchiveBrowserViewModel * model, { model->list_loading = false; }, true);
|
||||
browser->view,
|
||||
ArchiveBrowserViewModel * model,
|
||||
{
|
||||
files_array_sort(model->files);
|
||||
model->list_loading = false;
|
||||
},
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +146,7 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) {
|
||||
archive_get_items(browser, furi_string_get_cstr(browser->path));
|
||||
|
||||
if(!archive_file_get_array_size(browser) && archive_is_home(browser)) {
|
||||
archive_switch_tab(browser, TAB_RIGHT);
|
||||
archive_switch_tab(browser, TAB_LEFT);
|
||||
} else {
|
||||
with_view_model(
|
||||
browser->view,
|
||||
@ -207,7 +213,7 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) {
|
||||
false);
|
||||
|
||||
if((items_cnt == 0) && (archive_is_home(browser))) {
|
||||
archive_switch_tab(browser, TAB_RIGHT);
|
||||
archive_switch_tab(browser, TAB_LEFT);
|
||||
}
|
||||
|
||||
archive_update_offset(browser);
|
||||
@ -459,6 +465,7 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
|
||||
}
|
||||
if(tab == ArchiveTabInternal && !furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
browser->is_root = true;
|
||||
archive_set_tab(browser, tab);
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "../archive_i.h"
|
||||
#include <storage/storage.h>
|
||||
|
||||
#define TAB_RIGHT InputKeyRight // Default tab switch direction
|
||||
#define TAB_LEFT InputKeyLeft // Default tab switch direction
|
||||
#define TAB_DEFAULT ArchiveTabFavorites // Start tab
|
||||
#define FILE_LIST_BUF_LEN 50
|
||||
|
||||
|
@ -2,8 +2,11 @@
|
||||
|
||||
#include <m-array.h>
|
||||
#include <furi.h>
|
||||
#include <m-algo.h>
|
||||
#include <m-string.h>
|
||||
#include <storage/storage.h>
|
||||
#include "toolbox/path.h"
|
||||
#include "../../../settings/xtreme_settings/xtreme_settings.h"
|
||||
|
||||
#define FAP_MANIFEST_MAX_ICON_SIZE 32
|
||||
|
||||
@ -81,13 +84,31 @@ static void ArchiveFile_t_clear(ArchiveFile_t* obj) {
|
||||
furi_string_free(obj->custom_name);
|
||||
}
|
||||
|
||||
ARRAY_DEF(
|
||||
files_array,
|
||||
ArchiveFile_t,
|
||||
(INIT(API_2(ArchiveFile_t_init)),
|
||||
SET(API_6(ArchiveFile_t_set)),
|
||||
INIT_SET(API_6(ArchiveFile_t_init_set)),
|
||||
CLEAR(API_2(ArchiveFile_t_clear))))
|
||||
static int ArchiveFile_t_cmp(const ArchiveFile_t* a, const ArchiveFile_t* b) {
|
||||
if(!XTREME_SETTINGS()->sort_ignore_dirs) {
|
||||
if(a->type == ArchiveFileTypeFolder && b->type != ArchiveFileTypeFolder) {
|
||||
return -1;
|
||||
}
|
||||
if(a->type != ArchiveFileTypeFolder && b->type == ArchiveFileTypeFolder) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return furi_string_cmpi(a->path, b->path);
|
||||
}
|
||||
|
||||
#define M_OPL_ArchiveFile_t() \
|
||||
(INIT(API_2(ArchiveFile_t_init)), \
|
||||
SET(API_6(ArchiveFile_t_set)), \
|
||||
INIT_SET(API_6(ArchiveFile_t_init_set)), \
|
||||
CLEAR(API_2(ArchiveFile_t_clear)), \
|
||||
CMP(API_6(ArchiveFile_t_cmp)), \
|
||||
SWAP(M_SWAP_DEFAULT), \
|
||||
EQUAL(API_6(M_EQUAL_DEFAULT)))
|
||||
|
||||
ARRAY_DEF(files_array, ArchiveFile_t)
|
||||
|
||||
ALGO_DEF(files_array, ARRAY_OPLIST(files_array, M_OPL_ArchiveFile_t()))
|
||||
|
||||
void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder, bool is_app);
|
||||
bool archive_get_items(void* context, const char* path);
|
||||
|
@ -589,4 +589,4 @@ void browser_free(ArchiveBrowserView* browser) {
|
||||
|
||||
view_free(browser->view);
|
||||
free(browser);
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include "../helpers/archive_files.h"
|
||||
#include "../helpers/archive_favorites.h"
|
||||
#include "../helpers/archive_menu.h"
|
||||
|
||||
#include <gui/gui_i.h>
|
||||
#include <gui/view.h>
|
||||
@ -10,7 +9,10 @@
|
||||
#include <gui/elements.h>
|
||||
#include <gui/modules/file_browser_worker.h>
|
||||
#include <storage/storage.h>
|
||||
#include <furi.h>
|
||||
#include "../helpers/archive_files.h"
|
||||
#include "../helpers/archive_menu.h"
|
||||
#include "../helpers/archive_favorites.h"
|
||||
#include "gui/modules/file_browser_worker.h"
|
||||
|
||||
#define MAX_LEN_PX 110
|
||||
#define MAX_NAME_LEN 255
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <core/check.h>
|
||||
#include <core/common_defines.h>
|
||||
#include <core/log.h>
|
||||
#include "m-string.h"
|
||||
#include "m-algo.h"
|
||||
#include <m-array.h>
|
||||
|
||||
#define LIST_ITEMS 5u
|
||||
@ -77,13 +79,38 @@ static void BrowserItem_t_clear(BrowserItem_t* obj) {
|
||||
}
|
||||
}
|
||||
|
||||
ARRAY_DEF(
|
||||
items_array,
|
||||
BrowserItem_t,
|
||||
(INIT(API_2(BrowserItem_t_init)),
|
||||
SET(API_6(BrowserItem_t_set)),
|
||||
INIT_SET(API_6(BrowserItem_t_init_set)),
|
||||
CLEAR(API_2(BrowserItem_t_clear))))
|
||||
static int BrowserItem_t_cmp(const BrowserItem_t* a, const BrowserItem_t* b) {
|
||||
// Back indicator comes before everything, then folders, then all other files.
|
||||
if(a->type == BrowserItemTypeBack) {
|
||||
return -1;
|
||||
}
|
||||
if(b->type == BrowserItemTypeBack) {
|
||||
return 1;
|
||||
}
|
||||
if(!XTREME_SETTINGS()->sort_ignore_dirs) {
|
||||
if(a->type == BrowserItemTypeFolder && b->type != BrowserItemTypeFolder) {
|
||||
return -1;
|
||||
}
|
||||
if(a->type != BrowserItemTypeFolder && b->type == BrowserItemTypeFolder) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return furi_string_cmpi(a->path, b->path);
|
||||
}
|
||||
|
||||
#define M_OPL_BrowserItem_t() \
|
||||
(INIT(API_2(BrowserItem_t_init)), \
|
||||
SET(API_6(BrowserItem_t_set)), \
|
||||
INIT_SET(API_6(BrowserItem_t_init_set)), \
|
||||
CLEAR(API_2(BrowserItem_t_clear)), \
|
||||
CMP(API_6(BrowserItem_t_cmp)), \
|
||||
SWAP(M_SWAP_DEFAULT), \
|
||||
EQUAL(API_6(M_EQUAL_DEFAULT)))
|
||||
|
||||
ARRAY_DEF(items_array, BrowserItem_t)
|
||||
|
||||
ALGO_DEF(items_array, ARRAY_OPLIST(items_array, M_OPL_BrowserItem_t()))
|
||||
|
||||
struct FileBrowser {
|
||||
View* view;
|
||||
@ -438,7 +465,13 @@ static void
|
||||
}
|
||||
} else {
|
||||
with_view_model(
|
||||
browser->view, FileBrowserModel * model, { model->list_loading = false; }, true);
|
||||
browser->view,
|
||||
FileBrowserModel * model,
|
||||
{
|
||||
items_array_sort(model->items);
|
||||
model->list_loading = false;
|
||||
},
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
#define TAG "BrowserWorker"
|
||||
|
||||
#define ASSETS_DIR "assets"
|
||||
#define BADUSB_LAYOUTS_DIR "layouts"
|
||||
#define SUBGHZ_TEMP_DIR "tmp_history"
|
||||
#define BROWSER_ROOT STORAGE_ANY_PATH_PREFIX
|
||||
#define FILE_NAME_LEN_MAX 256
|
||||
#define LONG_LOAD_THRESHOLD 100
|
||||
@ -90,7 +92,9 @@ static bool browser_filter_by_name(BrowserWorker* browser, FuriString* name, boo
|
||||
if(is_folder) {
|
||||
// Skip assets folders (if enabled)
|
||||
if(browser->skip_assets) {
|
||||
return ((furi_string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true));
|
||||
return ((furi_string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true)) &&
|
||||
((furi_string_cmp_str(name, BADUSB_LAYOUTS_DIR) == 0) ? (false) : (true)) &&
|
||||
((furi_string_cmp_str(name, SUBGHZ_TEMP_DIR) == 0) ? (false) : (true));
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@ -202,55 +206,58 @@ static bool
|
||||
|
||||
uint32_t items_cnt = 0;
|
||||
|
||||
bool ret = false;
|
||||
do {
|
||||
if(!storage_dir_open(directory, furi_string_get_cstr(path))) {
|
||||
break;
|
||||
}
|
||||
|
||||
items_cnt = 0;
|
||||
while(items_cnt < offset) {
|
||||
if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) {
|
||||
break;
|
||||
}
|
||||
if(storage_file_get_error(directory) == FSE_OK) {
|
||||
furi_string_set(name_str, name_temp);
|
||||
if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) {
|
||||
items_cnt++;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(items_cnt != offset) {
|
||||
break;
|
||||
}
|
||||
// items_cnt = 0;
|
||||
// while(items_cnt < offset) {
|
||||
// if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) {
|
||||
// break;
|
||||
// }
|
||||
// if(storage_file_get_error(directory) == FSE_OK) {
|
||||
// furi_string_set(name_str, name_temp);
|
||||
// if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) {
|
||||
// items_cnt++;
|
||||
// }
|
||||
// } else {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if(items_cnt != offset) {
|
||||
// break;
|
||||
// }
|
||||
|
||||
// FLIPPER DEVS MOMENT
|
||||
// this used to load the file list in chunks, and then sort it...
|
||||
// so while scrolling, it loads more files and sorts them...
|
||||
// chances are, the new files are higher in the sorted list...
|
||||
// so the files keep shifting around while scrolling...
|
||||
// now this does something intelligent and loads all in one go.
|
||||
// might take a few milliseconds longer, but atleast it works :kekw:
|
||||
UNUSED(offset);
|
||||
UNUSED(count);
|
||||
if(browser->list_load_cb) {
|
||||
browser->list_load_cb(browser->cb_ctx, offset);
|
||||
browser->list_load_cb(browser->cb_ctx, 0);
|
||||
}
|
||||
|
||||
items_cnt = 0;
|
||||
while(items_cnt < count) {
|
||||
if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) {
|
||||
break;
|
||||
}
|
||||
if(storage_file_get_error(directory) == FSE_OK) {
|
||||
furi_string_set(name_str, name_temp);
|
||||
if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) {
|
||||
furi_string_printf(name_str, "%s/%s", furi_string_get_cstr(path), name_temp);
|
||||
if(browser->list_item_cb) {
|
||||
browser->list_item_cb(
|
||||
browser->cb_ctx, name_str, (file_info.flags & FSF_DIRECTORY), false);
|
||||
}
|
||||
items_cnt++;
|
||||
while(storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX) &&
|
||||
storage_file_get_error(directory) == FSE_OK) {
|
||||
furi_string_set(name_str, name_temp);
|
||||
if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) {
|
||||
furi_string_printf(name_str, "%s/%s", furi_string_get_cstr(path), name_temp);
|
||||
if(browser->list_item_cb) {
|
||||
browser->list_item_cb(
|
||||
browser->cb_ctx, name_str, (file_info.flags & FSF_DIRECTORY), false);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
items_cnt++;
|
||||
}
|
||||
}
|
||||
if(browser->list_item_cb) {
|
||||
browser->list_item_cb(browser->cb_ctx, NULL, false, true);
|
||||
}
|
||||
ret = true;
|
||||
} while(0);
|
||||
|
||||
furi_string_free(name_str);
|
||||
@ -260,7 +267,7 @@ static bool
|
||||
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
return (items_cnt == count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t browser_worker(void* context) {
|
||||
|
Loading…
Reference in New Issue
Block a user