mirror of
https://github.com/geode-sdk/android-launcher.git
synced 2026-10-26 09:19:21 +00:00
279 lines
12 KiB
Kotlin
279 lines
12 KiB
Kotlin
package com.geode.launcher.preferences
|
|
|
|
import android.content.ClipData
|
|
import android.content.ClipboardManager
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.os.Build
|
|
import android.os.Bundle
|
|
import android.widget.Toast
|
|
import androidx.activity.ComponentActivity
|
|
import androidx.activity.OnBackPressedDispatcher
|
|
import androidx.activity.compose.setContent
|
|
import androidx.activity.enableEdgeToEdge
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
import androidx.compose.foundation.layout.Column
|
|
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.rememberScrollState
|
|
import androidx.compose.foundation.verticalScroll
|
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.IconButton
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.Scaffold
|
|
import androidx.compose.material3.Surface
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.material3.TopAppBar
|
|
import androidx.compose.material3.TopAppBarDefaults
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.CompositionLocalProvider
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
|
import androidx.compose.ui.platform.LocalContext
|
|
import androidx.compose.ui.res.painterResource
|
|
import androidx.compose.ui.res.pluralStringResource
|
|
import androidx.compose.ui.res.stringResource
|
|
import androidx.compose.ui.text.style.TextOverflow
|
|
import androidx.compose.ui.unit.dp
|
|
import com.geode.launcher.R
|
|
import com.geode.launcher.preferences.components.OptionsButton
|
|
import com.geode.launcher.preferences.components.OptionsGroup
|
|
import com.geode.launcher.preferences.components.ProfileCreateCard
|
|
import com.geode.launcher.preferences.components.ProfileSelectCard
|
|
import com.geode.launcher.preferences.components.SettingsCard
|
|
import com.geode.launcher.preferences.components.SettingsSelectCard
|
|
import com.geode.launcher.preferences.components.SettingsStringCard
|
|
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.LaunchUtils
|
|
import com.geode.launcher.utils.PreferenceUtils
|
|
|
|
class DeveloperSettingsActivity : ComponentActivity() {
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
enableEdgeToEdge()
|
|
|
|
super.onCreate(savedInstanceState)
|
|
setContent {
|
|
val themeOption by PreferenceUtils.useIntPreference(PreferenceUtils.Key.THEME)
|
|
val theme = Theme.fromInt(themeOption)
|
|
|
|
val backgroundOption by PreferenceUtils.useBooleanPreference(PreferenceUtils.Key.BLACK_BACKGROUND)
|
|
val dynamicColorOption by PreferenceUtils.useBooleanPreference(PreferenceUtils.Key.DISABLE_USER_THEME)
|
|
|
|
CompositionLocalProvider(LocalTheme provides theme) {
|
|
GeodeLauncherTheme(theme = theme, blackBackground = backgroundOption, dynamicColor = !dynamicColorOption) {
|
|
Surface(
|
|
modifier = Modifier.fillMaxSize(),
|
|
color = MaterialTheme.colorScheme.background
|
|
) {
|
|
DeveloperSettingsScreen(onBackPressedDispatcher)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun onOpenFolder(context: Context) {
|
|
val file = LaunchUtils.getBaseDirectory(context)
|
|
val clipboardManager =
|
|
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
|
clipboardManager.setPrimaryClip(
|
|
ClipData.newPlainText(
|
|
context.getString(R.string.export_folder_tag),
|
|
file.path
|
|
)
|
|
)
|
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
|
Toast.makeText(
|
|
context,
|
|
context.getString(R.string.text_copied),
|
|
Toast.LENGTH_SHORT
|
|
).show()
|
|
}
|
|
}
|
|
|
|
fun onOpenLogs(context: Context) {
|
|
val launchIntent = Intent(context, ApplicationLogsActivity::class.java)
|
|
context.startActivity(launchIntent)
|
|
}
|
|
|
|
@OptIn(ExperimentalMaterial3Api::class)
|
|
@Composable
|
|
fun DeveloperSettingsScreen(onBackPressedDispatcher: OnBackPressedDispatcher?) {
|
|
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
|
|
|
|
Scaffold(
|
|
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
|
topBar = {
|
|
Column {
|
|
TopAppBar(
|
|
navigationIcon = {
|
|
IconButton(onClick = { onBackPressedDispatcher?.onBackPressed() }) {
|
|
Icon(
|
|
painterResource(R.drawable.icon_arrow_back),
|
|
contentDescription = stringResource(R.string.back_icon_alt)
|
|
)
|
|
}
|
|
},
|
|
title = {
|
|
Text(
|
|
stringResource(R.string.title_activity_developer_settings),
|
|
maxLines = 1,
|
|
overflow = TextOverflow.Ellipsis
|
|
)
|
|
},
|
|
scrollBehavior = scrollBehavior,
|
|
colors = TopAppBarDefaults.topAppBarColors(MaterialTheme.colorScheme.background),
|
|
)
|
|
}
|
|
}
|
|
) { innerPadding ->
|
|
Column(
|
|
Modifier
|
|
.padding(innerPadding)
|
|
.fillMaxWidth()
|
|
.verticalScroll(rememberScrollState()),
|
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
) {
|
|
|
|
val developerMode by PreferenceUtils.useBooleanPreference(PreferenceUtils.Key.DEVELOPER_MODE)
|
|
|
|
OptionsGroup {
|
|
SettingsCard(
|
|
title = stringResource(R.string.preference_developer_mode),
|
|
preferenceKey = PreferenceUtils.Key.DEVELOPER_MODE,
|
|
)
|
|
}
|
|
|
|
if (developerMode) {
|
|
OptionsGroup(title = stringResource(R.string.preference_category_gameplay)) {
|
|
SettingsStringCard(
|
|
title = stringResource(R.string.preference_launch_arguments_name),
|
|
dialogTitle = stringResource(R.string.preference_launch_arguments_set_title),
|
|
preferenceKey = PreferenceUtils.Key.LAUNCH_ARGUMENTS,
|
|
filterInput = {
|
|
it.filter { c ->
|
|
// if only there was a better way to define this!
|
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}<>[]?:;'\"~`-_+=\\| ".contains(
|
|
c
|
|
)
|
|
}
|
|
}
|
|
)
|
|
|
|
SettingsCard(
|
|
title = stringResource(R.string.preference_native_pacing),
|
|
description = stringResource(R.string.preference_native_pacing_description),
|
|
preferenceKey = PreferenceUtils.Key.NATIVE_FRAME_PACING,
|
|
)
|
|
|
|
/*
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
SettingsCard(
|
|
title = stringResource(R.string.preference_force_hrr),
|
|
preferenceKey = PreferenceUtils.Key.FORCE_HRR,
|
|
)
|
|
}
|
|
|
|
SettingsCard(
|
|
title = stringResource(R.string.preference_override_exceptions_name),
|
|
description = stringResource(R.string.preference_override_exceptions_description),
|
|
preferenceKey = PreferenceUtils.Key.CUSTOM_SYMBOL_LIST
|
|
)
|
|
*/
|
|
}
|
|
|
|
OptionsGroup(stringResource(R.string.preference_category_developer)) {
|
|
val context = LocalContext.current
|
|
OptionsButton(
|
|
title = stringResource(R.string.preferences_view_logs),
|
|
icon = {
|
|
Icon(
|
|
painterResource(R.drawable.icon_mobile_code),
|
|
contentDescription = null
|
|
)
|
|
},
|
|
onClick = { onOpenLogs(context) }
|
|
)
|
|
|
|
OptionsButton(
|
|
title = stringResource(R.string.preferences_copy_external_button),
|
|
description = LaunchUtils.getBaseDirectory(context).path,
|
|
onClick = { onOpenFolder(context) }
|
|
)
|
|
}
|
|
|
|
OptionsGroup(title = stringResource(R.string.preference_category_updater)) {
|
|
val context = LocalContext.current
|
|
|
|
SettingsSelectCard(
|
|
title = stringResource(R.string.preference_release_channel_tag_name),
|
|
dialogTitle = stringResource(R.string.preference_release_channel_select),
|
|
preferenceKey = PreferenceUtils.Key.RELEASE_CHANNEL_TAG,
|
|
options = linkedMapOf(
|
|
0 to stringResource(R.string.preference_release_channel_stable),
|
|
1 to stringResource(R.string.preference_release_channel_beta),
|
|
2 to stringResource(R.string.preference_release_channel_nightly),
|
|
),
|
|
extraSelectBehavior = {
|
|
PreferenceUtils.get(context)
|
|
.setLong(PreferenceUtils.Key.LAST_UPDATE_CHECK_TIME, 0L)
|
|
}
|
|
)
|
|
|
|
SettingsCard(
|
|
title = stringResource(R.string.preference_disable_update_cache),
|
|
preferenceKey = PreferenceUtils.Key.DISABLE_UPDATE_CACHE
|
|
)
|
|
}
|
|
|
|
OptionsGroup(title = stringResource(R.string.preference_category_testing)) {
|
|
SettingsSelectCard(
|
|
title = stringResource(R.string.preference_launch_delay),
|
|
dialogTitle = stringResource(R.string.preference_launch_delay_select),
|
|
preferenceKey = PreferenceUtils.Key.WAIT_PERIOD,
|
|
options = linkedMapOf(
|
|
0 to stringResource(R.string.preference_launch_delay_instant),
|
|
1 to pluralStringResource(
|
|
R.plurals.preference_launch_delay_value,
|
|
1,
|
|
1
|
|
),
|
|
3 to pluralStringResource(
|
|
R.plurals.preference_launch_delay_value,
|
|
3,
|
|
3
|
|
),
|
|
5 to pluralStringResource(
|
|
R.plurals.preference_launch_delay_value,
|
|
5,
|
|
5
|
|
),
|
|
)
|
|
)
|
|
|
|
/*
|
|
SettingsCard(
|
|
title = stringResource(R.string.preference_disable_redesign),
|
|
preferenceKey = PreferenceUtils.Key.DISABLE_REDESIGN,
|
|
)
|
|
*/
|
|
}
|
|
|
|
OptionsGroup(title = stringResource(R.string.preference_profiles)) {
|
|
ProfileCreateCard()
|
|
ProfileSelectCard()
|
|
}
|
|
}
|
|
|
|
Spacer(Modifier.height(4.dp))
|
|
}
|
|
}
|
|
} |