mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 03:25:23 +00:00
perf(previews): avoid unnecessary preview content copy (#507)
This commit is contained in:
parent
67c067ff40
commit
fc2f8b9473
@ -2,12 +2,6 @@ use std::hash::{Hash, Hasher};
|
|||||||
|
|
||||||
use devicons::FileIcon;
|
use devicons::FileIcon;
|
||||||
|
|
||||||
// NOTE: having an enum for entry types would be nice since it would allow
|
|
||||||
// having a nicer implementation for transitions between channels. This would
|
|
||||||
// permit implementing `From<EntryType>` for channels which would make the
|
|
||||||
// channel convertible from any other that yields `EntryType`.
|
|
||||||
// This needs pondering since it does bring another level of abstraction and
|
|
||||||
// adds a layer of complexity.
|
|
||||||
#[derive(Clone, Debug, Eq)]
|
#[derive(Clone, Debug, Eq)]
|
||||||
pub struct Entry {
|
pub struct Entry {
|
||||||
/// The name of the entry.
|
/// The name of the entry.
|
||||||
|
@ -9,6 +9,8 @@ pub struct PreviewState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PREVIEW_MIN_SCROLL_LINES: u16 = 3;
|
const PREVIEW_MIN_SCROLL_LINES: u16 = 3;
|
||||||
|
pub const ANSI_BEFORE_CONTEXT_SIZE: u16 = 10;
|
||||||
|
const ANSI_CONTEXT_SIZE: usize = 500;
|
||||||
|
|
||||||
impl PreviewState {
|
impl PreviewState {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
@ -55,4 +57,28 @@ impl PreviewState {
|
|||||||
self.target_line = target_line;
|
self.target_line = target_line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn for_render_context(&self) -> Self {
|
||||||
|
let skipped_lines =
|
||||||
|
self.scroll.saturating_sub(ANSI_BEFORE_CONTEXT_SIZE);
|
||||||
|
let cropped_content = self
|
||||||
|
.preview
|
||||||
|
.content
|
||||||
|
.lines()
|
||||||
|
.skip(skipped_lines as usize)
|
||||||
|
.take(ANSI_CONTEXT_SIZE)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n");
|
||||||
|
PreviewState::new(
|
||||||
|
self.enabled,
|
||||||
|
Preview::new(
|
||||||
|
&self.preview.title,
|
||||||
|
cropped_content,
|
||||||
|
self.preview.icon,
|
||||||
|
self.preview.total_lines,
|
||||||
|
),
|
||||||
|
skipped_lines,
|
||||||
|
self.target_line,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,21 +32,13 @@ pub fn draw_preview_content_block(
|
|||||||
use_nerd_font_icons,
|
use_nerd_font_icons,
|
||||||
)?;
|
)?;
|
||||||
// render the preview content
|
// render the preview content
|
||||||
let rp = build_preview_paragraph(
|
let rp = build_preview_paragraph(&preview_state.preview.content);
|
||||||
&preview_state.preview.content,
|
|
||||||
preview_state.target_line,
|
|
||||||
preview_state.scroll,
|
|
||||||
);
|
|
||||||
f.render_widget(rp, inner);
|
f.render_widget(rp, inner);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_preview_paragraph(
|
pub fn build_preview_paragraph(content: &str) -> Paragraph<'_> {
|
||||||
preview_content: &str,
|
|
||||||
#[allow(unused_variables)] target_line: Option<u16>,
|
|
||||||
preview_scroll: u16,
|
|
||||||
) -> Paragraph<'_> {
|
|
||||||
let preview_block =
|
let preview_block =
|
||||||
Block::default().style(Style::default()).padding(Padding {
|
Block::default().style(Style::default()).padding(Padding {
|
||||||
top: 0,
|
top: 0,
|
||||||
@ -55,42 +47,14 @@ pub fn build_preview_paragraph(
|
|||||||
left: 1,
|
left: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
build_ansi_text_paragraph(preview_content, preview_block, preview_scroll)
|
build_ansi_text_paragraph(content, preview_block)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ANSI_BEFORE_CONTEXT_SIZE: u16 = 10;
|
|
||||||
const ANSI_CONTEXT_SIZE: usize = 150;
|
|
||||||
|
|
||||||
fn build_ansi_text_paragraph<'a>(
|
fn build_ansi_text_paragraph<'a>(
|
||||||
text: &'a str,
|
text: &'a str,
|
||||||
preview_block: Block<'a>,
|
preview_block: Block<'a>,
|
||||||
preview_scroll: u16,
|
|
||||||
) -> Paragraph<'a> {
|
) -> Paragraph<'a> {
|
||||||
let lines = text.lines();
|
Paragraph::new(text.into_text().unwrap()).block(preview_block)
|
||||||
let skip =
|
|
||||||
preview_scroll.saturating_sub(ANSI_BEFORE_CONTEXT_SIZE) as usize;
|
|
||||||
let context = lines
|
|
||||||
.skip(skip)
|
|
||||||
.take(ANSI_CONTEXT_SIZE)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("\n");
|
|
||||||
|
|
||||||
let mut text = "\n".repeat(skip);
|
|
||||||
text.push_str(
|
|
||||||
&replace_non_printable(
|
|
||||||
context.as_bytes(),
|
|
||||||
&ReplaceNonPrintableConfig {
|
|
||||||
replace_line_feed: false,
|
|
||||||
replace_control_characters: false,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.0,
|
|
||||||
);
|
|
||||||
|
|
||||||
Paragraph::new(text.into_text().unwrap())
|
|
||||||
.block(preview_block)
|
|
||||||
.scroll((preview_scroll, 0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_meta_preview_paragraph<'a>(
|
pub fn build_meta_preview_paragraph<'a>(
|
||||||
|
@ -187,9 +187,7 @@ impl Television {
|
|||||||
self.rc_picker.clone(),
|
self.rc_picker.clone(),
|
||||||
channel_state,
|
channel_state,
|
||||||
self.spinner,
|
self.spinner,
|
||||||
// PERF: we shouldn't need to clone the whole preview here but only
|
self.preview_state.for_render_context(),
|
||||||
// what's in range of the preview window
|
|
||||||
self.preview_state.clone(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Ctx::new(
|
Ctx::new(
|
||||||
@ -197,7 +195,6 @@ impl Television {
|
|||||||
self.config.clone(),
|
self.config.clone(),
|
||||||
self.colorscheme.clone(),
|
self.colorscheme.clone(),
|
||||||
self.app_metadata.clone(),
|
self.app_metadata.clone(),
|
||||||
// now timestamp
|
|
||||||
std::time::Instant::now(),
|
std::time::Instant::now(),
|
||||||
self.ui_state.layout,
|
self.ui_state.layout,
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user