Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09fd13fc authored by Chaohui Wang's avatar Chaohui Wang
Browse files

[Spa] Add material color map

Bug: 419002002
Flag: EXEMPT bug fix
Test: visual - with gallery
Change-Id: I7fec8901c664662facbfbaa4677bcbc70559e84b
parent 1eb57933
Loading
Loading
Loading
Loading
+1 −44
Original line number Original line Diff line number Diff line
@@ -16,24 +16,15 @@


package com.android.settingslib.spa.widget.ui
package com.android.settingslib.spa.widget.ui


import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.colorResource
import com.airbnb.lottie.LottieProperty
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.animateLottieCompositionAsState
import com.airbnb.lottie.compose.animateLottieCompositionAsState
import com.airbnb.lottie.compose.rememberLottieComposition
import com.airbnb.lottie.compose.rememberLottieComposition
import com.airbnb.lottie.compose.rememberLottieDynamicProperties
import com.airbnb.lottie.compose.rememberLottieDynamicProperty
import com.android.settingslib.color.R


@Composable
@Composable
fun Lottie(resId: Int, modifier: Modifier = Modifier) {
fun Lottie(resId: Int, modifier: Modifier = Modifier) {
@@ -45,48 +36,14 @@ fun Lottie(spec: LottieCompositionSpec, modifier: Modifier = Modifier) {
    Box(modifier = modifier) { BaseLottie(spec) }
    Box(modifier = modifier) { BaseLottie(spec) }
}
}


object LottieColorUtils {
    private val DARK_TO_LIGHT_THEME_COLOR_MAP =
        mapOf(
            ".grey200" to R.color.settingslib_color_grey800,
            ".grey600" to R.color.settingslib_color_grey400,
            ".grey800" to R.color.settingslib_color_grey300,
            ".grey900" to R.color.settingslib_color_grey50,
            ".red400" to R.color.settingslib_color_red600,
            ".black" to android.R.color.white,
            ".blue400" to R.color.settingslib_color_blue600,
            ".green400" to R.color.settingslib_color_green600,
            ".green200" to R.color.settingslib_color_green500,
            ".red200" to R.color.settingslib_color_red500,
            ".cream" to R.color.settingslib_color_charcoal,
        )

    @Composable
    private fun getDefaultPropertiesList() =
        DARK_TO_LIGHT_THEME_COLOR_MAP.map { (key, colorRes) ->
            val color = colorResource(colorRes).toArgb()
            rememberLottieDynamicProperty(
                property = LottieProperty.COLOR_FILTER,
                keyPath = arrayOf("**", key, "**"),
            ) {
                PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP)
            }
        }

    @Composable
    fun getDefaultDynamicProperties() =
        rememberLottieDynamicProperties(*getDefaultPropertiesList().toTypedArray())
}

@Composable
@Composable
private fun BaseLottie(spec: LottieCompositionSpec) {
private fun BaseLottie(spec: LottieCompositionSpec) {
    val composition by rememberLottieComposition(spec)
    val composition by rememberLottieComposition(spec)
    val progress by
    val progress by
        animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)
        animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)
    val isLightMode = !isSystemInDarkTheme()
    LottieAnimation(
    LottieAnimation(
        composition = composition,
        composition = composition,
        dynamicProperties = LottieColorUtils.getDefaultDynamicProperties().takeIf { isLightMode },
        dynamicProperties = LottieColorUtils.getDefaultDynamicProperties(),
        progress = { progress },
        progress = { progress },
    )
    )
}
}
+125 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settingslib.spa.widget.ui

import android.graphics.ColorFilter
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.colorResource
import com.airbnb.lottie.LottieProperty
import com.airbnb.lottie.compose.LottieDynamicProperty
import com.airbnb.lottie.compose.rememberLottieDynamicProperties
import com.airbnb.lottie.compose.rememberLottieDynamicProperty
import com.android.settingslib.color.R

internal object LottieColorUtils {
    private val DARK_TO_LIGHT_THEME_COLOR_MAP =
        mapOf(
            ".grey200" to R.color.settingslib_color_grey800,
            ".grey600" to R.color.settingslib_color_grey400,
            ".grey800" to R.color.settingslib_color_grey300,
            ".grey900" to R.color.settingslib_color_grey50,
            ".red400" to R.color.settingslib_color_red600,
            ".black" to android.R.color.white,
            ".blue400" to R.color.settingslib_color_blue600,
            ".green400" to R.color.settingslib_color_green600,
            ".green200" to R.color.settingslib_color_green500,
            ".red200" to R.color.settingslib_color_red500,
            ".cream" to R.color.settingslib_color_charcoal,
        )

