fix(keep-notes): sidebar chevron, labels sync, batch org errors, perf guards
- Notebooks: chevron visible when expanded (remove overflow clip), functional expand state - Labels: sync/cleanup by notebookId, reconcile after note move - Settings: refresh notebooks after cleanup; label dialog routing - ConnectionsBadge lazy-load; reminder check persistence; i18n keys Made-with: Cursor
This commit is contained in:
@@ -1,44 +1,53 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { Note } from '@/lib/types';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
const STORAGE_KEY = 'memento-notified-reminders';
|
||||
|
||||
function getNotifiedFromStorage(): Set<string> {
|
||||
try {
|
||||
const raw = sessionStorage.getItem(STORAGE_KEY);
|
||||
return raw ? new Set(JSON.parse(raw)) : new Set();
|
||||
} catch {
|
||||
return new Set();
|
||||
}
|
||||
}
|
||||
|
||||
function persistNotified(ids: Set<string>) {
|
||||
try {
|
||||
sessionStorage.setItem(STORAGE_KEY, JSON.stringify([...ids]));
|
||||
} catch { /* quota exceeded — non-critical */ }
|
||||
}
|
||||
|
||||
export function useReminderCheck(notes: Note[]) {
|
||||
const [notifiedReminders, setNotifiedReminders] = useState<Set<string>>(new Set());
|
||||
const notifiedRef = useRef<Set<string>>(getNotifiedFromStorage());
|
||||
|
||||
useEffect(() => {
|
||||
const checkReminders = () => {
|
||||
const now = new Date();
|
||||
const dueReminders: string[] = [];
|
||||
const newIds: string[] = [];
|
||||
|
||||
for (const note of notes) {
|
||||
if (!note.reminder || note.isReminderDone) continue;
|
||||
if (notifiedRef.current.has(note.id)) continue;
|
||||
|
||||
// First pass: collect which reminders are due
|
||||
notes.forEach(note => {
|
||||
if (!note.reminder) return;
|
||||
const reminderDate = new Date(note.reminder);
|
||||
|
||||
if (reminderDate <= now && !notifiedReminders.has(note.id)) {
|
||||
dueReminders.push(note.id);
|
||||
toast.info("🔔 Reminder: " + (note.title || "Untitled Note"));
|
||||
if (reminderDate <= now) {
|
||||
newIds.push(note.id);
|
||||
toast.info(`🔔 ${note.title || 'Untitled Note'}`, { id: `reminder-${note.id}` });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Second pass: update state only once with all due reminders
|
||||
if (dueReminders.length > 0) {
|
||||
setNotifiedReminders(prev => {
|
||||
const newSet = new Set(prev);
|
||||
dueReminders.forEach(id => newSet.add(id));
|
||||
return newSet;
|
||||
});
|
||||
if (newIds.length > 0) {
|
||||
for (const id of newIds) notifiedRef.current.add(id);
|
||||
persistNotified(notifiedRef.current);
|
||||
}
|
||||
};
|
||||
|
||||
// Check immediately
|
||||
checkReminders();
|
||||
|
||||
// Then check every 30 seconds
|
||||
const interval = setInterval(checkReminders, 30000);
|
||||
|
||||
const interval = setInterval(checkReminders, 30_000);
|
||||
return () => clearInterval(interval);
|
||||
}, [notes]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user