Add support for multiple reminders

This commit is contained in:
2025-06-09 13:44:52 +02:00
parent 52dd10ac10
commit bff145d27f
6 changed files with 41 additions and 18 deletions

View File

@@ -74,13 +74,15 @@ delete = type:deleteIcon _ action:[a-zA-Z]+ {
/**************************************************************************************************************************************/
reminder = reminderIcon _ time:(longTime / shortTime)? {
reminder = reminderIcon _ time:(defaultTime / longTime / shortTime)|..,(_ "," _)| {
return {
feature: "reminder",
time
}
}
defaultTime = "_"
longTime = hour:[0-9]|1..2| ":" minute:[0-9]|1..2| {
return `${hour.join("").padStart(2, '0')}:${minute.join("").padStart(2, '0')}`;
}

View File

@@ -16,14 +16,14 @@ const backends = [
export async function remind(config: Config, profileConfig: ProfileConfig, db: TaskDatabase) {
const now = dayjs().format("HH:mm");
await run(config, profileConfig, db, db[now]);
await run(config, profileConfig, db[now]);
if(profileConfig?.defaultTime && profileConfig?.defaultTime === now) {
run(config, profileConfig, db, db.default);
run(config, profileConfig, db._);
}
}
async function run(config: Config, profileConfig: ProfileConfig, db: TaskDatabase, tasks?: Task[]) {
async function run(config: Config, profileConfig: ProfileConfig, tasks?: Task[]) {
if(!tasks) {
return;
}

View File

@@ -1,6 +1,10 @@
import fs from "fs";
import { Task, TaskDatabase } from "../types/task";
type FlatReminder = {
task: Task;
time: string;
}
/**
* Applies the mapper for each task from list, groups them by time and dumps the data into JSON formatted file.
@@ -21,12 +25,29 @@ export function serializeDatabase(tasks: Task[]): string {
* Applies the mapper for each task from list and groups them by time.
*/
export function createDatabase(tasks: Task[]): TaskDatabase {
return tasks.filter(t => t.reminder).reduce((acc, t) => {
if (t.reminder) {
(acc[t.reminder] = (acc[t.reminder] || [])).push(t);
};
return acc;
}, {} as TaskDatabase);
return tasks
.flatMap(flatTimes)
.reduce(pushTaskToDatabase, {} as TaskDatabase);
}
/**
* Returns list pairs of input task and consecutive reminder times.
* If reminder is missing, returns empty array.
* If reminder is empty array, returns ['_'], where '_' designates the default time.
* @param task input task
* @returns list pairs of input task and consecutive reminder times
*/
function flatTimes(task: Task): FlatReminder[] {
if (task.reminder === undefined) {
return [];
}
return task.reminder.length === 0
? [{ task, time: '_' }]
: task.reminder.map(time => ({ task, time }));
}
function pushTaskToDatabase(db: TaskDatabase, { task, time }: FlatReminder): TaskDatabase {
(db[time] = db[time] ?? []).push(task);
return db;
}

View File

@@ -128,11 +128,11 @@ export class DynamicTask implements Task {
return this.#features<ParsedTaskDependency>("dependency").find(x => x.type === '⛔')?.deps || [];
}
get reminder(): string|undefined {
get reminder(): string[]|undefined {
const feature = this.parsed.meta.find(x => x.feature === 'reminder');
if (feature) {
return feature.time || "default";
return feature.time;
}
return undefined;
@@ -209,7 +209,7 @@ export class DynamicTask implements Task {
o("delete", this.onDelete),
o("id", this.id),
o("deps", this.dependsOn?.join(",")),
o("reminder", this.reminder),
o("reminder", this.reminder?.join(",")),
o("tags", this.tags.join(","))
];
@@ -255,7 +255,7 @@ export class DynamicTask implements Task {
break;
case 'reminder':
segments.push(['⏰', meta.time ?? ""]);
segments.push(['⏰', meta.time.join(",")]);
break;
case 'recurrence':

View File

@@ -54,5 +54,5 @@ export type ParsedTaskDependency = {
export type ParsedTaskReminder = {
feature: 'reminder';
time: string;
time: string[];
}

View File

@@ -17,7 +17,7 @@ export type Task = {
onDelete?: string;
id?: string;
dependsOn?: string[];
reminder?: string;
reminder?: string[];
sourceFile: string;
sourceLine: number;
source: string;