From 06a9ec62688dafb8ad3b5f4477272142ced020a6 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Sun, 13 Jul 2025 23:57:10 +0200 Subject: [PATCH] badge --- .../bitchat/android/ui/SidebarComponents.kt | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/bitchat/android/ui/SidebarComponents.kt b/app/src/main/java/com/bitchat/android/ui/SidebarComponents.kt index 4186a76f..112c354c 100644 --- a/app/src/main/java/com/bitchat/android/ui/SidebarComponents.kt +++ b/app/src/main/java/com/bitchat/android/ui/SidebarComponents.kt @@ -39,6 +39,7 @@ fun SidebarOverlay( val currentChannel by viewModel.currentChannel.observeAsState() val selectedPrivatePeer by viewModel.selectedPrivateChatPeer.observeAsState() val nickname by viewModel.nickname.observeAsState("") + val unreadChannelMessages by viewModel.unreadChannelMessages.observeAsState(emptyMap()) // Get peer data from mesh service val peerNicknames = viewModel.meshService.getPeerNicknames() @@ -94,7 +95,8 @@ fun SidebarOverlay( }, onLeaveChannel = { channel -> viewModel.leaveChannel(channel) - } + }, + unreadChannelMessages = unreadChannelMessages ) } @@ -155,7 +157,8 @@ fun ChannelsSection( currentChannel: String?, colorScheme: ColorScheme, onChannelClick: (String) -> Unit, - onLeaveChannel: (String) -> Unit + onLeaveChannel: (String) -> Unit, + unreadChannelMessages: Map = emptyMap() ) { Column { Row( @@ -181,6 +184,7 @@ fun ChannelsSection( channels.forEach { channel -> val isSelected = channel == currentChannel + val unreadCount = unreadChannelMessages[channel] ?: 0 Row( modifier = Modifier @@ -193,6 +197,13 @@ fun ChannelsSection( .padding(horizontal = 24.dp, vertical = 8.dp), verticalAlignment = Alignment.CenterVertically ) { + // Unread badge for channels + UnreadBadge( + count = unreadCount, + colorScheme = colorScheme, + modifier = Modifier.padding(end = 8.dp) + ) + Text( text = channel, // Channel already contains the # prefix style = MaterialTheme.typography.bodyMedium, @@ -297,7 +308,11 @@ fun PeopleSection( onToggleFavorite = { Log.d("SidebarComponents", "Sidebar toggle favorite: peerID=$peerID, currentFavorite=$isFavorite") viewModel.toggleFavorite(peerID) - } + }, + unreadCount = privateChats[peerID]?.count { msg -> + // Count unread messages from this peer (messages not from the current user) + msg.sender != nickname && hasUnreadPrivateMessages.contains(peerID) + } ?: if (hasUnreadPrivateMessages.contains(peerID)) 1 else 0 ) } } @@ -314,7 +329,8 @@ private fun PeerItem( hasUnreadDM: Boolean, colorScheme: ColorScheme, onItemClick: () -> Unit, - onToggleFavorite: () -> Unit + onToggleFavorite: () -> Unit, + unreadCount: Int = 0 ) { Row( modifier = Modifier @@ -327,13 +343,11 @@ private fun PeerItem( .padding(horizontal = 24.dp, vertical = 8.dp), verticalAlignment = Alignment.CenterVertically ) { - // Show filled mail icon instead of signal strength when user has unread DMs + // Show unread badge or signal strength if (hasUnreadDM) { - Icon( - imageVector = Icons.Filled.Email, - contentDescription = "Unread messages", - modifier = Modifier.size(16.dp), - tint = Color(0xFFFF9500) // Orange to match private message theme + UnreadBadge( + count = unreadCount, + colorScheme = colorScheme ) } else { // Signal strength indicators @@ -391,3 +405,35 @@ private fun SignalStrengthIndicator( } } } + +/** + * Reusable unread badge component for both channels and private messages + */ +@Composable +private fun UnreadBadge( + count: Int, + colorScheme: ColorScheme, + modifier: Modifier = Modifier +) { + if (count > 0) { + Box( + modifier = modifier + .background( + color = Color(0xFFFFD700), // Yellow color + shape = RoundedCornerShape(10.dp) + ) + .padding(horizontal = 2.dp, vertical = 0.dp) + .defaultMinSize(minWidth = 14.dp, minHeight = 14.dp), + contentAlignment = Alignment.Center + ) { + Text( + text = if (count > 99) "99+" else count.toString(), + style = MaterialTheme.typography.labelSmall.copy( + fontSize = 10.sp, + fontWeight = FontWeight.Bold + ), + color = Color.Black // Black text on yellow background + ) + } + } +}