Add items
This commit is contained in:
parent
045e11cd63
commit
b1570a5e11
3 changed files with 304 additions and 87 deletions
114
src/app.rs
114
src/app.rs
|
|
@ -1,4 +1,5 @@
|
|||
use std::process::Command;
|
||||
use chrono::Utc;
|
||||
use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
|
||||
use crate::state::{AppState, TimeItem};
|
||||
use crate::config::Config;
|
||||
|
|
@ -7,6 +8,7 @@ pub enum Screen {
|
|||
Main,
|
||||
Help,
|
||||
ConfigHelp,
|
||||
NewEntry,
|
||||
}
|
||||
|
||||
pub struct App {
|
||||
|
|
@ -14,6 +16,15 @@ pub struct App {
|
|||
pub config: Config,
|
||||
pub current_screen: Screen,
|
||||
pub needs_redraw: bool,
|
||||
pub new_entry_buffer: String,
|
||||
pub new_entry_project: String,
|
||||
pub new_entry_cursor: usize,
|
||||
pub new_entry_mode: NewEntryMode, // Task or Project
|
||||
}
|
||||
|
||||
pub enum NewEntryMode {
|
||||
Task,
|
||||
Project,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
|
@ -23,6 +34,10 @@ impl App {
|
|||
config: Config::load()?,
|
||||
current_screen: Screen::Main,
|
||||
needs_redraw: true,
|
||||
new_entry_buffer: String::new(),
|
||||
new_entry_project: String::new(),
|
||||
new_entry_cursor: 0,
|
||||
new_entry_mode: NewEntryMode::Task,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -31,6 +46,7 @@ impl App {
|
|||
Screen::Main => self.handle_main_event(event),
|
||||
Screen::Help => self.handle_help_event(event),
|
||||
Screen::ConfigHelp => self.handle_config_help_event(event),
|
||||
Screen::NewEntry => self.handle_new_entry_event(event),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,10 +62,13 @@ impl App {
|
|||
(KeyCode::Char('k'), _) | (KeyCode::Up, _) => self.move_selection(-1),
|
||||
(KeyCode::Char('h'), _) | (KeyCode::Left, _) => self.change_pane(-1),
|
||||
(KeyCode::Char('l'), _) | (KeyCode::Right, _) => self.change_pane(1),
|
||||
(KeyCode::Char('n'), KeyModifiers::CONTROL) => self.change_pane(1),
|
||||
(KeyCode::Char('p'), KeyModifiers::CONTROL) => self.change_pane(-1),
|
||||
(KeyCode::Enter, _) => self.toggle_current_item()?,
|
||||
(KeyCode::Char('e'), KeyModifiers::CONTROL) => self.edit_config()?,
|
||||
(KeyCode::Char('?'), _) => self.current_screen = Screen::Help,
|
||||
(KeyCode::Char('c'), _) => self.edit_app_config()?,
|
||||
(KeyCode::Char('n'), _) => self.start_new_entry(),
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
|
|
@ -57,6 +76,93 @@ impl App {
|
|||
Ok(false)
|
||||
}
|
||||
|
||||
fn handle_new_entry_event(&mut self, event: Event) -> anyhow::Result<bool> {
|
||||
match event {
|
||||
Event::Key(KeyEvent {
|
||||
code,
|
||||
modifiers,
|
||||
..
|
||||
}) => {
|
||||
match (code, modifiers) {
|
||||
(KeyCode::Esc, _) => {
|
||||
self.current_screen = Screen::Main;
|
||||
self.new_entry_buffer.clear();
|
||||
self.new_entry_project.clear();
|
||||
self.new_entry_mode = NewEntryMode::Task;
|
||||
}
|
||||
(KeyCode::Enter, _) => {
|
||||
match self.new_entry_mode {
|
||||
NewEntryMode::Task => {
|
||||
if !self.new_entry_buffer.is_empty() {
|
||||
self.new_entry_mode = NewEntryMode::Project;
|
||||
}
|
||||
}
|
||||
NewEntryMode::Project => {
|
||||
if self.new_entry_project.is_empty() || self.config.is_valid_project(&self.new_entry_project) {
|
||||
// Create new time item
|
||||
let item = TimeItem {
|
||||
name: self.new_entry_buffer.clone(),
|
||||
tags: if self.new_entry_project.is_empty() {
|
||||
vec![]
|
||||
} else {
|
||||
vec![self.new_entry_project.clone()]
|
||||
},
|
||||
last_used: Some(Utc::now()),
|
||||
};
|
||||
// Add to current pane (or recurring if in recent)
|
||||
match self.state.current_pane {
|
||||
0 => self.state.permanent_items.push(item), // Permanent Items
|
||||
1 => self.state.recurring_items.push(item), // Recurring Items
|
||||
2 => self.state.recent_items.push(item), // Ad-Hoc Items
|
||||
_ => unreachable!(),
|
||||
}
|
||||
self.state.save()?;
|
||||
|
||||
// Clear and return to main screen
|
||||
self.current_screen = Screen::Main;
|
||||
self.new_entry_buffer.clear();
|
||||
self.new_entry_project.clear();
|
||||
self.new_entry_mode = NewEntryMode::Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(KeyCode::Backspace, _) => {
|
||||
match self.new_entry_mode {
|
||||
NewEntryMode::Task => {
|
||||
if self.new_entry_cursor > 0 {
|
||||
self.new_entry_buffer.remove(self.new_entry_cursor - 1);
|
||||
self.new_entry_cursor -= 1;
|
||||
}
|
||||
}
|
||||
NewEntryMode::Project => {
|
||||
if self.new_entry_cursor > 0 {
|
||||
self.new_entry_project.remove(self.new_entry_cursor - 1);
|
||||
self.new_entry_cursor -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(KeyCode::Char(c), m) if m.is_empty() => {
|
||||
match self.new_entry_mode {
|
||||
NewEntryMode::Task => {
|
||||
self.new_entry_buffer.insert(self.new_entry_cursor, c);
|
||||
self.new_entry_cursor += 1;
|
||||
}
|
||||
NewEntryMode::Project => {
|
||||
self.new_entry_project.insert(self.new_entry_cursor, c);
|
||||
self.new_entry_cursor += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn handle_help_event(&mut self, event: Event) -> anyhow::Result<bool> {
|
||||
match event {
|
||||
Event::Key(KeyEvent { code, .. }) => match code {
|
||||
|
|
@ -125,6 +231,14 @@ impl App {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn start_new_entry(&mut self) {
|
||||
self.current_screen = Screen::NewEntry;
|
||||
self.new_entry_buffer.clear();
|
||||
self.new_entry_project.clear();
|
||||
self.new_entry_cursor = 0;
|
||||
self.new_entry_mode = NewEntryMode::Task;
|
||||
}
|
||||
|
||||
fn edit_app_config(&mut self) -> anyhow::Result<()> {
|
||||
use crossterm::{
|
||||
terminal::{disable_raw_mode, enable_raw_mode},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue