From 562aa787d6a93b144915d49c4f85bb48c2ff1bf9 Mon Sep 17 00:00:00 2001
From: callebtc <93376500+callebtc@users.noreply.github.com>
Date: Mon, 27 Jul 2026 12:49:57 +0200
Subject: [PATCH] fix location channel layout
---
.../android/ui/LocationChannelsSheet.kt | 201 ++++++++++--------
app/src/main/res/values/strings.xml | 3 +-
2 files changed, 115 insertions(+), 89 deletions(-)
diff --git a/app/src/main/java/com/bitchat/android/ui/LocationChannelsSheet.kt b/app/src/main/java/com/bitchat/android/ui/LocationChannelsSheet.kt
index cb43cab0..bd8f2b9d 100644
--- a/app/src/main/java/com/bitchat/android/ui/LocationChannelsSheet.kt
+++ b/app/src/main/java/com/bitchat/android/ui/LocationChannelsSheet.kt
@@ -257,53 +257,129 @@ fun LocationChannelsSheet(
}
}
- // Location channels: globe + title, geohash subtitle, nearby levels + teleport
+ item(key = "location_channels_header") {
+ SheetIconSectionHeader(
+ icon = Icons.Outlined.Public,
+ title = stringResource(R.string.location_channels_heading),
+ subtitle = stringResource(R.string.location_channels_desc),
+ modifier = Modifier.padding(top = 20.dp)
+ )
+ }
+
+ selectedChannelOutsideNearby?.let { channel ->
+ item(key = "teleported_card") {
+ val coverage = coverageString(channel.geohash.length)
+ val name = bookmarkNames[channel.geohash]
+ val subtitle = "#${channel.geohash} • $coverage" +
+ (name?.let { " • ${formattedNamePrefix(channel.level)}$it" } ?: "")
+ val participantCount = geohashParticipantCounts[channel.geohash] ?: 0
+ val isBookmarked = bookmarksStore.isBookmarked(channel.geohash)
+
+ Column {
+ AboutSectionLabel(text = stringResource(R.string.cd_teleported))
+ Surface(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = AboutHorizontalPadding),
+ color = palette.surface,
+ shape = AboutCardShape
+ ) {
+ ChannelOptionRow(
+ title = geohashHashTitleWithCount(
+ channel.geohash,
+ participantCount
+ ),
+ subtitle = subtitle,
+ isSelected = true,
+ participantCount = participantCount,
+ titleColor = standardGreen,
+ titleBold = participantCount > 0,
+ trailingContent = {
+ ChannelBookmarkButton(
+ bookmarked = isBookmarked,
+ onClick = {
+ bookmarksStore.toggle(channel.geohash)
+ }
+ )
+ },
+ onClick = {
+ locationManager.select(ChannelID.Location(channel))
+ onDismiss()
+ }
+ )
+ }
+ }
+ }
+ }
+
+ if (bookmarks.isNotEmpty()) {
+ item(key = "bookmarks_card") {
+ Column {
+ AboutSectionLabel(text = stringResource(R.string.bookmarked))
+ Surface(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = AboutHorizontalPadding),
+ color = palette.surface,
+ shape = AboutCardShape
+ ) {
+ Column {
+ bookmarks.forEachIndexed { index, gh ->
+ if (index > 0) SheetCardDivider()
+ val level = levelForLength(gh.length)
+ val channel = GeohashChannel(level = level, geohash = gh)
+ val coverage = coverageString(gh.length)
+ val name = bookmarkNames[gh]
+ val subtitle = "#$gh • $coverage" +
+ (name?.let { " • ${formattedNamePrefix(level)}$it" } ?: "")
+ val participantCount = geohashParticipantCounts[gh] ?: 0
+
+ ChannelOptionRow(
+ title = geohashHashTitleWithCount(gh, participantCount),
+ subtitle = subtitle,
+ isSelected = isChannelSelected(channel, selectedChannel),
+ participantCount = participantCount,
+ titleBold = participantCount > 0,
+ trailingContent = {
+ ChannelBookmarkButton(
+ bookmarked = true,
+ onClick = { bookmarksStore.toggle(gh) }
+ )
+ },
+ onClick = {
+ val inRegional =
+ availableChannels.any { it.geohash == gh }
+ locationManager.setTeleported(
+ !inRegional && availableChannels.isNotEmpty()
+ )
+ locationManager.select(ChannelID.Location(channel))
+ onDismiss()
+ }
+ )
+ LaunchedEffect(gh) {
+ bookmarksStore.resolveNameIfNeeded(gh)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Nearby location channels and the control for teleporting somewhere new.
item(key = "channels_card") {
Column {
- SheetIconSectionHeader(
- icon = Icons.Outlined.Public,
- title = stringResource(R.string.location_channels_heading),
- subtitle = stringResource(R.string.location_channels_desc),
- modifier = Modifier.padding(top = 20.dp)
+ AboutSectionLabel(
+ text = stringResource(R.string.location_channels_nearby)
)
Surface(
modifier = Modifier
.fillMaxWidth()
- .padding(horizontal = AboutHorizontalPadding)
- .padding(top = 10.dp),
+ .padding(horizontal = AboutHorizontalPadding),
color = palette.surface,
shape = AboutCardShape
) {
Column {
- selectedChannelOutsideNearby?.let { channel ->
- val coverage = coverageString(channel.geohash.length)
- val name = bookmarkNames[channel.geohash]
- val subtitle = "#${channel.geohash} • $coverage" +
- (name?.let { " • ${formattedNamePrefix(channel.level)}$it" } ?: "")
- val participantCount = geohashParticipantCounts[channel.geohash] ?: 0
- val isBookmarked = bookmarksStore.isBookmarked(channel.geohash)
-
- ChannelOptionRow(
- title = geohashTitleWithCount(channel, participantCount),
- subtitle = subtitle,
- isSelected = true,
- participantCount = participantCount,
- titleColor = standardGreen,
- titleBold = participantCount > 0,
- trailingContent = {
- ChannelBookmarkButton(
- bookmarked = isBookmarked,
- onClick = { bookmarksStore.toggle(channel.geohash) }
- )
- },
- onClick = {
- locationManager.select(ChannelID.Location(channel))
- onDismiss()
- }
- )
- SheetCardDivider()
- }
-
if (locationServicesEnabled) {
if (nearbyChannels.isNotEmpty()) {
nearbyChannels.forEachIndexed { index, channel ->
@@ -418,57 +494,6 @@ fun LocationChannelsSheet(
}
}
- if (bookmarks.isNotEmpty()) {
- item(key = "bookmarks_card") {
- Column {
- AboutSectionLabel(text = stringResource(R.string.bookmarked))
- Surface(
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = AboutHorizontalPadding),
- color = palette.surface,
- shape = AboutCardShape
- ) {
- Column {
- bookmarks.forEachIndexed { index, gh ->
- if (index > 0) SheetCardDivider()
- val level = levelForLength(gh.length)
- val channel = GeohashChannel(level = level, geohash = gh)
- val coverage = coverageString(gh.length)
- val name = bookmarkNames[gh]
- val subtitle = "#$gh • $coverage" +
- (name?.let { " • ${formattedNamePrefix(level)}$it" } ?: "")
- val participantCount = geohashParticipantCounts[gh] ?: 0
-
- ChannelOptionRow(
- title = geohashHashTitleWithCount(gh, participantCount),
- subtitle = subtitle,
- isSelected = isChannelSelected(channel, selectedChannel),
- participantCount = participantCount,
- titleBold = participantCount > 0,
- trailingContent = {
- ChannelBookmarkButton(
- bookmarked = true,
- onClick = { bookmarksStore.toggle(gh) }
- )
- },
- onClick = {
- val inRegional = availableChannels.any { it.geohash == gh }
- locationManager.setTeleported(
- !inRegional && availableChannels.isNotEmpty()
- )
- locationManager.select(ChannelID.Location(channel))
- onDismiss()
- }
- )
- LaunchedEffect(gh) { bookmarksStore.resolveNameIfNeeded(gh) }
- }
- }
- }
- }
- }
- }
-
item(key = "tor_routing") {
val torProvider = remember { ArtiTorManager.getInstance() }
val torAvailable = remember { torProvider.isTorAvailable() }
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c5da7e33..d7aba32e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -303,7 +303,8 @@
Channels
Location Channels
- Chat nearby over geohash channels. Only a coarse location is shared, never exact GPS.
+ Chat by coarse location. Never shares exact GPS.
+ Nearby
Offline mesh via Bluetooth. No internet required.