Skip to content

Commit ba94568

Browse files
feat: updating theme (#2956)
1 parent 107388f commit ba94568

File tree

77 files changed

+696
-235
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+696
-235
lines changed

cmp-android/src/main/kotlin/cmp/android/app/ComponentActivityExtensions.kt

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,25 @@
99
*/
1010
package cmp.android.app
1111

12-
import android.content.res.Configuration
13-
import android.graphics.Color
1412
import androidx.activity.ComponentActivity
1513
import androidx.activity.SystemBarStyle
1614
import androidx.activity.enableEdgeToEdge
1715
import androidx.annotation.ColorInt
1816
import androidx.appcompat.app.AppCompatDelegate
19-
import androidx.core.util.Consumer
17+
import androidx.compose.ui.graphics.Color
18+
import androidx.compose.ui.graphics.toArgb
2019
import androidx.lifecycle.Lifecycle
2120
import androidx.lifecycle.lifecycleScope
2221
import androidx.lifecycle.repeatOnLifecycle
23-
import kotlinx.coroutines.channels.awaitClose
22+
import cmp.android.app.util.isSystemInDarkModeFlow
2423
import kotlinx.coroutines.flow.Flow
25-
import kotlinx.coroutines.flow.callbackFlow
2624
import kotlinx.coroutines.flow.combine
27-
import kotlinx.coroutines.flow.conflate
2825
import kotlinx.coroutines.flow.distinctUntilChanged
2926
import kotlinx.coroutines.launch
30-
import org.mifos.mobile.core.model.DarkThemeConfig
27+
import org.mifos.mobile.core.model.MifosThemeConfig
3128

3229
@ColorInt
33-
private val SCRIM_COLOR: Int = Color.TRANSPARENT
30+
private val SCRIM_COLOR: Int = Color.Transparent.toArgb()
3431

3532
/**
3633
* Helper method to handle edge-to-edge logic for dark mode.
@@ -40,15 +37,26 @@ private val SCRIM_COLOR: Int = Color.TRANSPARENT
4037
*/
4138
@Suppress("MaxLineLength")
4239
fun ComponentActivity.setupEdgeToEdge(
43-
appThemeFlow: Flow<DarkThemeConfig>,
40+
appThemeFlow: Flow<MifosThemeConfig>,
4441
) {
4542
lifecycleScope.launch {
4643
lifecycle.repeatOnLifecycle(state = Lifecycle.State.STARTED) {
4744
combine(
4845
isSystemInDarkModeFlow(),
4946
appThemeFlow,
5047
) { isSystemDarkMode, appTheme ->
51-
AppCompatDelegate.setDefaultNightMode(appTheme.osValue)
48+
49+
val currentNightMode = AppCompatDelegate.getDefaultNightMode()
50+
if (currentNightMode != appTheme.osValue) {
51+
AppCompatDelegate.setDefaultNightMode(appTheme.osValue)
52+
}
53+
54+
when (appTheme.osValue) {
55+
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM -> isSystemDarkMode
56+
AppCompatDelegate.MODE_NIGHT_YES -> true
57+
AppCompatDelegate.MODE_NIGHT_NO -> false
58+
else -> isSystemDarkMode
59+
}
5260
}
5361
.distinctUntilChanged()
5462
.collect { isDarkMode ->
@@ -58,28 +66,10 @@ fun ComponentActivity.setupEdgeToEdge(
5866
val style = SystemBarStyle.auto(
5967
darkScrim = SCRIM_COLOR,
6068
lightScrim = SCRIM_COLOR,
61-
// Disabling Dark Mode for this app
62-
detectDarkMode = { false },
69+
detectDarkMode = { isDarkMode },
6370
)
6471
enableEdgeToEdge(statusBarStyle = style, navigationBarStyle = style)
6572
}
6673
}
6774
}
6875
}
69-
70-
/**
71-
* Adds a configuration change listener to retrieve whether system is in
72-
* dark theme or not. This will emit current status immediately and then
73-
* will emit changes as needed.
74-
*/
75-
private fun ComponentActivity.isSystemInDarkModeFlow(): Flow<Boolean> =
76-
callbackFlow {
77-
channel.trySend(element = resources.configuration.isSystemInDarkMode)
78-
val listener = Consumer<Configuration> {
79-
channel.trySend(element = it.isSystemInDarkMode)
80-
}
81-
addOnConfigurationChangedListener(listener = listener)
82-
awaitClose { removeOnConfigurationChangedListener(listener = listener) }
83-
}
84-
.distinctUntilChanged()
85-
.conflate()

cmp-android/src/main/kotlin/cmp/android/app/ConfigurationExtension.kt

Lines changed: 0 additions & 15 deletions
This file was deleted.

cmp-android/src/main/kotlin/cmp/android/app/MainActivity.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import androidx.core.view.WindowCompat
1919
import cmp.shared.SharedApp
2020
import io.github.vinceglb.filekit.FileKit
2121
import io.github.vinceglb.filekit.dialogs.init
22+
import kotlinx.coroutines.flow.first
23+
import kotlinx.coroutines.runBlocking
2224
import org.koin.android.ext.android.inject
2325
import org.mifos.mobile.core.datastore.UserPreferencesRepository
2426
import org.mifos.mobile.core.ui.utils.ShareUtils
@@ -42,6 +44,11 @@ class MainActivity : ComponentActivity() {
4244

4345
override fun onCreate(savedInstanceState: Bundle?) {
4446
super.onCreate(savedInstanceState)
47+
runBlocking {
48+
val userThemeConfig = userPreferencesRepository.observeDarkThemeConfig.first()
49+
AppCompatDelegate.setDefaultNightMode(userThemeConfig.osValue)
50+
}
51+
4552
var shouldShowSplashScreen = true
4653
installSplashScreen().setKeepOnScreenCondition { shouldShowSplashScreen }
4754

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*
8+
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
9+
*/
10+
package cmp.android.app.util
11+
12+
import android.content.res.Configuration
13+
import androidx.activity.ComponentActivity
14+
import androidx.core.util.Consumer
15+
import kotlinx.coroutines.channels.awaitClose
16+
import kotlinx.coroutines.flow.Flow
17+
import kotlinx.coroutines.flow.callbackFlow
18+
import kotlinx.coroutines.flow.conflate
19+
import kotlinx.coroutines.flow.distinctUntilChanged
20+
21+
/**
22+
* Convenience wrapper for dark mode checking
23+
*/
24+
val Configuration.isSystemInDarkTheme
25+
get() = (uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES
26+
27+
/**
28+
* Adds a configuration change listener to retrieve whether system is in
29+
* dark theme or not. This will emit current status immediately and then
30+
* will emit changes as needed.
31+
*/
32+
fun ComponentActivity.isSystemInDarkModeFlow(): Flow<Boolean> =
33+
callbackFlow {
34+
channel.trySend(element = resources.configuration.isSystemInDarkTheme)
35+
val listener = Consumer<Configuration> {
36+
channel.trySend(element = it.isSystemInDarkTheme)
37+
}
38+
addOnConfigurationChangedListener(listener = listener)
39+
awaitClose { removeOnConfigurationChangedListener(listener = listener) }
40+
}
41+
.distinctUntilChanged()
42+
.conflate()
-13.7 KB
Binary file not shown.
4.92 KB
Loading
-4.09 KB
Binary file not shown.
4.92 KB
Loading
-2.56 KB
Binary file not shown.
4.92 KB
Loading

0 commit comments

Comments
 (0)