Tweak code

This commit is contained in:
vfsfitvnm
2022-10-02 16:57:07 +02:00
parent 917e194d63
commit a136b4f9d6
11 changed files with 227 additions and 249 deletions

View File

@@ -5,10 +5,6 @@ plugins {
} }
android { android {
signingConfigs {
create("release") {
}
}
compileSdk = 33 compileSdk = 33
defaultConfig { defaultConfig {
@@ -65,10 +61,6 @@ android {
freeCompilerArgs += "-Xcontext-receivers" freeCompilerArgs += "-Xcontext-receivers"
jvmTarget = "1.8" jvmTarget = "1.8"
} }
packagingOptions {
resources.excludes.add("META-INF/INDEX.LIST")
}
} }
kapt { kapt {

View File

@@ -41,10 +41,8 @@ inline fun <T : Innertube.Item> ArtistContent(
crossinline bookmarkIconContent: @Composable () -> Unit, crossinline bookmarkIconContent: @Composable () -> Unit,
crossinline shareIconContent: @Composable () -> Unit, crossinline shareIconContent: @Composable () -> Unit,
crossinline itemContent: @Composable LazyItemScope.(T) -> Unit, crossinline itemContent: @Composable LazyItemScope.(T) -> Unit,
noinline itemShimmer: @Composable () -> Unit, noinline itemPlaceholderContent: @Composable () -> Unit,
) { ) {
val (_, typography) = LocalAppearance.current
var items by rememberSaveable(stateSaver = stateSaver) { var items by rememberSaveable(stateSaver = stateSaver) {
mutableStateOf(listOf()) mutableStateOf(listOf())
} }
@@ -124,7 +122,7 @@ inline fun <T : Innertube.Item> ArtistContent(
if (hasMore || items.isEmpty()) { if (hasMore || items.isEmpty()) {
ShimmerHost { ShimmerHost {
repeat(if (hasMore) 3 else 8) { repeat(if (hasMore) 3 else 8) {
itemShimmer() itemPlaceholderContent()
} }
} }
@@ -147,7 +145,7 @@ inline fun <T : Innertube.Item> ArtistContent(
HeaderPlaceholder() HeaderPlaceholder()
repeat(5) { repeat(5) {
itemShimmer() itemPlaceholderContent()
} }
} }
} }

View File

@@ -47,10 +47,10 @@ 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.ui.styling.px import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.styling.shimmer import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.vfsfitvnm.vimusic.ui.views.AlternativeAlbumItem import it.vfsfitvnm.vimusic.ui.views.AlbumItem
import it.vfsfitvnm.vimusic.ui.views.AlternativeAlbumItemPlaceholder import it.vfsfitvnm.vimusic.ui.views.AlbumItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.SmallSongItem import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.ui.views.SmallSongItemShimmer import it.vfsfitvnm.vimusic.ui.views.SongItemPlaceholder
import it.vfsfitvnm.vimusic.utils.asMediaItem import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.center import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.forcePlay import it.vfsfitvnm.vimusic.utils.forcePlay
@@ -159,7 +159,7 @@ fun ArtistOverview(
} }
songs.forEach { song -> songs.forEach { song ->
SmallSongItem( SongItem(
song = song, song = song,
thumbnailSizePx = songThumbnailSizePx, thumbnailSizePx = songThumbnailSizePx,
onClick = { onClick = {
@@ -209,10 +209,11 @@ fun ArtistOverview(
items = albums, items = albums,
key = Innertube.AlbumItem::key key = Innertube.AlbumItem::key
) { album -> ) { album ->
AlternativeAlbumItem( AlbumItem(
album = album, album = album,
thumbnailSizePx = albumThumbnailSizePx, thumbnailSizePx = albumThumbnailSizePx,
thumbnailSizeDp = albumThumbnailSizeDp, thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true,
modifier = Modifier modifier = Modifier
.clickable( .clickable(
indication = rememberRipple(bounded = true), indication = rememberRipple(bounded = true),
@@ -259,10 +260,11 @@ fun ArtistOverview(
items = singles, items = singles,
key = Innertube.AlbumItem::key key = Innertube.AlbumItem::key
) { album -> ) { album ->
AlternativeAlbumItem( AlbumItem(
album = album, album = album,
thumbnailSizePx = albumThumbnailSizePx, thumbnailSizePx = albumThumbnailSizePx,
thumbnailSizeDp = albumThumbnailSizeDp, thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true,
modifier = Modifier modifier = Modifier
.clickable( .clickable(
indication = rememberRipple(bounded = true), indication = rememberRipple(bounded = true),
@@ -279,7 +281,7 @@ fun ArtistOverview(
TextPlaceholder(modifier = sectionTextModifier) TextPlaceholder(modifier = sectionTextModifier)
repeat(5) { repeat(5) {
SmallSongItemShimmer( SongItemPlaceholder(
thumbnailSizeDp = songThumbnailSizeDp, thumbnailSizeDp = songThumbnailSizeDp,
) )
} }
@@ -289,7 +291,10 @@ fun ArtistOverview(
Row { Row {
repeat(2) { repeat(2) {
AlternativeAlbumItemPlaceholder(thumbnailSizeDp = albumThumbnailSizeDp) AlbumItemPlaceholder(
thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true
)
} }
} }
} }
@@ -312,7 +317,7 @@ fun ArtistOverview(
TextPlaceholder(modifier = sectionTextModifier) TextPlaceholder(modifier = sectionTextModifier)
repeat(5) { repeat(5) {
SmallSongItemShimmer( SongItemPlaceholder(
thumbnailSizeDp = songThumbnailSizeDp, thumbnailSizeDp = songThumbnailSizeDp,
) )
} }
@@ -322,7 +327,10 @@ fun ArtistOverview(
Row { Row {
repeat(2) { repeat(2) {
AlternativeAlbumItemPlaceholder(thumbnailSizeDp = albumThumbnailSizeDp) AlbumItemPlaceholder(
thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true
)
} }
} }
} }

View File

@@ -37,9 +37,9 @@ 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.ui.styling.px import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.views.AlbumItem import it.vfsfitvnm.vimusic.ui.views.AlbumItem
import it.vfsfitvnm.vimusic.ui.views.AlbumItemShimmer import it.vfsfitvnm.vimusic.ui.views.AlbumItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.SmallSongItem import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.ui.views.SmallSongItemShimmer import it.vfsfitvnm.vimusic.ui.views.SongItemPlaceholder
import it.vfsfitvnm.vimusic.utils.artistScreenTabIndexKey import it.vfsfitvnm.vimusic.utils.artistScreenTabIndexKey
import it.vfsfitvnm.vimusic.utils.asMediaItem import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.forcePlay import it.vfsfitvnm.vimusic.utils.forcePlay
@@ -242,7 +242,7 @@ fun ArtistScreen(browseId: String) {
} }
}, },
itemContent = { song -> itemContent = { song ->
SmallSongItem( SongItem(
song = song, song = song,
thumbnailSizePx = thumbnailSizePx, thumbnailSizePx = thumbnailSizePx,
onClick = { onClick = {
@@ -252,8 +252,8 @@ fun ArtistScreen(browseId: String) {
} }
) )
}, },
itemShimmer = { itemPlaceholderContent = {
SmallSongItemShimmer(thumbnailSizeDp = thumbnailSizeDp) SongItemPlaceholder(thumbnailSizeDp = thumbnailSizeDp)
} }
) )
} }
@@ -299,8 +299,8 @@ fun ArtistScreen(browseId: String) {
) )
) )
}, },
itemShimmer = { itemPlaceholderContent = {
AlbumItemShimmer(thumbnailSizeDp = thumbnailSizeDp) AlbumItemPlaceholder(thumbnailSizeDp = thumbnailSizeDp)
} }
) )
} }
@@ -346,8 +346,8 @@ fun ArtistScreen(browseId: String) {
) )
) )
}, },
itemShimmer = { itemPlaceholderContent = {
AlbumItemShimmer(thumbnailSizeDp = thumbnailSizeDp) AlbumItemPlaceholder(thumbnailSizeDp = thumbnailSizeDp)
} }
) )
} }

