Skip to content

feature/local cache#28

Merged
typelets merged 6 commits intomainfrom
feature/local-cache
Nov 1, 2025
Merged

feature/local cache#28
typelets merged 6 commits intomainfrom
feature/local-cache

Conversation

@typelets
Copy link
Copy Markdown
Owner

@typelets typelets commented Nov 1, 2025

Summary

This PR completes the offline-first architecture implementation with significant performance optimizations and bug
fixes:

Performance Optimizations

  • Consolidated SQL queries: Reduced from 5 separate queries to 1 optimized query (~80% reduction in database round
    trips)
  • Database indexing: Added composite indexes for count queries (O(log n) instead of O(n) lookups)
  • Offline caching: Implemented 10s short-lived cache for offline counts to prevent recalculation on every render
  • Code deduplication: Created helper functions to eliminate 112 lines of duplicate code

Bug Fixes

  • Fix folder counts showing 0 when offline (now calculated from SQLite cache)
  • Fix subfolder counts not displaying when navigating into folders
  • Fix race condition in ViewNote causing infinite attachment loading loops
  • Fix infinite error toasts when viewing notes offline
  • Fix attachments button not appearing when viewing notes with attachments

UX Improvements

  • Add 500ms debouncing for network status changes (prevents issues with flaky connections)
  • Add prefetch during master password authentication for instant offline access
  • Add two-stage loading UI: "Securing Your Data" → "Caching Your Data"
  • Add loading spinner to prevent white screen flash during initial load

Security

  • Change default to encrypted cache for better security (decrypt on-demand)
  • Add "Offline Cache Security" documentation in Settings screen
  • Maintain end-to-end encryption throughout offline caching layer

Technical Details

Modified Files:

  • apps/mobile/v1/src/services/api/notes.ts - Optimized count calculations with caching
  • apps/mobile/v1/src/lib/database/index.ts - Added composite indexes
  • apps/mobile/v1/src/screens/ViewNote/index.tsx - Fixed race conditions
  • apps/mobile/v1/src/screens/FoldersScreen.tsx - Added network status debouncing
  • apps/mobile/v1/src/hooks/useMasterPassword.ts - Added prefetch logic
  • apps/mobile/v1/src/components/MasterPasswordDialog/* - Two-stage loading UI

Test Plan

  • Verify folder counts display correctly when offline
  • Verify subfolder counts show when navigating into folders offline
  • Verify attachments button appears for notes with attachments
  • Verify no infinite loops when viewing notes offline
  • Verify prefetch works during login
  • Verify encrypted cache is default setting
  • Run TypeScript type checking (passed)

batalabs and others added 6 commits October 31, 2025 07:15
…ructure

- Moved NotesListScreen.tsx → ListNotes/index.tsx (344 lines)
- Extracted 7 focused components:
     - NoteSkeletonItem: skeleton loading UI
     - FilterSortSheet: filter/sort modal
     - CreateFolderSheet: folder creation modal
     - NoteListItem: individual note rendering
     - SubfoldersList: folder grid/list view
     - NotesHeader: notes section header
     - EmptyState: empty search state
   - Extracted 3 custom hooks:
     - useNotesFiltering: filtering & sorting logic
     - useFolderPaths: folder path calculation
     - useNotesLoader: notes loading & decryption
   - Created utils/noteUtils.ts for shared utilities
   - Fixed TypeScript error in folder-notes.tsx viewType casting
   - Removed all unused imports and styles
## Core Features

### Offline-First Data Layer
- SQLite database for local note and folder caching
- Stale-while-revalidate pattern for instant UI updates
- Conditional HTTP requests (ETag/Last-Modified) to minimize data transfer
- Configurable cache preference: decrypted (instant) vs encrypted (secure)

### Background Sync System
- Mutation queue in SQLite for offline changes
- Auto-sync on network reconnect with race condition protection
- Retry logic with exponential backoff for failed syncs
- Optimistic UI updates with temp IDs for offline note creation

### Network Management
- Network status detection with @react-native-community/netinfo
- Orange floating offline indicator
- Disabled edit/delete when offline (create notes offline enabled)
- Clear user feedback with offline alerts

### User Settings
- Cache preference bottom sheet (replaced toggle)
- "Cache Decrypted" - instant loading, requires master password
- "Cache Encrypted" - maximum security, slightly slower

## Technical Improvements

### API Layer
- Enhanced HTTP client with conditional request support
- Database cache layer with metadata tracking
- Folder and note APIs with offline fallback
- Type-safe SQLite bindings with proper null handling

### UI/UX
- Fixed settings toggle switch positioning (16px → 20px translation)
- Better cache preference explanations with radio buttons
Performance Optimizations:
- Consolidate SQL queries from 5 separate queries to 1 optimized query (~80% reduction)
- Add composite database indexes for count queries (O(log n) instead of O(n) lookups)
- Implement 10s short-lived cache for offline counts to prevent recalculation
- Add helper functions to eliminate code duplication (112 lines deduplicated)

Bug Fixes:
- Fix folder counts not displaying when offline (calculate from SQLite cache)
- Fix race condition in ViewNote attachment loading with proper cleanup
- Fix infinite error toasts when viewing notes offline
- Improve error handling to return complete interfaces

UX Improvements:
- Add 500ms debouncing for network status changes (prevents flaky connection issues)
- Add prefetch during master password authentication for instant offline access
- Add two-stage loading UI: "Securing Your Data" → "Caching Your Data"
- Add loading spinner to prevent white screen flash

Security:
- Change default to encrypted cache for better security (decrypt on-demand)
- Add "Offline Cache Security" documentation in Settings
- Maintain end-to-end encryption throughout
@typelets typelets self-assigned this Nov 1, 2025
@typelets typelets merged commit eb9b344 into main Nov 1, 2025
3 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Nov 1, 2025

🎉 This PR is included in version 1.31.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@sentry
Copy link
Copy Markdown

sentry bot commented Nov 6, 2025

Issues attributed to commits in this pull request

This pull request was merged and Sentry observed the following issues:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants