fix: add window insets to top bar and bottom navigation bar, queue sheet

This commit is contained in:
Kingkor Roy Tirtho 2026-10-14 19:26:54 +06:00
parent fda5bb8a60
commit d5eaf101eb
9 changed files with 37 additions and 38 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<g id="Alapkör">
<circle id="XMLID_23_" fill="#CD201F" cx="50" cy="50" r="50"/>
</g>
<g id="Elemek">
<path id="XMLID_19_" fill="#FFFFFF" d="M47,28.2c-9-5.3-15.3-9-15.3-9v61.7c0,0,30.4-18,52.3-30.9C72.1,43,57.7,34.5,47,28.2z"/>
</g>
<g id="Fedő">
<path id="XMLID_5_" fill="#CD201F" d="M48.4,40.1c-4.1-2.4-7-4.1-7-4.1V64c0,0,13.9-8.2,23.8-14C59.8,46.8,53.3,42.9,48.4,40.1z"/>
<rect id="XMLID_4_" x="41.4" y="55.6" fill="#CD201F" width="6.2" height="21"/>
</g>
<g id="Vonalak">
</g>
</svg>

Before

Width:  |  Height:  |  Size: 787 B

View File

@ -32,7 +32,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
@ -156,7 +155,7 @@ fun PlatformWebViewScreen(webViewController: WebViewController) {
ApplicationMainBar(
title = {
Row(
modifier = Modifier.fillMaxWidth().statusBarsPadding().height(56.dp),
modifier = Modifier.fillMaxWidth().height(56.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
@ -227,4 +226,4 @@ fun PlatformWebViewScreen(webViewController: WebViewController) {
navigator.evaluateJavaScript(bridgeBootstrapScript)
})
}
}
}

View File

@ -30,7 +30,6 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
@ -128,7 +127,11 @@ fun AppShell(
Box(modifier = Modifier.fillMaxSize()) {
val useSidebar = viewModel.useSidebar()
val bottomOverlayInset = viewModel.bottomOverlayInset(useSidebar)
val density = LocalDensity.current
val navigationBarInset = with(density) {
WindowInsets.navigationBars.getBottom(this).toDp()
}
val bottomOverlayInset = viewModel.bottomOverlayInset(useSidebar) + navigationBarInset
CompositionLocalProvider(LocalAppShellBottomInset provides bottomOverlayInset) {
if (useSidebar) {
@ -278,7 +281,9 @@ private fun CompactPlayerOverlay(
val floatingPlayerHeightPx = with(density) { viewModel.floatingPlayerHeight.toPx() }
val bottomBarHeightPx = with(density) { viewModel.bottomBarHeight.toPx() }
val navBarInsetPx = WindowInsets.navigationBars.getBottom(density).toFloat()
val peekHeightPx = floatingPlayerHeightPx + bottomBarHeightPx + navBarInsetPx
val playerBarSpacingPx = with(density) { viewModel.floatingPlayerSpacing.toPx() }
val peekHeightPx =
floatingPlayerHeightPx + bottomBarHeightPx + navBarInsetPx + playerBarSpacingPx
val peekHeight = with(density) { peekHeightPx.toDp() }
val partialDetent = remember(peekHeight) {
@ -318,7 +323,6 @@ private fun CompactPlayerOverlay(
Column(modifier = Modifier.fillMaxWidth()) {
AppFloatingPlayer(
modifier = Modifier
.offset(y = 12.dp)
.graphicsLayer {
alpha = uiState.floatingPlayerAlpha
})
@ -332,9 +336,12 @@ private fun CompactPlayerOverlay(
AppBottombar(
navigator = navigator,
navigationState = navigationState,
modifier = Modifier.fillMaxWidth().align(Alignment.BottomCenter).graphicsLayer {
alpha = uiState.floatingPlayerAlpha
})
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter)
.graphicsLayer {
alpha = uiState.floatingPlayerAlpha
})
}
}
}

View File

@ -42,9 +42,9 @@ data class LyricsOverlayState(
class AppShellViewModel : ViewModel() {
val sidebarMinWidth = 840.dp
val bottomBarEstimatedHeight = 58.dp
val bottomBarHeight = 80.dp
val floatingPlayerHeight = 74.dp
val floatingPlayerHeight = 76.dp
val floatingPlayerSpacing = 12.dp
val largePlayerInset = 100.dp
val floatingPlayerDismissProgress = 0.7f
val expandedPlayerVisibilityThreshold = 0.001f
@ -53,11 +53,8 @@ class AppShellViewModel : ViewModel() {
val isLyricsOverlayVisible: StateFlow<Boolean> = lyricsOverlayVisible.asStateFlow()
val floatingPlayerBottomOffset: Dp
get() = bottomBarEstimatedHeight + 8.dp
val compactChromeInset: Dp
get() = floatingPlayerBottomOffset + floatingPlayerHeight + 10.dp
get() = bottomBarHeight + floatingPlayerHeight + floatingPlayerSpacing
@Composable
fun useSidebar(maxWidth: Dp? = null): Boolean {

View File

@ -34,6 +34,9 @@ import org.spotube.millennium.composables.MillenniumModalBottomSheet
import org.spotube.millennium.composables.rememberMillenniumDrawerState
private val SlidingSheetBreakpoint = 840.dp
private val MaxHeightSheetDetent = SheetDetent("max-height-85-percent") { containerHeight, sheetHeight ->
minOf(sheetHeight, containerHeight * 0.85f)
}
@Composable
fun QueueSheet(
@ -85,7 +88,10 @@ internal fun BottomSheetContent(
content: @Composable () -> Unit
) {
if (!isVisible) return
val sheetState = rememberModalBottomSheetState(initialDetent = SheetDetent.FullyExpanded)
val sheetState = rememberModalBottomSheetState(
initialDetent = MaxHeightSheetDetent,
detents = listOf(SheetDetent.Hidden, MaxHeightSheetDetent)
)
LaunchedEffect(sheetState.bottomSheetState.currentDetent) {
if (sheetState.bottomSheetState.currentDetent == SheetDetent.Hidden) {
onDismiss()

View File

@ -18,6 +18,8 @@
package dev.krtirtho.spotube.core.ui.component
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.statusBars
import org.spotube.millennium.composables.MillenniumTopAppBar
import androidx.compose.ui.graphics.Color
import androidx.compose.runtime.Composable
@ -33,10 +35,11 @@ actual fun ApplicationMainBar(
title = title,
subtitle = subtitle,
actions = actions,
windowInsets = WindowInsets.statusBars,
navigationIcon = {
if (backButton) {
ApplicationBackButton()
}
}
)
}
}

View File

@ -27,4 +27,8 @@ org.gradle.caching=true
#Android
android.nonTransitiveRClass=true
android.useAndroidX=true
android.useAndroidX=true
# Preserve compatibility with this project's current Kotlin Multiplatform Android setup on AGP 9.
android.builtInKotlin=false
android.newDsl=false
android.sourceset.disallowProvider=false

View File

@ -14,7 +14,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
[versions]
agp = "8.13.2"
agp = "9.1.0"
android-compileSdk = "37"
android-minSdk = "28"
android-targetSdk = "36"
@ -193,4 +193,4 @@ uniffi = { id = "dev.gobley.uniffi", version.ref = "uniffi" }
cargo = { id = "dev.gobley.cargo", version.ref = "uniffi" }
mokkery = { id = "dev.mokkery", version.ref = "mokkery" }
vanniktechMavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktechMavenPublish" }
neucleusFramework = { id = "dev.nucleusframework", version.ref = "nucleusNucleusApplication" }
neucleusFramework = { id = "dev.nucleusframework", version.ref = "nucleusNucleusApplication" }