Skip to content

Commit 9010d5c

Browse files
committed
ui: support Monet app icon background
1 parent 0556078 commit 9010d5c

30 files changed

Lines changed: 176 additions & 10 deletions

app/src/main/AndroidManifest.xml

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@
2929
android:name=".MainActivity"
3030
android:exported="true"
3131
android:launchMode="singleTop">
32-
<intent-filter>
33-
<action android:name="android.intent.action.MAIN" />
34-
<category android:name="android.intent.category.LAUNCHER" />
35-
</intent-filter>
3632
<intent-filter>
3733
<action android:name="android.intent.action.VIEW" />
3834

@@ -72,6 +68,34 @@
7268
</intent-filter>
7369
</activity>
7470

71+
<activity-alias
72+
android:name=".DefaultLauncherActivity"
73+
android:enabled="true"
74+
android:exported="true"
75+
android:icon="@mipmap/ic_launcher"
76+
android:label="@string/app_name"
77+
android:roundIcon="@mipmap/ic_launcher_round"
78+
android:targetActivity=".MainActivity">
79+
<intent-filter>
80+
<action android:name="android.intent.action.MAIN" />
81+
<category android:name="android.intent.category.LAUNCHER" />
82+
</intent-filter>
83+
</activity-alias>
84+
85+
<activity-alias
86+
android:name=".MonetLauncherActivity"
87+
android:enabled="false"
88+
android:exported="true"
89+
android:icon="@mipmap/ic_launcher_monet"
90+
android:label="@string/app_name"
91+
android:roundIcon="@mipmap/ic_launcher_monet_round"
92+
android:targetActivity=".MainActivity">
93+
<intent-filter>
94+
<action android:name="android.intent.action.MAIN" />
95+
<category android:name="android.intent.category.LAUNCHER" />
96+
</intent-filter>
97+
</activity-alias>
98+
7599
<activity-alias
76100
android:name="features.quicksettings.ProxyQuickSettingsHomeActivity"
77101
android:exported="true"

