add ui to launch in safe mode

closes #17
This commit is contained in:
qimiko committed 2024-02-02 02:06:43 -07:00
1 parent e806ec223a
commit 019d9747b5
2 files changed
+97 -8

No files matched your search

@@ -8,6 +8,8 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
@@ -27,8 +29,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -46,7 +51,10 @@ import com.geode.launcher.utils.Constants
import com.geode.launcher.utils.LaunchUtils import com.geode.launcher.utils.LaunchUtils
import com.geode.launcher.utils.PreferenceUtils import com.geode.launcher.utils.PreferenceUtils
import com.geode.launcher.updater.ReleaseManager import com.geode.launcher.updater.ReleaseManager
import com.geode.launcher.utils.GeodeUtils
import com.geode.launcher.utils.useCountdownTimer import com.geode.launcher.utils.useCountdownTimer
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import java.net.ConnectException import java.net.ConnectException
import java.net.UnknownHostException import java.net.UnknownHostException
@@ -122,7 +130,7 @@ fun LauncherUpdateIndicator(modifier: Modifier = Modifier, openTo: String, onDis
Spacer(Modifier.size(4.dp)) Spacer(Modifier.size(4.dp))
TextButton(onClick = { uriHandler.openUri(openTo) },) { TextButton(onClick = { uriHandler.openUri(openTo) }) {
Text(stringResource(R.string.launcher_download)) Text(stringResource(R.string.launcher_download))
} }
} }
@@ -226,7 +234,7 @@ fun LoadFailedDialog(returnTitle: String, returnMessage: String) {
} }
@Composable @Composable
fun UpdateWarning() { fun UpdateWarning(inSafeMode: Boolean = false) {
val context = LocalContext.current val context = LocalContext.current
val packageManager = context.packageManager val packageManager = context.packageManager
@@ -267,7 +275,7 @@ fun UpdateWarning() {
showUpdateWarning = false showUpdateWarning = false
lastDismissedVersion = gdVersionCode lastDismissedVersion = gdVersionCode
onLaunch(context) onLaunch(context, inSafeMode)
}) { }) {
Text(stringResource(R.string.message_box_accept)) Text(stringResource(R.string.message_box_accept))
} }
@@ -282,11 +290,36 @@ fun UpdateWarning() {
} }
} else { } else {
LaunchedEffect(gdVersionCode) { LaunchedEffect(gdVersionCode) {
onLaunch(context) onLaunch(context, inSafeMode)
} }
} }
} }
@Composable
fun SafeModeDialog(onDismiss: () -> Unit, onLaunch: () -> Unit) {
AlertDialog(
icon = {
Icon(
Icons.Filled.Warning,
contentDescription = stringResource(R.string.launcher_warning_icon_alt)
)
},
title = { Text(stringResource(R.string.safe_mode_enable_title)) },
text = { Text(stringResource(R.string.safe_mode_enable_description)) },
dismissButton = {
TextButton(onClick = onDismiss) {
Text(stringResource(R.string.message_box_cancel))
}
},
confirmButton = {
TextButton(onClick = onLaunch) {
Text(stringResource(R.string.message_box_continue))
}
},
onDismissRequest = onDismiss
)
}
@Composable @Composable
fun UpdateCard(releaseViewModel: ReleaseViewModel, modifier: Modifier = Modifier) { fun UpdateCard(releaseViewModel: ReleaseViewModel, modifier: Modifier = Modifier) {
val context = LocalContext.current val context = LocalContext.current
@@ -389,7 +422,13 @@ fun UpdateCard(releaseViewModel: ReleaseViewModel, modifier: Modifier = Modifier
} }
} }
fun onLaunch(context: Context) { fun onLaunch(context: Context, safeMode: Boolean = false) {
if (safeMode) {
GeodeUtils.setAdditionalLaunchArguments(GeodeUtils.ARGUMENT_SAFE_MODE)
} else {
GeodeUtils.clearLaunchArguments()
}
val launchIntent = Intent(context, GeometryDashActivity::class.java) val launchIntent = Intent(context, GeometryDashActivity::class.java)
launchIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK launchIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
@@ -423,6 +462,8 @@ fun MainScreen(
val geodeInstalled = geodePreinstalled || geodeJustInstalled val geodeInstalled = geodePreinstalled || geodeJustInstalled
var beginLaunch by remember { mutableStateOf(false) } var beginLaunch by remember { mutableStateOf(false) }
var showSafeModeDialog by remember { mutableStateOf(false) }
var launchInSafeMode by remember { mutableStateOf(false) }
LaunchedEffect(shouldUpdate) { LaunchedEffect(shouldUpdate) {
if (shouldUpdate && !releaseViewModel.hasPerformedCheck) { if (shouldUpdate && !releaseViewModel.hasPerformedCheck) {
@@ -476,10 +517,43 @@ fun MainScreen(
} }
} }
// compose apis don't provide a good way of adding long press to a button
val interactionSource = remember { MutableInteractionSource() }
val viewConfiguration = LocalViewConfiguration.current
val haptics = LocalHapticFeedback.current
LaunchedEffect(interactionSource) {
interactionSource.interactions.collectLatest { interaction ->
when (interaction) {
is PressInteraction.Press -> {
launchInSafeMode = false
delay(viewConfiguration.longPressTimeoutMillis)
// perform a second delay to make the action more obvious
haptics.performHapticFeedback(HapticFeedbackType.LongPress)
delay(viewConfiguration.longPressTimeoutMillis)
haptics.performHapticFeedback(HapticFeedbackType.LongPress)
showSafeModeDialog = true
}
is PressInteraction.Release -> {
if (!showSafeModeDialog) {
beginLaunch = true
}
}
}
}
}
Row { Row {
Button( Button(
onClick = { beginLaunch = true }, onClick = { },
enabled = !releaseViewModel.isInUpdate enabled = !releaseViewModel.isInUpdate,
interactionSource = interactionSource
) { ) {
Icon( Icon(
Icons.Filled.PlayArrow, Icons.Filled.PlayArrow,
@@ -545,7 +619,19 @@ fun MainScreen(
} }
if (beginLaunch) { if (beginLaunch) {
UpdateWarning() UpdateWarning(launchInSafeMode)
}
if (showSafeModeDialog) {
SafeModeDialog(
onDismiss = {
showSafeModeDialog = false
},
onLaunch = {
launchInSafeMode = true
beginLaunch = true
}
)
} }
} }
+3
View File
@@ -30,6 +30,8 @@
</string> </string>
<string name="launcher_update_available">A new launcher update is available!</string> <string name="launcher_update_available">A new launcher update is available!</string>
<string name="launcher_update_dismiss">Dismiss</string> <string name="launcher_update_dismiss">Dismiss</string>
<string name="safe_mode_enable_title">Enable safe mode?</string>
<string name="safe_mode_enable_description">Safe mode disables loading of all mods, allowing one to remove problematic mods or diagnose crashes. If you\'re not experiencing issues with Geode, you should probably not be using safe mode.</string>
<!-- Updater strings --> <!-- Updater strings -->
<string name="release_fetch_failed">Update failed.\n%1$s</string> <string name="release_fetch_failed">Update failed.\n%1$s</string>
@@ -53,6 +55,7 @@
<string name="load_failed_generic_error_description">Uncaught error during game load: `%1$s`.\nCheck application logs for more details.</string> <string name="load_failed_generic_error_description">Uncaught error during game load: `%1$s`.\nCheck application logs for more details.</string>
<string name="message_box_cancel">Cancel</string> <string name="message_box_cancel">Cancel</string>
<string name="message_box_accept">OK</string> <string name="message_box_accept">OK</string>
<string name="message_box_continue">Continue</string>
<string name="missing_permissions">Missing required permissions for this action!</string> <string name="missing_permissions">Missing required permissions for this action!</string>
<!-- SettingsActivity strings --> <!-- SettingsActivity strings -->