M6 1908b: foreground reminder delivery + recurrence/snooze UI (frontend)
Completes 1908 without Web Push. While the app is open, due reminders now actually surface; recurring reminders + snooze/done are manageable. - reminders store (singleton): polls /api/notes/reminders every 45s while the app is open; each due reminder fires ONCE as a toast (with an "Open" action) and, if the user opts in, a page-context OS Notification — no service worker, no PWA. Silently primes a stale backlog on first load; only announces recently-due ones. AppShell starts/stops it. - Editor reminder section: a Repeat picker (Does not repeat / Daily / Weekly / Monthly / Yearly) + Done (advances a recurring reminder / clears a one-off) + Snooze 1h/1d, shown when a reminder is set. - RemindersView rebuilt as a chronological list: per row a due time + recurrence badge + Done / 1h / 1d, click to open; plus an "Enable notifications" opt-in and a note that background alerts come with native. - Note type gains `recurrence`; notes store setRecurrence / completeReminder / snoozeReminder. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
This commit is contained in:
@@ -5,6 +5,7 @@ import { useSessionStore } from "../stores/session";
|
||||
import { useConfigStore } from "../stores/config";
|
||||
import { useLabelsStore } from "../stores/labels";
|
||||
import { useSavedFiltersStore, type SavedFilter } from "../stores/savedFilters";
|
||||
import { useReminderStore } from "../stores/reminders";
|
||||
import { useUiStore } from "../stores/ui";
|
||||
import CommandPalette from "./CommandPalette.vue";
|
||||
import Icon from "./Icon.vue";
|
||||
@@ -19,6 +20,7 @@ const session = useSessionStore();
|
||||
const config = useConfigStore();
|
||||
const labels = useLabelsStore();
|
||||
const savedFilters = useSavedFiltersStore();
|
||||
const reminders = useReminderStore();
|
||||
const ui = useUiStore();
|
||||
|
||||
async function removeView(f: SavedFilter) {
|
||||
@@ -153,9 +155,13 @@ function onKeydown(e: KeyboardEvent) {
|
||||
onMounted(() => {
|
||||
if (!labels.loaded) void labels.load();
|
||||
if (!savedFilters.loaded) void savedFilters.load();
|
||||
reminders.start(); // foreground reminder delivery while the app is open
|
||||
window.addEventListener("keydown", onKeydown);
|
||||
});
|
||||
onBeforeUnmount(() => window.removeEventListener("keydown", onKeydown));
|
||||
onBeforeUnmount(() => {
|
||||
reminders.stop();
|
||||
window.removeEventListener("keydown", onKeydown);
|
||||
});
|
||||
|
||||
const currentLabelId = computed(() => (route.name === "label" ? String(route.params.id) : null));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user