Attempt fix #401
This commit is contained in:
@@ -17,17 +17,17 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.valentinilk.shimmer.shimmer
|
||||
import it.vfsfitvnm.compose.persist.PersistMapCleanup
|
||||
import it.vfsfitvnm.compose.persist.persist
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.BrowseBody
|
||||
import it.vfsfitvnm.innertube.requests.albumPage
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.models.Album
|
||||
import it.vfsfitvnm.vimusic.models.SongAlbumMap
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
import it.vfsfitvnm.vimusic.savers.AlbumSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubeAlbumItemListSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubePlaylistOrAlbumPageSaver
|
||||
import it.vfsfitvnm.vimusic.savers.innertubeItemsPageSaver
|
||||
import it.vfsfitvnm.vimusic.savers.nullableSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder
|
||||
@@ -41,9 +41,6 @@ import it.vfsfitvnm.vimusic.ui.screens.searchresult.ItemsPage
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.ui.styling.px
|
||||
import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.BrowseBody
|
||||
import it.vfsfitvnm.innertube.requests.albumPage
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -58,13 +55,10 @@ fun AlbumScreen(browseId: String) {
|
||||
mutableStateOf(0)
|
||||
}
|
||||
|
||||
var album by rememberSaveable(stateSaver = nullableSaver(AlbumSaver)) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
var album by persist<Album?>("album/$browseId/album")
|
||||
var albumPage by persist<Innertube.PlaylistOrAlbumPage?>("album/$browseId/albumPage")
|
||||
|
||||
var albumPage by rememberSaveable(stateSaver = nullableSaver(InnertubePlaylistOrAlbumPageSaver)) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
PersistMapCleanup(tagPrefix = "album/$browseId/")
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
Database
|
||||
@@ -205,7 +199,7 @@ fun AlbumScreen(browseId: String) {
|
||||
val thumbnailSizePx = thumbnailSizeDp.px
|
||||
|
||||
ItemsPage(
|
||||
stateSaver = innertubeItemsPageSaver(InnertubeAlbumItemListSaver),
|
||||
tag = "album/$browseId/alternatives",
|
||||
headerContent = headerContent,
|
||||
initialPlaceholderCount = 1,
|
||||
continuationPlaceholderCount = 1,
|
||||
|
||||
@@ -6,26 +6,28 @@ import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.text.BasicText
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import it.vfsfitvnm.compose.persist.persistList
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
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.R
|
||||
import it.vfsfitvnm.vimusic.models.DetailedSong
|
||||
import it.vfsfitvnm.vimusic.savers.DetailedSongListSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.ShimmerHost
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
@@ -43,10 +45,7 @@ import it.vfsfitvnm.vimusic.utils.enqueue
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning
|
||||
import it.vfsfitvnm.vimusic.utils.isLandscape
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@ExperimentalFoundationApi
|
||||
@@ -60,14 +59,10 @@ fun AlbumSongs(
|
||||
val binder = LocalPlayerServiceBinder.current
|
||||
val menuState = LocalMenuState.current
|
||||
|
||||
val songs by produceSaveableState(
|
||||
initialValue = emptyList(),
|
||||
stateSaver = DetailedSongListSaver
|
||||
) {
|
||||
Database
|
||||
.albumSongs(browseId)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.collect { value = it }
|
||||
var songs by persistList<DetailedSong>("album/$browseId/songs")
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
Database.albumSongs(browseId).collect { songs = it }
|
||||
}
|
||||
|
||||
val thumbnailSizeDp = Dimensions.thumbnails.song
|
||||
|
||||
@@ -6,24 +6,25 @@ import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import it.vfsfitvnm.compose.persist.persist
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.ui.Alignment
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.models.DetailedSong
|
||||
import it.vfsfitvnm.vimusic.savers.DetailedSongListSaver
|
||||
import it.vfsfitvnm.vimusic.savers.nullableSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.ShimmerHost
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
@@ -39,9 +40,6 @@ import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
import it.vfsfitvnm.vimusic.utils.enqueue
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
@ExperimentalAnimationApi
|
||||
@@ -55,14 +53,10 @@ fun ArtistLocalSongs(
|
||||
val (colorPalette) = LocalAppearance.current
|
||||
val menuState = LocalMenuState.current
|
||||
|
||||
val songs by produceSaveableState(
|
||||
initialValue = null,
|
||||
stateSaver = nullableSaver(DetailedSongListSaver)
|
||||
) {
|
||||
Database
|
||||
.artistSongs(browseId)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.collect { value = it }
|
||||
var songs by persist<List<DetailedSong>?>("artist/$browseId/localSongs")
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
Database.artistSongs(browseId).collect { songs = it }
|
||||
}
|
||||
|
||||
val songThumbnailSizeDp = Dimensions.thumbnails.song
|
||||
|
||||
@@ -26,6 +26,8 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.NavigationEndpoint
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
@@ -49,8 +51,6 @@ import it.vfsfitvnm.vimusic.utils.color
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlay
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.NavigationEndpoint
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
@ExperimentalAnimationApi
|
||||
|
||||
@@ -10,8 +10,6 @@ import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
@@ -19,17 +17,20 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.valentinilk.shimmer.shimmer
|
||||
import it.vfsfitvnm.compose.persist.PersistMapCleanup
|
||||
import it.vfsfitvnm.compose.persist.persist
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.BrowseBody
|
||||
import it.vfsfitvnm.innertube.models.bodies.ContinuationBody
|
||||
import it.vfsfitvnm.innertube.requests.artistPage
|
||||
import it.vfsfitvnm.innertube.requests.itemsPage
|
||||
import it.vfsfitvnm.innertube.utils.from
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.models.Artist
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
import it.vfsfitvnm.vimusic.savers.ArtistSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubeAlbumsPageSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubeArtistPageSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubeSongsPageSaver
|
||||
import it.vfsfitvnm.vimusic.savers.nullableSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
|
||||
@@ -51,12 +52,6 @@ import it.vfsfitvnm.vimusic.utils.artistScreenTabIndexKey
|
||||
import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlay
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.BrowseBody
|
||||
import it.vfsfitvnm.innertube.models.bodies.ContinuationBody
|
||||
import it.vfsfitvnm.innertube.requests.artistPage
|
||||
import it.vfsfitvnm.innertube.requests.itemsPage
|
||||
import it.vfsfitvnm.innertube.utils.from
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
@@ -71,13 +66,11 @@ fun ArtistScreen(browseId: String) {
|
||||
|
||||
var tabIndex by rememberPreference(artistScreenTabIndexKey, defaultValue = 0)
|
||||
|
||||
var artist by rememberSaveable(stateSaver = nullableSaver(ArtistSaver)) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
PersistMapCleanup(tagPrefix = "artist/$browseId/")
|
||||
|
||||
var artistPage by rememberSaveable(stateSaver = nullableSaver(InnertubeArtistPageSaver)) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
var artist by persist<Artist?>("artist/$browseId/artist")
|
||||
|
||||
var artistPage by persist<Innertube.ArtistPage?>("artist/$browseId/artistPage")
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
Database
|
||||
@@ -209,7 +202,7 @@ fun ArtistScreen(browseId: String) {
|
||||
val thumbnailSizePx = thumbnailSizeDp.px
|
||||
|
||||
ItemsPage(
|
||||
stateSaver = InnertubeSongsPageSaver,
|
||||
tag = "artist/$browseId/songs",
|
||||
headerContent = headerContent,
|
||||
itemsPageProvider = artistPage?.let {
|
||||
({ continuation ->
|
||||
@@ -272,7 +265,7 @@ fun ArtistScreen(browseId: String) {
|
||||
val thumbnailSizePx = thumbnailSizeDp.px
|
||||
|
||||
ItemsPage(
|
||||
stateSaver = InnertubeAlbumsPageSaver,
|
||||
tag = "artist/$browseId/albums",
|
||||
headerContent = headerContent,
|
||||
emptyItemsText = "This artist didn't release any album",
|
||||
itemsPageProvider = artistPage?.let {
|
||||
@@ -322,7 +315,7 @@ fun ArtistScreen(browseId: String) {
|
||||
val thumbnailSizePx = thumbnailSizeDp.px
|
||||
|
||||
ItemsPage(
|
||||
stateSaver = InnertubeAlbumsPageSaver,
|
||||
tag = "artist/$browseId/singles",
|
||||
headerContent = headerContent,
|
||||
emptyItemsText = "This artist didn't release any single",
|
||||
itemsPageProvider = artistPage?.let {
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||
import it.vfsfitvnm.compose.persist.PersistMapCleanup
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.enums.BuiltInPlaylist
|
||||
@@ -25,6 +26,8 @@ fun BuiltInPlaylistScreen(builtInPlaylist: BuiltInPlaylist) {
|
||||
})
|
||||
}
|
||||
|
||||
PersistMapCleanup(tagPrefix = "${builtInPlaylist.name}/")
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
globalRoutes()
|
||||
|
||||
|
||||
@@ -15,16 +15,18 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.compose.persist.persistList
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.enums.BuiltInPlaylist
|
||||
import it.vfsfitvnm.vimusic.models.DetailedSong
|
||||
import it.vfsfitvnm.vimusic.savers.DetailedSongListSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
@@ -39,7 +41,6 @@ import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
import it.vfsfitvnm.vimusic.utils.enqueue
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
@@ -52,25 +53,24 @@ fun BuiltInPlaylistSongs(builtInPlaylist: BuiltInPlaylist) {
|
||||
val binder = LocalPlayerServiceBinder.current
|
||||
val menuState = LocalMenuState.current
|
||||
|
||||
val songs by produceSaveableState(
|
||||
initialValue = emptyList(),
|
||||
stateSaver = DetailedSongListSaver
|
||||
) {
|
||||
var songs by persistList<DetailedSong>("${builtInPlaylist.name}/songs")
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
when (builtInPlaylist) {
|
||||
BuiltInPlaylist.Favorites -> Database
|
||||
.favorites()
|
||||
.flowOn(Dispatchers.IO)
|
||||
|
||||
BuiltInPlaylist.Offline -> Database
|
||||
.songsWithContentLength()
|
||||
.flowOn(Dispatchers.IO)
|
||||
.map { songs ->
|
||||
songs.filter { song ->
|
||||
song.contentLength?.let {
|
||||
binder?.cache?.isCached(song.id, 0, song.contentLength)
|
||||
} ?: false
|
||||
songs.filter { song ->
|
||||
song.contentLength?.let {
|
||||
binder?.cache?.isCached(song.id, 0, song.contentLength)
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}.collect { value = it }
|
||||
}.collect { songs = it }
|
||||
}
|
||||
|
||||
val thumbnailSizeDp = Dimensions.thumbnails.song
|
||||
|
||||
@@ -15,21 +15,24 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.compose.persist.persist
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.enums.AlbumSortBy
|
||||
import it.vfsfitvnm.vimusic.enums.SortOrder
|
||||
import it.vfsfitvnm.vimusic.models.Album
|
||||
import it.vfsfitvnm.vimusic.savers.AlbumListSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
|
||||
@@ -39,10 +42,7 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.ui.styling.px
|
||||
import it.vfsfitvnm.vimusic.utils.albumSortByKey
|
||||
import it.vfsfitvnm.vimusic.utils.albumSortOrderKey
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
@ExperimentalAnimationApi
|
||||
@@ -56,15 +56,10 @@ fun HomeAlbums(
|
||||
var sortBy by rememberPreference(albumSortByKey, AlbumSortBy.DateAdded)
|
||||
var sortOrder by rememberPreference(albumSortOrderKey, SortOrder.Descending)
|
||||
|
||||
val items by produceSaveableState(
|
||||
initialValue = emptyList(),
|
||||
stateSaver = AlbumListSaver,
|
||||
sortBy, sortOrder,
|
||||
) {
|
||||
Database
|
||||
.albums(sortBy, sortOrder)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.collect { value = it }
|
||||
var items by persist<List<Album>>(tag = "home/albums", emptyList())
|
||||
|
||||
LaunchedEffect(sortBy, sortOrder) {
|
||||
Database.albums(sortBy, sortOrder).collect { items = it }
|
||||
}
|
||||
|
||||
val thumbnailSizeDp = Dimensions.thumbnails.song * 2
|
||||
|
||||
@@ -10,7 +10,10 @@ import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
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.only
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||
@@ -18,22 +21,20 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.compose.persist.persistList
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
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.R
|
||||
import it.vfsfitvnm.vimusic.enums.ArtistSortBy
|
||||
import it.vfsfitvnm.vimusic.enums.SortOrder
|
||||
import it.vfsfitvnm.vimusic.models.Artist
|
||||
import it.vfsfitvnm.vimusic.savers.ArtistListSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
|
||||
@@ -43,10 +44,7 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.ui.styling.px
|
||||
import it.vfsfitvnm.vimusic.utils.artistSortByKey
|
||||
import it.vfsfitvnm.vimusic.utils.artistSortOrderKey
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
@ExperimentalAnimationApi
|
||||
@@ -60,15 +58,10 @@ fun HomeArtistList(
|
||||
var sortBy by rememberPreference(artistSortByKey, ArtistSortBy.DateAdded)
|
||||
var sortOrder by rememberPreference(artistSortOrderKey, SortOrder.Descending)
|
||||
|
||||
val items by produceSaveableState(
|
||||
initialValue = emptyList(),
|
||||
stateSaver = ArtistListSaver,
|
||||
sortBy, sortOrder,
|
||||
) {
|
||||
Database
|
||||
.artists(sortBy, sortOrder)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.collect { value = it }
|
||||
var items by persistList<Artist>("home/artists")
|
||||
|
||||
LaunchedEffect(sortBy, sortOrder) {
|
||||
Database.artists(sortBy, sortOrder).collect { items = it }
|
||||
}
|
||||
|
||||
val thumbnailSizeDp = Dimensions.thumbnails.song * 2
|
||||
|
||||
@@ -21,6 +21,7 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
@@ -29,6 +30,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.compose.persist.persistList
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
@@ -36,8 +38,8 @@ import it.vfsfitvnm.vimusic.enums.BuiltInPlaylist
|
||||
import it.vfsfitvnm.vimusic.enums.PlaylistSortBy
|
||||
import it.vfsfitvnm.vimusic.enums.SortOrder
|
||||
import it.vfsfitvnm.vimusic.models.Playlist
|
||||
import it.vfsfitvnm.vimusic.models.PlaylistPreview
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
import it.vfsfitvnm.vimusic.savers.PlaylistPreviewListSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
|
||||
@@ -49,10 +51,7 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.ui.styling.px
|
||||
import it.vfsfitvnm.vimusic.utils.playlistSortByKey
|
||||
import it.vfsfitvnm.vimusic.utils.playlistSortOrderKey
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@ExperimentalFoundationApi
|
||||
@@ -85,15 +84,10 @@ fun HomePlaylists(
|
||||
var sortBy by rememberPreference(playlistSortByKey, PlaylistSortBy.DateAdded)
|
||||
var sortOrder by rememberPreference(playlistSortOrderKey, SortOrder.Descending)
|
||||
|
||||
val items by produceSaveableState(
|
||||
initialValue = emptyList(),
|
||||
stateSaver = PlaylistPreviewListSaver,
|
||||
sortBy, sortOrder,
|
||||
) {
|
||||
Database
|
||||
.playlistPreviews(sortBy, sortOrder)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.collect { value = it }
|
||||
var items by persistList<PlaylistPreview>("home/playlists")
|
||||
|
||||
LaunchedEffect(sortBy, sortOrder) {
|
||||
Database.playlistPreviews(sortBy, sortOrder).collect { items = it }
|
||||
}
|
||||
|
||||
val sortOrderIconRotation by animateFloatAsState(
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import it.vfsfitvnm.compose.persist.PersistMapCleanup
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.route.defaultStacking
|
||||
import it.vfsfitvnm.route.defaultStill
|
||||
@@ -42,6 +43,8 @@ import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
fun HomeScreen(onPlaylistUrl: (String) -> Unit) {
|
||||
val saveableStateHolder = rememberSaveableStateHolder()
|
||||
|
||||
PersistMapCleanup("home/")
|
||||
|
||||
RouteHandler(
|
||||
listenToGlobalEmitter = true,
|
||||
transitionSpec = {
|
||||
|
||||
@@ -21,6 +21,7 @@ import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.text.BasicText
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -30,6 +31,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.compose.persist.persistList
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
@@ -37,7 +39,6 @@ import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.enums.SongSortBy
|
||||
import it.vfsfitvnm.vimusic.enums.SortOrder
|
||||
import it.vfsfitvnm.vimusic.models.DetailedSong
|
||||
import it.vfsfitvnm.vimusic.savers.DetailedSongListSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
@@ -53,13 +54,10 @@ import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
import it.vfsfitvnm.vimusic.utils.center
|
||||
import it.vfsfitvnm.vimusic.utils.color
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||
import it.vfsfitvnm.vimusic.utils.songSortByKey
|
||||
import it.vfsfitvnm.vimusic.utils.songSortOrderKey
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
@ExperimentalAnimationApi
|
||||
@@ -77,15 +75,10 @@ fun HomeSongs(
|
||||
var sortBy by rememberPreference(songSortByKey, SongSortBy.DateAdded)
|
||||
var sortOrder by rememberPreference(songSortOrderKey, SortOrder.Descending)
|
||||
|
||||
val items by produceSaveableState(
|
||||
initialValue = emptyList(),
|
||||
stateSaver = DetailedSongListSaver,
|
||||
sortBy, sortOrder,
|
||||
) {
|
||||
Database
|
||||
.songs(sortBy, sortOrder)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.collect { value = it }
|
||||
var items by persistList<DetailedSong>("home/songs")
|
||||
|
||||
LaunchedEffect(sortBy, sortOrder) {
|
||||
Database.songs(sortBy, sortOrder).collect { items = it }
|
||||
}
|
||||
|
||||
val sortOrderIconRotation by animateFloatAsState(
|
||||
|
||||
@@ -31,24 +31,24 @@ import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.compose.persist.persist
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.NavigationEndpoint
|
||||
import it.vfsfitvnm.innertube.models.bodies.NextBody
|
||||
import it.vfsfitvnm.innertube.requests.relatedPage
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.models.DetailedSong
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
import it.vfsfitvnm.vimusic.savers.DetailedSongSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubeRelatedPageSaver
|
||||
import it.vfsfitvnm.vimusic.savers.nullableSaver
|
||||
import it.vfsfitvnm.vimusic.savers.resultSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.ShimmerHost
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
@@ -70,16 +70,10 @@ import it.vfsfitvnm.vimusic.utils.SnapLayoutInfoProvider
|
||||
import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
import it.vfsfitvnm.vimusic.utils.center
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlay
|
||||
import it.vfsfitvnm.vimusic.utils.isLandscape
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.NavigationEndpoint
|
||||
import it.vfsfitvnm.innertube.models.bodies.NextBody
|
||||
import it.vfsfitvnm.innertube.requests.relatedPage
|
||||
import it.vfsfitvnm.vimusic.utils.isLandscape
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
@ExperimentalAnimationApi
|
||||
@@ -95,25 +89,18 @@ fun QuickPicks(
|
||||
val menuState = LocalMenuState.current
|
||||
val windowInsets = LocalPlayerAwareWindowInsets.current
|
||||
|
||||
var trending by rememberSaveable(stateSaver = nullableSaver(DetailedSongSaver)) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
var trending by persist<DetailedSong?>("home/trending")
|
||||
|
||||
var relatedPageResult by rememberSaveable(stateSaver = resultSaver(nullableSaver(InnertubeRelatedPageSaver))) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
var relatedPageResult by persist<Result<Innertube.RelatedPage?>?>(tag = "home/relatedPageResult")
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
Database.trending()
|
||||
.flowOn(Dispatchers.IO)
|
||||
.distinctUntilChanged()
|
||||
.collect { song ->
|
||||
if ((song == null && relatedPageResult == null) || trending?.id != song?.id) {
|
||||
relatedPageResult =
|
||||
Innertube.relatedPage(NextBody(videoId = (song?.id ?: "J7p4bzqLvCw")))
|
||||
}
|
||||
trending = song
|
||||
Database.trending().distinctUntilChanged().collect { song ->
|
||||
if ((song == null && relatedPageResult == null) || trending?.id != song?.id) {
|
||||
relatedPageResult =
|
||||
Innertube.relatedPage(NextBody(videoId = (song?.id ?: "J7p4bzqLvCw")))
|
||||
}
|
||||
trending = song
|
||||
}
|
||||
}
|
||||
|
||||
val songThumbnailSizeDp = Dimensions.thumbnails.song
|
||||
|
||||
@@ -4,6 +4,7 @@ import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||
import it.vfsfitvnm.compose.persist.PersistMapCleanup
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Scaffold
|
||||
@@ -15,6 +16,8 @@ import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
|
||||
fun LocalPlaylistScreen(playlistId: Long) {
|
||||
val saveableStateHolder = rememberSaveableStateHolder()
|
||||
|
||||
PersistMapCleanup(tagPrefix = "localPlaylist/$playlistId/")
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
globalRoutes()
|
||||
|
||||
@@ -28,11 +31,13 @@ fun LocalPlaylistScreen(playlistId: Long) {
|
||||
Item(0, "Songs", R.drawable.musical_notes)
|
||||
}
|
||||
) { currentTabIndex ->
|
||||
saveableStateHolder.SaveableStateProvider(key = currentTabIndex) {
|
||||
LocalPlaylistSongs(
|
||||
playlistId = playlistId,
|
||||
onDelete = pop
|
||||
)
|
||||
saveableStateHolder.SaveableStateProvider(currentTabIndex) {
|
||||
when (currentTabIndex) {
|
||||
0 -> LocalPlaylistSongs(
|
||||
playlistId = playlistId,
|
||||
onDelete = pop
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,17 @@ import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.compose.persist.persist
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.BrowseBody
|
||||
import it.vfsfitvnm.innertube.requests.playlistPage
|
||||
import it.vfsfitvnm.reordering.ReorderingLazyColumn
|
||||
import it.vfsfitvnm.reordering.animateItemPlacement
|
||||
import it.vfsfitvnm.reordering.draggedItem
|
||||
@@ -32,10 +37,9 @@ import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.models.DetailedSong
|
||||
import it.vfsfitvnm.vimusic.models.PlaylistWithSongs
|
||||
import it.vfsfitvnm.vimusic.models.SongPlaylistMap
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
import it.vfsfitvnm.vimusic.savers.PlaylistWithSongsSaver
|
||||
import it.vfsfitvnm.vimusic.savers.nullableSaver
|
||||
import it.vfsfitvnm.vimusic.transaction
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog
|
||||
@@ -57,10 +61,6 @@ import it.vfsfitvnm.vimusic.utils.completed
|
||||
import it.vfsfitvnm.vimusic.utils.enqueue
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.BrowseBody
|
||||
import it.vfsfitvnm.innertube.requests.playlistPage
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@@ -77,14 +77,10 @@ fun LocalPlaylistSongs(
|
||||
val binder = LocalPlayerServiceBinder.current
|
||||
val menuState = LocalMenuState.current
|
||||
|
||||
val playlistWithSongs by produceSaveableState(
|
||||
initialValue = null,
|
||||
stateSaver = nullableSaver(PlaylistWithSongsSaver)
|
||||
) {
|
||||
Database
|
||||
.playlistWithSongs(playlistId)
|
||||
.filterNotNull()
|
||||
.collect { value = it }
|
||||
var playlistWithSongs by persist<PlaylistWithSongs?>("localPlaylist/$playlistId/playlistWithSongs")
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
Database.playlistWithSongs(playlistId).filterNotNull().collect { playlistWithSongs = it }
|
||||
}
|
||||
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
@@ -52,9 +52,7 @@ import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||
import it.vfsfitvnm.vimusic.utils.trackLoopEnabledKey
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@Composable
|
||||
fun Controls(
|
||||
@@ -82,11 +80,7 @@ fun Controls(
|
||||
}
|
||||
|
||||
LaunchedEffect(mediaId) {
|
||||
Database
|
||||
.likedAt(mediaId)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.distinctUntilChanged()
|
||||
.collect { likedAt = it }
|
||||
Database.likedAt(mediaId).distinctUntilChanged().collect { likedAt = it }
|
||||
}
|
||||
|
||||
val shouldBePlayingTransition = updateTransition(shouldBePlaying, label = "shouldBePlaying")
|
||||
|
||||
@@ -32,7 +32,7 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.autoSaver
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -70,14 +70,12 @@ import it.vfsfitvnm.vimusic.utils.center
|
||||
import it.vfsfitvnm.vimusic.utils.color
|
||||
import it.vfsfitvnm.vimusic.utils.isShowingSynchronizedLyricsKey
|
||||
import it.vfsfitvnm.vimusic.utils.medium
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import it.vfsfitvnm.vimusic.utils.toast
|
||||
import it.vfsfitvnm.vimusic.utils.verticalFadingEdge
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -108,19 +106,16 @@ fun Lyrics(
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
val lyrics by produceSaveableState(
|
||||
initialValue = ".",
|
||||
stateSaver = autoSaver<String?>(),
|
||||
mediaId, isShowingSynchronizedLyrics
|
||||
) {
|
||||
var lyrics by rememberSaveable {
|
||||
mutableStateOf<String?>(".")
|
||||
}
|
||||
|
||||
LaunchedEffect(mediaId, isShowingSynchronizedLyrics) {
|
||||
if (isShowingSynchronizedLyrics) {
|
||||
Database.synchronizedLyrics(mediaId)
|
||||
} else {
|
||||
Database.lyrics(mediaId)
|
||||
}
|
||||
.flowOn(Dispatchers.IO)
|
||||
.distinctUntilChanged()
|
||||
.collect { value = it }
|
||||
}.distinctUntilChanged().collect { lyrics = it }
|
||||
}
|
||||
|
||||
var isError by remember(lyrics) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||
import it.vfsfitvnm.compose.persist.PersistMapCleanup
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Scaffold
|
||||
@@ -14,6 +15,7 @@ import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
|
||||
@Composable
|
||||
fun PlaylistScreen(browseId: String) {
|
||||
val saveableStateHolder = rememberSaveableStateHolder()
|
||||
PersistMapCleanup(tagPrefix = "playlist/$browseId")
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
globalRoutes()
|
||||
|
||||
@@ -8,11 +8,15 @@ import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
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.only
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
@@ -21,18 +25,17 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.valentinilk.shimmer.shimmer
|
||||
import it.vfsfitvnm.compose.persist.persist
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.BrowseBody
|
||||
import it.vfsfitvnm.innertube.requests.playlistPage
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
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.R
|
||||
import it.vfsfitvnm.vimusic.models.Playlist
|
||||
import it.vfsfitvnm.vimusic.models.SongPlaylistMap
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubePlaylistOrAlbumPageSaver
|
||||
import it.vfsfitvnm.vimusic.savers.nullableSaver
|
||||
import it.vfsfitvnm.vimusic.transaction
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.ShimmerHost
|
||||
@@ -56,10 +59,6 @@ import it.vfsfitvnm.vimusic.utils.enqueue
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlayFromBeginning
|
||||
import it.vfsfitvnm.vimusic.utils.isLandscape
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.BrowseBody
|
||||
import it.vfsfitvnm.innertube.requests.playlistPage
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -74,13 +73,12 @@ fun PlaylistSongList(
|
||||
val context = LocalContext.current
|
||||
val menuState = LocalMenuState.current
|
||||
|
||||
val playlistPage by produceSaveableState(
|
||||
initialValue = null,
|
||||
stateSaver = nullableSaver(InnertubePlaylistOrAlbumPageSaver),
|
||||
) {
|
||||
if (value != null && value?.songsPage?.continuation == null) return@produceSaveableState
|
||||
var playlistPage by persist<Innertube.PlaylistOrAlbumPage?>("playlist/$browseId/playlistPage")
|
||||
|
||||
value = withContext(Dispatchers.IO) {
|
||||
LaunchedEffect(Unit) {
|
||||
if (playlistPage != null && playlistPage?.songsPage?.continuation == null) return@LaunchedEffect
|
||||
|
||||
playlistPage = withContext(Dispatchers.IO) {
|
||||
Innertube.playlistPage(BrowseBody(browseId = browseId))?.completed()?.getOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,27 +4,30 @@ import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import it.vfsfitvnm.compose.persist.persistList
|
||||
import it.vfsfitvnm.innertube.models.NavigationEndpoint
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
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.models.DetailedSong
|
||||
import it.vfsfitvnm.vimusic.savers.DetailedSongListSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
@@ -38,10 +41,6 @@ import it.vfsfitvnm.vimusic.utils.align
|
||||
import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlay
|
||||
import it.vfsfitvnm.vimusic.utils.medium
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.innertube.models.NavigationEndpoint
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
@ExperimentalAnimationApi
|
||||
@@ -55,16 +54,11 @@ fun LocalSongSearch(
|
||||
val binder = LocalPlayerServiceBinder.current
|
||||
val menuState = LocalMenuState.current
|
||||
|
||||
val items by produceSaveableState(
|
||||
initialValue = emptyList(),
|
||||
stateSaver = DetailedSongListSaver,
|
||||
key1 = textFieldValue.text
|
||||
) {
|
||||
var items by persistList<DetailedSong>("search/local/songs")
|
||||
|
||||
LaunchedEffect(textFieldValue.text) {
|
||||
if (textFieldValue.text.length > 1) {
|
||||
Database
|
||||
.search("%${textFieldValue.text}%")
|
||||
.flowOn(Dispatchers.IO)
|
||||
.collect { value = it }
|
||||
Database.search("%${textFieldValue.text}%").collect { items = it }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,7 @@ import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.autoSaver
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -46,14 +43,16 @@ import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.net.toUri
|
||||
import it.vfsfitvnm.compose.persist.persist
|
||||
import it.vfsfitvnm.compose.persist.persistList
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.SearchSuggestionsBody
|
||||
import it.vfsfitvnm.innertube.requests.searchSuggestions
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.models.SearchQuery
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
import it.vfsfitvnm.vimusic.savers.SearchQuerySaver
|
||||
import it.vfsfitvnm.vimusic.savers.listSaver
|
||||
import it.vfsfitvnm.vimusic.savers.resultSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.SecondaryTextButton
|
||||
@@ -61,17 +60,11 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.align
|
||||
import it.vfsfitvnm.vimusic.utils.center
|
||||
import it.vfsfitvnm.vimusic.utils.medium
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.SearchSuggestionsBody
|
||||
import it.vfsfitvnm.innertube.requests.searchSuggestions
|
||||
import it.vfsfitvnm.vimusic.utils.pauseSearchHistoryKey
|
||||
import it.vfsfitvnm.vimusic.utils.preferences
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
@@ -86,22 +79,17 @@ fun OnlineSearch(
|
||||
|
||||
val (colorPalette, typography) = LocalAppearance.current
|
||||
|
||||
val history by produceSaveableState(
|
||||
initialValue = emptyList(),
|
||||
stateSaver = listSaver(SearchQuerySaver),
|
||||
key1 = textFieldValue.text
|
||||
) {
|
||||
var history by persistList<SearchQuery>("search/online/history")
|
||||
|
||||
LaunchedEffect(textFieldValue.text) {
|
||||
if (!context.preferences.getBoolean(pauseSearchHistoryKey, false)) {
|
||||
Database.queries("%${textFieldValue.text}%")
|
||||
.flowOn(Dispatchers.IO)
|
||||
.distinctUntilChanged { old, new -> old.size == new.size }
|
||||
.collect { value = it }
|
||||
.collect { history = it }
|
||||
}
|
||||
}
|
||||
|
||||
var suggestionsResult by rememberSaveable(stateSaver = resultSaver(autoSaver<List<String>?>())) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
var suggestionsResult by persist<Result<List<String>?>?>("search/online/suggestionsResult")
|
||||
|
||||
LaunchedEffect(textFieldValue.text) {
|
||||
if (textFieldValue.text.isNotEmpty()) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import it.vfsfitvnm.compose.persist.PersistMapCleanup
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Scaffold
|
||||
@@ -49,6 +50,8 @@ fun SearchScreen(
|
||||
)
|
||||
}
|
||||
|
||||
PersistMapCleanup(tagPrefix = "search/")
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
globalRoutes()
|
||||
|
||||
|
||||
@@ -2,8 +2,11 @@ package it.vfsfitvnm.vimusic.ui.screens.searchresult
|
||||
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyItemScope
|
||||
@@ -11,32 +14,29 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.text.BasicText
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.saveable.Saver
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.compose.persist.persist
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.utils.plus
|
||||
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.savers.nullableSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.ShimmerHost
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.FloatingActionsContainerWithScrollToTop
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.center
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.utils.plus
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
inline fun <T : Innertube.Item> ItemsPage(
|
||||
stateSaver: Saver<Innertube.ItemsPage<T>, List<Any?>>,
|
||||
tag: String,
|
||||
crossinline headerContent: @Composable (textButton: (@Composable () -> Unit)?) -> Unit,
|
||||
crossinline itemContent: @Composable LazyItemScope.(T) -> Unit,
|
||||
noinline itemPlaceholderContent: @Composable () -> Unit,
|
||||
@@ -47,29 +47,29 @@ inline fun <T : Innertube.Item> ItemsPage(
|
||||
noinline itemsPageProvider: (suspend (String?) -> Result<Innertube.ItemsPage<T>?>?)? = null,
|
||||
) {
|
||||
val (_, typography) = LocalAppearance.current
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
val updatedItemsPageProvider by rememberUpdatedState(itemsPageProvider)
|
||||
|
||||
val itemsPage by produceSaveableState(
|
||||
initialValue = null,
|
||||
stateSaver = nullableSaver(stateSaver),
|
||||
lazyListState, updatedItemsPageProvider
|
||||
) {
|
||||
val currentItemsPageProvider = updatedItemsPageProvider ?: return@produceSaveableState
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
var itemsPage by persist<Innertube.ItemsPage<T>?>(tag)
|
||||
|
||||
LaunchedEffect(lazyListState, updatedItemsPageProvider) {
|
||||
val currentItemsPageProvider = updatedItemsPageProvider ?: return@LaunchedEffect
|
||||
|
||||
snapshotFlow { lazyListState.layoutInfo.visibleItemsInfo.any { it.key == "loading" } }
|
||||
.collect { shouldLoadMore ->
|
||||
if (!shouldLoadMore) return@collect
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
currentItemsPageProvider(value?.continuation)
|
||||
currentItemsPageProvider(itemsPage?.continuation)
|
||||
}?.onSuccess {
|
||||
if (it == null) {
|
||||
if (value == null) {
|
||||
value = Innertube.ItemsPage(null, null)
|
||||
if (itemsPage == null) {
|
||||
itemsPage = Innertube.ItemsPage(null, null)
|
||||
}
|
||||
} else {
|
||||
value += it
|
||||
itemsPage += it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,16 +9,18 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.compose.persist.PersistMapCleanup
|
||||
import it.vfsfitvnm.compose.persist.persistMap
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.ContinuationBody
|
||||
import it.vfsfitvnm.innertube.models.bodies.SearchBody
|
||||
import it.vfsfitvnm.innertube.requests.searchPage
|
||||
import it.vfsfitvnm.innertube.utils.from
|
||||
import it.vfsfitvnm.route.RouteHandler
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubeAlbumsPageSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubeArtistItemListSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubePlaylistItemListSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubeSongsPageSaver
|
||||
import it.vfsfitvnm.vimusic.savers.InnertubeVideoItemListSaver
|
||||
import it.vfsfitvnm.vimusic.savers.innertubeItemsPageSaver
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
|
||||
@@ -43,19 +45,17 @@ import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlay
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import it.vfsfitvnm.vimusic.utils.searchResultScreenTabIndexKey
|
||||
import it.vfsfitvnm.innertube.Innertube
|
||||
import it.vfsfitvnm.innertube.models.bodies.ContinuationBody
|
||||
import it.vfsfitvnm.innertube.models.bodies.SearchBody
|
||||
import it.vfsfitvnm.innertube.requests.searchPage
|
||||
import it.vfsfitvnm.innertube.utils.from
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val saveableStateHolder = rememberSaveableStateHolder()
|
||||
val (tabIndex, onTabIndexChanges) = rememberPreference(searchResultScreenTabIndexKey, 0)
|
||||
|
||||
PersistMapCleanup(tagPrefix = "searchResults/$query/")
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
globalRoutes()
|
||||
|
||||
@@ -66,6 +66,9 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
|
||||
modifier = Modifier
|
||||
.pointerInput(Unit) {
|
||||
detectTapGestures {
|
||||
context.persistMap?.keys?.removeAll {
|
||||
it.startsWith("searchResults/$query/")
|
||||
}
|
||||
onSearchAgain()
|
||||
}
|
||||
}
|
||||
@@ -74,8 +77,6 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
|
||||
|
||||
val emptyItemsText = "No results found. Please try a different query or category"
|
||||
|
||||
|
||||
|
||||
Scaffold(
|
||||
topIconButtonId = R.drawable.chevron_back,
|
||||
onTopIconButtonClick = pop,
|
||||
@@ -99,7 +100,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
|
||||
val thumbnailSizePx = thumbnailSizeDp.px
|
||||
|
||||
ItemsPage(
|
||||
stateSaver = InnertubeSongsPageSaver,
|
||||
tag = "searchResults/$query/songs",
|
||||
itemsPageProvider = { continuation ->
|
||||
if (continuation == null) {
|
||||
Innertube.searchPage(
|
||||
@@ -149,7 +150,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
|
||||
val thumbnailSizePx = thumbnailSizeDp.px
|
||||
|
||||
ItemsPage(
|
||||
stateSaver = InnertubeAlbumsPageSaver,
|
||||
tag = "searchResults/$query/albums",
|
||||
itemsPageProvider = { continuation ->
|
||||
if (continuation == null) {
|
||||
Innertube.searchPage(
|
||||
@@ -186,7 +187,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
|
||||
val thumbnailSizePx = thumbnailSizeDp.px
|
||||
|
||||
ItemsPage(
|
||||
stateSaver = innertubeItemsPageSaver(InnertubeArtistItemListSaver),
|
||||
tag = "searchResults/$query/artists",
|
||||
itemsPageProvider = { continuation ->
|
||||
if (continuation == null) {
|
||||
Innertube.searchPage(
|
||||
@@ -224,7 +225,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
|
||||
val thumbnailWidthDp = 128.dp
|
||||
|
||||
ItemsPage(
|
||||
stateSaver = innertubeItemsPageSaver(InnertubeVideoItemListSaver),
|
||||
tag = "searchResults/$query/videos",
|
||||
itemsPageProvider = { continuation ->
|
||||
if (continuation == null) {
|
||||
Innertube.searchPage(
|
||||
@@ -277,7 +278,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
|
||||
val thumbnailSizePx = thumbnailSizeDp.px
|
||||
|
||||
ItemsPage(
|
||||
stateSaver = innertubeItemsPageSaver(InnertubePlaylistItemListSaver),
|
||||
tag = "searchResults/$query/${if (tabIndex == 4) "playlists" else "featured"}",
|
||||
itemsPageProvider = { continuation ->
|
||||
if (continuation == null) {
|
||||
val filter = if (tabIndex == 4) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package it.vfsfitvnm.vimusic.ui.screens.settings
|
||||
|
||||
import android.os.Build
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
|
||||
@@ -15,8 +15,9 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.saveable.autoSaver
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import it.vfsfitvnm.vimusic.Database
|
||||
@@ -28,16 +29,13 @@ import it.vfsfitvnm.vimusic.service.PlayerService
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.Header
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.intent
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.toast
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import kotlin.system.exitProcess
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
@@ -45,12 +43,9 @@ fun DatabaseSettings() {
|
||||
val context = LocalContext.current
|
||||
val (colorPalette) = LocalAppearance.current
|
||||
|
||||
val eventsCount by produceSaveableState(initialValue = 0, stateSaver = autoSaver()) {
|
||||
Database.eventsCount()
|
||||
.flowOn(Dispatchers.IO)
|
||||
.distinctUntilChanged()
|
||||
.collect { value = it }
|
||||
}
|
||||
val eventsCount by remember {
|
||||
Database.eventsCount().distinctUntilChanged()
|
||||
}.collectAsState(initial = 0)
|
||||
|
||||
val backupLauncher =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("application/vnd.sqlite3")) { uri ->
|
||||
|
||||
@@ -21,10 +21,10 @@ import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SnapshotMutationPolicy
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.autoSaver
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@@ -39,12 +39,9 @@ import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6
|
||||
import it.vfsfitvnm.vimusic.utils.isIgnoringBatteryOptimizations
|
||||
import it.vfsfitvnm.vimusic.utils.isInvincibilityEnabledKey
|
||||
import it.vfsfitvnm.vimusic.utils.pauseSearchHistoryKey
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import it.vfsfitvnm.vimusic.utils.toast
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
|
||||
@SuppressLint("BatteryLife")
|
||||
@ExperimentalAnimationApi
|
||||
@@ -86,12 +83,9 @@ fun OtherSettings() {
|
||||
|
||||
var pauseSearchHistory by rememberPreference(pauseSearchHistoryKey, false)
|
||||
|
||||
val queriesCount by produceSaveableState(initialValue = 0, stateSaver = autoSaver()) {
|
||||
Database.queriesCount()
|
||||
.flowOn(Dispatchers.IO)
|
||||
.distinctUntilChanged()
|
||||
.collect { value = it }
|
||||
}
|
||||
val queriesCount by remember {
|
||||
Database.queriesCount().distinctUntilChanged()
|
||||
}.collectAsState(initial = 0)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
||||
@@ -11,6 +11,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.*
|
||||
import androidx.compose.ui.platform.LocalSavedStateRegistryOwner
|
||||
import androidx.compose.ui.unit.dp
|
||||
import it.vfsfitvnm.route.*
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
|
||||
Reference in New Issue
Block a user