Merge pull request #405 from jasonrhansen/back-remember-position

Select previous directory when navigating back
This commit is contained in:
Jeremy Soller 2024-08-19 07:48:40 -06:00 • committed by GitHub
commit fd2de87067
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 20 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]>),
@ -395,7 +395,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),
]) ])
} }
@ -405,13 +405,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()
@ -434,7 +441,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)
} }
@ -461,7 +468,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()
@ -1392,7 +1399,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() {
@ -1490,7 +1497,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);
} }
@ -1897,14 +1904,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 => {
@ -1979,11 +1986,14 @@ impl Application for App {
}; };
return self.open_tab(location, true); return self.open_tab(location, true);
} }
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);
}
} }
} }
_ => (), _ => (),
@ -2113,7 +2123,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),
@ -1024,11 +1024,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);
} }
} }
} }
@ -1867,8 +1872,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);
} }