diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 73f2a7a..f63b167 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -133,6 +133,7 @@ android { kotlin { sourceSets.all { languageSettings.enableLanguageFeature("ExplicitBackingFields") + languageSettings.enableLanguageFeature("WhenGuards") } } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsModel.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsModel.kt index d62590f..a260b4a 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsModel.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsModel.kt @@ -8,21 +8,56 @@ import com.aliucord.manager.ui.screens.patchopts.PatchOptions.IconReplacement class IconOptionsModel( prefilledOptions: IconReplacement, ) : ScreenModel { - var selectedColor by mutableStateOf(((prefilledOptions as? IconReplacement.CustomColor) ?: IconReplacement.Discord).color) + // ---------- Icon patching mode ---------- // + var mode by mutableStateOf(IconOptionsMode.Original) private set + fun changeMode(mode: IconOptionsMode) { + this.mode = mode + } + + // ---------- Replacement color ---------- // + var selectedColorValue by mutableLongStateOf(0) + val selectedColor: Color + inline get() = Color(selectedColorValue.toULong()) + fun changeSelectedColor(color: Color) { - this.selectedColor = color + selectedColorValue = color.value.toLong() } - fun generateConfig(): IconReplacement { - // TODO: other branches - return IconReplacement.CustomColor(color = selectedColor) + // ---------- Other ---------- // + init { + when (prefilledOptions) { + is IconReplacement.CustomColor if prefilledOptions.color == IconReplacement.Aliucord.color -> { + changeMode(IconOptionsMode.Aliucord) + changeSelectedColor(IconReplacement.Aliucord.color) + } + + is IconReplacement.CustomColor -> { + changeMode(IconOptionsMode.CustomColor) + changeSelectedColor(prefilledOptions.color) + } + + is IconReplacement.CustomImage -> { + changeMode(IconOptionsMode.CustomImage) + TODO() + } + + IconReplacement.Original -> changeMode(IconOptionsMode.Original) + } } - enum class Mode { - Original, - ReplaceColor, - ReplaceForeground, + fun generateConfig(): IconReplacement = when (mode) { + IconOptionsMode.Original -> IconReplacement.Original + IconOptionsMode.Aliucord -> IconReplacement.Aliucord + IconOptionsMode.CustomColor -> IconReplacement.CustomColor(color = selectedColor) + IconOptionsMode.CustomImage -> TODO() } } + +enum class IconOptionsMode { + Original, + Aliucord, + CustomColor, + CustomImage, +} diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsScreen.kt index 0152bb7..f03f53d 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsScreen.kt @@ -1,17 +1,23 @@ package com.aliucord.manager.ui.screens.iconopts import android.os.Parcelable +import androidx.compose.animation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.screen.Screen +import com.aliucord.manager.R import com.aliucord.manager.ui.screens.iconopts.components.IconOptionsAppBar +import com.aliucord.manager.ui.screens.iconopts.components.RadioSelectorItem import dev.zt64.compose.pipette.CircularColorPicker import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize @@ -37,6 +43,8 @@ class IconOptionsScreen( val model = parent.getIconModel() IconOptionsScreenContent( + mode = model.mode, + setMode = model::changeMode, selectedColor = model.selectedColor, setSelectedColor = model::changeSelectedColor, ) @@ -45,6 +53,8 @@ class IconOptionsScreen( @Composable fun IconOptionsScreenContent( + mode: IconOptionsMode, + setMode: (IconOptionsMode) -> Unit, selectedColor: Color, setSelectedColor: (Color) -> Unit, ) { @@ -60,11 +70,42 @@ fun IconOptionsScreenContent( .padding(paddingValues) .padding(horizontal = 20.dp, vertical = 20.dp) ) { - CircularColorPicker( - color = selectedColor, - onColorChange = setSelectedColor, - modifier = Modifier.size(250.dp) + // TODO: live icon preview + + HorizontalDivider(Modifier.padding(vertical = 16.dp)) + + RadioSelectorItem( + name = stringResource(R.string.discord), + description = stringResource(R.string.iconopts_variant_desc_discord), + selected = mode == IconOptionsMode.Original, + onClick = remember { { setMode(IconOptionsMode.Original) } }, ) + RadioSelectorItem( + name = stringResource(R.string.aliucord), + description = stringResource(R.string.iconopts_variant_desc_aliucord), + selected = mode == IconOptionsMode.Aliucord, + onClick = remember { { setMode(IconOptionsMode.Aliucord) } }, + ) + RadioSelectorItem( + name = stringResource(R.string.iconopts_variant_title_color), + description = stringResource(R.string.iconopts_variant_desc_color), + selected = mode == IconOptionsMode.CustomColor, + onClick = remember { { setMode(IconOptionsMode.CustomColor) } }, + ) + + HorizontalDivider(Modifier.padding(vertical = 16.dp)) + + AnimatedVisibility( + visible = mode == IconOptionsMode.CustomColor, + enter = fadeIn() + slideInVertically(), + exit = fadeOut() + slideOutVertically { -it / 10 }, + ) { + CircularColorPicker( + color = selectedColor, + onColorChange = setSelectedColor, + modifier = Modifier.size(230.dp), + ) + } } } } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/components/RadioSelectorItem.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/components/RadioSelectorItem.kt new file mode 100644 index 0000000..3896802 --- /dev/null +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/components/RadioSelectorItem.kt @@ -0,0 +1,48 @@ +package com.aliucord.manager.ui.screens.iconopts.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.material3.RadioButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.unit.dp +import com.aliucord.manager.ui.screens.patchopts.components.options.PatchOption + +@Composable +fun RadioSelectorItem( + name: String, + description: String, + selected: Boolean, + modifier: Modifier = Modifier.Companion, + onClick: () -> Unit, +) { + val interactionSource = remember(::MutableInteractionSource) + + Row( + horizontalArrangement = Arrangement.spacedBy(10.dp), + modifier = modifier + .fillMaxWidth() + .padding(end = 12.dp) + .clickable( + onClick = onClick, + interactionSource = interactionSource, + indication = null, + role = Role.Companion.Switch, + ), + ) { + RadioButton( + selected = selected, + onClick = onClick, + interactionSource = interactionSource, + ) + + PatchOption( + name = name, + description = description, + content = {}, + ) + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6dfaf1d..115dbca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -165,6 +165,10 @@ Advanced Icon Replacement + Custom Color + Does not alter the original icon, instead only adding the missing monochrome icon to the APK. + Changes the original icon color to Aliucord\'s branding. + Select a custom icon background color. Active installation Progress notifications sent during a minimized installation