From e6d8c87267059c4cf0c7af060ef153fb192eea12 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 | 5 +++++ 4 files changed, 40 insertions(+) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index b150ffc1..a37878d2 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 9041498f..c42e819f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -57,6 +57,8 @@ use crate::{ tab::{self, HeadingOptions, ItemMetadata, Location, Tab, HOVER_DURATION}, }; +static REFRESH_VIEW_DELAY_MS: u64 = 20; + #[derive(Clone, Debug)] pub struct Flags { pub config_handler: Option, @@ -90,6 +92,7 @@ pub enum Action { OpenWith, Paste, Properties, + Refresh, Rename, RestoreFromTrash, SearchActivate, @@ -139,6 +142,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, @@ -243,6 +247,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), @@ -1717,6 +1724,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| { @@ -2048,6 +2077,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 3abf36e4..af42fcf0 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1018,12 +1018,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, + } impl Tab { @@ -1044,6 +1046,7 @@ impl Tab { history, config, items_opt: None, + refresh_active: false, scrollable_id: widget::Id::unique(), select_focus: None, select_range: None, @@ -2394,6 +2397,8 @@ impl Tab { .into(), widget::text(if has_hidden { fl!("empty-folder-hidden") + } else if self.refresh_active { + fl!("refresh-loading") } else if matches!(self.location, Location::Search(_, _)) { fl!("no-results") } else {