diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 326ae65..b3aea9c 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -66,7 +66,18 @@ "Bash(awk 'NR>=535 && NR<=560 {print NR\": \"$0}' packages/shared/src/components/settings/UserSettingsModal.tsx)", "Bash(awk 'NR>=460 && NR<=480 {print NR\": \"$0}' packages/shared/src/components/settings/UserSettingsModal.tsx)", "Bash(python3 -)", - "Bash(awk 'NR>=525 && NR<=540 {print NR\": \"$0}' packages/shared/src/components/settings/UserSettingsModal.tsx)" + "Bash(awk 'NR>=525 && NR<=540 {print NR\": \"$0}' packages/shared/src/components/settings/UserSettingsModal.tsx)", + "Bash(sqlite3 data/backup.db \".schema\")", + "Bash(sqlite3 data/backup.db \"SELECT COUNT\\(*\\) as message_count FROM messages;\")", + "Bash(sqlite3 data/backup.db \"SELECT * FROM channels LIMIT 5;\")", + "Bash(sqlite3 data/backup.db \"SELECT id, channel_id, author_id, content, created_at, edited_at, deleted_at, replied_to_id FROM messages LIMIT 3;\")", + "Bash(sqlite3 data/backup.db \"SELECT COUNT\\(*\\) as attachment_count, SUM\\(CASE WHEN downloaded = 1 THEN 1 ELSE 0 END\\) as downloaded FROM attachments;\")", + "Bash(sqlite3 data/backup.db \"SELECT id, message_id, filename, size, content_type, local_path FROM attachments LIMIT 3;\")", + "Bash(sqlite3 data/backup.db \"SELECT COUNT\\(*\\) as reaction_count FROM reactions; SELECT COUNT\\(*\\) as embed_count FROM embeds; SELECT COUNT\\(*\\) as author_count FROM authors;\")", + "Bash(sqlite3 data/backup.db \"SELECT * FROM reactions LIMIT 3;\")", + "Bash(sqlite3 data/backup.db \"SELECT * FROM embeds LIMIT 2;\")", + "Bash(sqlite3 data/backup.db \"SELECT id, username, display_name, avatar_url FROM authors LIMIT 5;\")", + "Bash(sqlite3 data/backup.db \"SELECT message_id, content, edited_at FROM message_edits LIMIT 3;\")" ] } } diff --git a/CLAUDE.md b/CLAUDE.md index d603bea..b026fca 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -133,6 +133,7 @@ All platform-specific APIs are accessed via the `usePlatform()` hook: - Push-to-talk: `voiceSettings.inputMode` is `'voice-activity'` (default) or `'push-to-talk'`. Paired with the `voice.pushToTalk` keybind (marked `pressAndHold: true`). `KeybindContext` dispatches `brycord:keybind:voice.pushToTalk:down` / `:up` events — pressAndHold actions never `preventDefault`, so binding PTT to a letter still lets you type. `VoiceContext` reads the settings via the `brycord:voice-settings-changed` window event, listens for the PTT events, and routes them through a configurable release-delay timer before reconciling the LiveKit mic track. All mic-on/mic-off sources (user mute, deafen, server mute, PTT gate) converge on a single `setMicrophoneEnabled` effect - Plaintext cache: `SearchDatabase` has a `plaintext_cache` table (per-channel cap of 500) that persists decrypted message bodies encrypted at rest by the existing search DB key. `SearchContext` exposes `cachePlaintexts` / `getChannelPlaintexts`. `Messages.tsx` seeds the in-memory `decryptionCache` from it on cold channel open (source-scoped on the full ciphertext so edits naturally invalidate), and writes back after each successful decrypt batch. Cuts the "empty bubbles then fill in" wave on app restart - Webcam video: camera publish already lived in `VoiceContext.setCamera` via LiveKit `setCameraEnabled`. Now also propagates `isCameraOn` through `voiceStates.updateState`. `CameraTile` attaches a participant's camera track to a `