mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-08-15 06:56:30 +00:00
21 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7025009788
|
ui: complete the redesign — palette, top bar, composer, About, and a motion pass (#774)
* first pass * pass 2 * cleanup * capitalization * strings * input bar fixes * fixes * notes * nice * nicer * lists * cleanup * button * fixes * animations * Fix layout jumpiness in chat and geohash people list Three separate causes of things moving when they should not: - Chat lurched whenever a bottom sheet closed. Placement animation is meant to soften insertions and removals, but any relayout moves every item -- a sheet's text field opening the keyboard changes the chat's IME inset, and closing it changes it back. Placement animation is now armed only briefly around a real change to the message list, so items otherwise track the viewport exactly. - Anon list changed height as participants churned. Rows sized to their content, so any reorder could change the card's height; and the card sized to the live anon count, which moves constantly in a busy geohash. Rows now have an exact height, and a trimmed anon card reserves the full capped height regardless of how many are present beyond the cap. - Anons are now their own trailing section rather than a tail on each of "on location" and "teleported in", which had pushed the few recognisable names out of view twice over. Self is never grouped as an anon. Adds 7 tests covering the sectioning and the fixed-length behaviour. * Group geohash people as People and Anon Replaces the "on location" / "teleported in" / "anonymous" split with two sections: peers who announced a nickname, then the anons. Teleport state was never worth a section of its own -- every row already carries it as a distinct glyph -- and splitting on it fragmented the short list people actually read, in a channel where most participants are anonymous anyway. Self stays in the People section even when unnamed. * Key message list state per conversation Switching channels reused every piece of state in MessagesList, because none of it was keyed on which conversation was being shown: - The LazyListState carried the previous channel's scroll offset, so the new channel opened at a stale position and then corrected itself. - hasScrolledToInitialPosition and followIncomingMessages carried over, so a channel entered after scrolling up in another one did not land on its newest message at all. - The arrival tracker had never seen the incoming channel's ids, so a backlog of six or fewer messages was treated as six simultaneous arrivals and each one slid in. - previousMessageCount carried over, arming placement animation for the relayout that the switch itself caused. All of it is now keyed on a conversationKey derived the same way displayMessages is. The tracker also detects a list sharing no ids with the previous one and adopts it silently, which covers /clear and any caller that does not supply a distinct key. Adds 4 tests for wholesale replacement, including the case that the burst cap cannot catch on its own. * fix location channel layout * icon * location sheet * move location error * fix location channel lifecycle bug * remove empty lable * geist mono * timestamp no seconds * new icons * icons * cleanup * mentions * fix mentions * grouping of geohash channel list * colors * fix mention colors * Bring private and group chat headers up to the main header's layout Both conversation headers were built on TopAppBar with a centred title, a back arrow on the left and everything else crowded into the title slot, at 14sp with 14dp icons. Moving between the timeline and a conversation visibly shifted the bar's height, insets and type. Introduces ConversationHeader, built from the main header's own tokens rather than TopAppBar: same ChatHeaderHeight, same 12/8dp edge insets, leading glyph in a 44dp slot so it lands exactly where the brand mark does, same -6dp optical nudge pulling the title toward it, same 17sp label. - Drops the back button; the close action on the right is the way out. Leaving a channel outright already lives on its row in the network sheet, so it does not need a second home beside the exit. - Leading glyph is the transport: globe over the internet, wifi/bluetooth/ routed on the mesh, matching the main header's channel button. - Actions are right-aligned and unweighted -- favourite, encryption state, close -- so a long title yields space to them instead of pushing them off screen. - Private chat titles use the primary green like every other header label, rather than orange for Nostr-reachable peers. Height and edge insets now belong to each header variant instead of the ChatFloatingHeader wrapper, which was applying them a second time to the channel header. Adds nine spec icons in the existing 20x20 / 1.25-stroke language -- bluetooth, wifi, routed, close, check, warning, sync, lock_open, envelope -- so the headers and peer rows no longer mix Material glyphs into the set. * color |
||
|
|
4a34408db9
|
Enhancement/apk sharing (#632)
* feat: Add QR code generator for Wi-Fi and URLs
This commit introduces a `QrCodeGenerator` utility object to create QR code bitmaps for both Wi-Fi credentials and URLs.
Key features:
- **`generateWifiQr`**: Creates a QR code using the standard `WIFI:` format, allowing other devices to connect to a hotspot by scanning the code. It properly escapes special characters in the SSID and password.
- **`generateUrlQr`**: Generates a standard QR code for any given URL.
- **Implementation**: Uses the `zxing` library to encode the data and converts the resulting `BitMatrix` into an Android `Bitmap`.
* feat: Add manager for universal APK sharing
This commit introduces a comprehensive system for fetching, downloading, caching, and managing a "universal" APK of the app, intended for offline sharing with new users.
The core components are:
- `GitHubReleaseClient`: A new client to fetch the latest release information from the project's GitHub repository. It specifically looks for a universal APK asset in the release, parses its download URL, and attempts to extract its SHA256 checksum from the release notes.
- `UniversalApkManager`: Manages the entire lifecycle of the universal APK. It handles:
- Checking for new versions by comparing the cached APK version against the latest GitHub release.
- Downloading the APK with progress reporting.
- Verifying the downloaded file against the SHA256 checksum, if available.
- Caching the APK and its metadata (version, checksum, size) locally.
- Cleaning up old APK versions to conserve space.
* feat: Add offline APK sharing via Wi-Fi hotspot
This commit introduces a comprehensive feature for sharing the BitChat application offline using a self-hosted Wi-Fi Direct hotspot. This enables mesh network expansion by allowing users to distribute the app without requiring an internet connection.
Key components:
- **`HotspotManager`**: A new class that manages the creation and lifecycle of a Wi-Fi P2P (Wi-Fi Direct) group. It handles generating secure credentials (SSID/password), acquiring WakeLocks, and monitoring connected peers. It supports custom credentials on Android 10+ and falls back to system-generated ones on older versions.
- **`ApkWebServer`**: A lightweight HTTP server based on `NanoHTTPD` that serves the APK file and a user-friendly HTML landing page to connected devices.
- **`ApkSharingUtils`**: A utility to detect whether the app is installed as a single or split APK, collect the necessary files, and copy them to a cache directory for sharing.
- **`ApkInstaller`**: A utility using the `PackageInstaller` API to handle the installation of single or split APKs received from another user.
- **`HotspotActivity`**: A new Compose-based UI that guides the user through starting the hotspot, displays connection details (Wi-Fi credentials, QR codes for Wi-Fi and the download URL), and shows the number of connected peers. It also handles the necessary runtime permissions (`NEARBY_WIFI_DEVICES` or `ACCESS_FINE_LOCATION`).
- **Configuration**:
- Adds necessary Wi-Fi and P2P permissions to `AndroidManifest.xml`.
- Defines a `FileProvider` path for APK sharing in `file_paths.xml`.
- Adds numerous string resources for the new UI.
* feat: Add offline and online app sharing features
This commit introduces a comprehensive feature set for sharing the application, both offline via a Wi-Fi hotspot and online through standard Android sharing mechanisms.
Key additions:
- **Prepare for Sharing UI:**
- Adds a "Prepare App for Sharing" option in the settings sheet.
- This feature downloads a universal APK from a remote source, suitable for all Android devices.
- The UI displays the status: not downloaded, downloading (with progress), ready, or if an update is available.
- Users can download, update, or delete the cached universal APK.
- **Offline Sharing via Wi-Fi Hotspot:**
- Adds a "Share via Wi-Fi Hotspot" option.
- This launches a new `HotspotActivity` to share the prepared universal APK with nearby devices without an internet connection.
- A dialog informs the user if the APK hasn't been prepared yet.
- **Online & Local Sharing:**
- Adds an option to share via Bluetooth, email, etc., using the standard Android share sheet.
- This method shares the *installed* version of the app, which may be a split APK.
- An explanatory dialog is shown first, instructing the receiver on how to install split APKs if necessary.
- Implements logic to correctly package and share single or multiple split APK files using `FileProvider`.
* feat: Add NanoHTTPD for hotspot APK sharing
This commit introduces the `nanohttpd` library, which will be used to implement an HTTP server for sharing the application's APK over a local hotspot.
The specific dependency added is `org.nanohttpd:nanohttpd:2.3.1`.
* refactor: Improve hotspot and APK sharing stability
This commit introduces several fixes and refinements to the hotspot sharing and APK handling features, improving stability, user experience, and robustness.
Key changes:
- **Hotspot Flow:**
- Automatically starts the hotspot after the user grants the required Wi-Fi permission, removing the need for a second button press.
- Ensures all `HotspotManager` callbacks in `HotspotViewModel` are executed within `viewModelScope` to prevent threading issues and ensure safe UI updates.
- Fixes a potential `BroadcastReceiver` leak in `HotspotManager` by tracking its registration state, preventing crashes and resource leaks when stopping the hotspot.
- Changes the hotspot `WakeLock` to be non-expiring to prevent the CPU from sleeping while the hotspot is active.
- **APK Handling & Installation:**
- Adds a pre-download disk space check in `UniversalApkManager` to prevent download failures on devices with insufficient storage.
- Improves the file move logic after download by falling back to a copy-and-delete strategy if a direct rename fails, making it more robust across different filesystems.
- Introduces `InstallResultReceiver` to provide clear Toast notifications to the user about the success or failure of an APK installation, including specific error reasons (e.g., "Not enough storage").
- **Performance & UI:**
- Caches the generated HTML in `ApkWebServer` to improve performance by avoiding regeneration on every request.
- Throttles the APK download progress updates to prevent UI jankiness from too-frequent state changes.
- Moves hardcoded strings in the "Share App" UI to `strings.xml` for better localization and maintenance.
* feat: Refactor APK sharing to use universal APK
This commit refactors the "Share App" functionality to exclusively use the new universal APK system, removing the previous logic that shared the installed split APKs. This simplifies the sharing process and ensures a consistent, single-file sharing experience for all users.
Key changes:
- Deletes `ApkSharingUtils.kt`, which was responsible for detecting and copying split APKs from the device's installation directory.
- Updates `AboutSheet.kt` to use `UniversalApkManager` for all sharing actions (Hotspot and "Quick Share").
- Simplifies the sharing intent logic, as it now only needs to handle a single APK file (`ACTION_SEND`) instead of multiple files (`ACTION_SEND_MULTIPLE`).
- The UI for sharing options (Hotspot, Quick Share) is now dynamically hidden until the universal APK is prepared, preventing user confusion.
- Replaces hardcoded strings with string resources for better localization.
* refactor: Remove InstallResultReceiver
Deletes the `InstallResultReceiver` broadcast receiver.
This component was responsible for handling the results of an APK installation initiated via `PackageInstaller`, but it is no longer used in the current implementation.
* feat: Move APK download to resumable WorkManager pipeline
Replaces the ViewModel-scoped coroutine download with a WorkManager-backed
downloader so downloads survive app backgrounding and process death:
- New ApkDownloader interface with WorkManagerApkDownloader implementation
and ApkDownloadWorker (CoroutineWorker); transient IO errors return
Result.retry() and resume via HTTP Range requests from the partial file.
- UniversalApkManager gains resume support (Range header + persisted resume
metadata) and verifies the downloaded APK is signed with the same
certificate as the running app (no hardcoded fingerprint; debug-signed
builds skip enforcement).
- APK downloads now go through the shared OkHttpProvider so they respect
the app's Tor proxy configuration instead of leaking the direct IP.
- AboutSheet logic extracted into ApkDownloadViewModel (MVI: state/event/
effect), removing ~240 lines of UI-embedded logic.
- Removes unused ApkInstaller (receivers install via the system installer).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: Harden hotspot server and release metadata fetching
- ApkWebServer only serves the exact /bitchat.apk path instead of any
*.apk-suffixed URI.
- GitHubReleaseClient uses the shared OkHttpProvider (respects Tor proxy)
and drops the loose 'any lone 64-hex string in the release notes is the
checksum' fallback, which was spoofable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: Address review findings in HotspotManager
- Keep polling for group info while the group is still forming instead of
silently stopping when the first requestGroupInfo() returns null, with a
15s formation timeout (Codex P1).
- Release wake/wifi locks and unregister the broadcast receiver on terminal
startup failures via failStartup(), so a failed attempt no longer leaks
resources or blocks subsequent attempts (Codex P2).
- Use PARTIAL_WAKE_LOCK with a 30-minute timeout instead of the deprecated
FULL_WAKE_LOCK held indefinitely.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: harden offline APK sharing
* fix: Handle fully-downloaded temp file before adding Range header
If the process died after download_temp.apk was fully written but before
verification/promotion, the next attempt sent "Range: bytes=<size>-",
GitHub answered 416, and the worker retried the same request forever,
leaving the user stuck on an unresumable download.
- Skip the network entirely when the temp file already holds the full
asset and go straight to checksum/signature verification.
- Treat an HTTP 416 response as an invalid resume offset: discard the
partial state so the retry restarts from scratch instead of looping.
Addresses the Codex review finding on UniversalApkManager.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: Allow sharing when the GitHub release lags the installed version
Upstream bumps versionName in main before tagging the GitHub release, so
there is a recurring window where the installed app is newer than the
latest published universal APK. The hard version guard disabled the whole
sharing feature during that window (including for reviewers building this
branch at 1.7.5 while GitHub's latest is 1.7.4).
An older release is still a genuine, signed, checksum-verified universal
artifact, and Android already refuses downgrade installs on receivers, so:
- checkForUpdate now logs (instead of erroring) when the latest release is
older than the installed app and proceeds normally.
- downloadUniversalApk no longer fails for an older-than-installed release.
- A cached artifact stays shareable regardless of the installed version.
The cached-artifact preference (never replace a newer cached APK with an
older one) and all signature/checksum verification are unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat: Run APK download as foreground (dataSync) work
Long transfers — especially over Tor — can exceed WorkManager's
~10-minute background execution window, getting the worker stopped and
rescheduled repeatedly. Promote the download to foreground work with a
progress notification (cancel action included) so it can run to
completion.
- setForeground() with FOREGROUND_SERVICE_TYPE_DATA_SYNC; the manifest
already holds the FOREGROUND_SERVICE_DATA_SYNC permission, and the
WorkManager SystemForegroundService is merged with type dataSync.
- If Android 12+ rejects the promotion (app backgrounded), the worker
logs and continues as regular background work, relying on Range-resume.
- Notification updates are throttled to 5% steps and degrade gracefully
without POST_NOTIFICATIONS.
Addresses the Codex review finding on ApkDownloadWorker.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: Move temp APK into place instead of copying it
replaceFileSafely copied the source into a .new candidate before the
atomic move, doubling peak disk usage: with free space between 1.5x and
2x the APK size, the download completed and then promotion failed on the
copy, retrying against the same full temp file.
Source and target always live in the same cache directory, so a direct
ATOMIC_MOVE (rename) needs no extra space and keeps the same guarantee:
it either fully succeeds or leaves both files intact. The existing 1.5x
margin in checkDiskSpace is now genuinely sufficient.
Addresses the Codex review finding on UniversalApkManager.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: Base the disk space check on remaining bytes when resuming
The check ran before resume state was read and always demanded 1.5x the
full APK size. Bytes already sitting in download_temp.apk have already
consumed storage, so on a low-storage device an interrupted download
could fail every resume with "Insufficient storage" even when only a
small tail was left to fetch.
Read the resume state first and check space for the remaining bytes
only. A fresh download still checks the full size, and a complete temp
file needs no extra space since promotion is a rename.
Addresses the Codex review finding on UniversalApkManager.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: cancel APK downloads promptly
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
|
||
|
|
61588db474
|
chore(deps): upgrade to AGP 9.3.1, Gradle 9.6.1, Kotlin 2.4.10, SDK 37 (#750)
* chore(deps): upgrade to AGP 9.3.1, Gradle 9.6.1, Kotlin 2.4.10, SDK 37 Bring the toolchain and every dependency to latest stable. No app source changes were required. Toolchain: - AGP 8.10.1 -> 9.3.1, Gradle 8.13 -> 9.6.1, Kotlin 2.2.0 -> 2.4.10 - compileSdk 35 -> 37, targetSdk 35 -> 37 (Android 17, stable) - Java 8 -> 11 AGP 9 migration (built-in Kotlin): - Drop org.jetbrains.kotlin.android; AGP 9 provides Kotlin natively and the plugin is incompatible with the new DSL - Migrate kotlinOptions.jvmTarget to kotlin.compilerOptions (the String setter is a hard error in Kotlin 2.4) - Drop android.enableJetifier (deprecated, removed in AGP 10, no support library deps remain) Libraries: - Compose BOM 2025.06.01 -> 2026.06.01, activity-compose 1.10.1 -> 1.13.0 - core-ktx 1.16.0 -> 1.19.0, lifecycle 2.9.1 -> 2.11.0 (unified with lifecycle-process, which had drifted to 2.8.7) - okhttp 4.12.0 -> 5.4.0, coroutines 1.10.2 -> 1.11.0, gson 2.13.1 -> 2.14.0 - BouncyCastle 1.70 -> 1.85, switching bcprov-jdk15on -> bcprov-jdk18on (jdk15on is abandoned; same org.bouncycastle packages) - Tink 1.10.0 -> 1.23.0, CameraX 1.5.2 -> 1.6.1, gms-location 21.3.0 -> 21.4.0 - security-crypto 1.1.0-beta01 -> 1.1.0, navigation-compose 2.9.1 -> 2.9.8 - exifinterface 1.3.7 -> 1.4.2, moved from a hardcoded coordinate into the version catalog - Tests: espresso 3.6.1 -> 3.7.0, test-ext 1.2.1 -> 1.3.0, mockito-kotlin 4.1.0 -> 6.3.0; mockito-inline (deprecated) -> mockito-core 5.23.0; coroutines-test 1.6 -> 1.11.0, now sharing the coroutines version ref instead of drifting Robolectric stays pinned at 4.15: 4.16+ breaks EncryptionServiceTest with "AndroidKeyStore not found". Bisected away from security-crypto and shown not to be SDK-level related. Unpinning needs an EncryptionService refactor, which is deliberately left to a follow-up PR. targetSdk behaviour changes for API 36 and 37 were audited against the source: edge-to-edge and predictive back are already handled, ACCESS_LOCAL_NETWORK is not needed (loopback only, for Arti's SOCKS proxy), the reflection in ChatViewModel touches instance rather than static final fields, and there is no RFCOMM or scheduleAtFixedRate usage. Verified: compileDebugKotlin, testDebugUnitTest (96 tests, 0 failures), bundleRelease with R8, gradlew help, and build --dry-run. The 6 R8 "cannot parse kotlin metadata" warnings present under AGP 8.13.2 are gone under 9.3.1. Not verified on hardware. BLE mesh, foreground services, Nostr relay websockets, Tor, and the Noise handshake still need a device smoke test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: declare ACCESS_LOCAL_NETWORK for Wi-Fi Aware on Android 17 Android 17 (API 37) makes local network protection mandatory for apps targeting it. WifiAwareMeshService reaches peers over link-local IPv6 TCP sockets (connectAwareClientSocket), which may be gated by the new ACCESS_LOCAL_NETWORK runtime permission once targetSdk is raised to 37. The official local network permission documentation frames the feature as LAN access and does not explicitly state whether Wi-Fi Aware peer-to-peer networks are in scope, so this is defensive rather than confirmed-necessary. The sockets are bound to a dedicated Aware Network obtained via requestNetwork, not the user's subnet. Declaring it costs nothing: ACCESS_LOCAL_NETWORK shares the NEARBY_DEVICES group with NEARBY_WIFI_DEVICES, so users who have already granted the latter are not prompted again. The runtime request is gated on SDK_INT >= 37 so older devices are unaffected. Raised by automated review on #750. Verified: compileDebugKotlin, testDebugUnitTest (124 tests, 0 failures), bundleRelease, and ACCESS_LOCAL_NETWORK present in the merged manifest. Not verified on an Android 17 device. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: correct ACCESS_LOCAL_NETWORK permission-group claim Device testing on Android 17 (API 37) disproved the earlier claim that ACCESS_LOCAL_NETWORK is effectively free because it shares the NEARBY_DEVICES group with NEARBY_WIFI_DEVICES. Granting NEARBY_WIFI_DEVICES alone leaves ACCESS_LOCAL_NETWORK denied: pm grant ... NEARBY_WIFI_DEVICES -> NEARBY_WIFI_DEVICES: granted=true -> ACCESS_LOCAL_NETWORK: granted=false The two are tracked and granted independently, so ACCESS_LOCAL_NETWORK has to be requested explicitly. That is exactly what the wifiAwarePermissions() list already does, so no behavioural change is needed — only the comments were wrong. Whether the runtime dialog bundles the two into a single prompt remains unverified, since enabling Wi-Fi Aware from Debug Settings after onboarding never triggers a permission request at all (pre-existing, unrelated to this branch). Comment-only change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: request Wi-Fi Aware permissions when enabling it from Debug Settings Enabling Wi-Fi Aware from the Debug Settings sheet never requested the permissions it needs. The permission flow is reachable only through PermissionManager.getRequiredPermissions(), which gates the Wi-Fi Aware entries behind shouldRequireWifiAwarePermission() — and that returns false unless the debug toggle is already on. Since the toggle defaults to off, onboarding never asks, and flipping it later starts WifiAwareController directly, which only checks the permission and bails. The result was a silent dead end: Wi-Fi Aware could never start, and the controller logged "Missing NEARBY_WIFI_DEVICES permission" on a 5s retry loop indefinitely. Reproduced on a Pixel 9a (Android 17) and a Samsung SM-A366E (Android 16); both needed adb grants to get the transport running at all. The toggle and the Start chip now request the permissions first and only enable the transport once NEARBY_WIFI_DEVICES is granted. ACCESS_LOCAL_NETWORK is treated as best-effort since it does not exist below API 37 — confirmed by `pm grant` rejecting it as an unknown permission on the Android 16 device. The list comes from PermissionManager.wifiAwarePermissions() so the API 37 gate has a single definition. Also corrects the permission-group comments now that both levels are verified on Android 17: grants are tracked independently (granting NEARBY_WIFI_DEVICES alone leaves ACCESS_LOCAL_NETWORK denied), but the two share the NEARBY_DEVICES group so requesting them together produces a single "Nearby devices" prompt. Verified on device: after a clean uninstall/reinstall, toggling Wi-Fi Aware produced one prompt and left both permissions granted with the USER_SET flag. Addresses the second automated review finding on #750. Verified: compileDebugKotlin, testDebugUnitTest (124 tests, 0 failures). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: version-gate Wi-Fi Aware permissions, check live grant state Two issues from automated review of ee1ee3ad. wifiAwarePermissions() returned NEARBY_WIFI_DEVICES unconditionally, but that permission only exists from API 33 while minSdk is 26 and Wi-Fi Aware is available from API 26. On an API 26-32 device the new enable path would request an unknown permission, receive a denial, and never enable a transport that needs no runtime permission there at all — a regression introduced by the previous commit. Both entries are now version-gated. The result callback also inferred the Nearby grant from the result map, which omits permissions that were already held and so filtered out before launching. It now reads the live permission state instead. A denied ACCESS_LOCAL_NETWORK still does not block enabling: the controller starts fine without it (verified on Android 17), and its necessity for link-local sockets remains unproven, so a denial should not disable a transport that otherwise works. Also trims the comments added in the last two commits down to the density of the surrounding code. Verified: compileDebugKotlin, testDebugUnitTest (124 tests, 0 failures). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
ae6641270a
|
feat: disable Wi‑Fi Aware by default (#712)
Co-authored-by: CC <cc@ggg.local> |
||
|
|
3a983c5767
|
Wifi aware refactor mesh core (#711)
* wifi aware wip * wifi aware wip * starting to work * werk * dms work * wip * fix(wifi-aware): use bindSocket and scoped IPv6 instead of bindProcessToNetwork * Merge branch 'upstream/main' into fix/wifi-aware-socket-binding * Fix Wi-Fi Aware connectivity and UI integration post-merge - Replace bindProcessToNetwork with bindSocket for VPN compatibility. - Implement Scoped IPv6 address resolution (aware0) for mesh routing. - Bridge Wi-Fi Aware incoming messages to AppStateStore for UI visibility. - Fix syntax errors and variable name conflicts in Debug UI. * Enhance Wi-Fi Aware robustness and debug UI display - Clean up transport resources (sockets, server sockets, network callbacks) immediately on peer disconnection. - Implement resolveScopedAddress to show scoped IPv6 (e.g., %aware0) in Debug UI. - Fix Map type mismatch warning in ChatViewModel bridge. - Filter self-ID from peer cleanup tables to prevent recursive self-removal. * Share GossipSyncManager across transports to prevent redundant message synchronization - Registered BluetoothMeshService's GossipSyncManager as a singleton in MeshServiceHolder. - Modified WifiAwareMeshService to use the shared GossipSyncManager if available. - Added background cleanup for peer mappings on socket disconnection. - Fixed Kotlin type mismatch during nickname map merging. * Restore VPN acquisition logic and improve peer cleanup - Revert removal of NET_CAPABILITY_NOT_VPN to allow hardware handle acquisition while VPN is active. - Refactor handlePeerDisconnection to more reliably cleanup initial and routed IDs. - Switch cleanup logging to debug level to reduce log noise. * Fix wifi aware socket binding 2 (#536) * Background persistence (#505) * persistence step 1 * fix build * messages in the background work, notifications not yet * app state store * DM icon shows up * notification launches when app is closed! * keep ui updated * lifecycle fixes * extensive logging, maybe revert later * send nickname in announcement * quit in notification * setting in about sheet * fix quit bitchat * lifecycle fixes * power mode based on background state * stats for both direciotns * fix graph persistence * better counting * count per device * only compute when debug sheet is open? untested * fix read receipts * fix read receipts fully * fix unread badge if messages have been read in focus * foreground promotion fix * fix app kill in notification * adjust to new tor * nice * about sheet design * bump version 1.6.0 (#524) * Automated update of relay data - Sun Dec 14 06:06:53 UTC 2025 * bump targetSdk (#526) * Automated update of relay data - Sun Dec 21 06:06:56 UTC 2025 * Automated update of relay data - Sun Dec 28 06:07:12 UTC 2025 * Prevent quit notification from reappearing (#530) * shutdown sequence * Prevent quit notification from reappearing * Restrict force-finish broadcast * Cancel quit shutdown on relaunch * fix(wifi-aware): use bindSocket and scoped IPv6 instead of bindProcessToNetwork * Merge branch 'upstream/main' into fix/wifi-aware-socket-binding * Fix Wi-Fi Aware connectivity and UI integration post-merge - Replace bindProcessToNetwork with bindSocket for VPN compatibility. - Implement Scoped IPv6 address resolution (aware0) for mesh routing. - Bridge Wi-Fi Aware incoming messages to AppStateStore for UI visibility. - Fix syntax errors and variable name conflicts in Debug UI. * Enhance Wi-Fi Aware robustness and debug UI display - Clean up transport resources (sockets, server sockets, network callbacks) immediately on peer disconnection. - Implement resolveScopedAddress to show scoped IPv6 (e.g., %aware0) in Debug UI. - Fix Map type mismatch warning in ChatViewModel bridge. - Filter self-ID from peer cleanup tables to prevent recursive self-removal. * Share GossipSyncManager across transports to prevent redundant message synchronization - Registered BluetoothMeshService's GossipSyncManager as a singleton in MeshServiceHolder. - Modified WifiAwareMeshService to use the shared GossipSyncManager if available. - Added background cleanup for peer mappings on socket disconnection. - Fixed Kotlin type mismatch during nickname map merging. * Restore VPN acquisition logic and improve peer cleanup - Revert removal of NET_CAPABILITY_NOT_VPN to allow hardware handle acquisition while VPN is active. - Refactor handlePeerDisconnection to more reliably cleanup initial and routed IDs. - Switch cleanup logging to debug level to reduce log noise. --------- Co-authored-by: GitHub Action <action@github.com> Co-authored-by: aidenvalue <> * Fix wifi aware routing (#534) * Background persistence (#505) * persistence step 1 * fix build * messages in the background work, notifications not yet * app state store * DM icon shows up * notification launches when app is closed! * keep ui updated * lifecycle fixes * extensive logging, maybe revert later * send nickname in announcement * quit in notification * setting in about sheet * fix quit bitchat * lifecycle fixes * power mode based on background state * stats for both direciotns * fix graph persistence * better counting * count per device * only compute when debug sheet is open? untested * fix read receipts * fix read receipts fully * fix unread badge if messages have been read in focus * foreground promotion fix * fix app kill in notification * adjust to new tor * nice * about sheet design * bump version 1.6.0 (#524) * Automated update of relay data - Sun Dec 14 06:06:53 UTC 2025 * bump targetSdk (#526) * Automated update of relay data - Sun Dec 21 06:06:56 UTC 2025 * Automated update of relay data - Sun Dec 28 06:07:12 UTC 2025 * Prevent quit notification from reappearing (#530) * shutdown sequence * Prevent quit notification from reappearing * Restrict force-finish broadcast * Cancel quit shutdown on relaunch * fix(wifi-aware): use bindSocket and scoped IPv6 instead of bindProcessToNetwork * Merge branch 'upstream/main' into fix/wifi-aware-socket-binding * Fix Wi-Fi Aware connectivity and UI integration post-merge - Replace bindProcessToNetwork with bindSocket for VPN compatibility. - Implement Scoped IPv6 address resolution (aware0) for mesh routing. - Bridge Wi-Fi Aware incoming messages to AppStateStore for UI visibility. - Fix syntax errors and variable name conflicts in Debug UI. * Enhance Wi-Fi Aware robustness and debug UI display - Clean up transport resources (sockets, server sockets, network callbacks) immediately on peer disconnection. - Implement resolveScopedAddress to show scoped IPv6 (e.g., %aware0) in Debug UI. - Fix Map type mismatch warning in ChatViewModel bridge. - Filter self-ID from peer cleanup tables to prevent recursive self-removal. * Share GossipSyncManager across transports to prevent redundant message synchronization - Registered BluetoothMeshService's GossipSyncManager as a singleton in MeshServiceHolder. - Modified WifiAwareMeshService to use the shared GossipSyncManager if available. - Added background cleanup for peer mappings on socket disconnection. - Fixed Kotlin type mismatch during nickname map merging. * Restore VPN acquisition logic and improve peer cleanup - Revert removal of NET_CAPABILITY_NOT_VPN to allow hardware handle acquisition while VPN is active. - Refactor handlePeerDisconnection to more reliably cleanup initial and routed IDs. - Switch cleanup logging to debug level to reduce log noise. * fix wifi aware routing --------- Co-authored-by: GitHub Action <action@github.com> Co-authored-by: aidenvalue <> * unify connection tracker for ble and wifi (#537) * unify connection tracker for ble and wifi * cleanup nicely * Wifi aware skip bluetooth (#538) * unify connection tracker for ble and wifi * bluetooth optional * refactor mesh core * tests * share gossip * refresh peer list more often * patches: wifi aware mesh refactor core (#549) * Refactor WifiAware memory management and lifecycle handling * Fix Wi-Fi Aware reconnection by ensuring callback unregistration and session watchdog * fix(wifiaware): allow WifiAwareController to restart service if session drops * Enhance WiFi Aware logging with network request timeouts and detailed callback status * Ensure explicit release of WiFi Aware network callbacks on failure or disconnection --------- Co-authored-by: aidenvalue <> * fix: wifi aware mesh private dms (#561) * fix(wifi-aware): restore peer check and remove aggressive session restarts * synchronized access to sockets. * clear old peer socket `onClientConnected` if one was found. * address second round of review * fix: Restart publish session on termination in WifiAwareMeshService * fix: cleanup connection tracker resources when handling peer disconnection without active socket --------- Co-authored-by: aidenvalu3 <> * fix(mesh): address memory leaks and background persistence issues in Wi-Fi Aware - Move message persistence and background notifications for Wi-Fi Aware into the service layer via MeshCore hooks. - Fix memory leak in MainActivity by properly detaching WifiAwareMeshDelegate on pause. - Ensure BluetoothMeshService is initialized before WifiAwareMeshService to guarantee shared GossipSyncManager instance. - Deduplicate persistence logic from MainActivity delegate. * wifi aware working * more robust * fragments work * new files * wifi improvements * handshake works * improve * wifi mesh more robust * fix review * check for support * wifi aware fixes --------- Co-authored-by: aidenvalue <> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: aidenvalu3 <erendentman@gmail.com> Co-authored-by: a1denvalu3 <43107113+a1denvalu3@users.noreply.github.com> Co-authored-by: CC <cc@ggg.local> |
||
|
|
51a06cf0b7
|
Refactored BottomSheetTopBar to BitchatSheetTopBar (#601)
* Automated update of relay data - Sun Sep 21 06:21:05 UTC 2025 * Automated update of relay data - Sun Sep 28 06:20:40 UTC 2025 * refactor: new close button like ios(but not liquid glass) * Automated update of relay data - Sun Oct 5 06:20:09 UTC 2025 * Automated update of relay data - Sun Oct 12 06:20:12 UTC 2025 * Automated update of relay data - Sun Oct 19 06:21:51 UTC 2025 * Automated update of relay data - Sun Oct 26 06:21:31 UTC 2025 * Automated update of relay data - Sun Nov 2 06:22:16 UTC 2025 * Automated update of relay data - Sun Nov 9 06:21:43 UTC 2025 * Automated update of relay data - Sun Nov 16 06:22:37 UTC 2025 * Automated update of relay data - Sun Nov 23 06:22:51 UTC 2025 * Automated update of relay data - Sun Nov 30 06:24:08 UTC 2025 * Automated update of relay data - Sun Dec 7 06:22:59 UTC 2025 * Automated update of relay data - Sun Dec 14 06:24:33 UTC 2025 * Automated update of relay data - Sun Dec 21 06:24:49 UTC 2025 * Automated update of relay data - Sun Dec 28 06:25:38 UTC 2025 * Automated update of relay data - Sun Jan 4 06:26:28 UTC 2026 * Automated update of relay data - Sun Jan 11 06:26:19 UTC 2026 * feat: Add BitchatSheetTopBar component * Refactor: Use BitchatSheetTopBar in bottom sheets This commit refactors several bottom sheet components to use the new reusable `BitchatSheetTopBar` composable. This change provides a consistent look and feel for top bars across the following sheets: - DebugSettingsSheet - MeshPeerListSheet - LocationNotesSheet - LocationChannelsSheet - LocationNotesSheetPresenter (for the location unavailable state) The `BitchatSheetCenterTopBar` has been removed as its functionality is now covered by the more flexible `BitchatSheetTopBar`. * Refactor: Use BitchatSheetTopBar in MeshPeerListSheet --------- Co-authored-by: GitHub Action <action@github.com> |
||
|
|
dd856ac01f
|
visual logger refactor (#583) | ||
|
|
ce71de29f7
|
Feat/graph force (#581)
* mesh topology wip * graph * graph animated |
||
|
|
66012e9fe9
|
Gossip mesh topology + source-based routing (#445)
* wip mesh graph * gossip fix * gossip works * source-based routing wip * log * update spec to be explicit about intermediate hops only * drop duplicate hops * add to spec * test * forgot comma * source routing v2 * add compression bomb protection * v2 source routing * fragmented packets inherit route * update spec * Gossip routing tmp with connection limit fixed (#569) * fix: r8 exception for LocationManager (#566) * fragmented packets inherit route * update spec * fix connection limits * fix: deserialization issue with routed packets * log * dynamic fragment size * fragment size * add tests * feat(gossip): implement two-way handshake for source routing edges - Update MeshGraphService to track directed announcements - Require bidirectional announcements for a 'confirmed' edge - Update RoutePlanner to strictly use confirmed edges - Update Mesh Topology debug view to show confirmed vs unconfirmed edges (solid vs dotted) * docs: update SOURCE_ROUTING.md with two-way handshake requirement * evict stale peers from mesh graph service * better logging * fix announce spe * fix: empty route * fix spec * fix: compile error in DebugSettingsSheet and potential NPE in RoutePlanner * revert * try again |
||
|
|
654d385b6d
|
UI Refactor (#562)
* Automated update of relay data - Sun Sep 21 06:21:05 UTC 2025 * Automated update of relay data - Sun Sep 28 06:20:40 UTC 2025 * refactor: new close button like ios(but not liquid glass) * Automated update of relay data - Sun Oct 5 06:20:09 UTC 2025 * Automated update of relay data - Sun Oct 12 06:20:12 UTC 2025 * Automated update of relay data - Sun Oct 19 06:21:51 UTC 2025 * Automated update of relay data - Sun Oct 26 06:21:31 UTC 2025 * Automated update of relay data - Sun Nov 2 06:22:16 UTC 2025 * Automated update of relay data - Sun Nov 9 06:21:43 UTC 2025 * Automated update of relay data - Sun Nov 16 06:22:37 UTC 2025 * Automated update of relay data - Sun Nov 23 06:22:51 UTC 2025 * Automated update of relay data - Sun Nov 30 06:24:08 UTC 2025 * Automated update of relay data - Sun Dec 7 06:22:59 UTC 2025 * Automated update of relay data - Sun Dec 14 06:24:33 UTC 2025 * Automated update of relay data - Sun Dec 21 06:24:49 UTC 2025 * Automated update of relay data - Sun Dec 28 06:25:38 UTC 2025 * Automated update of relay data - Sun Jan 4 06:26:28 UTC 2026 * refactor: Extract CloseButton to core UI components * feat: Add BitchatBottomSheet component * refactor: Use BitchatBottomSheet component and minor ui change(CloseButton, colors) * Refactor: Use BitchatBottomSheet in MeshPeerListSheet --------- Co-authored-by: GitHub Action <action@github.com> |
||
|
|
fa1978d587
|
Revert "fix: wifi aware socket binding (#533)" (#535)
This reverts commit 0c7505b588b38b14f5b674ef6ec4d286cdb0f5c4. |
||
|
|
0c7505b588
|
fix: wifi aware socket binding (#533)
* wifi aware wip * wifi aware wip * starting to work * werk * dms work * wip * fix(wifi-aware): use bindSocket and scoped IPv6 instead of bindProcessToNetwork * Merge branch 'upstream/main' into fix/wifi-aware-socket-binding * Fix Wi-Fi Aware connectivity and UI integration post-merge - Replace bindProcessToNetwork with bindSocket for VPN compatibility. - Implement Scoped IPv6 address resolution (aware0) for mesh routing. - Bridge Wi-Fi Aware incoming messages to AppStateStore for UI visibility. - Fix syntax errors and variable name conflicts in Debug UI. * Enhance Wi-Fi Aware robustness and debug UI display - Clean up transport resources (sockets, server sockets, network callbacks) immediately on peer disconnection. - Implement resolveScopedAddress to show scoped IPv6 (e.g., %aware0) in Debug UI. - Fix Map type mismatch warning in ChatViewModel bridge. - Filter self-ID from peer cleanup tables to prevent recursive self-removal. * Share GossipSyncManager across transports to prevent redundant message synchronization - Registered BluetoothMeshService's GossipSyncManager as a singleton in MeshServiceHolder. - Modified WifiAwareMeshService to use the shared GossipSyncManager if available. - Added background cleanup for peer mappings on socket disconnection. - Fixed Kotlin type mismatch during nickname map merging. * Restore VPN acquisition logic and improve peer cleanup - Revert removal of NET_CAPABILITY_NOT_VPN to allow hardware handle acquisition while VPN is active. - Refactor handlePeerDisconnection to more reliably cleanup initial and routed IDs. - Switch cleanup logging to debug level to reduce log noise. --------- Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com> Co-authored-by: aidenvalue <> |
||
|
|
3f8c236a72
|
Background persistence (#505)
* persistence step 1 * fix build * messages in the background work, notifications not yet * app state store * DM icon shows up * notification launches when app is closed! * keep ui updated * lifecycle fixes * extensive logging, maybe revert later * send nickname in announcement * quit in notification * setting in about sheet * fix quit bitchat * lifecycle fixes * power mode based on background state * stats for both direciotns * fix graph persistence * better counting * count per device * only compute when debug sheet is open? untested * fix read receipts * fix read receipts fully * fix unread badge if messages have been read in focus * foreground promotion fix * fix app kill in notification * adjust to new tor * nice * about sheet design |
||
|
|
fc3a00b4b9
|
fix: Resolve debug settings bottom sheet crash on some devices (#474)
Fixes #472 - App crashing in debug settings The issue was in ui/debug/DebugSettingsSheet.kt: - Line 304: Code was pre-formatting double value with String.format() then passing to string resource that expected raw double parameter - Line 307: Numeric values weren't properly converted to strings for string resource that expected string parameters Changes made: - Changed stringResource(R.string.debug_target_fpr_fmt, String.format("%.2f", gcsFpr)) to stringResource(R.string.debug_target_fpr_fmt, gcsFpr) - passes raw double value - Changed stringResource(R.string.debug_derived_p_fmt, p, nmax) to stringResource(R.string.debug_derived_p_fmt, p.toString(), nmax.toString()) - properly converts numeric values to strings This resolves the IllegalFormatConversionException: f != java.lang.String crash when scrolling through the debug settings bottom sheet. |
||
|
|
ad28cc710c
|
Translations (#467)
* english done * de * more extraction * wip strings en * translations work * remove unneeded translations * remove notification message * add languages * new languages |
||
|
|
4eda850110
|
better verbose logging (#431) | ||
|
|
73c91b9509
|
Plumtree sync (#393)
* wip plumtree * sync works * fix logging * ttl to 0 * fix send packet to one peer * spec * wip GCS instead of bloom * remove bloom filter remainders * clean * prune old announcements * remove announcements from sync after LEAVE * sync after 1 second * pruning * track own announcement and prune messages without announcements * fix pruning * getGcsMaxFilterBytes default value 400 bytes * parameters |
||
|
|
c1e56188d6
|
Revert "Mesh gossip (#381)" (#394)
This reverts commit 0969c0641eeb272462ef0d5c21f7b0b3cd6b8bea. |
||
|
|
0969c0641e
|
Mesh gossip (#381)
* wip mesh graph * gossip fix * gossip works * source-based routing wip * log |
||
|
|
b131554efe
|
fix some debug settings (#383) | ||
|
|
f47819a31e
|
Debug button (#377)
* feat(debug): add DebugSettingsManager + DebugSettingsSheet scaffold and AboutSheet entry; groundwork for verbose logging, GATT controls, relay stats, device/scan views * fix(debug): wire debug sheet launch via onShowDebug in AboutSheet from ChatScreen; add public start/stop server/client methods} * fix(about): remove misplaced debug item block inside PoW section; keep debug launcher managed by ChatScreen only * feat(debug): wire DebugSettingsSheet role switches to explicit startServer/stopServer and startClient/stopClient; expose role controls + disconnectAll on BluetoothConnectionManager; fix syntax error; build passes * feat(debug): add connect/disconnect helpers; wire DebugSettingsSheet connect/disconnect actions to BluetoothConnectionManager * feat(debug): add debug settings button at bottom of AboutSheet; wire onShowDebug callback to open DebugSettingsSheet from ChatScreen * feat(debug): wire verbose logging into chat view via DebugSettingsManager; add rolling relay stats; push connected devices and scan results; ensure GATT role stop closes connections; log incoming packets and relay events; add UI polling for devices; build passes * chore(debug-branch): remove unrelated files that were mistakenly added in first commit; keep only intended debug settings changes * fix(chat): prevent mesh→geohash leak Root cause: - DebugSettingsManager→chat bridge appended system logs to the global timeline regardless of active channel - MeshDelegateHandler added public mesh messages to UI unconditionally Fixes: - Only inject debug system messages when selected location channel is Mesh - Only add public mesh messages to UI when Mesh is selected (still send notifications) Build: ./gradlew assembleDebug } * fix(timeline): restore message persistence across channel switches Root cause: - NostrGeohashService.switchLocationChannel() called messageManager.clearMessages() which wiped ALL messages (mesh + debug + geohash) from main timeline - Geohash events were adding to main timeline, causing cross-contamination Fixes: - Remove messageManager.clearMessages() from channel switching - ChatScreen displayMessages now routes to separate storage: - Mesh: messages (main timeline, includes debug logs when Mesh selected) - Geohash: viewModel.getGeohashMessages(geohash) from separate history - Private: privateChats[peerID] - Channels: channelMessages[channel] - Geohash events no longer add to main timeline, only to geohash history - Mesh messages always stored to preserve history when switching away Result: Each chat type has persistent separate storage, no message loss * Debug/relay logs: use MessageType names; include device route in verbose packet logs. * Verbose device-peer assignment and connection/disconnection logs with peerId, deviceId, nickname; packet relay log uses MessageType names.} * Debug logs API: include nickname and deviceId for incoming/relay; update callers.} * Fix compile: import MessageType; correct debug manager API usage and remove stray insertion; build.} * Respect relay toggle; helper to log relay with deviceId.} * PacketRelayManager: add relay toggle and unified logging helper; clean file header comments; build fixes.} * changes * Geohash local echo: do not add to mesh timeline; rely on geohash history and ChatScreen display for location channels. * persisting * persist debug settings * gitignore * gatt server / client controls * debugger * max connection settings and graph * more graph * better logging * refactor logging |