use super::{PagerAction, PagerContent, copy_to_clipboard};
use crossterm::event::{KeyCode, KeyModifiers};
use ratatui::text::Line;
pub(super) trait LineStyler {
type Line;
fn style_line(&self, lines: &[Self::Line], index: usize) -> Line<'static>;
fn prepare_render(&mut self, _lines: &[Self::Line], _scroll_offset: usize) {}
fn on_resize(&mut self, _lines: &mut Vec<Self::Line>, _width: usize, _height: usize) {}
}
pub(super) struct CopyAction {
pub text: String,
pub copied_label: &'static str,
}
pub(super) struct LinesContent<S: LineStyler> {
lines: Vec<S::Line>,
styler: S,
copy: Option<CopyAction>,
feedback_message: Option<String>,
}
impl<S: LineStyler> LinesContent<S> {
pub fn new(lines: Vec<S::Line>, styler: S, copy: Option<CopyAction>) -> Self {
Self {
lines,
styler,
copy,
feedback_message: None,
}
}
#[cfg(test)]
pub fn copy_text(&self) -> Option<&str> {
self.copy.as_ref().map(|copy| copy.text.as_str())
}
}
impl<S: LineStyler> PagerContent for LinesContent<S> {
fn line_count(&self) -> usize {
self.lines.len()
}
fn render_line(&self, index: usize, _width: usize) -> Line<'static> {
self.styler.style_line(&self.lines, index)
}
fn prepare_render(&mut self, scroll_offset: usize) {
self.styler.prepare_render(&self.lines, scroll_offset);
}
fn handle_key(&mut self, code: KeyCode, modifiers: KeyModifiers) -> Option<PagerAction> {
if code == KeyCode::Char('c')
&& modifiers == KeyModifiers::NONE
&& let Some(copy) = &self.copy
{
self.feedback_message = Some(if copy_to_clipboard(©.text).is_ok() {
copy.copied_label.to_string()
} else {
"Failed to copy".to_string()
});
}
None
}
fn feedback_message(&self) -> Option<&str> {
self.feedback_message.as_deref()
}
fn clear_feedback(&mut self) {
self.feedback_message = None;
}
fn on_resize(&mut self, width: usize, height: usize) {
self.styler.on_resize(&mut self.lines, width, height);
}
}