parent
6d9e6c1d20
commit
dfb2ca7443
1 changed files with 94 additions and 0 deletions
94
src/app.rs
94
src/app.rs
|
|
@ -369,6 +369,7 @@ pub enum Message {
|
||||||
PendingPauseAll(bool),
|
PendingPauseAll(bool),
|
||||||
PermanentlyDelete(Option<Entity>),
|
PermanentlyDelete(Option<Entity>),
|
||||||
Preview(Option<Entity>),
|
Preview(Option<Entity>),
|
||||||
|
RescanRecents,
|
||||||
RescanTrash,
|
RescanTrash,
|
||||||
RemoveFromRecents(Option<Entity>),
|
RemoveFromRecents(Option<Entity>),
|
||||||
Rename(Option<Entity>),
|
Rename(Option<Entity>),
|
||||||
|
|
@ -1246,6 +1247,23 @@ impl App {
|
||||||
Task::batch(commands)
|
Task::batch(commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Refresh all tabs that are opened in [`Location::Recents`].
|
||||||
|
fn refresh_recents_tabs(&mut self) -> Task<Message> {
|
||||||
|
let commands: Vec<_> = self
|
||||||
|
.tab_model
|
||||||
|
.iter()
|
||||||
|
.filter_map(|entity| {
|
||||||
|
let tab = self.tab_model.data::<Tab>(entity)?;
|
||||||
|
(tab.location == Location::Recents).then_some(entity)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let commands: Vec<_> = commands
|
||||||
|
.into_iter()
|
||||||
|
.map(|entity| self.update_tab(entity, Location::Recents, None))
|
||||||
|
.collect();
|
||||||
|
Task::batch(commands)
|
||||||
|
}
|
||||||
|
|
||||||
fn rescan_recents(&mut self) -> Task<Message> {
|
fn rescan_recents(&mut self) -> Task<Message> {
|
||||||
let mut needs_reload = Vec::new();
|
let mut needs_reload = Vec::new();
|
||||||
for entity in self.tab_model.iter() {
|
for entity in self.tab_model.iter() {
|
||||||
|
|
@ -3574,6 +3592,9 @@ impl Application for App {
|
||||||
let paths = self.selected_paths(entity_opt);
|
let paths = self.selected_paths(entity_opt);
|
||||||
return self.operation(Operation::RemoveFromRecents { paths });
|
return self.operation(Operation::RemoveFromRecents { paths });
|
||||||
}
|
}
|
||||||
|
Message::RescanRecents => {
|
||||||
|
return self.refresh_recents_tabs();
|
||||||
|
}
|
||||||
Message::RescanTrash => {
|
Message::RescanTrash => {
|
||||||
// Update trash icon if empty/full
|
// Update trash icon if empty/full
|
||||||
let maybe_entity = self.nav_model.iter().find(|&entity| {
|
let maybe_entity = self.nav_model.iter().find(|&entity| {
|
||||||
|
|
@ -5788,6 +5809,12 @@ impl Application for App {
|
||||||
struct WatcherSubscription;
|
struct WatcherSubscription;
|
||||||
struct TrashWatcherSubscription;
|
struct TrashWatcherSubscription;
|
||||||
struct TimeSubscription;
|
struct TimeSubscription;
|
||||||
|
#[cfg(all(
|
||||||
|
not(feature = "desktop-applet"),
|
||||||
|
not(target_os = "ios"),
|
||||||
|
not(target_os = "android")
|
||||||
|
))]
|
||||||
|
struct RecentsWatcherSubscription;
|
||||||
|
|
||||||
let mut subscriptions = vec![
|
let mut subscriptions = vec![
|
||||||
event::listen_with(|event, status, window_id| match event {
|
event::listen_with(|event, status, window_id| match event {
|
||||||
|
|
@ -5989,6 +6016,73 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::future::pending().await
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
#[cfg(all(
|
||||||
|
not(feature = "desktop-applet"),
|
||||||
|
not(target_os = "ios"),
|
||||||
|
not(target_os = "android")
|
||||||
|
))]
|
||||||
|
Subscription::run_with_id(
|
||||||
|
TypeId::of::<RecentsWatcherSubscription>(),
|
||||||
|
stream::channel(1, |mut output| async move {
|
||||||
|
let Some(recents_path) = recently_used_xbel::dir() else {
|
||||||
|
log::warn!(
|
||||||
|
"failed to watch recents changes: .recently_used.xbel does not exist"
|
||||||
|
);
|
||||||
|
return std::future::pending().await;
|
||||||
|
};
|
||||||
|
|
||||||
|
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(events) => {
|
||||||
|
// Programs differ in how they modify the recents file so the
|
||||||
|
// rescan is triggered on any event but access.
|
||||||
|
if events.iter().any(|event| {
|
||||||
|
let kind = event.kind;
|
||||||
|
kind.is_create()
|
||||||
|
|| kind.is_modify()
|
||||||
|
|| kind.is_remove()
|
||||||
|
|| kind.is_other()
|
||||||
|
}) {
|
||||||
|
if let Err(e) = futures::executor::block_on(async {
|
||||||
|
output.send(Message::RescanRecents).await
|
||||||
|
}) {
|
||||||
|
log::warn!("open recents tabs need to be updated but sending message failed: {e:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("failed to watch recents file for changes: {e:?}")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
match watcher_res {
|
||||||
|
Ok(mut watcher) => {
|
||||||
|
if let Err(e) = watcher
|
||||||
|
.watcher()
|
||||||
|
.watch(&recents_path, notify::RecursiveMode::NonRecursive)
|
||||||
|
{
|
||||||
|
log::warn!(
|
||||||
|
"failed to add recents file `{}` to watcher: {}",
|
||||||
|
recents_path.display(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't drop the watcher.
|
||||||
|
std::future::pending::<()>().await;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("failed to create new watcher for recents file: {e:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::future::pending().await
|
std::future::pending().await
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue