From 165a1c13896019bd4195888bc66ca1db52240d7c Mon Sep 17 00:00:00 2001 From: MikiVL Date: Tue, 5 May 2026 04:49:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20store=20=E8=BD=AF=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=94=B9=E9=80=A0=EF=BC=8C=E6=96=B0=E5=A2=9E=20restoreNote/emp?= =?UTF-8?q?tyTrash/trashNotes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- src/stores/appStore.ts | 49 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/stores/appStore.ts b/src/stores/appStore.ts index 44f82f7..a6c164a 100644 --- a/src/stores/appStore.ts +++ b/src/stores/appStore.ts @@ -6,7 +6,7 @@ interface AppState { notes: Note[] folders: Folder[] activeNoteId: string | null - activeFolderId: string | null | 'all' | 'starred' + activeFolderId: string | null | 'all' | 'starred' | 'trash' searchQuery: string theme: 'light' | 'dark' focusMode: boolean @@ -39,6 +39,9 @@ interface AppState { setSortOrder: (order: 'asc' | 'desc') => void filteredNotes: () => Note[] + restoreNote: (id: string) => Promise + emptyTrash: () => Promise + trashNotes: () => Note[] } export const useAppStore = create((set, get) => ({ @@ -57,10 +60,16 @@ export const useAppStore = create((set, get) => ({ _filteredCache: null, loadAll: async () => { - const [notes, folders] = await Promise.all([ + let [notes, folders] = await Promise.all([ db.notes.orderBy('updatedAt').reverse().toArray(), db.folders.orderBy('order').toArray(), ]) + const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000 + const expired = notes.filter(n => n.deletedAt !== null && Date.now() - n.deletedAt > THIRTY_DAYS) + if (expired.length > 0) { + await db.notes.bulkDelete(expired.map(n => n.id)) + notes = notes.filter(n => !expired.some(e => e.id === n.id)) + } set({ notes, folders, _notesVersion: get()._notesVersion + 1, _filteredCache: null }) // Keep welcome screen as default; only auto-select if already on a real note const cur = get().activeNoteId @@ -104,14 +113,36 @@ export const useAppStore = create((set, get) => ({ }, deleteNote: async (id) => { - await db.notes.delete(id) + const deletedAt = Date.now() + await db.notes.update(id, { deletedAt }) set(s => { - const notes = s.notes.filter(n => n.id !== id) + const notes = s.notes.map(n => n.id === id ? { ...n, deletedAt } : n) const activeNoteId = s.activeNoteId === id ? '__welcome__' : s.activeNoteId return { notes, activeNoteId, _notesVersion: s._notesVersion + 1, _filteredCache: null } }) }, + restoreNote: async (id) => { + await db.notes.update(id, { deletedAt: null }) + set(s => ({ + notes: s.notes.map(n => n.id === id ? { ...n, deletedAt: null } : n), + _notesVersion: s._notesVersion + 1, + _filteredCache: null, + })) + }, + + emptyTrash: async () => { + const trashed = await db.notes.where('deletedAt').above(0).toArray() + const ids = trashed.map(n => n.id) + await db.notes.bulkDelete(ids) + set(s => ({ + notes: s.notes.filter(n => n.deletedAt === null), + activeNoteId: ids.includes(s.activeNoteId ?? '') ? '__welcome__' : s.activeNoteId, + _notesVersion: s._notesVersion + 1, + _filteredCache: null, + })) + }, + toggleStar: async (id) => { const note = get().notes.find(n => n.id === id) if (!note) return @@ -163,7 +194,10 @@ export const useAppStore = create((set, get) => ({ const cacheKey = `${_notesVersion}|${activeFolderId}|${searchQuery}|${activeTag}|${sortBy}|${sortOrder}` if (_filteredCache?.key === cacheKey) return _filteredCache.result + if (activeFolderId === 'trash') return [] + let result = notes + result = result.filter(n => n.deletedAt === null) if (activeFolderId === 'starred') { result = result.filter(n => n.starred) @@ -197,4 +231,11 @@ export const useAppStore = create((set, get) => ({ set({ _filteredCache: { key: cacheKey, result } }) return result }, + + trashNotes: () => { + const { notes } = get() + return notes + .filter(n => n.deletedAt !== null) + .sort((a, b) => (b.deletedAt ?? 0) - (a.deletedAt ?? 0)) + }, }))