mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-11 19:33:30 -07:00
File and folder info go brrrrrrrrr
This commit is contained in:
@@ -8,9 +8,11 @@
|
||||
#include <gui/scene_manager.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
#include <gui/modules/widget.h>
|
||||
#include <gui/modules/widget_elements/widget_element_i.h>
|
||||
#include <gui/view_stack.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
#include <gui/modules/loading.h>
|
||||
#include <toolbox/dir_walk.h>
|
||||
#include <loader/loader.h>
|
||||
|
||||
#include "views/archive_browser_view.h"
|
||||
@@ -39,6 +41,9 @@ struct ArchiveApp {
|
||||
FuriString* fav_move_str;
|
||||
char text_store[MAX_NAME_LEN];
|
||||
FuriString* file_extension;
|
||||
|
||||
WidgetElement* element;
|
||||
FuriThread* thread;
|
||||
};
|
||||
|
||||
void archive_show_loading_popup(ArchiveApp* context, bool show);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#define TAG "Archive"
|
||||
|
||||
const char* units[] = {"Bytes", "KiB", "MiB", "GiB", "TiB"};
|
||||
|
||||
void archive_scene_info_widget_callback(GuiButtonType result, InputType type, void* context) {
|
||||
furi_assert(context);
|
||||
ArchiveApp* app = (ArchiveApp*)context;
|
||||
@@ -11,6 +13,54 @@ void archive_scene_info_widget_callback(GuiButtonType result, InputType type, vo
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t archive_scene_info_dirwalk(void* context) {
|
||||
furi_assert(context);
|
||||
ArchiveApp* instance = context;
|
||||
|
||||
char buf[128];
|
||||
FileInfo fileinfo;
|
||||
uint64_t total = 0;
|
||||
DirWalk* dir_walk = dir_walk_alloc(furi_record_open(RECORD_STORAGE));
|
||||
ArchiveFile_t* current = archive_get_current_file(instance->browser);
|
||||
if(dir_walk_open(dir_walk, furi_string_get_cstr(current->path))) {
|
||||
while(scene_manager_get_scene_state(instance->scene_manager, ArchiveAppSceneInfo)) {
|
||||
DirWalkResult result = dir_walk_read(dir_walk, NULL, &fileinfo);
|
||||
if(result == DirWalkError) {
|
||||
snprintf(buf, sizeof(buf), "Size: \e#Error\e#");
|
||||
widget_element_text_box_set_text(instance->element, buf);
|
||||
break;
|
||||
}
|
||||
bool is_last = result == DirWalkLast;
|
||||
if(!file_info_is_dir(&fileinfo) || is_last) {
|
||||
if(!is_last) total += fileinfo.size;
|
||||
double show = total;
|
||||
size_t unit;
|
||||
for(unit = 0; unit < COUNT_OF(units); unit++) {
|
||||
if(show < 1024) break;
|
||||
show /= 1024;
|
||||
}
|
||||
snprintf(
|
||||
buf,
|
||||
sizeof(buf),
|
||||
unit ? "Size: %s\e#%.2f\e# %s" : "Size: %s\e#%.0f\e# %s",
|
||||
is_last ? "" : "... ",
|
||||
show,
|
||||
units[unit]);
|
||||
widget_element_text_box_set_text(instance->element, buf);
|
||||
}
|
||||
if(is_last) break;
|
||||
}
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "Size: \e#Error\e#");
|
||||
widget_element_text_box_set_text(instance->element, buf);
|
||||
}
|
||||
dir_walk_free(dir_walk);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, ArchiveViewWidget);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void archive_scene_info_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
ArchiveApp* instance = context;
|
||||
@@ -18,55 +68,30 @@ void archive_scene_info_on_enter(void* context) {
|
||||
widget_add_button_element(
|
||||
instance->widget, GuiButtonTypeLeft, "Back", archive_scene_info_widget_callback, instance);
|
||||
|
||||
FuriString* filename;
|
||||
FuriString* dirname;
|
||||
FuriString* str_size;
|
||||
filename = furi_string_alloc();
|
||||
dirname = furi_string_alloc();
|
||||
str_size = furi_string_alloc();
|
||||
FuriString* filename = furi_string_alloc();
|
||||
FuriString* dirname = furi_string_alloc();
|
||||
|
||||
ArchiveFile_t* current = archive_get_current_file(instance->browser);
|
||||
char file_info_message[128];
|
||||
Storage* fs_api = furi_record_open(RECORD_STORAGE);
|
||||
char buf[128];
|
||||
|
||||
// Filename
|
||||
path_extract_filename(current->path, filename, false);
|
||||
snprintf(
|
||||
file_info_message, sizeof(file_info_message), "\e#%s\e#", furi_string_get_cstr(filename));
|
||||
snprintf(buf, sizeof(buf), "\e#%s\e#", furi_string_get_cstr(filename));
|
||||
widget_add_text_box_element(
|
||||
instance->widget, 0, 0, 128, 25, AlignLeft, AlignCenter, file_info_message, false);
|
||||
instance->widget, 0, 0, 128, 24, AlignLeft, AlignCenter, buf, false);
|
||||
|
||||
// Directory path
|
||||
path_extract_dirname(furi_string_get_cstr(current->path), dirname);
|
||||
|
||||
// File size
|
||||
FileInfo fileinfo;
|
||||
if(storage_common_stat(fs_api, furi_string_get_cstr(current->path), &fileinfo) != FSE_OK ||
|
||||
file_info_is_dir(&fileinfo)) {
|
||||
snprintf(
|
||||
file_info_message,
|
||||
sizeof(file_info_message),
|
||||
"Size: \e#N/A\e#\n%s",
|
||||
furi_string_get_cstr(dirname));
|
||||
} else if(fileinfo.size <= 1024) {
|
||||
furi_string_printf(str_size, "%lld", fileinfo.size);
|
||||
snprintf(
|
||||
file_info_message,
|
||||
sizeof(file_info_message),
|
||||
"Size: \e#%s\e# bytes\n%s",
|
||||
furi_string_get_cstr(str_size),
|
||||
furi_string_get_cstr(dirname));
|
||||
} else {
|
||||
furi_string_printf(str_size, "%lld", fileinfo.size / 1024);
|
||||
snprintf(
|
||||
file_info_message,
|
||||
sizeof(file_info_message),
|
||||
"Size: \e#%s\e# Kb.\n%s",
|
||||
furi_string_get_cstr(str_size),
|
||||
furi_string_get_cstr(dirname));
|
||||
}
|
||||
widget_add_text_box_element(
|
||||
instance->widget, 0, 25, 128, 25, AlignLeft, AlignCenter, file_info_message, true);
|
||||
instance->widget,
|
||||
0,
|
||||
42,
|
||||
128,
|
||||
12,
|
||||
AlignLeft,
|
||||
AlignCenter,
|
||||
furi_string_get_cstr(dirname),
|
||||
false);
|
||||
|
||||
// This one to return and cursor select this file
|
||||
path_extract_filename_no_ext(furi_string_get_cstr(current->path), filename);
|
||||
@@ -74,9 +99,44 @@ void archive_scene_info_on_enter(void* context) {
|
||||
|
||||
furi_string_free(filename);
|
||||
furi_string_free(dirname);
|
||||
furi_string_free(str_size);
|
||||
|
||||
// File size
|
||||
FileInfo fileinfo;
|
||||
bool is_dir = false;
|
||||
if(storage_common_stat(
|
||||
furi_record_open(RECORD_STORAGE), furi_string_get_cstr(current->path), &fileinfo) !=
|
||||
FSE_OK) {
|
||||
snprintf(buf, sizeof(buf), "Size: \e#Error\e#");
|
||||
} else if(file_info_is_dir(&fileinfo)) {
|
||||
is_dir = true;
|
||||
snprintf(buf, sizeof(buf), "Size: ... \e#0\e# %s", units[0]);
|
||||
|
||||
} else {
|
||||
double show = fileinfo.size;
|
||||
size_t unit;
|
||||
for(unit = 0; unit < COUNT_OF(units); unit++) {
|
||||
if(show < 1024) break;
|
||||
show /= 1024;
|
||||
}
|
||||
snprintf(
|
||||
buf,
|
||||
sizeof(buf),
|
||||
unit ? "Size: \e#%.2f\e# %s" : "Size: \e#%.0f\e# %s",
|
||||
show,
|
||||
units[unit]);
|
||||
}
|
||||
instance->element = widget_add_text_box_element(
|
||||
instance->widget, 0, 24, 128, 24, AlignLeft, AlignCenter, buf, true);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, ArchiveViewWidget);
|
||||
|
||||
if(is_dir) {
|
||||
scene_manager_set_scene_state(instance->scene_manager, ArchiveAppSceneInfo, true);
|
||||
instance->thread = furi_thread_alloc_ex(
|
||||
"ArchiveDirWalk", 1024, (FuriThreadCallback)archive_scene_info_dirwalk, instance);
|
||||
furi_thread_start(instance->thread);
|
||||
}
|
||||
}
|
||||
|
||||
bool archive_scene_info_on_event(void* context, SceneManagerEvent event) {
|
||||
@@ -94,5 +154,11 @@ void archive_scene_info_on_exit(void* context) {
|
||||
furi_assert(context);
|
||||
ArchiveApp* app = (ArchiveApp*)context;
|
||||
|
||||
scene_manager_set_scene_state(app->scene_manager, ArchiveAppSceneInfo, false);
|
||||
if(app->thread) {
|
||||
furi_thread_join(app->thread);
|
||||
furi_thread_free(app->thread);
|
||||
app->thread = NULL;
|
||||
}
|
||||
widget_reset(app->widget);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user