From 9c1913a24de6f68cd44a1d2250f541d7eb5e26b0 Mon Sep 17 00:00:00 2001 From: l-const Date: Thu, 29 Aug 2024 02:00:30 +0300 Subject: [PATCH] feat: Refresh/reload tab view & search fix(#146). --- i18n/en/cosmic_files.ftl | 1 + src/app.rs | 32 ++++++++++++++++++++++++++++++++ src/key_bind.rs | 2 ++ src/tab.rs | 7 ++++++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 9407db76..c467187c 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -2,6 +2,7 @@ cosmic-files = COSMIC Files empty-folder = Empty folder empty-folder-hidden = Empty folder (has hidden items) no-results = No results found +refresh-loading = Loading... filesystem = Filesystem home = Home notification-in-progress = File operations are in progress. diff --git a/src/app.rs b/src/app.rs index 71d5d540..536d5316 100644 --- a/src/app.rs +++ b/src/app.rs @@ -69,6 +69,8 @@ use crate::{ tab::{self, HeadingOptions, ItemMetadata, Location, Tab, HOVER_DURATION}, }; +static REFRESH_VIEW_DELAY_MS: u64 = 20; + #[derive(Clone, Debug)] pub enum Mode { App, @@ -111,6 +113,7 @@ pub enum Action { OpenWith, Paste, Properties, + Refresh, Rename, RestoreFromTrash, SearchActivate, @@ -163,6 +166,7 @@ impl Action { Action::OpenWith => Message::ToggleContextPage(ContextPage::OpenWith), Action::Paste => Message::Paste(entity_opt), Action::Properties => Message::ToggleContextPage(ContextPage::Properties(None)), + Action::Refresh => Message::Refresh(entity_opt), Action::Rename => Message::Rename(entity_opt), Action::RestoreFromTrash => Message::RestoreFromTrash(entity_opt), Action::SearchActivate => Message::SearchActivate, @@ -272,6 +276,9 @@ pub enum Message { PendingComplete(u64), PendingError(u64, String), PendingProgress(u64, f32), + Refresh(Option), + RefreshDelayStart(Entity, Location), + RefreshDelayComplete(Entity, Location), RescanTrash, Rename(Option), ReplaceResult(ReplaceResult), @@ -1849,6 +1856,28 @@ impl Application for App { } return self.update_notification(); } + Message::Refresh(entity_opt) => { + let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); + if let Some(tab) = self.tab_model.data_mut::(entity) { + let location = tab.location.clone(); + tab.set_items(vec![]); + tab.refresh_active = true; + return cosmic::command::message(Message::RefreshDelayStart(entity, location)); + } + return Command::none(); + } + Message::RefreshDelayComplete(entity, location) => { + if self.search_input.is_empty() { + return self.rescan_tab(entity, location, None); + } else { + return self.search(); + } + } + Message::RefreshDelayStart(entity, location) => { + return Command::perform(tokio::time::sleep(tokio::time::Duration::from_millis(REFRESH_VIEW_DELAY_MS)), move |_| { + cosmic::app::Message::App(Message::RefreshDelayComplete(entity, location)) + }); + } Message::RescanTrash => { // Update trash icon if empty/full let maybe_entity = self.nav_model.iter().find(|&entity| { @@ -2207,6 +2236,9 @@ impl Application for App { if let Some(selection_path) = selection_path { tab.select_path(selection_path); } + if tab.refresh_active { + tab.refresh_active = false; + } } } _ => (), diff --git a/src/key_bind.rs b/src/key_bind.rs index 255fb897..8bceb4f0 100644 --- a/src/key_bind.rs +++ b/src/key_bind.rs @@ -48,6 +48,8 @@ pub fn key_binds() -> HashMap { bind!([Ctrl], Key::Character("v".into()), Paste); bind!([], Key::Named(Named::Space), Properties); bind!([], Key::Named(Named::F2), Rename); + bind!([], Key::Named(Named::F5), Refresh); + bind!([Ctrl], Key::Character("r".into()), Refresh); bind!([Ctrl], Key::Character("f".into()), SearchActivate); bind!([Ctrl], Key::Character("a".into()), SelectAll); bind!([Ctrl], Key::Character(",".into()), Settings); diff --git a/src/tab.rs b/src/tab.rs index e4a0463f..df91137e 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1171,12 +1171,14 @@ pub struct Tab { pub config: TabConfig, pub(crate) items_opt: Option>, pub dnd_hovered: Option<(Location, Instant)>, + pub(crate) refresh_active: bool, scrollable_id: widget::Id, select_focus: Option, select_range: Option<(usize, usize)>, cached_selected: RefCell>, clicked: Option, selected_clicked: bool, + } fn folder_name>(path: P) -> (String, bool) { @@ -1216,6 +1218,7 @@ impl Tab { history, config, items_opt: None, + refresh_active: false, scrollable_id: widget::Id::unique(), select_focus: None, select_range: None, @@ -2608,7 +2611,9 @@ impl Tab { .size(64) .icon() .into(), - widget::text(if has_hidden { + widget::text(if self.refresh_active { + fl!("refresh-loading") + } else if has_hidden { fl!("empty-folder-hidden") } else if matches!(self.location, Location::Search(_, _)) { fl!("no-results")