mirror of
https://github.com/geode-sdk/android-launcher.git
synced 2026-10-21 08:19:33 +00:00
error view
This commit is contained in:
4 files changed
+80
-12
No files matched your search
@@ -1,5 +1,6 @@
|
||||
package com.geode.launcher
|
||||
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.os.Bundle
|
||||
import android.text.format.Formatter
|
||||
import androidx.activity.ComponentActivity
|
||||
@@ -26,6 +27,7 @@ import androidx.compose.material.icons.filled.Warning
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.FilledTonalButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
@@ -44,7 +46,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -63,7 +64,7 @@ class AltMainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
||||
enableEdgeToEdge()
|
||||
|
||||
val gdInstalled = GamePackageUtils.isGameInstalled(packageManager)
|
||||
@@ -98,16 +99,13 @@ class AltMainActivity : ComponentActivity() {
|
||||
CompositionLocalProvider(LocalTheme provides theme) {
|
||||
GeodeLauncherTheme(theme = theme, blackBackground = backgroundOption) {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = Color.Transparent
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
WithWave {
|
||||
AltMainScreen(launchViewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gdInstalled && geodeInstalled) {
|
||||
intent.getBooleanExtra("restarted", false).let {
|
||||
@@ -234,11 +232,15 @@ fun LaunchProgressBody(statusInfo: LaunchStatusInfo, modifier: Modifier = Modifi
|
||||
if (statusInfo.progress != null) {
|
||||
LinearProgressIndicator(
|
||||
statusInfo.progress,
|
||||
modifier = Modifier.width(300.dp).align(Alignment.CenterHorizontally)
|
||||
modifier = Modifier
|
||||
.width(300.dp)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
} else {
|
||||
LinearProgressIndicator(
|
||||
modifier = Modifier.width(300.dp).align(Alignment.CenterHorizontally)
|
||||
modifier = Modifier
|
||||
.width(300.dp)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -249,7 +251,14 @@ fun LaunchProgressBody(statusInfo: LaunchStatusInfo, modifier: Modifier = Modifi
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LaunchProgressCard(uiState: LaunchViewModel.LaunchUIState, onCancel: () -> Unit, onResume: () -> Unit, modifier: Modifier = Modifier) {
|
||||
fun LaunchProgressCard(
|
||||
uiState: LaunchViewModel.LaunchUIState,
|
||||
crashInfo: LoadFailureInfo?,
|
||||
onCancel: () -> Unit,
|
||||
onResume: () -> Unit,
|
||||
onMore: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val status = mapLaunchStatusToInfo(uiState)
|
||||
Card(modifier = modifier) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.padding(16.dp)) {
|
||||
@@ -260,6 +269,7 @@ fun LaunchProgressCard(uiState: LaunchViewModel.LaunchUIState, onCancel: () -> U
|
||||
inProgress = uiState.inProgress
|
||||
)
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
if (uiState.reason.allowsRetry()) {
|
||||
Button(onClick = onResume) {
|
||||
Icon(
|
||||
@@ -270,6 +280,18 @@ fun LaunchProgressCard(uiState: LaunchViewModel.LaunchUIState, onCancel: () -> U
|
||||
Text(stringResource(R.string.launcher_cancelled_restart))
|
||||
}
|
||||
}
|
||||
|
||||
if (crashInfo != null) {
|
||||
FilledTonalButton(onClick = onMore) {
|
||||
Icon(
|
||||
painterResource(R.drawable.icon_question_mark),
|
||||
contentDescription = null
|
||||
)
|
||||
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
|
||||
Text(stringResource(R.string.launcher_error_more))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LaunchProgressBody(statusInfo = status)
|
||||
|
||||
@@ -314,6 +336,7 @@ fun AltMainScreen(
|
||||
val launchUIState by launchViewModel.uiState.collectAsState()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var launchInSafeMode by remember { mutableStateOf(false) }
|
||||
var showErrorInfo by remember { mutableStateOf(false) }
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
@@ -325,6 +348,7 @@ fun AltMainScreen(
|
||||
|
||||
LaunchProgressCard(
|
||||
launchUIState,
|
||||
crashInfo = launchViewModel.currentCrashInfo(),
|
||||
onCancel = {
|
||||
launchInSafeMode = false
|
||||
coroutineScope.launch {
|
||||
@@ -332,12 +356,17 @@ fun AltMainScreen(
|
||||
}
|
||||
},
|
||||
onResume = {
|
||||
launchViewModel.loadFailure = null
|
||||
launchViewModel.clearCrashInfo()
|
||||
coroutineScope.launch {
|
||||
launchViewModel.beginLaunchFlow()
|
||||
}
|
||||
},
|
||||
modifier = Modifier.padding(16.dp).offset(y = 90.dp)
|
||||
onMore = {
|
||||
showErrorInfo = true
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.offset(y = 90.dp)
|
||||
)
|
||||
|
||||
Row(
|
||||
@@ -374,4 +403,9 @@ fun AltMainScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val loadFailure = launchViewModel.currentCrashInfo()
|
||||
if (showErrorInfo && loadFailure != null) {
|
||||
ErrorInfoSheet(loadFailure, onDismiss = { showErrorInfo = false })
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,7 @@ class MainActivity : ComponentActivity() {
|
||||
val redirectToAlt = PreferenceUtils.get(this).getBoolean(PreferenceUtils.Key.ENABLE_REDESIGN)
|
||||
if (redirectToAlt) {
|
||||
val launchIntent = Intent(this, AltMainActivity::class.java)
|
||||
launchIntent.putExtras(intent)
|
||||
startActivity(launchIntent)
|
||||
|
||||
return
|
||||
|
||||
@@ -18,6 +18,8 @@ import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private const val COOLDOWN_LENGTH_MS = 1000L
|
||||
|
||||
class LaunchViewModel(private val application: Application): ViewModel() {
|
||||
companion object {
|
||||
val Factory: ViewModelProvider.Factory = viewModelFactory {
|
||||
@@ -35,7 +37,7 @@ class LaunchViewModel(private val application: Application): ViewModel() {
|
||||
private var readyTimer: CountDownTimer? = null
|
||||
|
||||
private fun initReadyTimer() {
|
||||
readyTimer = object : CountDownTimer(1000, 1000) {
|
||||
readyTimer = object : CountDownTimer(COOLDOWN_LENGTH_MS, 1000) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
// no tick necessary
|
||||
}
|
||||
@@ -97,6 +99,22 @@ class LaunchViewModel(private val application: Application): ViewModel() {
|
||||
preReadyCheck()
|
||||
}
|
||||
|
||||
fun currentCrashInfo(): LoadFailureInfo? {
|
||||
val currentState = _uiState.value
|
||||
if (currentState is LaunchUIState.Cancelled && currentState.reason == LaunchCancelReason.LAST_LAUNCH_CRASHED) {
|
||||
return loadFailure
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun clearCrashInfo() {
|
||||
val currentState = _uiState.value
|
||||
if (currentState is LaunchUIState.Cancelled && currentState.reason == LaunchCancelReason.LAST_LAUNCH_CRASHED) {
|
||||
loadFailure = null
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun preReadyCheck() {
|
||||
if (isCancelling) {
|
||||
// don't let the game start if cancelled
|
||||
@@ -161,6 +179,11 @@ class LaunchViewModel(private val application: Application): ViewModel() {
|
||||
}
|
||||
|
||||
suspend fun cancelLaunch() {
|
||||
// no need to double cancel
|
||||
if (_uiState.value is LaunchUIState.Cancelled) {
|
||||
return
|
||||
}
|
||||
|
||||
isCancelling = true
|
||||
_uiState.emit(LaunchUIState.Cancelled(LaunchCancelReason.MANUAL, true))
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M424,640Q424,559 438.5,523.5Q453,488 500,446Q541,410 562.5,383.5Q584,357 584,323Q584,282 556.5,255Q529,228 480,228Q429,228 402.5,259Q376,290 365,322L262,278Q283,214 339,167Q395,120 480,120Q585,120 641.5,178.5Q698,237 698,319Q698,369 676.5,404.5Q655,440 609,485Q560,532 549.5,556.5Q539,581 539,640L424,640ZM480,880Q447,880 423.5,856.5Q400,833 400,800Q400,767 423.5,743.5Q447,720 480,720Q513,720 536.5,743.5Q560,767 560,800Q560,833 536.5,856.5Q513,880 480,880Z"/>
|
||||
</vector>
|
||||
Reference in new issue
Block a user