From 0ec5f72169f32b29d595fbae95d5e54e8cd2cd2f Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 10 Jun 2024 13:02:06 -0600 Subject: [PATCH] Search in current tab --- src/app.rs | 51 +++++++++++++++++++++++++++++++++++++++------------ src/tab.rs | 46 +++++++++++++++++++++++++++++++--------------- 2 files changed, 70 insertions(+), 27 deletions(-) diff --git a/src/app.rs b/src/app.rs index b291bb4..1c18c0c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -37,7 +37,7 @@ use std::{ num::NonZeroU16, path::PathBuf, process, - sync::{Arc, Mutex}, + sync::Arc, time::{self, Instant}, }; @@ -237,7 +237,7 @@ pub enum Message { TabConfig(TabConfig), TabMessage(Option, tab::Message), TabNew, - TabRescan(Entity, Vec), + TabRescan(Entity, Location, Vec), ToggleContextPage(ContextPage), WindowClose, WindowNew, @@ -376,8 +376,9 @@ impl App { let icon_sizes = self.config.tab.icon_sizes; Command::perform( async move { - match tokio::task::spawn_blocking(move || location.scan(icon_sizes)).await { - Ok(items) => message::app(Message::TabRescan(entity, items)), + let location2 = location.clone(); + match tokio::task::spawn_blocking(move || location2.scan(icon_sizes)).await { + Ok(items) => message::app(Message::TabRescan(entity, location, items)), Err(err) => { log::warn!("failed to rescan: {}", err); message::none() @@ -406,7 +407,29 @@ impl App { } fn search(&mut self) -> Command { - self.open_tab(Location::Search(home_dir(), self.search_input.clone())) + let entity = self.tab_model.active(); + let mut title_location_opt = None; + if let Some(tab) = self.tab_model.data_mut::(entity) { + match &tab.location { + Location::Path(path) | Location::Search(path, ..) => { + tab.change_location( + &Location::Search(path.clone(), self.search_input.clone()), + None, + ); + title_location_opt = Some((tab.title(), tab.location.clone())); + } + _ => {} + } + } + if let Some((title, location)) = title_location_opt { + self.tab_model.text_set(entity, title); + return Command::batch([ + self.update_title(), + self.update_watcher(), + self.rescan_tab(entity, location), + ]); + } + Command::none() } fn selected_paths(&self, entity_opt: Option) -> Vec { @@ -977,8 +1000,8 @@ impl Application for App { NavMenuAction::Properties(id), ), cosmic::widget::menu::Item::Divider, - if is_context_trash { - cosmic ::widget::menu::Item::Button( + if is_context_trash { + cosmic::widget::menu::Item::Button( fl!("empty-trash"), NavMenuAction::EmptyTrash(id), ) @@ -1717,12 +1740,16 @@ impl Application for App { }; return self.open_tab(location); } - Message::TabRescan(entity, items) => match self.tab_model.data_mut::(entity) { - Some(tab) => { - tab.set_items(items); + Message::TabRescan(entity, location, items) => { + match self.tab_model.data_mut::(entity) { + Some(tab) => { + if location == tab.location { + tab.set_items(items); + } + } + _ => (), } - _ => (), - }, + } //TODO: TABRELOAD Message::ToggleContextPage(context_page) => { //TODO: ensure context menus are closed diff --git a/src/tab.rs b/src/tab.rs index c135281..632823c 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -376,10 +376,11 @@ pub fn scan_search(tab_path: &PathBuf, term: &str, sizes: IconSizes) -> Vec { + Location::Search(_path, _term) => { cd = Some(location); } Location::Trash => { @@ -1701,7 +1702,7 @@ impl Tab { Some(items) } - pub fn location_view(&self) -> Option> { + pub fn location_view(&self) -> Element { let cosmic_theme::Spacing { space_xxxs, space_xxs, @@ -1747,7 +1748,7 @@ impl Tab { }) .on_submit(Message::Location(location.clone())), ); - return Some(row.into()); + return row.into(); } _ => { //TODO: allow editing other locations @@ -1760,11 +1761,25 @@ impl Tab { .padding(space_xxs) .style(theme::Button::Icon), ); + } else if let Location::Search(_, term) = &self.location { + row = row.push( + widget::button( + widget::row::with_children(vec![ + widget::icon::from_name("system-search-symbolic") + .size(16) + .into(), + widget::text(term).into(), + ]) + .spacing(space_xxs), + ) + .padding(space_xxs) + .style(theme::Button::Icon), + ); } let mut children: Vec> = Vec::new(); match &self.location { - Location::Path(path) => { + Location::Path(path) | Location::Search(path, ..) => { let home_dir = crate::home_dir(); for ancestor in path.ancestors() { let ancestor = ancestor.to_path_buf(); @@ -1811,7 +1826,13 @@ impl Tab { children.push( widget::button(row) .padding(space_xxxs) - .on_press(Message::Location(Location::Path(ancestor))) + .on_press(Message::Location(match &self.location { + Location::Path(_) => Location::Path(ancestor), + Location::Search(_, term) => { + Location::Search(ancestor, term.clone()) + } + other => other.clone(), + })) .style(theme::Button::Link) .into(), ); @@ -1822,9 +1843,6 @@ impl Tab { } children.reverse(); } - Location::Search(path, term) => { - return None; - } Location::Trash => { let mut row = widget::row::with_capacity(2) .align_items(Alignment::Center) @@ -1845,7 +1863,7 @@ impl Tab { for child in children { row = row.push(child); } - Some(row.into()) + row.into() } pub fn empty_view(&self, has_hidden: bool) -> Element { @@ -2485,7 +2503,7 @@ impl Tab { // Update cached size self.size_opt.set(Some(size)); - let location_view_opt = self.location_view(); + let location_view = self.location_view(); let (drag_list, mut item_view, can_scroll) = match self.config.view { View::Grid => self.grid_view(), View::List => self.list_view(), @@ -2545,9 +2563,7 @@ impl Tab { .position(widget::popover::Position::Point(point)); } let mut tab_column = widget::column::with_capacity(3); - if let Some(location_view) = location_view_opt { - tab_column = tab_column.push(location_view); - } + tab_column = tab_column.push(location_view); if can_scroll { tab_column = tab_column.push( widget::scrollable(popover)