View File

@@ -6,14 +6,17 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.items
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
@@ -44,14 +47,13 @@ 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.ui.styling.px import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.views.AlbumItem import it.vfsfitvnm.vimusic.ui.views.AlbumItem
import it.vfsfitvnm.vimusic.ui.views.AlbumItemShimmer import it.vfsfitvnm.vimusic.ui.views.AlbumItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.ArtistItem import it.vfsfitvnm.vimusic.ui.views.ArtistItem
import it.vfsfitvnm.vimusic.ui.views.ArtistItemShimmer import it.vfsfitvnm.vimusic.ui.views.ArtistItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.PlaylistItem import it.vfsfitvnm.vimusic.ui.views.PlaylistItem
import it.vfsfitvnm.vimusic.ui.views.PlaylistItemShimmer import it.vfsfitvnm.vimusic.ui.views.PlaylistItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.SmallSongItem
import it.vfsfitvnm.vimusic.ui.views.SmallSongItemShimmer
import it.vfsfitvnm.vimusic.ui.views.SongItem import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.ui.views.SongItemPlaceholder
import it.vfsfitvnm.vimusic.utils.asMediaItem import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.center import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.forcePlay import it.vfsfitvnm.vimusic.utils.forcePlay
@@ -104,7 +106,7 @@ fun QuickPicks(
val songThumbnailSizePx = songThumbnailSizeDp.px val songThumbnailSizePx = songThumbnailSizeDp.px
val albumThumbnailSizeDp = 108.dp val albumThumbnailSizeDp = 108.dp
val albumThumbnailSizePx = albumThumbnailSizeDp.px val albumThumbnailSizePx = albumThumbnailSizeDp.px
val artistThumbnailSizeDp = 64.dp val artistThumbnailSizeDp = 92.dp
val artistThumbnailSizePx = artistThumbnailSizeDp.px val artistThumbnailSizePx = artistThumbnailSizeDp.px
val playlistThumbnailSizeDp = 108.dp val playlistThumbnailSizeDp = 108.dp
val playlistThumbnailSizePx = playlistThumbnailSizeDp.px val playlistThumbnailSizePx = playlistThumbnailSizeDp.px
@@ -158,7 +160,7 @@ fun QuickPicks(
items = related.songs ?: emptyList(), items = related.songs ?: emptyList(),
key = Innertube.SongItem::key key = Innertube.SongItem::key
) { song -> ) { song ->
SmallSongItem( SongItem(
song = song, song = song,
thumbnailSizePx = songThumbnailSizePx, thumbnailSizePx = songThumbnailSizePx,
onClick = { onClick = {
@@ -181,12 +183,7 @@ fun QuickPicks(
modifier = sectionTextModifier modifier = sectionTextModifier
) )
LazyHorizontalGrid( LazyRow {
rows = GridCells.Fixed(2),
modifier = Modifier
.fillMaxWidth()
.height((albumThumbnailSizeDp + Dimensions.itemsVerticalPadding * 2) * 2)
) {
items( items(
items = related.albums ?: emptyList(), items = related.albums ?: emptyList(),
key = Innertube.AlbumItem::key key = Innertube.AlbumItem::key
@@ -195,13 +192,13 @@ fun QuickPicks(
album = album, album = album,
thumbnailSizePx = albumThumbnailSizePx, thumbnailSizePx = albumThumbnailSizePx,
thumbnailSizeDp = albumThumbnailSizeDp, thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true,
modifier = Modifier modifier = Modifier
.clickable( .clickable(
indication = rememberRipple(bounded = true), indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
onClick = { onAlbumClick(album.key) } onClick = { onAlbumClick(album.key) }
) )
.width(itemInHorizontalGridWidth)
) )
} }
} }
@@ -212,12 +209,7 @@ fun QuickPicks(
modifier = sectionTextModifier modifier = sectionTextModifier
) )
LazyHorizontalGrid( LazyRow {
rows = GridCells.Fixed(1),
modifier = Modifier
.fillMaxWidth()
.height((artistThumbnailSizeDp + Dimensions.itemsVerticalPadding * 2))
) {
items( items(
items = related.artists ?: emptyList(), items = related.artists ?: emptyList(),
key = Innertube.ArtistItem::key, key = Innertube.ArtistItem::key,
@@ -226,13 +218,13 @@ fun QuickPicks(
artist = artist, artist = artist,
thumbnailSizePx = artistThumbnailSizePx, thumbnailSizePx = artistThumbnailSizePx,
thumbnailSizeDp = artistThumbnailSizeDp, thumbnailSizeDp = artistThumbnailSizeDp,
alternative = true,
modifier = Modifier modifier = Modifier
.clickable( .clickable(
indication = rememberRipple(bounded = true), indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
onClick = { onArtistClick(artist.key) } onClick = { onArtistClick(artist.key) }
) )
.width(itemInHorizontalGridWidth)
) )
} }
} }
@@ -245,12 +237,7 @@ fun QuickPicks(
.padding(top = 24.dp, bottom = 8.dp) .padding(top = 24.dp, bottom = 8.dp)
) )
LazyHorizontalGrid( LazyRow {
rows = GridCells.Fixed(2),
modifier = Modifier
.fillMaxWidth()
.height((playlistThumbnailSizeDp + Dimensions.itemsVerticalPadding * 2) * 2)
) {
items( items(
items = related.playlists ?: emptyList(), items = related.playlists ?: emptyList(),
key = Innertube.PlaylistItem::key, key = Innertube.PlaylistItem::key,
@@ -259,13 +246,13 @@ fun QuickPicks(
playlist = playlist, playlist = playlist,
thumbnailSizePx = playlistThumbnailSizePx, thumbnailSizePx = playlistThumbnailSizePx,
thumbnailSizeDp = playlistThumbnailSizeDp, thumbnailSizeDp = playlistThumbnailSizeDp,
alternative = true,
modifier = Modifier modifier = Modifier
.clickable( .clickable(
indication = rememberRipple(bounded = true), indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
onClick = { onPlaylistClick(playlist.key) } onClick = { onPlaylistClick(playlist.key) }
) )
.width(itemInHorizontalGridWidth)
) )
} }
} }
@@ -292,25 +279,42 @@ fun QuickPicks(
} }
) { ) {
repeat(4) { repeat(4) {
SmallSongItemShimmer( SongItemPlaceholder(
thumbnailSizeDp = songThumbnailSizeDp, thumbnailSizeDp = songThumbnailSizeDp,
) )
} }
TextPlaceholder(modifier = sectionTextModifier) TextPlaceholder(modifier = sectionTextModifier)
repeat(2) { Row {
AlbumItemShimmer(thumbnailSizeDp = albumThumbnailSizeDp) repeat(2) {
AlbumItemPlaceholder(
thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true
)
}
} }
TextPlaceholder(modifier = sectionTextModifier) TextPlaceholder(modifier = sectionTextModifier)
ArtistItemShimmer(thumbnailSizeDp = artistThumbnailSizeDp) Row {
repeat(2) {
ArtistItemPlaceholder(
thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true
)
}
}
TextPlaceholder(modifier = sectionTextModifier) TextPlaceholder(modifier = sectionTextModifier)
repeat(2) { Row {
PlaylistItemShimmer(thumbnailSizeDp = playlistThumbnailSizeDp) repeat(2) {
PlaylistItemPlaceholder(
thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true
)
}
} }
} }
} }

