Minor UI tweaks
This commit is contained in:
@@ -561,6 +561,7 @@ fun MediaItemMenu(
|
|||||||
DialogTextButton(
|
DialogTextButton(
|
||||||
text = "Set",
|
text = "Set",
|
||||||
enabled = amount > 0,
|
enabled = amount > 0,
|
||||||
|
primary = true,
|
||||||
onClick = {
|
onClick = {
|
||||||
binder?.startSleepTimer(amount * 10 * 60 * 1000L)
|
binder?.startSleepTimer(amount * 10 * 60 * 1000L)
|
||||||
isShowingSleepTimerDialog = false
|
isShowingSleepTimerDialog = false
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.offset
|
|||||||
import androidx.compose.foundation.layout.only
|
import androidx.compose.foundation.layout.only
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
@@ -34,6 +35,8 @@ import androidx.compose.ui.unit.dp
|
|||||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||||
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
|
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
|
||||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||||
|
import it.vfsfitvnm.vimusic.utils.center
|
||||||
|
import it.vfsfitvnm.vimusic.utils.color
|
||||||
import it.vfsfitvnm.vimusic.utils.isLandscape
|
import it.vfsfitvnm.vimusic.utils.isLandscape
|
||||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||||
|
|
||||||
@@ -83,7 +86,11 @@ inline fun NavigationRail(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
|
.width(if (isLandscape) Dimensions.navigationRailWidthLandscape else Dimensions.navigationRailWidth)
|
||||||
|
) {
|
||||||
val transition = updateTransition(targetState = tabIndex, label = null)
|
val transition = updateTransition(targetState = tabIndex, label = null)
|
||||||
|
|
||||||
content { index, text, icon ->
|
content { index, text, icon ->
|
||||||
@@ -114,7 +121,7 @@ inline fun NavigationRail(
|
|||||||
val textContent: @Composable () -> Unit = {
|
val textContent: @Composable () -> Unit = {
|
||||||
BasicText(
|
BasicText(
|
||||||
text = text,
|
text = text,
|
||||||
style = typography.xs.semiBold.copy(color = textColor),
|
style = typography.xs.semiBold.center.color(textColor),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.vertical(enabled = !isLandscape)
|
.vertical(enabled = !isLandscape)
|
||||||
.rotate(if (isLandscape) 0f else -90f)
|
.rotate(if (isLandscape) 0f else -90f)
|
||||||
@@ -153,7 +160,7 @@ inline fun NavigationRail(
|
|||||||
fun Modifier.vertical(enabled: Boolean = true) =
|
fun Modifier.vertical(enabled: Boolean = true) =
|
||||||
if (enabled)
|
if (enabled)
|
||||||
layout { measurable, constraints ->
|
layout { measurable, constraints ->
|
||||||
val placeable = measurable.measure(constraints)
|
val placeable = measurable.measure(constraints.copy(maxWidth = Int.MAX_VALUE))
|
||||||
layout(placeable.height, placeable.width) {
|
layout(placeable.height, placeable.width) {
|
||||||
placeable.place(
|
placeable.place(
|
||||||
x = -(placeable.width / 2 - placeable.height / 2),
|
x = -(placeable.width / 2 - placeable.height / 2),
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import androidx.compose.animation.core.VisibilityThreshold
|
|||||||
import androidx.compose.animation.core.spring
|
import androidx.compose.animation.core.spring
|
||||||
import androidx.compose.animation.with
|
import androidx.compose.animation.with
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -31,42 +30,37 @@ fun Scaffold(
|
|||||||
) {
|
) {
|
||||||
val (colorPalette) = LocalAppearance.current
|
val (colorPalette) = LocalAppearance.current
|
||||||
|
|
||||||
Box(
|
Row(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.background(colorPalette.background0)
|
.background(colorPalette.background0)
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
Row(
|
NavigationRail(
|
||||||
modifier = modifier
|
topIconButtonId = topIconButtonId,
|
||||||
.fillMaxSize()
|
onTopIconButtonClick = onTopIconButtonClick,
|
||||||
) {
|
tabIndex = tabIndex,
|
||||||
NavigationRail(
|
onTabIndexChanged = onTabChanged,
|
||||||
topIconButtonId = topIconButtonId,
|
content = tabColumnContent
|
||||||
onTopIconButtonClick = onTopIconButtonClick,
|
)
|
||||||
tabIndex = tabIndex,
|
|
||||||
onTabIndexChanged = onTabChanged,
|
|
||||||
content = tabColumnContent
|
|
||||||
)
|
|
||||||
|
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = tabIndex,
|
targetState = tabIndex,
|
||||||
transitionSpec = {
|
transitionSpec = {
|
||||||
val slideDirection = when (targetState > initialState) {
|
val slideDirection = when (targetState > initialState) {
|
||||||
true -> AnimatedContentScope.SlideDirection.Up
|
true -> AnimatedContentScope.SlideDirection.Up
|
||||||
false -> AnimatedContentScope.SlideDirection.Down
|
false -> AnimatedContentScope.SlideDirection.Down
|
||||||
}
|
}
|
||||||
|
|
||||||
val animationSpec = spring(
|
val animationSpec = spring(
|
||||||
dampingRatio = 0.9f,
|
dampingRatio = 0.9f,
|
||||||
stiffness = Spring.StiffnessLow,
|
stiffness = Spring.StiffnessLow,
|
||||||
visibilityThreshold = IntOffset.VisibilityThreshold
|
visibilityThreshold = IntOffset.VisibilityThreshold
|
||||||
)
|
)
|
||||||
|
|
||||||
slideIntoContainer(slideDirection, animationSpec) with
|
slideIntoContainer(slideDirection, animationSpec) with
|
||||||
slideOutOfContainer(slideDirection, animationSpec)
|
slideOutOfContainer(slideDirection, animationSpec)
|
||||||
},
|
},
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,20 @@ import androidx.compose.foundation.background
|
|||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||||
|
import androidx.compose.foundation.layout.asPaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.only
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
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.unit.dp
|
||||||
import it.vfsfitvnm.vimusic.Database
|
import it.vfsfitvnm.vimusic.Database
|
||||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
|
||||||
import androidx.compose.foundation.layout.asPaddingValues
|
|
||||||
import androidx.compose.foundation.layout.only
|
|
||||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||||
import it.vfsfitvnm.vimusic.R
|
import it.vfsfitvnm.vimusic.R
|
||||||
import it.vfsfitvnm.vimusic.enums.BuiltInPlaylist
|
import it.vfsfitvnm.vimusic.enums.BuiltInPlaylist
|
||||||
@@ -93,7 +95,9 @@ fun BuiltInPlaylistSongs(builtInPlaylist: BuiltInPlaylist) {
|
|||||||
title = when (builtInPlaylist) {
|
title = when (builtInPlaylist) {
|
||||||
BuiltInPlaylist.Favorites -> "Favorites"
|
BuiltInPlaylist.Favorites -> "Favorites"
|
||||||
BuiltInPlaylist.Offline -> "Offline"
|
BuiltInPlaylist.Offline -> "Offline"
|
||||||
}
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(bottom = 8.dp)
|
||||||
) {
|
) {
|
||||||
SecondaryTextButton(
|
SecondaryTextButton(
|
||||||
text = "Enqueue",
|
text = "Enqueue",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
|||||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||||
import androidx.compose.foundation.layout.asPaddingValues
|
import androidx.compose.foundation.layout.asPaddingValues
|
||||||
import androidx.compose.foundation.layout.only
|
import androidx.compose.foundation.layout.only
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||||
import it.vfsfitvnm.vimusic.R
|
import it.vfsfitvnm.vimusic.R
|
||||||
import it.vfsfitvnm.vimusic.models.DetailedSong
|
import it.vfsfitvnm.vimusic.models.DetailedSong
|
||||||
@@ -151,7 +152,11 @@ fun LocalPlaylistSongs(
|
|||||||
key = "header",
|
key = "header",
|
||||||
contentType = 0
|
contentType = 0
|
||||||
) {
|
) {
|
||||||
Header(title = playlistWithSongs?.playlist?.name ?: "Unknown") {
|
Header(
|
||||||
|
title = playlistWithSongs?.playlist?.name ?: "Unknown",
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(bottom = 8.dp)
|
||||||
|
) {
|
||||||
SecondaryTextButton(
|
SecondaryTextButton(
|
||||||
text = "Enqueue",
|
text = "Enqueue",
|
||||||
enabled = playlistWithSongs?.songs?.isNotEmpty() == true,
|
enabled = playlistWithSongs?.songs?.isNotEmpty() == true,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import androidx.compose.foundation.Image
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -24,6 +25,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
|||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.text.BasicText
|
import androidx.compose.foundation.text.BasicText
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -296,76 +298,80 @@ fun Lyrics(
|
|||||||
colorFilter = ColorFilter.tint(DefaultDarkColorPalette.text),
|
colorFilter = ColorFilter.tint(DefaultDarkColorPalette.text),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(all = 4.dp)
|
.padding(all = 4.dp)
|
||||||
.clickable {
|
.clickable(
|
||||||
menuState.display {
|
indication = rememberRipple(bounded = false),
|
||||||
Menu {
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
MenuEntry(
|
onClick = {
|
||||||
icon = R.drawable.time,
|
menuState.display {
|
||||||
text = "Show ${if (isShowingSynchronizedLyrics) "un" else ""}synchronized lyrics",
|
Menu {
|
||||||
secondaryText = if (isShowingSynchronizedLyrics) null else "Provided by kugou.com",
|
MenuEntry(
|
||||||
onClick = {
|
icon = R.drawable.time,
|
||||||
menuState.hide()
|
text = "Show ${if (isShowingSynchronizedLyrics) "un" else ""}synchronized lyrics",
|
||||||
isShowingSynchronizedLyrics =
|
secondaryText = if (isShowingSynchronizedLyrics) null else "Provided by kugou.com",
|
||||||
!isShowingSynchronizedLyrics
|
onClick = {
|
||||||
}
|
menuState.hide()
|
||||||
)
|
isShowingSynchronizedLyrics =
|
||||||
|
!isShowingSynchronizedLyrics
|
||||||
MenuEntry(
|
|
||||||
icon = R.drawable.pencil,
|
|
||||||
text = "Edit lyrics",
|
|
||||||
onClick = {
|
|
||||||
menuState.hide()
|
|
||||||
isEditing = true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
MenuEntry(
|
|
||||||
icon = R.drawable.search,
|
|
||||||
text = "Search lyrics online",
|
|
||||||
onClick = {
|
|
||||||
menuState.hide()
|
|
||||||
val mediaMetadata = mediaMetadataProvider()
|
|
||||||
|
|
||||||
val intent =
|
|
||||||
Intent(Intent.ACTION_WEB_SEARCH).apply {
|
|
||||||
putExtra(
|
|
||||||
SearchManager.QUERY,
|
|
||||||
"${mediaMetadata.title} ${mediaMetadata.artist} lyrics"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intent.resolveActivity(context.packageManager) != null) {
|
|
||||||
context.startActivity(intent)
|
|
||||||
} else {
|
|
||||||
Toast
|
|
||||||
.makeText(
|
|
||||||
context,
|
|
||||||
"No browser app found!",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
)
|
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
|
||||||
|
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon = R.drawable.download,
|
icon = R.drawable.pencil,
|
||||||
text = "Fetch lyrics again",
|
text = "Edit lyrics",
|
||||||
enabled = lyrics != null,
|
onClick = {
|
||||||
onClick = {
|
menuState.hide()
|
||||||
menuState.hide()
|
isEditing = true
|
||||||
query {
|
}
|
||||||
if (isShowingSynchronizedLyrics) {
|
)
|
||||||
Database.updateSynchronizedLyrics(mediaId, null)
|
|
||||||
|
MenuEntry(
|
||||||
|
icon = R.drawable.search,
|
||||||
|
text = "Search lyrics online",
|
||||||
|
onClick = {
|
||||||
|
menuState.hide()
|
||||||
|
val mediaMetadata = mediaMetadataProvider()
|
||||||
|
|
||||||
|
val intent =
|
||||||
|
Intent(Intent.ACTION_WEB_SEARCH).apply {
|
||||||
|
putExtra(
|
||||||
|
SearchManager.QUERY,
|
||||||
|
"${mediaMetadata.title} ${mediaMetadata.artist} lyrics"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intent.resolveActivity(context.packageManager) != null) {
|
||||||
|
context.startActivity(intent)
|
||||||
} else {
|
} else {
|
||||||
Database.updateLyrics(mediaId, null)
|
Toast
|
||||||
|
.makeText(
|
||||||
|
context,
|
||||||
|
"No browser app found!",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
|
||||||
|
MenuEntry(
|
||||||
|
icon = R.drawable.download,
|
||||||
|
text = "Fetch lyrics again",
|
||||||
|
enabled = lyrics != null,
|
||||||
|
onClick = {
|
||||||
|
menuState.hide()
|
||||||
|
query {
|
||||||
|
if (isShowingSynchronizedLyrics) {
|
||||||
|
Database.updateSynchronizedLyrics(mediaId, null)
|
||||||
|
} else {
|
||||||
|
Database.updateLyrics(mediaId, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
.padding(all = 8.dp)
|
.padding(all = 8.dp)
|
||||||
.size(20.dp)
|
.size(20.dp)
|
||||||
.align(Alignment.BottomEnd)
|
.align(Alignment.BottomEnd)
|
||||||
|
|||||||
Reference in New Issue
Block a user