|
| 1 | +package io.trtc.tuikit.chat.demo |
| 2 | + |
| 3 | +import android.content.res.Configuration |
| 4 | +import android.graphics.Color |
| 5 | +import android.graphics.drawable.ColorDrawable |
| 6 | +import android.os.Bundle |
| 7 | +import androidx.activity.enableEdgeToEdge |
| 8 | +import androidx.appcompat.app.AppCompatActivity |
| 9 | +import androidx.core.view.WindowCompat |
| 10 | +import androidx.core.view.WindowInsetsControllerCompat |
| 11 | +import com.tencent.mmkv.MMKV |
| 12 | +import io.trtc.tuikit.atomicx.theme.Theme |
| 13 | +import io.trtc.tuikit.atomicx.theme.ThemeStore |
| 14 | +import io.trtc.tuikit.atomicx.theme.tokens.ColorTokens |
| 15 | +import kotlinx.coroutines.CoroutineScope |
| 16 | +import kotlinx.coroutines.Dispatchers |
| 17 | +import kotlinx.coroutines.SupervisorJob |
| 18 | +import kotlinx.coroutines.cancel |
| 19 | +import kotlinx.coroutines.flow.collectLatest |
| 20 | +import kotlinx.coroutines.launch |
| 21 | + |
| 22 | +abstract class BaseActivity : AppCompatActivity() { |
| 23 | + |
| 24 | + private val themeStore by lazy { ThemeStore.shared(this) } |
| 25 | + private var themeScope: CoroutineScope? = null |
| 26 | + |
| 27 | + override fun onCreate(savedInstanceState: Bundle?) { |
| 28 | + enableEdgeToEdge() |
| 29 | + super.onCreate(savedInstanceState) |
| 30 | + WindowCompat.setDecorFitsSystemWindows(window, false) |
| 31 | + window.statusBarColor = Color.TRANSPARENT |
| 32 | + window.navigationBarColor = Color.TRANSPARENT |
| 33 | + updateWindowAppearance(themeStore.themeState.value.currentTheme.tokens.color) |
| 34 | + } |
| 35 | + |
| 36 | + override fun onStart() { |
| 37 | + super.onStart() |
| 38 | + themeScope = CoroutineScope(Dispatchers.Main + SupervisorJob()) |
| 39 | + themeScope?.launch { |
| 40 | + themeStore.themeState.collectLatest { state -> |
| 41 | + updateWindowAppearance(state.currentTheme.tokens.color) |
| 42 | + } |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + override fun onStop() { |
| 47 | + super.onStop() |
| 48 | + themeScope?.cancel() |
| 49 | + themeScope = null |
| 50 | + } |
| 51 | + |
| 52 | + override fun onConfigurationChanged(newConfig: Configuration) { |
| 53 | + super.onConfigurationChanged(newConfig) |
| 54 | + val themeMode = MMKV.defaultMMKV().decodeInt( |
| 55 | + AppConstants.KEY_THEME_MODE, |
| 56 | + AppConstants.THEME_MODE_SYSTEM |
| 57 | + ) |
| 58 | + if (themeMode == AppConstants.THEME_MODE_SYSTEM) { |
| 59 | + val isNight = (newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK) == |
| 60 | + Configuration.UI_MODE_NIGHT_YES |
| 61 | + themeStore.setTheme( |
| 62 | + if (isNight) Theme.darkTheme(this) else Theme.lightTheme(this) |
| 63 | + ) |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + private fun updateWindowAppearance(colors: ColorTokens) { |
| 68 | + window.setBackgroundDrawable(ColorDrawable(colors.bgColorDefault)) |
| 69 | + val controller = WindowInsetsControllerCompat(window, window.decorView) |
| 70 | + val isLight = isColorLight(colors.bgColorOperate) |
| 71 | + controller.isAppearanceLightStatusBars = isLight |
| 72 | + controller.isAppearanceLightNavigationBars = isLight |
| 73 | + } |
| 74 | + |
| 75 | + private fun isColorLight(color: Int): Boolean { |
| 76 | + val r = (color shr 16) and 0xFF |
| 77 | + val g = (color shr 8) and 0xFF |
| 78 | + val b = color and 0xFF |
| 79 | + val luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255 |
| 80 | + return luminance > 0.5 |
| 81 | + } |
| 82 | +} |
0 commit comments