small ui change

This commit is contained in:
Chloe committed 2025-01-20 05:36:31 -07:00
1 parent 220c1b0dd6
commit b03ff6b735
12 files changed
+152 -107

No files matched your search

@@ -15,7 +15,6 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.size
@@ -24,13 +23,12 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Warning
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
@@ -60,6 +58,7 @@ import com.geode.launcher.main.*
import com.geode.launcher.ui.theme.GeodeLauncherTheme
import com.geode.launcher.ui.theme.LocalTheme
import com.geode.launcher.ui.theme.Theme
import com.geode.launcher.utils.Constants
import com.geode.launcher.utils.GamePackageUtils
import com.geode.launcher.utils.LaunchUtils
import com.geode.launcher.utils.PreferenceUtils
@@ -123,7 +122,7 @@ class AltMainActivity : ComponentActivity() {
}
data class LaunchStatusInfo(
val title: String,
val title: String?,
val details: String? = null,
val progress: (() -> Float)? = null
)
@@ -156,8 +155,9 @@ fun mapCancelReasonToInfo(cancelReason: LaunchViewModel.LaunchCancelReason): Lau
title = stringResource(R.string.launcher_cancelled_error),
details = stringResource(R.string.launcher_cancelled_outdated)
)
LaunchViewModel.LaunchCancelReason.AUTOMATIC -> LaunchStatusInfo(
title = stringResource(R.string.launcher_cancelled_navigated_away)
LaunchViewModel.LaunchCancelReason.AUTOMATIC,
LaunchViewModel.LaunchCancelReason.MANUAL-> LaunchStatusInfo(
title = null
)
else -> LaunchStatusInfo(
title = stringResource(R.string.launcher_cancelled_manual)
@@ -185,7 +185,7 @@ fun mapLaunchStatusToInfo(state: LaunchViewModel.LaunchUIState, inSafeMode: Bool
}
val outOf = remember(state.outOf) {
state.outOf?.apply {
state.outOf?.run {
Formatter.formatShortFileSize(context, this)
}
}
@@ -207,16 +207,22 @@ fun mapLaunchStatusToInfo(state: LaunchViewModel.LaunchUIState, inSafeMode: Bool
@Composable
fun LaunchCancelledBody(statusInfo: LaunchStatusInfo, icon: @Composable () -> Unit, inProgress: Boolean, modifier: Modifier = Modifier) {
if (statusInfo.title == null && statusInfo.details == null && !inProgress) {
return
}
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalAlignment = Alignment.Start,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier.width(300.dp)
) {
Row(verticalAlignment = Alignment.CenterVertically) {
CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.bodyLarge) {
icon()
Spacer(Modifier.size(8.dp))
Text(statusInfo.title)
if (statusInfo.title != null) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center) {
CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.bodyLarge) {
icon()
Spacer(Modifier.size(8.dp))
Text(statusInfo.title)
}
}
}
@@ -227,7 +233,8 @@ fun LaunchCancelledBody(statusInfo: LaunchStatusInfo, icon: @Composable () -> Un
if (statusInfo.details != null) {
Text(
statusInfo.details,
style = MaterialTheme.typography.bodyMedium
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Center
)
}
}
@@ -241,7 +248,9 @@ fun LaunchProgressBody(statusInfo: LaunchStatusInfo, modifier: Modifier = Modifi
horizontalAlignment = Alignment.Start,
modifier = modifier.width(300.dp)
) {
Text(statusInfo.title, style = MaterialTheme.typography.bodyLarge)
if (statusInfo.title != null) {
Text(statusInfo.title, style = MaterialTheme.typography.bodyLarge)
}
if (statusInfo.progress != null) {
LinearProgressIndicator(
@@ -261,16 +270,7 @@ fun LaunchProgressBody(statusInfo: LaunchStatusInfo, modifier: Modifier = Modifi
@Composable
fun RetryButtonContents(reason: LaunchViewModel.LaunchCancelReason) {
when (reason) {
LaunchViewModel.LaunchCancelReason.MANUAL -> {
Icon(
Icons.Filled.Refresh,
contentDescription = null
)
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
Text(stringResource(R.string.launcher_cancelled_restart))
}
LaunchViewModel.LaunchCancelReason.LAST_LAUNCH_CRASHED,
LaunchViewModel.LaunchCancelReason.AUTOMATIC -> {
LaunchViewModel.LaunchCancelReason.LAST_LAUNCH_CRASHED -> {
Icon(
painterResource(R.drawable.icon_resume),
contentDescription = null
@@ -278,6 +278,15 @@ fun RetryButtonContents(reason: LaunchViewModel.LaunchCancelReason) {
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
Text(stringResource(R.string.launcher_cancelled_resume))
}
LaunchViewModel.LaunchCancelReason.MANUAL,
LaunchViewModel.LaunchCancelReason.AUTOMATIC -> {
Icon(
Icons.Filled.PlayArrow,
contentDescription = null
)
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
Text(stringResource(R.string.launcher_launch))
}
LaunchViewModel.LaunchCancelReason.GEODE_NOT_FOUND -> {
Icon(
Icons.Filled.Refresh,
@@ -307,8 +316,8 @@ fun LaunchProgressCard(
var showSafeModeDialog by remember { mutableStateOf(false) }
val status = mapLaunchStatusToInfo(uiState, safeModeEnabled)
Card(modifier = modifier.width(300.dp)) {
Column(verticalArrangement = Arrangement.spacedBy(12.dp), modifier = Modifier.padding(16.dp)) {
Box(modifier = modifier) {
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
if (uiState is LaunchViewModel.LaunchUIState.Cancelled) {
LaunchCancelledBody(
statusInfo = status,
@@ -316,13 +325,9 @@ fun LaunchProgressCard(
inProgress = uiState.inProgress
)
if (uiState.reason == LaunchViewModel.LaunchCancelReason.GAME_OUTDATED) {
if (uiState.reason.isGameInstallIssue()) {
val context = LocalContext.current
// game should be downloaded if this message is showing
val showDownload = remember {
!GamePackageUtils.identifyGameLegitimacy(context.packageManager)
}
val showDownload = remember { GamePackageUtils.showDownloadBadge(context.packageManager) }
if (showDownload) {
GooglePlayBadge(modifier = Modifier.align(Alignment.CenterHorizontally))
@@ -331,8 +336,8 @@ fun LaunchProgressCard(
if (uiState.reason.allowsRetry()) {
FlowRow(
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.width(300.dp)
horizontalArrangement = Arrangement.spacedBy(8.dp, alignment = Alignment.CenterHorizontally),
modifier = Modifier.align(Alignment.CenterHorizontally)
) {
LongPressButton(onClick = { onResume(false) }, onLongPress = {
showSafeModeDialog = true
@@ -340,14 +345,14 @@ fun LaunchProgressCard(
RetryButtonContents(uiState.reason)
}
Spacer(Modifier.weight(1.0f))
if (crashInfo != null) {
IconButton(onClick = onMore) {
FilledTonalButton(onClick = onMore) {
Icon(
painterResource(R.drawable.icon_question_mark),
contentDescription = stringResource(R.string.launcher_cancelled_help_alt)
contentDescription = null
)
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
Text(stringResource(R.string.launcher_cancelled_help_alt))
}
}
@@ -355,7 +360,7 @@ fun LaunchProgressCard(
}
}
} else {
LaunchProgressBody(statusInfo = status)
LaunchProgressBody(statusInfo = status, modifier = Modifier.padding(top = 16.dp))
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.width(300.dp)) {
TextButton(onClick = onCancel) {
@@ -438,10 +443,9 @@ fun AltMainScreen(
contentAlignment = Alignment.Center
) {
Column(
verticalArrangement = Arrangement.spacedBy(32.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.height(350.dp)
.padding(8.dp)
.verticalScroll(rememberScrollState())
) {
@@ -485,27 +489,18 @@ fun AltMainScreen(
safeModeEnabled = launchInSafeMode
)
val nextLauncherUpdate by launchViewModel.nextLauncherUpdate.collectAsState()
// only show launcher update in a case where a user won't see it ingame
if (nextLauncherUpdate != null && launchUIState is LaunchViewModel.LaunchUIState.Cancelled) {
StatusIndicator(
icon = {
Icon(
Icons.Default.Info,
contentDescription = null
)
},
onClick = {
installLauncherUpdate(context)
},
text = {
Text(
stringResource(R.string.launcher_update_available),
textAlign = TextAlign.Center
)
}
)
if (launchUIState is LaunchViewModel.LaunchUIState.Cancelled) {
val gameVersion = remember { GamePackageUtils.getGameVersionCodeOrNull(context.packageManager) }
if (gameVersion != null && gameVersion < Constants.SUPPORTED_VERSION_CODE_MIN_WARNING) {
UnsupportedVersionWarning()
}
val nextLauncherUpdate by launchViewModel.nextLauncherUpdate.collectAsState()
if (nextLauncherUpdate != null) {
LauncherUpdateIndicator()
}
}
}
}
@@ -22,6 +22,7 @@ import androidx.core.view.WindowInsetsControllerCompat
import com.customRobTop.BaseRobTopActivity
import com.customRobTop.JniToCpp
import com.geode.launcher.main.LaunchNotification
import com.geode.launcher.main.determineDisplayedCards
import com.geode.launcher.utils.Constants
import com.geode.launcher.utils.ConstrainedFrameLayout
import com.geode.launcher.utils.DownloadUtils
@@ -406,11 +407,14 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
val showNotification = PreferenceUtils.get(this).getBoolean(PreferenceUtils.Key.ENABLE_REDESIGN)
if (showNotification) {
val notificationView = ComposeView(this)
frameLayout.addView(notificationView)
val hasCards = determineDisplayedCards(this)
if (hasCards.isNotEmpty()) {
val notificationView = ComposeView(this)
frameLayout.addView(notificationView)
notificationView.setContent {
LaunchNotification()
notificationView.setContent {
LaunchNotification()
}
}
}
@@ -63,7 +63,6 @@ class MainActivity : ComponentActivity() {
LoadFailureInfo(LaunchUtils.LauncherError.CRASHED)
} else { null }
/*
val redirectToAlt = PreferenceUtils.get(this).getBoolean(PreferenceUtils.Key.ENABLE_REDESIGN)
if (redirectToAlt) {
val launchIntent = Intent(this, AltMainActivity::class.java)
@@ -72,7 +71,6 @@ class MainActivity : ComponentActivity() {
return
}
*/
setContent {
val themeOption by PreferenceUtils.useIntPreference(PreferenceUtils.Key.THEME)
@@ -114,7 +112,7 @@ fun MainScreen(
val autoUpdateState by releaseViewModel.uiState.collectAsState()
val geodeJustInstalled = (autoUpdateState as? ReleaseViewModel.ReleaseUIState.Finished)
?.hasUpdated ?: false
?.hasUpdated == true
val geodeInstalled = geodePreinstalled || geodeJustInstalled
var beginLaunch by remember { mutableStateOf(false) }
@@ -194,26 +192,7 @@ fun MainScreen(
)
if (gdVersion < Constants.SUPPORTED_VERSION_CODE_MIN_WARNING) {
InlineDialog(
headline = {
Icon(
Icons.Default.Warning,
contentDescription = null,
modifier = Modifier.size(28.dp)
)
Text(
stringResource(R.string.launcher_unsupported_version_title),
style = MaterialTheme.typography.titleMedium,
)
},
body = {
Text(
stringResource(R.string.launcher_game_update_required),
)
},
modifier = Modifier.padding(8.dp)
)
UnsupportedVersionWarning()
}
}
}
@@ -266,10 +266,7 @@ fun DownloadRecommendation(needsUniversal: Boolean, modifier: Modifier = Modifie
val context = LocalContext.current
val version = BuildConfig.VERSION_NAME
val showDownload = remember {
!GamePackageUtils.isGameInstalled(context.packageManager) ||
!GamePackageUtils.identifyGameLegitimacy(context.packageManager)
}
val showDownload = remember { GamePackageUtils.showDownloadBadge(context.packageManager) }
val downloadBase = "https://github.com/geode-sdk/android-launcher/releases/download/$version"
val legacyDownloadUrl = "$downloadBase/geode-launcher-v$version-android32.apk"
@@ -279,10 +279,7 @@ fun PlayButton(
fun LaunchBlockedLabel(text: String) {
val context = LocalContext.current
val showDownload = remember {
!GamePackageUtils.isGameInstalled(context.packageManager) ||
!GamePackageUtils.identifyGameLegitimacy(context.packageManager)
}
val showDownload = remember { GamePackageUtils.showDownloadBadge(context.packageManager) }
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text, textAlign = TextAlign.Center, modifier = Modifier.padding(12.dp))
@@ -292,3 +289,27 @@ fun LaunchBlockedLabel(text: String) {
}
}
}
@Composable
fun UnsupportedVersionWarning(modifier: Modifier = Modifier) {
InlineDialog(
headline = {
Icon(
Icons.Default.Warning,
contentDescription = null,
modifier = Modifier.size(28.dp)
)
Text(
stringResource(R.string.launcher_unsupported_version_title),
style = MaterialTheme.typography.titleMedium,
)
},
body = {
Text(
stringResource(R.string.launcher_game_update_required),
)
},
modifier = modifier.padding(8.dp)
)
}
@@ -39,16 +39,22 @@ import com.geode.launcher.ui.theme.GeodeLauncherTheme
import com.geode.launcher.ui.theme.LocalTheme
import com.geode.launcher.ui.theme.Theme
import com.geode.launcher.updater.ReleaseManager
import com.geode.launcher.utils.Constants
import com.geode.launcher.utils.GamePackageUtils
import com.geode.launcher.utils.PreferenceUtils
import kotlinx.coroutines.delay
enum class LaunchNotificationType {
GEODE_UPDATED, LAUNCHER_UPDATE_AVAILABLE, UPDATE_FAILED;
GEODE_UPDATED, LAUNCHER_UPDATE_AVAILABLE, UPDATE_FAILED, UNSUPPORTED_VERSION;
}
fun determineDisplayedCards(context: Context): List<LaunchNotificationType> {
val cards = mutableListOf<LaunchNotificationType>()
if (GamePackageUtils.getGameVersionCode(context.packageManager) < Constants.SUPPORTED_VERSION_CODE_MIN_WARNING) {
cards.add(LaunchNotificationType.UNSUPPORTED_VERSION)
}
val releaseManager = ReleaseManager.get(context)
val availableUpdate = releaseManager.availableLauncherUpdate.value
@@ -95,6 +101,11 @@ fun NotificationCardFromType(type: LaunchNotificationType) {
UpdateFailedContent()
}
}
LaunchNotificationType.UNSUPPORTED_VERSION -> {
AnimatedNotificationCard {
OutdatedVersionContent()
}
}
else -> {}
}
}
@@ -212,6 +223,25 @@ fun UpdateNotificationContent(modifier: Modifier = Modifier) {
)
}
@Composable
fun OutdatedVersionContent(modifier: Modifier = Modifier) {
ListItem(
headlineContent = {
Text(text = stringResource(id = R.string.launcher_notification_compatibility))
},
leadingContent = {
Icon(
Icons.Filled.Warning,
contentDescription = null,
)
},
supportingContent = {
Text(text = stringResource(id = R.string.launcher_notification_compatibility_description))
},
modifier = modifier.width(IntrinsicSize.Max)
)
}
@Composable
fun UpdateFailedContent(modifier: Modifier = Modifier) {
ListItem(
@@ -18,7 +18,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.launch
private const val COOLDOWN_LENGTH_MS = 1000L
private const val COOLDOWN_LENGTH_MS = 3000L
class LaunchViewModel(private val application: Application): ViewModel() {
companion object {
@@ -65,6 +65,12 @@ class LaunchViewModel(private val application: Application): ViewModel() {
GAME_MISSING,
GAME_OUTDATED -> false
}
fun isGameInstallIssue() = when (this) {
GAME_OUTDATED,
GAME_MISSING -> true
else -> false
}
}
sealed class LaunchUIState {
@@ -171,14 +171,13 @@ fun DeveloperSettingsScreen(onBackPressedDispatcher: OnBackPressedDispatcher?) {
)
}
}
/*
OptionsGroup(title = stringResource(R.string.preference_category_testing)) {
SettingsCard(
title = stringResource(R.string.preference_enable_redesign),
preferenceKey = PreferenceUtils.Key.ENABLE_REDESIGN,
)
}
*/
}
}
}
@@ -188,8 +188,8 @@ fun UpdateIndicator(
context.getString(R.string.preference_check_for_updates_success)
)
} else {
val gdInstalled = GamePackageUtils.isGameInstalled(context.packageManager)
if (gdInstalled && GamePackageUtils.getGameVersionCode(context.packageManager) < Constants.SUPPORTED_VERSION_CODE) {
val gameVersion = GamePackageUtils.getGameVersionCodeOrNull(context.packageManager)
if (gameVersion != null && gameVersion < Constants.SUPPORTED_VERSION_CODE) {
snackbarHostState.showSnackbar(
context.getString(R.string.launcher_game_update_required_short)
)
@@ -20,6 +20,9 @@ object GamePackageUtils {
}
}
fun showDownloadBadge(packageManager: PackageManager) =
!isGameInstalled(packageManager) || !identifyGameLegitimacy(packageManager)
fun getGameVersionCode(packageManager: PackageManager): Long {
val game = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
@@ -31,6 +34,14 @@ object GamePackageUtils {
}
}
fun getGameVersionCodeOrNull(packageManager: PackageManager): Long? {
return try {
getGameVersionCode(packageManager)
} catch (e: PackageManager.NameNotFoundException) {
null
}
}
fun getGameVersionString(packageManager: PackageManager): String {
val game = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
return game.versionName ?: "0.000"
@@ -3,6 +3,7 @@ package com.geode.launcher.utils
import android.content.Context
import android.os.Build
import java.io.File
import java.io.Serializable
object LaunchUtils {
// supposedly CPU_ABI returns the current arch for the running application
@@ -92,7 +93,7 @@ object LaunchUtils {
return crashIndicatorFile.exists()
}
enum class LauncherError {
enum class LauncherError : Serializable {
LINKER_NEEDS_64BIT,
LINKER_NEEDS_32BIT,
LINKER_FAILED_STL,
+5 -3
View File
@@ -58,14 +58,16 @@
<string name="launcher_error_device_info">Android %2$s, %1$s (%5$s)\nGD %4$s, Geode %3$s + v%6$s</string>
<string name="launcher_notification_settings">Launcher Settings</string>
<string name="launcher_notification_update_failed">Failed to check for updates.</string>
<string name="launcher_notification_update_failed">Failed to update Geode.</string>
<string name="launcher_notification_update_success">Geode updated!</string>
<string name="launcher_notification_update_cta">Tap to view.</string>
<string name="launcher_notification_compatibility">Unsupported Geometry Dash version.</string>
<string name="launcher_notification_compatibility_description">An update is required to receive Geode updates.</string>
<string name="launcher_notification_update_cta">Tap for more information.</string>
<string name="launcher_starting_game">Starting Geometry Dash…</string>
<string name="launcher_downloading_update">Downloading update…</string>
<string name="launcher_downloading_update_details">(%1$s/%2$s)</string>
<string name="launcher_cancelled_manual">Launch cancelled.</string>
<string name="launcher_cancelled_manual">Launch paused.</string>
<string name="launcher_cancelled_navigated_away">Launch paused.</string>
<string name="launcher_cancelled_crash">Launch paused due to a crash.</string>
<string name="launcher_cancelled_error">Could not start Geode.</string>