Merge pull request #92 from joshuamegnauth54/trash-watcher
Reload trash on changes
This commit is contained in:
commit
5ee260c7a0
3 changed files with 87 additions and 3 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
|
@ -5074,9 +5074,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trash"
|
name = "trash"
|
||||||
version = "3.3.1"
|
version = "4.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c658458d46d9d5a153a3b5cdd88d8579ad50d4fb85d53961e4526c8fc7c55a57"
|
checksum = "6a1a7a9a17d3b004898be42be29a4c18d5a4cf008b5cdf72d69b1945dfcb158a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ paste = "1.0"
|
||||||
serde = { version = "1", features = ["serde_derive"] }
|
serde = { version = "1", features = ["serde_derive"] }
|
||||||
shlex = { version = "1.3" }
|
shlex = { version = "1.3" }
|
||||||
tokio = { version = "1", features = ["sync"] }
|
tokio = { version = "1", features = ["sync"] }
|
||||||
trash = "3.2.0"
|
trash = "4.1.0"
|
||||||
xdg = { version = "2.5.2", optional = true }
|
xdg = { version = "2.5.2", optional = true }
|
||||||
xdg-mime = "0.3"
|
xdg-mime = "0.3"
|
||||||
url = "2.5"
|
url = "2.5"
|
||||||
|
|
|
||||||
84
src/app.rs
84
src/app.rs
|
|
@ -165,6 +165,7 @@ pub enum Message {
|
||||||
PendingComplete(u64),
|
PendingComplete(u64),
|
||||||
PendingError(u64, String),
|
PendingError(u64, String),
|
||||||
PendingProgress(u64, f32),
|
PendingProgress(u64, f32),
|
||||||
|
RescanTrash,
|
||||||
Rename(Option<Entity>),
|
Rename(Option<Entity>),
|
||||||
RestoreFromTrash(Option<Entity>),
|
RestoreFromTrash(Option<Entity>),
|
||||||
SystemThemeModeChange(cosmic_theme::ThemeMode),
|
SystemThemeModeChange(cosmic_theme::ThemeMode),
|
||||||
|
|
@ -1100,6 +1101,22 @@ impl Application for App {
|
||||||
*progress = new_progress;
|
*progress = new_progress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::RescanTrash => {
|
||||||
|
// Update trash icon if empty/full
|
||||||
|
let maybe_entity = self.nav_model.iter().find(|&entity| {
|
||||||
|
self.nav_model
|
||||||
|
.data::<Location>(entity)
|
||||||
|
.map(|loc| *loc == Location::Trash)
|
||||||
|
.unwrap_or_default()
|
||||||
|
});
|
||||||
|
if let Some(entity) = maybe_entity {
|
||||||
|
self.nav_model
|
||||||
|
.icon_set(entity, widget::icon::icon(tab::trash_icon_symbolic(16)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.rescan_trash();
|
||||||
|
}
|
||||||
|
|
||||||
Message::Rename(entity_opt) => {
|
Message::Rename(entity_opt) => {
|
||||||
let entity = entity_opt.unwrap_or_else(|| self.tab_model.active());
|
let entity = entity_opt.unwrap_or_else(|| self.tab_model.active());
|
||||||
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
|
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
|
||||||
|
|
@ -1567,6 +1584,7 @@ impl Application for App {
|
||||||
struct ConfigSubscription;
|
struct ConfigSubscription;
|
||||||
struct ThemeSubscription;
|
struct ThemeSubscription;
|
||||||
struct WatcherSubscription;
|
struct WatcherSubscription;
|
||||||
|
struct TrashWatcherSubscription;
|
||||||
|
|
||||||
let mut subscriptions = vec![
|
let mut subscriptions = vec![
|
||||||
event::listen_with(|event, status| match event {
|
event::listen_with(|event, status| match event {
|
||||||
|
|
@ -1687,6 +1705,72 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
subscription::channel(
|
||||||
|
TypeId::of::<TrashWatcherSubscription>(),
|
||||||
|
25,
|
||||||
|
|mut output| async move {
|
||||||
|
let watcher_res = new_debouncer(
|
||||||
|
time::Duration::from_millis(250),
|
||||||
|
Some(time::Duration::from_millis(250)),
|
||||||
|
move |event_res: notify_debouncer_full::DebounceEventResult| match event_res
|
||||||
|
{
|
||||||
|
Ok(mut events) => {
|
||||||
|
events.retain(|event| {
|
||||||
|
matches!(
|
||||||
|
event.kind,
|
||||||
|
notify::EventKind::Create(_) | notify::EventKind::Remove(_)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
if !events.is_empty() {
|
||||||
|
if let Err(e) = futures::executor::block_on(async {
|
||||||
|
output.send(Message::RescanTrash).await
|
||||||
|
}) {
|
||||||
|
log::warn!("trash needs to be rescanned but sending message failed: {e:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("failed to watch trash bin for changes: {e:?}")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: Trash watching support for Windows, macOS, and other OSes
|
||||||
|
#[cfg(all(
|
||||||
|
unix,
|
||||||
|
not(target_os = "macos"),
|
||||||
|
not(target_os = "ios"),
|
||||||
|
not(target_os = "android")
|
||||||
|
))]
|
||||||
|
match (watcher_res, trash::os_limited::trash_folders()) {
|
||||||
|
(Ok(mut watcher), Ok(trash_bins)) => {
|
||||||
|
for path in trash_bins {
|
||||||
|
if let Err(e) = watcher
|
||||||
|
.watcher()
|
||||||
|
.watch(&path, notify::RecursiveMode::Recursive)
|
||||||
|
{
|
||||||
|
log::warn!(
|
||||||
|
"failed to add trash bin `{}` to watcher: {e:?}",
|
||||||
|
path.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't drop the watcher
|
||||||
|
std::future::pending().await
|
||||||
|
}
|
||||||
|
(Err(e), _) => {
|
||||||
|
log::warn!("failed to create new watcher for trash bin: {e:?}")
|
||||||
|
}
|
||||||
|
(_, Err(e)) => {
|
||||||
|
log::warn!("could not find any valid trash bins to watch: {e:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::future::pending().await
|
||||||
|
},
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (id, (pending_operation, _)) in self.pending_operations.iter() {
|
for (id, (pending_operation, _)) in self.pending_operations.iter() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue