mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-24 00:01:03 +00:00
feat: check and refresh the file list when the terminal gains focus (#3561)
This commit is contained in:
parent
41e5717930
commit
0c8c973e6c
18 changed files with 95 additions and 69 deletions
|
|
@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
|
||||
- Tree view for the preset archive previewer ([#3525])
|
||||
- Support compressed tarballs (`.tar.gz`, `.tar.bz2`, etc.) in the preset archive previewer ([#3518])
|
||||
- Check and refresh the file list when the terminal gains focus ([#3561])
|
||||
- New `Path.os()` API creates an OS-native `Path` ([#3541])
|
||||
|
||||
### Fixed
|
||||
|
|
@ -1601,3 +1602,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
[#3532]: https://github.com/sxyazi/yazi/pull/3532
|
||||
[#3540]: https://github.com/sxyazi/yazi/pull/3540
|
||||
[#3541]: https://github.com/sxyazi/yazi/pull/3541
|
||||
[#3561]: https://github.com/sxyazi/yazi/pull/3561
|
||||
|
|
|
|||
|
|
@ -21,11 +21,12 @@ impl Actions {
|
|||
writeln!(s, " Version: {}", Self::process_output("ya", "--version"))?;
|
||||
|
||||
writeln!(s, "\nConfig")?;
|
||||
writeln!(s, " Yazi : {}", Self::config_state("yazi"))?;
|
||||
writeln!(s, " Keymap : {}", Self::config_state("keymap"))?;
|
||||
writeln!(s, " Theme : {}", Self::config_state("theme"))?;
|
||||
writeln!(s, " VFS : {}", Self::config_state("vfs"))?;
|
||||
writeln!(s, " Package : {}", Self::config_state("package"))?;
|
||||
writeln!(s, " Init : {}", Self::config_state("init.lua"))?;
|
||||
writeln!(s, " Yazi : {}", Self::config_state("yazi.toml"))?;
|
||||
writeln!(s, " Keymap : {}", Self::config_state("keymap.toml"))?;
|
||||
writeln!(s, " Theme : {}", Self::config_state("theme.toml"))?;
|
||||
writeln!(s, " VFS : {}", Self::config_state("vfs.toml"))?;
|
||||
writeln!(s, " Package : {}", Self::config_state("package.toml"))?;
|
||||
writeln!(s, " Dark/light flavor: {:?} / {:?}", THEME.flavor.dark, THEME.flavor.light)?;
|
||||
|
||||
writeln!(s, "\nEmulator")?;
|
||||
|
|
@ -125,7 +126,7 @@ impl Actions {
|
|||
}
|
||||
|
||||
fn config_state(name: &str) -> String {
|
||||
let p = Xdg::config_dir().join(format!("{name}.toml"));
|
||||
let p = Xdg::config_dir().join(name);
|
||||
match std::fs::read_to_string(&p) {
|
||||
Ok(s) if s.is_empty() => format!("{} (empty)", p.display()),
|
||||
Ok(s) if s.trim().is_empty() => format!("{} (whitespaces)", p.display()),
|
||||
|
|
|
|||
15
yazi-fm/src/app/commands/focus.rs
Normal file
15
yazi-fm/src/app/commands/focus.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use anyhow::Result;
|
||||
use yazi_actor::Ctx;
|
||||
use yazi_macro::act;
|
||||
use yazi_parser::VoidOpt;
|
||||
use yazi_shared::data::Data;
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
impl App {
|
||||
pub fn focus(&mut self, _: VoidOpt) -> Result<Data> {
|
||||
let cx = &mut Ctx::active(&mut self.core);
|
||||
|
||||
act!(mgr:refresh, cx)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ yazi_macro::mod_flat!(
|
|||
accept_payload
|
||||
bootstrap
|
||||
deprecate
|
||||
focus
|
||||
mouse
|
||||
notify
|
||||
plugin
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ impl<'a> Dispatcher<'a> {
|
|||
Event::Key(key) => self.dispatch_key(key),
|
||||
Event::Mouse(mouse) => act!(mouse, self.app, mouse),
|
||||
Event::Resize => act!(resize, self.app),
|
||||
Event::Focus => act!(focus, self.app),
|
||||
Event::Paste(str) => self.dispatch_paste(str),
|
||||
Event::Quit(opt) => act!(quit, self.app, opt),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -64,8 +64,9 @@ impl Signals {
|
|||
Event::Mouse(mouse).emit();
|
||||
}
|
||||
}
|
||||
CrosstermEvent::Paste(str) => Event::Paste(str).emit(),
|
||||
CrosstermEvent::Resize(..) => Event::Resize.emit(),
|
||||
CrosstermEvent::FocusGained => Event::Focus.emit(),
|
||||
CrosstermEvent::Paste(str) => Event::Paste(str).emit(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{io, ops::{Deref, DerefMut}, sync::atomic::{AtomicBool, Ordering}};
|
||||
|
||||
use anyhow::Result;
|
||||
use crossterm::{event::{DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, style::Print, terminal::{EnterAlternateScreen, LeaveAlternateScreen, SetTitle, disable_raw_mode, enable_raw_mode}};
|
||||
use crossterm::{event::{DisableBracketedPaste, DisableFocusChange, DisableMouseCapture, EnableBracketedPaste, EnableFocusChange, EnableMouseCapture, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, style::Print, terminal::{EnterAlternateScreen, LeaveAlternateScreen, SetTitle, disable_raw_mode, enable_raw_mode}};
|
||||
use ratatui::{CompletedFrame, Frame, Terminal, backend::CrosstermBackend, buffer::Buffer, layout::Rect};
|
||||
use yazi_adapter::{Emulator, Mux, TMUX};
|
||||
use yazi_config::{THEME, YAZI};
|
||||
|
|
@ -40,6 +40,7 @@ impl Term {
|
|||
yazi_term::If(TMUX.get(), EnterAlternateScreen),
|
||||
yazi_term::SetBackground(true, THEME.app.bg_color()), // Set app background
|
||||
EnableBracketedPaste,
|
||||
EnableFocusChange,
|
||||
yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), EnableMouseCapture),
|
||||
)?;
|
||||
|
||||
|
|
@ -81,6 +82,7 @@ impl Term {
|
|||
TTY.writer(),
|
||||
yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), DisableMouseCapture),
|
||||
yazi_term::RestoreCursor,
|
||||
DisableFocusChange,
|
||||
DisableBracketedPaste,
|
||||
LeaveAlternateScreen,
|
||||
)?;
|
||||
|
|
@ -103,6 +105,7 @@ impl Term {
|
|||
yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), DisableMouseCapture),
|
||||
yazi_term::SetBackground(false, THEME.app.bg_color()),
|
||||
yazi_term::RestoreCursor,
|
||||
DisableFocusChange,
|
||||
DisableBracketedPaste,
|
||||
LeaveAlternateScreen,
|
||||
crossterm::cursor::Show
|
||||
|
|
|
|||
|
|
@ -455,6 +455,7 @@ pub(crate) enum FileOutUpload {
|
|||
Deform(String),
|
||||
Succ,
|
||||
Fail(String),
|
||||
Clean,
|
||||
}
|
||||
|
||||
impl From<anyhow::Error> for FileOutUpload {
|
||||
|
|
@ -481,6 +482,9 @@ impl FileOutUpload {
|
|||
prog.collected = Some(false);
|
||||
task.log(reason);
|
||||
}
|
||||
Self::Clean => {
|
||||
prog.cleaned = Some(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ pub struct FileProgUpload {
|
|||
pub total_bytes: u64,
|
||||
pub processed_bytes: u64,
|
||||
pub collected: Option<bool>,
|
||||
pub cleaned: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<FileProgUpload> for TaskSummary {
|
||||
|
|
@ -340,14 +341,16 @@ impl FileProgUpload {
|
|||
}
|
||||
|
||||
pub fn running(self) -> bool {
|
||||
self.collected.is_none() || self.success_files + self.failed_files != self.total_files
|
||||
self.collected.is_none()
|
||||
|| self.success_files + self.failed_files != self.total_files
|
||||
|| (self.cleaned.is_none() && self.cooked())
|
||||
}
|
||||
|
||||
pub fn success(self) -> bool { self.cooked() }
|
||||
pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() }
|
||||
|
||||
pub fn failed(self) -> bool { self.collected == Some(false) }
|
||||
pub fn failed(self) -> bool { self.cleaned == Some(false) || self.collected == Some(false) }
|
||||
|
||||
pub fn cleaned(self) -> Option<bool> { None }
|
||||
pub fn cleaned(self) -> Option<bool> { self.cleaned }
|
||||
|
||||
pub fn percent(self) -> Option<f32> {
|
||||
Some(if self.success() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use yazi_fs::ok_or_not_found;
|
|||
use yazi_proxy::TasksProxy;
|
||||
use yazi_vfs::provider;
|
||||
|
||||
use crate::{Ongoing, TaskOp, TaskOps, file::{FileOutCopy, FileOutCut, FileOutDelete, FileOutDownload, FileOutTrash}, hook::{HookInOutCopy, HookInOutCut, HookInOutDelete, HookInOutDownload, HookInOutTrash}};
|
||||
use crate::{Ongoing, TaskOp, TaskOps, file::{FileOutCopy, FileOutCut, FileOutDelete, FileOutDownload, FileOutTrash, FileOutUpload}, hook::{HookInDelete, HookInDownload, HookInOutCopy, HookInOutCut, HookInTrash, HookInUpload}};
|
||||
|
||||
pub(crate) struct Hook {
|
||||
ops: TaskOps,
|
||||
|
|
@ -41,7 +41,7 @@ impl Hook {
|
|||
self.ops.out(task.id, FileOutCopy::Clean);
|
||||
}
|
||||
|
||||
pub(crate) async fn delete(&self, task: HookInOutDelete) {
|
||||
pub(crate) async fn delete(&self, task: HookInDelete) {
|
||||
if !self.ongoing.lock().intact(task.id) {
|
||||
return self.ops.out(task.id, FileOutDelete::Clean(Ok(())));
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ impl Hook {
|
|||
self.ops.out(task.id, FileOutDelete::Clean(result));
|
||||
}
|
||||
|
||||
pub(crate) async fn trash(&self, task: HookInOutTrash) {
|
||||
pub(crate) async fn trash(&self, task: HookInTrash) {
|
||||
let intact = self.ongoing.lock().intact(task.id);
|
||||
if intact {
|
||||
TasksProxy::update_succeed([&task.target]);
|
||||
|
|
@ -62,7 +62,15 @@ impl Hook {
|
|||
self.ops.out(task.id, FileOutTrash::Clean);
|
||||
}
|
||||
|
||||
pub(crate) async fn download(&self, task: HookInOutDownload) {
|
||||
pub(crate) async fn download(&self, task: HookInDownload) {
|
||||
self.ops.out(task.id, FileOutDownload::Clean);
|
||||
}
|
||||
|
||||
pub(crate) async fn upload(&self, task: HookInUpload) {
|
||||
let intact = self.ongoing.lock().intact(task.id);
|
||||
if intact {
|
||||
TasksProxy::update_succeed([task.target]);
|
||||
}
|
||||
self.ops.out(task.id, FileOutUpload::Clean);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,44 +48,27 @@ impl HookInOutCut {
|
|||
|
||||
// --- Delete
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct HookInOutDelete {
|
||||
pub(crate) struct HookInDelete {
|
||||
pub(crate) id: Id,
|
||||
pub(crate) target: UrlBuf,
|
||||
}
|
||||
|
||||
impl HookInOutDelete {
|
||||
pub(crate) fn reduce(self, task: &mut Task) {
|
||||
if let TaskProg::FileDelete(_) = &task.prog {
|
||||
task.hook = Some(self.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Trash
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct HookInOutTrash {
|
||||
pub(crate) struct HookInTrash {
|
||||
pub(crate) id: Id,
|
||||
pub(crate) target: UrlBuf,
|
||||
}
|
||||
|
||||
impl HookInOutTrash {
|
||||
pub(crate) fn reduce(self, task: &mut Task) {
|
||||
if let TaskProg::FileTrash(_) = &task.prog {
|
||||
task.hook = Some(self.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Download
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct HookInOutDownload {
|
||||
pub(crate) struct HookInDownload {
|
||||
pub(crate) id: Id,
|
||||
}
|
||||
|
||||
impl HookInOutDownload {
|
||||
pub(crate) fn reduce(self, task: &mut Task) {
|
||||
if let TaskProg::FileDownload(_) = &task.prog {
|
||||
task.hook = Some(self.into());
|
||||
}
|
||||
}
|
||||
// --- Upload
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct HookInUpload {
|
||||
pub(crate) id: Id,
|
||||
pub(crate) target: UrlBuf,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use yazi_shared::Id;
|
||||
|
||||
use crate::{file::{FileInCopy, FileInCut, FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInTrash, FileInUpload}, hook::{HookInOutCopy, HookInOutCut, HookInOutDelete, HookInOutDownload, HookInOutTrash}, impl_from_in, plugin::PluginInEntry, prework::{PreworkInFetch, PreworkInLoad, PreworkInSize}, process::{ProcessInBg, ProcessInBlock, ProcessInOrphan}};
|
||||
use crate::{file::{FileInCopy, FileInCut, FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInTrash, FileInUpload}, hook::{HookInDelete, HookInDownload, HookInOutCopy, HookInOutCut, HookInTrash, HookInUpload}, impl_from_in, plugin::PluginInEntry, prework::{PreworkInFetch, PreworkInLoad, PreworkInSize}, process::{ProcessInBg, ProcessInBlock, ProcessInOrphan}};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum TaskIn {
|
||||
|
|
@ -26,9 +26,10 @@ pub(crate) enum TaskIn {
|
|||
// Hook
|
||||
HookCopy(HookInOutCopy),
|
||||
HookCut(HookInOutCut),
|
||||
HookDelete(HookInOutDelete),
|
||||
HookTrash(HookInOutTrash),
|
||||
HookDownload(HookInOutDownload),
|
||||
HookDelete(HookInDelete),
|
||||
HookTrash(HookInTrash),
|
||||
HookDownload(HookInDownload),
|
||||
HookUpload(HookInUpload),
|
||||
}
|
||||
|
||||
impl_from_in! {
|
||||
|
|
@ -41,7 +42,7 @@ impl_from_in! {
|
|||
// Process
|
||||
ProcessBlock(ProcessInBlock), ProcessOrphan(ProcessInOrphan), ProcessBg(ProcessInBg),
|
||||
// Hook
|
||||
HookCopy(HookInOutCopy), HookCut(HookInOutCut), HookDelete(HookInOutDelete), HookTrash(HookInOutTrash), HookDownload(HookInOutDownload),
|
||||
HookCopy(HookInOutCopy), HookCut(HookInOutCut), HookDelete(HookInDelete), HookTrash(HookInTrash), HookDownload(HookInDownload), HookUpload(HookInUpload),
|
||||
}
|
||||
|
||||
impl TaskIn {
|
||||
|
|
@ -72,6 +73,7 @@ impl TaskIn {
|
|||
Self::HookDelete(r#in) => r#in.id,
|
||||
Self::HookTrash(r#in) => r#in.id,
|
||||
Self::HookDownload(r#in) => r#in.id,
|
||||
Self::HookUpload(r#in) => r#in.id,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,6 +104,7 @@ impl TaskIn {
|
|||
Self::HookDelete(_) => true,
|
||||
Self::HookTrash(_) => true,
|
||||
Self::HookDownload(_) => true,
|
||||
Self::HookUpload(_) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Task, file::{FileOutCopy, FileOutCopyDo, FileOutCut, FileOutCutDo, FileOutDelete, FileOutDeleteDo, FileOutDownload, FileOutDownloadDo, FileOutHardlink, FileOutHardlinkDo, FileOutLink, FileOutTrash, FileOutUpload, FileOutUploadDo}, hook::{HookInOutCopy, HookInOutCut, HookInOutDelete, HookInOutDownload, HookInOutTrash}, impl_from_out, plugin::PluginOutEntry, prework::{PreworkOutFetch, PreworkOutLoad, PreworkOutSize}, process::{ProcessOutBg, ProcessOutBlock, ProcessOutOrphan}};
|
||||
use crate::{Task, file::{FileOutCopy, FileOutCopyDo, FileOutCut, FileOutCutDo, FileOutDelete, FileOutDeleteDo, FileOutDownload, FileOutDownloadDo, FileOutHardlink, FileOutHardlinkDo, FileOutLink, FileOutTrash, FileOutUpload, FileOutUploadDo}, hook::{HookInOutCopy, HookInOutCut}, impl_from_out, plugin::PluginOutEntry, prework::{PreworkOutFetch, PreworkOutLoad, PreworkOutSize}, process::{ProcessOutBg, ProcessOutBlock, ProcessOutOrphan}};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) enum TaskOut {
|
||||
|
|
@ -30,9 +30,6 @@ pub(super) enum TaskOut {
|
|||
// Hook
|
||||
HookCopy(HookInOutCopy),
|
||||
HookCut(HookInOutCut),
|
||||
HookDelete(HookInOutDelete),
|
||||
HookTrash(HookInOutTrash),
|
||||
HookDownload(HookInOutDownload),
|
||||
}
|
||||
|
||||
impl_from_out! {
|
||||
|
|
@ -45,7 +42,7 @@ impl_from_out! {
|
|||
// Process
|
||||
ProcessBlock(ProcessOutBlock), ProcessOrphan(ProcessOutOrphan), ProcessBg(ProcessOutBg),
|
||||
// Hook
|
||||
HookCopy(HookInOutCopy), HookCut(HookInOutCut), HookDelete(HookInOutDelete), HookTrash(HookInOutTrash), HookDownload(HookInOutDownload),
|
||||
HookCopy(HookInOutCopy), HookCut(HookInOutCut),
|
||||
}
|
||||
|
||||
impl TaskOut {
|
||||
|
|
@ -79,9 +76,6 @@ impl TaskOut {
|
|||
// Hook
|
||||
Self::HookCopy(out) => out.reduce(task),
|
||||
Self::HookCut(out) => out.reduce(task),
|
||||
Self::HookDelete(out) => out.reduce(task),
|
||||
Self::HookTrash(out) => out.reduce(task),
|
||||
Self::HookDownload(out) => out.reduce(task),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ impl Runner {
|
|||
TaskIn::HookDelete(r#in) => Ok(self.hook.delete(r#in).await),
|
||||
TaskIn::HookTrash(r#in) => Ok(self.hook.trash(r#in).await),
|
||||
TaskIn::HookDownload(r#in) => Ok(self.hook.download(r#in).await),
|
||||
TaskIn::HookUpload(r#in) => Ok(self.hook.upload(r#in).await),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -69,6 +70,7 @@ impl Runner {
|
|||
TaskIn::HookDelete(_in) => unreachable!(),
|
||||
TaskIn::HookTrash(_in) => unreachable!(),
|
||||
TaskIn::HookDownload(_in) => unreachable!(),
|
||||
TaskIn::HookUpload(_in) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use yazi_parser::{app::PluginOpt, tasks::ProcessOpenOpt};
|
|||
use yazi_shared::{CompletionToken, Id, Throttle, url::{UrlBuf, UrlLike}};
|
||||
|
||||
use super::{Ongoing, TaskOp};
|
||||
use crate::{HIGH, LOW, NORMAL, Runner, TaskIn, TaskOps, file::{File, FileInCopy, FileInCut, FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInTrash, FileInUpload, FileOutCopy, FileOutCut, FileOutDownload, FileOutHardlink, FileOutUpload, FileProgCopy, FileProgCut, FileProgDelete, FileProgDownload, FileProgHardlink, FileProgLink, FileProgTrash, FileProgUpload}, hook::{Hook, HookInOutDelete, HookInOutDownload, HookInOutTrash}, plugin::{Plugin, PluginInEntry, PluginProgEntry}, prework::{Prework, PreworkInFetch, PreworkInLoad, PreworkInSize, PreworkProgFetch, PreworkProgLoad, PreworkProgSize}, process::{Process, ProcessInBg, ProcessInBlock, ProcessInOrphan, ProcessProgBg, ProcessProgBlock, ProcessProgOrphan}};
|
||||
use crate::{HIGH, LOW, NORMAL, Runner, TaskIn, TaskOps, file::{File, FileInCopy, FileInCut, FileInDelete, FileInDownload, FileInHardlink, FileInLink, FileInTrash, FileInUpload, FileOutCopy, FileOutCut, FileOutDownload, FileOutHardlink, FileOutUpload, FileProgCopy, FileProgCut, FileProgDelete, FileProgDownload, FileProgHardlink, FileProgLink, FileProgTrash, FileProgUpload}, hook::{Hook, HookInDelete, HookInDownload, HookInTrash, HookInUpload}, plugin::{Plugin, PluginInEntry, PluginProgEntry}, prework::{Prework, PreworkInFetch, PreworkInLoad, PreworkInSize, PreworkProgFetch, PreworkProgLoad, PreworkProgSize}, process::{Process, ProcessInBg, ProcessInBlock, ProcessInOrphan, ProcessProgBg, ProcessProgBlock, ProcessProgOrphan}};
|
||||
|
||||
pub struct Scheduler {
|
||||
ops: TaskOps,
|
||||
|
|
@ -163,7 +163,7 @@ impl Scheduler {
|
|||
let mut ongoing = self.ongoing.lock();
|
||||
let task = ongoing.add::<FileProgDelete>(format!("Delete {}", target.display()));
|
||||
|
||||
task.set_hook(HookInOutDelete { id: task.id, target: target.clone() });
|
||||
task.set_hook(HookInDelete { id: task.id, target: target.clone() });
|
||||
self.queue(FileInDelete { id: task.id, target, cha: None }, LOW);
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ impl Scheduler {
|
|||
let mut ongoing = self.ongoing.lock();
|
||||
let task = ongoing.add::<FileProgTrash>(format!("Trash {}", target.display()));
|
||||
|
||||
task.set_hook(HookInOutTrash { id: task.id, target: target.clone() });
|
||||
task.set_hook(HookInTrash { id: task.id, target: target.clone() });
|
||||
self.queue(FileInTrash { id: task.id, target }, LOW);
|
||||
}
|
||||
|
||||
|
|
@ -179,8 +179,8 @@ impl Scheduler {
|
|||
let mut ongoing = self.ongoing.lock();
|
||||
let task = ongoing.add::<FileProgDownload>(format!("Download {}", url.display()));
|
||||
|
||||
task.set_hook(HookInOutDownload { id: task.id });
|
||||
if url.kind().is_remote() {
|
||||
task.set_hook(HookInDownload { id: task.id });
|
||||
self.queue(
|
||||
FileInDownload { id: task.id, url, cha: None, retry: 0, done: task.done.clone() },
|
||||
LOW,
|
||||
|
|
@ -202,6 +202,7 @@ impl Scheduler {
|
|||
.out(task.id, FileOutUpload::Fail("Cannot upload non-remote file".to_owned()));
|
||||
};
|
||||
|
||||
task.set_hook(HookInUpload { id: task.id, target: url.clone() });
|
||||
self.queue(
|
||||
FileInUpload { id: task.id, url, cha: None, cache: None, done: task.done.clone() },
|
||||
LOW,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ pub enum Event {
|
|||
Key(KeyEvent),
|
||||
Mouse(MouseEvent),
|
||||
Resize,
|
||||
Focus,
|
||||
Paste(String),
|
||||
Quit(EventQuit),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use anyhow::Result;
|
||||
use hashbrown::HashSet;
|
||||
use hashbrown::HashMap;
|
||||
use tokio::{pin, sync::mpsc::UnboundedReceiver};
|
||||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||
use yazi_fs::{File, FilesOp};
|
||||
|
|
@ -14,7 +14,7 @@ use crate::{Reporter, WATCHER};
|
|||
pub(crate) struct Remote;
|
||||
|
||||
impl Remote {
|
||||
pub(crate) fn serve(rx: UnboundedReceiver<UrlBuf>, _reporter: Reporter) -> Self {
|
||||
pub(crate) fn serve(rx: UnboundedReceiver<(UrlBuf, bool)>, _reporter: Reporter) -> Self {
|
||||
tokio::spawn(Self::changed(rx));
|
||||
|
||||
Self
|
||||
|
|
@ -24,19 +24,22 @@ impl Remote {
|
|||
|
||||
pub(crate) fn unwatch(&mut self, _url: Url) -> Result<()> { Ok(()) }
|
||||
|
||||
async fn changed(rx: UnboundedReceiver<UrlBuf>) {
|
||||
async fn changed(rx: UnboundedReceiver<(UrlBuf, bool)>) {
|
||||
let rx = UnboundedReceiverStream::new(rx).chunks_timeout(1000, Duration::from_millis(250));
|
||||
pin!(rx);
|
||||
|
||||
while let Some(chunk) = rx.next().await {
|
||||
let urls: HashSet<_> = chunk.into_iter().collect();
|
||||
let mut urls = HashMap::with_capacity(chunk.len());
|
||||
for (u, upload) in chunk {
|
||||
urls.entry(u).and_modify(|b| *b |= upload).or_insert(upload);
|
||||
}
|
||||
|
||||
let _permit = WATCHER.acquire().await.unwrap();
|
||||
|
||||
let mut ops = Vec::with_capacity(urls.len());
|
||||
let mut ups = Vec::with_capacity(urls.len());
|
||||
|
||||
for u in urls {
|
||||
for (u, upload) in urls {
|
||||
let Some((parent, urn)) = u.pair() else { continue };
|
||||
let Ok(mut file) = File::new(&u).await else {
|
||||
ops.push(FilesOp::Deleting(parent.into(), [urn.into()].into()));
|
||||
|
|
@ -47,7 +50,7 @@ impl Remote {
|
|||
file.cha.ctime = Some(SystemTime::now());
|
||||
|
||||
ops.push(FilesOp::Upserting(parent.into(), [(urn.into(), file)].into()));
|
||||
if is_file {
|
||||
if upload && is_file {
|
||||
ups.push(u);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::{WATCHED, local::LINKED};
|
|||
#[derive(Clone)]
|
||||
pub(crate) struct Reporter {
|
||||
pub(super) local_tx: mpsc::UnboundedSender<UrlBuf>,
|
||||
pub(super) remote_tx: mpsc::UnboundedSender<UrlBuf>,
|
||||
pub(super) remote_tx: mpsc::UnboundedSender<(UrlBuf, bool)>,
|
||||
}
|
||||
|
||||
impl Reporter {
|
||||
|
|
@ -49,9 +49,9 @@ impl Reporter {
|
|||
let Some(dir) = watched.find_by_cache(parent.loc()) else { continue };
|
||||
let Some(name) = url.name() else { continue };
|
||||
if let Ok(u) = dir.try_join(Cow::from(percent_decode(name.encoded_bytes()))) {
|
||||
self.remote_tx.send(u).ok();
|
||||
self.remote_tx.send((u, true)).ok();
|
||||
}
|
||||
self.remote_tx.send(dir).ok();
|
||||
self.remote_tx.send((dir, false)).ok();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ impl Reporter {
|
|||
return;
|
||||
}
|
||||
|
||||
self.remote_tx.send(parent.to_owned()).ok();
|
||||
self.remote_tx.send(url.into_owned()).ok();
|
||||
self.remote_tx.send((parent.to_owned(), false)).ok();
|
||||
self.remote_tx.send((url.into_owned(), false)).ok();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue