Show message when ItemsPage is empty

This commit is contained in:
vfsfitvnm
2022-10-04 08:00:57 +02:00
parent c84ae199c1
commit 29168b085b
5 changed files with 43 additions and 8 deletions

View File

@@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
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.shape.CircleShape
import androidx.compose.material.ripple.rememberRipple import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@@ -38,8 +37,9 @@ import it.vfsfitvnm.vimusic.models.Album
import it.vfsfitvnm.vimusic.models.SongAlbumMap import it.vfsfitvnm.vimusic.models.SongAlbumMap
import it.vfsfitvnm.vimusic.query import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.savers.AlbumSaver import it.vfsfitvnm.vimusic.savers.AlbumSaver
import it.vfsfitvnm.vimusic.savers.InnertubeAlbumsPageSaver import it.vfsfitvnm.vimusic.savers.InnertubeAlbumItemListSaver
import it.vfsfitvnm.vimusic.savers.InnertubePlaylistOrAlbumPageSaver import it.vfsfitvnm.vimusic.savers.InnertubePlaylistOrAlbumPageSaver
import it.vfsfitvnm.vimusic.savers.innertubeItemsPageSaver
import it.vfsfitvnm.vimusic.savers.nullableSaver import it.vfsfitvnm.vimusic.savers.nullableSaver
import it.vfsfitvnm.vimusic.ui.components.themed.Header import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder
@@ -249,8 +249,11 @@ fun AlbumScreen(browseId: String) {
val thumbnailSizePx = thumbnailSizeDp.px val thumbnailSizePx = thumbnailSizeDp.px
ItemsPage( ItemsPage(
stateSaver = InnertubeAlbumsPageSaver, stateSaver = innertubeItemsPageSaver(InnertubeAlbumItemListSaver),
headerContent = headerContent, headerContent = headerContent,
initialPlaceholderCount = 1,
continuationPlaceholderCount = 1,
emptyItemsText = "This album doesn't have any alternative version",
itemsPageProvider = innertubeAlbum?.let { itemsPageProvider = innertubeAlbum?.let {
({ ({
Result.success( Result.success(

View File

@@ -304,6 +304,7 @@ fun ArtistScreen(browseId: String) {
ItemsPage( ItemsPage(
stateSaver = InnertubeAlbumsPageSaver, stateSaver = InnertubeAlbumsPageSaver,
headerContent = headerContent, headerContent = headerContent,
emptyItemsText = "This artist didn't release any album",
itemsPageProvider = youtubeArtist?.let {({ continuation -> itemsPageProvider = youtubeArtist?.let {({ continuation ->
continuation?.let { continuation?.let {
Innertube.itemsPage( Innertube.itemsPage(
@@ -355,6 +356,7 @@ fun ArtistScreen(browseId: String) {
ItemsPage( ItemsPage(
stateSaver = InnertubeAlbumsPageSaver, stateSaver = InnertubeAlbumsPageSaver,
headerContent = headerContent, headerContent = headerContent,
emptyItemsText = "This artist didn't release any single",
itemsPageProvider = youtubeArtist?.let {({ continuation -> itemsPageProvider = youtubeArtist?.let {({ continuation ->
continuation?.let { continuation?.let {
Innertube.itemsPage( Innertube.itemsPage(

View File

@@ -11,7 +11,6 @@ import androidx.compose.foundation.lazy.itemsIndexed
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 it.vfsfitvnm.reordering.animateItemPlacement
import it.vfsfitvnm.vimusic.Database import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder

View File

@@ -2,20 +2,27 @@ package it.vfsfitvnm.vimusic.ui.screens.searchresult
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.saveable.Saver import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.snapshotFlow import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
import it.vfsfitvnm.vimusic.savers.nullableSaver import it.vfsfitvnm.vimusic.savers.nullableSaver
import it.vfsfitvnm.vimusic.ui.components.themed.ShimmerHost import it.vfsfitvnm.vimusic.ui.components.themed.ShimmerHost
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.produceSaveableState import it.vfsfitvnm.vimusic.utils.produceSaveableState
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.youtubemusic.Innertube import it.vfsfitvnm.youtubemusic.Innertube
import it.vfsfitvnm.youtubemusic.utils.plus import it.vfsfitvnm.youtubemusic.utils.plus
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -25,11 +32,16 @@ import kotlinx.coroutines.withContext
@Composable @Composable
inline fun <T : Innertube.Item> ItemsPage( inline fun <T : Innertube.Item> ItemsPage(
stateSaver: Saver<Innertube.ItemsPage<T>, List<Any?>>, stateSaver: Saver<Innertube.ItemsPage<T>, List<Any?>>,
noinline itemsPageProvider: (suspend (String?) -> Result<Innertube.ItemsPage<T>?>?)? = null,
crossinline headerContent: @Composable (textButton: (@Composable () -> Unit)?) -> Unit, crossinline headerContent: @Composable (textButton: (@Composable () -> Unit)?) -> Unit,
crossinline itemContent: @Composable LazyItemScope.(T) -> Unit, crossinline itemContent: @Composable LazyItemScope.(T) -> Unit,
noinline itemPlaceholderContent: @Composable () -> Unit, noinline itemPlaceholderContent: @Composable () -> Unit,
modifier: Modifier = Modifier,
initialPlaceholderCount: Int = 8,
continuationPlaceholderCount: Int = 3,
emptyItemsText: String = "No items found",
noinline itemsPageProvider: (suspend (String?) -> Result<Innertube.ItemsPage<T>?>?)? = null,
) { ) {
val (_, typography) = LocalAppearance.current
val lazyListState = rememberLazyListState() val lazyListState = rememberLazyListState()
val updatedItemsPageProvider by rememberUpdatedState(itemsPageProvider) val updatedItemsPageProvider by rememberUpdatedState(itemsPageProvider)
@@ -61,12 +73,12 @@ inline fun <T : Innertube.Item> ItemsPage(
LazyColumn( LazyColumn(
state = lazyListState, state = lazyListState,
contentPadding = LocalPlayerAwarePaddingValues.current, contentPadding = LocalPlayerAwarePaddingValues.current,
modifier = Modifier modifier = modifier
.fillMaxSize() .fillMaxSize()
) { ) {
item( item(
key = "header", key = "header",
contentType = 0, contentType = "header",
) { ) {
headerContent(null) headerContent(null)
} }
@@ -77,10 +89,22 @@ inline fun <T : Innertube.Item> ItemsPage(
itemContent = itemContent itemContent = itemContent
) )
if (itemsPage != null && itemsPage?.items.isNullOrEmpty()) {
item(key = "empty") {
BasicText(
text = emptyItemsText,
style = typography.xs.secondary.center,
modifier = Modifier
.padding(horizontal = 16.dp, vertical = 32.dp)
.fillMaxWidth()
)
}
}
if (!(itemsPage != null && itemsPage?.continuation == null)) { if (!(itemsPage != null && itemsPage?.continuation == null)) {
item(key = "loading") { item(key = "loading") {
ShimmerHost { ShimmerHost {
repeat(if (itemsPage?.items.isNullOrEmpty()) 8 else 3) { repeat(if (itemsPage?.items.isNullOrEmpty()) initialPlaceholderCount else continuationPlaceholderCount) {
itemPlaceholderContent() itemPlaceholderContent()
} }
} }

View File

@@ -72,6 +72,8 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
) )
} }
val emptyItemsText = "No results found. Please try a different query or category"
Scaffold( Scaffold(
topIconButtonId = R.drawable.chevron_back, topIconButtonId = R.drawable.chevron_back,
onTopIconButtonClick = pop, onTopIconButtonClick = pop,
@@ -108,6 +110,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
) )
} }
}, },
emptyItemsText = emptyItemsText,
headerContent = headerContent, headerContent = headerContent,
itemContent = { song -> itemContent = { song ->
SongItem( SongItem(
@@ -145,6 +148,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
) )
} }
}, },
emptyItemsText = emptyItemsText,
headerContent = headerContent, headerContent = headerContent,
itemContent = { album -> itemContent = { album ->
AlbumItem( AlbumItem(
@@ -185,6 +189,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
) )
} }
}, },
emptyItemsText = emptyItemsText,
headerContent = headerContent, headerContent = headerContent,
itemContent = { artist -> itemContent = { artist ->
ArtistItem( ArtistItem(
@@ -224,6 +229,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
) )
} }
}, },
emptyItemsText = emptyItemsText,
headerContent = headerContent, headerContent = headerContent,
itemContent = { video -> itemContent = { video ->
VideoItem( VideoItem(
@@ -271,6 +277,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
) )
} }
}, },
emptyItemsText = emptyItemsText,
headerContent = headerContent, headerContent = headerContent,
itemContent = { playlist -> itemContent = { playlist ->
PlaylistItem( PlaylistItem(