Search in current tab

This commit is contained in:
Jeremy Soller 2024-06-10 13:02:06 -06:00
parent a193b186fb
commit 0ec5f72169
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
2 changed files with 70 additions and 27 deletions

View file

@ -37,7 +37,7 @@ use std::{
num::NonZeroU16, num::NonZeroU16,
path::PathBuf, path::PathBuf,
process, process,
sync::{Arc, Mutex}, sync::Arc,
time::{self, Instant}, time::{self, Instant},
}; };
@ -237,7 +237,7 @@ pub enum Message {
TabConfig(TabConfig), TabConfig(TabConfig),
TabMessage(Option<Entity>, tab::Message), TabMessage(Option<Entity>, tab::Message),
TabNew, TabNew,
TabRescan(Entity, Vec<tab::Item>), TabRescan(Entity, Location, Vec<tab::Item>),
ToggleContextPage(ContextPage), ToggleContextPage(ContextPage),
WindowClose, WindowClose,
WindowNew, WindowNew,
@ -376,8 +376,9 @@ impl App {
let icon_sizes = self.config.tab.icon_sizes; let icon_sizes = self.config.tab.icon_sizes;
Command::perform( Command::perform(
async move { async move {
match tokio::task::spawn_blocking(move || location.scan(icon_sizes)).await { let location2 = location.clone();
Ok(items) => message::app(Message::TabRescan(entity, items)), match tokio::task::spawn_blocking(move || location2.scan(icon_sizes)).await {
Ok(items) => message::app(Message::TabRescan(entity, location, items)),
Err(err) => { Err(err) => {
log::warn!("failed to rescan: {}", err); log::warn!("failed to rescan: {}", err);
message::none() message::none()
@ -406,7 +407,29 @@ impl App {
} }
fn search(&mut self) -> Command<Message> { fn search(&mut self) -> Command<Message> {
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::<Tab>(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<Entity>) -> Vec<PathBuf> { fn selected_paths(&self, entity_opt: Option<Entity>) -> Vec<PathBuf> {
@ -977,8 +1000,8 @@ impl Application for App {
NavMenuAction::Properties(id), NavMenuAction::Properties(id),
), ),
cosmic::widget::menu::Item::Divider, cosmic::widget::menu::Item::Divider,
if is_context_trash { if is_context_trash {
cosmic ::widget::menu::Item::Button( cosmic::widget::menu::Item::Button(
fl!("empty-trash"), fl!("empty-trash"),
NavMenuAction::EmptyTrash(id), NavMenuAction::EmptyTrash(id),
) )
@ -1717,12 +1740,16 @@ impl Application for App {
}; };
return self.open_tab(location); return self.open_tab(location);
} }
Message::TabRescan(entity, items) => match self.tab_model.data_mut::<Tab>(entity) { Message::TabRescan(entity, location, items) => {
Some(tab) => { match self.tab_model.data_mut::<Tab>(entity) {
tab.set_items(items); Some(tab) => {
if location == tab.location {
tab.set_items(items);
}
}
_ => (),
} }
_ => (), }
},
//TODO: TABRELOAD //TODO: TABRELOAD
Message::ToggleContextPage(context_page) => { Message::ToggleContextPage(context_page) => {
//TODO: ensure context menus are closed //TODO: ensure context menus are closed

View file

@ -376,10 +376,11 @@ pub fn scan_search(tab_path: &PathBuf, term: &str, sizes: IconSizes) -> Vec<Item
let mut items = Arc::into_inner(items_arc).unwrap().into_inner().unwrap(); let mut items = Arc::into_inner(items_arc).unwrap().into_inner().unwrap();
let duration = start.elapsed(); let duration = start.elapsed();
log::info!( log::info!(
"searched for {:?} in {:?}, found {} items", "searched for {:?} inside {:?} in {:?}, found {} items",
term, term,
tab_path,
duration, duration,
items.len() items.len(),
); );
let start = Instant::now(); let start = Instant::now();
@ -1417,7 +1418,7 @@ impl Tab {
commands.push(Command::OpenFile(path.clone())); commands.push(Command::OpenFile(path.clone()));
} }
} }
Location::Search(path, term) => { Location::Search(_path, _term) => {
cd = Some(location); cd = Some(location);
} }
Location::Trash => { Location::Trash => {
@ -1701,7 +1702,7 @@ impl Tab {
Some(items) Some(items)
} }
pub fn location_view(&self) -> Option<Element<Message>> { pub fn location_view(&self) -> Element<Message> {
let cosmic_theme::Spacing { let cosmic_theme::Spacing {
space_xxxs, space_xxxs,
space_xxs, space_xxs,
@ -1747,7 +1748,7 @@ impl Tab {
}) })
.on_submit(Message::Location(location.clone())), .on_submit(Message::Location(location.clone())),
); );
return Some(row.into()); return row.into();
} }
_ => { _ => {
//TODO: allow editing other locations //TODO: allow editing other locations
@ -1760,11 +1761,25 @@ impl Tab {
.padding(space_xxs) .padding(space_xxs)
.style(theme::Button::Icon), .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<Element<_>> = Vec::new(); let mut children: Vec<Element<_>> = Vec::new();
match &self.location { match &self.location {
Location::Path(path) => { Location::Path(path) | Location::Search(path, ..) => {
let home_dir = crate::home_dir(); let home_dir = crate::home_dir();
for ancestor in path.ancestors() { for ancestor in path.ancestors() {
let ancestor = ancestor.to_path_buf(); let ancestor = ancestor.to_path_buf();
@ -1811,7 +1826,13 @@ impl Tab {
children.push( children.push(
widget::button(row) widget::button(row)
.padding(space_xxxs) .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) .style(theme::Button::Link)
.into(), .into(),
); );
@ -1822,9 +1843,6 @@ impl Tab {
} }
children.reverse(); children.reverse();
} }
Location::Search(path, term) => {
return None;
}
Location::Trash => { Location::Trash => {
let mut row = widget::row::with_capacity(2) let mut row = widget::row::with_capacity(2)
.align_items(Alignment::Center) .align_items(Alignment::Center)
@ -1845,7 +1863,7 @@ impl Tab {
for child in children { for child in children {
row = row.push(child); row = row.push(child);
} }
Some(row.into()) row.into()
} }
pub fn empty_view(&self, has_hidden: bool) -> Element<Message> { pub fn empty_view(&self, has_hidden: bool) -> Element<Message> {
@ -2485,7 +2503,7 @@ impl Tab {
// Update cached size // Update cached size
self.size_opt.set(Some(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 { let (drag_list, mut item_view, can_scroll) = match self.config.view {
View::Grid => self.grid_view(), View::Grid => self.grid_view(),
View::List => self.list_view(), View::List => self.list_view(),
@ -2545,9 +2563,7 @@ impl Tab {
.position(widget::popover::Position::Point(point)); .position(widget::popover::Position::Point(point));
} }
let mut tab_column = widget::column::with_capacity(3); 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 { if can_scroll {
tab_column = tab_column.push( tab_column = tab_column.push(
widget::scrollable(popover) widget::scrollable(popover)