ADD - notes app

This commit is contained in:
Eichenholz
2026-08-04 11:41:56 +02:00
parent dfc358f85a
commit 8090dbd5ab
11 changed files with 482 additions and 5 deletions
+26
View File
@@ -0,0 +1,26 @@
import { describe, expect, it } from 'vitest'
import { parseNotes } from './notes'
describe('notes persistence', () => {
it('returns valid notes and ignores malformed entries', () => {
const valid = {
body: 'Meet at Mission Row.',
createdAt: 10,
id: 'note-1',
pinned: true,
title: 'Shift briefing',
updatedAt: 20,
}
expect(parseNotes(JSON.stringify([valid, { id: 'broken' }]))).toEqual([
valid,
])
})
it('recovers from missing or invalid storage', () => {
expect(parseNotes(null)).toEqual([])
expect(parseNotes('{invalid')).toEqual([])
expect(parseNotes('{}')).toEqual([])
})
})
+48
View File
@@ -0,0 +1,48 @@
export const NOTES_STORAGE_KEY = 'sky_phone.notes.v1'
export type Note = {
body: string
createdAt: number
id: string
pinned: boolean
title: string
updatedAt: number
}
export type NoteDraft = Pick<Note, 'body' | 'title'>
function isNote(value: unknown): value is Note {
if (!value || typeof value !== 'object') return false
const note = value as Partial<Note>
return (
typeof note.body === 'string' &&
typeof note.createdAt === 'number' &&
Number.isFinite(note.createdAt) &&
typeof note.id === 'string' &&
Boolean(note.id) &&
typeof note.pinned === 'boolean' &&
typeof note.title === 'string' &&
typeof note.updatedAt === 'number' &&
Number.isFinite(note.updatedAt)
)
}
export function parseNotes(raw: string | null): Note[] {
if (!raw) return []
try {
const parsed = JSON.parse(raw) as unknown
if (!Array.isArray(parsed)) return []
return parsed.filter(isNote)
} catch {
return []
}
}
export function readNotes(): Note[] {
return parseNotes(window.localStorage.getItem(NOTES_STORAGE_KEY))
}
export function writeNotes(notes: Note[]): void {
window.localStorage.setItem(NOTES_STORAGE_KEY, JSON.stringify(notes))
}
+1
View File
@@ -50,6 +50,7 @@ const DEFAULT_APP_NOTIFICATIONS: Record<
calculator: { enabled: true, sounds: true },
camera: { enabled: true, sounds: true },
clock: { enabled: true, sounds: true },
notes: { enabled: true, sounds: true },
photos: { enabled: true, sounds: true },
settings: { enabled: true, sounds: true },
}