Show message when ItemsPage is empty
This commit is contained in:
@@ -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(
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user