From 933b3ba4483c85f523f708e2f90e24f3c17a5b59 Mon Sep 17 00:00:00 2001 From: ivan-lednev Date: Sat, 28 Sep 2024 18:11:20 +0200 Subject: [PATCH 1/4] feat: add timestamp to notifications Resolves #544, #542 --- src/main.ts | 6 +++++- src/util/notify-about-started-tasks.ts | 17 ++++++++++++++--- src/util/task-utils.ts | 12 ++++++++++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main.ts b/src/main.ts index c9742dcf5..964c2b37f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -265,7 +265,11 @@ export default class DayPlanner extends Plugin { }, }); - this.register(newlyStartedTasks.subscribe(notifyAboutStartedTasks)); + this.register( + newlyStartedTasks.subscribe((value) => + notifyAboutStartedTasks(value, this.settings()), + ), + ); this.addCommand({ id: "re-sync", name: "Re-sync tasks", diff --git a/src/util/notify-about-started-tasks.ts b/src/util/notify-about-started-tasks.ts index 8d28a39fa..51f85b859 100644 --- a/src/util/notify-about-started-tasks.ts +++ b/src/util/notify-about-started-tasks.ts @@ -1,13 +1,24 @@ +import type { DayPlannerSettings } from "../settings"; import type { Task, WithTime } from "../task-types"; -import { getOneLineSummary } from "./task-utils"; +import { createTimestamp, getOneLineSummary } from "./task-utils"; -export function notifyAboutStartedTasks(tasks: WithTime[]) { +export function notifyAboutStartedTasks( + tasks: WithTime[], + settings: DayPlannerSettings, +) { if (tasks.length === 0) { return; } const firstTask = tasks[0]; + const summary = getOneLineSummary(firstTask); + const timestamp = createTimestamp( + firstTask.startMinutes, + firstTask.durationMinutes, + settings.timestampFormat, + ); - new Notification(`Task started: ${getOneLineSummary(firstTask)}`); + new Notification(`Task started: ${summary} +${timestamp}`); } diff --git a/src/util/task-utils.ts b/src/util/task-utils.ts index 9f3a66d45..b72291403 100644 --- a/src/util/task-utils.ts +++ b/src/util/task-utils.ts @@ -1,4 +1,4 @@ -import { isEmpty } from "lodash/fp"; +import { flow, isEmpty } from "lodash/fp"; import type { Moment } from "moment"; import { get } from "svelte/store"; @@ -8,6 +8,7 @@ import { checkboxRegExp, keylessScheduledPropRegExp, listTokenWithSpacesRegExp, + looseTimestampAtStartOfLineRegExp, scheduledPropRegExp, shortScheduledPropRegExp, } from "../regexp"; @@ -185,7 +186,10 @@ export function getOneLineSummary(task: Task) { return task.summary; } - return getFirstLine(task.text); + return flow( + removeListTokens, + removeTimestampFromStart, + )(getFirstLine(task.text)); } export function getLinesAfterFirst(text: string) { @@ -197,3 +201,7 @@ export function removeListTokens(text: string) { .replace(listTokenWithSpacesRegExp, "") .replace(checkboxRegExp, ""); } + +export function removeTimestampFromStart(text: string) { + return text.replace(looseTimestampAtStartOfLineRegExp, ""); +} From f5964ab3a7a19b94b5887db9d4baaf45263557df Mon Sep 17 00:00:00 2001 From: ivan-lednev Date: Sat, 28 Sep 2024 18:25:30 +0200 Subject: [PATCH 2/4] fix: fix 12 am parsed as noon Resolves #461, #522 --- src/parser/timestamp/timestamp.test.ts | 1 + src/parser/timestamp/timestamp.ts | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/parser/timestamp/timestamp.test.ts b/src/parser/timestamp/timestamp.test.ts index a2480f733..5fc7f18a2 100644 --- a/src/parser/timestamp/timestamp.test.ts +++ b/src/parser/timestamp/timestamp.test.ts @@ -17,6 +17,7 @@ it.each([ ["3PM", { hours: 15, minutes: 0 }], ["11 PM ", { hours: 23, minutes: 0 }], ["0301PM", { hours: 15, minutes: 1 }], + ["12:30am", { hours: 0, minutes: 30 }], ])("Parses timestamp %s", (asText, object) => { expect(parseTimestamp(asText, moment()).toObject()).toMatchObject(object); }); diff --git a/src/parser/timestamp/timestamp.ts b/src/parser/timestamp/timestamp.ts index 5b10feb98..23d920b3e 100644 --- a/src/parser/timestamp/timestamp.ts +++ b/src/parser/timestamp/timestamp.ts @@ -23,6 +23,10 @@ export function parseTimestamp(asText: string, day: Moment) { parsedHours += 12; } + if (ampm?.toLowerCase().trim() === "am" && parsedHours === 12) { + parsedHours = 0; + } + const timeOfDay = window.moment.duration({ hours: parsedHours, minutes: parsedMinutes, From 4af69c5ec0e9ba879b4f5adcc9b826a9ae632e48 Mon Sep 17 00:00:00 2001 From: ivan-lednev Date: Sat, 28 Sep 2024 18:38:48 +0200 Subject: [PATCH 3/4] feat: add active task end time in status bar Resolves #413 --- src/ui/components/status-bar-widget.svelte | 6 ++++-- src/ui/hooks/use-status-bar-widget.ts | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ui/components/status-bar-widget.svelte b/src/ui/components/status-bar-widget.svelte index 886a276c2..c2af1d925 100644 --- a/src/ui/components/status-bar-widget.svelte +++ b/src/ui/components/status-bar-widget.svelte @@ -11,7 +11,7 @@ const statusBarProps = useStatusBarWidget({ tasksForToday }); - $: ({ showNow, showNext, progressIndicator } = $settings); + $: ({ showNow, showNext, progressIndicator, timestampFormat } = $settings); $: ({ current, next } = $statusBarProps); @@ -24,7 +24,9 @@ {:else} {#if showNow && current} Now: {current.text} (-{current.timeLeft})Now: {current.text} (-{current.timeLeft}, till {current.endTime.format( + timestampFormat, + )}) {#if progressIndicator === "pie"}
Date: Sat, 28 Sep 2024 17:16:13 -0400 Subject: [PATCH 4/4] feat: append to end of file when plannerHeader is empty --- src/service/plan-editor.ts | 19 +++++++++---------- src/ui/settings-tab.ts | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/service/plan-editor.ts b/src/service/plan-editor.ts index e1d56330c..2043cdffb 100644 --- a/src/service/plan-editor.ts +++ b/src/service/plan-editor.ts @@ -173,12 +173,12 @@ export class PlanEditor { private async editFile(path: string, editFn: (contents: string) => string) { await this.obsidianFacade.editFile(path, (contents) => { const edited = editFn(contents); + const { plannerHeading, sortTasksInPlanAfterEdit } = this.settings(); - if (!this.settings().sortTasksInPlanAfterEdit) { + if (!plannerHeading || !sortTasksInPlanAfterEdit) { return edited; } - const plannerHeading = this.settings().plannerHeading; const mdastRoot = fromMarkdown(edited); const headingWithChildren = findHeadingWithChildren( mdastRoot, @@ -214,15 +214,14 @@ export class PlanEditor { contents: string[], metadata: CachedMetadata, ): [number, string[]] { - const planHeading = getHeadingByText( - metadata, - this.settings().plannerHeading, - ); + const { plannerHeading } = this.settings(); - const planListItems = getListItemsUnderHeading( - metadata, - this.settings().plannerHeading, - ); + if (!plannerHeading) { + return [contents.length, contents]; + } + + const planHeading = getHeadingByText(metadata, plannerHeading); + const planListItems = getListItemsUnderHeading(metadata, plannerHeading); if (planListItems && planListItems?.length > 0) { const lastListItem = planListItems[planListItems.length - 1]; diff --git a/src/ui/settings-tab.ts b/src/ui/settings-tab.ts index d2a3ca0a0..e27a67ab8 100644 --- a/src/ui/settings-tab.ts +++ b/src/ui/settings-tab.ts @@ -375,7 +375,7 @@ export class DayPlannerSettingsTab extends PluginSettingTab { new Setting(containerEl) .setName("Planner Heading Text") .setDesc( - `When you create a planner, this text is going to be in the heading`, + `When you create a planner, the events will be kept under this header. If empty, then events are placed at the bottom of the file.`, ) .addText((component) => component