mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-03 01:50:12 +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;
|
||||
|
||||
// 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)]
|
||||
pub struct Entry {
|
||||
/// The name of the entry.
|
||||
|
@ -9,6 +9,8 @@ pub struct PreviewState {
|
||||
}
|
||||
|
||||
const PREVIEW_MIN_SCROLL_LINES: u16 = 3;
|
||||
pub const ANSI_BEFORE_CONTEXT_SIZE: u16 = 10;
|
||||
const ANSI_CONTEXT_SIZE: usize = 500;
|
||||
|
||||
impl PreviewState {
|
||||
pub fn new(
|
||||
@ -55,4 +57,28 @@ impl PreviewState {
|
||||
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,
|
||||
)?;
|
||||
// render the preview content
|
||||
let rp = build_preview_paragraph(
|
||||
&preview_state.preview.content,
|
||||
preview_state.target_line,
|
||||
preview_state.scroll,
|
||||
);
|
||||
let rp = build_preview_paragraph(&preview_state.preview.content);
|
||||
f.render_widget(rp, inner);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn build_preview_paragraph(
|
||||
preview_content: &str,
|
||||
#[allow(unused_variables)] target_line: Option<u16>,
|
||||
preview_scroll: u16,
|
||||
) -> Paragraph<'_> {
|
||||
pub fn build_preview_paragraph(content: &str) -> Paragraph<'_> {
|
||||
let preview_block =
|
||||
Block::default().style(Style::default()).padding(Padding {
|
||||
top: 0,
|
||||
@ -55,42 +47,14 @@ pub fn build_preview_paragraph(
|
||||
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>(
|
||||
text: &'a str,
|
||||
preview_block: Block<'a>,
|
||||
preview_scroll: u16,
|
||||
) -> Paragraph<'a> {
|
||||
let lines = text.lines();
|
||||
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))
|
||||
Paragraph::new(text.into_text().unwrap()).block(preview_block)
|
||||
}
|
||||
|
||||
pub fn build_meta_preview_paragraph<'a>(
|
||||
|
@ -187,9 +187,7 @@ impl Television {
|
||||
self.rc_picker.clone(),
|
||||
channel_state,
|
||||
self.spinner,
|
||||
// PERF: we shouldn't need to clone the whole preview here but only
|
||||
// what's in range of the preview window
|
||||
self.preview_state.clone(),
|
||||
self.preview_state.for_render_context(),
|
||||
);
|
||||
|
||||
Ctx::new(
|
||||
@ -197,7 +195,6 @@ impl Television {
|
||||
self.config.clone(),
|
||||
self.colorscheme.clone(),
|
||||
self.app_metadata.clone(),
|
||||
// now timestamp
|
||||
std::time::Instant::now(),
|
||||
self.ui_state.layout,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user