forked from kageru/tracc
make editing times possible
This commit is contained in:
parent
0439c3a637
commit
78ae05de42
|
@ -9,12 +9,12 @@ pub struct TimeSheet {
|
||||||
pub times: Vec<TimePoint>,
|
pub times: Vec<TimePoint>,
|
||||||
pub selected: usize,
|
pub selected: usize,
|
||||||
pub register: Option<TimePoint>,
|
pub register: Option<TimePoint>,
|
||||||
pub editing_time: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PAUSE_TEXTS: [&str; 3] = ["lunch", "mittag", "pause"];
|
const PAUSE_TEXTS: [&str; 3] = ["lunch", "mittag", "pause"];
|
||||||
|
const TIME_FORMAT: &str = "%H:%M";
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref OVERRIDE_REGEX: regex::Regex = regex::Regex::new("\\[(.*)\\]").unwrap();
|
static ref OVERRIDE_REGEX: regex::Regex = regex::Regex::new("\\((.*)\\)").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
@ -25,16 +25,17 @@ pub struct TimePoint {
|
||||||
|
|
||||||
impl TimePoint {
|
impl TimePoint {
|
||||||
pub fn new(text: &str) -> Self {
|
pub fn new(text: &str) -> Self {
|
||||||
|
let time = OffsetDateTime::now_local().time();
|
||||||
Self {
|
Self {
|
||||||
text: String::from(text),
|
time,
|
||||||
time: OffsetDateTime::now_local().time(),
|
text: format!("[{}] {}", time.format(TIME_FORMAT), text),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TimePoint {
|
impl fmt::Display for TimePoint {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "[{}] {}", self.time.format("%H:%M"), self.text)
|
write!(f, "{}", self.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +72,6 @@ impl TimeSheet {
|
||||||
times: read_times(path).unwrap_or_else(|| vec![TimePoint::new("start")]),
|
times: read_times(path).unwrap_or_else(|| vec![TimePoint::new("start")]),
|
||||||
selected: 0,
|
selected: 0,
|
||||||
register: None,
|
register: None,
|
||||||
editing_time: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,12 @@ impl TimeSheet {
|
||||||
.iter()
|
.iter()
|
||||||
.chain(iter::once(&TimePoint::new("end")))
|
.chain(iter::once(&TimePoint::new("end")))
|
||||||
.tuple_windows()
|
.tuple_windows()
|
||||||
.map(|(prev, next)| (prev.text.clone(), next.time - prev.time))
|
.map(|(prev, next)| {
|
||||||
|
(
|
||||||
|
prev.text.clone().splitn(2, " ").last().unwrap().to_string(),
|
||||||
|
next.time - prev.time,
|
||||||
|
)
|
||||||
|
})
|
||||||
// Fold into a map to group by description.
|
// Fold into a map to group by description.
|
||||||
// I use a BTreeMap because I need a stable output order for the iterator
|
// I use a BTreeMap because I need a stable output order for the iterator
|
||||||
// (otherwise the summary list will jump around on every input).
|
// (otherwise the summary list will jump around on every input).
|
||||||
|
@ -103,7 +108,7 @@ impl TimeSheet {
|
||||||
|
|
||||||
pub fn time_by_tasks(&self) -> String {
|
pub fn time_by_tasks(&self) -> String {
|
||||||
self.grouped_times()
|
self.grouped_times()
|
||||||
.map(|(text, duration)| format!("{}: {}", text, format_duration(&duration)))
|
.map(|(text, duration)| format!("{} {}", text, format_duration(&duration)))
|
||||||
.join(" | ")
|
.join(" | ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,16 +138,24 @@ impl ListView<TimePoint> for TimeSheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normal_mode(&mut self) {
|
fn normal_mode(&mut self) {
|
||||||
if self.current().text.is_empty() {
|
let old_text = self.current().text.clone();
|
||||||
|
let parts: Vec<_> = old_text.splitn(2, " ").collect();
|
||||||
|
if parts.len() < 2 {
|
||||||
self.remove_current();
|
self.remove_current();
|
||||||
self.selected = self.selected.saturating_sub(1);
|
self.selected = self.selected.saturating_sub(1);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
let current = &mut self.times[self.selected];
|
||||||
|
// if we have a parse error, just keep the old time
|
||||||
|
if let Ok(t) = Time::parse(parts[0].replace('[', "").replace(']', ""), TIME_FORMAT) {
|
||||||
|
current.time = t;
|
||||||
|
}
|
||||||
|
current.text = format!("[{}] {}", current.time.format(TIME_FORMAT), parts[1]);
|
||||||
self.times.sort_by_key(|t| t.time);
|
self.times.sort_by_key(|t| t.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle_current(&mut self) {
|
// noop for this
|
||||||
self.editing_time = !self.editing_time;
|
fn toggle_current(&mut self) {}
|
||||||
}
|
|
||||||
|
|
||||||
fn append_to_current(&mut self, chr: char) {
|
fn append_to_current(&mut self, chr: char) {
|
||||||
self.times[self.selected].text.push(chr);
|
self.times[self.selected].text.push(chr);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user