Skip to content

Commit 62bd776

Browse files
committed
feat: add support for parsing start/end times from task text
1 parent 12d4f86 commit 62bd776

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

src/utils/__tests__/parse-emojis.ts

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import { parseEmojis } from "../parse-emojis";
66
describe("Parsing emojis", () => {
77
it.each([
88
[{ description: "task text" }, " \t task text \t "],
9+
[{ times: { start: DateTime.fromISO("09:00") } }, "09:00 do at 9am"],
10+
[
11+
{ times: { start: DateTime.fromISO("09:00"), end: DateTime.fromISO("10:00") } },
12+
"09:00/10:00 do between 9am and 10am",
13+
],
914
[{ priority: 0 }, "🔺"],
1015
[{ priority: 1 }, "⏫"],
1116
[{ priority: 2 }, "🔼"],

src/utils/parse-emojis.ts

+20-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import { Dictionary, set } from "lodash";
2-
import { DateTime } from "luxon";
2+
import { DateTime, Interval } from "luxon";
33
import { DeepPartial } from "utility-types";
44

55
import { Task } from "@/data/task";
66

77
export function parseEmojis(text: string): DeepPartial<Task> {
88
const matches = [...text.matchAll(EMOJI_REGEXP), /$/.exec(text) as RegExpExecArray];
99

10-
const taskParts: DeepPartial<Task> = {
11-
description: text.slice(0, matches[0].index).trim(),
12-
dates: {},
13-
};
10+
const taskHeader = text.slice(0, matches[0].index).trim();
11+
const { description, times } = parseTaskHeader(taskHeader);
12+
const taskParts: DeepPartial<Task> = { description, times, dates: {} };
1413

1514
for (let i = 0; i <= matches.length - 2; ++i) {
1615
const [start, stop] = matches.slice(i, i + 2);
@@ -33,6 +32,22 @@ export function parseEmojis(text: string): DeepPartial<Task> {
3332
return taskParts;
3433
}
3534

35+
function parseTaskHeader(header: string) {
36+
const [isoTime, description] = header.split(/\s+/, 2);
37+
38+
const interval = Interval.fromISO(isoTime);
39+
if (interval.isValid) {
40+
return { description, times: { start: interval.start, end: interval.end } };
41+
}
42+
43+
const time = DateTime.fromISO(isoTime);
44+
if (time.isValid) {
45+
return { description, times: { start: time } };
46+
}
47+
48+
return { description: header };
49+
}
50+
3651
const TASK_PATH_BY_EMOJI: Readonly<Dictionary<string>> = {
3752
"❌": "dates.cancelled",
3853
"➕": "dates.created",

0 commit comments

Comments
 (0)