Skip to content

Fs tree - #70

Open
Divarion-D wants to merge 2 commits into
GyverLibs:mainfrom
Divarion-D:fs-tree
Open

Fs tree#70
Divarion-D wants to merge 2 commits into
GyverLibs:mainfrom
Divarion-D:fs-tree

Conversation

@Divarion-D

Copy link
Copy Markdown

Добавлен опциональный древовидный режим файлового менеджера (SETT_FS_TREE)

Проблема

Сейчас файловый менеджер отображает файловую систему одним плоским списком полных путей. Это связано с тем, что прошивка возвращает рекурсивный список файлов (HybridFS::listDir()), а веб-интерфейс просто выводит каждую строку отдельно.

Если файлы лежат в папках (например, записи с камеры, логи или любые автоматически создаваемые файлы), пользоваться таким списком становится неудобно. Вместо привычной структуры получается длинный список вида:

/CamName003/CamName003.014.avi
/CamName003/CamName003.015.avi
...

Найти нужный файл сложно, а чтобы удалить папку, приходится удалять каждый файл отдельно.

Настройками это не решается. В библиотеке есть только возможность включить или отключить файловый менеджер (useFS()), понятия директорий в протоколе нет.


Что добавлено

Добавлен необязательный режим отображения файлов по папкам.

Включается так:

#define SETT_FS_TREE
#include <SettingsGyver.h>

SettingsGyver sett("My Settings");

void setup() {
    sett.useFsTree();
    sett.begin();
}

После включения файлы автоматически группируются по папкам.

Для каждой папки отображаются:

  • имя;
  • количество файлов;
  • общий размер;
  • кнопка удаления.

В списке файлов отображается только имя файла, полный путь остаётся в подсказке.

Удаление папки выполняется одним действием с подтверждением и удаляет всё её содержимое.


Реализация

Веб-интерфейс

Вся логика находится в src/web/fs_tree.h и подключается через существующий механизм /custom.js.

Скрипт загружается браузером один раз и кэшируется по хэшу.

После каждого обновления списка файлов он отслеживает контейнер .fs_cont и группирует уже созданные элементы по папкам.

Важно, что скрипт не создаёт собственный интерфейс, а лишь переставляет существующие элементы DOM. Благодаря этому скачивание, редактирование и удаление отдельных файлов продолжают работать без каких-либо изменений.


Удаление папок

Штатная веб-морда умеет удалять только отдельные пути.

При удалении папки скрипт отправляет обычное действие remove, передавая путь директории.

В parse() под SETT_FS_TREE добавлен простой fallback:

  1. сначала путь удаляется как файл;
  2. если это не удалось — выполняется рекурсивное удаление директории.

Отдельная проверка "это папка?" не требуется, так как unlink() для директории всё равно возвращает ошибку.

Рекурсивное удаление реализовано через:

  • FSWrapper::removeDir() (ESP32 и ESP8266);
  • HybridFS::removeDir().

Перед удалением содержимое директории сначала собирается в список, и только потом удаляется. Это исключает проблемы при обходе файловой системы (openNextFile() не гарантирует корректную работу при удалении элементов во время обхода).


Размер прошивки

Без SETT_FS_TREE не компилируется ничего из новой функциональности:

  • useFsTree();
  • JavaScript;
  • removeDir().

Измерения на ESP32-CAM:

Режим Flash RAM
выключен 1 113 529 61 880
включен 1 119 601 61 880

Дополнительный размер прошивки — 6072 байта.

Использование оперативной памяти не изменилось.

При отключённом флаге итоговая сборка совпадает с текущей версией библиотеки.


Ограничения

Используется слот custom.js

Функция useFsTree() несовместима с setCustom() и setCustomFile(), так как использует существующий механизм /custom.js.

Если это окажется принципиальным, можно сделать поддержку нескольких кастомных JS-чанков, но это потребует изменений во всех реализациях веб-сервера, поэтому в данный PR не включалось.

Зависимость от текущей вёрстки

Скрипт использует внутренние классы файлового менеджера:

  • .fs_cont
  • .fs_row
  • .fs_path
  • .fs_size
  • .fs_info

Также он зависит от текущего формата registerCustom() (один класс без WidgetBase, Component, EL, popup и т.п.). Эти ограничения описаны в комментарии в fs_tree.h.

Индикатор занятого места

После удаления папки индикатор занятого места обновляется только при следующем открытии вкладки, так как текущая веб-морда не обрабатывает обновление после такого запроса.

Вложенность

Папки группируются по полному пути.

Например:

/a/b/file.txt

будет отображаться как одна папка:

/a/b

Полноценное многоуровневое дерево не реализовано.


Проверено

Проверено на ESP32-CAM (Arduino Core, PlatformIO).

Проверено:

  • сборка с SETT_FS_TREE;
  • сборка без SETT_FS_TREE;
  • отображение файлов по папкам;
  • сворачивание и разворачивание папок;
  • удаление отдельных файлов;
  • рекурсивное удаление папок;
  • отсутствие изменений в размере RAM;
  • корректная работа registerCustom() и обработка AsyncConfirm/popup.

image

Файловый менеджер показывает файловую систему одним плоским списком полных
путей: прошивка отдаёт рекурсивный листинг (HybridFS::listDir), а вебморда
рисует по строке на путь. Если файлы разложены по папкам (логгеры, записи по
датам), таким списком неудобно пользоваться.

Добавлен опциональный вид по папкам: объявить SETT_FS_TREE и вызвать
useFsTree(). Скрипт отдаётся через штатный слот кастомного js, следит за
панелью файлов и после каждой перерисовки раскладывает строки по сворачиваемым
папкам. Он перемещает элементы, созданные самой вебмордой, поэтому скачивание,
редактирование и удаление продолжают работать без изменений.

Без SETT_FS_TREE ни метода, ни скрипта в сборке нет: проверено на esp32,
разница по флешу 3684 байта (ровно размер скрипта), RAM не меняется.
В заголовке папки появилась кнопка удаления. Вебморда умеет удалять только
файлы, поэтому скрипт отправляет действие remove с путём папки, а прошивка со
сборкой SETT_FS_TREE пробует удалить путь как файл и, если не вышло, удаляет
его как папку рекурсивно - HybridFS::removeDir() / FSWrapper::removeDir().

Содержимое директории сначала собирается в список и только потом удаляется:
удалять записи прямо во время обхода директории небезопасно.

Без SETT_FS_TREE поведение и размер прошивки не меняются: проверено на esp32,
сборка без флага 1 113 529 байт против 1 119 601 с флагом.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant