mirror of
https://github.com/geode-sdk/android-launcher.git
synced 2026-10-21 16:32:39 +00:00
add autoload countdown
This commit is contained in:
5 files changed
+134
-2
No files matched your search
@@ -20,7 +20,10 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.geode.geodelauncher.ui.theme.GeodeLauncherTheme
|
||||
import com.geode.geodelauncher.ui.theme.Typography
|
||||
import com.geode.geodelauncher.utils.LaunchUtils
|
||||
import com.geode.geodelauncher.utils.countdownTimerWatcher
|
||||
import com.geode.geodelauncher.utils.preferenceWatcher
|
||||
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
@@ -58,6 +61,11 @@ fun onSettings(context: Context) {
|
||||
fun MainScreen(gdInstalled: Boolean = true) {
|
||||
val context = LocalContext.current
|
||||
|
||||
val shouldAutomaticallyLaunch = preferenceWatcher(
|
||||
preferenceFileKey = R.string.preference_file_key,
|
||||
preferenceId = R.string.preference_load_automatically
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
@@ -74,6 +82,29 @@ fun MainScreen(gdInstalled: Boolean = true) {
|
||||
modifier = Modifier.padding(12.dp)
|
||||
)
|
||||
if (gdInstalled) {
|
||||
if (shouldAutomaticallyLaunch.value) {
|
||||
val countdownTimer = countdownTimerWatcher(
|
||||
time = 3000,
|
||||
onCountdownFinish = {
|
||||
// just in case this changed async
|
||||
if (shouldAutomaticallyLaunch.value) {
|
||||
onLaunch(context)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if (countdownTimer.value != 0) {
|
||||
Text(
|
||||
context.resources.getQuantityString(
|
||||
R.plurals.automatically_load_countdown, countdownTimer.value, countdownTimer.value
|
||||
),
|
||||
style = Typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSecondaryContainer,
|
||||
)
|
||||
Spacer(Modifier.size(12.dp))
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
Button(onClick = { onLaunch(context) }, enabled = gdInstalled) {
|
||||
Icon(
|
||||
|
||||
@@ -143,7 +143,7 @@ fun toggleSetting(context: Context, @StringRes preferenceId: Int): Boolean {
|
||||
commit()
|
||||
}
|
||||
|
||||
return preferences.getBoolean(context.getString(R.string.preference_load_testing), false)
|
||||
return preferences.getBoolean(context.getString(preferenceId), false)
|
||||
}
|
||||
|
||||
fun getSetting(context: Context, @StringRes preferenceId: Int): Boolean {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.geode.geodelauncher.utils
|
||||
|
||||
import android.os.CountDownTimer
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
|
||||
const val MS_TO_SEC = 1000
|
||||
|
||||
@Composable
|
||||
fun countdownTimerWatcher(lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current, time: Int, onCountdownFinish: () -> Unit): MutableState<Int> {
|
||||
val timeData = remember {
|
||||
mutableStateOf(time / MS_TO_SEC % MS_TO_SEC)
|
||||
}
|
||||
|
||||
val countdownTimer =
|
||||
object : CountDownTimer(time.toLong(), 1000) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
timeData.value = (millisUntilFinished / MS_TO_SEC % MS_TO_SEC).toInt() + 1
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
onCountdownFinish()
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(lifecycleOwner) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_START) {
|
||||
countdownTimer.start()
|
||||
} else if (event == Lifecycle.Event.ON_STOP) {
|
||||
countdownTimer.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
|
||||
onDispose {
|
||||
lifecycleOwner.lifecycle.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
|
||||
return timeData
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.geode.geodelauncher.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
|
||||
|
||||
@Composable
|
||||
fun preferenceWatcher(@StringRes preferenceFileKey: Int, @StringRes preferenceId: Int, lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current): MutableState<Boolean> {
|
||||
val context = LocalContext.current
|
||||
val preferences = context.getSharedPreferences(
|
||||
context.getString(preferenceFileKey), Context.MODE_PRIVATE
|
||||
)
|
||||
|
||||
val preferenceValue = remember {
|
||||
mutableStateOf(
|
||||
preferences.getBoolean(
|
||||
context.getString(preferenceId),
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val listener = SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
sharedPreferences, key -> preferenceValue.value = sharedPreferences.getBoolean(key, false)
|
||||
}
|
||||
|
||||
DisposableEffect(lifecycleOwner) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_START) {
|
||||
preferences.registerOnSharedPreferenceChangeListener(listener)
|
||||
} else if (event == Lifecycle.Event.ON_DESTROY) {
|
||||
preferences.unregisterOnSharedPreferenceChangeListener(listener)
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
|
||||
onDispose {
|
||||
lifecycleOwner.lifecycle.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
|
||||
return preferenceValue
|
||||
}
|
||||
@@ -3,13 +3,17 @@
|
||||
<string name="title_activity_geometry_dash">GeometryDash</string>
|
||||
<string name="failed_mod_core">Failed to load mod core.</string>
|
||||
<string name="no_activity_found">No activity found for this action.</string>
|
||||
<plurals name="automatically_load_countdown">
|
||||
<item quantity="one">Automatically launching game in %1$d second.</item>
|
||||
<item quantity="other">Automatically launching game in %1$d seconds.</item>
|
||||
</plurals>
|
||||
<string name="preference_file_key">GeodeLauncherPreferencesFileKey</string>
|
||||
<string name="preference_category_testing">General</string>
|
||||
<string name="preference_load_testing">PreferenceLoadTesting</string>
|
||||
<string name="preference_load_testing_name">Load files from /test</string>
|
||||
<string name="preference_load_automatically">PreferenceLoadAutomatically</string>
|
||||
<string name="preference_load_automatically_name">Automatically launch</string>
|
||||
<string name="preference_load_automatically_description">Launches the game after a second-long delay.</string>
|
||||
<string name="preference_load_automatically_description">Launches the game after a short delay.</string>
|
||||
<string name="preferences_copy_external_button">Copy external files directory</string>
|
||||
<string name="title_activity_settings">SettingsActivity</string>
|
||||
</resources>
|
||||
Reference in new issue
Block a user