feat: retry opening network locations after mounting
This commit is contained in:
parent
7711b4bcc0
commit
c7e9828d7b
9 changed files with 333 additions and 56 deletions
216
src/app.rs
216
src/app.rs
|
|
@ -334,6 +334,12 @@ pub enum Message {
|
|||
NavMenuAction(NavMenuAction),
|
||||
NetworkAuth(MounterKey, String, MounterAuth, mpsc::Sender<MounterAuth>),
|
||||
NetworkDriveInput(String),
|
||||
NetworkDriveOpenEntityAfterMount {
|
||||
entity: Entity,
|
||||
},
|
||||
NetworkDriveOpenTabAfterMount {
|
||||
location: Location,
|
||||
},
|
||||
NetworkDriveSubmit,
|
||||
NetworkResult(MounterKey, String, Result<bool, String>),
|
||||
NewItem(Option<Entity>, bool),
|
||||
|
|
@ -885,6 +891,58 @@ impl App {
|
|||
activate: bool,
|
||||
selection_paths: Option<Vec<PathBuf>>,
|
||||
) -> (Entity, Task<Message>) {
|
||||
#[cfg(feature = "gvfs")]
|
||||
if let Location::Network(ref uri, ref name, Some(ref path)) = location {
|
||||
dbg!(path, self.mounter_items.len());
|
||||
let mut found = false;
|
||||
|
||||
if let Some(key) = self
|
||||
.mounter_items
|
||||
.iter()
|
||||
.find_map(|(k, items)| {
|
||||
items.iter().find_map(|item| {
|
||||
found |= item.path().is_some_and(|p| path.starts_with(p))
|
||||
|| item.name() == *name
|
||||
|| item.uri() == *uri;
|
||||
dbg!(
|
||||
item.is_mounted(),
|
||||
item.path(),
|
||||
path,
|
||||
name,
|
||||
item.name(),
|
||||
item.uri(),
|
||||
uri
|
||||
);
|
||||
(!item.is_mounted() && found).then(|| *k)
|
||||
})
|
||||
})
|
||||
.or(if found {
|
||||
dbg!("found so skip...");
|
||||
None
|
||||
} else {
|
||||
dbg!("not found...");
|
||||
// TODO do we need to choose the correct mounter?
|
||||
self.mounter_items.iter().map(|(k, _)| *k).next()
|
||||
})
|
||||
{
|
||||
if let Some(mounter) = MOUNTERS.get(&key) {
|
||||
let location = location.clone();
|
||||
dbg!(&location);
|
||||
return (
|
||||
Entity::null(),
|
||||
mounter.network_drive(uri.clone()).map(move |_| {
|
||||
cosmic::Action::App(Message::NetworkDriveOpenTabAfterMount {
|
||||
location: location.clone(),
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
dbg!("huh...");
|
||||
}
|
||||
}
|
||||
|
||||
dbg!(&location);
|
||||
let mut tab = Tab::new(
|
||||
location.clone(),
|
||||
self.config.tab,
|
||||
|
|
@ -1061,6 +1119,7 @@ impl App {
|
|||
location: Location,
|
||||
selection_paths: Option<Vec<PathBuf>>,
|
||||
) -> Task<Message> {
|
||||
dbg!("rescan", &location);
|
||||
log::info!("rescan_tab {entity:?} {location:?} {selection_paths:?}");
|
||||
let icon_sizes = self.config.tab.icon_sizes;
|
||||
let mounter_items = self.mounter_items.clone();
|
||||
|
|
@ -1303,7 +1362,12 @@ impl App {
|
|||
})
|
||||
.size(16),
|
||||
)
|
||||
.data(Location::Path(path.clone()))
|
||||
.data(match favorite {
|
||||
Favorite::Network { uri, name, path } => {
|
||||
Location::Network(uri.clone(), name.clone(), Some(path.to_owned()))
|
||||
}
|
||||
_ => Location::Path(path.clone()),
|
||||
})
|
||||
.data(FavoriteIndex(favorite_i))
|
||||
});
|
||||
}
|
||||
|
|
@ -1327,6 +1391,7 @@ impl App {
|
|||
.data(Location::Network(
|
||||
"network:///".to_string(),
|
||||
fl!("networks"),
|
||||
None,
|
||||
))
|
||||
.divider_above()
|
||||
});
|
||||
|
|
@ -1346,7 +1411,13 @@ impl App {
|
|||
nav_model = nav_model.insert(|mut b| {
|
||||
b = b.text(item.name()).data(MounterData(key, item.clone()));
|
||||
if let Some(path) = item.path() {
|
||||
b = b.data(Location::Path(path.clone()));
|
||||
b = b.data(Location::Network(
|
||||
item.uri().to_string(),
|
||||
item.name(),
|
||||
Some(path),
|
||||
));
|
||||
} else {
|
||||
b = b.data(Location::Network(item.uri().to_string(), item.name(), None));
|
||||
}
|
||||
if let Some(icon) = item.icon(true) {
|
||||
b = b.icon(widget::icon::icon(icon).size(16));
|
||||
|
|
@ -2155,35 +2226,85 @@ impl Application for App {
|
|||
fn on_nav_select(&mut self, entity: Entity) -> Task<Self::Message> {
|
||||
self.nav_model.activate(entity);
|
||||
if let Some(location) = self.nav_model.data::<Location>(entity) {
|
||||
dbg!(&location);
|
||||
|
||||
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
|
||||
#[cfg(feature = "gvfs")]
|
||||
Location::Network(uri, name, Some(path))
|
||||
if !path.try_exists().unwrap_or_default() =>
|
||||
{
|
||||
dbg!(&location, path, self.mounter_items.len(), uri, path);
|
||||
let mut found = false;
|
||||
|
||||
if let Some(key) = self
|
||||
.mounter_items
|
||||
.iter()
|
||||
.find_map(|(k, items)| {
|
||||
items.iter().find_map(|item| {
|
||||
found |= item.path().is_some_and(|p| path.starts_with(&p))
|
||||
|| item.name() == *name
|
||||
|| item.uri() == *uri;
|
||||
dbg!(item.is_mounted(), item.path());
|
||||
(!item.is_mounted() && found).then(|| *k)
|
||||
})
|
||||
})
|
||||
.or(if found {
|
||||
None
|
||||
} else {
|
||||
// TODO do we need to choose the correct mounter?
|
||||
self.mounter_items.iter().map(|(k, _)| *k).next()
|
||||
})
|
||||
{
|
||||
if let Some(mounter) = MOUNTERS.get(&key) {
|
||||
dbg!(&location);
|
||||
// TODO can we detect an error and handle failure?
|
||||
let location = location.clone();
|
||||
return mounter.network_drive(uri.clone()).map(move |_| {
|
||||
cosmic::Action::App(Message::NetworkDriveOpenEntityAfterMount {
|
||||
entity,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("failed to open favorite for path: {:?}, {}", path, err);
|
||||
self.dialog_pages.push_back(DialogPage::FavoritePathError {
|
||||
path: path.clone(),
|
||||
entity,
|
||||
});
|
||||
false
|
||||
|
||||
log::warn!("failed to open favorite, path does not exist: {:?}", path);
|
||||
self.dialog_pages.push_back(DialogPage::FavoritePathError {
|
||||
path: path.clone(),
|
||||
entity,
|
||||
});
|
||||
false
|
||||
}
|
||||
Location::Path(path) | Location::Network(_, _, Some(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,
|
||||
};
|
||||
|
||||
dbg!(should_open);
|
||||
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::<MounterData>(entity) {
|
||||
if let Some(mounter) = MOUNTERS.get(&data.0) {
|
||||
return mounter
|
||||
|
|
@ -2296,10 +2417,45 @@ impl Application for App {
|
|||
match message {
|
||||
Message::AddToSidebar(entity_opt) => {
|
||||
let mut favorites = self.config.favorites.clone();
|
||||
// check if the selected entity is in the current tab
|
||||
// else just use the selected entity and check its location
|
||||
let entity = entity_opt.unwrap_or_else(|| self.tab_model.active());
|
||||
|
||||
for path in self.selected_paths(entity_opt) {
|
||||
let favorite = Favorite::from_path(path);
|
||||
dbg!(&path);
|
||||
let is_network = self.tab_model.data::<Tab>(entity).and_then(|tab| {
|
||||
let in_current_tab =
|
||||
tab.location.path_opt().zip(path.parent()).is_some_and(
|
||||
|(t_path, parent)| {
|
||||
dbg!(&parent, &t_path);
|
||||
parent == t_path
|
||||
},
|
||||
);
|
||||
let tab = if in_current_tab {
|
||||
self.tab_model
|
||||
.data::<Tab>(self.tab_model.active())
|
||||
.unwrap_or(tab)
|
||||
} else {
|
||||
tab
|
||||
};
|
||||
dbg!(in_current_tab, &tab.location);
|
||||
let name = Location::Path(path.clone()).title();
|
||||
if let Location::Network(uri, _, _) = tab.location.clone() {
|
||||
Some((uri, name, path.clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
dbg!(&is_network);
|
||||
let name = Location::Path(path.clone()).title();
|
||||
let favorite = if let Some((uri, _, _)) = is_network.clone() {
|
||||
Favorite::Network { uri, name, path }
|
||||
} else {
|
||||
Favorite::from_path(path)
|
||||
};
|
||||
if !favorites.iter().any(|f| f == &favorite) {
|
||||
favorites.push(favorite);
|
||||
dbg!(&favorites);
|
||||
}
|
||||
}
|
||||
config_set!(favorites, favorites);
|
||||
|
|
@ -2991,6 +3147,7 @@ impl Application for App {
|
|||
Message::OpenInNewTab(entity_opt) => {
|
||||
return Task::batch(self.selected_paths(entity_opt).into_iter().filter_map(
|
||||
|path| {
|
||||
dbg!(&path);
|
||||
if path.is_dir() {
|
||||
Some(self.open_tab(Location::Path(path), false, None))
|
||||
} else {
|
||||
|
|
@ -3510,6 +3667,7 @@ impl Application for App {
|
|||
config.show_hidden = !config.show_hidden;
|
||||
return self.update(Message::TabConfig(config));
|
||||
}
|
||||
|
||||
Message::TabMessage(entity_opt, tab_message) => {
|
||||
let entity = entity_opt.unwrap_or_else(|| self.tab_model.active());
|
||||
|
||||
|
|
@ -3528,6 +3686,7 @@ impl Application for App {
|
|||
for tab_command in tab_commands {
|
||||
match tab_command {
|
||||
tab::Command::Action(action) => {
|
||||
dbg!(&action);
|
||||
commands.push(self.update(action.message(Some(entity))));
|
||||
}
|
||||
tab::Command::AddNetworkDrive => {
|
||||
|
|
@ -3535,6 +3694,7 @@ impl Application for App {
|
|||
self.set_show_context(true);
|
||||
}
|
||||
tab::Command::AddToSidebar(path) => {
|
||||
dbg!("add to sidebar");
|
||||
let mut favorites = self.config.favorites.clone();
|
||||
let favorite = Favorite::from_path(path);
|
||||
if !favorites.iter().any(|f| f == &favorite) {
|
||||
|
|
@ -3580,6 +3740,7 @@ impl Application for App {
|
|||
}
|
||||
tab::Command::OpenFile(paths) => self.open_file(&paths),
|
||||
tab::Command::OpenInNewTab(path) => {
|
||||
dbg!(&path);
|
||||
commands.push(self.open_tab(Location::Path(path.clone()), false, None));
|
||||
}
|
||||
tab::Command::OpenInNewWindow(path) => match env::current_exe() {
|
||||
|
|
@ -4037,14 +4198,15 @@ impl Application for App {
|
|||
}
|
||||
NavMenuAction::OpenInNewTab(entity) => {
|
||||
match self.nav_model.data::<Location>(entity) {
|
||||
Some(Location::Network(ref uri, ref display_name)) => {
|
||||
Some(Location::Network(ref uri, ref display_name, path)) => {
|
||||
return self.open_tab(
|
||||
Location::Network(uri.clone(), display_name.clone()),
|
||||
Location::Network(uri.clone(), display_name.clone(), path.clone()),
|
||||
false,
|
||||
None,
|
||||
);
|
||||
}
|
||||
Some(Location::Path(ref path)) => {
|
||||
dbg!(path);
|
||||
return self.open_tab(Location::Path(path.clone()), false, None);
|
||||
}
|
||||
Some(Location::Recents) => {
|
||||
|
|
@ -4304,6 +4466,13 @@ impl Application for App {
|
|||
Message::DragId(id) => {
|
||||
return window::drag(id);
|
||||
}
|
||||
Message::NetworkDriveOpenEntityAfterMount { entity } => {
|
||||
return self.on_nav_select(entity);
|
||||
}
|
||||
Message::NetworkDriveOpenTabAfterMount { location } => {
|
||||
dbg!("location");
|
||||
return self.open_tab(location, false, None);
|
||||
}
|
||||
}
|
||||
|
||||
Task::none()
|
||||
|
|
@ -5880,6 +6049,7 @@ pub(crate) mod test_utils {
|
|||
nested: usize,
|
||||
name_len: usize,
|
||||
) -> io::Result<(TempDir, Tab)> {
|
||||
dbg!("new tab...");
|
||||
let fs = simple_fs(files, hidden, dirs, nested, name_len)?;
|
||||
let path = fs.path();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue