Skip to content

Commit

Permalink
GamePage: 优化用户体验
Browse files Browse the repository at this point in the history
  • Loading branch information
purofle committed Dec 27, 2023
1 parent b9a233b commit 0e4f1f4
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import io.ktor.http.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import java.util.concurrent.CancellationException


object MicrosoftAuth {
Expand Down Expand Up @@ -60,6 +61,9 @@ object MicrosoftAuth {
throw Exception(authError.error.toString())
}
}.onFailure {
if (it is CancellationException) {
throw it
}
emit(result.toJsonObject<SuccessAuthentication>())
getToken = false
}.onSuccess {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ package com.github.purofle.nmsl.config
import com.github.purofle.nmsl.utils.json.JsonUtils.toJsonObject
import com.github.purofle.nmsl.utils.json.JsonUtils.toJsonString
import com.github.purofle.nmsl.utils.os.OS
import kotlin.io.path.createDirectories
import kotlin.io.path.readText
import kotlin.io.path.writeText

object Config {
private val configPath by lazy { OS.getConfigPath() }
private val configPath by lazy {
OS.getConfigPath().also { it.parent.createDirectories() }
}
val config by lazy { readConfig() }

fun createConfig(config: NmslConfig) {
configPath.writeText(config.toJsonString())
}

private fun readConfig(): NmslConfig = configPath.readText().toJsonObject()
fun readConfig(): NmslConfig = configPath.readText().toJsonObject()
}
5 changes: 5 additions & 0 deletions compose-desktop.pro
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
-keepclasseswithmembers public class com.github.purofle.nmsl.MainKt {
public static void main(java.lang.String[]);
}

-keepattributes InnerClasses

-keep @kotlinx.serialization.Serializable class * {*;}

-keep class org.jetbrains.skia.** { *; }
-keep class org.jetbrains.skiko.** { *; }

Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/com/github/purofle/nmsl/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.apache.logging.log4j.LogManager
fun main() {

Thread.setDefaultUncaughtExceptionHandler { _, e ->
e.printStackTrace()
LogManager.getLogger("error").error(e)
}

Expand Down
48 changes: 30 additions & 18 deletions src/main/kotlin/com/github/purofle/nmsl/pages/GamePage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,30 @@ class GamePage : Page {
val gameList = remember { mutableStateListOf<String>() }
var showMicrosoftLoginDialog by remember { mutableStateOf(false) }

val snackbarHostState = remember { SnackbarHostState() }

var config = Config.readConfig().profile.minecraftProfile.name
if (config.isEmpty()) {
config = "Microsoft Account"
}

val scope = rememberCoroutineScope()

LaunchedEffect(Unit) {
gameList.addAll(GameManager.versions)
}

if (showMicrosoftLoginDialog) {
MicrosoftLoginDialog {
MicrosoftLoginDialog({
showMicrosoftLoginDialog = false
scope.launch {
snackbarHostState.showSnackbar("Login cancel")
}
}) {
showMicrosoftLoginDialog = false
scope.launch {
snackbarHostState.showSnackbar("Login success")
}
}
}

Expand All @@ -70,7 +85,7 @@ class GamePage : Page {
Scaffold(
topBar = {
Column(Modifier.fillMaxWidth()) {
MicrosoftAccount {
MicrosoftAccount(config) {
showMicrosoftLoginDialog = true
}
}
Expand All @@ -90,7 +105,10 @@ class GamePage : Page {
Text("启动游戏")
}
}
}
},
snackbarHost = {
SnackbarHost(hostState = snackbarHostState)
},
) { pd ->
Box(modifier = Modifier.padding(pd).fillMaxSize()) {
if (selectedGame.isEmpty()) {
Expand Down Expand Up @@ -137,14 +155,9 @@ fun GameItem(text: String, onClick: () -> Unit) {
}

@Composable
fun MicrosoftAccount(onClick: () -> Unit) {
fun MicrosoftAccount(name: String, onClick: () -> Unit) {
val primaryContainer = MaterialTheme.colorScheme.primaryContainer

var config = Config.config.profile.minecraftProfile.name
if (config.isEmpty()) {
config = "Microsoft Account"
}

Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.clickable {
Expand All @@ -153,24 +166,23 @@ fun MicrosoftAccount(onClick: () -> Unit) {
.background(MaterialTheme.colorScheme.onSecondary)
) {

Text(config.first().uppercase(), modifier = Modifier.drawBehind {
Text(name.first().uppercase(), modifier = Modifier.drawBehind {
drawCircle(primaryContainer, radius = 20f)
}.padding(30.dp, 15.dp))

Text(config, modifier = Modifier.padding(5.dp, 0.dp))
Text(name, modifier = Modifier.padding(5.dp, 0.dp))
}
}

@Composable
fun MicrosoftLoginDialog(callback: () -> Unit) {
fun MicrosoftLoginDialog(onDismissCallback: () -> Unit, callback: () -> Unit) {

var deviceCode by remember { mutableStateOf("") }

LaunchedEffect(Unit) {
val deviceFlow = MicrosoftAuth.getDeviceAuthorization()
deviceCode = deviceFlow.userCode

launch {
MicrosoftAuth.authorizationFlow(deviceFlow.deviceCode).collect { auth ->
Config.createConfig(
NmslConfig(
Expand All @@ -183,19 +195,19 @@ fun MicrosoftLoginDialog(callback: () -> Unit) {
)
)
callback()
}

}
}

val text = if (deviceCode.isNotEmpty()) "复制 $deviceCode 并打开 https://www.microsoft.com/link 来登录" else "请稍等..."
AlertDialog(
onDismissRequest = { callback() },
onDismissRequest = { onDismissCallback() },
title = { Text("Microsoft Login") },
text = { Text("复制 $deviceCode 并打开 https://www.microsoft.com/link 来登录") },
text = { Text(text) },
confirmButton = {
Button(onClick = {
ClipboardManager().setText(deviceCode)
URIManager().openUri("https://www.microsoft.com/link")
}) {
}, enabled = deviceCode.isNotEmpty()) {
Text("复制并打开浏览器")
}
},
Expand Down

0 comments on commit 0e4f1f4

Please sign in to comment.