app/src/main/kotlin/app/App.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import androidx.compose.runtime.remember
1313
import androidx.compose.ui.platform.LocalContext
1414
import androidx.compose.ui.unit.dp
1515
import app.effects.ProxyStatusSynchronizer
16+
import app.effects.LauncherIconSynchronizer
1617
import app.effects.ResourceFileSynchronizer
1718
import app.effects.SubscriptionAutoUpdater
1819
import app.effects.RootBootScriptSynchronizer
@@ -163,6 +164,10 @@ fun App(
163164
ResourceFileSynchronizer(
164165
resourceFileUseCase = resourceFileUseCase,
165166
)
167+
LauncherIconSynchronizer(
168+
context = appContext,
169+
stateStore = stateStore,
170+
)
166171
SubscriptionAutoUpdater(
167172
stateStore = stateStore,
168173
subscriptionFetcher = subscriptionFetcher,
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright 2026, AsteriskNG contributors
2+
// SPDX-License-Identifier: GPL-3.0
3+
4+
package app.effects
5+
6+
import android.content.ComponentName
7+
import android.content.Context
8+
import android.content.pm.PackageManager
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.runtime.LaunchedEffect
11+
import app.AppState
12+
import app.MainActivity
13+
import app.modes.ColorModeThemeDark
14+
import app.modes.ColorModeThemeSystem
15+
import data.AndroidAppStateStore
16+
import features.logs.AndroidAppLogger
17+
import kotlinx.coroutines.Dispatchers
18+
import kotlinx.coroutines.flow.distinctUntilChanged
19+
import kotlinx.coroutines.flow.map
20+
import kotlinx.coroutines.withContext
21+
22+
@Composable
23+
internal fun LauncherIconSynchronizer(
24+
context: Context,
25+
stateStore: AndroidAppStateStore,
26+
) {
27+
val appContext = context.applicationContext
28+
LaunchedEffect(appContext, stateStore) {
29+
stateStore.state
30+
.map { state -> state.usesMonetLauncherIcon }
31+
.distinctUntilChanged()
32+
.collect { useMonetIcon ->
33+
runCatching {
34+
withContext(Dispatchers.IO) {
35+
appContext.setLauncherIcon(useMonetIcon)
36+
}
37+
}.onFailure { error ->
38+
AndroidAppLogger.warn(
39+
LogTag,
40+
"Failed to synchronize launcher icon",
41+
error,
42+
)
43+
}
44+
}
45+
}
46+
}
47+
48+
private val AppState.usesMonetLauncherIcon: Boolean
49+
get() = colorMode in ColorModeThemeSystem..ColorModeThemeDark
50+
51+
private fun Context.setLauncherIcon(useMonetIcon: Boolean) {
52+
val packageManager = packageManager
53+
val launcherPackageName = MainActivity::class.java.name.substringBeforeLast('.')
54+
val defaultLauncher = ComponentName(packageName, "$launcherPackageName.DefaultLauncherActivity")
55+
val monetLauncher = ComponentName(packageName, "$launcherPackageName.MonetLauncherActivity")
56+
val enabledLauncher = if (useMonetIcon) monetLauncher else defaultLauncher
57+
val disabledLauncher = if (useMonetIcon) defaultLauncher else monetLauncher
58+
59+
packageManager.setComponentEnabledSetting(
60+
enabledLauncher,
61+
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
62+
PackageManager.DONT_KILL_APP,
63+
)
64+
packageManager.setComponentEnabledSetting(
65+
disabledLauncher,
66+
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
67+
PackageManager.DONT_KILL_APP,
68+
)
69+
}
70+
71+
private const val LogTag = "LauncherIconSync"

app/src/main/kotlin/features/about/AboutComponents.kt

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ import androidx.compose.ui.Alignment
1919
import androidx.compose.ui.Modifier
2020
import androidx.compose.ui.draw.clip
2121
import androidx.compose.ui.draw.scale
22+
import androidx.compose.ui.graphics.Color
23+
import androidx.compose.ui.graphics.ColorFilter
2224
import androidx.compose.ui.layout.ContentScale
2325
import androidx.compose.ui.platform.LocalUriHandler
24-
import androidx.compose.ui.res.colorResource
2526
import androidx.compose.ui.unit.dp
27+
import app.LocalAppChromeState
2628
import app.R
2729
import app.ProjectInfo
30+
import app.modes.ColorModeThemeDark
31+
import app.modes.ColorModeThemeSystem
2832
import androidx.compose.ui.res.painterResource
2933
import androidx.compose.ui.res.stringResource
3034
import top.yukonga.miuix.kmp.basic.BasicComponent
@@ -67,24 +71,49 @@ internal fun AboutHeader(
6771
private fun AboutAppIcon(
6872
modifier: Modifier = Modifier,
6973
) {
74+
val iconStyle = aboutIconStyle()
75+
7076
Box(
7177
modifier = modifier
7278
.size(88.dp)
7379
.clip(RoundedCornerShape(22.dp))
74-
.background(colorResource(R.color.ic_launcher_background)),
80+
.background(MiuixTheme.colorScheme.surface),
7581
contentAlignment = Alignment.Center,
7682
) {
7783
Image(
78-
painter = painterResource(R.mipmap.ic_launcher_foreground),
84+
painter = painterResource(iconStyle.foregroundResId),
7985
contentDescription = ProjectInfo.PROJECT_NAME,
8086
contentScale = ContentScale.Fit,
87+
colorFilter = iconStyle.foregroundTint?.let { tint -> ColorFilter.tint(tint) },
8188
modifier = Modifier
8289
.fillMaxSize()
8390
.scale(AboutIconForegroundScale),
8491
)
8592
}
8693
}
8794

95+
@Composable
96+
private fun aboutIconStyle(): AboutIconStyle {
97+
val chromeState = LocalAppChromeState.current
98+
val isMonetMode = chromeState.colorMode in ColorModeThemeSystem..ColorModeThemeDark
99+
if (!isMonetMode) {
100+
return AboutIconStyle(
101+
foregroundResId = R.mipmap.ic_launcher_foreground,
102+
foregroundTint = null,
103+
)
104+
}
105+
106+
return AboutIconStyle(
107+
foregroundResId = R.mipmap.ic_launcher_monet_monochrome,
108+
foregroundTint = MiuixTheme.colorScheme.primary,
109+
)
110+
}
111+
112+
private data class AboutIconStyle(
113+
val foregroundResId: Int,
114+
val foregroundTint: Color?,
115+
)
116+
88117
@Composable
89118
internal fun AboutRuntimeCard(
90119
modifier: Modifier = Modifier,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:gravity="center"
4+
android:src="@mipmap/ic_launcher_monet_monochrome"
5+
android:tint="@color/ic_launcher_monet_foreground" />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3+
<background android:drawable="@color/ic_launcher_monet_background" />
4+
<foreground android:drawable="@drawable/ic_launcher_monet_foreground" />
5+
<monochrome android:drawable="@mipmap/ic_launcher_monet_monochrome" />
6+
</adaptive-icon>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3+
<background android:drawable="@color/ic_launcher_monet_background" />
4+
<foreground android:drawable="@drawable/ic_launcher_monet_foreground" />
5+
<monochrome android:drawable="@mipmap/ic_launcher_monet_monochrome" />
6+
</adaptive-icon>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3+
<background android:drawable="@color/ic_launcher_monet_background" />
4+
<foreground android:drawable="@drawable/ic_launcher_monet_foreground" />
5+
<monochrome android:drawable="@mipmap/ic_launcher_monet_monochrome" />
6+
</adaptive-icon>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3+
<background android:drawable="@color/ic_launcher_monet_background" />
4+
<foreground android:drawable="@drawable/ic_launcher_monet_foreground" />
5+
<monochrome android:drawable="@mipmap/ic_launcher_monet_monochrome" />
6+
</adaptive-icon>
6.81 KB
Loading

0 commit comments

Comments
 (0)