Select previous directory when navigating back

This commit is contained in:
Jason Rodney Hansen 2024-08-17 13:16:53 -06:00
parent aebc652006
commit 0575ec7cb8
3 changed files with 44 additions and 28 deletions

View file

@ -252,7 +252,7 @@ pub enum Message {
TabConfig(TabConfig), TabConfig(TabConfig),
TabMessage(Option<Entity>, tab::Message), TabMessage(Option<Entity>, tab::Message),
TabNew, TabNew,
TabRescan(Entity, Location, Vec<tab::Item>), TabRescan(Entity, Location, Vec<tab::Item>, Option<PathBuf>),
ToggleContextPage(ContextPage), ToggleContextPage(ContextPage),
Undo(usize), Undo(usize),
UndoTrash(usize, Arc<[PathBuf]>), UndoTrash(usize, Arc<[PathBuf]>),
@ -393,7 +393,7 @@ impl App {
Command::batch([ Command::batch([
self.update_title(), self.update_title(),
self.update_watcher(), self.update_watcher(),
self.rescan_tab(entity, location), self.rescan_tab(entity, location, None),
]) ])
} }
@ -403,13 +403,20 @@ impl App {
self.pending_operations.insert(id, (operation, 0.0)); self.pending_operations.insert(id, (operation, 0.0));
} }
fn rescan_tab(&mut self, entity: Entity, location: Location) -> Command<Message> { fn rescan_tab(
&mut self,
entity: Entity,
location: Location,
selection_path: Option<PathBuf>,
) -> Command<Message> {
let icon_sizes = self.config.tab.icon_sizes; let icon_sizes = self.config.tab.icon_sizes;
Command::perform( Command::perform(
async move { async move {
let location2 = location.clone(); let location2 = location.clone();
match tokio::task::spawn_blocking(move || location2.scan(icon_sizes)).await { match tokio::task::spawn_blocking(move || location2.scan(icon_sizes)).await {
Ok(items) => message::app(Message::TabRescan(entity, location, items)), Ok(items) => {
message::app(Message::TabRescan(entity, location, items, selection_path))
}
Err(err) => { Err(err) => {
log::warn!("failed to rescan: {}", err); log::warn!("failed to rescan: {}", err);
message::none() message::none()
@ -432,7 +439,7 @@ impl App {
let mut commands = Vec::with_capacity(needs_reload.len()); let mut commands = Vec::with_capacity(needs_reload.len());
for (entity, location) in needs_reload { for (entity, location) in needs_reload {
commands.push(self.rescan_tab(entity, location)); commands.push(self.rescan_tab(entity, location, None));
} }
Command::batch(commands) Command::batch(commands)
} }
@ -445,14 +452,10 @@ impl App {
Location::Path(path) | Location::Search(path, ..) => { Location::Path(path) | Location::Search(path, ..) => {
let location = if !self.search_input.is_empty() { let location = if !self.search_input.is_empty() {
Location::Search(path.clone(), self.search_input.clone()) Location::Search(path.clone(), self.search_input.clone())
} } else {
else {
Location::Path(path.clone()) Location::Path(path.clone())
}; };
tab.change_location( tab.change_location(&location, None);
&location,
None,
);
title_location_opt = Some((tab.title(), tab.location.clone())); title_location_opt = Some((tab.title(), tab.location.clone()));
} }
_ => {} _ => {}
@ -463,7 +466,7 @@ impl App {
return Command::batch([ return Command::batch([
self.update_title(), self.update_title(),
self.update_watcher(), self.update_watcher(),
self.rescan_tab(entity, location), self.rescan_tab(entity, location, None),
]); ]);
} }
Command::none() Command::none()
@ -1394,7 +1397,7 @@ impl Application for App {
}; };
if let Some(title) = title_opt { if let Some(title) = title_opt {
self.tab_model.text_set(entity, title); self.tab_model.text_set(entity, title);
commands.push(self.rescan_tab(entity, home_location.clone())); commands.push(self.rescan_tab(entity, home_location.clone(), None));
} }
} }
if !commands.is_empty() { if !commands.is_empty() {
@ -1492,7 +1495,7 @@ impl Application for App {
let mut commands = Vec::with_capacity(needs_reload.len()); let mut commands = Vec::with_capacity(needs_reload.len());
for (entity, location) in needs_reload { for (entity, location) in needs_reload {
commands.push(self.rescan_tab(entity, location)); commands.push(self.rescan_tab(entity, location, None));
} }
return Command::batch(commands); return Command::batch(commands);
} }
@ -1899,14 +1902,14 @@ impl Application for App {
tab::Command::Action(action) => { tab::Command::Action(action) => {
commands.push(self.update(action.message(Some(entity)))); commands.push(self.update(action.message(Some(entity))));
} }
tab::Command::ChangeLocation(tab_title, tab_path) => { tab::Command::ChangeLocation(tab_title, tab_path, selection_path) => {
self.activate_nav_model_location(&tab_path); self.activate_nav_model_location(&tab_path);
self.tab_model.text_set(entity, tab_title); self.tab_model.text_set(entity, tab_title);
commands.push(Command::batch([ commands.push(Command::batch([
self.update_title(), self.update_title(),
self.update_watcher(), self.update_watcher(),
self.rescan_tab(entity, tab_path), self.rescan_tab(entity, tab_path, selection_path),
])); ]));
} }
tab::Command::EmptyTrash => { tab::Command::EmptyTrash => {
@ -1981,11 +1984,14 @@ impl Application for App {
}; };
return self.open_tab(location); return self.open_tab(location);
} }
Message::TabRescan(entity, location, items) => { Message::TabRescan(entity, location, items, selection_path) => {
match self.tab_model.data_mut::<Tab>(entity) { match self.tab_model.data_mut::<Tab>(entity) {
Some(tab) => { Some(tab) => {
if location == tab.location { if location == tab.location {
tab.set_items(items); tab.set_items(items);
if let Some(selection_path) = selection_path {
tab.select_path(selection_path);
}
} }
} }
_ => (), _ => (),
@ -2115,7 +2121,7 @@ impl Application for App {
return Command::batch([ return Command::batch([
self.update_title(), self.update_title(),
self.update_watcher(), self.update_watcher(),
self.rescan_tab(entity, location), self.rescan_tab(entity, location, None),
]); ]);
} }
} }

View file

@ -754,7 +754,7 @@ impl Application for App {
tab::Command::Action(action) => { tab::Command::Action(action) => {
log::warn!("Action {:?} not supported in dialog", action); log::warn!("Action {:?} not supported in dialog", action);
} }
tab::Command::ChangeLocation(_tab_title, _tab_path) => { tab::Command::ChangeLocation(_tab_title, _tab_path, _selection_path) => {
commands commands
.push(Command::batch([self.update_watcher(), self.rescan_tab()])); .push(Command::batch([self.update_watcher(), self.rescan_tab()]));
} }

View file

@ -573,7 +573,7 @@ impl Location {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Command { pub enum Command {
Action(Action), Action(Action),
ChangeLocation(String, Location), ChangeLocation(String, Location, Option<PathBuf>),
EmptyTrash, EmptyTrash,
FocusButton(widget::Id), FocusButton(widget::Id),
FocusTextInput(widget::Id), FocusTextInput(widget::Id),
@ -1022,11 +1022,16 @@ impl Tab {
*self.cached_selected.borrow_mut() = None; *self.cached_selected.borrow_mut() = None;
if let Some(ref mut items) = self.items_opt { if let Some(ref mut items) = self.items_opt {
for item in items.iter_mut() { for item in items.iter_mut() {
if item.name == name { item.selected = item.name == name;
item.selected = true; }
} else { }
item.selected = false; }
}
pub fn select_path(&mut self, path: PathBuf) {
*self.cached_selected.borrow_mut() = None;
if let Some(ref mut items) = self.items_opt {
for item in items.iter_mut() {
item.selected = item.path_opt.as_ref() == Some(&path);
} }
} }
} }
@ -1862,8 +1867,13 @@ impl Tab {
Location::Search(path, _term) => path.is_dir(), Location::Search(path, _term) => path.is_dir(),
Location::Trash => true, Location::Trash => true,
} { } {
let prev_path = if let Location::Path(path) = &self.location {
Some(path.clone())
} else {
None
};
self.change_location(&location, history_i_opt); self.change_location(&location, history_i_opt);
commands.push(Command::ChangeLocation(self.title(), location)); commands.push(Command::ChangeLocation(self.title(), location, prev_path));
} else { } else {
log::warn!("tried to cd to {:?} which is not a directory", location); log::warn!("tried to cd to {:?} which is not a directory", location);
} }