- Created `tt_get_platform()` to use with more complex platform checks aside from the `ESP_PLATFORM` preprocessor directive - Expand PC/sim memory to 256k so we can load the max amount of entries in Files without memory issues. I decided to skip the LVGL buffer entirely so it's easier to catch memory leaks. - Simplified logic in `files_data.c` - Implement statusbar as a proper widget - Implement statusbar widget for wifi service - Implement statusbar widget for sdcard mounting/unmounting
113 lines
3.8 KiB
C
113 lines
3.8 KiB
C
#include "files_data.h"
|
|
#include "file_utils.h"
|
|
#include "tactility_core.h"
|
|
#include <string_utils.h>
|
|
|
|
#define TAG "files_app"
|
|
|
|
static bool get_child_path(char* base_path, const char* child_path, char* out_path, size_t out_size) {
|
|
size_t current_path_length = strlen(base_path);
|
|
size_t added_path_length = strlen(child_path);
|
|
size_t total_path_length = current_path_length + added_path_length + 1; // two paths with `/`
|
|
|
|
if (total_path_length >= out_size) {
|
|
TT_LOG_E(TAG, "Path limit reached (%d chars)", MAX_PATH_LENGTH);
|
|
return false;
|
|
} else {
|
|
memcpy(out_path, base_path, current_path_length);
|
|
// Postfix with "/" when the current path isn't "/"
|
|
if (current_path_length != 1) {
|
|
out_path[current_path_length] = '/';
|
|
strcpy(&out_path[current_path_length + 1], child_path);
|
|
} else {
|
|
strcpy(&out_path[current_path_length], child_path);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
FilesData* files_data_alloc() {
|
|
FilesData* data = malloc(sizeof(FilesData));
|
|
*data = (FilesData) {
|
|
.current_path = { 0x00 },
|
|
.dir_entries = NULL,
|
|
.dir_entries_count = 0
|
|
};
|
|
return data;
|
|
}
|
|
|
|
void files_data_free(FilesData* data) {
|
|
files_data_free_entries(data);
|
|
free(data);
|
|
}
|
|
|
|
void files_data_free_entries(FilesData* data) {
|
|
for (int i = 0; i < data->dir_entries_count; ++i) {
|
|
free(data->dir_entries[i]);
|
|
}
|
|
free(data->dir_entries);
|
|
data->dir_entries = NULL;
|
|
data->dir_entries_count = 0;
|
|
}
|
|
|
|
static void files_data_set_entries(FilesData* data, struct dirent** entries, int count) {
|
|
if (data->dir_entries != NULL) {
|
|
files_data_free_entries(data);
|
|
}
|
|
|
|
data->dir_entries = entries;
|
|
data->dir_entries_count = count;
|
|
}
|
|
|
|
bool files_data_set_entries_for_path(FilesData* data, const char* path) {
|
|
TT_LOG_I(TAG, "Changing path: %s -> %s", data->current_path, path);
|
|
|
|
/**
|
|
* ESP32 does not have a root directory, so we have to create it manually.
|
|
* We'll add the NVS Flash partitions and the binding for the sdcard.
|
|
*/
|
|
if (tt_get_platform() == PLATFORM_ESP && strcmp(path, "/") == 0) {
|
|
int dir_entries_count = 3;
|
|
struct dirent** dir_entries = malloc(sizeof(struct dirent*) * 3);
|
|
|
|
dir_entries[0] = malloc(sizeof(struct dirent));
|
|
dir_entries[0]->d_type = TT_DT_DIR;
|
|
strcpy(dir_entries[0]->d_name, "assets");
|
|
|
|
dir_entries[1] = malloc(sizeof(struct dirent));
|
|
dir_entries[1]->d_type = TT_DT_DIR;
|
|
strcpy(dir_entries[1]->d_name, "config");
|
|
|
|
dir_entries[2] = malloc(sizeof(struct dirent));
|
|
dir_entries[2]->d_type = TT_DT_DIR;
|
|
strcpy(dir_entries[2]->d_name, "sdcard");
|
|
|
|
files_data_set_entries(data, dir_entries, dir_entries_count);
|
|
strcpy(data->current_path, path);
|
|
return true;
|
|
} else {
|
|
struct dirent** entries = NULL;
|
|
int count = tt_scandir(path, &entries, &tt_dirent_filter_dot_entries, &tt_dirent_sort_alpha_and_type);
|
|
if (count >= 0) {
|
|
TT_LOG_I(TAG, "%s has %u entries", path, count);
|
|
files_data_set_entries(data, entries, count);
|
|
strcpy(data->current_path, path);
|
|
return true;
|
|
} else {
|
|
TT_LOG_E(TAG, "Failed to fetch entries for %s", path);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool files_data_set_entries_for_child_path(FilesData* data, const char* child_path) {
|
|
char new_absolute_path[MAX_PATH_LENGTH];
|
|
if (get_child_path(data->current_path, child_path, new_absolute_path, MAX_PATH_LENGTH)) {
|
|
TT_LOG_I(TAG, "Navigating from %s to %s", data->current_path, new_absolute_path);
|
|
return files_data_set_entries_for_path(data, new_absolute_path);
|
|
} else {
|
|
TT_LOG_I(TAG, "Failed to get child path for %s/%s", data->current_path, child_path);
|
|
return false;
|
|
}
|
|
}
|