wip: icon options screen basic setup
This commit is contained in:
parent
b329e1bad6
commit
9cd713ef70
12 changed files with 196 additions and 65 deletions
|
|
@ -160,6 +160,7 @@ dependencies {
|
|||
implementation(libs.microg)
|
||||
implementation(libs.smali)
|
||||
implementation(libs.baksmali)
|
||||
implementation(libs.compose.pipette)
|
||||
implementation(libs.compose.shimmer)
|
||||
implementation(variantOf(libs.zip) { artifactType("aar") })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.aliucord.manager.manager.PreferencesManager
|
|||
import com.aliucord.manager.ui.components.*
|
||||
import com.aliucord.manager.ui.components.dialogs.StoragePermissionsDialog
|
||||
import com.aliucord.manager.ui.screens.home.HomeScreen
|
||||
import com.aliucord.manager.ui.screens.iconopts.IconOptionsScreen
|
||||
import com.aliucord.manager.ui.screens.patching.PatchingScreen
|
||||
import com.aliucord.manager.ui.screens.patchopts.PatchOptionsScreen
|
||||
import com.aliucord.manager.ui.widgets.updater.UpdaterDialog
|
||||
|
|
@ -77,6 +78,12 @@ class MainActivity : ComponentActivity() {
|
|||
// Going from InstallOptions -> Install
|
||||
initialState is PatchOptionsScreen && targetState is PatchingScreen ->
|
||||
slideInHorizontally { it * 2 } + fadeIn togetherWith fadeOut
|
||||
// Going from PatchOptions -> IconOptions
|
||||
initialState is PatchOptionsScreen && targetState is IconOptionsScreen ->
|
||||
slideInHorizontally { it * 2 } + fadeIn togetherWith fadeOut
|
||||
// Going from IconOptions -> PatchOptions
|
||||
initialState is IconOptionsScreen && targetState is PatchOptionsScreen ->
|
||||
fadeIn togetherWith slideOutHorizontally { it * 2 } + fadeOut
|
||||
// Going from Install -> InstallOptions
|
||||
initialState is PatchingScreen && targetState is PatchOptionsScreen ->
|
||||
fadeIn togetherWith slideOutHorizontally { it * 2 } + fadeOut
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ private fun PatchOptionsScreenPreview(
|
|||
isDevMode = parameters.isDevMode,
|
||||
debuggable = parameters.debuggable,
|
||||
setDebuggable = {},
|
||||
replaceIcon = parameters.replaceIcon,
|
||||
setReplaceIcon = {},
|
||||
onOpenIconOptions = {},
|
||||
appName = parameters.appName,
|
||||
appNameIsError = parameters.appNameIsError,
|
||||
setAppName = {},
|
||||
|
|
@ -39,7 +38,6 @@ private data class PatchOptionsParameters(
|
|||
val isUpdate: Boolean,
|
||||
val isDevMode: Boolean,
|
||||
val debuggable: Boolean,
|
||||
val replaceIcon: Boolean,
|
||||
val appName: String,
|
||||
val appNameIsError: Boolean,
|
||||
val packageName: String,
|
||||
|
|
@ -54,7 +52,6 @@ private class PatchOptionsParametersProvider : PreviewParameterProvider<PatchOpt
|
|||
isUpdate = false,
|
||||
isDevMode = false,
|
||||
debuggable = false,
|
||||
replaceIcon = true,
|
||||
appName = PatchOptions.Default.appName,
|
||||
appNameIsError = false,
|
||||
packageName = PatchOptions.Default.packageName,
|
||||
|
|
@ -65,7 +62,6 @@ private class PatchOptionsParametersProvider : PreviewParameterProvider<PatchOpt
|
|||
isUpdate = true,
|
||||
isDevMode = false,
|
||||
debuggable = false,
|
||||
replaceIcon = true,
|
||||
appName = "an invalid app name.",
|
||||
appNameIsError = true,
|
||||
packageName = "a b",
|
||||
|
|
@ -76,7 +72,6 @@ private class PatchOptionsParametersProvider : PreviewParameterProvider<PatchOpt
|
|||
isUpdate = false,
|
||||
isDevMode = true,
|
||||
debuggable = true,
|
||||
replaceIcon = false,
|
||||
appName = PatchOptions.Default.appName,
|
||||
appNameIsError = false,
|
||||
packageName = PatchOptions.Default.packageName,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package com.aliucord.manager.ui.screens.iconopts
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import com.aliucord.manager.ui.screens.iconopts.components.IconOptionsAppBar
|
||||
import com.aliucord.manager.ui.screens.patchopts.PatchOptions.IconReplacement
|
||||
import dev.zt64.compose.pipette.CircularColorPicker
|
||||
|
||||
class IconOptionsScreen(
|
||||
private val prefilledOptions: IconReplacement,
|
||||
) : Screen {
|
||||
override val key = "IconOptions"
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
var (color, setColor) = remember { mutableStateOf(IconReplacement.Aliucord.color) }
|
||||
|
||||
IconOptionsScreenContent(
|
||||
selectedColor = color,
|
||||
setSelectedColor = setColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun IconOptionsScreenContent(
|
||||
selectedColor: Color,
|
||||
setSelectedColor: (Color) -> Unit,
|
||||
) {
|
||||
Scaffold(
|
||||
topBar = { IconOptionsAppBar() },
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(20.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(paddingValues)
|
||||
.padding(horizontal = 20.dp, vertical = 20.dp)
|
||||
) {
|
||||
CircularColorPicker(
|
||||
color = selectedColor,
|
||||
onColorChange = setSelectedColor,
|
||||
modifier = Modifier.size(250.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.aliucord.manager.ui.screens.iconopts.components
|
||||
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import com.aliucord.manager.R
|
||||
import com.aliucord.manager.ui.components.BackButton
|
||||
import com.aliucord.manager.ui.screens.settings.SettingsScreen
|
||||
|
||||
@Composable
|
||||
fun IconOptionsAppBar() {
|
||||
TopAppBar(
|
||||
navigationIcon = { BackButton() },
|
||||
title = { Text(stringResource(R.string.iconopts_screen_title)) },
|
||||
actions = {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
|
||||
IconButton(onClick = { navigator.push(SettingsScreen()) }) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_settings),
|
||||
contentDescription = stringResource(R.string.navigation_settings)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ class PatchingScreen(private val data: PatchOptions) : Screen, Parcelable {
|
|||
|
||||
val state by model.state.collectAsState()
|
||||
val listState = rememberLazyListState()
|
||||
val showMinimizationWarning = remember { !context.isIgnoringBatteryOptimizations() }
|
||||
val showMinimizationWarning = rememberSaveable { !context.isIgnoringBatteryOptimizations() }
|
||||
|
||||
// Exit warning dialog (dismiss itself if install process state changes, esp. for Success)
|
||||
var showAbortWarning by rememberSaveable(model.state.collectAsState().value) { mutableStateOf(false) }
|
||||
|
|
|
|||
|
|
@ -41,14 +41,6 @@ class PatchOptionsModel(
|
|||
appNameIsError = newAppName.length !in (1..150)
|
||||
}
|
||||
|
||||
// ---------- Icon patching state ----------
|
||||
var replaceIcon by mutableStateOf(prefilledOptions.iconReplacement == PatchOptions.IconReplacement.Aliucord)
|
||||
private set
|
||||
|
||||
fun changeReplaceIcon(value: Boolean) {
|
||||
replaceIcon = value
|
||||
}
|
||||
|
||||
// ---------- Debuggable state ----------
|
||||
var debuggable by mutableStateOf(prefilledOptions.debuggable)
|
||||
private set
|
||||
|
|
@ -75,7 +67,7 @@ class PatchOptionsModel(
|
|||
packageName = packageName,
|
||||
debuggable = debuggable,
|
||||
// TODO: advanced icon options
|
||||
iconReplacement = if (replaceIcon) PatchOptions.IconReplacement.Aliucord else PatchOptions.IconReplacement.Original,
|
||||
iconReplacement = PatchOptions.IconReplacement.Aliucord,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
package com.aliucord.manager.ui.screens.patchopts
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
|
|
@ -21,12 +23,13 @@ import com.aliucord.manager.R
|
|||
import com.aliucord.manager.ui.components.TextDivider
|
||||
import com.aliucord.manager.ui.components.dialogs.NetworkWarningDialog
|
||||
import com.aliucord.manager.ui.components.dialogs.UnknownSourcesPermissionDialog
|
||||
import com.aliucord.manager.ui.screens.iconopts.IconOptionsScreen
|
||||
import com.aliucord.manager.ui.screens.patching.PatchingScreen
|
||||
import com.aliucord.manager.ui.screens.patchopts.components.PackageNameStateLabel
|
||||
import com.aliucord.manager.ui.screens.patchopts.components.PatchOptionsAppBar
|
||||
import com.aliucord.manager.ui.screens.patchopts.components.options.SwitchPatchOption
|
||||
import com.aliucord.manager.ui.screens.patchopts.components.options.TextPatchOption
|
||||
import com.aliucord.manager.ui.util.*
|
||||
import com.aliucord.manager.ui.screens.patchopts.components.options.*
|
||||
import com.aliucord.manager.ui.util.InstallNotifications
|
||||
import com.aliucord.manager.ui.util.spacedByLastAtBottom
|
||||
import com.aliucord.manager.util.isIgnoringBatteryOptimizations
|
||||
import com.aliucord.manager.util.requestNoBatteryOptimizations
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
@ -58,7 +61,7 @@ class PatchOptionsScreen(
|
|||
context.requestNoBatteryOptimizations()
|
||||
}
|
||||
|
||||
var showNetworkWarningDialog by remember { mutableStateOf(model.isNetworkDangerous()) }
|
||||
var showNetworkWarningDialog by rememberSaveable { mutableStateOf(model.isNetworkDangerous()) }
|
||||
if (showNetworkWarningDialog) {
|
||||
NetworkWarningDialog(
|
||||
onConfirm = { showNetworkWarningDialog = false },
|
||||
|
|
@ -78,8 +81,8 @@ class PatchOptionsScreen(
|
|||
debuggable = model.debuggable,
|
||||
setDebuggable = model::changeDebuggable,
|
||||
|
||||
replaceIcon = model.replaceIcon,
|
||||
setReplaceIcon = model::changeReplaceIcon,
|
||||
// TODO: actual filled in options
|
||||
onOpenIconOptions = { navigator.push(IconOptionsScreen(PatchOptions.Default.iconReplacement)) },
|
||||
|
||||
appName = model.appName,
|
||||
appNameIsError = model.appNameIsError,
|
||||
|
|
@ -103,8 +106,7 @@ fun PatchOptionsScreenContent(
|
|||
debuggable: Boolean,
|
||||
setDebuggable: (Boolean) -> Unit,
|
||||
|
||||
replaceIcon: Boolean,
|
||||
setReplaceIcon: (Boolean) -> Unit,
|
||||
onOpenIconOptions: () -> Unit,
|
||||
|
||||
appName: String,
|
||||
appNameIsError: Boolean,
|
||||
|
|
@ -137,14 +139,29 @@ fun PatchOptionsScreenContent(
|
|||
|
||||
TextDivider(text = stringResource(R.string.patchopts_divider_basic))
|
||||
|
||||
SwitchPatchOption(
|
||||
IconPatchOption(
|
||||
icon = painterResource(R.drawable.ic_app_shortcut),
|
||||
name = stringResource(R.string.patchopts_icon_title),
|
||||
description = stringResource(R.string.patchopts_icon_desc),
|
||||
value = replaceIcon,
|
||||
onValueChange = setReplaceIcon,
|
||||
modifier = Modifier.padding(bottom = 8.dp)
|
||||
)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
interactionSource = remember(::MutableInteractionSource),
|
||||
onClick = onOpenIconOptions,
|
||||
indication = null,
|
||||
role = Role.Switch,
|
||||
)
|
||||
.padding(bottom = 8.dp),
|
||||
) {
|
||||
// TODO: selected icon options preview
|
||||
// Icon(
|
||||
// painter = painterResource(R.drawable.ic_discord),
|
||||
// contentDescription = null,
|
||||
// modifier = Modifier
|
||||
// .padding(start = 4.dp, end = 14.dp)
|
||||
// .size(26.dp),
|
||||
// )
|
||||
}
|
||||
|
||||
val appNameIsDefault by remember {
|
||||
derivedStateOf {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
package com.aliucord.manager.ui.screens.patchopts.components.options
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun IconPatchOption(
|
||||
icon: Painter,
|
||||
name: String,
|
||||
description: String,
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable RowScope.() -> Unit,
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = modifier,
|
||||
) {
|
||||
Icon(
|
||||
painter = icon,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(26.dp),
|
||||
)
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = name,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = description,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
modifier = Modifier
|
||||
.alpha(.7f)
|
||||
)
|
||||
}
|
||||
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,13 +2,12 @@ package com.aliucord.manager.ui.screens.patchopts.components.options
|
|||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -26,9 +25,10 @@ fun SwitchPatchOption(
|
|||
val interactionSource = remember(::MutableInteractionSource)
|
||||
val onClick = remember(value) { { onValueChange(!value) } }
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
IconPatchOption(
|
||||
icon = icon,
|
||||
name = name,
|
||||
description = description,
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
|
|
@ -39,29 +39,6 @@ fun SwitchPatchOption(
|
|||
role = Role.Switch,
|
||||
),
|
||||
) {
|
||||
Icon(
|
||||
painter = icon,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(26.dp),
|
||||
)
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = name,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = description,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
modifier = Modifier
|
||||
.alpha(.7f)
|
||||
)
|
||||
}
|
||||
|
||||
Switch(
|
||||
checked = value,
|
||||
enabled = enabled,
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
<string name="action_dismiss">Dismiss</string>
|
||||
<string name="action_install">Install</string>
|
||||
<string name="action_uninstall">Uninstall</string>
|
||||
<string name="action_add_install">New install</string>
|
||||
<string name="action_update_install">Update install</string>
|
||||
<string name="action_add_install">New Install</string>
|
||||
<string name="action_update_install">Update Install</string>
|
||||
<string name="action_update">Update</string>
|
||||
<string name="action_clear">Clear</string>
|
||||
<string name="action_launch">Launch</string>
|
||||
|
|
@ -160,10 +160,12 @@
|
|||
<string name="patchopts_debuggable_title">Debuggable</string>
|
||||
<string name="patchopts_debuggable_desc">Enable the debuggable manifest flag. Only use this if you know what you are doing!</string>
|
||||
<string name="patchopts_icon_title">Replace app icon</string>
|
||||
<string name="patchopts_icon_desc">Changes the app\'s icon to use Aliucord branding instead of Discord\'s own.</string>
|
||||
<string name="patchopts_icon_desc">Change the app\'s icon to Aliucord\'s icon (or a custom one) instead of Discord\'s.</string>
|
||||
<string name="patchopts_divider_basic">Basic</string>
|
||||
<string name="patchopts_divider_advanced">Advanced</string>
|
||||
|
||||
<string name="iconopts_screen_title">Icon Replacement</string>
|
||||
|
||||
<string name="notif_group_install_title">Active installation</string>
|
||||
<string name="notif_group_install_desc">Progress notifications sent during a minimized installation</string>
|
||||
<string name="notif_install_ready_title">Aliucord installation ready!</string>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ coil = "3.1.0"
|
|||
compose = "1.7.7"
|
||||
compose-tracing = "1.7.7"
|
||||
compose-material3 = "1.3.1"
|
||||
compose-pipette = "1.0.0-beta01"
|
||||
#diff = "4.12"
|
||||
koin = "4.0.2"
|
||||
kotlin = "2.1.10"
|
||||
|
|
@ -53,6 +54,10 @@ compose-material3 = { module = "androidx.compose.material3:material3", version.r
|
|||
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
|
||||
compose-runtime-tracing = { module = "androidx.compose.runtime:runtime-tracing", version.ref = "compose-tracing" }
|
||||
|
||||
# Extra compose libs
|
||||
compose-pipette = { module = "dev.zt64.compose.pipette:compose-pipette", version.ref = "compose-pipette" }
|
||||
compose-shimmer = { module = "com.valentinilk.shimmer:compose-shimmer", version.ref = "shimmer" }
|
||||
|
||||
# Koin
|
||||
koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" }
|
||||
koin-compose = { module = "io.insert-koin:koin-androidx-compose", version.ref = "koin" }
|
||||
|
|
@ -86,7 +91,6 @@ zip = { module = "io.github.diamondminer88:zip-android", version.ref = "zip" } #
|
|||
|
||||
# Other
|
||||
microg = { module = "org.microg.gms:play-services-safetynet", version.ref = "microg" }
|
||||
compose-shimmer = { module = "com.valentinilk.shimmer:compose-shimmer", version.ref = "shimmer" }
|
||||
|
||||
[bundles]
|
||||
accompanist = [
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue