Rework song UI
This commit is contained in:
parent
2f46d44ed1
commit
749e995d42
5 changed files with 72 additions and 28 deletions
|
@ -276,6 +276,17 @@ fun LocalPlaylistScreen(
|
||||||
song = song
|
song = song
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
trailingContent = {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(R.drawable.reorder),
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(colorPalette.textSecondary),
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable {}
|
||||||
|
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||||
|
.size(20.dp)
|
||||||
|
)
|
||||||
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.verticalDragAfterLongPressToReorder(
|
.verticalDragAfterLongPressToReorder(
|
||||||
reorderingState = reorderingState,
|
reorderingState = reorderingState,
|
||||||
|
|
|
@ -6,6 +6,7 @@ import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
@ -138,6 +139,17 @@ fun CurrentPlaylistView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
trailingContent = {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(R.drawable.reorder),
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(colorPalette.textSecondary),
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable {}
|
||||||
|
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||||
|
.size(20.dp)
|
||||||
|
)
|
||||||
|
},
|
||||||
backgroundColor = colorPalette.elevatedBackground,
|
backgroundColor = colorPalette.elevatedBackground,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.verticalDragAfterLongPressToReorder(
|
.verticalDragAfterLongPressToReorder(
|
||||||
|
|
|
@ -95,7 +95,7 @@ fun PlayerView(
|
||||||
collapsedContent = {
|
collapsedContent = {
|
||||||
if (!layoutState.isExpanded) {
|
if (!layoutState.isExpanded) {
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.height(layoutState.lowerBound)
|
.height(layoutState.lowerBound)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package it.vfsfitvnm.vimusic.ui.views
|
package it.vfsfitvnm.vimusic.ui.views
|
||||||
|
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.text.BasicText
|
import androidx.compose.foundation.text.BasicText
|
||||||
|
@ -15,16 +15,13 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import it.vfsfitvnm.vimusic.R
|
|
||||||
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
|
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
|
||||||
import it.vfsfitvnm.vimusic.models.DetailedSong
|
import it.vfsfitvnm.vimusic.models.DetailedSong
|
||||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||||
|
@ -46,6 +43,7 @@ fun SongItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
backgroundColor: Color? = null,
|
backgroundColor: Color? = null,
|
||||||
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
|
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
|
||||||
|
trailingContent: (@Composable () -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
SongItem(
|
SongItem(
|
||||||
thumbnailModel = ImageRequest.Builder(LocalContext.current)
|
thumbnailModel = ImageRequest.Builder(LocalContext.current)
|
||||||
|
@ -58,6 +56,7 @@ fun SongItem(
|
||||||
menuContent = menuContent,
|
menuContent = menuContent,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
onThumbnailContent = onThumbnailContent,
|
onThumbnailContent = onThumbnailContent,
|
||||||
|
trailingContent = trailingContent,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
|
@ -74,6 +73,7 @@ fun SongItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
backgroundColor: Color? = null,
|
backgroundColor: Color? = null,
|
||||||
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
|
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
|
||||||
|
trailingContent: (@Composable () -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
SongItem(
|
SongItem(
|
||||||
thumbnailModel = song.song.thumbnailUrl?.thumbnail(thumbnailSize),
|
thumbnailModel = song.song.thumbnailUrl?.thumbnail(thumbnailSize),
|
||||||
|
@ -84,6 +84,7 @@ fun SongItem(
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
onThumbnailContent = onThumbnailContent,
|
onThumbnailContent = onThumbnailContent,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
|
trailingContent = trailingContent,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -102,6 +103,7 @@ fun SongItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
backgroundColor: Color? = null,
|
backgroundColor: Color? = null,
|
||||||
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
|
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
|
||||||
|
trailingContent: (@Composable () -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
SongItem(
|
SongItem(
|
||||||
title = title,
|
title = title,
|
||||||
|
@ -127,10 +129,12 @@ fun SongItem(
|
||||||
},
|
},
|
||||||
menuContent = menuContent,
|
menuContent = menuContent,
|
||||||
backgroundColor = backgroundColor,
|
backgroundColor = backgroundColor,
|
||||||
|
trailingContent = trailingContent,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
@Composable
|
@Composable
|
||||||
fun SongItem(
|
fun SongItem(
|
||||||
|
@ -142,6 +146,7 @@ fun SongItem(
|
||||||
menuContent: @Composable () -> Unit,
|
menuContent: @Composable () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
backgroundColor: Color? = null,
|
backgroundColor: Color? = null,
|
||||||
|
trailingContent: (@Composable () -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
val menuState = LocalMenuState.current
|
val menuState = LocalMenuState.current
|
||||||
val colorPalette = LocalColorPalette.current
|
val colorPalette = LocalColorPalette.current
|
||||||
|
@ -149,17 +154,20 @@ fun SongItem(
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.clickable(
|
.combinedClickable(
|
||||||
indication = rememberRipple(bounded = true),
|
indication = rememberRipple(bounded = true),
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
onLongClick = {
|
||||||
|
menuState.display(menuContent)
|
||||||
|
},
|
||||||
onClick = onClick
|
onClick = onClick
|
||||||
)
|
)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 4.dp)
|
.padding(vertical = 5.dp)
|
||||||
.background(backgroundColor ?: colorPalette.background)
|
.background(backgroundColor ?: colorPalette.background)
|
||||||
.padding(start = 16.dp, end = 8.dp)
|
.padding(start = 16.dp, end = if (trailingContent == null) 16.dp else 8.dp)
|
||||||
) {
|
) {
|
||||||
startContent()
|
startContent()
|
||||||
|
|
||||||
|
@ -174,29 +182,22 @@ fun SongItem(
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
BasicText(
|
BasicText(
|
||||||
text = buildString {
|
text = authors ?: "",
|
||||||
append(authors)
|
|
||||||
if (authors?.isNotEmpty() == true && durationText != null) {
|
|
||||||
append(" • ")
|
|
||||||
}
|
|
||||||
append(durationText)
|
|
||||||
},
|
|
||||||
style = typography.xs.semiBold.secondary,
|
style = typography.xs.semiBold.secondary,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Image(
|
durationText?.let {
|
||||||
painter = painterResource(R.drawable.ellipsis_vertical),
|
BasicText(
|
||||||
contentDescription = null,
|
text = durationText,
|
||||||
colorFilter = ColorFilter.tint(colorPalette.textSecondary),
|
style = typography.xxs.secondary,
|
||||||
modifier = Modifier
|
maxLines = 1,
|
||||||
.clickable {
|
overflow = TextOverflow.Ellipsis,
|
||||||
menuState.display(menuContent)
|
|
||||||
}
|
|
||||||
.padding(horizontal = 8.dp, vertical = 4.dp)
|
|
||||||
.size(20.dp)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trailingContent?.invoke()
|
||||||
|
}
|
||||||
}
|
}
|
20
app/src/main/res/drawable/reorder.xml
Normal file
20
app/src/main/res/drawable/reorder.xml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="512"
|
||||||
|
android:viewportHeight="512">
|
||||||
|
<path
|
||||||
|
android:pathData="M118,304L394,304"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="44"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#000"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M118,208L394,208"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="44"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#000"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
Loading…
Add table
Reference in a new issue