refactor: 主页重构,联机模式/游戏设置改为二级页面,昵称/主题/关于移至设置
This commit is contained in:
parent
093a759ad4
commit
d8191a44b1
@ -198,40 +198,17 @@ fun UnoApp() {
|
||||
) {
|
||||
composable(Screen.MainMenu.route) {
|
||||
MainMenuScreen(
|
||||
initialName = savedName,
|
||||
onNameChanged = { name ->
|
||||
savedName = name
|
||||
prefs.edit().putString("player_name", name).apply()
|
||||
},
|
||||
onLocalGame = {
|
||||
navController.navigate(Screen.ModeSelect.route)
|
||||
},
|
||||
onScoreboard = {
|
||||
navController.navigate(Screen.Scoreboard.route)
|
||||
},
|
||||
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,
|
||||
onLocalGame = { navController.navigate(Screen.ModeSelect.route) },
|
||||
onOnlineGame = { navController.navigate(Screen.LobbyMenu.route) },
|
||||
onScoreboard = { navController.navigate(Screen.Scoreboard.route) },
|
||||
onRules = { navController.navigate(Screen.Rules.route) },
|
||||
onSettings = { navController.navigate(Screen.Settings.route) }
|
||||
)
|
||||
}
|
||||
|
||||
composable(Screen.LobbyMenu.route) {
|
||||
LobbyMenuScreen(
|
||||
playerName = savedName,
|
||||
onHostGame = { name ->
|
||||
myName = name
|
||||
isHost = true
|
||||
@ -244,7 +221,6 @@ fun UnoApp() {
|
||||
discoveryService = discovery
|
||||
discovery.startAdvertising(name, 1)
|
||||
navController.navigate(Screen.Lobby.createRoute(true))
|
||||
// Host connects as a client too (to localhost) - on IO thread
|
||||
scope.launch {
|
||||
val client = GameClient()
|
||||
if (client.connect("127.0.0.1", name)) {
|
||||
@ -262,7 +238,6 @@ fun UnoApp() {
|
||||
discoveryService = discovery
|
||||
discovery.startDiscovery(name)
|
||||
isDiscovering = true
|
||||
|
||||
scope.launch {
|
||||
discovery.hosts.collect { hosts ->
|
||||
discoveredHosts = hosts
|
||||
@ -270,7 +245,8 @@ fun UnoApp() {
|
||||
}
|
||||
}
|
||||
navController.navigate(Screen.Lobby.createRoute(false))
|
||||
}
|
||||
},
|
||||
onBack = { navController.popBackStack() }
|
||||
)
|
||||
}
|
||||
|
||||
@ -424,6 +400,34 @@ fun UnoApp() {
|
||||
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) {
|
||||
gameState?.let { state ->
|
||||
GameScreen(
|
||||
|
||||
@ -6,6 +6,7 @@ sealed class Screen(val route: String) {
|
||||
fun createRoute(isHost: Boolean) = "lobby/$isHost"
|
||||
}
|
||||
data object ModeSelect : Screen("mode_select")
|
||||
data object LobbyMenu : Screen("lobby_menu")
|
||||
data object LocalSetup : Screen("local_setup/{modeName}") {
|
||||
fun createRoute(mode: String) = "local_setup/$mode"
|
||||
}
|
||||
@ -20,4 +21,5 @@ sealed class Screen(val route: String) {
|
||||
fun createRoute(winnerName: String, isYouWinner: Boolean) =
|
||||
"game_over/$winnerName/$isYouWinner"
|
||||
}
|
||||
data object Settings : Screen("settings")
|
||||
}
|
||||
|
||||
101
app/src/main/java/com/unogame/ui/screens/LobbyMenuScreen.kt
Normal file
101
app/src/main/java/com/unogame/ui/screens/LobbyMenuScreen.kt
Normal 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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package com.unogame.ui.screens
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
@ -12,10 +11,8 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
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.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@ -23,23 +20,12 @@ import com.unogame.ui.theme.*
|
||||
|
||||
@Composable
|
||||
fun MainMenuScreen(
|
||||
initialName: String,
|
||||
currentTheme: CardTheme,
|
||||
currentBg: TableBg,
|
||||
onHostGame: (String) -> Unit,
|
||||
onJoinGame: (String) -> Unit,
|
||||
onLocalGame: () -> Unit,
|
||||
onOnlineGame: () -> Unit,
|
||||
onScoreboard: () -> Unit,
|
||||
onRules: () -> Unit,
|
||||
onToggleTheme: () -> Unit,
|
||||
onToggleBg: () -> Unit,
|
||||
onToggleOrientation: () -> Unit,
|
||||
isLandscape: Boolean,
|
||||
onNameChanged: (String) -> Unit
|
||||
onSettings: () -> Unit
|
||||
) {
|
||||
var playerName by remember { mutableStateOf(initialName) }
|
||||
var showAbout by remember { mutableStateOf(false) }
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
@ -54,15 +40,13 @@ fun MainMenuScreen(
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
// Title
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
text = "UNO",
|
||||
fontSize = 72.sp,
|
||||
fontWeight = FontWeight.Black,
|
||||
color = GoldAccent,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = "UNO",
|
||||
fontSize = 72.sp,
|
||||
fontWeight = FontWeight.Black,
|
||||
color = GoldAccent,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Text(
|
||||
text = "卡牌游戏",
|
||||
fontSize = 18.sp,
|
||||
@ -70,76 +54,9 @@ fun MainMenuScreen(
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(60.dp))
|
||||
Spacer(modifier = Modifier.height(48.dp))
|
||||
|
||||
// Name input
|
||||
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
|
||||
// 1. 本地模式
|
||||
Button(
|
||||
onClick = onLocalGame,
|
||||
modifier = Modifier
|
||||
@ -158,7 +75,26 @@ fun MainMenuScreen(
|
||||
|
||||
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(
|
||||
onClick = onScoreboard,
|
||||
modifier = Modifier
|
||||
@ -177,7 +113,7 @@ fun MainMenuScreen(
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Rules button
|
||||
// 4. 规则说明
|
||||
Button(
|
||||
onClick = onRules,
|
||||
modifier = Modifier
|
||||
@ -196,92 +132,22 @@ fun MainMenuScreen(
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Theme toggle
|
||||
TextButton(onClick = onToggleTheme) {
|
||||
Icon(Icons.Default.Palette, null, tint = Color.White.copy(alpha = 0.5f))
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
Text("卡面: ${currentTheme.displayName}", color = Color.White.copy(alpha = 0.5f), fontSize = 14.sp)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text("→", color = GoldAccent, fontSize = 14.sp)
|
||||
}
|
||||
|
||||
// Background toggle
|
||||
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))
|
||||
// 5. 游戏设置
|
||||
Button(
|
||||
onClick = onSettings,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(56.dp),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = DarkSurface,
|
||||
contentColor = Color.White.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下的房间\n• 与同颜色、同数字/功能的牌匹配",
|
||||
color = Color.White.copy(alpha = 0.7f),
|
||||
fontSize = 12.sp,
|
||||
lineHeight = 18.sp
|
||||
)
|
||||
}
|
||||
Icon(Icons.Default.Settings, contentDescription = null)
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Text("游戏设置", fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
167
app/src/main/java/com/unogame/ui/screens/SettingsScreen.kt
Normal file
167
app/src/main/java/com/unogame/ui/screens/SettingsScreen.kt
Normal 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))
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user