Skip to content

feat: VoiceKeeper new features — keyboard UX, sort, default filter, checkboxes, export, acronym validation - #48

Merged
End2EndAI merged 17 commits into
mainfrom
feature/voicekeeper-new-features
Apr 2, 2026
Merged

feat: VoiceKeeper new features — keyboard UX, sort, default filter, checkboxes, export, acronym validation#48
End2EndAI merged 17 commits into
mainfrom
feature/voicekeeper-new-features

Conversation

@End2EndAI

@End2EndAI End2EndAI commented Mar 27, 2026

Copy link
Copy Markdown
Owner

Summary

New features and polish across the VoiceKeeper app:

  • Keyboard & edit UX — keyboard no longer covers content while editing; edit mode opens without auto-focusing; long titles wrap instead of truncating
  • Export / Copy — share button in note view opens the native share sheet; long-pressing a note card copies title + content to clipboard
  • Action items — notes displayed as interactive checkboxes (tap to check, remove button per item, checked items below with strikethrough); no auto-edit mode; inline "+ Add item" row
  • Sort notes — sort picker (newest, oldest, A→Z, Z→A, manual order); active sort shown in home subtitle row; manual order is the default
  • Drag-to-reorder — dedicated reorder mode toggle in the header (≡ button, only visible in Manual order); drag handles appear per card; order persists across sessions
  • Default tag filter — set a default tag in Settings; home screen opens pre-filtered to that tag
  • Acronym validation — after transcription, uncertain terms are flagged for review; confirmed corrections reused in future notes
  • AI auto-tagging limited to 1 tag per note (manual tagging remains unlimited)
  • Tag picker on text note creation — select tags before saving a text note

Migrations

# File Change
019 019_default_tag.sql default_tag_id column on user_preferences
020 020_validated_terms.sql New user_validated_terms table with RLS

Test plan

  • Edit a note — keyboard doesn't cover content; edit mode active but keyboard not shown on open
  • Long-press a note card — "Copied!" badge appears, content is in clipboard
  • Tap share in note view — native share sheet opens
  • Open an action items note — checkboxes render correctly; tap to check, remove, add item
  • Sort picker — changing sort reorders notes; Manual order is the default on fresh install
  • Tap ≡ in header (Manual order mode) — drag handles appear; drag to reorder; order persists after restart
  • Create a text note — tag picker shown at bottom; selected tags applied on save
  • Record a note with autotagging enabled — only 1 tag assigned by AI
  • Settings → set a default tag — reopen app, list pre-filtered to that tag
  • Record a note with an acronym — validation modal appears; corrections reused in future recordings

🤖 Generated with Claude Code

@vercel

vercel Bot commented Mar 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
voicekeeper Ready Ready Preview, Comment Apr 2, 2026 5:14am

@github-actions

github-actions Bot commented Mar 27, 2026

Copy link
Copy Markdown

📱 Preview Update Ready

Branch: pr-48
Update: View on Expo

Scan to open in Expo Go

QR Code

Open the app on your device and scan this QR code, or open the Expo Go app and navigate to the update.

@End2EndAI

Copy link
Copy Markdown
Owner Author

Add a ticket : enabled or not acronyme détection. And also auto save the note after recording (for biking or else)

End2EndAI and others added 9 commits April 2, 2026 05:19
…rt, edit-by-default

