feat: implement haze effect and UI enhancements in AppLargePlayer and AppShell

This commit is contained in:
Kingkor Roy Tirtho 2026-07-20 13:22:14 +06:00
parent 12dea49c2c
commit edc7cdd3fa
2 changed files with 222 additions and 184 deletions

View File

@ -18,18 +18,23 @@
package dev.krtirtho.spotube.modules.shell
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
@ -45,9 +50,14 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.blur.HazeColorEffect
import dev.chrisbanes.haze.blur.blurEffect
import dev.chrisbanes.haze.hazeEffect
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil3.compose.AsyncImage
import dev.krtirtho.spotube.core.audioplayer.AudioPlayer
@ -100,6 +110,7 @@ import kotlin.time.Duration.Companion.milliseconds
@Composable
fun AppLargePlayer(
modifier: Modifier = Modifier,
hazeState: HazeState,
onQueue: () -> Unit = {},
onAlternativeSource: () -> Unit = {},
onMoreOptions: () -> Unit = {},
@ -171,10 +182,30 @@ fun AppLargePlayer(
}
}
val surfaceTint = MaterialTheme.colorScheme.surface.copy(alpha = 0.85f)
Surface(
modifier = modifier.fillMaxWidth(),
tonalElevation = 0.dp,
shadowElevation = 0.dp
modifier = modifier
.windowInsetsPadding(WindowInsets.navigationBars),
color = Color.Transparent,
shadowElevation = 0.dp,
) {
HorizontalDivider(
modifier = Modifier.fillMaxWidth(),
color = Color.Gray,
thickness = 1.dp,
)
Box(
modifier = Modifier
.fillMaxWidth()
.hazeEffect(state = hazeState) {
blurEffect {
blurRadius = 20.dp
colorEffects = listOf(
HazeColorEffect.tint(surfaceTint)
)
}
}
) {
Row(
modifier = Modifier
@ -379,5 +410,6 @@ fun AppLargePlayer(
}
}
}
}
}

View File

@ -39,6 +39,7 @@ import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.SheetValue
import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider
import androidx.compose.material3.rememberBottomSheetScaffoldState
import androidx.compose.material3.rememberStandardBottomSheetState
@ -57,6 +58,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import dev.chrisbanes.haze.hazeSource
import dev.chrisbanes.haze.rememberHazeState
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import dev.krtirtho.spotube.core.navigation.NavigationCommands
@ -116,8 +119,13 @@ fun AppShell(
CompositionLocalProvider(LocalAppShellBottomInset provides bottomOverlayInset) {
if (useSidebar) {
Column(modifier = Modifier.fillMaxSize()) {
Box(modifier = Modifier.fillMaxSize().weight(1f)) {
val hazeState = rememberHazeState()
Box(modifier = Modifier.fillMaxSize()) {
Box(
modifier = Modifier
.fillMaxSize()
.hazeSource(hazeState)
) {
Row(modifier = Modifier.fillMaxSize()) {
AppSidebar(
navigator = navigator, navigationState = navigationState
@ -174,13 +182,11 @@ fun AppShell(
)
}
}
HorizontalDivider(
modifier = Modifier.fillMaxWidth(),
color = Color.Gray.copy(alpha = 0.2f),
thickness = 1.dp,
)
AppLargePlayer(
modifier = Modifier.fillMaxWidth(),
hazeState = hazeState,
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter),
onQueue = queueViewModel::toggleQueueVisibility,
onAlternativeSource = alternativeViewModel::toggleAlternativeVisibility,
onLyrics = { navigatorCommands.navigateTo(Routes.Lyrics) },