    @Composable
    private fun getMaterialColorMap(): Map<String, Color> =
        mapOf(
            ".primary" to MaterialTheme.colorScheme.primary,
            ".onPrimary" to MaterialTheme.colorScheme.onPrimary,
            ".primaryContainer" to MaterialTheme.colorScheme.primaryContainer,
            ".onPrimaryContainer" to MaterialTheme.colorScheme.onPrimaryContainer,
            ".primaryInverse" to MaterialTheme.colorScheme.inversePrimary,
            ".primaryFixed" to MaterialTheme.colorScheme.primaryFixed,
            ".primaryFixedDim" to MaterialTheme.colorScheme.primaryFixedDim,
            ".onPrimaryFixed" to MaterialTheme.colorScheme.onPrimaryFixed,
            ".onPrimaryFixedVariant" to MaterialTheme.colorScheme.onPrimaryFixedVariant,
            ".secondary" to MaterialTheme.colorScheme.secondary,
            ".onSecondary" to MaterialTheme.colorScheme.onSecondary,
            ".secondaryContainer" to MaterialTheme.colorScheme.secondaryContainer,
            ".onSecondaryContainer" to MaterialTheme.colorScheme.onSecondaryContainer,
            ".secondaryFixed" to MaterialTheme.colorScheme.secondaryFixed,
            ".secondaryFixedDim" to MaterialTheme.colorScheme.secondaryFixedDim,
            ".onSecondaryFixed" to MaterialTheme.colorScheme.onSecondaryFixed,
            ".onSecondaryFixedVariant" to MaterialTheme.colorScheme.onSecondaryFixedVariant,
            ".tertiary" to MaterialTheme.colorScheme.tertiary,
            ".onTertiary" to MaterialTheme.colorScheme.onTertiary,
            ".tertiaryContainer" to MaterialTheme.colorScheme.tertiaryContainer,
            ".onTertiaryContainer" to MaterialTheme.colorScheme.onTertiaryContainer,
            ".tertiaryFixed" to MaterialTheme.colorScheme.tertiaryFixed,
            ".tertiaryFixedDim" to MaterialTheme.colorScheme.tertiaryFixedDim,
            ".onTertiaryFixed" to MaterialTheme.colorScheme.onTertiaryFixed,
            ".onTertiaryFixedVariant" to MaterialTheme.colorScheme.onTertiaryFixedVariant,
            ".error" to MaterialTheme.colorScheme.error,
            ".onError" to MaterialTheme.colorScheme.onError,
            ".errorContainer" to MaterialTheme.colorScheme.errorContainer,
            ".onErrorContainer" to MaterialTheme.colorScheme.onErrorContainer,
            ".outline" to MaterialTheme.colorScheme.outline,
            ".outlineVariant" to MaterialTheme.colorScheme.outlineVariant,
            ".background" to MaterialTheme.colorScheme.background,
            ".onBackground" to MaterialTheme.colorScheme.onBackground,
            ".surface" to MaterialTheme.colorScheme.surface,
            ".onSurface" to MaterialTheme.colorScheme.onSurface,
            ".surfaceVariant" to MaterialTheme.colorScheme.surfaceVariant,
            ".onSurfaceVariant" to MaterialTheme.colorScheme.onSurfaceVariant,
            ".surfaceInverse" to MaterialTheme.colorScheme.inverseSurface,
            ".onSurfaceInverse" to MaterialTheme.colorScheme.inverseOnSurface,
            ".surfaceBright" to MaterialTheme.colorScheme.surfaceBright,
            ".surfaceDim" to MaterialTheme.colorScheme.surfaceDim,
            ".surfaceContainer" to MaterialTheme.colorScheme.surfaceContainer,
            ".surfaceContainerLow" to MaterialTheme.colorScheme.surfaceContainerLow,
            ".surfaceContainerLowest" to MaterialTheme.colorScheme.surfaceContainerLowest,
            ".surfaceContainerHigh" to MaterialTheme.colorScheme.surfaceContainerHigh,
            ".surfaceContainerHighest" to MaterialTheme.colorScheme.surfaceContainerHighest,
        )

    @Composable
    private fun getDefaultPropertiesList(): List<LottieDynamicProperty<ColorFilter>> = buildList {
        if (!isSystemInDarkTheme()) {
            for ((key, colorRes) in DARK_TO_LIGHT_THEME_COLOR_MAP) {
                add(createColorFilter(key, colorResource(colorRes)))
            }
        }
        for ((key, color) in getMaterialColorMap()) {
            add(createColorFilter(key, color))
        }
    }

    @Composable
    private fun createColorFilter(key: String, color: Color): LottieDynamicProperty<ColorFilter> =
        rememberLottieDynamicProperty(
            property = LottieProperty.COLOR_FILTER,
            keyPath = arrayOf("**", key, "**"),
        ) {
            PorterDuffColorFilter(color.toArgb(), PorterDuff.Mode.SRC_ATOP)
        }

    @Composable
    fun getDefaultDynamicProperties() =
        rememberLottieDynamicProperties(*getDefaultPropertiesList().toTypedArray())
}