fix: display plugins + settings screens properly

This commit is contained in:
rushiiMachine 2024-01-24 12:29:50 -08:00
parent 9635e4aaee
commit f314283b8e
No known key found for this signature in database
GPG key ID: DCBE5952BB3B6420
5 changed files with 221 additions and 184 deletions

View file

@ -26,6 +26,8 @@ import com.aliucord.manager.ui.components.dialogs.InstallerDialog
import com.aliucord.manager.ui.components.home.InfoCard
import com.aliucord.manager.ui.screens.about.AboutScreen
import com.aliucord.manager.ui.screens.install.InstallScreen
import com.aliucord.manager.ui.screens.plugins.PluginsScreen
import com.aliucord.manager.ui.screens.settings.SettingsScreen
class HomeScreen : Screen {
override val key = "Home"
@ -51,8 +53,6 @@ class HomeScreen : Screen {
)
}
// TODO: add a way to open plugins and settings
Scaffold(
topBar = { HomeAppBar() },
) { paddingValues ->
@ -102,6 +102,20 @@ private fun HomeAppBar() {
contentDescription = stringResource(R.string.navigation_about)
)
}
IconButton(onClick = { navigator.push(PluginsScreen()) }) {
Icon(
painter = painterResource(R.drawable.ic_extension),
contentDescription = stringResource(R.string.navigation_about)
)
}
IconButton(onClick = { navigator.push(SettingsScreen()) }) {
Icon(
painter = painterResource(R.drawable.ic_settings),
contentDescription = stringResource(R.string.navigation_settings)
)
}
}
)
}

View file

