diff --git a/Documentation/ideas.md b/Documentation/ideas.md index c0128538..8af0de7b 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -31,6 +31,7 @@ - Bug: Turn on WiFi (when testing it wasn't connected/connecting - just active). Open chat. Observe crash. - Toolbar: when the title doesn't fit, scroll the text instead of splitting it onto a new line (try on Waveshare 1.47") - UI: create UI size classification (e.g. "compact" for tiny screens without touch) +- Bug: Crash handling app cannot be exited with an EncoderDevice. (current work-around is to manually reset the device) ## Lower Priority diff --git a/Tactility/Source/app/filebrowser/State.cpp b/Tactility/Source/app/filebrowser/State.cpp index 352f274e..feda67a9 100644 --- a/Tactility/Source/app/filebrowser/State.cpp +++ b/Tactility/Source/app/filebrowser/State.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace tt::app::filebrowser { @@ -56,18 +57,19 @@ bool State::setEntriesForPath(const std::string& path) { return true; } else { dir_entries.clear(); - // TODO: file Lock - int count = file::scandir(path, dir_entries, &file::direntFilterDotEntries, file::direntSortAlphaAndType); - if (count >= 0) { - TT_LOG_I(TAG, "%s has %u entries", path.c_str(), count); - current_path = path; - selected_child_entry = ""; - action = ActionNone; - return true; - } else { - TT_LOG_E(TAG, "Failed to fetch entries for %s", path.c_str()); - return false; - } + return file::withLock(path, [this, &path] { + int count = file::scandir(path, dir_entries, &file::direntFilterDotEntries, file::direntSortAlphaAndType); + if (count >= 0) { + TT_LOG_I(TAG, "%s has %u entries", path.c_str(), count); + current_path = path; + selected_child_entry = ""; + action = ActionNone; + return true; + } else { + TT_LOG_E(TAG, "Failed to fetch entries for %s", path.c_str()); + return false; + } + }); } } diff --git a/Tactility/Source/app/filebrowser/View.cpp b/Tactility/Source/app/filebrowser/View.cpp index 2406c237..95983185 100644 --- a/Tactility/Source/app/filebrowser/View.cpp +++ b/Tactility/Source/app/filebrowser/View.cpp @@ -16,6 +16,7 @@ #include #include +#include #ifdef ESP_PLATFORM #include "Tactility/service/loader/Loader.h" @@ -215,6 +216,8 @@ void View::showActionsForDirectory() { auto* rename_button = lv_list_add_button(action_list, LV_SYMBOL_EDIT, "Rename"); lv_obj_add_event_cb(rename_button, onRenamePressedCallback, LV_EVENT_SHORT_CLICKED, this); + auto* delete_button = lv_list_add_button(action_list, LV_SYMBOL_TRASH, "Delete"); + lv_obj_add_event_cb(delete_button, onDeletePressedCallback, LV_EVENT_SHORT_CLICKED, this); lv_obj_remove_flag(action_list, LV_OBJ_FLAG_HIDDEN); } @@ -314,12 +317,18 @@ void View::onResult(LaunchId launchId, Result result, std::unique_ptr bu switch (state->getPendingAction()) { case State::ActionDelete: { if (alertdialog::getResultIndex(*bundle) == 0) { - int delete_count = remove(filepath.c_str()); - if (delete_count > 0) { - TT_LOG_I(TAG, "Deleted %d items", delete_count); - } else { - TT_LOG_W(TAG, "Failed to delete %s", filepath.c_str()); - } + file::withLock(filepath, [&filepath] { + if (file::isDirectory(filepath)) { + if (!file::deleteRecursively(filepath)) { + TT_LOG_W(TAG, "Failed to delete %s", filepath.c_str()); + } + } else if (file::isFile(filepath)) { + if (remove(filepath.c_str()) <= 0) { + TT_LOG_W(TAG, "Failed to delete %s", filepath.c_str()); + } + } + }); + state->setEntriesForPath(state->getCurrentPath()); update(); } @@ -328,12 +337,15 @@ void View::onResult(LaunchId launchId, Result result, std::unique_ptr bu case State::ActionRename: { auto new_name = inputdialog::getResult(*bundle); if (!new_name.empty() && new_name != state->getSelectedChildEntry()) { - std::string rename_to = file::getChildPath(state->getCurrentPath(), new_name); - if (rename(filepath.c_str(), rename_to.c_str())) { - TT_LOG_I(TAG, "Renamed \"%s\" to \"%s\"", filepath.c_str(), rename_to.c_str()); - } else { - TT_LOG_E(TAG, "Failed to rename \"%s\" to \"%s\"", filepath.c_str(), rename_to.c_str()); - } + file::withLock(filepath, [this, &filepath, &new_name] { + std::string rename_to = file::getChildPath(state->getCurrentPath(), new_name); + if (rename(filepath.c_str(), rename_to.c_str())) { + TT_LOG_I(TAG, "Renamed \"%s\" to \"%s\"", filepath.c_str(), rename_to.c_str()); + } else { + TT_LOG_E(TAG, "Failed to rename \"%s\" to \"%s\"", filepath.c_str(), rename_to.c_str()); + } + }); + state->setEntriesForPath(state->getCurrentPath()); update(); }