feat(IconOpts): old discord logo+color option
This commit is contained in:
parent
910be40d79
commit
3d282507ca
10 changed files with 100 additions and 24 deletions
|
|
@ -123,11 +123,30 @@ class PatchIconsStep(private val options: PatchOptions) : Step(), KoinComponent
|
|||
// Add a new color resource to use
|
||||
if (options.iconReplacement is IconReplacement.CustomColor) {
|
||||
container.log("Adding icon color resource to arsc")
|
||||
|
||||
backgroundIcon = arsc.getPackageChunk()
|
||||
.addColorResource("icon_background_replacement", options.iconReplacement.color)
|
||||
}
|
||||
|
||||
// Add a new color and axml svg resource
|
||||
else if (options.iconReplacement is IconReplacement.OldDiscord) {
|
||||
container.log("Adding icon color resource to arsc")
|
||||
backgroundIcon = arsc.getPackageChunk()
|
||||
.addColorResource("icon_background_replacement", IconReplacement.OldBlurpleColor)
|
||||
|
||||
container.log("Adding custom icon foreground to arsc")
|
||||
|
||||
val iconPathIdx = arsc.getMainArscChunk().stringPool
|
||||
.addString("res/ic_foreground_replacement.xml")
|
||||
|
||||
foregroundIcon = arsc.getPackageChunk().addResource(
|
||||
typeName = "drawable",
|
||||
resourceName = "ic_foreground_replacement",
|
||||
configurations = { println("configuration: $it"); true },
|
||||
valueType = BinaryResourceValue.Type.STRING,
|
||||
valueData = iconPathIdx,
|
||||
)
|
||||
}
|
||||
|
||||
// Add a new mipmap resource and the file to be added later
|
||||
else if (options.iconReplacement is IconReplacement.CustomImage) {
|
||||
container.log("Adding custom icon foreground to arsc")
|
||||
|
|
@ -162,14 +181,17 @@ class PatchIconsStep(private val options: PatchOptions) : Step(), KoinComponent
|
|||
it.writeEntry("res/ic_aliucord_monochrome.xml", context.getResBytes(R.drawable.ic_discord_monochrome))
|
||||
}
|
||||
|
||||
if (options.iconReplacement is IconReplacement.CustomImage) {
|
||||
if (options.iconReplacement is IconReplacement.OldDiscord) {
|
||||
container.log("Writing custom icon foreground to apk")
|
||||
it.writeEntry("res/ic_foreground_replacement.xml", context.getResBytes(R.drawable.ic_discord_old))
|
||||
} else if (options.iconReplacement is IconReplacement.CustomImage) {
|
||||
container.log("Writing custom icon foreground to apk")
|
||||
it.writeEntry("res/ic_foreground_replacement.png", options.iconReplacement.imageBytes)
|
||||
}
|
||||
|
||||
container.log("Writing resources unaligned compressed")
|
||||
it.deleteEntry("resources.arsc")
|
||||
// This doesn't need to be aligned and uncompressed here, since it that is done during AlignmentStep
|
||||
// This doesn't need to be aligned and uncompressed here, since that is done during AlignmentStep
|
||||
it.writeEntry("resources.arsc", arsc.toByteArray())
|
||||
}
|
||||
}
|
||||
|
|
@ -192,13 +214,17 @@ class PatchIconsStep(private val options: PatchOptions) : Step(), KoinComponent
|
|||
val allIconFiles = squareIconFiles + roundIconFiles
|
||||
|
||||
val backgroundColor = when (options.iconReplacement) {
|
||||
IconReplacement.Original -> IconReplacement.Aliucord.color
|
||||
IconReplacement.Original -> IconReplacement.AliucordColor
|
||||
IconReplacement.OldDiscord -> IconReplacement.OldBlurpleColor
|
||||
is IconReplacement.CustomColor -> options.iconReplacement.color
|
||||
is IconReplacement.CustomImage -> error("Cannot patch custom images below Android 8 (Adaptive Icons are required)")
|
||||
}
|
||||
|
||||
container.log("Generating static launcher icon")
|
||||
val icon = createDiscordLauncherIcon(backgroundColor)
|
||||
val icon = createDiscordLauncherIcon(
|
||||
backgroundColor = backgroundColor,
|
||||
oldLogo = options.iconReplacement == IconReplacement.OldDiscord,
|
||||
)
|
||||
val iconBytes = ByteArrayOutputStream().use {
|
||||
icon.compress(Bitmap.CompressFormat.PNG, 0, it)
|
||||
icon.recycle()
|
||||
|
|
@ -219,14 +245,24 @@ class PatchIconsStep(private val options: PatchOptions) : Step(), KoinComponent
|
|||
* to create a launcher icon like Discord's. This is used for devices that
|
||||
* do not support adaptive icons.
|
||||
*/
|
||||
private fun createDiscordLauncherIcon(backgroundColor: Color, size: Int = 192): Bitmap {
|
||||
private fun createDiscordLauncherIcon(
|
||||
backgroundColor: Color,
|
||||
oldLogo: Boolean = false,
|
||||
size: Int = 192,
|
||||
): Bitmap {
|
||||
val paint = Paint().apply {
|
||||
style = Paint.Style.FILL
|
||||
setColor(backgroundColor.toArgb())
|
||||
}
|
||||
|
||||
val vectorDrawable = ContextCompat.getDrawable(context, R.drawable.ic_discord)!!
|
||||
val drawable = InsetDrawable(vectorDrawable, (size * .17f).toInt())
|
||||
val drawableId = when (oldLogo) {
|
||||
false -> R.drawable.ic_discord
|
||||
true -> R.drawable.ic_discord_old
|
||||
}
|
||||
val vectorDrawable = ContextCompat.getDrawable(context, drawableId)!!
|
||||
val drawable = InsetDrawable(vectorDrawable, (size * .17f).toInt()).apply {
|
||||
setTint(Color.White.toArgb())
|
||||
}
|
||||
|
||||
val icon = createBitmap(size, size).applyCanvas {
|
||||
drawRect(Rect(0, 0, width, height), paint)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,9 @@ fun discordIconDrawable(
|
|||
InsetDrawable(
|
||||
/* drawable = */ ContextCompat.getDrawable(context, R.drawable.ic_discord)!!,
|
||||
/* inset = */ (size * .17f).toInt(),
|
||||
)
|
||||
).apply {
|
||||
setTint(Color.White.toArgb())
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(size) {
|
||||
|
|
|
|||
|
|
@ -60,12 +60,12 @@ private class IconOptionsParametersProvider : PreviewParameterProvider<IconOptio
|
|||
override val values = sequenceOf(
|
||||
IconOptionsParameters(
|
||||
mode = IconOptionsMode.Original,
|
||||
selectedColor = IconReplacement.Aliucord.color,
|
||||
selectedColor = IconReplacement.AliucordColor,
|
||||
selectedImage = { null },
|
||||
),
|
||||
IconOptionsParameters(
|
||||
mode = IconOptionsMode.Aliucord,
|
||||
selectedColor = IconReplacement.Aliucord.color,
|
||||
selectedColor = IconReplacement.AliucordColor,
|
||||
selectedImage = { null },
|
||||
),
|
||||
IconOptionsParameters(
|
||||
|
|
@ -89,7 +89,7 @@ private class IconOptionsParametersProvider : PreviewParameterProvider<IconOptio
|
|||
)
|
||||
|
||||
private fun getMipmapBytes(context: Context, @DrawableRes id: Int): ByteArray {
|
||||
val drawable = AppCompatResources.getDrawable(context, R.mipmap.ic_launcher)!!
|
||||
val drawable = AppCompatResources.getDrawable(context, id)!!
|
||||
val bitmap = drawable.toBitmap()
|
||||
return ByteArrayOutputStream().use {
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, it)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import androidx.compose.runtime.Immutable
|
|||
@Immutable
|
||||
enum class IconOptionsMode {
|
||||
Original,
|
||||
OldDiscord,
|
||||
Aliucord,
|
||||
CustomColor,
|
||||
CustomImage,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class IconOptionsModel(
|
|||
}
|
||||
|
||||
// ---------- Replacement color ---------- //
|
||||
var selectedColor by mutableStateOf(HsvColor(IconReplacement.Aliucord.color))
|
||||
var selectedColor by mutableStateOf(HsvColor(IconReplacement.AliucordColor))
|
||||
private set
|
||||
|
||||
fun changeSelectedColor(color: HsvColor) {
|
||||
|
|
@ -75,9 +75,9 @@ class IconOptionsModel(
|
|||
// ---------- Other ---------- //
|
||||
init {
|
||||
when (prefilledOptions) {
|
||||
is IconReplacement.CustomColor if prefilledOptions.color == IconReplacement.Aliucord.color -> {
|
||||
is IconReplacement.CustomColor if prefilledOptions.color == IconReplacement.AliucordColor -> {
|
||||
changeMode(IconOptionsMode.Aliucord)
|
||||
initSelectedColor(IconReplacement.Aliucord.color)
|
||||
initSelectedColor(IconReplacement.AliucordColor)
|
||||
}
|
||||
|
||||
is IconReplacement.CustomColor -> {
|
||||
|
|
@ -91,14 +91,17 @@ class IconOptionsModel(
|
|||
}
|
||||
|
||||
IconReplacement.Original -> changeMode(IconOptionsMode.Original)
|
||||
IconReplacement.OldDiscord -> changeMode(IconOptionsMode.OldDiscord)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateConfig(): IconReplacement = when (mode) {
|
||||
IconOptionsMode.Original -> IconReplacement.Original
|
||||
IconOptionsMode.Aliucord -> IconReplacement.Aliucord
|
||||
IconOptionsMode.OldDiscord -> IconReplacement.OldDiscord
|
||||
IconOptionsMode.Aliucord -> IconReplacement.CustomColor(IconReplacement.AliucordColor)
|
||||
IconOptionsMode.CustomColor -> IconReplacement.CustomColor(color = selectedColor.toColor())
|
||||
IconOptionsMode.CustomImage -> IconReplacement.CustomImage(
|
||||
// TODO: fix this?
|
||||
imageBytes = selectedImage ?: throw IllegalStateException("Cannot generate config without a selected image"),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,8 +96,9 @@ fun IconOptionsScreenContent(
|
|||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
val color = when (mode) {
|
||||
IconOptionsMode.Original -> PatchOptions.IconReplacement.Blurple.color // TODO: old vs new discord color?
|
||||
IconOptionsMode.Aliucord -> PatchOptions.IconReplacement.Aliucord.color
|
||||
IconOptionsMode.Original -> PatchOptions.IconReplacement.BlurpleColor
|
||||
IconOptionsMode.OldDiscord -> PatchOptions.IconReplacement.OldBlurpleColor
|
||||
IconOptionsMode.Aliucord -> PatchOptions.IconReplacement.AliucordColor
|
||||
IconOptionsMode.CustomColor -> selectedColor.toColor()
|
||||
IconOptionsMode.CustomImage -> Color.Black // TODO: custom image icon preview
|
||||
}
|
||||
|
|
@ -130,6 +131,12 @@ fun IconOptionsScreenContent(
|
|||
selected = mode == IconOptionsMode.Original,
|
||||
onClick = remember { { setMode(IconOptionsMode.Original) } },
|
||||
)
|
||||
RadioSelectorItem(
|
||||
name = stringResource(R.string.iconopts_variant_title_old_discord),
|
||||
description = stringResource(R.string.iconopts_variant_desc_old_discord),
|
||||
selected = mode == IconOptionsMode.OldDiscord,
|
||||
onClick = remember { { setMode(IconOptionsMode.OldDiscord) } },
|
||||
)
|
||||
RadioSelectorItem(
|
||||
name = stringResource(R.string.aliucord),
|
||||
description = stringResource(R.string.iconopts_variant_desc_aliucord),
|
||||
|
|
@ -202,6 +209,7 @@ private fun CustomColorOptions(
|
|||
saturation = color.saturation,
|
||||
value = color.value,
|
||||
onColorChange = { hue, saturation ->
|
||||
// FIXME: lightness slider resets when color wheel is used
|
||||
color.copy(hue = hue, saturation = saturation).let {
|
||||
setColor(it)
|
||||
initialRGBFieldColor = it.toColor()
|
||||
|
|
|
|||
|
|
@ -47,6 +47,16 @@ data class PatchOptions(
|
|||
@SerialName("original")
|
||||
data object Original : IconReplacement
|
||||
|
||||
/**
|
||||
* Changes the foreground logo to Discord's old logo and the
|
||||
* background color to old blurple, like prior to early 2021.
|
||||
*/
|
||||
@Immutable
|
||||
@Parcelize
|
||||
@Serializable
|
||||
@SerialName("old_discord")
|
||||
data object OldDiscord : IconReplacement
|
||||
|
||||
/**
|
||||
* Changes the background of the icon to a specific color without
|
||||
* altering the foreground or monochrome variants.
|
||||
|
|
@ -77,14 +87,19 @@ data class PatchOptions(
|
|||
|
||||
companion object {
|
||||
/**
|
||||
* The default icon replacement option.
|
||||
* The default Aliucord background color.
|
||||
*/
|
||||
val Aliucord = CustomColor(Color(0xFF00C853))
|
||||
val AliucordColor = Color(0xFF00C853)
|
||||
|
||||
/**
|
||||
* The new Discord blurple.
|
||||
* The new Discord blurple used in icons.
|
||||
*/
|
||||
val Blurple = CustomColor(Color(0xFF5865F2))
|
||||
val BlurpleColor = Color(0xFF5865F2)
|
||||
|
||||
/**
|
||||
* The old Discord icon color (before the accessibility redesign).
|
||||
*/
|
||||
val OldBlurpleColor = Color(0xFF7289DA)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +108,7 @@ data class PatchOptions(
|
|||
appName = "Aliucord",
|
||||
packageName = "com.aliucord",
|
||||
debuggable = false,
|
||||
iconReplacement = IconReplacement.Aliucord,
|
||||
iconReplacement = IconReplacement.CustomColor(IconReplacement.AliucordColor),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
android:viewportWidth="256"
|
||||
android:viewportHeight="256">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:fillColor="#5865F2"
|
||||
android:pathData="M216.86,45.1C200.29,37.34 182.57,31.71 164.04,28.5C161.77,32.61 159.11,38.15 157.28,42.55C137.58,39.58 118.07,39.58 98.74,42.55C96.91,38.15 94.19,32.61 91.9,28.5C73.35,31.71 55.61,37.36 39.04,45.14C5.62,95.65 -3.44,144.9 1.09,193.46C23.26,210.01 44.74,220.07 65.86,226.65C71.08,219.47 75.73,211.84 79.74,203.8C72.1,200.9 64.79,197.32 57.89,193.17C59.72,191.81 61.51,190.39 63.24,188.93C105.37,208.63 151.13,208.63 192.75,188.93C194.51,190.39 196.3,191.81 198.11,193.17C191.18,197.34 183.85,200.92 176.22,203.82C180.23,211.84 184.86,219.49 190.1,226.67C211.24,220.09 232.74,210.03 254.91,193.46C260.23,137.17 245.83,88.37 216.86,45.1ZM85.47,163.59C72.83,163.59 62.46,151.79 62.46,137.41C62.46,123.04 72.61,111.21 85.47,111.21C98.34,111.21 108.71,123.02 108.49,137.41C108.51,151.79 98.34,163.59 85.47,163.59ZM170.53,163.59C157.88,163.59 147.51,151.79 147.51,137.41C147.51,123.04 157.66,111.21 170.53,111.21C183.39,111.21 193.76,123.02 193.54,137.41C193.54,151.79 183.39,163.59 170.53,163.59Z" />
|
||||
</vector>
|
||||
|
|
|
|||
9
app/src/main/res/drawable/ic_discord_old.xml
Normal file
9
app/src/main/res/drawable/ic_discord_old.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="800"
|
||||
android:viewportHeight="800">
|
||||
<path
|
||||
android:fillColor="#6665D2"
|
||||
android:pathData="M701.3,185.8c-98,-73.4 -191.9,-71.3 -191.9,-71.3l-9.6,11c116.5,35 170.7,86.4 170.7,86.4c-166.7,-91.8 -379.1,-91.1 -552.5,0c0,0 56.2,-54.2 179.6,-89.1l-6.9,-8.2c0,0 -93.2,-2.1 -191.9,71.3C98.7,185.8 0,363.3 0,582c0,0 57.6,98.7 209.1,103.5c0,0 25.4,-30.2 45.9,-56.2c-87.1,-26 -120,-80.2 -120,-80.2c54.7,34.2 110,55.6 178.9,69.2c112.1,23.1 251.6,-0.7 355.8,-69.2c0,0 -34.3,55.5 -124.1,80.9c20.6,25.4 45.2,54.8 45.2,54.8C742.4,680 800,581.3 800,582C800,363.3 701.3,185.8 701.3,185.8zM272.1,518.3c-38.4,0 -69.9,-33.6 -69.9,-75.4c2.8,-100.1 137.7,-99.8 139.8,0C342.1,484.7 311.2,518.3 272.1,518.3zM522.4,518.3c-38.4,0 -69.9,-33.6 -69.9,-75.4c3.1,-99.9 136.3,-100 139.8,0C592.3,484.7 561.4,518.3 522.4,518.3z" />
|
||||
</vector>
|
||||
|
|
@ -171,6 +171,8 @@
|
|||
<string name="patchopts_divider_advanced">Advanced</string>
|
||||
|
||||
<string name="iconopts_screen_title">Icon Replacement</string>
|
||||
<string name="iconopts_variant_title_old_discord">Old Discord</string>
|
||||
<string name="iconopts_variant_desc_old_discord">The old Discord blurple color and logo from 2021 and prior.</string>
|
||||
<string name="iconopts_variant_title_color">Custom Color</string>
|
||||
<string name="iconopts_variant_title_image">Custom Image</string>
|
||||
<string name="iconopts_variant_desc_discord">Does not alter the original icon, instead only adding the missing monochrome icon to the APK.</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue