From 6a8f487a357043c230db7e93065c17b9c9b92dd2 Mon Sep 17 00:00:00 2001 From: Jason Rodney Hansen Date: Sun, 9 Mar 2025 12:58:47 -0600 Subject: [PATCH] Handle broken favorites in sidebar --- i18n/en/cosmic_files.ftl | 10 +++++++ src/app.rs | 56 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 6e72a04..1f71d75 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -121,6 +121,16 @@ read-write = Read and write ### Mode 7 read-write-execute = Read, write, and execute +## Favorite Path Error Dialog +favorite-path-error = Error opening directory +favorite-path-error-description = + Unable to open "{$path}". + It may not exist or you don't have permission to open it. + + Would you like to remove it from the sidebar? +remove = Remove +keep = Keep + # Context Pages ## About diff --git a/src/app.rs b/src/app.rs index e469bce..05917ca 100644 --- a/src/app.rs +++ b/src/app.rs @@ -477,6 +477,10 @@ pub enum DialogPage { SetExecutableAndLaunch { path: PathBuf, }, + FavoritePathError { + path: PathBuf, + entity: Entity, + }, } pub struct FavoriteIndex(usize); @@ -1852,8 +1856,33 @@ impl Application for App { fn on_nav_select(&mut self, entity: Entity) -> Task { self.nav_model.activate(entity); if let Some(location) = self.nav_model.data::(entity) { - let message = Message::TabMessage(None, tab::Message::Location(location.clone())); - return self.update(message); + let should_open = match location { + Location::Path(path) => match path.try_exists() { + Ok(true) => true, + Ok(false) => { + log::warn!("failed to open favorite, path does not exist: {:?}", path); + self.dialog_pages.push_back(DialogPage::FavoritePathError { + path: path.clone(), + entity, + }); + false + } + Err(err) => { + log::warn!("failed to open favorite for path: {:?}, {}", path, err); + self.dialog_pages.push_back(DialogPage::FavoritePathError { + path: path.clone(), + entity, + }); + false + } + }, + _ => true, + }; + + if should_open { + let message = Message::TabMessage(None, tab::Message::Location(location.clone())); + return self.update(message); + } } if let Some(data) = self.nav_model.data::(entity) { @@ -2228,6 +2257,16 @@ impl Application for App { DialogPage::SetExecutableAndLaunch { path } => { self.operation(Operation::SetExecutableAndLaunch { path }); } + DialogPage::FavoritePathError { entity, .. } => { + if let Some(FavoriteIndex(favorite_i)) = + self.nav_model.data::(entity) + { + let mut favorites = self.config.favorites.clone(); + favorites.remove(*favorite_i); + config_set!(favorites, favorites); + return self.update_config(); + } + } } } } @@ -4436,6 +4475,19 @@ impl Application for App { name = name ))) } + DialogPage::FavoritePathError { path, .. } => widget::dialog() + .title(fl!("favorite-path-error")) + .body(fl!( + "favorite-path-error-description", + path = path.as_os_str().to_str() + )) + .icon(widget::icon::from_name("dialog-error").size(64)) + .primary_action( + widget::button::destructive(fl!("remove")).on_press(Message::DialogComplete), + ) + .secondary_action( + widget::button::standard(fl!("keep")).on_press(Message::DialogCancel), + ), }; Some(dialog.into())