diff --git a/src/shared.rs b/src/shared.rs index 865c624ca3f59605e636bd653c18b49252db0f5b..382338ecb3ee93482712091a01be42fec27bd634 100644 --- a/src/shared.rs +++ b/src/shared.rs @@ -99,6 +99,7 @@ impl BackupConfig { let icon = drive .as_ref() .and_then(gio::Drive::get_icon) + .or_else(|| mount.as_ref().and_then(gio::Mount::get_icon)) .as_ref() .and_then(gio::IconExt::to_string) .as_ref() diff --git a/src/ui/new_backup.rs b/src/ui/new_backup.rs index d462eb5ca32bb781f3dc50311e30258ead7fd4f7..047df3fe6194fd3d83262c72ce6ebd614b94748d 100644 --- a/src/ui/new_backup.rs +++ b/src/ui/new_backup.rs @@ -15,7 +15,7 @@ use ui::main_pending; pub fn new_backup() { let ui_new = Rc::new(ui::builder::NewBackup::new()); - refresh(&ui_new); + load_available_mounts_and_repos(ui_new.clone()); ui_new .password_quality() .add_offset_value(>k::LEVEL_BAR_OFFSET_LOW, 7.0); @@ -64,16 +64,65 @@ pub fn new_backup() { // refresh ui on mount events let monitor = gio::VolumeMonitor::get(); - let ui = ui_new.clone(); - monitor.connect_mount_added(move |_, _| refresh(&ui)); - let ui = ui_new.clone(); - monitor.connect_mount_changed(move |_, _| refresh(&ui)); - let ui = ui_new.clone(); - monitor.connect_mount_removed(move |_, _| refresh(&ui)); + monitor.connect_mount_added(enclose!((ui_new) move |_, mount| { + debug!("Mount added"); + load_mount(ui_new.clone(), mount.clone()); + })); + + monitor.connect_mount_removed(enclose!((ui_new) move |_, mount| { + debug!("Mount removed"); + remove_mount(&ui_new.add_repo_list(), mount.get_root().unwrap().get_uri()); + remove_mount( + &ui_new.init_repo_list(), + mount.get_root().unwrap().get_uri(), + ); + })); ui_new.new_backup().show_all(); } +fn load_available_mounts_and_repos(ui: Rc) { + debug!("Refreshing list of existing repos"); + let monitor = gio::VolumeMonitor::get(); + + ui::utils::clear(&ui.add_repo_list()); + ui::utils::clear(&ui.init_repo_list()); + + for mount in monitor.get_mounts() { + load_mount(ui.clone(), mount); + } + + debug!("List of existing repos refreshed"); +} + +fn load_mount(ui: Rc, mount: gio::Mount) { + if let Some(mount_point) = mount.get_root().unwrap().get_path() { + add_mount(&ui.init_repo_list(), &mount, Some(&mount_point)); + ui::utils::async_react( + "check_mount_for_repos", + move || { + let mut paths = Vec::new(); + if let Ok(dirs) = mount_point.read_dir() { + for dir in dirs { + if let Ok(path) = dir { + if is_backup_repo(&path.path()) { + paths.push(path.path()); + } + } + } + } + paths + }, + enclose!((ui) move |paths: Vec| { + for path in paths { + trace!("Adding repo to ui '{:?}'", path); + add_mount(&ui.add_repo_list(), &mount, Some(&path)); + } + }), + ); + } +} + fn add_repo_list_activated(row: >k::ListBoxRow, ui: Rc) { let name = row.get_widget_name(); if name == "-add-local" { @@ -232,41 +281,23 @@ fn init_repo_password_changed(ui: &builder::NewBackup) { ui.password_quality().set_value(score.into()); } -fn refresh(ui: &ui::builder::NewBackup) { - debug!("Refreshing list of existing repos"); - let monitor = gio::VolumeMonitor::get(); - - ui::utils::clear(&ui.add_repo_list()); - ui::utils::clear(&ui.init_repo_list()); - - for mount in monitor.get_mounts() { - if let Some(mount_point) = mount.get_root().as_ref().and_then(gio::File::get_path) { - add_mount(&ui.init_repo_list(), &mount, Some(&mount_point)); - if let Ok(dirs) = mount_point.read_dir() { - for dir in dirs { - if let Ok(path) = dir { - if is_backup_repo(&path.path()) { - add_mount(&ui.add_repo_list(), &mount, Some(&path.path())); - } - } - } - } +fn remove_mount(list: >k::ListBox, root: glib::GString) { + for list_row in list.get_children() { + if list_row.get_widget_name() == root { + list.remove(&list_row); } - - ui.add_repo_list().show_all(); - ui.init_repo_list().show_all(); } - - debug!("List of existing repos refreshed"); } fn add_mount(list: >k::ListBox, mount: &gio::Mount, repo: Option<&std::path::Path>) { let drive = mount.get_drive(); let name = repo.map(std::path::Path::to_string_lossy); - let (_, horizontal_box) = + let (row, horizontal_box) = ui::utils::add_list_box_row(list, name.as_ref().map(std::borrow::Borrow::borrow), 0); + row.set_widget_name(&mount.get_root().unwrap().get_uri()); + if let Some(icon) = drive.as_ref().and_then(gio::Drive::get_icon) { let img = gtk::Image::from_gicon(&icon, gtk::IconSize::Dialog); horizontal_box.add(&img); @@ -303,6 +334,8 @@ fn add_mount(list: >k::ListBox, mount: &gio::Mount, repo: Option<&std::path::P let (vertical_box, _, _) = ui::utils::list_vertical_box(Some(label1.as_str()), Some(label2.as_str())); horizontal_box.add(&vertical_box); + + list.show_all(); } fn add_repo_config_local(repo: &std::path::Path, ui: Rc) { diff --git a/src/ui/prelude.rs b/src/ui/prelude.rs index f6393812619aec1c4a3dafbe1f2a9a70e51abac2..0103113d3aecc8574c05ae4e8ae437a3a345d7c0 100644 --- a/src/ui/prelude.rs +++ b/src/ui/prelude.rs @@ -26,7 +26,7 @@ impl Humanize for chrono::Duration { } pub trait ArcSwapAdditions { - fn update ()>(&self, updater: F); + fn update(&self, updater: F); fn get(&self) -> T; } @@ -34,7 +34,7 @@ impl ArcSwapAdditions for ArcSwap where T: Clone, { - fn update ()>(&self, updater: F) { + fn update(&self, updater: F) { self.rcu(|current| { let mut new = T::clone(current); updater(&mut new); @@ -51,7 +51,7 @@ impl ArcSwapAdditions for once_cell::sync::Lazy> where T: Clone, { - fn update ()>(&self, updater: F) { + fn update(&self, updater: F) { (**self).rcu(|current| { let mut new = T::clone(current); updater(&mut new);