- Wrap note editor in KeyboardAvoidingView so keyboard never covers text (#1, #8)
- Set isEditing=true by default without auto-focusing textarea (#9)
- Make title TextInput multiline with lineHeight:34 so long titles wrap (#8)
- Add native Share sheet via React Native Share API — share button in view mode (#7)
- Add '+ Add item' row to ActionItemsList with inline TextInput for action_items format (#4)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add NoteSort type (date_desc/asc, title_asc/desc); server-side ordering in fetchNotes (#5)
- Sort picker bottom-sheet modal in home screen header with active checkmark (#5)
- Store defaultTagId in user_preferences via Supabase upsert (migration 019) (#6)
- PreferencesContext exposes defaultTagId/setDefaultTagId; home screen applies it on mount (#6)
- setDefaultTagId service function for Supabase persistence (#6)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a tag pill selector in the Tags settings section so users can tap any
tag (or None) to set it as their landing filter — persists across sessions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After Whisper transcribes audio, a GPT-5-nano call flags low-confidence
terms (acronyms, proper nouns, brand names). A bottom-sheet modal shows
each uncertain term with its suggested correction; users can edit or skip.
Confirmed corrections are saved to user_validated_terms (migration 020)
and injected into future formatting prompts so the LLM uses the right spelling.

- detectUncertainTerms() in edge function: post-transcription GPT pass
- validated_terms injected into buildSystemPrompt for format_only mode
- AcronymValidationModal: editable pill list with skip-per-term support
- saveValidatedTerms / loadValidatedTerms services with Supabase upsert
- recording/[id].tsx pauses auto-advance for modal when terms are found

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AcronymValidationModal: deduplicate uncertain terms by original field
  to prevent duplicate React keys and repeated entries in the modal
- services/notes: add 'id' as secondary sort key in all fetchNotes cases
  to ensure stable ordering when primary sort values are equal
- NotesContext: persist sort preference to AsyncStorage so it survives
  app restarts instead of always resetting to 'date_desc'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… detection

Switch back from json_object to json_schema with strict mode enabled.
Previous strict schema failed silently due to: missing strict:true,
invalid type:["string","null"] syntax (must use anyOf), unsupported
maxItems, and missing additionalProperties:false at each level.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The handleReformat function in note/[id].tsx was calling formatTranscription
without loading or passing the user's saved validated terms, so previous
acronym corrections were not applied when reformatting an existing note.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New screen at /acronyms listing all user-confirmed term corrections
- Each row shows the original (misheard) term → corrected spelling
- Per-term remove button with confirmation dialog
- "Clear all" button in the header to wipe all corrections at once
- Empty state with explanation of how the feature works
- Accessible from Settings > Notes > Saved Terms
- Added deleteValidatedTerm / deleteAllValidatedTerms to validatedTerms service

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e not re-flagged

- transcribeRecording() now accepts knownTerms and forwards them to the edge function
- Both auto-advance and manual transcribe paths load existing validated terms before calling
- Edge function detectUncertainTerms() skips terms already confirmed by the user
- Formatting system prompt clarified: LLM now told to replace misrecognized spellings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The header had three items (sort pill + "Recordings" text + settings circle)
that overflowed on standard screen widths, pushing the settings button
off-screen. Convert Recordings to a compact 44x44 icon button (three
horizontal bars) matching the settings button style. Both icon buttons
now share the same iconButton/iconButtonPressed style.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Header:
- Move sort control into subtitle row ("10 notes · ↕ Title A→Z"), tappable
- Header right side now has only 2 icon buttons (recordings + settings) — no more overflow

Action items:
- Open in view/checkbox mode by default (not text edit mode)
- Add ✕ remove button per item
- Unchecked items rendered first; checked items grouped below with a divider
- Checked items keep strikethrough; unchecked/checked split updates live

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a 'Manual order' sort option. When selected, notes display with
drag handles on the right. Dragging reorders the list and persists the
order to AsyncStorage. New notes are appended at the end of the saved order.

- types/index.ts: add 'manual' to NoteSort
- services/notes.ts: manual sort fetches by date_desc (order applied client-side)
- contexts/NotesContext.tsx: manualOrder state, setManualOrder, filteredNotes applies saved order
- components/DraggableNoteList.tsx: PanResponder-based drag-to-reorder list
- components/NoteGrid.tsx: conditionally renders DraggableNoteList when draggable=true
- app/index.tsx: wire up Manual sort option and pass draggable/onReorder to NoteGrid

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Long press a note card to copy title + content to clipboard; card highlights
  with a 'Copied!' badge for 1.5 s (expo-clipboard)
- AI auto-tagging limited to 1 tag per note (was up to 3); manual tagging
  remains unlimited
- Text note creation screen now shows a tag picker at the bottom; selected tags
  are applied on save

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The session reset setState was missing manualOrder, causing it to be
undefined. Added defensive fallback in filteredNotes useMemo as well.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use React state for scrollEnabled instead of setNativeProps (works on web)
- Add Capture variants of PanResponder handlers to intercept events before
  browser scroll takes over
- Default sort changed from date_desc to manual; persisted via AsyncStorage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Drag handles only shown when reorder mode is active (toggle button in
  header, only visible when sort is Manual order)
- Toggle button highlights with primary color when active
- Removing RefreshControl from DraggableNoteList and adding bounces=false
  + overScrollMode=never to prevent pull-to-refresh triggering during drag

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@End2EndAI
End2EndAI merged commit 3e5e1af into main Apr 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant