Skip to content

Commit 21c683a

Browse files
wip: add timer widget
1 parent 7c0ba01 commit 21c683a

File tree

6 files changed

+127
-3
lines changed

6 files changed

+127
-3
lines changed

.config/config.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"<Shift-l>" = "TabRight"
1111
"<Shift-Left>" = "TabLeft"
1212
"<shift-h>" = "TabLeft"
13-
13+
# Navigation
14+
"<Enter>"= "Enter"
1415

1516
[keybindings.Explorer]
1617
# App

Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ serde = {version = "1.0.215", features = ["derive"]}
4343
tracing = "0.1.40"
4444
pretty_assertions = "1.4.1"
4545
strum = {version = "0.26.3", features = ["derive"]}
46+
vault-tasks-time-management = "0.1.0"
4647

4748
[dev-dependencies]
4849
insta = {version = "1.41.1", features = ["yaml"]}

src/components/time_management_tab.rs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
1+
use std::time::Duration;
2+
3+
use chrono::TimeDelta;
14
use color_eyre::Result;
25
use ratatui::prelude::*;
36
use tokio::sync::mpsc::UnboundedSender;
47
use tracing::debug;
8+
use vault_tasks_time_management::time_management_technique::TimeManagementTechnique;
9+
use vault_tasks_time_management::TimeManagementEngine;
510

611
use super::Component;
712

813
use crate::app::Mode;
914
use crate::tui::Tui;
1015
use crate::widgets::help_menu::HelpMenu;
16+
use crate::widgets::timer::{TimerState, TimerWidget};
1117
use crate::{action::Action, config::Config};
1218

19+
/// Struct that helps with drawing the component
20+
struct TimeManagementTabArea {
21+
content: Rect,
22+
footer: Rect,
23+
}
1324
#[derive(Default)]
1425
pub struct TimeManagementTab<'a> {
1526
command_tx: Option<UnboundedSender<Action>>,
1627
config: Config,
1728
is_focused: bool,
29+
timer_state: TimerState,
1830
/// Whether the help panel is open or not
1931
show_help: bool,
2032
help_menu_wigdet: HelpMenu<'a>,
@@ -23,6 +35,45 @@ impl<'a> TimeManagementTab<'a> {
2335
pub fn new() -> Self {
2436
Self::default()
2537
}
38+
39+
fn split_frame(area: Rect) -> TimeManagementTabArea {
40+
let vertical = Layout::vertical([
41+
Constraint::Length(1),
42+
Constraint::Min(0),
43+
Constraint::Length(1),
44+
Constraint::Length(1),
45+
]);
46+
let [_header, content, footer, _tab_footera] = vertical.areas(area);
47+
48+
TimeManagementTabArea { content, footer }
49+
}
50+
51+
// fn render_sorting_modes(&self, area: Rect, buf: &mut Buffer) {
52+
// let titles = TimeManagementTechnique::iter()
53+
// .map(|arg0: TimeManagementTechnique| TimeManagementTechnique::to_string(&arg0));
54+
55+
// let highlight_style = *self
56+
// .config
57+
// .styles
58+
// .get(&crate::app::Mode::Home)
59+
// .unwrap()
60+
// .get("highlighted_tab")
61+
// .unwrap();
62+
63+
// let selected_tab_index = self.sorting_mode as usize;
64+
// Tabs::new(titles)
65+
// .select(selected_tab_index)
66+
// .highlight_style(highlight_style)
67+
// .padding("", "")
68+
// .divider(" ")
69+
// .block(Block::bordered().title("Sort By"))
70+
// .render(area, buf);
71+
// }
72+
fn render_footer(&self, area: Rect, frame: &mut Frame) {
73+
Line::raw("Footer Place Holder")
74+
.centered()
75+
.render(area, frame.buffer_mut());
76+
}
2677
}
2778
impl<'a> Component for TimeManagementTab<'a> {
2879
fn register_action_handler(&mut self, tx: UnboundedSender<Action>) -> Result<()> {
@@ -54,6 +105,17 @@ impl<'a> Component for TimeManagementTab<'a> {
54105
}
55106
} else {
56107
match action {
108+
Action::Enter => {
109+
self.timer_state = TimerState::ClockDown {
110+
stop_at: chrono::Local::now()
111+
.checked_add_signed(
112+
TimeDelta::from_std(Duration::from_secs(15)).unwrap(),
113+
)
114+
.unwrap()
115+
.time(),
116+
}
117+
}
118+
57119
Action::Focus(mode) if mode != Mode::TimeManagement => self.is_focused = false,
58120
Action::Focus(Mode::TimeManagement) => self.is_focused = true,
59121

@@ -75,9 +137,10 @@ impl<'a> Component for TimeManagementTab<'a> {
75137
if !self.is_focused {
76138
return Ok(());
77139
}
78-
let _ = frame;
79-
let _ = area;
80140

141+
let areas = Self::split_frame(area);
142+
self.render_footer(areas.footer, frame);
143+
TimerWidget {}.render(areas.content, frame.buffer_mut(), &mut self.timer_state);
81144
if self.show_help {
82145
debug!("showing help");
83146
self.help_menu_wigdet.clone().render(

src/widgets.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ pub mod help_menu;
22
pub mod input_bar;
33
pub mod task_list;
44
pub mod task_list_item;
5+
pub mod timer;

src/widgets/timer.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use std::default;
2+
3+
use chrono::{NaiveDateTime, NaiveTime};
4+
use ratatui::widgets::{Paragraph, StatefulWidget, Widget};
5+
pub struct TimerWidget;
6+
7+
#[derive(Default)]
8+
pub enum TimerState {
9+
ClockDown {
10+
stop_at: NaiveTime,
11+
},
12+
ClockUp {
13+
started_at: NaiveTime,
14+
},
15+
#[default]
16+
NotInitialized,
17+
}
18+
19+
impl StatefulWidget for TimerWidget {
20+
type State = TimerState;
21+
22+
fn render(
23+
self,
24+
area: ratatui::prelude::Rect,
25+
buf: &mut ratatui::prelude::Buffer,
26+
state: &mut Self::State,
27+
) {
28+
let now = chrono::Local::now().time();
29+
match state {
30+
TimerState::ClockUp { started_at } => {
31+
let current = now - *started_at;
32+
Paragraph::new(format!("{current:?}"))
33+
.centered()
34+
.render(area, buf);
35+
}
36+
TimerState::ClockDown { stop_at } => {
37+
let remaining = *stop_at - now;
38+
Paragraph::new(format!("{remaining:?}"))
39+
.centered()
40+
.render(area, buf);
41+
}
42+
TimerState::NotInitialized => Paragraph::new(format!("Not initialized"))
43+
.centered()
44+
.render(area, buf),
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)