use ratatui::Frame;
use ratatui::layout::{Alignment, Rect};
use ratatui::style::{Color, Modifier, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::Paragraph;
use crate::delights::shimmer_brightness;
use crate::theme::{EffectiveColorMode, map_color};
const AQUA: (u8, u8, u8) = (0x22, 0xd3, 0xee);
const ICE: (u8, u8, u8) = (0xe0, 0xf2, 0xfe);
const ACCENT: Color = Color::Cyan;
const MUTED: Color = Color::DarkGray;
const SLOGAN: &str = "think further.";
const VERSION: &str = env!("CARGO_PKG_VERSION");
const QUICK_HINTS: &[(&str, &str)] = &[
("/", "commands"),
("@", "files"),
("?", "keys"),
("Tab", "panels"),
];
pub fn render(
frame: &mut Frame,
area: Rect,
color_mode: EffectiveColorMode,
shimmer_phase: Option<u64>,
) {
if area.width == 0 || area.height == 0 {
return;
}
let lines = build_lines(area.height, color_mode, shimmer_phase);
let paragraph = Paragraph::new(lines).alignment(Alignment::Center);
frame.render_widget(paragraph, area);
}
fn build_lines(
height: u16,
mode: EffectiveColorMode,
shimmer_phase: Option<u64>,
) -> Vec<Line<'static>> {
let wordmark = wordmark_line(mode, shimmer_phase);
let hints = hints_line(mode);
if height < 3 {
return vec![wordmark];
}
if height < 8 {
let compact = compact_wordmark_line(mode, shimmer_phase);
return vec![compact, hints];
}
let slogan_style = Style::default().fg(MUTED);
let version_style = Style::default().fg(MUTED);
vec![
Line::default(),
wordmark,
Line::from(Span::styled(SLOGAN, slogan_style)),
Line::from(Span::styled(format!("v{VERSION}"), version_style)),
Line::default(),
hints,
Line::default(),
Line::default(),
]
}
fn wordmark_line(mode: EffectiveColorMode, shimmer_phase: Option<u64>) -> Line<'static> {
match mode {
EffectiveColorMode::Truecolor | EffectiveColorMode::Ansi256 => {
gradient_wordmark_line("≈ ", mode, shimmer_phase)
}
EffectiveColorMode::Ansi16 => {
Line::from(Span::styled("≈ zeph", Style::default().fg(ACCENT)))
}
EffectiveColorMode::Never => Line::from(Span::raw("~ zeph")),
}
}
fn compact_wordmark_line(mode: EffectiveColorMode, shimmer_phase: Option<u64>) -> Line<'static> {
match mode {
EffectiveColorMode::Truecolor | EffectiveColorMode::Ansi256 => {
let mut spans = gradient_wordmark_spans("≈ ", mode, shimmer_phase);
spans.push(Span::styled(
format!(" {SLOGAN}"),
Style::default().fg(MUTED),
));
Line::from(spans)
}
EffectiveColorMode::Ansi16 => Line::from(vec![
Span::styled("≈ zeph", Style::default().fg(ACCENT)),
Span::styled(format!(" {SLOGAN}"), Style::default().fg(MUTED)),
]),
EffectiveColorMode::Never => Line::from(format!("~ zeph {SLOGAN}")),
}
}
fn hints_line(mode: EffectiveColorMode) -> Line<'static> {
let key_style = match mode {
EffectiveColorMode::Never => Style::default(),
_ => Style::default().fg(ACCENT).add_modifier(Modifier::BOLD),
};
let desc_style = match mode {
EffectiveColorMode::Never => Style::default(),
_ => Style::default().fg(MUTED),
};
let mut spans: Vec<Span<'static>> = Vec::with_capacity(QUICK_HINTS.len() * 3);
for (i, (key, desc)) in QUICK_HINTS.iter().enumerate() {
if i > 0 {
spans.push(Span::styled(" ", desc_style));
}
spans.push(Span::styled(*key, key_style));
spans.push(Span::styled(format!(" {desc}"), desc_style));
}
Line::from(spans)
}
fn gradient_wordmark_line(
prefix: &'static str,
mode: EffectiveColorMode,
shimmer_phase: Option<u64>,
) -> Line<'static> {
Line::from(gradient_wordmark_spans(prefix, mode, shimmer_phase))
}
fn gradient_wordmark_spans(
prefix: &'static str,
mode: EffectiveColorMode,
shimmer_phase: Option<u64>,
) -> Vec<Span<'static>> {
let accent_style = Style::default().fg(map_color(ACCENT, mode));
let letters: &[char] = &['z', 'e', 'p', 'h'];
let n_letters = letters.len();
let mut spans: Vec<Span<'static>> = Vec::with_capacity(1 + n_letters);
spans.push(Span::styled(prefix, accent_style));
for (letter_pos, ch) in letters.iter().enumerate() {
#[allow(clippy::cast_precision_loss)]
let interp = if n_letters <= 1 {
0.0_f32
} else {
letter_pos as f32 / (n_letters - 1) as f32
};
let (red, green, blue) = lerp_rgb_components(AQUA, ICE, interp);
let (red, green, blue) = if let Some(phase) = shimmer_phase {
let boost = shimmer_brightness(letter_pos, n_letters, phase);
boost_rgb(red, green, blue, boost)
} else {
(red, green, blue)
};
let color = map_color(Color::Rgb(red, green, blue), mode);
spans.push(Span::styled(ch.to_string(), Style::default().fg(color)));
}
spans
}
fn lerp_rgb_components(
(r1, g1, b1): (u8, u8, u8),
(r2, g2, b2): (u8, u8, u8),
t: f32,
) -> (u8, u8, u8) {
(
lerp_channel(r1, r2, t),
lerp_channel(g1, g2, t),
lerp_channel(b1, b2, t),
)
}
fn lerp_channel(a: u8, b: u8, t: f32) -> u8 {
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
{
(f32::from(a) + (f32::from(b) - f32::from(a)) * t).round() as u8
}
}
fn boost_rgb(r: u8, g: u8, b: u8, amount: f32) -> (u8, u8, u8) {
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
let boost = |c: u8| -> u8 {
let boosted = f32::from(c) + (255.0 - f32::from(c)) * amount;
boosted.min(255.0) as u8
};
(boost(r), boost(g), boost(b))
}
#[cfg(test)]
mod tests {
use insta::assert_snapshot;
use crate::test_utils::render_to_string;
use crate::theme::EffectiveColorMode;
fn render(width: u16, height: u16, mode: EffectiveColorMode) -> String {
render_to_string(width, height, |frame, area| {
super::render(frame, area, mode, None);
})
}
#[test]
fn splash_truecolor_full_layout() {
let output = render(60, 20, EffectiveColorMode::Truecolor);
assert_snapshot!(output);
}
#[test]
fn splash_ansi16_full_layout() {
let output = render(60, 20, EffectiveColorMode::Ansi16);
assert_snapshot!(output);
}
#[test]
fn splash_ascii_only_full_layout() {
let output = render(60, 20, EffectiveColorMode::Never);
assert_snapshot!(output);
}
#[test]
fn splash_short_terminal_compact_layout() {
let output = render(60, 5, EffectiveColorMode::Truecolor);
assert_snapshot!(output);
}
#[test]
fn splash_minimal_single_line() {
let output = render(60, 2, EffectiveColorMode::Truecolor);
assert_snapshot!(output);
}
#[test]
fn splash_ascii_prefix_used_in_never_mode() {
let output = render(60, 20, EffectiveColorMode::Never);
assert!(
output.contains("~ zeph"),
"ASCII mode must use '~ zeph' prefix, got: {output}"
);
assert!(
!output.contains("≈"),
"ASCII mode must not contain '≈', got: {output}"
);
}
#[test]
fn splash_unicode_prefix_in_truecolor() {
let output = render(60, 20, EffectiveColorMode::Truecolor);
assert!(
output.contains("≈"),
"Truecolor mode must contain '≈', got: {output}"
);
}
#[test]
fn splash_version_shown_in_full_layout() {
let output = render(60, 20, EffectiveColorMode::Ansi16);
assert!(
output.contains(env!("CARGO_PKG_VERSION")),
"Full layout must contain crate version, got: {output}"
);
}
#[test]
fn splash_hints_present_in_full_layout() {
let output = render(60, 20, EffectiveColorMode::Ansi16);
assert!(
output.contains("commands"),
"Full layout must contain hint text, got: {output}"
);
}
#[test]
fn splash_zero_area_no_panic() {
render_to_string(0, 0, |frame, area| {
super::render(frame, area, EffectiveColorMode::Truecolor, None);
});
}
#[test]
fn splash_shimmer_none_matches_baseline() {
let without_shimmer = render(60, 20, EffectiveColorMode::Truecolor);
let with_none = render_to_string(60, 20, |frame, area| {
super::render(frame, area, EffectiveColorMode::Truecolor, None);
});
assert_eq!(
without_shimmer, with_none,
"shimmer_phase=None must be byte-identical to baseline (off-state)"
);
}
#[test]
fn splash_shimmer_active_does_not_panic() {
for phase in 0..crate::delights::SHIMMER_TICKS {
render_to_string(60, 20, |frame, area| {
super::render(frame, area, EffectiveColorMode::Truecolor, Some(phase));
});
}
}
}