use altar::*;
use tokio::sync::mpsc;
struct SimpleAsyncApp {
count: usize,
super_charge: Option<usize>,
}
enum Message {
Charge,
}
impl SimpleAsyncApp {
fn handle_key_event(
&mut self,
key_event: KeyEvent,
tx: &mpsc::UnboundedSender<Message>,
) -> bool {
match key_event.code {
KeyCode::Down => self.count = self.count.saturating_sub(1),
KeyCode::Up => self.count = self.count.saturating_add(1),
KeyCode::Left => self.charged_adjust(false),
KeyCode::Right => self.charged_adjust(true),
KeyCode::Char('q') => return false,
KeyCode::Char('c') => self.start_charging(tx),
_ => {}
}
true
}
fn charged_adjust(&mut self, should_add: bool) {
if let Some(charge) = self.super_charge {
if charge == 10 {
if should_add {
self.count = self.count.saturating_add(10);
} else {
self.count = self.count.saturating_sub(10);
}
self.super_charge = None;
}
}
}
fn start_charging(&mut self, tx: &mpsc::UnboundedSender<Message>) {
if self.super_charge.is_none() {
self.super_charge = Some(0);
let tx = tx.clone();
tokio::spawn(async move {
for _ in 0..10 {
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
tx.send(Message::Charge).unwrap();
}
});
}
}
}
impl AsyncTerminalApp for SimpleAsyncApp {
type Message = Message;
fn render(&self) -> impl View {
let count = self.count.to_string();
let children = for_each_view(0..self.count, |i| i.to_string());
let charging = self.super_charge.map(|c| {
let slots: String = "=".repeat(c) + &" ".repeat(10 - c);
hstack((
"CHARGING: ",
hstack(("|", slots, "|")).spacing(0).color(Color::Red),
))
});
vstack((hstack(("Count:", count)), charging, vstack(children)))
.border()
.border_style(BorderStyle::Rounded)
}
fn update(
&mut self,
event: Event<Self::Message>,
tx: &mpsc::UnboundedSender<Self::Message>,
) -> bool {
match event {
Event::Key(key_event) => self.handle_key_event(key_event, tx),
Event::Message(Message::Charge) => {
self.super_charge = self.super_charge.map(|x| x.saturating_add(1));
true
}
}
}
}
#[tokio::main]
async fn main() {
let mut app = SimpleAsyncApp {
count: 5,
super_charge: None,
};
app.run(false).await;
}