yazi_core/spot/
spot.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use std::borrow::Cow;

use tokio_util::sync::CancellationToken;
use yazi_config::PLUGIN;
use yazi_fs::File;
use yazi_plugin::{isolate, utils::SpotLock};
use yazi_shared::url::Url;

#[derive(Default)]
pub struct Spot {
	pub lock: Option<SpotLock>,
	pub skip: usize,

	pub(super) ct: Option<CancellationToken>,
}

impl Spot {
	pub fn go(&mut self, file: File, mime: Cow<'static, str>) {
		if mime.is_empty() {
			return; // Wait till mimetype is resolved to avoid flickering
		} else if self.same_lock(&file, &mime) {
			return;
		}

		let Some(spotter) = PLUGIN.spotter(&file.url, &mime) else {
			return self.close(());
		};

		self.abort();
		self.ct = Some(isolate::spot(&spotter.run, file, mime, self.skip));
	}

	#[inline]
	pub fn visible(&self) -> bool { self.lock.is_some() }

	#[inline]
	pub fn abort(&mut self) { self.ct.take().map(|ct| ct.cancel()); }

	#[inline]
	pub fn same_url(&self, url: &Url) -> bool { self.lock.as_ref().is_some_and(|l| *url == l.url) }

	#[inline]
	pub fn same_file(&self, file: &File, mime: &str) -> bool {
		self.same_url(&file.url)
			&& self.lock.as_ref().is_some_and(|l| file.cha.hits(l.cha) && mime == l.mime)
	}

	#[inline]
	pub fn same_lock(&self, file: &File, mime: &str) -> bool {
		self.same_file(file, mime) && self.lock.as_ref().is_some_and(|l| self.skip == l.skip)
	}
}