From 8abe570374d81c1eeb4227e2bb6e9ce4ff286ca1 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Thu, 30 Jul 2026 19:29:19 +0200 Subject: [PATCH] Restore location notes access --- .../java/com/bitchat/android/ui/ChatScreen.kt | 6 ++ .../android/ui/LocationChannelsSheet.kt | 66 ++++++++++++++++++- .../bitchat/android/ui/LocationNotesButton.kt | 8 +-- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/bitchat/android/ui/ChatScreen.kt b/app/src/main/java/com/bitchat/android/ui/ChatScreen.kt index 30e972c2..301be917 100644 --- a/app/src/main/java/com/bitchat/android/ui/ChatScreen.kt +++ b/app/src/main/java/com/bitchat/android/ui/ChatScreen.kt @@ -517,6 +517,10 @@ fun ChatScreen(viewModel: ChatViewModel) { onAppInfoDismiss = { viewModel.hideAppInfo() }, showLocationChannelsSheet = showLocationChannelsSheet, onLocationChannelsSheetDismiss = { showLocationChannelsSheet = false }, + onLocationNotesFromChannelsClick = { + showLocationChannelsSheet = false + showLocationNotesSheet = true + }, showLocationNotesSheet = showLocationNotesSheet, onLocationNotesSheetDismiss = { showLocationNotesSheet = false }, showUserSheet = showUserSheet, @@ -794,6 +798,7 @@ private fun ChatDialogs( onAppInfoDismiss: () -> Unit, showLocationChannelsSheet: Boolean, onLocationChannelsSheetDismiss: () -> Unit, + onLocationNotesFromChannelsClick: () -> Unit, showLocationNotesSheet: Boolean, onLocationNotesSheetDismiss: () -> Unit, showUserSheet: Boolean, @@ -840,6 +845,7 @@ private fun ChatDialogs( LocationChannelsSheet( isPresented = showLocationChannelsSheet, onDismiss = onLocationChannelsSheetDismiss, + onLocationNotesClick = onLocationNotesFromChannelsClick, viewModel = viewModel ) } 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 505ea5b0..5cf204b8 100644 --- a/app/src/main/java/com/bitchat/android/ui/LocationChannelsSheet.kt +++ b/app/src/main/java/com/bitchat/android/ui/LocationChannelsSheet.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.scale import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Bookmark +import androidx.compose.material.icons.filled.ChevronRight import androidx.compose.material.icons.filled.Hub import androidx.compose.material.icons.filled.Map import androidx.compose.material.icons.filled.PinDrop @@ -52,6 +53,7 @@ import androidx.compose.ui.unit.sp import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import com.bitchat.android.ui.theme.BitchatFontFamily +import com.bitchat.android.nostr.LocationNotesManager import com.bitchat.android.nostr.NearbyNotesController import com.bitchat.android.nostr.geohashesForSampling import com.bitchat.android.ui.theme.BASE_FONT_SIZE @@ -106,16 +108,21 @@ private const val SelectionConfirmDelayMs = 180L fun LocationChannelsSheet( isPresented: Boolean, onDismiss: () -> Unit, + onLocationNotesClick: () -> Unit, viewModel: ChatViewModel, modifier: Modifier = Modifier ) { val context = LocalContext.current val locationManager = LocationChannelManager.getInstance(context) val bookmarksStore = remember { GeohashBookmarksStore.getInstance(context) } + val nearbyNotesController = remember { NearbyNotesController.shared } + val notesManager = remember { LocationNotesManager.getInstance() } val permissionState by locationManager.permissionState.collectAsStateWithLifecycle() val availableChannels by locationManager.availableChannels.collectAsStateWithLifecycle() - val notesRevealed by NearbyNotesController.shared.revealed.collectAsStateWithLifecycle() + val notesRevealed by nearbyNotesController.revealed.collectAsStateWithLifecycle() + val nearbyNotes by notesManager.notes.collectAsStateWithLifecycle() + val nearbyNotesState by notesManager.state.collectAsStateWithLifecycle() val selectedChannel by locationManager.selectedChannel.collectAsStateWithLifecycle() val locationNames by locationManager.locationNames.collectAsStateWithLifecycle() val appLocationEnabled by locationManager.locationServicesEnabled.collectAsStateWithLifecycle() @@ -171,6 +178,17 @@ fun LocationChannelsSheet( val showNearbyLoading = nearbyChannels.isEmpty() && permissionState == LocationChannelManager.PermissionState.AUTHORIZED && locationServicesEnabled + val locationNotesSubtitle = when { + !notesRevealed -> stringResource(R.string.nearby_notes_reveal) + nearbyNotesState == LocationNotesManager.State.NO_RELAYS -> + stringResource(R.string.location_notes_relays_unavailable) + nearbyNotesState == LocationNotesManager.State.LOADING -> + stringResource(R.string.loading_location_notes) + nearbyNotes.size == 1 -> stringResource(R.string.nearby_notes_one) + nearbyNotes.size > 1 -> + stringResource(R.string.nearby_notes_many, nearbyNotes.size) + else -> stringResource(R.string.location_notes_empty_title) + } if (isPresented) { BitchatBottomSheet( @@ -527,6 +545,43 @@ fun LocationChannelsSheet( } } + item(key = "location_notes_card") { + Surface( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = AboutHorizontalPadding) + .padding(top = 10.dp), + color = colorScheme.surface, + shape = AboutCardShape + ) { + ChannelOptionRow( + title = stringResource(R.string.cd_location_notes), + subtitle = locationNotesSubtitle, + isSelected = false, + participantCount = 0, + titleColor = standardGreen, + leadingIconRes = R.drawable.ic_spec_chat_bubbles, + trailingContent = { + Icon( + imageVector = Icons.Filled.ChevronRight, + contentDescription = null, + tint = colorScheme.onSurfaceVariant, + modifier = Modifier.size(20.dp) + ) + }, + onClick = { + locationManager.refreshChannels() + nearbyNotesController.reveal() + coroutineScope.launch { + runCatching { sheetState.hide() } + onDismiss() + onLocationNotesClick() + } + } + ) + } + } + item(key = "tor_routing") { val torProvider = remember { ArtiTorManager.getInstance() } val torAvailable = remember { torProvider.isTorAvailable() } @@ -662,6 +717,7 @@ private fun ChannelOptionRow( titleColor: Color? = null, titleBold: Boolean = false, leadingIcon: ImageVector? = null, + leadingIconRes: Int? = null, trailingContent: (@Composable (() -> Unit))? = null, onClick: () -> Unit ) { @@ -695,6 +751,14 @@ private fun ChannelOptionRow( modifier = Modifier.size(22.dp) ) } + leadingIconRes != null -> { + Icon( + painter = painterResource(leadingIconRes), + contentDescription = null, + tint = colorScheme.primary, + modifier = Modifier.size(22.dp) + ) + } } } diff --git a/app/src/main/java/com/bitchat/android/ui/LocationNotesButton.kt b/app/src/main/java/com/bitchat/android/ui/LocationNotesButton.kt index 489ddaf4..098f190b 100644 --- a/app/src/main/java/com/bitchat/android/ui/LocationNotesButton.kt +++ b/app/src/main/java/com/bitchat/android/ui/LocationNotesButton.kt @@ -48,12 +48,10 @@ fun LocationNotesButton( val notes by notesManager.notes.collectAsStateWithLifecycle() val notesCount = notes.size - // Only show in mesh mode when location is authorized (iOS pattern) - if (selectedLocationChannel is ChannelID.Mesh && locationEnabled) { - val hasNotes = notesCount > 0 + // Keep the header quiet until there is at least one nearby note worth opening. + if (selectedLocationChannel is ChannelID.Mesh && locationEnabled && notesCount > 0) { val contentDescription = stringResource(R.string.cd_location_notes) - val normalTint = if (hasNotes) colorScheme.primary else colorScheme.onSurfaceVariant - val torVisual = rememberTorConnectionVisual(normal = normalTint) + val torVisual = rememberTorConnectionVisual(normal = colorScheme.primary) Box( modifier = modifier