Calendar events support multiple reminder offsets with presets and per-user defaults. Lists index adds inline task entry and list property editing. Generic entity comments on list detail. New bangs.stats dashboard widget. Closes Gitea #28, #29, #30, #31. Migrations 0022 and 0023.
63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
export type ReminderOffsetUnit = "minutes" | "hours" | "days" | "weeks";
|
|
|
|
export type ReminderPreset = {
|
|
label: string;
|
|
offsetMinutes: number;
|
|
};
|
|
|
|
export const REMINDER_PRESETS: ReminderPreset[] = [
|
|
{ label: "At event time", offsetMinutes: 0 },
|
|
{ label: "5 minutes before", offsetMinutes: 5 },
|
|
{ label: "15 minutes before", offsetMinutes: 15 },
|
|
{ label: "30 minutes before", offsetMinutes: 30 },
|
|
{ label: "1 hour before", offsetMinutes: 60 },
|
|
{ label: "2 hours before", offsetMinutes: 120 },
|
|
{ label: "1 day before", offsetMinutes: 1440 },
|
|
{ label: "2 days before", offsetMinutes: 2880 },
|
|
{ label: "1 week before", offsetMinutes: 10080 },
|
|
];
|
|
|
|
export function formatReminderOffset(offsetMinutes: number): string {
|
|
const preset = REMINDER_PRESETS.find((p) => p.offsetMinutes === offsetMinutes);
|
|
if (preset) return preset.label;
|
|
|
|
if (offsetMinutes === 0) return "At event time";
|
|
if (offsetMinutes % 10080 === 0) {
|
|
const weeks = offsetMinutes / 10080;
|
|
return weeks === 1 ? "1 week before" : `${weeks} weeks before`;
|
|
}
|
|
if (offsetMinutes % 1440 === 0) {
|
|
const days = offsetMinutes / 1440;
|
|
return days === 1 ? "1 day before" : `${days} days before`;
|
|
}
|
|
if (offsetMinutes % 60 === 0) {
|
|
const hours = offsetMinutes / 60;
|
|
return hours === 1 ? "1 hour before" : `${hours} hours before`;
|
|
}
|
|
return offsetMinutes === 1 ? "1 minute before" : `${offsetMinutes} minutes before`;
|
|
}
|
|
|
|
export function customOffsetToMinutes(value: number, unit: ReminderOffsetUnit): number {
|
|
const safe = Math.max(0, Math.floor(value));
|
|
switch (unit) {
|
|
case "minutes":
|
|
return safe;
|
|
case "hours":
|
|
return safe * 60;
|
|
case "days":
|
|
return safe * 1440;
|
|
case "weeks":
|
|
return safe * 10080;
|
|
}
|
|
}
|
|
|
|
export function normalizeReminderOffsets(offsets: number[]): number[] {
|
|
return [...new Set(offsets.filter((n) => Number.isFinite(n) && n >= 0))].toSorted(
|
|
(a, b) => b - a,
|
|
);
|
|
}
|
|
|
|
export function fireAtForEventStart(startAt: Date, offsetMinutes: number): Date {
|
|
return new Date(startAt.getTime() - offsetMinutes * 60_000);
|
|
}
|