Commit Graph
100 Commits
Author SHA1 Message Date
jack 1cf4ea9e57 Allow file fragments to account for protocol overhead 2025-10-17 22:43:35 +02:00
jackandislam 830f7ee4b8 Limit PhotosPicker to iOS only to fix CI
PhotosPickerItem has SDK availability issues on macOS in CI.
Change PhotosPicker from canImport(PhotosUI) to os(iOS) only.

macOS users can still import images via file importer (.fileImporter).
This is actually cleaner as macOS file picker is more familiar to users.

Fixes CI build failures.
2025-10-15 17:37:19 +01:00
jackandislam c8768c32b8 Add proper availability checks for PhotosPickerItem
PhotosPickerItem requires iOS 16+ / macOS 13+ but canImport(PhotosUI)
succeeds on older macOS versions. Add compiler version check to ensure
PhotosPicker code only compiles when actually available.

This fixes CI build failures on older macOS environments.
2025-10-15 17:37:19 +01:00
jackandislam 1352484491 Fix remaining compilation issues after rebase
- Fix PhotosUI import order (must be after platform imports)
- Fix Data.WritingOptions.atomic reference
- Add identity derivation caching to NostrIdentityBridge
- Fix all remaining PeerID type conversions in ChatViewModel
- Fix ContentView body structure to use main's VStack layout
- Fix PaymentChipView API usage (now uses PaymentType enum)

Build and tests now passing.
2025-10-15 17:37:19 +01:00
jackandislam ef396936a3 Fix post-rebase compilation errors
- Remove duplicate NostrIdentityBridge and Bech32 from NostrIdentity.swift (now in separate files)
- Add caching to NostrIdentityBridge.deriveIdentity() for performance
- Remove duplicate NotificationStreamAssembler from BLEService.swift
- Remove duplicate function declarations in BLEService.swift
- Remove duplicate DeliveryStatusView and PaymentChipView from ContentView.swift
- Fix PeerID type conversions throughout (use .id for String, PeerID(str:) for wrapping)
- Update ContentView body to use main's simple VStack structure
- Fix NostrIdentityBridge instance method calls
- Remove privateChatView (replaced with sheet-based UI in main)

Build and tests passing (137/139 tests pass).
2025-10-15 17:37:19 +01:00
jackandislam c3ce32ad07 Fix critical security issues in fragment reassembly and file cleanup
Fragment Reassembly Race Condition (CRITICAL):
- Wrap all incomingFragments/fragmentMetadata access in collectionsQueue.sync
- Prevents concurrent modification crashes from multi-threaded access
- Minimizes lock contention by doing heavy work (reassembly/decode) outside locks
- Add upper bound check: reject fragments with total > 10,000 (DoS prevention)
- Add cumulative size validation before storing fragments (memory DoS prevention)

File Cleanup Path Traversal (CRITICAL):
- Use NSString.lastPathComponent to extract filename safely
- Prevents directory traversal attacks via malicious filenames
- Add path prefix validation before file deletion
- Now checks both incoming and outgoing directories (fixes disk leak)

Additional Protections:
- Fragment assemblies now limited by both count (128) and cumulative bytes (1MB)
- Explicit checks for "." and ".." filenames in cleanup
- Defense-in-depth: multiple validation layers
2025-10-15 17:37:19 +01:00
jackandislam d7ca99ae5d Optimize voice note codec to 16 kHz / 20 kbps for smaller file sizes
- Reduce sample rate from 44.1 kHz to 16 kHz (telephony standard)
- Lower bitrate from 32 kbps to 20 kbps
- Results in ~37% file size reduction (~150 KB/min vs 240 KB/min)
- Increases max voice note length from 4.4 to 7 minutes over 1 MiB BLE limit
- Maintains excellent voice quality using native AAC-LC codec
2025-10-15 17:37:19 +01:00
jackandislam b25f0d9f63 Remove debug print statements from sendMessage 2025-10-15 17:37:19 +01:00
jackandislam abb998d809 macOS: Focus message input on launch instead of nickname field 2025-10-15 17:37:19 +01:00
jackandislam d71befd8b7 Complete all translations to 100% and fix auto-extraction
- Mark non-localizable strings with Text(verbatim:) to prevent extraction
- Update UI strings to lowercase per style guide (open, save, close, recording)
- Add complete translations for all 29 languages (194/194 strings at 100%)
- Remove empty/duplicate entries (@, bitchat/, Open, Recording %@)
- Add proper localization comments for all user-facing strings
2025-10-15 17:37:19 +01:00
jackandislam 78c4bed1ad Fix infinite render loop and apply all security fixes
CRITICAL BUG FIX - Infinite Render Loop:

