711 Commits

Author SHA1 Message Date
callebtc
13f15ca1ef
Merge pull request #836 from permissionlesstech/codex/restore-globe-picker-ux
Restore globe picker UX and teleport selection
2026-07-30 23:40:12 +02:00
callebtc
87184eddde globe fixes 2026-07-30 23:09:53 +02:00
callebtc
daee720738
Merge pull request #834 from permissionlesstech/codex/restore-location-notes-entry
Restore location notes access
2026-07-30 19:32:52 +02:00
callebtc
8abe570374 Restore location notes access 2026-07-30 19:29:19 +02:00
callebtc
643f329d9d
Merge pull request #813 from qutad/fix/766-header-location-control
feat: improve location control accessibility and crowding
2026-07-30 19:12:51 +02:00
callebtc
ae70c02149
Merge pull request #833 from a1denvalu3/optimize/geohash-picker-low-end
Optimize geohash globe rendering and gestures
2026-07-30 19:08:38 +02:00
callebtc
aaac810f4f
Merge pull request #829 from TheCodeSmith404/fix/panic-mode-memory-purge-807
fix(panic): clear in-memory networking caches, router outbox, and Nostr queues on panic wipe (#807)
2026-07-30 16:33:06 +02:00
a1denvalu3
0d7f8cef10 Prevent whole-globe land fills 2026-07-30 15:50:21 +02:00
a1denvalu3
6edd361ed3 Fix globe land fill orientation 2026-07-30 15:33:17 +02:00
a1denvalu3
6fc4583a15 Stabilize globe quality selector layout 2026-07-30 15:09:29 +02:00
callebtc
fa4442d836
Merge pull request #832 from permissionlesstech/codex/fix-conversation-alias-isolation
Prevent private messages from merging across conversations
2026-07-30 14:54:58 +02:00
a1denvalu3
8602db88de Add geohash globe render quality selector 2026-07-30 14:39:29 +02:00
a1denvalu3
5bde4e0b4a Close fully visible geohash outlines 2026-07-30 14:29:22 +02:00
a1denvalu3
2a43265e12 Optimize geohash globe rendering and gestures 2026-07-30 14:01:02 +02:00
callebtc
1a953a17ab Fix private conversation alias isolation 2026-07-30 12:36:46 +02:00
callebtc
b692ec7b44
Merge pull request #828 from moehamade/fix/hotspot-group-consent
fix(hotspot): never disturb another app's Wi-Fi Direct group without consent
2026-07-30 12:30:00 +02:00
TheCodeSmith404
e311649525 fix(panic): clear in-memory networking caches, router outbox, and Nostr queues on panic wipe (#807) 2026-07-30 11:04:17 +05:30
callebtc
b6ad8971a8 fix(hotspot): revalidate ownership during teardown 2026-07-30 03:20:48 +02:00
callebtc
1699cc7986 Header: preserve compact channel accessibility state 2026-07-30 03:00:49 +02:00
callebtc
33538fa9e0
Merge pull request #827 from a1denvalu3/fix/stale-peer-cleanup
Fix stale peer lifecycle cleanup
2026-07-30 02:41:13 +02:00
Moe Hamade
5859ac29cd fix(hotspot): confirm a group is ours before trusting or removing it
Two related ways the app could act on a group it did not create.

createdGroup was set once and never revisited, so it outlived the group it
described. Our group can disappear without us - Wi-Fi toggled, another app
issuing its own device-scoped removeGroup(), a driver reset - and another
app can create one in its place while the sharing screen is still open.
Stop then believed the group present was ours and removed it, disconnecting
a session the user never agreed to touch. Every group snapshot now
reconciles the flag against what is actually on the framework.

isGroupOwner cannot carry that judgement on its own: it reports that this
DEVICE hosts the group, which is equally true of an autonomous group
another app created here. So a replacement group was still being adopted -
its name persisted as ownedGroupName, its credentials shown as ours below Q
- and because ownership is now an exact-name match, the next start
classified that name as ours and removed it with no confirmation. Snapshots
are only read once the group is confirmed to be the one we created: above Q
by the network name we chose, below Q by the first name the framework
reported for our own successful creation, fixed from then on.

Reconciliation waits until our group has been named, because a null
snapshot during formation says nothing about a group that has not appeared
yet. Losing the flag to a transient null is safe in a way that keeping it
is not - the group we created is left behind, and the next start recognises
it by name and removes it silently.

A group-info reply arriving after the stop is now ignored, so it cannot
revive state the stop just cleared.

Device-verified on a Pixel 9a (Android 16, API 37).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 02:40:17 +03:00
Moe Hamade
141adf5468 fix(hotspot): only remove our own group; ask consent to replace a foreign one
removeGroup() is device-scoped: it removes whatever Wi-Fi Direct group
exists, including one owned by Cast, Android Auto or Quick Share.
stopHotspot() called it unconditionally, so the path built to protect a
foreign group tore that group down anyway. Removal on stop is now gated on
a createdGroup flag, set once our own createGroup command is accepted; with
nothing of ours on the framework, stop closes the channel and leaves the
group alone.

When a group we did not record creating is active at start, the app no
longer guesses about ownership - it asks. A confirmation dialog explains
that starting will disconnect the current Wi-Fi Direct connection;
confirming retries the start with replacement authorized, cancelling
leaves everything untouched. Consent is bound to the group it was given
for: the conflicting group's name travels through the dialog, and the
policy only authorizes removing a group with exactly that name - one that
appeared later, or swapped in mid-retry, re-prompts instead of riding on
stale approval.

Because consent replaces ownership proof, the DIRECT-BC- prefix heuristic
is gone: a prefix match is not ownership (this device can be connected to
another phone's bitchat group), so only the exact recorded name counts.
The record is also kept honest: never taken from a group we do not host,
and never overwritten while an old group of ours may still exist, so a
BUSY retry cannot misclassify our own stale group as foreign.

Also: SecurityException guards on the removeGroup() sites reached from
framework callbacks (permission revoked mid-session crashed instead of
failing cleanly); stopHotspot() takes a completion callback so the
ViewModel releases its Wi-Fi Aware lease only after the framework
acknowledges the removal, with an idempotent 10s fallback so a dropped
acknowledgement cannot pin the mesh down; and the confirm/cancel handlers
guard on the ConfirmDisconnect state so a tap landing through a screen
transition cannot tear down a just-confirmed session.

Replaces the state-machine approach of #811 - same protection at
proportionate cost.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 01:28:09 +03:00
Moe Hamade
3562ad10d5 fix(wifi-aware): count hotspot radio holds and never drop a restart request
Two fixes to how Wi-Fi Aware yields the radio to the Wi-Fi Direct hotspot.

A restart request could be swallowed: restartIfStillEnabled() coalesces on
an in-flight flag, so a request arriving while an earlier loop was still
burning attempts against the hotspot hold lost the CAS and was dropped.
The loop then exhausted its attempts without ever seeing the cleared hold,
leaving the mesh down despite the user's setting. Requests are now recorded
before coalescing and re-checked after each pass.

The hold itself was a single flag, so overlapping share sessions could
release each other's claim. It is now a counted, once-releasable
HotspotLease: Aware restarts only when no session still needs the radio,
and a duplicate or late release is a no-op. Publication of a started
service is checked against the hold inside the same lock stop() takes, so
a start racing a new hold cannot resurrect NAN while the hotspot owns the
radio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 00:50:36 +03:00
a1denvalu3
6ebbae0326 Rerun CI 2026-07-29 23:35:53 +02:00
a1denvalu3
9f0223591f Fix stale peer lifecycle cleanup 2026-07-29 23:15:01 +02:00
callebtc
97d6e8a479
Merge pull request #825 from permissionlesstech/codex/network-tab-list-cleanup
Polish Network list badges and previews
2026-07-29 22:32:04 +02:00
callebtc
1774414f2e
Merge pull request #819 from spradhan7656/main
android 10 or below chat ui input field padding issue
2026-07-29 22:17:16 +02:00
callebtc
5dd7b2c809 Restore Gradle verification metadata 2026-07-29 21:57:41 +02:00
callebtc
a5dfe9fe42 Polish network conversation rows 2026-07-29 21:56:12 +02:00
callebtc
2176160ac0
Merge pull request #823 from permissionlesstech/ui/geohash-globe-picker
feat: animated 3D globe geohash picker with borders and cities
2026-07-29 21:55:07 +02:00
callebtc
57cc39dbdf Merge main into fix/766-header-location-control 2026-07-29 20:52:00 +02:00
callebtc
fe93be379a Remove generated Gradle daemon JVM config 2026-07-29 20:45:41 +02:00
callebtc
44f62a3c14
Merge pull request #776 from a1denvalu3/feat/cashu-chips-android
feat: add Cashu ecash chips and /pay command
2026-07-29 20:21:12 +02:00
callebtc
03de6f3519 fix: allow targeting polar geohashes
Relaxes the view-center clamp from ±80° to ±89°. Previously opening or
tapping a geohash above 80°N/S clamped the fly-in and syncSelection()
encoded the clamped center, silently returning a different cell than
the user picked. Verified with p2 (87°N) and p6 (85°S) cells: the view
now centers on the requested cell and selects it correctly.
2026-07-29 20:21:12 +02:00
callebtc
b073dc2160
Merge pull request #824 from permissionlesstech/codex/fix-peer-verification-status-badge
Fix peer verification status and private chat badge
2026-07-29 20:18:34 +02:00
callebtc
70185ae86f Refine private chat header actions 2026-07-29 19:40:21 +02:00
callebtc
79bf154ce3 feat: overlay country borders and cities on the globe picker
Adds public-domain Natural Earth vector overlays in the established
terminal style, bundled as compact assets (works fully off-grid):
- world_borders.geojson (56KB): admin-0 boundary lines, stroked as
  front-facing horizon-clipped runs in a muted theme color
- world_cities.geojson (99KB, 1251 populated places): zoom-tiered by
  scale rank - capitals as accent dots, other cities as muted dots;
  name labels in Geist Mono fade in from regional zoom levels to keep
  the whole-globe view uncluttered
2026-07-29 19:39:51 +02:00
callebtc
29f9eb0cbc
Merge pull request #821 from permissionlesstech/codex/fix-android-studio-strict-build
fix: restore Android Studio sync with strict Gradle security
2026-07-29 19:39:16 +02:00
callebtc
c7ced41bcb
Merge pull request #822 from permissionlesstech/uniform-lists-design
Unify people lists with conversation-row avatar design
2026-07-29 19:39:07 +02:00
callebtc
9f81a1e40d Fix peer verification status and badge 2026-07-29 19:32:28 +02:00
callebtc
9ca1413a1f feat: replace Leaflet WebView geohash picker with animated 3D globe
Reworks the geohash picker as a fully offline, native Compose globe:
- Orthographic 3D Earth rendered on a Canvas: starfield, atmosphere,
  shaded ocean, graticule and vector continents from bundled public-domain
  Natural Earth 110m data (world_land.geojson, 81KB)
- Geohash cells projected onto the sphere with theme-aware dark styling,
  Geist Mono labels, level + coverage readout and pulsing crosshair
- Gestures: drag to spin with inertial fling, pinch to zoom (precision
  follows zoom), tap to focus, double-tap zoom, cinematic fly-in intro,
  haptic tick on cell change
- Removes the WebView/Leaflet/CDN dependency; picker now works off-grid
  and matches the app theme in dark and light mode

Rendering notes: horizon-clipped polygon fills (front-run splitting with
limb arcs) and viewport clipping of all path geometry to avoid Skia
precision loss for coordinates beyond 32767px at high zoom.
2026-07-29 19:28:16 +02:00
callebtc
79e04ed3cc
Merge pull request #820 from permissionlesstech/codex/fix-wear-private-message-navigation
Improve Watch private-chat navigation and peer identity UI
2026-07-29 19:23:43 +02:00
callebtc
a306340119 Preserve Watch navigation across recreation 2026-07-29 19:12:13 +02:00
callebtc
4fdc9babbe feat: unify people lists with conversation-row avatar design
- Extract shared PeerAvatar (initial circle + lower-right transport badge)
  from the conversation row and use it in the mesh peer list and the
  geohash/Nostr people list
- Remove the favorite toggle button from the peer list; favorite state is
  now a small star badge on the avatar (filled = we favorited, outline =
  they favorited us), so favoriting only happens from the private chat
- Show the unread-count badge on peer rows, matching conversation rows
2026-07-29 19:11:06 +02:00
a1denvalu3
199f95fdbd Fix Cashu payment review issues 2026-07-29 19:09:05 +02:00
callebtc
3b0e569882 ci: use exact Temurin catalog version 2026-07-29 19:08:35 +02:00
a1denvalu3
6f4f6b988b Keep Cashu composer preview compact 2026-07-29 19:07:31 +02:00
a1denvalu3
adce27c0d1 Preview Cashu tokens in message composer 2026-07-29 19:07:12 +02:00
a1denvalu3
b9ca8ed3eb Add Cashu payment chips and pay command 2026-07-29 19:06:50 +02:00
callebtc
4f567ecd5f
Merge pull request #800 from a1denvalu3/issue-764-language-picker
Add in-app language picker
2026-07-29 19:03:01 +02:00