View File

@@ -57,7 +57,7 @@ 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.ui.styling.onOverlay import it.vfsfitvnm.vimusic.ui.styling.onOverlay
import it.vfsfitvnm.vimusic.ui.styling.px import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.views.SmallSongItemShimmer import it.vfsfitvnm.vimusic.ui.views.SongItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.SongItem import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.utils.medium import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.rememberMediaItemIndex import it.vfsfitvnm.vimusic.utils.rememberMediaItemIndex
@@ -233,7 +233,7 @@ fun PlayerBottomSheet(
.shimmer() .shimmer()
) { ) {
repeat(3) { index -> repeat(3) { index ->
SmallSongItemShimmer( SongItemPlaceholder(
thumbnailSizeDp = Dimensions.thumbnails.song, thumbnailSizeDp = Dimensions.thumbnails.song,
modifier = Modifier modifier = Modifier
.alpha(1f - index * 0.125f) .alpha(1f - index * 0.125f)

View File

@@ -48,7 +48,7 @@ inline fun <T : Innertube.Item> SearchResult(
noinline fromMusicShelfRendererContent: (MusicShelfRenderer.Content) -> T?, noinline fromMusicShelfRendererContent: (MusicShelfRenderer.Content) -> T?,
crossinline onSearchAgain: () -> Unit, crossinline onSearchAgain: () -> Unit,
crossinline itemContent: @Composable LazyItemScope.(T) -> Unit, crossinline itemContent: @Composable LazyItemScope.(T) -> Unit,
noinline itemShimmer: @Composable BoxScope.() -> Unit, noinline itemPlaceholderContent: @Composable BoxScope.() -> Unit,
) { ) {
val (_, typography) = LocalAppearance.current val (_, typography) = LocalAppearance.current
@@ -163,7 +163,7 @@ inline fun <T : Innertube.Item> SearchResult(
Box( Box(
modifier = Modifier modifier = Modifier
.alpha(1f - index * 0.125f), .alpha(1f - index * 0.125f),
content = itemShimmer content = itemPlaceholderContent
) )
} }
} }

View File

@@ -26,15 +26,15 @@ import it.vfsfitvnm.vimusic.ui.screens.playlistRoute
import it.vfsfitvnm.vimusic.ui.styling.Dimensions import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.px import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.views.AlbumItem import it.vfsfitvnm.vimusic.ui.views.AlbumItem
import it.vfsfitvnm.vimusic.ui.views.AlbumItemShimmer import it.vfsfitvnm.vimusic.ui.views.AlbumItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.ArtistItem import it.vfsfitvnm.vimusic.ui.views.ArtistItem
import it.vfsfitvnm.vimusic.ui.views.ArtistItemShimmer import it.vfsfitvnm.vimusic.ui.views.ArtistItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.PlaylistItem import it.vfsfitvnm.vimusic.ui.views.PlaylistItem
import it.vfsfitvnm.vimusic.ui.views.PlaylistItemShimmer import it.vfsfitvnm.vimusic.ui.views.PlaylistItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.SmallSongItem import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.ui.views.SmallSongItemShimmer import it.vfsfitvnm.vimusic.ui.views.SongItemPlaceholder
import it.vfsfitvnm.vimusic.ui.views.VideoItem import it.vfsfitvnm.vimusic.ui.views.VideoItem
import it.vfsfitvnm.vimusic.ui.views.VideoItemShimmer import it.vfsfitvnm.vimusic.ui.views.VideoItemPlaceholder
import it.vfsfitvnm.vimusic.utils.asMediaItem import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.forcePlay import it.vfsfitvnm.vimusic.utils.forcePlay
import it.vfsfitvnm.vimusic.utils.rememberPreference import it.vfsfitvnm.vimusic.utils.rememberPreference
@@ -91,7 +91,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
stateSaver = InnertubeSongItemListSaver, stateSaver = InnertubeSongItemListSaver,
fromMusicShelfRendererContent = Innertube.SongItem.Companion::from, fromMusicShelfRendererContent = Innertube.SongItem.Companion::from,
itemContent = { song -> itemContent = { song ->
SmallSongItem( SongItem(
song = song, song = song,
thumbnailSizePx = thumbnailSizePx, thumbnailSizePx = thumbnailSizePx,
onClick = { onClick = {
@@ -101,8 +101,8 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
} }
) )
}, },
itemShimmer = { itemPlaceholderContent = {
SmallSongItemShimmer(thumbnailSizeDp = thumbnailSizeDp) SongItemPlaceholder(thumbnailSizeDp = thumbnailSizeDp)
} }
) )
} }
@@ -131,8 +131,8 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
) )
}, },
itemShimmer = { itemPlaceholderContent = {
AlbumItemShimmer(thumbnailSizeDp = thumbnailSizeDp) AlbumItemPlaceholder(thumbnailSizeDp = thumbnailSizeDp)
} }
) )
} }
@@ -160,8 +160,8 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
) )
) )
}, },
itemShimmer = { itemPlaceholderContent = {
ArtistItemShimmer(thumbnailSizeDp = thumbnailSizeDp) ArtistItemPlaceholder(thumbnailSizeDp = thumbnailSizeDp)
} }
) )
} }
@@ -188,8 +188,8 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
} }
) )
}, },
itemShimmer = { itemPlaceholderContent = {
VideoItemShimmer( VideoItemPlaceholder(
thumbnailHeightDp = thumbnailHeightDp, thumbnailHeightDp = thumbnailHeightDp,
thumbnailWidthDp = thumbnailWidthDp thumbnailWidthDp = thumbnailWidthDp
) )
@@ -220,8 +220,8 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
) )
) )
}, },
itemShimmer = { itemPlaceholderContent = {
PlaylistItemShimmer(thumbnailSizeDp = thumbnailSizeDp) PlaylistItemPlaceholder(thumbnailSizeDp = thumbnailSizeDp)
} }
) )
} }