Root Cause: Duplicate view identity in ContentView.swift:368
  ForEach(messageItems) { item in  // Already uses item.id via Identifiable
      messageRow(...)
          .id(item.id)  //  REDUNDANT modifier caused identity re-evaluation loop
  }

When @Published properties updated, SwiftUI re-evaluated .id() → appeared as
'new' identity → triggered re-render → infinite loop. Caused UI freezes,
keyboard failures, and 100% CPU usage.

Fix: Remove redundant .id() modifier - ForEach already has stable identity.

PERFORMANCE FIXES:

1. Waveform Cache Deadlock (Waveform.swift)
   - Removed nested queue.async(barrier) on cache hits
   - Was causing task saturation and potential deadlocks

2. Async Send Pattern (ContentView.swift)
   - Clear input immediately, defer actual send to next runloop
   - Prevents blocking current event handler

3. Proper Swift Concurrency (VoiceNoteView.swift)
   - Switch from .onAppear + DispatchQueue to .task
   - Cleaner async/await pattern for loading

4. Remove Redundant objectWillChange (ChatViewModel.swift)
   - @Published already triggers updates automatically
   - Explicit send() was causing double update cycles

SECURITY FIXES (C1-C5, H1-H2):

C1. Path Traversal Protection (BLEService.swift)
    - Unicode normalization, null byte removal
    - Replace ALL path separators, reject dotfiles
    - Validate paths don't escape directory

C2. Integer Overflow (BitchatFilePacket.swift)
    - Use UInt64 for TLV parsing, safe Int conversion

C3. MIME Validation (BLEService.swift)
    - Whitelist: JPEG, PNG, GIF, WebP, M4A, MP3, WAV, OGG, PDF
    - Magic byte validation for all types
    - Lenient on M4A (platform variations)

C4. Compression Bomb (BinaryProtocol.swift)
    - Ratio validation <= 50,000:1
    - Defense-in-depth with 1MB size cap

C5. TOCTOU Race (ChatViewModel.swift)
    - Direct removeItem without fileExists check

H1. File Size Validation (ChatViewModel, ImageUtils)
    - Check attributes BEFORE Data(contentsOf:)
    - Prevents memory exhaustion

H2. Metadata Stripping (ImageUtils.swift)
    - Remove ALL metadata keys from JPEG encoding
    - Only compression quality set
    - Protects GPS/EXIF/device info privacy

RESULT:
 No render loops
 Works with Xcode debugger
 Voice notes display properly
 All security vulnerabilities fixed
 164 tests passing

Production ready.
2025-10-15 17:37:19 +01:00
jackandislam c52a2a7772 Ensure /clear and panic triple-tap delete media files
Fix: /clear command and panicClearAllData() now properly delete media files

1. /clear (triple-tap on chat):
   - Deletes outgoing media (voice notes, images, files)
   - Conservative: only our sent media, preserves received media
   - Runs in background to avoid UI freeze

2. panicClearAllData() (triple-tap on bitchat/ header):
   - Deletes ALL media files (incoming + outgoing)
   - Removes entire files directory and recreates structure
   - Ensures complete data wipe for emergency scenarios

Both operations run async on .utility queue to prevent blocking UI.
2025-10-15 17:37:19 +01:00
jackandislam 3df0aa0cc4 Make voice note loading completely lazy with deferred initialization
Aggressive performance optimization to prevent UI freezes:

Problem: Even with async loading, creating 10+ VoiceNotePlaybackController
instances simultaneously (when scrolling past multiple voice notes) spawned
20+ concurrent background tasks, potentially starving main thread.

Solution - Ultra-lazy loading:
1. VoiceNotePlaybackController.init() now does ZERO work
   - No duration loading
   - No player creation
   - Instant initialization

2. Duration loaded on-demand via public loadDuration() method
   - Called from VoiceNoteView.onAppear after 150ms delay
   - Reduced priority: .utility instead of .userInitiated
   - Guard prevents duplicate loading

3. Waveform loading also deferred 150ms
   - Gives UI time to settle after message appears
   - Prevents task storms when multiple voice notes appear

This spreads the work over time instead of all at once.
2025-10-15 17:37:19 +01:00
jackandislam 46caded099 Cache geohash identity in ChatViewModel to prevent crypto during rendering
Additional optimization for location channels (voice notes are mesh-only,
but this helps with text message rendering in geohash channels):

- Add cachedGeohashIdentity to avoid deriveIdentity calls during rendering
- Check cache before falling back to crypto derivation
- Reduces main thread crypto work in location channels
2025-10-15 17:37:19 +01:00
jackandislam a04ac9dabd Cache Nostr identity derivation to prevent crypto during view rendering
Critical performance fix:

Problem: formatMessageHeader() called deriveIdentity(forGeohash:) during
every SwiftUI render for every media message. Each call performed:
- Keychain I/O (getOrCreateDeviceSeed)
- HMAC-SHA256 computation
- Up to 10 secp256k1 key validations (elliptic curve crypto)

With multiple media messages, this resulted in 100s of milliseconds of
blocking crypto on main thread per render cycle.

Solution: Add thread-safe cache for derived identities
- Check cache before expensive crypto operations
- NSLock protects concurrent access
- Identity is deterministic per geohash, so caching is safe

This eliminates crypto from the hot rendering path.
2025-10-15 17:37:19 +01:00
jackandislam 1825d115bc Eliminate disk I/O from SwiftUI view rendering path
Critical performance fix for UI freezes when receiving media:

Problem: mediaAttachment(for:) was called during every SwiftUI render,
performing synchronous disk I/O on main thread:
- FileManager.fileExists() called 2-6x per message (checking subdirs)
- applicationFilesDirectory() creating directories on every call
- With multiple media messages, this meant 20-100+ disk ops per render

Solution:
1. Remove fileExists checks - construct URLs directly
   - Files are validated during playback/display (fail gracefully if missing)
   - Sender determines subdirectory (outgoing vs incoming)

2. Cache applicationFilesDirectory() result
   - Static cache prevents repeated FileManager.url() calls
   - Directory created only once

3. Remove redundant playback.replaceURL() in VoiceNoteView.onAppear
   - Controller already initialized with correct URL

This eliminates ALL disk I/O from the view rendering hot path.
2025-10-15 17:37:19 +01:00
jackandislam 9754881af8 Fix memory leaks and post-playback freeze
Fixes:
1. Post-playback freeze: audioPlayerDidFinishPlaying now dispatches to main
   thread before updating @Published properties (Swift concurrency violation)

2. Unbounded waveform cache: Implement LRU eviction with 20-entry limit
   - Track last access time for each cached waveform
   - Evict oldest entry when cache is full
   - Prevents unlimited memory growth as voice notes accumulate

3. Audio buffer memory leaks: Wrap computeWaveform in autoreleasepool
   - AVAudioPCMBuffer allocations are autoreleased
   - Pool ensures buffers are freed promptly

4. Image processing memory: Add autoreleasepool around compression loops
   - Each jpegData() call creates temporary objects
   - Inner pool per iteration prevents memory spikes during quality search

Memory should now remain stable during extended use.
2025-10-15 17:37:19 +01:00
jackandislam 59cc857fde Fix UI freeze when receiving voice notes
Problem: AVAudioPlayer initialization in VoiceNotePlaybackController.init()
was running synchronously on main thread during view creation, blocking
UI for 50-200ms per voice note.