@ -60,6 +60,7 @@ class InstallModel(
fun copyDebugToClipboard() {
val text = "$debugInfo\n\n$stacktrace"
// TODO: remove this useless replace
.replace("(\\\\*~_)".toRegex(), "\\$1")
application.copyToClipboard(text)

View file

@ -25,6 +25,7 @@ import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import com.aliucord.manager.R
import com.aliucord.manager.ui.components.BackButton
import com.aliucord.manager.ui.components.plugins.Changelog
import com.aliucord.manager.ui.components.plugins.PluginCard
@ -52,75 +53,85 @@ class PluginsScreen : Screen {
)
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp),
verticalArrangement = Arrangement.spacedBy(14.dp)
) {
PluginSearch(
currentFilter = model.search,
onFilterChange = model::search,
modifier = Modifier.fillMaxWidth(),
)
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(R.string.plugins_title)) },
navigationIcon = { BackButton() },
)
}
) { paddingValues ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.padding(horizontal = 16.dp),
verticalArrangement = Arrangement.spacedBy(14.dp)
) {
PluginSearch(
currentFilter = model.search,
onFilterChange = model::search,
modifier = Modifier.fillMaxWidth(),
)
if (model.error) {
Box(
modifier = Modifier.fillMaxSize()
) {
Column(
modifier = Modifier.align(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp),
if (model.error) {
Box(
modifier = Modifier.fillMaxSize()
) {
Icon(
imageVector = Icons.Default.Warning,
contentDescription = null,
tint = MaterialTheme.colorScheme.error,
)
Text(
text = stringResource(R.string.plugins_error),
color = MaterialTheme.colorScheme.error,
)
}
}
} else if (model.plugins.isNotEmpty()) {
LazyColumn(
contentPadding = PaddingValues(bottom = 15.dp, top = 6.dp),
verticalArrangement = Arrangement.spacedBy(14.dp)
) {
items(
// TODO: remember {} this
model.plugins.filter { plugin ->
plugin.manifest.run {
name.contains(model.search, true)
|| description.contains(model.search, true)
|| authors.any { (name) -> name.contains(model.search, true) }
}
Column(
modifier = Modifier.align(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
Icon(
imageVector = Icons.Default.Warning,
contentDescription = null,
tint = MaterialTheme.colorScheme.error,
)
Text(
text = stringResource(R.string.plugins_error),
color = MaterialTheme.colorScheme.error,
)
}
) { plugin ->
PluginCard(
plugin = plugin,
enabled = model.enabled[plugin.manifest.name] ?: true,
onClickDelete = { model.showUninstallDialog(plugin) },
onClickShowChangelog = { model.showChangelogDialog(plugin) },
onSetEnabled = { model.setPluginEnabled(plugin.manifest.name, it) }
)
}
}
} else {
Box(
modifier = Modifier.fillMaxSize()
) {
Column(
modifier = Modifier.align(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally
} else if (model.plugins.isNotEmpty()) {
LazyColumn(
contentPadding = PaddingValues(bottom = 15.dp, top = 6.dp),
verticalArrangement = Arrangement.spacedBy(14.dp)
) {
Icon(
painter = painterResource(R.drawable.ic_extension_off),
contentDescription = null
)
Text(stringResource(R.string.plugins_none_installed))
items(
// TODO: remember {} this
model.plugins.filter { plugin ->
plugin.manifest.run {
name.contains(model.search, true)
|| description.contains(model.search, true)
|| authors.any { (name) -> name.contains(model.search, true) }
}
}
) { plugin ->
PluginCard(
plugin = plugin,
enabled = model.enabled[plugin.manifest.name] ?: true,
onClickDelete = { model.showUninstallDialog(plugin) },
onClickShowChangelog = { model.showChangelogDialog(plugin) },
onSetEnabled = { model.setPluginEnabled(plugin.manifest.name, it) }
)
}
}
} else {
Box(
modifier = Modifier.fillMaxSize()
) {
Column(
modifier = Modifier.align(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
painter = painterResource(R.drawable.ic_extension_off),
contentDescription = null
)
Text(stringResource(R.string.plugins_none_installed))
}
}
}
}

View file

@ -20,6 +20,7 @@ import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import com.aliucord.manager.R
import com.aliucord.manager.ui.components.BackButton
import com.aliucord.manager.ui.components.Theme
import com.aliucord.manager.ui.components.settings.*
@ -30,126 +31,136 @@ class SettingsScreen : Screen {
override fun Content() {
val model = getScreenModel<SettingsModel>()
Column(
modifier = Modifier
.verticalScroll(state = rememberScrollState())
) {
val preferences = model.preferences
if (model.showThemeDialog) {
ThemeDialog(
currentTheme = preferences.theme,
onDismissRequest = model::hideThemeDialog,
onConfirm = model::setTheme
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(R.string.navigation_settings)) },
navigationIcon = { BackButton() },
)
}
SettingsHeader(stringResource(R.string.settings_appearance))
SettingsItem(
modifier = Modifier.clickable(onClick = model::showThemeDialog),
icon = { Icon(painterResource(R.drawable.ic_brush), null) },
text = { Text(stringResource(R.string.settings_theme)) }
) {
FilledTonalButton(onClick = model::showThemeDialog) {
Text(preferences.theme.toDisplayName())
}
}
SettingsSwitch(
label = stringResource(R.string.setting_dynamic_color),
pref = preferences.dynamicColor,
icon = { Icon(painterResource(R.drawable.ic_palette), null) }
) {
preferences.dynamicColor = it
}
SettingsHeader(stringResource(R.string.settings_advanced))
SettingsTextField(
label = stringResource(R.string.setting_app_name),
pref = preferences.appName,
onPrefChange = model::setAppName
)
Spacer(modifier = Modifier.height(4.dp))
SettingsSwitch(
label = stringResource(R.string.setting_replace_icon),
secondaryLabel = stringResource(R.string.setting_replace_icon_desc),
pref = preferences.replaceIcon,
icon = { Icon(painterResource(R.drawable.ic_app_shortcut), null) }
) {
preferences.replaceIcon = it
}
SettingsSwitch(
label = stringResource(R.string.setting_keep_patched_apks),
secondaryLabel = stringResource(R.string.setting_keep_patched_apks_desc),
icon = { Icon(painterResource(R.drawable.ic_delete_forever), null) },
pref = preferences.keepPatchedApks,
onPrefChange = { preferences.keepPatchedApks = it },
)
Spacer(modifier = Modifier.height(14.dp))
SettingsSwitch(
label = stringResource(R.string.settings_developer_options),
pref = preferences.devMode,
icon = { Icon(painterResource(R.drawable.ic_code), null) }
) {
preferences.devMode = it
}
AnimatedVisibility(
visible = preferences.devMode,
enter = expandVertically(),
exit = shrinkVertically()
) {
Column(
verticalArrangement = Arrangement.spacedBy(6.dp)
) {
SettingsTextField(
label = stringResource(R.string.setting_package_name),
pref = preferences.packageName,
onPrefChange = model::setPackageName,
error = model.packageNameError
)
SettingsTextField(
label = stringResource(R.string.setting_target_version),
pref = preferences.version,
onPrefChange = model::setVersion
)
SettingsSwitch(
label = stringResource(R.string.setting_debuggable),
secondaryLabel = stringResource(R.string.setting_debuggable_desc),
pref = preferences.debuggable,
icon = { Icon(painterResource(R.drawable.ic_bug), null) },
onPrefChange = { preferences.debuggable = it },
)
SettingsSwitch(
label = stringResource(R.string.setting_hermes_replace_libcpp),
secondaryLabel = stringResource(R.string.setting_hermes_replace_libcpp_desc),
icon = { Icon(painterResource(R.drawable.ic_copy_file), null) },
pref = preferences.hermesReplaceLibCpp,
onPrefChange = { preferences.hermesReplaceLibCpp = it },
)
}
}
Button(
},
) { paddingValues ->
Column(
modifier = Modifier
.fillMaxWidth()
.padding(18.dp),
shape = ShapeDefaults.Large,
onClick = model::clearCacheDir
.padding(paddingValues)
.verticalScroll(state = rememberScrollState())
) {
Text(
text = stringResource(R.string.setting_clear_cache),
textAlign = TextAlign.Center
val preferences = model.preferences
if (model.showThemeDialog) {
ThemeDialog(
currentTheme = preferences.theme,
onDismissRequest = model::hideThemeDialog,
onConfirm = model::setTheme
)
}
SettingsHeader(stringResource(R.string.settings_appearance))
SettingsItem(
modifier = Modifier.clickable(onClick = model::showThemeDialog),
icon = { Icon(painterResource(R.drawable.ic_brush), null) },
text = { Text(stringResource(R.string.settings_theme)) }
) {
FilledTonalButton(onClick = model::showThemeDialog) {
Text(preferences.theme.toDisplayName())
}
}
SettingsSwitch(
label = stringResource(R.string.setting_dynamic_color),
pref = preferences.dynamicColor,
icon = { Icon(painterResource(R.drawable.ic_palette), null) }
) {
preferences.dynamicColor = it
}
SettingsHeader(stringResource(R.string.settings_advanced))
SettingsTextField(
label = stringResource(R.string.setting_app_name),
pref = preferences.appName,
onPrefChange = model::setAppName
)
Spacer(modifier = Modifier.height(4.dp))
SettingsSwitch(
label = stringResource(R.string.setting_replace_icon),
secondaryLabel = stringResource(R.string.setting_replace_icon_desc),
pref = preferences.replaceIcon,
icon = { Icon(painterResource(R.drawable.ic_app_shortcut), null) }
) {
preferences.replaceIcon = it
}
SettingsSwitch(
label = stringResource(R.string.setting_keep_patched_apks),
secondaryLabel = stringResource(R.string.setting_keep_patched_apks_desc),
icon = { Icon(painterResource(R.drawable.ic_delete_forever), null) },
pref = preferences.keepPatchedApks,
onPrefChange = { preferences.keepPatchedApks = it },
)
Spacer(modifier = Modifier.height(14.dp))
SettingsSwitch(
label = stringResource(R.string.settings_developer_options),
pref = preferences.devMode,
icon = { Icon(painterResource(R.drawable.ic_code), null) }
) {
preferences.devMode = it
}
AnimatedVisibility(
visible = preferences.devMode,
enter = expandVertically(),
exit = shrinkVertically()
) {
Column(
verticalArrangement = Arrangement.spacedBy(6.dp)
) {
SettingsTextField(
label = stringResource(R.string.setting_package_name),
pref = preferences.packageName,
onPrefChange = model::setPackageName,
error = model.packageNameError
)
SettingsTextField(
label = stringResource(R.string.setting_target_version),
pref = preferences.version,
onPrefChange = model::setVersion
)
SettingsSwitch(
label = stringResource(R.string.setting_debuggable),
secondaryLabel = stringResource(R.string.setting_debuggable_desc),
pref = preferences.debuggable,
icon = { Icon(painterResource(R.drawable.ic_bug), null) },
onPrefChange = { preferences.debuggable = it },
)
SettingsSwitch(
label = stringResource(R.string.setting_hermes_replace_libcpp),
secondaryLabel = stringResource(R.string.setting_hermes_replace_libcpp_desc),
icon = { Icon(painterResource(R.drawable.ic_copy_file), null) },
pref = preferences.hermesReplaceLibCpp,
onPrefChange = { preferences.hermesReplaceLibCpp = it },
)
}
}
Button(
modifier = Modifier
.fillMaxWidth()
.padding(18.dp),
shape = ShapeDefaults.Large,
onClick = model::clearCacheDir
) {
Text(
text = stringResource(R.string.setting_clear_cache),
textAlign = TextAlign.Center
)
}
}
}
}

View file

@ -8,11 +8,11 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import com.aliucord.manager.R
import org.koin.androidx.compose.getViewModel
import org.koin.androidx.compose.koinViewModel
@Composable
fun UpdaterDialog(
viewModel: UpdaterViewModel = getViewModel(),
viewModel: UpdaterViewModel = koinViewModel(),
) {
if (!viewModel.showDialog) return