Merge two singleton location managers into a unified LocationStateManager:
- CoreLocation permissions and channel computation
- Channel selection and teleport state tracking
- Bookmark persistence and friendly name resolution
- Reverse geocoding (shared, deduplicated)
Provides backward-compatible typealiases so existing code continues to work:
- typealias LocationChannelManager = LocationStateManager
- typealias GeohashBookmarksStore = LocationStateManager
Reduces 4 location-related files to 3 (keeping LocationNotesManager and
GeohashParticipantTracker separate due to different lifecycles).
Files: 2 deleted, 1 created (~525 lines -> ~420 lines)
- Extend MessageDeduplicator with configurable maxAge/maxCount params
- Add timestampFor() method for content key time-window checks
- Add record() method to store entries with specific timestamps
- Replace ChatViewModel's custom contentLRU implementation with MessageDeduplicator
- Remove ~35 lines of duplicate LRU code from ChatViewModel
This consolidates 2 separate deduplication implementations into one
reusable, thread-safe component.
Add proper error logging for Bech32 decode failures instead of silently
returning. This improves debuggability by making it clear when and why
npub decoding fails for favorite notifications, delivery acks, and read
receipts.
The previous empty catch blocks made it difficult to diagnose issues
with malformed or invalid npub addresses. Now all decoding errors are
properly logged with context about which operation failed.