Files
termato/src/main.rs
T

118 lines
2.8 KiB
Rust
Raw Normal View History

mod app;
mod audio;
mod events;
mod msg;
mod notification;
mod terminal;
mod ui;
use std::{
2026-07-27 17:08:31 -05:00
io::{self, stdout},
sync::mpsc,
2026-07-27 17:08:31 -05:00
thread,
time::Duration,
};
use crossterm::event;
use figlet_rs::Toilet;
use ratatui::{Terminal, backend::CrosstermBackend};
use app::Termato;
use audio::AudioVisualizer;
use events::handle_event;
use msg::Message;
use terminal::TerminalGuard;
use ui::render_app;
fn main() -> Result<(), io::Error> {
2026-07-22 22:48:27 -05:00
let args: Vec<String> = std::env::args().collect();
2026-07-27 17:08:31 -05:00
2026-07-22 22:48:27 -05:00
if args.iter().any(|arg| arg == "-h" || arg == "--help") {
println!("Usage: termato [options] [work_minutes] [break_minutes]");
println!();
println!("Options:");
println!(" -n, --notify Enable desktop notifications");
println!(" -h, --help Print this help message");
println!(" -v, --version Print the version number");
2026-07-27 15:00:07 -05:00
println!(" -z, --visualizer Display visualizer of playing audio");
println!();
2026-07-22 22:48:27 -05:00
println!("Defaults: work_minutes = 25, break_minutes = 5");
return Ok(());
}
if args.iter().any(|arg| arg == "-v" || arg == "--version") {
println!("termato version {}", env!("CARGO_PKG_VERSION"));
return Ok(());
}
let _guard = TerminalGuard::new()?;
let backend = CrosstermBackend::new(stdout());
let mut terminal = Terminal::new(backend)?;
let font = Toilet::smblock().unwrap();
2026-07-22 22:48:27 -05:00
2026-07-27 15:00:07 -05:00
let enable_visualizer = args.iter().any(|arg| arg == "-z" || arg == "--visualizer");
let enable_notifications = args.iter().any(|arg| arg == "-n" || arg == "--notify");
2026-07-27 15:00:07 -05:00
2026-07-27 17:08:31 -05:00
let visualizer = if enable_visualizer {
Some(AudioVisualizer::new(64))
} else {
None
};
2026-07-27 17:38:41 -05:00
let is_flag = |arg: &str| {
arg == "-n"
|| arg == "--notify"
|| arg == "-z"
|| arg == "--visualizer"
|| arg == "-h"
|| arg == "--help"
|| arg == "-v"
|| arg == "--version"
};
2026-07-27 17:38:41 -05:00
let positional_args: Vec<&String> = args.iter().skip(1).filter(|arg| !is_flag(arg)).collect();
2026-07-27 17:08:31 -05:00
let work_mins = positional_args
.first()
.and_then(|s| s.parse().ok())
.unwrap_or(25);
let break_mins = positional_args
.get(1)
.and_then(|s| s.parse().ok())
.unwrap_or(5);
2026-07-27 15:00:07 -05:00
let mut termato = Termato::new(work_mins, break_mins)
2026-07-27 17:08:31 -05:00
.with_notifications(enable_notifications)
.with_visualizer(enable_visualizer);
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
loop {
thread::sleep(Duration::from_secs(1));
if tx.send(()).is_err() {
break;
}
}
});
while !termato.should_quit {
terminal.draw(|f| render_app(&termato, f, &font, visualizer.as_ref()))?;
2026-07-22 22:24:48 -05:00
if event::poll(Duration::from_millis(16))? {
let raw_event = event::read()?;
if let Some(msg) = handle_event(raw_event) {
termato.update(msg);
}
}
if rx.try_recv().is_ok() {
termato.update(Message::Tick);
}
}
Ok(())
}