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