quinjet 0.0.74

A fast, live, keyboard-first Git source-control interface for the terminal
use std::fmt::Write;
use std::num::NonZeroU16;

use ratatui::buffer::{Buffer, CellDiffOption};
use ratatui::widgets::Widget;
use ratatui_image::Image;
use ratatui_image::protocol::Protocol;

use super::{Frame, Rect};

pub(super) struct KittyPlacement {
    prefix: String,
    rows: Vec<String>,
    width: u16,
    transmitted: bool,
}

impl KittyPlacement {
    pub(super) fn new(encoded: &Protocol) -> Option<Self> {
        let area = encoded.area();
        if area.width == 0 || area.height == 0 {
            return None;
        }
        let mut buffer = Buffer::empty(Rect::new(0, 0, area.width, area.height));
        Image::new(encoded).render(buffer.area, &mut buffer);
        let mut prefix = String::new();
        let mut rows = Vec::with_capacity(usize::from(area.height));
        for row in 0..area.height {
            let symbol = buffer.cell((0, row))?.symbol();
            let (before_restore, _) = symbol.split_once("\x1b[u")?;
            let (before_save, body) = before_restore.split_once("\x1b[s")?;
            if row == 0 {
                prefix.push_str(before_save);
            }
            let mut prepared = String::from("\x1b[s");
            prepared.push_str(body);
            rows.push(prepared);
        }
        Some(Self {
            prefix,
            rows,
            width: area.width,
            transmitted: false,
        })
    }

    pub(super) fn render(
        &mut self,
        frame: &mut Frame<'_>,
        area: Rect,
        row_offset: u16,
        available_height: u16,
    ) -> bool {
        let offset = usize::from(row_offset);
        let visible = self
            .rows
            .len()
            .saturating_sub(offset)
            .min(usize::from(available_height));
        if visible == 0 {
            return true;
        }
        let Some(height) = u16::try_from(visible).ok() else {
            return false;
        };
        for row in 0..height {
            let Some(body) = self.rows.get(offset + usize::from(row)) else {
                return false;
            };
            let mut symbol = String::new();
            if !self.transmitted && row == 0 {
                symbol.push_str(&self.prefix);
                self.transmitted = true;
            }
            symbol.push_str(body);
            let _result = write!(
                symbol,
                "\x1b[u\x1b[{}C\x1b[{}B",
                self.width.saturating_sub(1),
                height.saturating_sub(1)
            );
            let y = area.y.saturating_add(row);
            let Some(cell) = frame.buffer_mut().cell_mut((area.x, y)) else {
                return false;
            };
            let _cell = cell.set_symbol(&symbol);
            cell.diff_option = CellDiffOption::ForcedWidth(NonZeroU16::MIN);
            for column in 1..self.width {
                if let Some(cell) = frame
                    .buffer_mut()
                    .cell_mut((area.x.saturating_add(column), y))
                {
                    cell.diff_option = CellDiffOption::Skip;
                }
            }
        }
        true
    }
}