use std::borrow::Cow;
use ratatui::{
Frame,
layout::Rect,
style::Style,
widgets::{Clear, Paragraph},
};
use crate::config::Theme;
pub const SPINNER_CHARS: [&str; 10] = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
pub struct LoadingSpinner<'a> {
spinner_state: usize,
style: Style,
message: Option<Cow<'a, str>>,
}
impl<'a> LoadingSpinner<'a> {
pub fn new(theme: &Theme) -> Self {
Self {
spinner_state: 0,
style: theme.primary.into(),
message: None,
}
}
pub fn with_message(mut self, message: impl Into<Cow<'a, str>>) -> Self {
self.set_message(message);
self
}
pub fn set_message(&mut self, message: impl Into<Cow<'a, str>>) {
self.message = Some(message.into());
}
pub fn tick(&mut self) {
self.spinner_state = (self.spinner_state + 1) % SPINNER_CHARS.len();
}
pub fn render_in(&self, frame: &mut Frame, area: Rect) {
let spinner_char = SPINNER_CHARS[self.spinner_state];
let loading_text = if let Some(ref msg) = self.message {
format!("{spinner_char} {msg}")
} else {
spinner_char.to_string()
};
let loading_paragraph = Paragraph::new(loading_text).style(self.style);
frame.render_widget(Clear, area);
frame.render_widget(loading_paragraph, area);
}
}