use std::time::Duration;
use rusty_bubbles::progress;
use rusty_bubbletea::commands;
use rusty_bubbletea::model::Model as ModelTrait;
use rusty_bubbletea::screen::WindowSizeMsg;
use rusty_bubbletea::{quit, Cmd, KeyPressMsg, Msg, Program, View};
use rusty_lipgloss::{Color, Style};
const PADDING: usize = 2;
const MAX_WIDTH: usize = 80;
fn help_style() -> Style {
Style::new().foreground_color(Color::parse("#626262"))
}
#[derive(Debug)]
struct TickMsg;
fn tick_cmd() -> Cmd {
commands::tick(Duration::from_secs(1), |_t| Some(Box::new(TickMsg)))
}
struct Model {
progress: progress::Model,
}
impl Model {
fn new() -> Self {
Model {
progress: progress::new(vec![progress::with_default_blend()]),
}
}
}
impl ModelTrait for Model {
fn init(&self) -> Cmd {
tick_cmd()
}
fn update(&mut self, msg: &dyn Msg) -> Cmd {
if msg.as_any().downcast_ref::<KeyPressMsg>().is_some() {
return quit();
}
if let Some(w) = msg.as_any().downcast_ref::<WindowSizeMsg>() {
let width = w.width.saturating_sub(PADDING * 2 + 4);
self.progress.set_width(width);
if self.progress.width() > MAX_WIDTH {
self.progress.set_width(MAX_WIDTH);
}
return None;
}
if msg.as_any().is::<TickMsg>() {
if self.progress.percent() == 1.0 {
return quit();
}
let cmd = self.progress.incr_percent(0.25);
return commands::batch(vec![tick_cmd(), cmd]);
}
if msg.as_any().downcast_ref::<progress::FrameMsg>().is_some() {
return self.progress.update(msg);
}
None
}
fn view(&self) -> View {
let pad = " ".repeat(PADDING);
View::new(&format!(
"\n{}{}\n\n{}{}",
pad,
self.progress.view(),
pad,
help_style().render("Press any key to quit")
))
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let p = Program::new(Model::new());
p.run()?;
Ok(())
}