fix: erase overlapping image portions when previewing errors (#3067)

Co-authored-by: sxyazi <sxyazi@gmail.com>
This commit is contained in:
boydaihungst 2025-08-18 18:55:28 +07:00 committed by GitHub
parent 3ca33c1f84
commit a41931275c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 29 additions and 13 deletions

View file

@ -3,7 +3,7 @@ use std::any::TypeId;
use mlua::{AnyUserData, ExternalError};
use super::{Bar, Border, Clear, Gauge, Line, List, Table, Text};
use crate::{Error, elements::{Area, Rect}};
use crate::{Error, elements::Area};
#[derive(Clone, Debug)]
pub enum Renderable {
@ -31,6 +31,21 @@ impl Renderable {
}
}
pub fn with_area(mut self, area: impl Into<Area>) -> Self {
let area = area.into();
match &mut self {
Self::Line(line) => line.area = area,
Self::Text(text) => text.area = area,
Self::List(list) => list.area = area,
Self::Bar(bar) => bar.area = area,
Self::Clear(clear) => clear.area = area,
Self::Border(border) => border.area = area,
Self::Gauge(gauge) => gauge.area = area,
Self::Table(table) => table.area = area,
}
self
}
pub fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) {
match self {
Self::Line(line) => line.render(rect, buf),
@ -77,10 +92,9 @@ impl TryFrom<AnyUserData> for Renderable {
fn try_from(ud: AnyUserData) -> Result<Self, Self::Error> { Self::try_from(&ud) }
}
impl From<(Rect, Error)> for Renderable {
fn from((area, error): (Rect, Error)) -> Self {
impl From<Error> for Renderable {
fn from(error: Error) -> Self {
Self::Text(Text {
area: area.into(),
inner: error.into_string().into(),
wrap: ratatui::widgets::Wrap { trim: false }.into(),
..Default::default()

View file

@ -9,7 +9,7 @@ function M:peek(job)
ya.sleep(math.max(0, rt.preview.image_delay / 1000 + start - os.clock()))
local _, err = ya.image_show(url, job.area)
ya.preview_widget(job, err and ui.Text(err):area(job.area):wrap(ui.Wrap.YES))
ya.preview_widget(job, err)
end
function M:seek() end

View file

@ -6,8 +6,10 @@ function M:peek(job)
return
end
local ok, err = self:preload(job)
if not ok or err then
local ok, err, bound = self:preload(job)
if bound and bound > 0 then
return ya.emit("peek", { bound - 1, only_if = job.file.url, upper_bound = true })
elseif not ok or err then
return ya.preview_widget(job, err)
end
@ -48,11 +50,8 @@ function M:preload(job)
if not output then
return true, Err("Failed to start `pdftoppm`, error: %s", err)
elseif not output.status.success then
local pages = tonumber(output.stderr:match("the last page %((%d+)%)")) or 0
if job.skip > 0 and pages > 0 then
ya.emit("peek", { math.max(0, pages - 1), only_if = job.file.url, upper_bound = true })
end
return true, Err("Failed to convert PDF to image, stderr: %s", output.stderr)
local pages = job.skip > 0 and tonumber(output.stderr:match("the last page %((%d+)%)"))
return true, Err("Failed to convert PDF to image, stderr: %s", output.stderr), pages
end
local ok, err = os.rename(string.format("%s.jpg", cache), tostring(cache))

View file

@ -47,7 +47,10 @@ impl Utils {
Ok(r) => vec![r],
Err(e) => {
if let Ok(err) = ud.take::<Error>() {
vec![(lock.area, err).into()]
vec![
Renderable::Clear(yazi_binding::elements::Clear { area: lock.area.into() }),
Renderable::from(err).with_area(lock.area),
]
} else {
Err(e)?
}