From 2f7694563e4328c93697727def7d347d1ec0950b Mon Sep 17 00:00:00 2001 From: sxyazi Date: Wed, 25 Dec 2024 00:22:44 +0800 Subject: [PATCH] feat: new `ya.confirm()` API --- yazi-config/preset/yazi-default.toml | 2 +- yazi-config/src/popup/options.rs | 10 +++---- yazi-core/src/confirm/commands/show.rs | 2 +- yazi-core/src/confirm/confirm.rs | 6 ++--- yazi-fm/src/confirm/confirm.rs | 17 +++++++----- yazi-fm/src/confirm/content.rs | 27 ++++++++++++------- yazi-plugin/src/elements/line.rs | 4 +++ yazi-plugin/src/utils/layer.rs | 37 ++++++++++++++++---------- yazi-plugin/src/utils/utils.rs | 1 + yazi-shared/src/theme/style.rs | 7 +++++ 10 files changed, 74 insertions(+), 39 deletions(-) diff --git a/yazi-config/preset/yazi-default.toml b/yazi-config/preset/yazi-default.toml index dd0f24053..429e67599 100644 --- a/yazi-config/preset/yazi-default.toml +++ b/yazi-config/preset/yazi-default.toml @@ -204,7 +204,7 @@ overwrite_offset = [ 0, 0, 50, 15 ] # quit quit_title = "Quit?" -quit_content = "The following task is still running, are you sure you want to quit?" +quit_content = "The following tasks are still running, are you sure you want to quit?" quit_origin = "center" quit_offset = [ 0, 0, 50, 15 ] diff --git a/yazi-config/src/popup/options.rs b/yazi-config/src/popup/options.rs index b1d4b550b..fc3708ef5 100644 --- a/yazi-config/src/popup/options.rs +++ b/yazi-config/src/popup/options.rs @@ -1,4 +1,4 @@ -use ratatui::{text::Text, widgets::{Paragraph, Wrap}}; +use ratatui::{text::{Line, Text}, widgets::{Paragraph, Wrap}}; use yazi_shared::url::Url; use super::{Offset, Origin, Position}; @@ -24,8 +24,8 @@ pub struct PickCfg { #[derive(Default)] pub struct ConfirmCfg { - pub title: String, pub position: Position, + pub title: Line<'static>, pub content: Paragraph<'static>, pub list: Paragraph<'static>, } @@ -112,10 +112,10 @@ impl ConfirmCfg { list: Option>, ) -> Self { Self { - title, position: Position::new(origin, offset), - content: content.map(|c| Paragraph::new(c).wrap(Wrap { trim: false })).unwrap_or_default(), - list: list.map(|l| Paragraph::new(l).wrap(Wrap { trim: false })).unwrap_or_default(), + title: Line::raw(title), + content: content.map(|c| Paragraph::new(c).wrap(Wrap { trim: false })).unwrap_or_default(), + list: list.map(|l| Paragraph::new(l).wrap(Wrap { trim: false })).unwrap_or_default(), } } diff --git a/yazi-core/src/confirm/commands/show.rs b/yazi-core/src/confirm/commands/show.rs index 076b498fb..845342444 100644 --- a/yazi-core/src/confirm/commands/show.rs +++ b/yazi-core/src/confirm/commands/show.rs @@ -29,8 +29,8 @@ impl Confirm { self.content = opt.cfg.content; self.list = opt.cfg.list; - self.offset = 0; self.position = opt.cfg.position; + self.offset = 0; self.callback = Some(opt.tx); self.visible = true; diff --git a/yazi-core/src/confirm/confirm.rs b/yazi-core/src/confirm/confirm.rs index fe7649c42..60a0ebdef 100644 --- a/yazi-core/src/confirm/confirm.rs +++ b/yazi-core/src/confirm/confirm.rs @@ -1,15 +1,15 @@ -use ratatui::widgets::Paragraph; +use ratatui::{text::Line, widgets::Paragraph}; use tokio::sync::oneshot::Sender; use yazi_config::popup::Position; #[derive(Default)] pub struct Confirm { - pub title: String, + pub title: Line<'static>, pub content: Paragraph<'static>, pub list: Paragraph<'static>, - pub offset: usize, pub position: Position, + pub offset: usize, pub(super) callback: Option>, pub visible: bool, diff --git a/yazi-fm/src/confirm/confirm.rs b/yazi-fm/src/confirm/confirm.rs index 7b129fc84..1b195fc11 100644 --- a/yazi-fm/src/confirm/confirm.rs +++ b/yazi-fm/src/confirm/confirm.rs @@ -1,4 +1,4 @@ -use ratatui::{buffer::Buffer, layout::{Alignment, Constraint, Layout, Margin, Rect}, text::Line, widgets::{Block, BorderType, Widget}}; +use ratatui::{buffer::Buffer, layout::{Alignment, Constraint, Layout, Margin, Rect}, widgets::{Block, BorderType, Widget}}; use yazi_config::THEME; use crate::Ctx; @@ -12,7 +12,7 @@ impl<'a> Confirm<'a> { } impl Widget for Confirm<'_> { - fn render(self, _win: Rect, buf: &mut Buffer) { + fn render(self, _: Rect, buf: &mut Buffer) { let confirm = &self.cx.confirm; let area = self.cx.manager.area(confirm.position); @@ -21,21 +21,26 @@ impl Widget for Confirm<'_> { Block::bordered() .border_type(BorderType::Rounded) .border_style(THEME.confirm.border) - .title(Line::styled(&confirm.title, THEME.confirm.title)) + .title(confirm.title.clone().style(THEME.confirm.title.derive(confirm.title.style))) .title_alignment(Alignment::Center) .render(area, buf); let content = confirm.content.clone(); - let content_height = content.line_count(area.width).saturating_add(1) as u16; + let content_border = confirm.list.line_count(area.width) != 0; + let content_height = content.line_count(area.width) as u16; let chunks = Layout::vertical([ - Constraint::Length(if content_height == 1 { 0 } else { content_height }), + Constraint::Length(if content_height == 0 { + 0 + } else { + content_height.saturating_add(content_border as u16) + }), Constraint::Fill(1), Constraint::Length(1), ]) .split(area.inner(Margin::new(0, 1))); - super::Content::new(content).render(chunks[0], buf); + super::Content::new(self.cx, content_border).render(chunks[0], buf); super::List::new(self.cx).render(chunks[1], buf); super::Buttons.render(chunks[2], buf); } diff --git a/yazi-fm/src/confirm/content.rs b/yazi-fm/src/confirm/content.rs index 88f8398c2..015d6a9c9 100644 --- a/yazi-fm/src/confirm/content.rs +++ b/yazi-fm/src/confirm/content.rs @@ -1,28 +1,37 @@ -use ratatui::{buffer::Buffer, layout::{Margin, Rect}, widgets::{Block, Borders, Paragraph, Widget}}; +use ratatui::{buffer::Buffer, layout::{Margin, Rect}, style::Styled, widgets::{Block, Borders, Widget}}; use yazi_config::THEME; +use crate::Ctx; + pub(crate) struct Content<'a> { - p: Paragraph<'a>, + cx: &'a Ctx, + border: bool, } impl<'a> Content<'a> { - pub(crate) fn new(p: Paragraph<'a>) -> Self { Self { p } } + pub(crate) fn new(cx: &'a Ctx, border: bool) -> Self { Self { cx, border } } } impl Widget for Content<'_> { fn render(self, area: Rect, buf: &mut Buffer) { + let confirm = &self.cx.confirm; + // Content area let inner = area.inner(Margin::new(1, 0)); - // Bottom border - let block = Block::new().borders(Borders::BOTTOM).border_style(THEME.confirm.border); - block.clone().render(area.inner(Margin::new(1, 0)), buf); + // Border + let block = if self.border { + Block::new().borders(Borders::BOTTOM).border_style(THEME.confirm.border) + } else { + Block::new() + }; - self - .p + confirm + .content + .clone() .alignment(ratatui::layout::Alignment::Center) .block(block) - .style(THEME.confirm.content) + .style(THEME.confirm.content.derive(Styled::style(&confirm.content))) .render(inner, buf); } } diff --git a/yazi-plugin/src/elements/line.rs b/yazi-plugin/src/elements/line.rs index 01282d752..e3b8ace2a 100644 --- a/yazi-plugin/src/elements/line.rs +++ b/yazi-plugin/src/elements/line.rs @@ -93,6 +93,10 @@ impl TryFrom for Line { } } +impl From for ratatui::text::Line<'static> { + fn from(value: Line) -> Self { value.0 } +} + impl UserData for Line { fn add_methods>(methods: &mut M) { crate::impl_style_method!(methods, 0.style); diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index 816341fc7..e9b4960c8 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -3,13 +3,13 @@ use std::{str::FromStr, time::Duration}; use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, Table, Value}; use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; -use yazi_config::{keymap::{Chord, Key}, popup::InputCfg}; +use yazi_config::{keymap::{Chord, Key}, popup::{ConfirmCfg, InputCfg}}; use yazi_macro::emit; -use yazi_proxy::{AppProxy, InputProxy}; +use yazi_proxy::{AppProxy, ConfirmProxy, InputProxy}; use yazi_shared::{Debounce, Layer, event::Cmd}; use super::Utils; -use crate::{bindings::InputRx, elements::Pos}; +use crate::{bindings::InputRx, elements::{Line, Pos, Text}}; impl Utils { pub(super) fn which(lua: &Lua) -> mlua::Result { @@ -68,17 +68,26 @@ impl Utils { }) } - // TODO: redesign the confirm API - // pub(super) fn confirm(lua: &Lua, ya: &Table) -> mlua::Result { - // lua.create_async_function(|_, t: Table| async move { - // let result = ConfirmProxy::show(ConfirmCfg { - // title: t.raw_get("title")?, - // content: t.raw_get("content")?, - // position: Position::try_from(t.raw_get::<_, Table>("position")?)?.into(), - // }); - // Ok(result.await) - // }) - // } + pub(super) fn confirm(lua: &Lua) -> mlua::Result { + fn content(t: &Table) -> mlua::Result> { + Ok(match t.raw_get::("content") { + Ok(v) if v.is_nil() => Default::default(), + Ok(v) => Text::try_from(v)?.into(), + Err(e) => Err(e)?, + }) + } + + lua.create_async_function(|_, t: Table| async move { + let result = ConfirmProxy::show(ConfirmCfg { + position: Pos::try_from(t.raw_get::
("pos")?)?.into(), + title: Line::try_from(t.raw_get::("title")?)?.into(), + content: content(&t)?, + list: Default::default(), // TODO + }); + + Ok(result.await) + }) + } pub(super) fn notify(lua: &Lua) -> mlua::Result { lua.create_function(|_, t: Table| { diff --git a/yazi-plugin/src/utils/utils.rs b/yazi-plugin/src/utils/utils.rs index 7812c86cc..914b905dc 100644 --- a/yazi-plugin/src/utils/utils.rs +++ b/yazi-plugin/src/utils/utils.rs @@ -30,6 +30,7 @@ pub fn compose(lua: &Lua, isolate: bool) -> mlua::Result
{ // Layout b"which" => Utils::which(lua)?, b"input" => Utils::input(lua)?, + b"confirm" => Utils::confirm(lua)?, b"notify" => Utils::notify(lua)?, // Log diff --git a/yazi-shared/src/theme/style.rs b/yazi-shared/src/theme/style.rs index e54ed1765..b7086c055 100644 --- a/yazi-shared/src/theme/style.rs +++ b/yazi-shared/src/theme/style.rs @@ -36,6 +36,13 @@ impl From