View File

@@ -8,6 +8,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@@ -43,8 +44,29 @@ import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.youtubemusic.Innertube import it.vfsfitvnm.youtubemusic.Innertube
@ExperimentalAnimationApi
@Composable @Composable
fun SmallSongItemShimmer( fun SongItem(
song: Innertube.SongItem,
thumbnailSizePx: Int,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
SongItem(
thumbnailModel = song.thumbnail?.size(thumbnailSizePx),
title = song.info?.name,
authors = song.authors?.joinToString("") { it.name ?: "" },
durationText = song.durationText,
onClick = onClick,
menuContent = {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)
},
modifier = modifier
)
}
@Composable
fun SongItemPlaceholder(
thumbnailSizeDp: Dp, thumbnailSizeDp: Dp,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
@@ -70,27 +92,6 @@ fun SmallSongItemShimmer(
} }
} }
@ExperimentalAnimationApi
@Composable
fun SmallSongItem(
song: Innertube.SongItem,
thumbnailSizePx: Int,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
SongItem(
thumbnailModel = song.thumbnail?.size(thumbnailSizePx),
title = song.info?.name,
authors = song.authors?.joinToString("") { it.name ?: "" },
durationText = song.durationText,
onClick = onClick,
menuContent = {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)
},
modifier = modifier
)
}
@ExperimentalFoundationApi @ExperimentalFoundationApi
@ExperimentalAnimationApi @ExperimentalAnimationApi
@Composable @Composable
@@ -104,9 +105,9 @@ fun VideoItem(
val menuState = LocalMenuState.current val menuState = LocalMenuState.current
val (colorPalette, typography, thumbnailShape) = LocalAppearance.current val (colorPalette, typography, thumbnailShape) = LocalAppearance.current
Row( ItemContainer(
verticalAlignment = Alignment.CenterVertically, alternative = false,
horizontalArrangement = Arrangement.spacedBy(12.dp), thumbnailSizeDp = 0.dp,
modifier = modifier modifier = modifier
.combinedClickable( .combinedClickable(
indication = rememberRipple(bounded = true), indication = rememberRipple(bounded = true),
@@ -118,9 +119,6 @@ fun VideoItem(
}, },
onClick = onClick onClick = onClick
) )
.fillMaxWidth()
.padding(vertical = Dimensions.itemsVerticalPadding)
.padding(horizontal = 16.dp)
) { ) {
Box { Box {
AsyncImage( AsyncImage(
@@ -147,7 +145,7 @@ fun VideoItem(
} }
} }
Column { ItemInfoContainer {
BasicText( BasicText(
text = video.info?.name ?: "", text = video.info?.name ?: "",
style = typography.xs.semiBold, style = typography.xs.semiBold,
@@ -169,7 +167,7 @@ fun VideoItem(
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
modifier = Modifier modifier = Modifier
.padding(top = 8.dp) .padding(top = 4.dp)
) )
} }
} }
@@ -179,19 +177,17 @@ fun VideoItem(
@ExperimentalFoundationApi @ExperimentalFoundationApi
@ExperimentalAnimationApi @ExperimentalAnimationApi
@Composable @Composable
fun VideoItemShimmer( fun VideoItemPlaceholder(
thumbnailHeightDp: Dp, thumbnailHeightDp: Dp,
thumbnailWidthDp: Dp, thumbnailWidthDp: Dp,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val (colorPalette, _, thumbnailShape) = LocalAppearance.current val (colorPalette, _, thumbnailShape) = LocalAppearance.current
Row( ItemContainer(
verticalAlignment = Alignment.CenterVertically, alternative = false,
horizontalArrangement = Arrangement.spacedBy(12.dp), thumbnailSizeDp = 0.dp,
modifier = modifier modifier = modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = Dimensions.itemsVerticalPadding)
) { ) {
Spacer( Spacer(
modifier = Modifier modifier = Modifier
@@ -199,7 +195,7 @@ fun VideoItemShimmer(
.size(width = thumbnailWidthDp, height = thumbnailHeightDp) .size(width = thumbnailWidthDp, height = thumbnailHeightDp)
) )
Column { ItemInfoContainer {
TextPlaceholder() TextPlaceholder()
TextPlaceholder() TextPlaceholder()
TextPlaceholder( TextPlaceholder(
@@ -216,15 +212,14 @@ fun PlaylistItem(
thumbnailSizePx: Int, thumbnailSizePx: Int,
thumbnailSizeDp: Dp, thumbnailSizeDp: Dp,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
alternative: Boolean = false,
) { ) {
val (colorPalette, typography, thumbnailShape) = LocalAppearance.current val (colorPalette, typography, thumbnailShape) = LocalAppearance.current
Row( ItemContainer(
verticalAlignment = Alignment.CenterVertically, alternative = alternative,
horizontalArrangement = Arrangement.spacedBy(12.dp), thumbnailSizeDp = thumbnailSizeDp,
modifier = modifier modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.fillMaxWidth()
) { ) {
Box { Box {
AsyncImage( AsyncImage(
@@ -251,7 +246,7 @@ fun PlaylistItem(
} }
} }
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { ItemInfoContainer {
BasicText( BasicText(
text = playlist.info?.name ?: "", text = playlist.info?.name ?: "",
style = typography.xs.semiBold, style = typography.xs.semiBold,
@@ -270,18 +265,17 @@ fun PlaylistItem(
} }
@Composable @Composable
fun PlaylistItemShimmer( fun PlaylistItemPlaceholder(
thumbnailSizeDp: Dp, thumbnailSizeDp: Dp,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
alternative: Boolean = false,
) { ) {
val (colorPalette, _, thumbnailShape) = LocalAppearance.current val (colorPalette, _, thumbnailShape) = LocalAppearance.current
Row( ItemContainer(
verticalAlignment = Alignment.CenterVertically, alternative = alternative,
horizontalArrangement = Arrangement.spacedBy(12.dp), thumbnailSizeDp = thumbnailSizeDp,
modifier = modifier modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.fillMaxWidth()
) { ) {
Spacer( Spacer(
modifier = Modifier modifier = Modifier
@@ -289,7 +283,7 @@ fun PlaylistItemShimmer(
.size(thumbnailSizeDp) .size(thumbnailSizeDp)
) )
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { ItemInfoContainer {
TextPlaceholder() TextPlaceholder()
TextPlaceholder() TextPlaceholder()
} }
@@ -302,15 +296,14 @@ fun AlbumItem(
thumbnailSizePx: Int, thumbnailSizePx: Int,
thumbnailSizeDp: Dp, thumbnailSizeDp: Dp,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
alternative: Boolean = false
) { ) {
val (_, typography, thumbnailShape) = LocalAppearance.current val (_, typography, thumbnailShape) = LocalAppearance.current
Row( ItemContainer(
verticalAlignment = Alignment.CenterVertically, alternative = alternative,
horizontalArrangement = Arrangement.spacedBy(12.dp), thumbnailSizeDp = thumbnailSizeDp,
modifier = modifier modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.fillMaxWidth()
) { ) {
AsyncImage( AsyncImage(
model = album.thumbnail?.size(thumbnailSizePx), model = album.thumbnail?.size(thumbnailSizePx),
@@ -321,97 +314,22 @@ fun AlbumItem(
.size(thumbnailSizeDp) .size(thumbnailSizeDp)
) )
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { ItemInfoContainer {
BasicText( BasicText(
text = album.info?.name ?: "", text = album.info?.name ?: "",
style = typography.xs.semiBold, style = typography.xs.semiBold,
maxLines = 2, maxLines = if (alternative) 1 else 2,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) )
BasicText( if (!alternative) {
text = album.authors?.joinToString("") { it.name ?: "" } ?: "",
style = typography.xs.semiBold.secondary,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
)
album.year?.let { year ->
BasicText( BasicText(
text = year, text = album.authors?.joinToString("") { it.name ?: "" } ?: "",
style = typography.xxs.semiBold.secondary, style = typography.xs.semiBold.secondary,
maxLines = 1, maxLines = 2,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
modifier = Modifier
.padding(top = 8.dp)
) )
} }
}
}
}
@Composable
fun AlbumItemShimmer(
thumbnailSizeDp: Dp,
modifier: Modifier = Modifier,
) {
val (colorPalette, _, thumbnailShape) = LocalAppearance.current
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp),
modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.fillMaxWidth()
) {
Spacer(
modifier = Modifier
.background(color = colorPalette.shimmer, shape = thumbnailShape)
.size(thumbnailSizeDp)
)
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
TextPlaceholder()
TextPlaceholder()
TextPlaceholder(
modifier = Modifier
.padding(top = 8.dp)
)
}
}
}
@Composable
fun AlternativeAlbumItem(
album: Innertube.AlbumItem,
thumbnailSizePx: Int,
thumbnailSizeDp: Dp,
modifier: Modifier = Modifier,
) {
val (_, typography, thumbnailShape) = LocalAppearance.current
Column(
verticalArrangement = Arrangement.spacedBy(12.dp),
modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.width(thumbnailSizeDp)
) {
AsyncImage(
model = album.thumbnail?.size(thumbnailSizePx),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier
.clip(thumbnailShape)
.size(thumbnailSizeDp)
)
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
BasicText(
text = album.info?.name ?: "",
style = typography.xs.semiBold,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
BasicText( BasicText(
text = album.year ?: "", text = album.year ?: "",
@@ -419,23 +337,24 @@ fun AlternativeAlbumItem(
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
modifier = Modifier modifier = Modifier
.padding(top = 4.dp)
) )
} }
} }
} }
@Composable @Composable
fun AlternativeAlbumItemPlaceholder( fun AlbumItemPlaceholder(
thumbnailSizeDp: Dp, thumbnailSizeDp: Dp,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
alternative: Boolean = false
) { ) {
val (colorPalette, _, thumbnailShape) = LocalAppearance.current val (colorPalette, _, thumbnailShape) = LocalAppearance.current
Column( ItemContainer(
verticalArrangement = Arrangement.spacedBy(12.dp), alternative = alternative,
thumbnailSizeDp = thumbnailSizeDp,
modifier = modifier modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.width(thumbnailSizeDp)
) { ) {
Spacer( Spacer(
modifier = Modifier modifier = Modifier
@@ -443,9 +362,17 @@ fun AlternativeAlbumItemPlaceholder(
.size(thumbnailSizeDp) .size(thumbnailSizeDp)
) )
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { ItemInfoContainer {
TextPlaceholder()
TextPlaceholder() TextPlaceholder()
if (!alternative) {
TextPlaceholder()
}
TextPlaceholder(
modifier = Modifier
.padding(top = 4.dp)
)
} }
} }
} }
@@ -456,15 +383,15 @@ fun ArtistItem(
thumbnailSizePx: Int, thumbnailSizePx: Int,
thumbnailSizeDp: Dp, thumbnailSizeDp: Dp,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
alternative: Boolean = false,
) { ) {
val (_, typography) = LocalAppearance.current val (_, typography) = LocalAppearance.current
Row( ItemContainer(
verticalAlignment = Alignment.CenterVertically, alternative = alternative,
horizontalArrangement = Arrangement.spacedBy(12.dp), thumbnailSizeDp = thumbnailSizeDp,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.fillMaxWidth()
) { ) {
AsyncImage( AsyncImage(
model = artist.thumbnail?.size(thumbnailSizePx), model = artist.thumbnail?.size(thumbnailSizePx),
@@ -474,11 +401,13 @@ fun ArtistItem(
.size(thumbnailSizeDp) .size(thumbnailSizeDp)
) )
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { ItemInfoContainer(
horizontalAlignment = if (alternative) Alignment.CenterHorizontally else Alignment.Start,
) {
BasicText( BasicText(
text = artist.info?.name ?: "", text = artist.info?.name ?: "",
style = typography.xs.semiBold, style = typography.xs.semiBold,
maxLines = 2, maxLines = if (alternative) 1 else 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
@@ -497,18 +426,18 @@ fun ArtistItem(
} }
@Composable @Composable
fun ArtistItemShimmer( fun ArtistItemPlaceholder(
thumbnailSizeDp: Dp, thumbnailSizeDp: Dp,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
alternative: Boolean = false,
) { ) {
val (colorPalette) = LocalAppearance.current val (colorPalette) = LocalAppearance.current
Row( ItemContainer(
verticalAlignment = Alignment.CenterVertically, alternative = alternative,
horizontalArrangement = Arrangement.spacedBy(12.dp), thumbnailSizeDp = thumbnailSizeDp,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.fillMaxWidth()
) { ) {
Spacer( Spacer(
modifier = Modifier modifier = Modifier
@@ -516,7 +445,9 @@ fun ArtistItemShimmer(
.size(thumbnailSizeDp) .size(thumbnailSizeDp)
) )
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { ItemInfoContainer(
horizontalAlignment = if (alternative) Alignment.CenterHorizontally else Alignment.Start,
) {
TextPlaceholder() TextPlaceholder()
TextPlaceholder( TextPlaceholder(
modifier = Modifier modifier = Modifier
@@ -525,3 +456,49 @@ fun ArtistItemShimmer(
} }
} }
} }
@Composable
private inline fun ItemContainer(
alternative: Boolean,
thumbnailSizeDp: Dp,
modifier: Modifier = Modifier,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
content: @Composable () -> Unit
) {
if (alternative) {
Column(
horizontalAlignment = horizontalAlignment,
verticalArrangement = Arrangement.spacedBy(12.dp),
modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.width(thumbnailSizeDp)
) {
content()
}
} else {
Row(
verticalAlignment = verticalAlignment,
horizontalArrangement = Arrangement.spacedBy(12.dp),
modifier = modifier
.padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
.fillMaxWidth()
) {
content()
}
}
}
@Composable
private inline fun ItemInfoContainer(
modifier: Modifier = Modifier,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
content: @Composable ColumnScope.() -> Unit
) {
Column(
horizontalAlignment = horizontalAlignment,
verticalArrangement = Arrangement.spacedBy(4.dp),
modifier = modifier,
content = content
)
}

View File

@@ -57,8 +57,6 @@ object Innertube {
internal const val musicTwoRowItemRendererMask = "musicTwoRowItemRenderer(thumbnailRenderer,title,subtitle,navigationEndpoint)" internal const val musicTwoRowItemRendererMask = "musicTwoRowItemRenderer(thumbnailRenderer,title,subtitle,navigationEndpoint)"
const val playlistPanelVideoRendererMask = "playlistPanelVideoRenderer(title,navigationEndpoint,longBylineText,shortBylineText,thumbnail,lengthText)" const val playlistPanelVideoRendererMask = "playlistPanelVideoRenderer(title,navigationEndpoint,longBylineText,shortBylineText,thumbnail,lengthText)"
// contents.singleColumnBrowseResultsRenderer.tabs.tabRenderer.content.sectionListRenderer.contents(musicPlaylistShelfRenderer(continuations,contents.musicResponsiveListItemRenderer(flexColumns,fixedColumns,thumbnail)),gridRenderer(continuations,items.musicTwoRowItemRenderer(thumbnailRenderer,title,subtitle,navigationEndpoint)))
internal fun HttpRequestBuilder.mask(value: String = "*") = internal fun HttpRequestBuilder.mask(value: String = "*") =
header("X-Goog-FieldMask", value) header("X-Goog-FieldMask", value)

View File

@@ -54,7 +54,8 @@ suspend fun Innertube.relatedPage(body: NextBody) = runCatchingNonCancellable {
?.musicCarouselShelfRenderer ?.musicCarouselShelfRenderer
?.contents ?.contents
?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer) ?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer)
?.mapNotNull(Innertube.PlaylistItem::from), ?.mapNotNull(Innertube.PlaylistItem::from)
?.sortedByDescending { it.channel?.name == "YouTube Music" },
albums = sectionListRenderer albums = sectionListRenderer
?.findSectionByStrapline("MORE FROM") ?.findSectionByStrapline("MORE FROM")
?.musicCarouselShelfRenderer ?.musicCarouselShelfRenderer