From 4b1d6f8c04f3326c552dafce042acf4b3d598888 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 25 Jul 2025 20:02:59 +0200 Subject: [PATCH] UI improvements (#192) * bitchat logo * improve ui --- .../onboarding/BatteryOptimizationScreen.kt | 6 +- .../onboarding/BluetoothCheckScreen.kt | 2 +- .../android/onboarding/InitializingScreen.kt | 2 +- .../android/onboarding/LocationCheckScreen.kt | 2 +- .../onboarding/PermissionExplanationScreen.kt | 2 +- .../java/com/bitchat/android/ui/ChatHeader.kt | 6 +- .../com/bitchat/android/ui/ChatViewModel.kt | 4 +- .../bitchat/android/ui/DialogComponents.kt | 2 +- .../com/bitchat/android/ui/InputComponents.kt | 89 +++++++++++-------- 9 files changed, 63 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/com/bitchat/android/onboarding/BatteryOptimizationScreen.kt b/app/src/main/java/com/bitchat/android/onboarding/BatteryOptimizationScreen.kt index 3b1ebf9e..a5491f46 100644 --- a/app/src/main/java/com/bitchat/android/onboarding/BatteryOptimizationScreen.kt +++ b/app/src/main/java/com/bitchat/android/onboarding/BatteryOptimizationScreen.kt @@ -90,7 +90,7 @@ private fun BatteryOptimizationEnabledContent( horizontalAlignment = Alignment.CenterHorizontally ) { Text( - text = "bitchat*", + text = "bitchat", style = MaterialTheme.typography.headlineLarge.copy( fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, @@ -214,7 +214,7 @@ private fun BatteryOptimizationCheckingContent( horizontalAlignment = Alignment.CenterHorizontally ) { Text( - text = "bitchat*", + text = "bitchat", style = MaterialTheme.typography.headlineLarge.copy( fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, @@ -271,7 +271,7 @@ private fun BatteryOptimizationNotSupportedContent( horizontalAlignment = Alignment.CenterHorizontally ) { Text( - text = "bitchat*", + text = "bitchat", style = MaterialTheme.typography.headlineLarge.copy( fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, diff --git a/app/src/main/java/com/bitchat/android/onboarding/BluetoothCheckScreen.kt b/app/src/main/java/com/bitchat/android/onboarding/BluetoothCheckScreen.kt index 9e701af3..bec42f17 100644 --- a/app/src/main/java/com/bitchat/android/onboarding/BluetoothCheckScreen.kt +++ b/app/src/main/java/com/bitchat/android/onboarding/BluetoothCheckScreen.kt @@ -222,7 +222,7 @@ private fun BluetoothCheckingContent( horizontalAlignment = Alignment.CenterHorizontally ) { Text( - text = "bitchat*", + text = "bitchat", style = MaterialTheme.typography.headlineLarge.copy( fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, diff --git a/app/src/main/java/com/bitchat/android/onboarding/InitializingScreen.kt b/app/src/main/java/com/bitchat/android/onboarding/InitializingScreen.kt index a195a594..f6bc2174 100644 --- a/app/src/main/java/com/bitchat/android/onboarding/InitializingScreen.kt +++ b/app/src/main/java/com/bitchat/android/onboarding/InitializingScreen.kt @@ -61,7 +61,7 @@ fun InitializingScreen() { ) { // App title Text( - text = "bitchat*", + text = "bitchat", style = MaterialTheme.typography.headlineLarge.copy( fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, diff --git a/app/src/main/java/com/bitchat/android/onboarding/LocationCheckScreen.kt b/app/src/main/java/com/bitchat/android/onboarding/LocationCheckScreen.kt index 37fb072f..4f44ee96 100644 --- a/app/src/main/java/com/bitchat/android/onboarding/LocationCheckScreen.kt +++ b/app/src/main/java/com/bitchat/android/onboarding/LocationCheckScreen.kt @@ -247,7 +247,7 @@ private fun LocationCheckingContent( horizontalAlignment = Alignment.CenterHorizontally ) { Text( - text = "bitchat*", + text = "bitchat", style = MaterialTheme.typography.headlineLarge.copy( fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, diff --git a/app/src/main/java/com/bitchat/android/onboarding/PermissionExplanationScreen.kt b/app/src/main/java/com/bitchat/android/onboarding/PermissionExplanationScreen.kt index 7c24cadc..855e774f 100644 --- a/app/src/main/java/com/bitchat/android/onboarding/PermissionExplanationScreen.kt +++ b/app/src/main/java/com/bitchat/android/onboarding/PermissionExplanationScreen.kt @@ -45,7 +45,7 @@ fun PermissionExplanationScreen( horizontalAlignment = Alignment.CenterHorizontally ) { Text( - text = "Welcome to bitchat*", + text = "Welcome to bitchat", style = MaterialTheme.typography.headlineMedium.copy( fontFamily = FontFamily.Monospace, fontWeight = FontWeight.Bold, diff --git a/app/src/main/java/com/bitchat/android/ui/ChatHeader.kt b/app/src/main/java/com/bitchat/android/ui/ChatHeader.kt index fda00233..21f7e5ed 100644 --- a/app/src/main/java/com/bitchat/android/ui/ChatHeader.kt +++ b/app/src/main/java/com/bitchat/android/ui/ChatHeader.kt @@ -166,7 +166,7 @@ fun PeerCounter( } Icon( - imageVector = Icons.Default.Person, + imageVector = Icons.Default.Group, contentDescription = "Connected peers", modifier = Modifier.size(16.dp), tint = if (isConnected) Color(0xFF00C851) else Color.Red @@ -425,7 +425,7 @@ private fun MainHeader( verticalAlignment = Alignment.CenterVertically ) { Text( - text = "bitchat*", + text = "bitchat/", style = MaterialTheme.typography.headlineSmall, color = colorScheme.primary, modifier = Modifier.singleOrTripleClickable( @@ -434,7 +434,7 @@ private fun MainHeader( ) ) - Spacer(modifier = Modifier.width(8.dp)) + Spacer(modifier = Modifier.width(2.dp)) NicknameEditor( value = nickname, diff --git a/app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt b/app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt index 68f0f683..874694da 100644 --- a/app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt +++ b/app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt @@ -124,11 +124,11 @@ class ChatViewModel( // Show welcome message if no peers after delay viewModelScope.launch { - delay(3000) + delay(10000) if (state.getConnectedPeersValue().isEmpty() && state.getMessagesValue().isEmpty()) { val welcomeMessage = BitchatMessage( sender = "system", - content = "get people around you to download bitchat…and chat with them here!", + content = "get people around you to download bitchat and chat with them here!", timestamp = Date(), isRelay = false ) diff --git a/app/src/main/java/com/bitchat/android/ui/DialogComponents.kt b/app/src/main/java/com/bitchat/android/ui/DialogComponents.kt index 1051233a..05309d20 100644 --- a/app/src/main/java/com/bitchat/android/ui/DialogComponents.kt +++ b/app/src/main/java/com/bitchat/android/ui/DialogComponents.kt @@ -93,7 +93,7 @@ fun AppInfoDialog( onDismissRequest = onDismiss, title = { Text( - text = "About bitchat*", + text = "About bitchat", style = MaterialTheme.typography.titleMedium, color = colorScheme.onSurface ) diff --git a/app/src/main/java/com/bitchat/android/ui/InputComponents.kt b/app/src/main/java/com/bitchat/android/ui/InputComponents.kt index d04d84aa..0489930e 100644 --- a/app/src/main/java/com/bitchat/android/ui/InputComponents.kt +++ b/app/src/main/java/com/bitchat/android/ui/InputComponents.kt @@ -96,58 +96,66 @@ fun MessageInput( ) { val colorScheme = MaterialTheme.colorScheme val isFocused = remember { mutableStateOf(false) } + val hasText = value.text.isNotBlank() // Check if there's text for send button state Row( modifier = modifier.padding(horizontal = 12.dp, vertical = 8.dp), // Reduced padding verticalAlignment = Alignment.CenterVertically ) { - // Remove arrow from both private and channel inputs to match DM style - Text( - text = "<@$nickname>", // No arrow for both private and channel - style = MaterialTheme.typography.bodySmall.copy(fontWeight = FontWeight.Medium), - color = when { - selectedPrivatePeer != null -> Color(0xFFFF9500) // Orange for private - currentChannel != null -> Color(0xFFFF9500) // Orange for channels too - else -> colorScheme.primary - }, - fontFamily = FontFamily.Monospace, - fontSize = 14.sp - ) - - Spacer(modifier = Modifier.width(8.dp)) - - // Text input - BasicTextField( - value = value, - onValueChange = onValueChange, - textStyle = MaterialTheme.typography.bodyMedium.copy( - color = colorScheme.primary, - fontFamily = FontFamily.Monospace - ), - cursorBrush = SolidColor(colorScheme.primary), - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Send), - keyboardActions = KeyboardActions(onSend = { onSend() }), - visualTransformation = SlashCommandVisualTransformation(), - modifier = Modifier - .weight(1f) - .onFocusChanged { focusState -> - isFocused.value = focusState.isFocused - } - ) + // Text input with placeholder + Box( + modifier = Modifier.weight(1f) + ) { + BasicTextField( + value = value, + onValueChange = onValueChange, + textStyle = MaterialTheme.typography.bodyMedium.copy( + color = colorScheme.primary, + fontFamily = FontFamily.Monospace + ), + cursorBrush = SolidColor(colorScheme.primary), + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Send), + keyboardActions = KeyboardActions(onSend = { + if (hasText) onSend() // Only send if there's text + }), + visualTransformation = SlashCommandVisualTransformation(), + modifier = Modifier + .fillMaxWidth() + .onFocusChanged { focusState -> + isFocused.value = focusState.isFocused + } + ) + + // Show placeholder when there's no text + if (value.text.isEmpty()) { + Text( + text = "type a message...", + style = MaterialTheme.typography.bodyMedium.copy( + fontFamily = FontFamily.Monospace + ), + color = colorScheme.onSurface.copy(alpha = 0.5f), // Muted grey + modifier = Modifier.fillMaxWidth() + ) + } + } Spacer(modifier = Modifier.width(8.dp)) // Reduced spacing - // Update send button to match input field colors + // Send button with enabled/disabled state IconButton( - onClick = onSend, + onClick = { if (hasText) onSend() }, // Only execute if there's text + enabled = hasText, // Enable only when there's text modifier = Modifier.size(32.dp) ) { Box( modifier = Modifier .size(30.dp) .background( - color = if (selectedPrivatePeer != null || currentChannel != null) { - // Orange for both private messages and channels to match nickname color + color = if (!hasText) { + // Disabled state - muted grey + colorScheme.onSurface.copy(alpha = 0.3f) + } else if (selectedPrivatePeer != null || currentChannel != null) { + // Orange for both private messages and channels when enabled Color(0xFFFF9500).copy(alpha = 0.75f) } else if (colorScheme.background == Color.Black) { Color(0xFF00FF00).copy(alpha = 0.75f) // Bright green for dark theme @@ -159,10 +167,13 @@ fun MessageInput( contentAlignment = Alignment.Center ) { Icon( - imageVector = Icons.Filled.KeyboardArrowRight, + imageVector = Icons.Filled.ArrowUpward, contentDescription = "Send message", modifier = Modifier.size(20.dp), - tint = if (selectedPrivatePeer != null || currentChannel != null) { + tint = if (!hasText) { + // Disabled state - muted grey icon + colorScheme.onSurface.copy(alpha = 0.5f) + } else if (selectedPrivatePeer != null || currentChannel != null) { // Black arrow on orange for both private and channel modes Color.Black } else if (colorScheme.background == Color.Black) {