Skip to main content

yazi_core/notify/
message.rs

1use std::time::{Duration, Instant};
2
3use unicode_width::UnicodeWidthStr;
4
5use super::NOTIFY_BORDER;
6use crate::notify::{MessageLevel, MessageOpt};
7
8pub struct Message {
9	pub title:   String,
10	pub content: String,
11	pub level:   MessageLevel,
12	pub timeout: Duration,
13
14	pub instant: Instant,
15	pub percent: u8,
16
17	title_width:   usize, // Width of title without icon
18	content_width: usize, // Width of longest line in content
19}
20
21impl From<MessageOpt> for Message {
22	fn from(opt: MessageOpt) -> Self {
23		let title = opt.title.lines().next().unwrap_or_default();
24		let content_width = opt.content.lines().map(|s| s.width()).max().unwrap_or(0);
25
26		Self {
27			title: title.to_owned(),
28			content: opt.content,
29			level: opt.level,
30			timeout: opt.timeout,
31
32			instant: Instant::now(),
33			percent: 0,
34
35			title_width: title.width(),
36			content_width,
37		}
38	}
39}
40
41impl PartialEq for Message {
42	fn eq(&self, other: &Self) -> bool {
43		self.level == other.level && self.content == other.content && self.title == other.title
44	}
45}
46
47impl Message {
48	pub fn width(&self) -> usize {
49		let icon_width = self.level.icon().width() + /* Space */ 1;
50
51		self.content_width.max(self.title_width + icon_width) + NOTIFY_BORDER as usize
52	}
53
54	pub fn height(&self, width: u16) -> usize {
55		let lines = ratatui::widgets::Paragraph::new(self.content.as_str())
56			.wrap(ratatui::widgets::Wrap { trim: false })
57			.line_count(width.saturating_sub(NOTIFY_BORDER));
58
59		lines + NOTIFY_BORDER as usize
60	}
61}