Solution:
- Remove eager preparePlayer() call from init
- Load duration asynchronously on background queue
- Player is only prepared when playback is actually requested via ensurePlayerReady()

This prevents UI freezes when voice notes appear in the chat.
2025-10-15 17:37:19 +01:00
jackandislam f0ca1b27c2 Fix critical issues from PR #681 review
Critical fixes:
- BinaryProtocol: Return nil for unknown versions (prevents buffer underflows)
- Add BinaryProtocol.Offsets struct to centralize magic numbers
- Replace magic offset calculations with named constants

Security/Privacy:
- FileAttachmentView: Use url.lastPathComponent instead of url.path
  (prevents exposing full system paths)

Documentation:
- Fix compression algorithm documentation (zlib, not LZ4)

All tests passing.
2025-10-15 17:37:19 +01:00
jackandislam 5beff8b4dc Fix binary protocol test fixtures 2025-10-15 17:37:19 +01:00
jackandislam ba49b885bb Reset BLE assembler on stalled fragment trains 2025-10-15 17:37:19 +01:00
jackandislam ac10e906c0 Drop attachment ceilings to 1 MiB and bump release version 2025-10-15 17:37:19 +01:00
jackandislam 119e882574 Guard peer map reads on BLE message path 2025-10-15 17:37:19 +01:00
jackandislam 0acbbdf2e3 Restore BLE broadcasts when notify buffer is saturated 2025-10-15 17:37:19 +01:00
jackandislam 40fe0c8ba5 Fix cleanupLocalFile lookup 2025-10-15 17:37:19 +01:00
jackandislam 7593053137 Resolve image/voice path handling 2025-10-15 17:37:19 +01:00
jackandislam 4dde063027 Hide absolute paths in media messages 2025-10-15 17:37:19 +01:00
jackandislam 8c4fead945 Stub file transfer methods in mock 2025-10-15 17:37:19 +01:00
jackandislam 2543277755 Stub file transfer methods in mock 2025-10-15 17:37:19 +01:00
jackandislam a8ce4cbf64 Use unique transfer identifiers 2025-10-15 17:37:19 +01:00
jackandislam 93aa714ed4 Preserve packet version when signing 2025-10-15 17:37:19 +01:00
jackandislam 9c7bf26e13 Fix CFMutableData handling 2025-10-15 17:37:19 +01:00
jackandislam c29c7d83fe Target image byte size across platforms 2025-10-15 17:37:19 +01:00
jackandislam 7f743d48fe Normalize mac JPEG color space 2025-10-15 17:37:19 +01:00
jackandislam 27c39332d5 Strip metadata in mac image encoding 2025-10-15 17:37:19 +01:00
jackandislam 53c08d6807 Revert unsupported JPEG option 2025-10-15 17:37:19 +01:00
jackandislam 7efe0a23b1 Align mac image JPEG encoding 2025-10-15 17:37:19 +01:00
jackandislam 8dedc81512 Allow user-selected write access 2025-10-15 17:37:19 +01:00
jackandislam 5cbe9d4aa7 Fix image attachment detection 2025-10-15 17:37:19 +01:00
jackandislam 515fae9e25 Use save panel for mac image export 2025-10-15 17:37:19 +01:00
jackandislam 0946d3921f Keep processed images for outgoing messages 2025-10-15 17:37:19 +01:00
jackandislam 1d40950118 Lowercase image preview buttons 2025-10-15 17:37:19 +01:00
jackandislam b404d48ba6 Reblur images via swipe 2025-10-15 17:37:19 +01:00
jackandislam 2f1ba27d51 Allow long-press reblur on images 2025-10-15 17:37:19 +01:00
jackandislam 23124b36b7 Use Photos picker on mac 2025-10-15 17:37:19 +01:00
jackandislam 3e8d05fa2e Restore mac photo picker access 2025-10-15 17:37:19 +01:00
jackandislam c36b582209 Display recording milliseconds 2025-10-15 17:37:19 +01:00
jackandislam 3c66ca7499 Harden attachment transfer bookkeeping 2025-10-15 17:37:19 +01:00
jackandislam a042576652 Describe microphone usage 2025-10-15 17:37:19 +01:00
jackandislam 3c120042a4 Permit mac media library access 2025-10-15 17:37:19 +01:00
jackandislam 4e3603d5e4 Allow mac microphone access 2025-10-15 17:37:19 +01:00
jackandislam f7ad970a83 Enable mac attachment importers 2025-10-15 17:37:19 +01:00
jackandislam 4cc87633e1 Fix compressed BLE file transfers 2025-10-15 17:37:19 +01:00
jackandislam 2d565ad918 Stop dropping partial BLE frames while assembling notifications 2025-10-15 17:37:19 +01:00
jackandislam b4cb4d36f1 Log incomplete BLE frames for debugging 2025-10-15 17:37:19 +01:00
jackandislam 7fcef2a9cb Add detailed logging for BLE fragment assembly 2025-10-15 17:37:18 +01:00
jackandislam e7dc0e0c5a Let BLE assembler accept large frames up to hard cap 2025-10-15 17:37:18 +01:00
jackandislam 3b2c7d2f73 Add guard to drop oversized BLE notification assemblies 2025-10-15 17:37:18 +01:00
jackandislam 209f926990 Revert "Raise BLE notification buffer cap for large file transfers"
This reverts commit b624523af843475db84e4a846db8dcbe824ae408.
2025-10-15 17:37:18 +01:00
jackandislam ef8b509ea5 Raise BLE notification buffer cap for large file transfers 2025-10-15 17:37:18 +01:00
jackandislam 06b5bdb6da Allow file transfers from connected but unverified peers 2025-10-15 17:37:18 +01:00
jackandislam a5a3efebcb Copy imported files before sending to preserve access 2025-10-15 17:37:18 +01:00
jackandislam cd39d8c8c0 Restore iOS file importer for attachments 2025-10-15 17:37:18 +01:00
jackandislam 1046bfec0f Reduce vertical padding between chat rows 2025-10-15 17:37:18 +01:00
jackandislam d8c83e25f4 Tighten spacing above media message bubbles 2025-10-15 17:37:18 +01:00
jackandislam a9fa614416 Gracefully disable mac attachment pickers in sandbox 2025-10-15 17:37:18 +01:00
jackandislam ecbbc23862 Add BLE file transfer support and media UX 2025-10-15 17:37:18 +01:00
jackandGitHub b6d42261d0 Guard peer collision checks with snapshot (#810) 2025-10-15 16:12:16 +02:00
3479c7d5df Fix people sheet dismiss gestures (#803)
* Allow closing people sheet from X and swipe

* Swipe right to return from DM to people list

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-14 21:11:44 +02:00
8a0727fcf7 Guard BLE link state lookups on BLE queue (#805)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-14 21:11:07 +02:00
6588861e34 Align gossip sync stale cleanup with Android client (#798)
* Align DM sheet toolbar with people list

* Gate stale gossip announcements

* Remove stale peer messages during gossip cleanup

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-14 13:54:36 +02:00
e3149fa098 Process incoming fragments on message queue (#804)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-14 12:20:39 +02:00
jack 987ba2e694 Fix people sheet close button 2025-10-12 20:18:29 +02:00
615273a63e Align DM sheet toolbar with people list (#795)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-12 19:53:08 +02:00
d994ccf012 Fix send button tap responsiveness and sidebar drag jitter (#783)
Restructured ContentView layout to prevent sidebar from covering input box
and removed gesture conflicts that caused jitter during slow drags.

Changes:
- Moved sidebar overlay to only cover messages area, not input box
- Input box now always accessible below sidebar (not covered by overlay)
- Removed blocking drag gesture from mainChatView
- Changed sidebar gesture from simultaneousGesture to gesture for priority
- Removed animation-disabling transactions that amplified touch noise
- Removed 2pt threshold checks that caused visible jumps

Result: Send button taps immediately, sidebar slides smoothly without jitter.

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-09 23:45:05 +02:00
0f23ed0a99 Location notes: fix performance and UI issues (#774)
* Location notes: fix performance and UI issues

Performance fixes:
- Add Set-based duplicate detection (O(1) vs O(n) lookup)
- Eliminates lag when receiving 200+ notes during EOSE

Correctness fixes:
- Fix optimistic echo timestamp to match signed event timestamp
- Add echo IDs to noteIDs set for consistency

UI improvements:
- Remove duplicate "loading recent notes" text in header
- Simplify toolbar icon color logic for immediate green indication
- Icon now reliably turns green when notes exist in geohash

Tests: All 3 LocationNotes tests passing

* Location notes: add remaining robustness fixes

Additional improvements:
- Align counter/manager limits to 200 (prevents showing count higher than displayable)
- Set loading state before clearing notes to eliminate UI flicker on geohash change
- Add geohash validation for building-level precision (8 valid base32 chars)
- Add defensive 500-note memory cap with automatic trimming
- Clear stale notesGeohash state on sheet dismiss

Tests:
- Fix test geohashes to use valid base32 characters
- All 3 LocationNotes tests passing

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-07 12:36:54 +02:00
c583949031 Fix QR verification sending multiple notifications (#773)
The camera scanner was continuously detecting the same QR code (10-30+ times/second), causing multiple verification notifications to be sent. This happened because:

1. AVCaptureMetadataOutput fires repeatedly while QR is visible
2. Each detection triggered a new verification flow
3. After receiving response, pendingQRVerifications was cleared, allowing duplicate scans

Changes:
- Add deduplication using lastValid state to ignore re-scans of same QR code
- Only set lastValid after successful verification initiation
- Add onSuccess callback to close scanner after successful scan
- Automatically return to "My QR" view after verification starts
- Apply same logic to both iOS camera and macOS manual input paths

This ensures exactly one verification request per scan session.

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-07 11:32:57 +02:00
7149182c56 Fix ghost peers and stale messages from gossip sync (#766)
Problem:
- Ghost peers from yesterday appeared on app restart
- Old messages resurfaced after restarting
- Peers running 24+ hours synced stale data to restarting peers

Root causes:
1. GossipSyncManager stored packets indefinitely (no time limit)
2. handleAnnounce/handleMessage had no timestamp validation
3. Relayed announces from other peers could be arbitrarily old

Solution (defense in depth):
- Added 15-minute age window to GossipSyncManager config
- Gossip storage rejects expired packets at ingestion
- Gossip sync responses filter out expired packets
- GCS payload building excludes expired packets
- Periodic cleanup removes expired announcements/messages
- handleAnnounce rejects stale announces before processing
- handleMessage rejects stale broadcast messages before processing

This prevents ghost peers from appearing on restart and ensures
only recent mesh state is synchronized between peers.

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-07 00:56:25 +02:00
b5b05977fb Show Bluetooth permission alerts on launch and foreground (#765)
* Fix test suite peer ID collisions

Use unique peer IDs for each test suite to prevent global registry
collisions when Swift Testing runs suites in parallel.

- PrivateChatE2ETests: PRIV_* prefix
- PublicChatE2ETests: PUB_* prefix
- Update all peer ID references to use actual instance IDs

This fixes the race condition where simplePublicMessage() was receiving
duplicate deliveries due to registry contamination.

* Add Bluetooth permission & state alerts on launch and foreground

Wire up existing Bluetooth alert infrastructure to show notifications
when Bluetooth is off, unauthorized, or unsupported.

Changes:
- Add didUpdateBluetoothState() to BitchatDelegate protocol
- BLEService now notifies delegate when Bluetooth state changes
- ChatViewModel implements delegate method to show alerts
- Check Bluetooth state on app launch (after 100ms delay)
- Check Bluetooth state when app comes to foreground
- Add getCurrentBluetoothState() method to BLEService

The UI alert already existed but wasn't wired up. Now users will see
appropriate alerts for:
- Bluetooth turned off
- Bluetooth permission denied
- Bluetooth unsupported on device

Alert includes a button to open Settings on iOS.

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-06 22:47:11 +02:00
af6703cf24 Fix test suite peer ID collisions (#764)
Use unique peer IDs for each test suite to prevent global registry
collisions when Swift Testing runs suites in parallel.

- PrivateChatE2ETests: PRIV_* prefix
- PublicChatE2ETests: PUB_* prefix
- Update all peer ID references to use actual instance IDs

This fixes the race condition where simplePublicMessage() was receiving
duplicate deliveries due to registry contamination.

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-06 22:46:45 +02:00
jack faae625e53 Add shared macOS scheme to match iOS scheme 2025-10-02 11:59:46 +02:00
jackandGitHub ea72212f66 Prune unused validation helpers (#701) 2025-10-01 13:29:09 +02:00
jack 2ffa709cca Bump version to 1.4.4 2025-09-30 13:14:26 +02:00
jackandGitHub b2214e30f5 Remove unused favorites and notification helpers (#693) 2025-09-30 12:44:46 +02:00
jackandGitHub 85063e9359 Optimize private chat deduplication (#694) 2025-09-30 12:37:48 +02:00
b873b19104 Add new languages (#700)
* Fix establishing encryption typo

* Add Bengali localizations

* Add Hindi localizations

* Add Turkish localizations

* Add Portuguese (Portugal) localizations

* Add widespread localization coverage

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-30 12:31:29 +02:00
f5caa1751a Add base localization infrastructure and externalize strings (#670)
* Add base localization infrastructure and externalize strings

* Add Spanish localization scaffolding with translations

* Add machine translations for expanded locales

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-24 15:12:42 +02:00
jack de906cb97c Refresh typography and channel sheet styling 2025-09-24 12:32:11 +02:00
1fd2da18f5 Improve BLE relay reliability (#665)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-23 21:09:22 +02:00
c49a1b264e Support Dynamic Type across chat surfaces (#664)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-23 19:56:16 +02:00
3a94b57341 Fix BLE stream crashes and gossip sync races (#663)
* Handle long BLE packets safely

* Keep BLE stream aligned after partial drops

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-23 14:06:13 +02:00
f8f780d2d6 Refine location notes UI and align sheet layouts (#660)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-21 14:56:20 +02:00
jackandGitHub c837afb818 Remove unused handshake coordinator and identity placeholders (#656) 2025-09-21 13:20:21 +02:00
jack d1e5ce21a7 Enable default relays when location permission granted 2025-09-21 12:43:27 +02:00
jack 50ae8da5f9 Bump marketing version to 1.4.2 2025-09-16 08:16:21 -07:00
54bb812469 Gate relays on mutual favorites and add Tor toggle (#631)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-16 08:12:51 -07:00
jack 56e7324069 Improve Tor dormant resume and restart flow 2025-09-15 23:08:29 +02:00
1733dda6cd Ignore self when presenting message actions (#625)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-15 21:58:39 +02:00
00ff5fd31c Refine panic mode to regenerate identities immediately (#624)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-15 21:39:39 +02:00
9cbdb0a764 Gate Tor/Nostr start behind permissions or mutual favorites; add clean shutdown + robust gating (#619)
- Add NetworkActivationService to permit Tor/Nostr only when location is authorized OR at least one mutual favorite exists.
- Gate TorManager.startIfNeeded/ensureRunningOnForeground behind a global allowAutoStart flag.
- Always stop Tor on background for deterministic restarts; rebuild sessions on foreground when allowed.
- NostrRelayManager respects the gate in connect/ensureConnections/subscribe/send/connectToRelay and skips reconnection when disallowed.
- Symmetric shutdown when conditions become disallowed: disconnect relays and stop Tor.
- Fix double-start by avoiding restart if Tor is already ready; prevent background thrash.
- Improve UX: post "starting tor…" via TorWillStart, and "tor started…" on initial ready; keep existing restart messages.

Rationale: Avoid starting Tor/relays when the user has no location permission and no mutual favorites, and ensure a clean, predictable lifecycle (no stale sockets, no double starts).

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-15 16:46:49 +02:00