Commit Graph
77 Commits
Author SHA1 Message Date
jack 1cf4ea9e57 Allow file fragments to account for protocol overhead 2025-10-17 22:43:35 +02:00
islam 2b3264b581 Convert new tests to Swift Testing 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 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 4cc87633e1 Fix compressed BLE file transfers 2025-10-15 17:37:19 +01:00
3d914dcf46 Convert the remaining tests to Swift Testing (#781)
* SwiftTesting: NoiseProtocolTests + BinaryProtocolPaddingTests

* SwiftTesting: `NotificationStreamAssemblerTests`

* SwiftTesting: `NostrProtocolTests`

* SwiftTesting: `BinaryProtocolTests`

* SwiftTesting: `PeerIDTests`

* SwiftTesting: `BLEServiceTests`

* SwiftTesting: `CommandProcessorTests`

* SwiftTesting: `GCSFilterTests`

* SwiftTesting: `GeohashBookmarksStoreTests`

* Remove `peerID` test constants

* Remove PeerID + String interop from tests

* Refactor IntegrationTests to extract state management

* Refactor global state management of MockBLEService

* NoiseProtocolSwiftTests: `actor` -> `struct`

* Remove measurement tests w/ no benchmark

* `NoiseProtocolSwiftTests` -> `NoiseProtocolTests`

* SwiftTesting: `LocationChannelsTests`

* SwiftTesting: `GossipSyncManagerTests`

* SwiftTesting: `LocationNotesManagerTests`

* Global `sleep` function for tests

* SwiftTesting: `IntegrationTests`

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-15 01:04:01 +02:00
b3ec5eeda0 Refactor Noise: Extract files and remove dead code (#806)
* Extract each type to a separate file

* NoiseSessionManager: Remove unused functions

---------

Co-authored-by: jack <212554440+jackjackbits@users.noreply.github.com>
2025-10-15 00:32:44 +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
ad4103bacc Refactor Nostr ID Bridge & Keychain Helper (#796)
* Extract each type to a separate file

* Nostr ID Bridge: Convert static func/vars to instance

* `KeychainHelper` behind a protocol to easily mock

* Update tests with ID Bridge and MockKeychainHelper

---------

Co-authored-by: jack <212554440+jackjackbits@users.noreply.github.com>
2025-10-14 12:26:18 +02:00
IslamandGitHub d371131ad5 Remove MockBluetoothMeshService (#777) 2025-10-09 23:47:01 +02:00
IslamandGitHub 7ec84857eb PeerID 20/n: BLEService’s private functions (#771) 2025-10-07 16:26:17 +02:00
IslamandGitHub 551a843691 PeerID 18/n: BitchatDelegate + Tests (#769) 2025-10-07 16:01:53 +02:00
IslamandGitHub fbc15ea08f SwiftTesting: Enable in GitHubActions + peer uuids (#767) 2025-10-07 12:40:20 +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
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
eb13eec4c5 Swift Testing (#748)
* Swift Testing: `PrivateChatE2ETests` + minor refactor

* Swift Testing: `PublicChatE2ETests`

* Swift Testing: `FragmentationTests`

* Fix MockBLEService init to accept PeerID and remove _testRegister call

* Add peerID property to MockBLEService and fix ttlDecrement test

* Remove duplicate peerID property and fix type comparisons

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-10-06 20:55:52 +02:00
IslamandGitHub 5f44c56a90 PeerID 15/n: Bitchat Message & Packet accept in init (#754) 2025-10-06 17:16:11 +02:00
IslamandGitHub 2673d28686 PeerID 12/n: GossipSyncManager (#751)
* Noise types use PeerID

* Fix tests

* Extract `NoiseSessionManager` into a separate file

* Extract `NoiseSessionState` into a separate file

* Remove `failed` state from `NoiseSessionState`

* Extract `NoiseSessionError` into a separate file

* PeerID 12/n: `GossipSyncManager`
2025-10-05 15:53:57 +02:00
IslamandGitHub 03c357f048 PeerID 11/n: Noise types use PeerID + create separate files (#750)
* Noise types use PeerID

* Fix tests

* Extract `NoiseSessionManager` into a separate file

* Extract `NoiseSessionState` into a separate file

* Remove `failed` state from `NoiseSessionState`

* Extract `NoiseSessionError` into a separate file
2025-10-05 15:51:06 +02:00
IslamandGitHub bdc31d3be3 Don’t auto-register mock BLE services on creation (#746) 2025-10-05 12:36:35 +02:00
IslamandGitHub 8cfee095d3 PeerID 6/n: Unifiy validation (#743) 2025-10-02 13:36:49 +02:00
IslamandGitHub e4ec2ef3fe PeerID 5/n: Ephemeral and Secure Identities (#742) 2025-10-02 13:29:48 +02:00
IslamandGitHub bd11940151 Injectable UserDefaults to fix race condition in tests (#741) 2025-10-02 12:59:48 +02:00
IslamandGitHub 90273cee2d PeerID 4/n: BitchatMessage.senderPeerID + String equality (#739) 2025-10-02 12:57:17 +02:00
IslamandGitHub aeec15f054 Temporarily disable broken tests to catch actual issues (#740) 2025-10-01 14:48:39 +02:00
IslamandGitHub 8d938e8518 PeerID 2/n: Count and hex conversion done with bare (#705) 2025-10-01 13:33:39 +02:00
IslamandGitHub 3183703a63 Fix broken build + uncover localization tests (#702)
* Move LocalizationCatalogTests out of Localization/

SPM is treating all the files under Localization as a resource as per the Package.swift, hence it’s not even building it

* Use a class object vs struct to fix build issue

* Explicitly check that the output is not a l10n key

* Remove skipped test
2025-10-01 13:16:59 +02:00
IslamandGitHub bf712a0610 Refactor peerID - 1/n: Add PeerID + Tests (#688)
* Unify SHA256 hash and hex usages

* Refactor `peerID` - 1/n: Add `PeerID` + Tests
2025-09-30 12:49:36 +02:00
IslamandGitHub 78fb3f1bf6 Unify SHA256 hash and hex usages (#687) 2025-09-30 12:47:16 +02:00
Jonathan BoiceandGitHub f5af00be88 test(localization): squash divergent history to restore clean commit (#695)
- Replace 474/474 sync divergence with a single descriptive commit
- Keep only intended localization test improvements vs main
- Ensure readable history for code review and future merges
2025-09-30 12:45:49 +02:00
Jonathan BoiceandGitHub f67f728d79 Fix broke tests with LocationNotesManagerTests to expect localization key (#699)
* fix(test): update LocationNotesManagerTests to expect localization key

The tests were failing because in the test environment, String(localized:) returns
the localization key instead of the actual localized value. Updated the assertions
to expect 'location_notes.error.no_relays' instead of the English translation
'no geo relays available near this location. try again soon.'

* Fix LocationNotesManager test assertions for localization bundle

- Update test assertions to use String(localized:) to match manager behavior in test environment
- Fixes issue where tests expected localized text but manager returns raw keys in SPM test environment
- Both manager and tests now consistently handle localization bundle differences
- Resolves P1 issue: Keep LocationNotes error messages localized
- All 124 tests now pass after clean build

* SPM: process bitchat/Localizable.xcstrings in main target to fix CLI warning; keep tests' Localization resource.
2025-09-30 12:32:53 +02:00
0f7bcf17ff Refactor: Migrate to Swift String Catalogs (.xcstrings) (#691)
* Automated update of relay data - Sun Sep 21 06:26:33 UTC 2025

* chore(l10n): add empty string catalogs

* chore(l10n): populate string catalogs from legacy resources

* test(l10n): add catalog guardrail suite

* chore(l10n): remove legacy localization files

* fix: Add localization resources to Package.swift targets

- Add .process("Localization") to bitchat target resources
- Add .process("Localization") to bitchatTests target resources
- Resolves Bundle.module resource loading for localization files
- Enables proper localization testing in Swift Package Manager builds

* feat: Add Korean localization and convert to UTF-8 format

Korean Language Support:
- Add complete Korean (ko) localization with 191 strings from PR #686
- Include all app strings: UI, features, system messages, alerts
- Include all share extension strings: status messages, errors
- Verified 100% translation coverage for Korean locale

UTF-8 Format Conversion:
- Convert 23,047 Unicode escape sequences to readable UTF-8 characters
- Transform \u sequences (e.g. \u0625\u063a\u0644\u0627\u0642) to native text (إغلاق)
- Improve maintainability across all 15 supported locales
- Preserve all existing translations while enhancing readability

Locales supported: en, ar, de, es, fr, he, id, it, ja, ko, ne, pt-BR, ru, uk, zh-Hans

* test: Enhance dynamic localization test framework

Dynamic Test Framework:
- Replace hardcoded locale tests with data-driven approach
- Add testLocalizationExpectedValues() for dynamic locale validation
- Add testConfiguredLocalesCompleteness() for coverage verification
- Tests now read configuration from PrimaryLocalizationKeys.json

Expanded Test Coverage:
- Increase from 14 to 33 key validations (135% increase)
- Add critical UI strings: common actions, app info, security, sharing
- Cover 364 total string validations across 15 locales
- Include Korean validation with native Korean expected values

Test Categories Added:
- Common UI: cancel, close, copy actions
- App Info: encryption, offline features, app name
- Bluetooth: permission and settings alerts
- Security: verification badges and actions
- Share Extension: all status and error messages
- Content Actions: accessibility and user actions

Maintains 100% test success rate across all supported locales.

* fix: Convert plural strings to correct xcstrings format

Three plural strings (content.accessibility.people_count,
location_channels.row_title, location_notes.header) were using
incorrect format causing runtime String(format:) errors.

Migrated from stringUnit.variations structure to proper
substitutions.variations format across all 14 languages.

* refactor(l10n): migrate to native String(localized:) APIs

Remove L10n.string wrapper in favor of Swift's native localization APIs.
Migrate 100+ localization call sites to use String(localized:) and String(localized:defaultValue:) with string interpolation.

- Update catalog to use interpolation syntax (\(var)) instead of format specifiers (%@)
- Migrate simple strings to String(localized:)
- Migrate strings with arguments to String(localized:defaultValue:) with interpolation
- Keep format strings for plural substitutions (String(format:locale:))
- Remove bitchat/Utils/Localization.swift

Net result: -407 insertions, +130 deletions across 15 files

* fix(l10n): correct interpolation to use format strings

Interpolation in String(localized:defaultValue:) doesn't work as expected -
the interpolation happens at the call site before localization lookup.

Convert dynamic strings to use String(format:String(localized:),args) pattern:
- Update catalog entries from \(var) syntax to %@ placeholders
- Wrap String(localized:) calls with String(format:locale:) for dynamic values
- Affects 17 strings across 6 files

This fixes UI showing literal "\(geohash)" text instead of actual values.

* chore(l10n): remove invalid catalog entries

Remove auto-extracted literal strings (@, #, ✔︎, @%@, bitchat/) that were
generated without proper localization structure. These caused test
decoding failures.

* fix(l10n): remove unused auto-extracted format string

Remove '%@/%@' key that was auto-extracted by Xcode but never used.
This key only existed in English causing locale parity test failures
across all 13 other languages.

Fixes locale parity tests - all 8 localization tests now pass with
only expected failures (incomplete translations in some locales).

* fix(l10n): copy format string to all locales for 100% completion

Add %@/%@ format string to all 14 non-English locales. Format strings
are locale-independent so using the same value everywhere is correct.

This brings all locales to 100% completion (189/189 strings) to prevent
Xcode from reporting incomplete translations when building.

* fix(l10n): prevent auto-extraction of UI literals

Use Text(verbatim:) for non-localizable UI elements:
- App branding ("bitchat/")
- Symbols (@, #, ✔︎)
- Dynamic usernames (@username)
- Count ratios (reached/total)

This prevents Xcode from auto-extracting these literals into the
String Catalog when building through Xcode GUI, which was causing
locales to show 96% completion instead of 100%.

* chore(l10n): remove auto-extracted UI literal entries

Delete 5 auto-extracted keys from catalog that are now using Text(verbatim:):
- @, #, ✔︎, %@, %@/%@

These were showing as stale/incomplete in Xcode causing 97% completion.
All locales now at 100% (188/188 strings).

* fix(l10n): prevent AttributedString from extracting @ symbol

Use string interpolation "\\(at)" instead of literal "@" in
AttributedString to prevent Xcode from auto-extracting it to the
String Catalog during build.

This was the last string causing locales to show 99% instead of 100%.

* fix(l10n): add %@ as non-translatable key in all locales

Mark %@ as non-translatable and add to all 15 locales with same value.
This prevents Xcode from showing incomplete translations when it
auto-extracts this format specifier during GUI builds.

All locales remain at 100% (189/189 strings).

* refactor: move Localizable.xcstrings to bitchat root

Move bitchat/Localization/Localizable.xcstrings to bitchat/ (after LaunchScreen)
and remove empty Localization directory.

* fix(test): update catalog path in localization tests

Update test paths from bitchat/Localization/Localizable.xcstrings to
bitchat/Localizable.xcstrings after moving the file.

---------

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-29 22:31:59 +02:00
IslamandGitHub 9abfab3248 Comment out broken tests (#675) 2025-09-25 19:34:32 +02:00
IslamandGitHub 0ae09f73d8 Fix tests that were broken after localization integration (#677) 2025-09-25 19:34:08 +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
IslamandGitHub ea8d51a36b Refactor: BitchatMessage (#610)
* Extract BitchatMessage into a separate file

* Convert `fromBinaryPayload` to `convenience init?`

* Extract message dedup into an extension

* Remove dead `formatMessageContent`

* Minor refactor of timestamp and username formatting

* Remove dead `getSenderColor`
2025-09-15 15:00:12 +02:00
920dc31795 Refactor: Testable Keychain and Identity Manager (#584)
* Make static functions instance functions to be testable

* Injectable KeychainManager + Mock + updated tests

* Remove `pendingActions` from identity manager (dead code)

* Remove `getHandshakeState` from identity manager (dead code)

* Remove `getAllSocialIdentities` from identity manager (dead code)

* Remove `getCryptographicIdentity` from identity manager (dead code)

* Remove `resolveIdentity` from identity manager (dead code)

* Identity Manager: minor clean up

* Put Identity Manager behind a protocol

* Remove Keychain and Identity Manager singletons

* Tests: include MockKeychain/MockIdentityManager in project; init identityManager in CommandProcessorTests

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-12 14:37:34 +02:00
4b0634d1d0 Fix/general queue (#580)
* Fix emote targeting and grammar; add tests

Prevent 'system' mis-target via peerID-derived display name in actions sheet. Correct /hug and /slap usage/error grammar by passing base command name. Improve geohash nickname resolution to match displayName with #suffix. Add CommandProcessor tests.

* Geohash ordering: strict in-order inserts and timestamp clamp

Use channel-aware late-insert threshold with 0s for geohash to keep strict chronological order. Clamp future Nostr event timestamps to 'now' to avoid future-dated items skewing order in geohash timelines.

* Trim trailing/leading spaces in geohash nicknames and tag emission

Sanitize Nostr 'n' tag values on ingest and emit by trimming whitespace/newlines to prevent trailing spaces in displayed usernames. Local nickname is already trimmed on focus loss and submit.

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-09-11 21:02:48 +02:00
IslamandGitHub e72fe50ffa Perf: Add final to classes that are not inherited (#574) 2025-09-11 19:17:04 +02:00
cf1bfdac6b Geohash Bookmarks + Rising‑Edge Notifications + Friendly Names (#538)
* Add geohash bookmarks: persistence, sampling integration, and UI\n\n- Add GeohashBookmarksStore with UserDefaults persistence and toggle API\n- Sample union of regional + bookmarked geohashes for activity notifications\n- LocationChannelsSheet: bookmark icons on nearby rows and a Bookmarked section\n- Header toolbar: toggle bookmark for current geohash\n- Tests: GeohashBookmarksStoreTests for normalization and persistence\n\nRationale: Bookmarked geohashes are always sampled for new activity notifications and quickly selectable from the sheet.

* Notifications: remove background 'new chats!' nudge; geohash activity only on zero→alive; mesh 'nearby' only on zero→alive\n\n- Geohash sampling: notify only when previous participant count in last 5m was zero, with 30s freshness gate\n- Suppress old sampled events after (re)subscribe\n- Remove channel inactivity nudge\n- Mesh: reset rising-edge gate immediately when peer list goes empty (strict zero→alive)

* Geohash notifications: ensure triggering message appears\n\n- On zero→alive sampling, pre-populate geoTimelines[gh] with the triggering message\n- Dedup on per-geohash timeline and UI messages by message ID to avoid duplicates after subscribe\n- Keeps participant update, block/self checks, and cooldown intact

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-08-28 09:10:15 +01:00
60b0deee7b Cleanup: remove dead code, normalize fingerprints, modernize share extension, trim test noise, and drop ‘preparing to share…’ message (#520)
* Remove dead code and artifacts: drop PeerManager, unused views/types; delete LegacyTestProtocolTypes; update .gitignore; purge TestResult.xcresult and build.log

* Tests: gate verbose prints under DEBUG; ChatViewModel: remove legacy fingerprint helper and rely on UnifiedPeerService

* Share Extension: migrate to UIKit + UTTypes; drop Social/SLComposeServiceViewController

* Remove 'preparing to share …' system message; send shared content immediately

* Inline comment cleanup: drop legacy 'removed' breadcrumbs across protocols, services, view model, and views

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-08-25 18:01:19 +02:00
e6903456ab NIP‑17/44: XChaCha20 v2 gift wraps, DM kind=14, receipts + UI fixes (#506)
* NIP-17/44: adopt NIP-44 v2 (XChaCha20-Poly1305, v2: base64url), switch rumor kind to 14, randomize BIP-340 aux; add XChaCha20Poly1305Compat and wire-up

* Nostr DMs: ensure delivered/read acks are sent even without Noise key mapping by falling back to direct Nostr (geohash-style) acks to sender pubkey

* NIP-44 v2 decrypt: try both Y parities for x-only sender pubkeys (even then odd) to fix unwrap authentication failures

* Tests: add NIP-44 v2 ACK round-trip tests (delivered/read) using bitchat1 embedding and gift-wrap decrypt path

* UI: fix DM autoscroll IDs by using dm:<peer>|<id> for private chat item IDs and preserve anchors, ensuring scrollTo targets exist when opening/switching/new messages

* UI: fix string interpolation in DM/geohash context keys (remove escaped interpolation) to resolve 'unused ch' warnings and ensure proper IDs

* UI: MeshPeerList shows transport state icon: radio for mesh-connected, purple globe for mutual favorite/Nostr; fallback dim person for others

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-08-24 17:56:43 +02:00
0260798712 Fix/UI (#500)
* Remove link previews: link URLs inline\n\n- Delete LinkPreviewView and all references\n- Strip preview usage from ContentView\n- Make detected URLs tappable via .link attribute\n- Add MessageTextHelpers for tokens/length checks\n- Wire helpers into iOS/macOS targets

* Peer list UX: match message colors, use map pin icon, stable ordering\n\n- Color list names and icons with same peer color as messages\n- Default icon mappin; teleported uses face.dashed (iOS)\n- Geohash: move teleported peers to bottom\n- Maintain stable order: append new peers, remove missing\n- Mesh list: replace state icons with colored mappin/person

* Fix peer list build errors: remove ambiguous Set type, avoid guard in ViewBuilder, remove duplicate bindings, and simplify person lookup

* Peer list: remove onChange expressions to avoid type-check issues; rely on ObservedObject updates

* Peer lists: simplify view structure to satisfy SwiftUI type checker (replace Group with VStack, flatten body)

* Peer lists: move ordering mutations to onAppear/onChange, keep body pure; fix result builder errors

* Fix: remove trailing modifiers outside if/else to avoid ViewBuilder type issues

* Color parity: fix seed cache to include color scheme; normalize Nostr seeds; switch to mappin.circle icon

* Peer colors: ensure exact match with message colors\n\n- Mesh list uses same seed logic as messages (getNoiseKeyForShortID fallback)\n- Color cache keyed by theme; normalize nostr seeds\n- Icons: use mappin.and.ellipse (default) and face.dashed for teleported\n- Teleport tag: accept "teleported" in addition to "teleport" and presence events

* Fix geohash color mismatch: populate nostrKeyMapping before building messages in resubscribe; also honor t,teleport tag for teleported state

* Message actions: username tap opens sheet via clickable AttributedString; message tap inserts @mention; rename to 'direct message'

* Cashu UX: suppress 'Show more' when message contains a Cashu token (chips handle rendering)

* Cashu detection: broaden regex (allow '.') + shorter min length; avoid long-text fallback when Cashu present so chips render and no full blob

* Geohash levels: rename region->province, country->region; update labels, precision, UI, manager mapping, tests; add Codable backward-compat for renamed cases

* Fix braces in LocationChannel.swift: close enum before extension to satisfy file-scope declarations

* Geohash links: make #geohash tappable and open that channel (bitchat://geohash/<gh>); handle in ContentView.onOpenURL with validation and selection

* Underline tappable #geohash mentions for clarity

* Geochat: sanitize timeline on channel switch to remove any blank-content entries (prevents blank rows)

* Xcode project: sync sources after UI changes (remove LinkPreview, add helpers, update build refs)

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-08-24 02:05:02 +02:00
a0a973eb81 Fixes/location channels (#465)
* Remove "street" location channel; add coverage + names; style mesh

- Drop GeohashChannelLevel.street and update mappings/tests\n- Map geohash lengths >=8 to Block in teleport, no Street\n- Show ~distance coverage (mi/km via Locale.measurementSystem) next to each #geohash\n- Add reverse geocoding to display coarse names (country/region/city/neighborhood) per level\n- Style "#mesh" row title with toolbar blue\n- Fix iOS 16 deprecation: use Locale.measurementSystem

* Project: update Xcode project (auto)

* UI: use '~' without trailing space before location name in sheet

* Location sheet: poll for location at regular intervals while open (replace significant-move updates)

* UI: show Bluetooth range next to #bluetooth in location sheet

* UI: remove leading '#' from mesh title in location sheet

* UI: bold location name in sheet when geohash has >0 people; refactor row to render subtitle pieces

* UI: bold mesh/level titles when participant count > 0; factor meshCount()

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-08-21 01:01:29 +02:00
3074fa0fcb Refactor/repo hardening 01 (#462)
* BinaryProtocol: add optional padding control; BitchatPacket API for padded/unpadded bytes; BLEService: use unpadded encoding and remove ad-hoc unpadding on BLE writes

* BLEService: balance BLE padding — pad Noise handshake/encrypted frames; leave public/announce/leave unpadded; keep fragmentation consistent with chosen padding

* BLEService: replace Timer with DispatchSourceTimer on bleQueue; NostrTransport: cache placeholder NoiseEncryptionService to avoid reallocation

* Unify peerID validation: InputValidator handles 16-hex, 64-hex, or alnum-/_; NoiseSecurityValidator now delegates to InputValidator

* UI: use standard green for geohash toolbar badge and count (less bright in light mode)

* UI: standardize geohash sheet green to app standard (dark: system green, light: darker green) for buttons and checkmark

* Docs: align BinaryProtocol compression docs to zlib; Logs: reduce NostrTransport DELIVERED ack logs to debug to cut noise

* Tests: add InputValidator peerID coverage and BinaryProtocol padding round-trip/length tests

* Project: ensure Xcode project reflects new tests (references added)

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
2025-08-20 13:29:53 +02:00