From e2f1350f759793c6ced49016044e705006aa574f Mon Sep 17 00:00:00 2001 From: KhooLy <73142442+KhooLy@users.noreply.github.com> Date: Sun, 19 Jul 2026 19:07:58 +0300 Subject: [PATCH] Use real backdrop blur for Liquid Glass mode via Haze Pulls in dev.chrisbanes.haze 1.7.2 (Android + iOS klibs, matching the shared module's targets) and swaps the earlier translucency-only fallback for genuine hardware-accelerated background blur: the screen content is marked as a hazeSource, and the nav bar reads it through hazeEffect with a tinted, noisy glass style. --- gradle/libs.versions.toml | 4 +++ shared/build.gradle.kts | 1 + .../kotlin/com/fluxa/app/shared/FluxaApp.kt | 34 +++++++++++++------ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f615157..26e6d79 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,6 +25,7 @@ okhttp = "5.4.0" cronetEmbedded = "143.7445.0" cronetOkhttp = "0.1.1" coil3 = "3.4.0" +haze = "1.7.2" room = "2.8.4" jna = "5.17.0" cloudstream = "v4.7.0" @@ -118,6 +119,9 @@ coil3-network-okhttp= { group = "io.coil-kt.coil3", name = "coil-network-okhttp" coil3-svg = { group = "io.coil-kt.coil3", name = "coil-svg", version.ref = "coil3" } coil3-gif = { group = "io.coil-kt.coil3", name = "coil-gif", version.ref = "coil3" } +# Haze +haze = { group = "dev.chrisbanes.haze", name = "haze", version.ref = "haze" } + cloudstream = { group = "com.github.recloudstream.cloudstream",name = "library", version.ref = "cloudstream" } # JNA (UniFFI) diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 913de7a..8b08379 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -32,6 +32,7 @@ kotlin { implementation(libs.kotlinx.serialization.json) implementation(libs.coil3) implementation(libs.coil3.compose) + implementation(libs.haze) } androidMain.dependencies { implementation(libs.coil3.network.okhttp) diff --git a/shared/src/commonMain/kotlin/com/fluxa/app/shared/FluxaApp.kt b/shared/src/commonMain/kotlin/com/fluxa/app/shared/FluxaApp.kt index 96a491a..169151f 100644 --- a/shared/src/commonMain/kotlin/com/fluxa/app/shared/FluxaApp.kt +++ b/shared/src/commonMain/kotlin/com/fluxa/app/shared/FluxaApp.kt @@ -67,6 +67,11 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import dev.chrisbanes.haze.HazeDefaults +import dev.chrisbanes.haze.HazeTint +import dev.chrisbanes.haze.hazeEffect +import dev.chrisbanes.haze.hazeSource +import dev.chrisbanes.haze.rememberHazeState import kotlinx.coroutines.delay import androidx.compose.animation.core.animateFloatAsState import androidx.compose.ui.draw.alpha @@ -217,6 +222,8 @@ fun FluxaApp( modifier: Modifier = Modifier ) { MaterialTheme(colorScheme = FluxaColorScheme) { + val liquidGlassMode = settingsState?.appearance?.liquidGlassMode == true + val hazeState = rememberHazeState() Box( modifier = modifier .fillMaxSize() @@ -245,11 +252,13 @@ fun FluxaApp( .togetherWith(fadeOut(tween(120))) }, label = "fluxa-screen-transition", - modifier = if (isHomeActive || !showNavigationBar) { - Modifier.fillMaxSize() - } else { - Modifier.fillMaxSize().padding(bottom = navBarHeightDp) - } + modifier = ( + if (isHomeActive || !showNavigationBar) { + Modifier.fillMaxSize() + } else { + Modifier.fillMaxSize().padding(bottom = navBarHeightDp) + } + ).then(if (liquidGlassMode) Modifier.hazeSource(hazeState) else Modifier) ) { key -> saveableStateHolder.SaveableStateProvider(key) { when { @@ -454,7 +463,8 @@ fun FluxaApp( destination = state.destination, accentColorArgb = profileState?.activeProfile?.accentColorArgb, floating = settingsState?.appearance?.floatingBottomBar == true, - liquidGlass = settingsState?.appearance?.liquidGlassMode == true, + liquidGlass = liquidGlassMode, + hazeState = hazeState, showLabels = settingsState?.appearance?.bottomBarLabels == true, showProfile = settingsState?.appearanceHome?.topBarEnabled == false, profileAvatarUrl = profileState?.activeProfile?.avatarUrl, @@ -488,6 +498,7 @@ private fun FluxaNavigationBar( accentColorArgb: Long?, floating: Boolean, liquidGlass: Boolean, + hazeState: dev.chrisbanes.haze.HazeState, showLabels: Boolean, showProfile: Boolean, profileAvatarUrl: String?, @@ -517,12 +528,15 @@ private fun FluxaNavigationBar( .then( if (liquidGlass) { Modifier - .background( - Brush.verticalGradient( - listOf(Color(0x33FFFFFF), Color(0x1AFFFFFF)) + .hazeEffect( + state = hazeState, + style = HazeDefaults.style( + backgroundColor = if (floating) Color(0xFF222222) else Color(0xFF111111), + tint = HazeTint(Color.White.copy(alpha = 0.08f)), + blurRadius = 24.dp, + noiseFactor = 0.12f ) ) - .background(if (floating) Color(0x99222222) else Color(0x99111111)) .border(1.dp, Color(0x26FFFFFF), barShape) } else { Modifier.background(if (floating) Color(0xF2222222) else Color(0xFF111111))