Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-22 12:53:21 +03:00
parent 69c93a6503
commit 21ae76847b
2 changed files with 9 additions and 31 deletions

View file

@ -2,11 +2,9 @@ package com.tangem.core.ui.components.haze
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.tangem.core.ui.res.LocalHazeState import com.tangem.core.ui.res.LocalHazeState
import com.tangem.core.ui.res.LocalPowerSavingState
import com.tangem.core.ui.res.LocalRootBackgroundColor import com.tangem.core.ui.res.LocalRootBackgroundColor
import dev.chrisbanes.haze.* import dev.chrisbanes.haze.*
import dev.chrisbanes.haze.materials.CupertinoMaterials import dev.chrisbanes.haze.materials.CupertinoMaterials
@ -25,32 +23,19 @@ fun ProvideHaze(content: @Composable () -> Unit) {
} }
/** /**
* Returns whether the haze blur effect would actually render for the given [state], taking both * Applies a haze effect to the [Modifier] with consideration of global haze settings.
* the global [HazeState.blurEnabled] flag and the device's power-saving mode into account.
*
* Callers that pass a fully-transparent fallback to [hazeEffectTangem] should use this to decide
* whether they need to render an opaque fallback layer themselves otherwise the surface can
* become invisible whenever blur is disabled (e.g. while power-saving mode is on).
*/
@Composable
fun isHazeBlurEffectivelyEnabled(state: HazeState = LocalHazeState.current): Boolean {
val isPowerSavingEnabled by LocalPowerSavingState.current.isPowerSavingModeEnabled.collectAsState()
return state.blurEnabled && !isPowerSavingEnabled
}
/**
* Applies a haze effect to the [Modifier] with consideration of global haze settings and power saving mode.
* *
* @param configure A lambda to configure the [HazeEffectScope]. * @param configure A lambda to configure the [HazeEffectScope].
* @return A [Modifier] with the configured haze effect applied. * @return A [Modifier] with the configured haze effect applied.
*/ */
@OptIn(ExperimentalHazeMaterialsApi::class)
@Composable @Composable
fun Modifier.hazeEffectTangem( fun Modifier.hazeEffectTangem(
state: HazeState = LocalHazeState.current, state: HazeState = LocalHazeState.current,
style: HazeStyle = CupertinoMaterials.ultraThin(), style: HazeStyle = CupertinoMaterials.ultraThin(),
configure: HazeEffectScope.() -> Unit = {}, configure: HazeEffectScope.() -> Unit = {},
): Modifier { ): Modifier {
val isGlobalBlurEnabled = isHazeBlurEffectivelyEnabled(state) val isGlobalBlurEnabled = state.blurEnabled
val rootBackground by LocalRootBackgroundColor.current val rootBackground by LocalRootBackgroundColor.current
return hazeEffect(state, style) { return hazeEffect(state, style) {
@ -66,25 +51,19 @@ fun Modifier.hazeEffectTangem(
* *
* @param style The [HazeStyle] to apply. Defaults to [HazeStyle.Unspecified]. * @param style The [HazeStyle] to apply. Defaults to [HazeStyle.Unspecified].
* @param isBlurEnabled A Boolean indicating whether blur is enabled. Defaults to true. * @param isBlurEnabled A Boolean indicating whether blur is enabled. Defaults to true.
* @param reactToPowerSavingMode A Boolean indicating whether the haze effect should react to power saving mode.
* Defaults to false.
* @param configure A lambda to configure the [HazeEffectScope]. * @param configure A lambda to configure the [HazeEffectScope].
* @return A [Modifier] with the configured haze foreground effect applied. * @return A [Modifier] with the configured haze foreground effect applied.
*/ */
@Composable @Composable
fun Modifier.hazeForegroundEffectTangem( fun Modifier.hazeForegroundEffectTangem(
style: HazeStyle = HazeStyle.Unspecified, style: HazeStyle = HazeStyle.Unspecified,
reactToPowerSavingMode: Boolean = false,
isBlurEnabled: Boolean = true, isBlurEnabled: Boolean = true,
configure: HazeEffectScope.() -> Unit = {}, configure: HazeEffectScope.() -> Unit = {},
): Modifier { ): Modifier {
val powerSavingEnabled = LocalPowerSavingState.current.isPowerSavingModeEnabled.collectAsState()
val isGlobalBlurEnabled = isBlurEnabled && (!reactToPowerSavingMode || !powerSavingEnabled.value)
return hazeEffect( return hazeEffect(
style = style, style = style,
) { ) {
blurEnabled = isGlobalBlurEnabled blurEnabled = isBlurEnabled
configure() configure()
} }
} }

View file

@ -18,9 +18,9 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.haze.hazeEffectTangem import com.tangem.core.ui.components.haze.hazeEffectTangem
import com.tangem.core.ui.components.haze.isHazeBlurEffectivelyEnabled
import com.tangem.core.ui.extensions.conditionalCompose import com.tangem.core.ui.extensions.conditionalCompose
import com.tangem.core.ui.extensions.softLayerShadow import com.tangem.core.ui.extensions.softLayerShadow
import com.tangem.core.ui.res.LocalHazeState
import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemTheme
import dev.chrisbanes.haze.HazeStyle import dev.chrisbanes.haze.HazeStyle
import dev.chrisbanes.haze.HazeTint import dev.chrisbanes.haze.HazeTint
@ -134,14 +134,13 @@ private fun Modifier.materialBorder(shape: Shape): Modifier = border(
* When the haze state is enabled, paints a haze-blurred backdrop. When disabled, layers two * When the haze state is enabled, paints a haze-blurred backdrop. When disabled, layers two
* solid colors so the result still reads as "tinted fill" instead of going transparent. * solid colors so the result still reads as "tinted fill" instead of going transparent.
* *
* Uses [isHazeBlurEffectivelyEnabled] (rather than [LocalHazeState]'s `blurEnabled` directly) so * Reads [LocalHazeState]'s `blurEnabled` so the solid fallback is applied whenever blur is off
* the solid fallback is also applied when blur is suppressed for reasons other than the haze flag * otherwise the haze modifier's `fallbackTint = HazeTint(Color.Transparent)` would leave the
* most notably when the device is in power-saving mode. Otherwise the haze modifier's * surface fully transparent.
* `fallbackTint = HazeTint(Color.Transparent)` would leave the surface fully transparent.
*/ */
@Composable @Composable
private fun Modifier.materialFill(): Modifier { private fun Modifier.materialFill(): Modifier {
val isBlurEnabled = isHazeBlurEffectivelyEnabled() val isBlurEnabled = LocalHazeState.current.blurEnabled
val hazed = hazeEffectTangem( val hazed = hazeEffectTangem(
style = HazeStyle( style = HazeStyle(
backgroundColor = TangemTheme.colors3.material.fill.blur, backgroundColor = TangemTheme.colors3.material.fill.blur,