refactor: 主页重构,联机模式/游戏设置改为二级页面,昵称/主题/关于移至设置

This commit is contained in:
flykhan 2026-04-26 18:16:23 +08:00
parent 093a759ad4
commit d8191a44b1
5 changed files with 357 additions and 217 deletions

View File

@ -198,40 +198,17 @@ fun UnoApp() {
) { ) {
composable(Screen.MainMenu.route) { composable(Screen.MainMenu.route) {
MainMenuScreen( MainMenuScreen(
initialName = savedName, onLocalGame = { navController.navigate(Screen.ModeSelect.route) },
onNameChanged = { name -> onOnlineGame = { navController.navigate(Screen.LobbyMenu.route) },
savedName = name onScoreboard = { navController.navigate(Screen.Scoreboard.route) },
prefs.edit().putString("player_name", name).apply() onRules = { navController.navigate(Screen.Rules.route) },
}, onSettings = { navController.navigate(Screen.Settings.route) }
onLocalGame = { )
navController.navigate(Screen.ModeSelect.route) }
},
onScoreboard = { composable(Screen.LobbyMenu.route) {
navController.navigate(Screen.Scoreboard.route) LobbyMenuScreen(
}, playerName = savedName,
onRules = {
navController.navigate(Screen.Rules.route)
},
currentTheme = cardTheme,
currentBg = tableBg,
onToggleTheme = {
val next = CardTheme.values()[(cardTheme.ordinal + 1) % CardTheme.values().size]
cardTheme = next
CardTheme.save(context, next)
},
onToggleBg = {
val next = TableBg.values()[(tableBg.ordinal + 1) % TableBg.values().size]
tableBg = next
TableBg.save(context, next)
},
onToggleOrientation = {
isLandscape = !isLandscape
prefs.edit().putBoolean("landscape", isLandscape).apply()
(context as? android.app.Activity)?.requestedOrientation =
if (isLandscape) ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
else ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
},
isLandscape = isLandscape,
onHostGame = { name -> onHostGame = { name ->
myName = name myName = name
isHost = true isHost = true
@ -244,7 +221,6 @@ fun UnoApp() {
discoveryService = discovery discoveryService = discovery
discovery.startAdvertising(name, 1) discovery.startAdvertising(name, 1)
navController.navigate(Screen.Lobby.createRoute(true)) navController.navigate(Screen.Lobby.createRoute(true))
// Host connects as a client too (to localhost) - on IO thread
scope.launch { scope.launch {
val client = GameClient() val client = GameClient()
if (client.connect("127.0.0.1", name)) { if (client.connect("127.0.0.1", name)) {
@ -262,7 +238,6 @@ fun UnoApp() {
discoveryService = discovery discoveryService = discovery
discovery.startDiscovery(name) discovery.startDiscovery(name)
isDiscovering = true isDiscovering = true
scope.launch { scope.launch {
discovery.hosts.collect { hosts -> discovery.hosts.collect { hosts ->
discoveredHosts = hosts discoveredHosts = hosts
@ -270,7 +245,8 @@ fun UnoApp() {
} }
} }
navController.navigate(Screen.Lobby.createRoute(false)) navController.navigate(Screen.Lobby.createRoute(false))
} },
onBack = { navController.popBackStack() }
) )
} }
@ -424,6 +400,34 @@ fun UnoApp() {
RulesHelpScreen(onBack = { navController.popBackStack() }) RulesHelpScreen(onBack = { navController.popBackStack() })
} }
composable(Screen.Settings.route) {
SettingsScreen(
initialName = savedName,
currentTheme = cardTheme,
currentBg = tableBg,
isLandscape = isLandscape,
onNameChanged = { name ->
savedName = name
prefs.edit().putString("player_name", name).apply()
},
onToggleTheme = {
val next = CardTheme.values()[(cardTheme.ordinal + 1) % CardTheme.values().size]
cardTheme = next
CardTheme.save(context, next)
},
onToggleBg = {
val next = TableBg.values()[(tableBg.ordinal + 1) % TableBg.values().size]
tableBg = next
TableBg.save(context, next)
},
onToggleOrientation = {
isLandscape = !isLandscape
prefs.edit().putBoolean("landscape", isLandscape).apply()
},
onBack = { navController.popBackStack() }
)
}
composable(Screen.Game.route) { composable(Screen.Game.route) {
gameState?.let { state -> gameState?.let { state ->
GameScreen( GameScreen(

View File

@ -6,6 +6,7 @@ sealed class Screen(val route: String) {
fun createRoute(isHost: Boolean) = "lobby/$isHost" fun createRoute(isHost: Boolean) = "lobby/$isHost"
} }
data object ModeSelect : Screen("mode_select") data object ModeSelect : Screen("mode_select")
data object LobbyMenu : Screen("lobby_menu")
data object LocalSetup : Screen("local_setup/{modeName}") { data object LocalSetup : Screen("local_setup/{modeName}") {
fun createRoute(mode: String) = "local_setup/$mode" fun createRoute(mode: String) = "local_setup/$mode"
} }
@ -20,4 +21,5 @@ sealed class Screen(val route: String) {
fun createRoute(winnerName: String, isYouWinner: Boolean) = fun createRoute(winnerName: String, isYouWinner: Boolean) =
"game_over/$winnerName/$isYouWinner" "game_over/$winnerName/$isYouWinner"
} }
data object Settings : Screen("settings")
} }

View File

@ -0,0 +1,101 @@
package com.unogame.ui.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.unogame.ui.theme.*
@Composable
fun LobbyMenuScreen(
playerName: String,
onHostGame: (String) -> Unit,
onJoinGame: (String) -> Unit,
onBack: () -> Unit
) {
Box(modifier = Modifier.fillMaxSize().background(LocalTableBg.current.color)) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(24.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = onBack) {
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White)
}
Text("联机模式", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = Color.White)
}
Spacer(modifier = Modifier.height(40.dp))
// Create room
Button(
onClick = {
val name = playerName.ifBlank { "玩家" }
onHostGame(name)
},
modifier = Modifier.fillMaxWidth().height(56.dp),
shape = RoundedCornerShape(16.dp),
colors = ButtonDefaults.buttonColors(
containerColor = GoldAccent,
contentColor = Color.Black
)
) {
Icon(Icons.Default.Home, null)
Spacer(modifier = Modifier.width(12.dp))
Text("创建房间", fontSize = 18.sp, fontWeight = FontWeight.Bold)
}
Spacer(modifier = Modifier.height(16.dp))
// Join room
Button(
onClick = {
val name = playerName.ifBlank { "玩家" }
onJoinGame(name)
},
modifier = Modifier.fillMaxWidth().height(56.dp),
shape = RoundedCornerShape(16.dp),
colors = ButtonDefaults.buttonColors(
containerColor = DarkSurface,
contentColor = Color.White
)
) {
Icon(Icons.Default.Search, null)
Spacer(modifier = Modifier.width(12.dp))
Text("加入房间", fontSize = 18.sp, fontWeight = FontWeight.Bold)
}
Spacer(modifier = Modifier.height(24.dp))
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(containerColor = DarkSurface.copy(alpha = 0.5f))
) {
Column(modifier = Modifier.padding(16.dp)) {
Text("说明", color = GoldAccent, fontWeight = FontWeight.Bold, fontSize = 14.sp)
Spacer(modifier = Modifier.height(8.dp))
Text(
"创建房间:作为房主等待其他玩家加入\n加入房间搜索同一WiFi下的房间",
color = Color.White.copy(alpha = 0.6f),
fontSize = 13.sp,
lineHeight = 20.sp
)
}
}
}
}
}

View File

@ -1,6 +1,5 @@
package com.unogame.ui.screens package com.unogame.ui.screens
import androidx.compose.animation.*
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@ -12,10 +11,8 @@ import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@ -23,23 +20,12 @@ import com.unogame.ui.theme.*
@Composable @Composable
fun MainMenuScreen( fun MainMenuScreen(
initialName: String,
currentTheme: CardTheme,
currentBg: TableBg,
onHostGame: (String) -> Unit,
onJoinGame: (String) -> Unit,
onLocalGame: () -> Unit, onLocalGame: () -> Unit,
onOnlineGame: () -> Unit,
onScoreboard: () -> Unit, onScoreboard: () -> Unit,
onRules: () -> Unit, onRules: () -> Unit,
onToggleTheme: () -> Unit, onSettings: () -> Unit
onToggleBg: () -> Unit,
onToggleOrientation: () -> Unit,
isLandscape: Boolean,
onNameChanged: (String) -> Unit
) { ) {
var playerName by remember { mutableStateOf(initialName) }
var showAbout by remember { mutableStateOf(false) }
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -54,7 +40,6 @@ fun MainMenuScreen(
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
// Title // Title
Row(verticalAlignment = Alignment.CenterVertically) {
Text( Text(
text = "UNO", text = "UNO",
fontSize = 72.sp, fontSize = 72.sp,
@ -62,7 +47,6 @@ fun MainMenuScreen(
color = GoldAccent, color = GoldAccent,
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
}
Text( Text(
text = "卡牌游戏", text = "卡牌游戏",
fontSize = 18.sp, fontSize = 18.sp,
@ -70,76 +54,9 @@ fun MainMenuScreen(
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
Spacer(modifier = Modifier.height(60.dp)) Spacer(modifier = Modifier.height(48.dp))
// Name input // 1. 本地模式
OutlinedTextField(
value = playerName,
onValueChange = {
playerName = it.take(10)
onNameChanged(playerName.ifBlank { "玩家" })
},
label = { Text("你的昵称", color = Color.White.copy(alpha = 0.6f)) },
singleLine = true,
colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White,
unfocusedTextColor = Color.White,
focusedBorderColor = GoldAccent,
unfocusedBorderColor = Color.Gray,
cursorColor = GoldAccent
),
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(32.dp))
// Host Game button
Button(
onClick = {
val name = playerName.ifBlank { "玩家" }
onNameChanged(name)
onHostGame(name)
},
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
shape = RoundedCornerShape(16.dp),
colors = ButtonDefaults.buttonColors(
containerColor = DarkSurface,
contentColor = GoldAccent
)
) {
Icon(Icons.Default.Home, contentDescription = null)
Spacer(modifier = Modifier.width(12.dp))
Text("创建房间", fontSize = 18.sp, fontWeight = FontWeight.Bold)
}
Spacer(modifier = Modifier.height(16.dp))
// Join Game button
Button(
onClick = {
val name = playerName.ifBlank { "玩家" }
onNameChanged(name)
onJoinGame(name)
},
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
shape = RoundedCornerShape(16.dp),
colors = ButtonDefaults.buttonColors(
containerColor = DarkSurface,
contentColor = Color.White
)
) {
Icon(Icons.Default.Search, contentDescription = null)
Spacer(modifier = Modifier.width(12.dp))
Text("加入房间", fontSize = 18.sp, fontWeight = FontWeight.Bold)
}
Spacer(modifier = Modifier.height(16.dp))
// Local Game button
Button( Button(
onClick = onLocalGame, onClick = onLocalGame,
modifier = Modifier modifier = Modifier
@ -158,7 +75,26 @@ fun MainMenuScreen(
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
// Scoreboard button // 2. 联机模式
Button(
onClick = onOnlineGame,
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
shape = RoundedCornerShape(16.dp),
colors = ButtonDefaults.buttonColors(
containerColor = DarkSurface,
contentColor = GoldAccent
)
) {
Icon(Icons.Default.Wifi, contentDescription = null)
Spacer(modifier = Modifier.width(12.dp))
Text("联机模式", fontSize = 18.sp, fontWeight = FontWeight.Bold)
}
Spacer(modifier = Modifier.height(16.dp))
// 3. 排行榜
Button( Button(
onClick = onScoreboard, onClick = onScoreboard,
modifier = Modifier modifier = Modifier
@ -177,7 +113,7 @@ fun MainMenuScreen(
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
// Rules button // 4. 规则说明
Button( Button(
onClick = onRules, onClick = onRules,
modifier = Modifier modifier = Modifier
@ -196,92 +132,22 @@ fun MainMenuScreen(
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
// Theme toggle // 5. 游戏设置
TextButton(onClick = onToggleTheme) { Button(
Icon(Icons.Default.Palette, null, tint = Color.White.copy(alpha = 0.5f)) onClick = onSettings,
Spacer(modifier = Modifier.width(6.dp)) modifier = Modifier
Text("卡面: ${currentTheme.displayName}", color = Color.White.copy(alpha = 0.5f), fontSize = 14.sp) .fillMaxWidth()
Spacer(modifier = Modifier.width(4.dp)) .height(56.dp),
Text("", color = GoldAccent, fontSize = 14.sp) shape = RoundedCornerShape(16.dp),
} colors = ButtonDefaults.buttonColors(
containerColor = DarkSurface,
// Background toggle contentColor = Color.White.copy(alpha = 0.5f)
TextButton(onClick = onToggleBg) { )
Icon(Icons.Default.Wallpaper, null, tint = Color.White.copy(alpha = 0.5f))
Spacer(modifier = Modifier.width(6.dp))
Text("牌桌: ${currentBg.displayName}", color = Color.White.copy(alpha = 0.5f), fontSize = 14.sp)
Spacer(modifier = Modifier.width(4.dp))
Text("", color = GoldAccent, fontSize = 14.sp)
}
// Orientation toggle
TextButton(onClick = onToggleOrientation) {
Icon(if (isLandscape) Icons.Default.StayCurrentLandscape else Icons.Default.StayCurrentPortrait,
null, tint = Color.White.copy(alpha = 0.5f))
Spacer(modifier = Modifier.width(6.dp))
Text(if (isLandscape) "横屏" else "竖屏", color = Color.White.copy(alpha = 0.5f), fontSize = 14.sp)
Spacer(modifier = Modifier.width(4.dp))
Text("", color = GoldAccent, fontSize = 14.sp)
}
Spacer(modifier = Modifier.height(16.dp))
// About button
TextButton(onClick = { showAbout = true }) {
Icon(Icons.Default.Info, null, tint = Color.White.copy(alpha = 0.5f))
Spacer(modifier = Modifier.width(6.dp))
Text("关于", color = Color.White.copy(alpha = 0.5f), fontSize = 14.sp)
}
Spacer(modifier = Modifier.height(8.dp))
// Instructions
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(containerColor = DarkSurface.copy(alpha = 0.5f))
) { ) {
Column(modifier = Modifier.padding(16.dp)) { Icon(Icons.Default.Settings, contentDescription = null)
Text( Spacer(modifier = Modifier.width(12.dp))
"游戏说明", Text("游戏设置", fontSize = 18.sp, fontWeight = FontWeight.Bold)
color = GoldAccent,
fontWeight = FontWeight.Bold,
fontSize = 14.sp
)
Spacer(modifier = Modifier.height(8.dp))
Text(
"• 创建房间:作为房主等待其他玩家加入\n• 加入房间搜索同一WiFi下的房间\n• 与同颜色、同数字/功能的牌匹配",
color = Color.White.copy(alpha = 0.7f),
fontSize = 12.sp,
lineHeight = 18.sp
)
} }
} }
} }
} }
// About dialog
if (showAbout) {
AlertDialog(
onDismissRequest = { showAbout = false },
title = { Text("关于", color = GoldAccent, fontWeight = FontWeight.Bold) },
text = {
Column {
Text("感谢名单", color = GoldAccent, fontSize = 16.sp, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(12.dp))
Text("主创:刘博", color = Color.White, fontSize = 14.sp)
Spacer(modifier = Modifier.height(4.dp))
Text("最佳苦力opencode、deepseek v4 pro", color = Color.White, fontSize = 14.sp)
Spacer(modifier = Modifier.height(4.dp))
Text("金牌测试:张天弈、蔺明智", color = Color.White, fontSize = 14.sp)
}
},
confirmButton = {
TextButton(onClick = { showAbout = false }) {
Text("关闭", color = GoldAccent)
}
},
containerColor = DarkSurface
)
}
}

View File

@ -0,0 +1,167 @@
package com.unogame.ui.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.unogame.ui.theme.*
@Composable
fun SettingsScreen(
initialName: String,
currentTheme: CardTheme,
currentBg: TableBg,
isLandscape: Boolean,
onNameChanged: (String) -> Unit,
onToggleTheme: () -> Unit,
onToggleBg: () -> Unit,
onToggleOrientation: () -> Unit,
onBack: () -> Unit
) {
var playerName by remember { mutableStateOf(initialName) }
var showAbout by remember { mutableStateOf(false) }
Box(modifier = Modifier.fillMaxSize().background(LocalTableBg.current.color)) {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(24.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = onBack) {
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White)
}
Text("游戏设置", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = Color.White)
}
Spacer(modifier = Modifier.height(32.dp))
// Nickname
Text("你的昵称", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField(
value = playerName,
onValueChange = {
playerName = it.take(10)
onNameChanged(playerName.ifBlank { "玩家" })
},
singleLine = true,
modifier = Modifier.fillMaxWidth(),
colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White,
unfocusedTextColor = Color.White,
focusedBorderColor = GoldAccent,
unfocusedBorderColor = Color.Gray,
cursorColor = GoldAccent
)
)
Spacer(modifier = Modifier.height(28.dp))
// Card theme
Text("外观设置", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(12.dp))
SettingsRow(
icon = Icons.Default.Palette,
label = "卡面风格",
value = currentTheme.displayName,
onClick = onToggleTheme
)
SettingsRow(
icon = Icons.Default.Wallpaper,
label = "牌桌背景",
value = currentBg.displayName,
onClick = onToggleBg
)
SettingsRow(
icon = if (isLandscape) Icons.Default.StayCurrentLandscape else Icons.Default.StayCurrentPortrait,
label = "屏幕方向",
value = if (isLandscape) "横屏" else "竖屏",
onClick = onToggleOrientation
)
Spacer(modifier = Modifier.height(28.dp))
// About
Text("其他", color = Color.White.copy(alpha = 0.6f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(12.dp))
SettingsRow(
icon = Icons.Default.Info,
label = "关于",
value = "",
onClick = { showAbout = true }
)
}
}
if (showAbout) {
AlertDialog(
onDismissRequest = { showAbout = false },
title = { Text("关于", color = GoldAccent, fontWeight = FontWeight.Bold) },
text = {
Column {
Text("感谢名单", color = GoldAccent, fontSize = 16.sp, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(12.dp))
Text("主创:刘博", color = Color.White, fontSize = 14.sp)
Spacer(modifier = Modifier.height(4.dp))
Text("最佳苦力opencode、deepseek v4 pro", color = Color.White.copy(alpha = 0.7f), fontSize = 14.sp)
Spacer(modifier = Modifier.height(4.dp))
Text("金牌测试:张天羿、蔺明智", color = Color.White.copy(alpha = 0.7f), fontSize = 14.sp)
}
},
confirmButton = {
TextButton(onClick = { showAbout = false }) {
Text("关闭", color = GoldAccent)
}
},
containerColor = DarkSurface
)
}
}
@Composable
private fun SettingsRow(
icon: androidx.compose.ui.graphics.vector.ImageVector,
label: String,
value: String,
onClick: () -> Unit
) {
Card(
modifier = Modifier
.fillMaxWidth()
.clickable { onClick() },
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(containerColor = DarkSurface)
) {
Row(
modifier = Modifier.padding(horizontal = 16.dp, vertical = 14.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(icon, null, tint = Color.White.copy(alpha = 0.6f), modifier = Modifier.size(20.dp))
Spacer(modifier = Modifier.width(12.dp))
Text(label, color = Color.White, fontSize = 15.sp, modifier = Modifier.weight(1f))
if (value.isNotEmpty()) {
Text(value, color = GoldAccent, fontSize = 14.sp)
Spacer(modifier = Modifier.width(4.dp))
Icon(Icons.Default.ChevronRight, null, tint = Color.White.copy(alpha = 0.3f), modifier = Modifier.size(18.dp))
}
}
}
Spacer(modifier = Modifier.height(8.dp))
}