mirror of
https://github.com/sxyazi/yazi.git
synced 2024-12-18 22:31:35 +03:00
fix: notification of file changes in linked directories (#121)
This commit is contained in:
parent
230362d6c7
commit
00932a77b7
@ -1,4 +1,4 @@
|
|||||||
use std::{borrow::Cow, ffi::OsStr, fs::Metadata, path::PathBuf};
|
use std::{borrow::Cow, ffi::OsStr, fs::Metadata};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use shared::Url;
|
use shared::Url;
|
||||||
@ -9,7 +9,7 @@ pub struct File {
|
|||||||
pub(super) url: Url,
|
pub(super) url: Url,
|
||||||
pub(super) meta: Metadata,
|
pub(super) meta: Metadata,
|
||||||
pub(super) length: Option<u64>,
|
pub(super) length: Option<u64>,
|
||||||
pub(super) link_to: Option<PathBuf>,
|
pub(super) link_to: Option<Url>,
|
||||||
pub(super) is_link: bool,
|
pub(super) is_link: bool,
|
||||||
pub(super) is_hidden: bool,
|
pub(super) is_hidden: bool,
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ impl File {
|
|||||||
|
|
||||||
if is_link {
|
if is_link {
|
||||||
meta = fs::metadata(&url).await.unwrap_or(meta);
|
meta = fs::metadata(&url).await.unwrap_or(meta);
|
||||||
link_to = fs::read_link(&url).await.ok();
|
link_to = fs::read_link(&url).await.map(Url::from).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
let length = if meta.is_dir() { None } else { Some(meta.len()) };
|
let length = if meta.is_dir() { None } else { Some(meta.len()) };
|
||||||
@ -37,7 +37,7 @@ impl File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl File {
|
impl File {
|
||||||
// --- Path
|
// --- Url
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn url(&self) -> &Url { &self.url }
|
pub fn url(&self) -> &Url { &self.url }
|
||||||
|
|
||||||
@ -80,5 +80,5 @@ impl File {
|
|||||||
|
|
||||||
// --- Link to
|
// --- Link to
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn link_to(&self) -> Option<&PathBuf> { self.link_to.as_ref() }
|
pub fn link_to(&self) -> Option<&Url> { self.link_to.as_ref() }
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ impl Manager {
|
|||||||
.map(|f| {
|
.map(|f| {
|
||||||
(
|
(
|
||||||
f.url_owned(),
|
f.url_owned(),
|
||||||
if f.is_dir() { Some(MIME_DIR.to_owned()) } else { self.mimetype.get(f.url()).cloned() },
|
f.is_dir().then(|| MIME_DIR.to_owned()).or_else(|| self.mimetype.get(f.url()).cloned()),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -99,7 +99,6 @@ impl Watcher {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
guard.sort_unstable_by(|_, a, _, b| b.cmp(a));
|
|
||||||
|
|
||||||
let lock = self.watched.clone();
|
let lock = self.watched.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
@ -113,9 +112,7 @@ impl Watcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut guard = lock.write();
|
lock.write().extend(ext);
|
||||||
guard.extend(ext);
|
|
||||||
guard.sort_unstable_by(|_, a, _, b| b.cmp(a));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +144,7 @@ impl Watcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::file_changed(files.iter().collect()).await;
|
Self::file_changed(&files, watched.clone()).await;
|
||||||
for file in files {
|
for file in files {
|
||||||
emit!(Files(FilesOp::IOErr(file)));
|
emit!(Files(FilesOp::IOErr(file)));
|
||||||
}
|
}
|
||||||
@ -158,17 +155,34 @@ impl Watcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn file_changed(urls: Vec<&Url>) {
|
async fn file_changed(urls: &[Url], watched: Arc<RwLock<IndexMap<Url, Option<Url>>>>) {
|
||||||
if let Ok(mimes) = external::file(&urls).await {
|
let Ok(mut mimes) = external::file(urls).await else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let linked: Vec<_> = watched
|
||||||
|
.read()
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(k, v)| v.as_ref().map(|v| (k, v)))
|
||||||
|
.fold(Vec::new(), |mut aac, (k, v)| {
|
||||||
|
mimes
|
||||||
|
.iter()
|
||||||
|
.filter(|(f, _)| f.parent().map(|p| p == **v) == Some(true))
|
||||||
|
.for_each(|(f, m)| aac.push((k.join(f.file_name().unwrap()), m.clone())));
|
||||||
|
aac
|
||||||
|
});
|
||||||
|
|
||||||
|
mimes.extend(linked);
|
||||||
emit!(Mimetype(mimes));
|
emit!(Mimetype(mimes));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async fn dir_changed(url: &Url, watched: Arc<RwLock<IndexMap<Url, Option<Url>>>>) {
|
async fn dir_changed(url: &Url, watched: Arc<RwLock<IndexMap<Url, Option<Url>>>>) {
|
||||||
let linked: Vec<_> = watched
|
let linked: Vec<_> = watched
|
||||||
.read()
|
.read()
|
||||||
.iter()
|
.iter()
|
||||||
.map_while(|(k, v)| v.as_ref().and_then(|v| url.strip_prefix(v)).map(|v| k.join(v)))
|
.filter_map(|(k, v)| v.as_ref().map(|v| (k, v)))
|
||||||
|
.filter(|(_, v)| *v == url)
|
||||||
|
.map(|(k, _)| k.clone())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let Ok(rx) = Files::from_dir(url).await else {
|
let Ok(rx) = Files::from_dir(url).await else {
|
||||||
|
Loading…
Reference in New Issue
Block a user