Skip to content

Commit 4319c60

Browse files
committed
fix: layout adjustments, handle resize events
1 parent eaf87e7 commit 4319c60

File tree

4 files changed

+45
-27
lines changed

4 files changed

+45
-27
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "thokr"
33
description = "a sleek typing tui written in rust"
4-
version = "0.1.0"
4+
version = "0.1.1"
55
readme = "README.md"
66
repository = "https://github.com/coloradocolby/thokr.git"
77
homepage = "https://github.com/coloradocolby/thokr"

src/main.rs

+27-14
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod util;
66
use crate::{lang::Language, thok::Thok};
77
use clap::{ArgEnum, ErrorKind, IntoApp, Parser};
88
use crossterm::{
9-
event::{self, Event, KeyCode},
9+
event::{self, Event, KeyCode, KeyEvent},
1010
execute,
1111
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
1212
tty::IsTty,
@@ -129,7 +129,10 @@ fn start_tui<B: Backend>(
129129
mut app: &mut App,
130130
) -> Result<(), Box<dyn Error>> {
131131
let cli = app.cli.clone();
132-
let events = get_events(cli.unwrap().number_of_secs.unwrap_or(0) > 0);
132+
133+
let should_tick = cli.unwrap().number_of_secs.unwrap_or(0) > 0;
134+
135+
let thok_events = get_thok_events(should_tick);
133136

134137
loop {
135138
let mut exit_type: ExitType = ExitType::Quit;
@@ -138,8 +141,8 @@ fn start_tui<B: Backend>(
138141
loop {
139142
let app = &mut app;
140143

141-
match events.recv()? {
142-
Events::Tick => {
144+
match thok_events.recv()? {
145+
ThokEvent::Tick => {
143146
if app.thok.has_started() && !app.thok.has_finished() {
144147
app.thok.on_tick();
145148

@@ -149,8 +152,11 @@ fn start_tui<B: Backend>(
149152
terminal.draw(|f| ui(f, app))?;
150153
}
151154
}
152-
Events::Input(key) => {
153-
match key {
155+
ThokEvent::Resize => {
156+
terminal.draw(|f| ui(f, app))?;
157+
}
158+
ThokEvent::Key(key) => {
159+
match key.code {
154160
KeyCode::Esc => {
155161
break;
156162
}
@@ -174,10 +180,10 @@ fn start_tui<B: Backend>(
174180
app.thok.calc_results();
175181
}
176182
}
177-
true => match key {
183+
true => match key.code {
178184
KeyCode::Char('t') => {
179185
webbrowser::open(&format!("https://twitter.com/intent/tweet?text={}%20wpm%20%2F%20{}%25%20acc%20%2F%20{:.2}%20sd%0A%0Ahttps%3A%2F%2Fgithub.com%2Fcoloradocolby%2Fthokr", app.thok.wpm, app.thok.accuracy, app.thok.std_dev))
180-
.unwrap_or_default();
186+
.unwrap_or_default();
181187
}
182188
KeyCode::Char('r') => {
183189
exit_type = ExitType::Restart;
@@ -214,25 +220,32 @@ fn start_tui<B: Backend>(
214220
}
215221

216222
#[derive(Clone)]
217-
enum Events {
218-
Input(KeyCode),
223+
enum ThokEvent {
224+
Key(KeyEvent),
225+
Resize,
219226
Tick,
220227
}
221228

222-
fn get_events(should_tick: bool) -> mpsc::Receiver<Events> {
229+
fn get_thok_events(should_tick: bool) -> mpsc::Receiver<ThokEvent> {
223230
let (tx, rx) = mpsc::channel();
224231

225232
if should_tick {
226233
let tick_x = tx.clone();
227234
thread::spawn(move || loop {
228-
tick_x.send(Events::Tick).unwrap();
235+
tick_x.send(ThokEvent::Tick).unwrap();
229236
thread::sleep(Duration::from_millis(100))
230237
});
231238
}
232239

233240
thread::spawn(move || loop {
234-
if let Event::Key(key) = event::read().unwrap() {
235-
tx.send(Events::Input(key.code)).unwrap();
241+
match event::read().unwrap() {
242+
Event::Key(key) => {
243+
tx.send(ThokEvent::Key(key)).unwrap();
244+
}
245+
Event::Resize(_, _) => {
246+
tx.send(ThokEvent::Resize).unwrap();
247+
}
248+
_ => {}
236249
}
237250
});
238251

src/ui.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use unicode_width::UnicodeWidthStr;
99

1010
use crate::thok::{Outcome, Thok};
1111

12-
const HORIZONTAL_MARGIN: u16 = 10;
12+
const HORIZONTAL_MARGIN: u16 = 5;
13+
const VERTICAL_MARGIN: u16 = 2;
1314

1415
impl Widget for &Thok {
1516
fn render(self, area: Rect, buf: &mut Buffer) {
@@ -36,7 +37,8 @@ impl Widget for &Thok {
3637
let max_chars_per_line = area.width - (HORIZONTAL_MARGIN * 2);
3738
let mut prompt_occupied_lines =
3839
((self.prompt.width() as f64 / max_chars_per_line as f64).ceil() + 1.0) as u16;
39-
let time_left_lines = 2;
40+
41+
let time_left_lines = if self.duration.is_some() { 2 } else { 0 };
4042

4143
if self.prompt.width() <= max_chars_per_line as usize {
4244
prompt_occupied_lines = 1;
@@ -85,12 +87,15 @@ impl Widget for &Thok {
8587
dim_bold_style,
8688
));
8789

88-
let widget = match prompt_occupied_lines {
89-
1 => Paragraph::new(Spans::from(spans))
90-
.alignment(Alignment::Center)
91-
.wrap(Wrap { trim: true }),
92-
_ => Paragraph::new(Spans::from(spans)).wrap(Wrap { trim: true }),
93-
};
90+
let widget = Paragraph::new(Spans::from(spans))
91+
.alignment(if prompt_occupied_lines == 1 {
92+
// when the prompt is small enough to fit on one line
93+
// centering the text gives a nice zen feeling
94+
Alignment::Center
95+
} else {
96+
Alignment::Left
97+
})
98+
.wrap(Wrap { trim: true });
9499

95100
widget.render(chunks[2], buf);
96101

@@ -107,11 +112,11 @@ impl Widget for &Thok {
107112
false => {
108113
let chunks = Layout::default()
109114
.direction(Direction::Vertical)
110-
.horizontal_margin(10)
111-
.vertical_margin(5)
115+
.horizontal_margin(HORIZONTAL_MARGIN)
116+
.vertical_margin(VERTICAL_MARGIN)
112117
.constraints(
113118
[
114-
Constraint::Percentage(90),
119+
Constraint::Min(1),
115120
Constraint::Length(1),
116121
Constraint::Length(1), // for padding
117122
Constraint::Length(1),

0 commit comments

Comments
 (0)