43 Commits

Author SHA1 Message Date
callebtc
81a35d9dba ui: use shared green CloseButton in private and channel headers
Align conversation exit controls with bottom-sheet close chrome so the X reads as primary green rather than muted grey.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 17:58:36 +02:00
callebtc
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
2026-07-27 17:33:11 +02:00
Ruslan
92d07b22fa
ui: refresh chat branding and text message layout (#767)
* Add BitChatBrandButton and BitChatIcon

Add a dedicated brand button component and custom vector icon to the UI library. Refactor the chat header to use this component, replacing the previous modifier-based multi-click implementation.

* **BitChatBrandButton**: A new Composable that encapsulates single and triple click detection logic using coroutine delays and tap counting.
* **BitChatIcon**: A custom pixel-style `ImageVector` representing the brand.
* **ChatHeader**: Updated to use the new brand button and included a visual separator (`/`) in the layout.
* **ModifierExt.kt**: Removed the `singleOrTripleClickable` extension as its functionality is now handled internally by the brand button component.

* ui: refactor text messages to two-row layout

Refactor the message list items to use a two-row layout for standard text messages, while preserving the legacy compact format for system messages.

*   **UI Formatting**: Added `formatTextMessageSender`, `formatTextMessageMetadata`, and `formatTextMessageBody` in `ChatUIUtils.kt` to separate the rendering of sender info, timestamps/PoW, and message content.
*   **Layout Change**: Replaced the single-block `Text` component with a `Column` containing a `Row` (Sender + Metadata) and a message body `Text` block for standard messages.
*   **Interaction**: Updated `pointerInput` and `detectTapGestures` to handle nickname clicks in the header row and geohash/URL clicks within the message body row.
*   **Styling**: Refined `appendIOSFormattedContent` to support a `contentColor` parameter and applied specific font weights and colors (e.g., orange for self-messages) to match the platform's design language.
*   **System Messages**: Explicitly kept messages where `sender == "system"` on the original compact layout.

* refactor(ui): extract annotated text pointer handling

* fix(ui): address chat redesign review feedback

* fix(ui): align PoW animation with text layout

* refactor(ui): extract message interaction helpers

---------

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
2026-07-27 00:54:51 +02:00
callebtc
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>
2026-06-16 12:11:33 -05:00
yet300
94b28b2107
Move PrivateChatSheet hosting into ChatDialogs and unify sheet state (#586)
* 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: Show private chat in sheet from notification

* Refactor: Hoist private chat sheet state to ChatViewModel

* remove icon

* remove old bottom sheet

---------

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
2026-01-14 17:12:40 +07:00
callebtc
123a24ce34
Revert "Fix small-screen header clipping (#519) (#532)" (#548)
This reverts commit d73976537d6df37f794063c4b6e94981ec6af96e.
2026-01-04 21:08:52 +07:00
yet300
c663e8ede0
QR and Verification feature (#529)
* 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

* feat: Add ZXing dependency for QR code scanning

* feat: Request camera permission for QR verification

* Add QR verification payloads and mesh wiring

* Wire verification state, system messages, and notifications

* Add verification sheets and UI affordances

* Show verified badges in sidebar and add strings

* Persist fingerprint caches for offline verification

* Handle bitchat://verify deep links

* feat: Replace zxing-android-embedded with ML Kit and CameraX

* Refactor(Verification): Replace zxing with MLKit for QR scanning

* Replace `AndroidView` with `CameraXViewfinder` for camera preview

* Refactor QR verification: Extract VerificationHandler and fix concurrency issues

* Extract and translate strings for QR verification feature

* Fix build errors: Escape ampersands in strings and restore missing methods in ChatViewModel

* return to main

* return to main 2

---------

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
2026-01-04 16:29:07 +07:00
kargathara Aakash
d73976537d
Fix small-screen header clipping (#519) (#532)
* Fix small-screen header clipping: reserve status-bar space and center-constrain titles (fixes #519)

* Remove redundant Gradle configuration lines
2026-01-04 13:57:55 +07:00
yet300
e96330e50b
Migrate from LiveData to Kotlin Flow (#518)
* 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

* Chore: Remove unused `lifecycle-livedata-ktx` dependency

This commit removes the `androidx.lifecycle:lifecycle-livedata-ktx` library from the project's dependencies.

The `[libraries]` and `[bundles]` sections in `gradle/libs.versions.toml` have been updated to reflect this removal, as the dependency is no longer in use.

* Refactor: Remove unused `runtime-livedata` dependency

* Refactor: Migrate `LocationChannelManager` and `GeohashBookmarksStore` to StateFlow

This commit refactors `LocationChannelManager` and `GeohashBookmarksStore` to use `StateFlow` instead of `LiveData` for managing and exposing their state. This change aligns with modern Android development practices and improves testability.

**Key Changes:**

- **`LocationChannelManager`**:
    - All `MutableLiveData` properties (`permissionState`, `availableChannels`, `selectedChannel`, etc.) have been replaced with `MutableStateFlow`.
    - Consumers now access these properties as `StateFlow`.
    - State updates have been changed from `postValue()` to direct `.value` assignments, simplifying thread management within the manager which already uses a dedicated coroutine scope.

- **`GeohashBookmarksStore`**:
    - `bookmarks` and `bookmarkNames` are now exposed as `StateFlow` instead of `LiveData`.
    - State updates similarly use `.value` assignment.

- **Nullability**:
    - The non-nullable nature of `StateFlow`'s value reduces the need for null-checks in both the manager classes and their consumers, leading to safer code.

* Refactor: Migrate from LiveData to StateFlow for Nostr components

This commit replaces `LiveData` with `StateFlow` across core Nostr-related classes to align with modern Android architecture and improve state management. This change affects `NostrClient`, `NostrRelayManager`, `LocationNotesManager`, and `GeohashRepository`.

**Key Changes:**

-   **`NostrClient`**:
    -   `isInitialized` and `currentNpub` are now `StateFlow` instead of `LiveData`.
    -   `relayConnectionStatus` and `relayInfo` now return `StateFlow` from `NostrRelayManager`.

-   **`NostrRelayManager`**:
    -   Public properties `relays` and `isConnected` are migrated from `MutableLiveData` to `MutableStateFlow`.
    -   Updates are now pushed using `.value` instead of `.postValue()`.

-   **`LocationNotesManager`**:
    -   All public `LiveData` properties (`notes`, `geohash`, `initialLoadComplete`, `state`, `errorMessage`) are converted to `StateFlow`.
    -   The class documentation is updated to reflect the use of `StateFlow`.

-   **`GeohashRepository`**:
    -   Methods `updateGeohashPeople` and `updateReactiveParticipantCounts` now call `set...` methods on the `state` object instead of `post...`, reflecting the removal of `LiveData` from the underlying state management.

* Refactor: Migrate ChatState from LiveData to StateFlow

This commit refactors the `ChatState`, `ChatViewModel`, and `GeohashViewModel` to use `StateFlow` instead of `LiveData` for managing and exposing UI state. This migration improves state management by leveraging modern coroutine-based flows.

**Key Changes:**

- **`ChatState.kt`**:
    - Replaced all `MutableLiveData` instances with `MutableStateFlow`.
    - Exposed state properties as `StateFlow` instead of `LiveData`.
    - Removed `MediatorLiveData` for computed properties (`hasUnreadChannels`, `hasUnreadPrivateMessages`) and replaced them with `Flow.combine` to create derivative `StateFlows`.
    - Simplified non-nullable `getters` to directly return the `.value` of the `StateFlows`.
    - Removed `postValue` helpers that are no longer necessary.

- **`ChatViewModel.kt`**:
    - Updated all state properties to be `StateFlow`, reflecting the changes in `ChatState`.

- **`GeohashViewModel.kt`**:
    - Changed state properties (`geohashPeople`, `geohashParticipantCounts`, etc.) from `LiveData` to `StateFlow`.
    - Replaced `observeForever` on `LiveData` from `LocationChannelManager` with `viewModelScope.launch` blocks that `.collect()` from the underlying flows.

* Refactor: Migrate UI from LiveData to StateFlow

This commit replaces `LiveData.observeAsState()` with `StateFlow.collectAsState()` across various UI components. This change aligns the codebase with modern Android development practices, using Kotlin Flows for reactive UI state management.

No functional changes are intended. The primary goal is to remove the dependency on `androidx.lifecycle.livedata` from the composable functions.

**Affected Components:**
- `ChatScreen`
- `SidebarComponents`
- `ChatHeader`
- `LocationChannelsSheet`
- `LocationNotesSheet`
- `LocationNotesButton`
- `GeohashPeopleList`
- `LocationNotesSheetPresenter`

* Refactor: Use `collectAsStateWithLifecycle` for UI state collection

* Refactor: move CloseButton to core/ui/component

* Refactor: remove AI generated comments

* Refactor: fix combine to map and use WhileSubscribed

* Refactor: Pass CoroutineScope to ChatState

This commit refactors the `ChatState` class to accept a `CoroutineScope` in its constructor instead of creating its own.

**Key Changes:**

- **`ChatState.kt`**: The constructor now requires a `CoroutineScope`. This scope is used for the `stateIn` operators that convert `Flows` into `StateFlows` (`hasUnreadChannels`, `hasUnreadPrivateMessages`), ensuring they operate within the lifecycle of the provided scope.
- **`ChatViewModel.kt`**: The `viewModelScope` is now passed to the `ChatState` constructor during its instantiation. This ties the lifecycle of the state's coroutines directly to the `ViewModel`'s lifecycle.

* Test: Use `TestScope` for coroutines in `CommandProcessorTest`

This commit refactors `CommandProcessorTest` to use a `TestScope` and `UnconfinedTestDispatcher` for managing coroutines.

This ensures that coroutine-based operations within the test are executed in a controlled and predictable manner, improving test reliability. The `coroutineScope` for `CommandProcessor` and the `scope` for `ChatState` are now both configured to use this test-specific scope.

---------

Co-authored-by: GitHub Action <action@github.com>
2025-12-13 15:58:48 +07:00
Moe Hamade
b2febcee88
feat: add product flavors and TorProvider abstraction (#508)
* feat: add product flavors and TorProvider abstraction

Introduces build flavors to separate Tor functionality from the standard build, reducing APK size for users who don't need Tor.

- Creates `standard` and `tor` product flavors.
- The `standard` flavor is the default, lightweight build.
- The `tor` flavor includes the Arti (Tor) dependency and is identified by the `.tor` application ID suffix.
- Adds a `TorProvider` interface and a `TorProviderFactory` to abstract Tor implementation details between flavors.

Prepares architecture for optional Tor support to reduce APK size
from 142MB to ~4-5MB for standard builds

Related to #454

* Refactor: implement StandardTorProvider and RealTorProvider

This commit refactors the Tor integration by introducing a `TorProvider` interface and creating separate implementations for 'tor' and 'standard' product flavors.

- The original `TorManager` singleton has been moved into `RealTorProvider` for the 'tor' flavor.
- A no-op `StandardTorProvider` is introduced for the 'standard' flavor, which reports Tor as unavailable.
- A `TorProviderFactory` is used to create the appropriate provider at runtime based on the build variant.

* refactor: migrate to TorProvider abstraction

Replaced direct calls to the static `TorManager` with an instance obtained from `TorProviderFactory`.

This change allows for different Tor implementations based on build flavors, improving modularity and abstracting the Tor provider logic.

Updated `BitchatApplication`, `ChatHeader`, `OkHttpProvider`, and `AboutSheet` to use the new factory pattern for accessing Tor functionalities.

* build: add flavor-specific ProGuard rules and CI/CD

 - Split ProGuard rules: base, standard-specific, tor-specific
  - Move Arti/Guardian Project rules to proguard-tor.pro
  - Update CI/CD workflow to build both flavors
  - Add separate artifact uploads for each flavor
  - Add descriptive release notes template

  CI now builds both standard (~4-5MB) and tor (~140MB) APKs."

  resolves #454

* refactor: centralize network reset logic

Extracts the repeated network connection reset logic into a new private function `resetNetworkConnections()`.

This change also replaces direct `_statusFlow.value = ...` assignments with the safer `_statusFlow.update { ... }` function to prevent race conditions.

* ci: run separate build steps for flavors

* feat: disable Tor toggle if not available in build

* ci: parallelize builds and add conditional tor lint

Optimizes CI workflow:
- Parallel matrix builds (4 runners instead of sequential)
- Conditional tor lint only when app/src/tor/ changes in PRs
- Merged test+lint jobs to reduce setup overhead

Reduces CI time by ~50% (8-11 min vs 18-26 min)

* refactor: Unify Tor implementation and remove build flavors

This commit refactors the Tor integration by removing the `standard` and `tor` product flavors in favor of a single, unified build that always includes a custom-built Arti (Tor) library.

Key changes include:
*   **Removed Build Flavors:** Deleted the `standard` and `tor` product flavors from `build.gradle.kts`, simplifying the build process and CI configuration.
*   **Unified Tor Manager:** Replaced the `TorProvider` interface and flavor-specific implementations (`StandardTorProvider`, `RealTorProvider`) with a new singleton, `ArtiTorManager`. This class now manages the Arti lifecycle for all builds.
*   **Custom Arti Wrapper:** Introduced a new `ArtiProxy` class to provide a compatible API wrapper around the custom-built native Arti library (`libarti_android.so`). This replaces the dependency on the external `arti-mobile-ex` library.
*   **Updated Proguard:** Consolidated and updated Proguard rules into the main `proguard-rules.pro` file to keep the necessary `ArtiTorManager` and native library classes.
*   **CI/CD Simplification:** Updated GitHub Actions workflows (`release.yml`, `android-build.yml`) to build and release a single APK instead of separate ones for each flavor.

* build: Configure ABI filters for debug and release builds

For debug builds, include `x86_64` to support emulators.

For release builds, only include `arm64-v8a` to minimize the final APK size.

* feat: Ignore jniLibs directory

This change adds the `app/src/main/jniLibs/` directory to the `.gitignore` file to prevent native libraries from being committed to the repository.

* feat: Refine .gitignore for Arti build artifacts

Improves the `.gitignore` file by:
- Ignoring all `build/` directories except for `tools/arti-build/`.
- Adding specific ignores for Arti build artifacts, including the cloned source repository and the Rust build cache directory.

* feat: Update arti android native library

* feat: add build script and JNI wrapper for Arti

Adds a comprehensive build system for creating custom Arti (Tor in Rust) shared libraries for Android. This replaces the dependency on external, outdated AARs with a fully transparent and reproducible build process.

Key changes:
- Introduces `build-arti.sh`, a script to clone the official Arti repository, apply a JNI wrapper, and build `.so` files for Android.
- Adds `ARTI_VERSION` to pin the build to a specific Arti release (v1.7.0).
- Implements a new Rust JNI wrapper (`src/lib.rs`) that exposes core functions like `initialize`, `startSocksProxy`, and `stop` to the Android app.
- Includes a `Cargo.toml` with release profile optimizations for size (`lto`, `strip`, `opt-level = "z"`).
- Provides detailed documentation in `README.md` explaining the build process, prerequisites, and architecture.

* build script for mac

* consolidate both scripts

* improve script

---------

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
2025-12-12 23:27:52 +07:00
callebtc
f99cb46b26
Location notes (#482)
* try 1

* works

* equalize UI with ios

* ui cleanup

* geohash chats: no building

* load notes in background

* insta

* simplify and tor icon change

* icons nice

* refactor

* unify location enabled / disabled

* cooler

* simplify, doesnt subscribe right away

* load when clicked

* plus minus location notes

* load when tor is available

* translations

* fix transalations

* implement review comments
2025-10-18 14:19:53 +02:00
callebtc
ad28cc710c
Translations (#467)
* english done

* de

* more extraction

* wip strings en

* translations work

* remove unneeded translations

* remove notification message

* add languages

* new languages
2025-10-12 18:54:20 +02:00
lollerfirst
779717217f
feat: geohash bookmarks (iOS parity) (#410)
* Geohash bookmarks (iOS parity):
- Add GeohashBookmarksStore (persist bookmarks + friendly names)
- Integrate bookmark toggle into LocationChannelsSheet (nearby + bookmarked sections)
- Add header toggle for current geohash bookmark
- Sample counts for union of nearby + bookmarks while sheet open
- Add Geohash.decodeToBounds() to support friendly name resolution
- Fix coroutine usage and Gson type inference issues

* fix UI

* clear bookmarks on triple tap

* adjust icons

---------

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
2025-09-14 03:46:37 +02:00
callebtc
998ee606b1
Nostr refactor simplify (#390)
* fix bug

* geoDM receive works, send doesnt, and incoming message doesnt make sender appear in peer list

* fix nostr dm

* geohash dms work

* Geohash DM UI: stop mixing Nostr DM temp chats into mesh offline list; ensure geohash DM senders are added to geohash people list only. Removed nostr_* sidebar append in PeopleSection; kept 64-hex mesh offline favorites. Verified build.

* refactor

* nice

* works

* merging nostr -> mesh works

* tripple click to delete all

* fix sidebar icon

* remove hash

* dms have correct recipient

* works

* wip unread badge

* geohash dms wip

* dms work
2025-09-08 13:46:15 +02:00
callebtc
b62b15a21f
Nip13 pow (#357)
* add pow

* animation

* matrix style

* animation better

* improve animation

* improve animation

* works

* fix jump

* difficulty indicator

* 10 is default

* animation runs forever

* pow in message timestamp

* pow works

* default on

* adjust animation

* no printing
2025-08-31 13:23:22 +02:00
callebtc
6b77eb93c1
move tor icon (#355) 2025-08-30 13:57:50 +02:00
callebtc
686e2e78ec
Bundle tor (#339)
* tor started

* tor works

* tor code

* improve manager

* works

* move tor icon

* werks

* arti works

* arti works

* arti works with reconnect

* delay fix

* refactor
2025-08-29 14:37:35 +02:00
callebtc
6fe6e049ad
Nip17 dms to extend the mesh (#313)
* favorite each other

* show favorites as system messsages

* wip show glove when offline but mayb edoesnt work

* send and receive works

* wip kinda works but no

* getting there

* kinda

* show offline peers in peer list

* kinda wonky but almost works

* fixes

* nostr user goes offline works

* nostr -> mesh works

* handoff works

* background message processing

* read works

* seen message store was missing
2025-08-25 18:38:10 +02:00
shroominic
47c40fb9f3
fix nip-17 (#305)
* NIP-59 stuff

* nip-17 ios to androing works, android to ios still wip

* fix impl

* ios compat

* default relays for DMs

* delivery ack works

* delivery ack

---------

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
2025-08-24 19:06:29 +02:00
callebtc
37c8c79310
UI changes and fixes (#301)
* country -> region, region –> province

* revise clicks

* fix longpress for mention etc

* scroll down button wip

* fix distance

* fix button

* fix header icon
2025-08-23 21:18:36 +02:00
callebtc
2458b471ed
UI fixes 2 (#282)
* better icon

* scroll

* scroll bottom sheet
2025-08-22 22:27:35 +02:00
callebtc
7243d841a3
Nostr geohash (#276)
* first nostr build

* add test file

* internet access

* fix relay manager

* fix serialization

* demo service - remove later

* fix nostr

* event dedupe

* dedupe

* ui wip

* can send messages

* subscription works

* works

* favs

* works

* delete chat on change

* fix mentions

* remove autojoin channels

* styling

* adjust colors

* ui changes

* live updates working

* use local timestamp

* message history in background

* robust

* fixes

* nicknames refresh optimization

* nostr service

* refactor nostr

* style

* geohash works

* centralize colors

* refactoring

* disable DMs for now: click on peer nickname doesnt open chat list in geohash mode

* use local time

* less logging

* robustness

* scroll nickname

* adjust some text
2025-08-22 19:09:18 +02:00
Tair
8bf2220cea
Make Sidebar react to the nickname and RSSI changes. (#228) 2025-08-06 00:06:47 +02:00
callebtc
4cb5932fd0
improve identity announcements (#198)
* improve identity announcements

* touches

* signing noise id

* panic mode delete signing key
2025-07-31 06:26:41 +02:00
callebtc
4b1d6f8c04
UI improvements (#192)
* bitchat logo

* improve ui
2025-07-25 20:02:59 +02:00
callebtc
c9aba00478
Dm header icons reactive (#190)
* header reactive to noise session

* favorite button reactive

* icon change

* nice
2025-07-25 19:50:40 +02:00
callebtc
c3c395832c
Implement Noise XX Handshake Protocol for Direct Messages (#180)
* noise

* works?

* noise

* temporary

* better

* wip: use subnet

* better

* barely working

* werk

* subnet

* fix peer ID

* 8 byte peer ID

* wip noise

* wip fixes for noise

* std lib for noise

* noise handshake one step further

* buffers

* use fork

* fix imports

* simplify counter

* remove trash

* hashing

* no prologue

* nice

* wip, use noise encryption

* peer ID hex

* simplify session manager

* heavy logging

* use singleton

* Fix Noise session race condition with elegant per-peer actor serialization

- Use Kotlin coroutine actors for per-peer packet processing
- Each peer gets dedicated actor that processes packets sequentially
- Eliminates race conditions in session management without complex locking
- Single surgical change in PacketProcessor - minimal, maintainable
- Leverages Kotlin's native concurrency primitives

* decrypt correctly

* iniator works now

* clean code and fix signature to null

* better

* no signature in private message

* small fixes

* refactor ack

* refactor but untested

* messages working

* wip ack

* wip fix ack

* more logging

* pending tracker

* keep pending connections on errors

* less logging

* refactor model

* refactor frombinarydata

* idendityannouncement refactor and update to new binary protocol

* fix keys

* refix keys

* dms work

* revert to mainnet

* do not change bluetooth adapter name

* keep code but uncomment

* clean up comments

* cleanup comments
2025-07-24 12:01:46 +02:00
callebtc
50cbb69e9e
Merge pull request #145 from moehamade/fix/toolbar-center-align-141
fix: center align toolbar item in ChatHeader
2025-07-18 00:08:09 +02:00
Mohamad Hamade
0611baa681 fix: center align toolbar item in ChatHeader
- passed modifier.fillmaxHeight so the content inside the row can actually be centered
2025-07-17 13:49:31 +03:00
Mohamad Hamade
17472a1854 Refactor: Remove unused tripleClickCount state variable
The `tripleClickCount` mutable state variable in the `ChatHeader` composable was not being used and has been removed to simplify the code
2025-07-15 13:18:29 +03:00
Mohamad Hamade
0a33bd734d Bugfix: Handled single or triple clicked at once instead of executing them as separate events
This commit introduces a new `singleOrTripleClickable` Modifier extension function.

This function allows distinguishing between single and triple clicks on a Composable element.

The `ChatHeader` was updated to utilize this new Modifier for handling clicks on the "bitchat*" title, where a single click shows app info and a triple click triggers a separate action.
2025-07-14 22:16:19 +03:00
callebtc
a97e2549b8 fix fav updates 2025-07-12 17:11:19 +02:00
callebtc
ea25b71d6f fix favorites 2025-07-12 16:55:50 +02:00
callebtc
50995c670f orange 2025-07-12 02:55:14 +02:00
callebtc
759ebaec93 buttons 2025-07-12 02:49:49 +02:00
callebtc
a9995ebfc1 like 2025-07-12 02:45:59 +02:00
callebtc
006ac7e78a buttons 2025-07-12 02:37:51 +02:00
callebtc
83da8f3b1b input 2025-07-12 02:34:56 +02:00
callebtc
472c6e8d51 design 2025-07-10 00:29:22 +02:00
callebtc
efbdf8c6ff icons 2025-07-10 00:20:03 +02:00
callebtc
caf494c1bf ui 2025-07-10 00:17:22 +02:00
callebtc
215383e012 design 2025-07-10 00:03:15 +02:00
callebtc
6d22aa7315 nice 2025-07-09 00:34:47 +02:00