Add the UI foundation: vim keymap, widgets and the component contract
- keymap: every key sequence in vim notation (gg, yy, <C-a>, <Space>s), with counts (5j), per-screen overrides and which-key hints, all from the same tables. - Component: the one trait for screens and popups. They only look at the data through a Context and answer with Actions. - Action: everything a screen can ask the app to do. - widgets: big digits, buttons, a day timeline, a heatmap, a text field. - ui/mod.rs: tabs, status line and the which-key popup; terminal.rs sets the terminal up (and restores it after a crash). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
eff7834838
commit
7c8a02275e
13 files changed
+1588
No files matched your search
@@ -0,0 +1,85 @@
|
||||
//! Everything a screen or popup can ask the app to do.
|
||||
//!
|
||||
//! Screens and popups never change your data themselves: they return an
|
||||
//! `Action`, and the app applies it in one place (`App::apply`), saves, and
|
||||
//! reports what happened. That's the only way anything changes.
|
||||
|
||||
use jiff::civil::Date;
|
||||
use jiff::{SignedDuration, Timestamp};
|
||||
|
||||
use crate::domain::Segment;
|
||||
use crate::export::ExportFormat;
|
||||
use crate::export::timesheet::CopyPreset;
|
||||
use crate::time::DateRange;
|
||||
use crate::ui::{Component, Tab};
|
||||
|
||||
pub enum Action {
|
||||
// ----- Moving around the app
|
||||
GoTo(Tab),
|
||||
OpenPopup(Box<dyn Component>),
|
||||
ClosePopup,
|
||||
/// The help popup for the current screen.
|
||||
ShowHelp,
|
||||
/// Show a message in the status line.
|
||||
Notify(String),
|
||||
Quit,
|
||||
|
||||
// ----- The shift
|
||||
Start,
|
||||
/// Start working as if you had pressed Start at this earlier moment.
|
||||
StartAt(Timestamp),
|
||||
Pause,
|
||||
/// Pause as if you had pressed Pause at this earlier moment.
|
||||
PauseAt(Timestamp),
|
||||
EndDay,
|
||||
EndDayAt(Timestamp),
|
||||
/// Move the start of the session in progress by this much.
|
||||
ShiftRunningStart(SignedDuration),
|
||||
/// Correct the session in progress: when it started, and optionally
|
||||
/// when it actually stopped (you forgot to pause).
|
||||
FixRunning {
|
||||
since: Timestamp,
|
||||
stopped: Option<Timestamp>,
|
||||
},
|
||||
/// Silence the break suggestion for a while.
|
||||
Snooze,
|
||||
|
||||
// ----- Recorded work
|
||||
AddSegment {
|
||||
day: Date,
|
||||
segment: Segment,
|
||||
},
|
||||
/// Replace segment `index` of `day`, filing the new one under `new_day`.
|
||||
ReplaceSegment {
|
||||
day: Date,
|
||||
index: usize,
|
||||
segment: Segment,
|
||||
new_day: Date,
|
||||
},
|
||||
DeleteSegment {
|
||||
day: Date,
|
||||
index: usize,
|
||||
},
|
||||
Undo,
|
||||
Redo,
|
||||
|
||||
// ----- Getting data out
|
||||
Copy {
|
||||
days: Vec<Date>,
|
||||
preset: CopyPreset,
|
||||
},
|
||||
Export {
|
||||
format: ExportFormat,
|
||||
range: DateRange,
|
||||
},
|
||||
|
||||
// ----- Settings, by their key in config.toml
|
||||
SetSetting {
|
||||
key: &'static str,
|
||||
value: String,
|
||||
},
|
||||
ResetSetting {
|
||||
key: &'static str,
|
||||
},
|
||||
ToggleWhichKey,
|
||||
}
|
||||
Reference in new issue
Block a user