feat: make text big and add key binds for toggle/reset
This commit is contained in:
+61
-5
@@ -10,10 +10,12 @@ use crossterm::{
|
||||
event::{self, Event, KeyCode, KeyModifiers},
|
||||
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
|
||||
};
|
||||
|
||||
use figlet_rs::Toilet;
|
||||
use ratatui::{
|
||||
Terminal,
|
||||
backend::CrosstermBackend,
|
||||
layout::Alignment,
|
||||
layout::{Alignment, Constraint, Direction, Layout},
|
||||
style::{Color, Style},
|
||||
widgets::Paragraph,
|
||||
};
|
||||
@@ -87,17 +89,27 @@ impl Termato {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
self.is_running = false;
|
||||
self.state = TimerState::Work;
|
||||
self.prior_state = TimerState::Work;
|
||||
self.duration_in_secs = self.work_mins * SECONDS_PER_MIN;
|
||||
self.time_remaining_in_sec = self.duration_in_secs;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), io::Error> {
|
||||
enable_raw_mode()?;
|
||||
stdout().execute(EnterAlternateScreen)?;
|
||||
|
||||
let backend = CrosstermBackend::new(stdout());
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
|
||||
let font = Toilet::smblock().unwrap();
|
||||
let mut termato = Termato::new(1, 1);
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
@@ -110,15 +122,39 @@ fn main() -> Result<(), io::Error> {
|
||||
loop {
|
||||
terminal.draw(|f| {
|
||||
let size = f.area();
|
||||
|
||||
let minutes = termato.time_remaining_in_sec / SECONDS_PER_MIN;
|
||||
let seconds = termato.time_remaining_in_sec % SECONDS_PER_MIN;
|
||||
let time_str = format!("{:02}:{:02}", minutes, seconds);
|
||||
|
||||
let time_color = match termato.state {
|
||||
TimerState::Work => Color::Red,
|
||||
TimerState::Break => Color::Green,
|
||||
TimerState::Paused => Color::Yellow,
|
||||
};
|
||||
|
||||
let paragraph = Paragraph::new(time_str)
|
||||
.style(Style::default().fg(Color::White))
|
||||
let big_time_text = if let Some(fig) = font.convert(&time_str) {
|
||||
fig.to_string()
|
||||
} else {
|
||||
time_str
|
||||
};
|
||||
|
||||
let text_height = big_time_text.lines().count() as u16;
|
||||
|
||||
let vertical_layout = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([
|
||||
Constraint::Min(0),
|
||||
Constraint::Length(text_height),
|
||||
Constraint::Min(0),
|
||||
])
|
||||
.split(size);
|
||||
|
||||
let timer_paragraph = Paragraph::new(big_time_text)
|
||||
.style(Style::default().fg(time_color))
|
||||
.alignment(Alignment::Center);
|
||||
|
||||
f.render_widget(paragraph, size);
|
||||
f.render_widget(timer_paragraph, vertical_layout[1]);
|
||||
})?;
|
||||
|
||||
if event::poll(Duration::from_millis(100))?
|
||||
@@ -129,6 +165,8 @@ fn main() -> Result<(), io::Error> {
|
||||
KeyCode::Char('q') | KeyCode::Char('Q') => break,
|
||||
KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => break,
|
||||
KeyCode::Char(' ') => termato.toggle_running(),
|
||||
KeyCode::Char('s') | KeyCode::Char('S') => termato.toggle_mode(),
|
||||
KeyCode::Char('r') | KeyCode::Char('R') => termato.reset(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -255,4 +293,22 @@ mod tests {
|
||||
assert_eq!(termato.prior_state, TimerState::Work);
|
||||
assert!(termato.is_running)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn termato_rest_when_called_it_should_reset_the_apps_state() {
|
||||
let mut termato = Termato::new(1, 1);
|
||||
termato.is_running = true;
|
||||
termato.state = TimerState::Break;
|
||||
termato.prior_state = TimerState::Break;
|
||||
termato.duration_in_secs = 1;
|
||||
termato.time_remaining_in_sec = 1;
|
||||
|
||||
termato.reset();
|
||||
|
||||
assert!(!termato.is_running);
|
||||
assert_eq!(termato.state, TimerState::Work);
|
||||
assert_eq!(termato.prior_state, TimerState::Work);
|
||||
assert_eq!(termato.duration_in_secs, 60);
|
||||
assert_eq!(termato.time_remaining_in_sec, 60);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user