Files
Momentum-Firmware/applications/main/archive/scenes/archive_scene_search.c
Willy-JL b7220237de Small bump in the road
- Update assets and references for new project
- Revert DFU image and CLI motd
- Remove NSFW text and flag
- Remove credits animation (will be replaced with a setting menu soon)
- New EvilPortal example HTML and better error message
- Initial standalone naming for asset packs and mainmenu apps
- File migration fixes/improvements
- Remove hotfix workflow
2024-03-01 06:11:16 +00:00

122 lines
4.4 KiB
C

#include "../archive_i.h"
#include "../helpers/archive_favorites.h"
#include "../helpers/archive_files.h"
#include "../helpers/archive_browser.h"
#include "archive/views/archive_browser_view.h"
#include "toolbox/path.h"
#include <dialogs/dialogs.h>
#include <desktop/animations/animation_storage.h>
#define TAG "Archive"
#define SCENE_SEARCH_CUSTOM_EVENT (0UL)
void archive_scene_search_text_input_callback(void* context) {
ArchiveApp* archive = (ArchiveApp*)context;
view_dispatcher_send_custom_event(archive->view_dispatcher, SCENE_SEARCH_CUSTOM_EVENT);
}
void archive_scene_search_on_enter(void* context) {
ArchiveApp* archive = context;
TextInput* text_input = archive->text_input;
strlcpy(archive->text_store, "", MAX_NAME_LEN);
text_input_set_header_text(text_input, "Search for files:");
text_input_set_result_callback(
text_input,
archive_scene_search_text_input_callback,
context,
archive->text_store,
MAX_NAME_LEN,
false);
view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewTextInput);
}
uint32_t archive_scene_search_dirwalk(void* context) {
furi_assert(context);
ArchiveApp* archive = context;
uint32_t count = 1;
DirWalk* dir_walk = dir_walk_alloc(furi_record_open(RECORD_STORAGE));
const char* ignore[] = {
ASSET_PACKS_PATH,
BASE_ANIMATION_DIR,
};
dir_walk_set_recurse_filter(dir_walk, ignore, COUNT_OF(ignore));
FuriString* path = furi_string_alloc();
FuriString* name = furi_string_alloc();
FileInfo fileinfo;
if(dir_walk_open(dir_walk, STORAGE_EXT_PATH_PREFIX)) {
while(scene_manager_get_scene_state(archive->scene_manager, ArchiveAppSceneSearch)) {
DirWalkResult result = dir_walk_read(dir_walk, path, &fileinfo);
if(result == DirWalkError) {
archive_add_app_item(archive->browser, "/app:search/Error while searching!");
archive_set_item_count(archive->browser, ++count);
break;
}
if(result == DirWalkLast) {
if(count == 1) {
archive_add_app_item(archive->browser, "/app:search/No results found!");
archive_set_item_count(archive->browser, ++count);
}
break;
}
if(!file_info_is_dir(&fileinfo)) {
furi_string_set(
name, furi_string_get_cstr(path) + furi_string_search_rchar(path, '/') + 1);
if(strcasestr(furi_string_get_cstr(name), archive->text_store) != NULL) {
archive_add_file_item(archive->browser, false, furi_string_get_cstr(path));
archive_set_item_count(archive->browser, ++count);
}
}
}
} else {
archive_add_app_item(archive->browser, "/app:search/Error while searching!");
archive_set_item_count(archive->browser, ++count);
}
furi_string_set(
archive_get_file_at(archive->browser, 0)->path, "/app:search/Search for files");
scene_manager_set_scene_state(archive->scene_manager, ArchiveAppSceneSearch, false);
furi_string_free(name);
furi_string_free(path);
dir_walk_free(dir_walk);
furi_record_close(RECORD_STORAGE);
return 0;
}
bool archive_scene_search_on_event(void* context, SceneManagerEvent event) {
ArchiveApp* archive = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SCENE_SEARCH_CUSTOM_EVENT) {
archive_file_array_rm_all(archive->browser);
archive_add_app_item(archive->browser, "/app:search/Cancel search");
archive_set_item_count(archive->browser, 1);
// Thread here is fine because only the info pane uses it too,
// but only for directories, which are ignored for search
scene_manager_set_scene_state(archive->scene_manager, ArchiveAppSceneSearch, true);
archive->thread = furi_thread_alloc_ex(
"ArchiveSearchDirWalk",
1024,
(FuriThreadCallback)archive_scene_search_dirwalk,
archive);
furi_thread_start(archive->thread);
scene_manager_previous_scene(archive->scene_manager);
consumed = true;
}
}
return consumed;
}
void archive_scene_search_on_exit(void* context) {
ArchiveApp* archive = context;
text_input_reset(archive->text_input);
}