refactor: 积分榜导入导出改为右上角三点菜单,支持文件导出导入
This commit is contained in:
parent
da9828f4b2
commit
093a759ad4
@ -3,7 +3,10 @@ package com.unogame.ui.screens
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
@ -43,8 +46,49 @@ fun ScoreboardScreen(onBack: () -> Unit) {
|
||||
var detailEntry by remember { mutableStateOf<ScoreEntry?>(null) }
|
||||
var showImportDialog by remember { mutableStateOf(false) }
|
||||
var importJson by remember { mutableStateOf("") }
|
||||
var showMenu by remember { mutableStateOf(false) }
|
||||
val gson = remember { Gson() }
|
||||
|
||||
// Export file launcher
|
||||
val exportLauncher = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.CreateDocument("application/json")
|
||||
) { uri: Uri? ->
|
||||
uri?.let {
|
||||
try {
|
||||
val json = gson.toJson(scores)
|
||||
context.contentResolver.openOutputStream(it)?.use { out ->
|
||||
out.write(json.toByteArray())
|
||||
}
|
||||
Toast.makeText(context, "备份已导出", Toast.LENGTH_SHORT).show()
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(context, "导出失败: ${e.message}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Import file launcher
|
||||
val importLauncher = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.OpenDocument()
|
||||
) { uri: Uri? ->
|
||||
uri?.let {
|
||||
try {
|
||||
val json = context.contentResolver.openInputStream(it)?.bufferedReader()?.readText() ?: ""
|
||||
val imported = gson.fromJson(json, Array<ScoreEntry>::class.java)?.toList() ?: emptyList()
|
||||
if (imported.isNotEmpty()) {
|
||||
val merged = (scores + imported).distinctBy { e -> "${e.name}_${e.mode}_${e.date}" }
|
||||
.sortedByDescending { e -> e.points }.take(50)
|
||||
Scoreboard.saveScores(context, merged)
|
||||
scores = merged
|
||||
Toast.makeText(context, "成功导入 ${imported.size} 条记录", Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(context, "文件中无有效数据", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(context, "导入失败: ${e.message}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val filtered = if (selectedFilter == "全部") scores
|
||||
else scores.filter { it.mode == selectedFilter }
|
||||
|
||||
@ -57,42 +101,55 @@ fun ScoreboardScreen(onBack: () -> Unit) {
|
||||
IconButton(onClick = onBack) {
|
||||
Icon(Icons.Default.ArrowBack, "返回", tint = Color.White)
|
||||
}
|
||||
Text("积分排行榜", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = Color.White)
|
||||
Text("积分排行榜", fontSize = 24.sp, fontWeight = FontWeight.Bold, color = Color.White, modifier = Modifier.weight(1f))
|
||||
Box {
|
||||
IconButton(onClick = { showMenu = true }) {
|
||||
Icon(Icons.Default.MoreVert, "菜单", tint = Color.White)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Import / Export buttons
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
DropdownMenu(
|
||||
expanded = showMenu,
|
||||
onDismissRequest = { showMenu = false }
|
||||
) {
|
||||
OutlinedButton(
|
||||
DropdownMenuItem(
|
||||
text = { Text("导出到文件") },
|
||||
onClick = {
|
||||
showMenu = false
|
||||
exportLauncher.launch("uno_scoreboard_backup.json")
|
||||
},
|
||||
leadingIcon = { Icon(Icons.Default.FileUpload, null) }
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text("从文件导入") },
|
||||
onClick = {
|
||||
showMenu = false
|
||||
importLauncher.launch(arrayOf("application/json", "*/*"))
|
||||
},
|
||||
leadingIcon = { Icon(Icons.Default.FileDownload, null) }
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text("复制备份") },
|
||||
onClick = {
|
||||
showMenu = false
|
||||
val json = gson.toJson(scores)
|
||||
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
clipboard.setPrimaryClip(ClipData.newPlainText("uno_scoreboard", json))
|
||||
Toast.makeText(context, "已复制备份JSON到剪贴板", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(context, "已复制JSON到剪贴板", Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
modifier = Modifier.weight(1f),
|
||||
colors = ButtonDefaults.outlinedButtonColors(contentColor = Color.White.copy(alpha = 0.7f))
|
||||
) {
|
||||
Icon(Icons.Default.FileUpload, null, modifier = Modifier.size(16.dp))
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text("导出备份", fontSize = 12.sp)
|
||||
leadingIcon = { Icon(Icons.Default.ContentCopy, null) }
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text("粘贴导入") },
|
||||
onClick = {
|
||||
showMenu = false
|
||||
showImportDialog = true
|
||||
},
|
||||
leadingIcon = { Icon(Icons.Default.ContentPaste, null) }
|
||||
)
|
||||
}
|
||||
OutlinedButton(
|
||||
onClick = { showImportDialog = true },
|
||||
modifier = Modifier.weight(1f),
|
||||
colors = ButtonDefaults.outlinedButtonColors(contentColor = Color.White.copy(alpha = 0.7f))
|
||||
) {
|
||||
Icon(Icons.Default.FileDownload, null, modifier = Modifier.size(16.dp))
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text("导入备份", fontSize = 12.sp)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Mode filter chips
|
||||
if (scores.isNotEmpty()) {
|
||||
@ -282,7 +339,7 @@ fun ScoreboardScreen(onBack: () -> Unit) {
|
||||
if (showImportDialog) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showImportDialog = false },
|
||||
title = { Text("导入备份", color = GoldAccent) },
|
||||
title = { Text("粘贴导入", color = GoldAccent) },
|
||||
text = {
|
||||
Column {
|
||||
Text("粘贴之前导出的JSON数据:", color = Color.White.copy(alpha = 0.7f), fontSize = 14.sp)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user