Tweak code
This commit is contained in:
parent
9a5ea69de4
commit
df36075c3e
7 changed files with 132 additions and 160 deletions
|
@ -153,9 +153,6 @@ interface Database {
|
|||
@Query("SELECT * FROM Artist WHERE id = :id")
|
||||
fun artist(id: String): Flow<Artist?>
|
||||
|
||||
@Query("SELECT timestamp FROM Artist WHERE id = :id")
|
||||
fun artistTimestamp(id: String): Long?
|
||||
|
||||
@Query("SELECT * FROM Artist WHERE bookmarkedAt IS NOT NULL ORDER BY name DESC")
|
||||
fun artistsByNameDesc(): Flow<List<Artist>>
|
||||
|
||||
|
|
|
@ -6,10 +6,13 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
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
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
@ -38,12 +41,11 @@ 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.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.youtubemusic.Innertube
|
||||
import it.vfsfitvnm.youtubemusic.models.bodies.BrowseBody
|
||||
import it.vfsfitvnm.youtubemusic.requests.albumPage
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
|
@ -52,63 +54,61 @@ import kotlinx.coroutines.withContext
|
|||
fun AlbumScreen(browseId: String) {
|
||||
val saveableStateHolder = rememberSaveableStateHolder()
|
||||
|
||||
val (tabIndex, onTabChanged) = rememberSaveable {
|
||||
var tabIndex by rememberSaveable {
|
||||
mutableStateOf(0)
|
||||
}
|
||||
|
||||
val album by produceSaveableState(
|
||||
initialValue = null,
|
||||
stateSaver = nullableSaver(AlbumSaver),
|
||||
) {
|
||||
Database
|
||||
.album(browseId)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.collect { value = it }
|
||||
var album by rememberSaveable(stateSaver = nullableSaver(AlbumSaver)) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
|
||||
val innertubeAlbum by produceSaveableState(
|
||||
initialValue = null,
|
||||
stateSaver = nullableSaver(InnertubePlaylistOrAlbumPageSaver),
|
||||
tabIndex > 0
|
||||
) {
|
||||
if (value != null || (tabIndex == 0 && withContext(Dispatchers.IO) {
|
||||
Database.albumTimestamp(
|
||||
browseId
|
||||
)
|
||||
} != null)) return@produceSaveableState
|
||||
var albumPage by rememberSaveable(stateSaver = nullableSaver(InnertubePlaylistOrAlbumPageSaver)) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
Innertube.albumPage(BrowseBody(browseId = browseId))
|
||||
}?.onSuccess { albumPage ->
|
||||
value = albumPage
|
||||
LaunchedEffect(Unit) {
|
||||
Database
|
||||
.album(browseId)
|
||||
.combine(snapshotFlow { tabIndex }) { album, tabIndex -> album to tabIndex }
|
||||
.collect { (currentAlbum, tabIndex) ->
|
||||
album = currentAlbum
|
||||
|
||||
query {
|
||||
Database.upsert(
|
||||
Album(
|
||||
id = browseId,
|
||||
title = albumPage.title,
|
||||
thumbnailUrl = albumPage.thumbnail?.url,
|
||||
year = albumPage.year,
|
||||
authorsText = albumPage.authors?.joinToString("") { it.name ?: "" },
|
||||
shareUrl = albumPage.url,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
bookmarkedAt = album?.bookmarkedAt
|
||||
),
|
||||
albumPage
|
||||
.songsPage
|
||||
?.items
|
||||
?.map(Innertube.SongItem::asMediaItem)
|
||||
?.onEach(Database::insert)
|
||||
?.mapIndexed { position, mediaItem ->
|
||||
SongAlbumMap(
|
||||
songId = mediaItem.mediaId,
|
||||
albumId = browseId,
|
||||
position = position
|
||||
)
|
||||
} ?: emptyList()
|
||||
)
|
||||
if (albumPage == null && (currentAlbum?.timestamp == null || tabIndex == 1)) {
|
||||
withContext(Dispatchers.IO) {
|
||||
Innertube.albumPage(BrowseBody(browseId = browseId))
|
||||
?.onSuccess { currentAlbumPage ->
|
||||
albumPage = currentAlbumPage
|
||||
|
||||
Database.upsert(
|
||||
Album(
|
||||
id = browseId,
|
||||
title = currentAlbumPage.title,
|
||||
thumbnailUrl = currentAlbumPage.thumbnail?.url,
|
||||
year = currentAlbumPage.year,
|
||||
authorsText = currentAlbumPage.authors
|
||||
?.joinToString("") { it.name ?: "" },
|
||||
shareUrl = currentAlbumPage.url,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
bookmarkedAt = album?.bookmarkedAt
|
||||
),
|
||||
currentAlbumPage
|
||||
.songsPage
|
||||
?.items
|
||||
?.map(Innertube.SongItem::asMediaItem)
|
||||
?.onEach(Database::insert)
|
||||
?.mapIndexed { position, mediaItem ->
|
||||
SongAlbumMap(
|
||||
songId = mediaItem.mediaId,
|
||||
albumId = browseId,
|
||||
position = position
|
||||
)
|
||||
} ?: emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
|
@ -184,7 +184,7 @@ fun AlbumScreen(browseId: String) {
|
|||
topIconButtonId = R.drawable.chevron_back,
|
||||
onTopIconButtonClick = pop,
|
||||
tabIndex = tabIndex,
|
||||
onTabChanged = onTabChanged,
|
||||
onTabChanged = { tabIndex = it },
|
||||
tabColumnContent = { Item ->
|
||||
Item(0, "Songs", R.drawable.musical_notes)
|
||||
Item(1, "Other versions", R.drawable.disc)
|
||||
|
@ -208,11 +208,11 @@ fun AlbumScreen(browseId: String) {
|
|||
initialPlaceholderCount = 1,
|
||||
continuationPlaceholderCount = 1,
|
||||
emptyItemsText = "This album doesn't have any alternative version",
|
||||
itemsPageProvider = innertubeAlbum?.let {
|
||||
itemsPageProvider = albumPage?.let {
|
||||
({
|
||||
Result.success(
|
||||
Innertube.ItemsPage(
|
||||
items = innertubeAlbum?.otherVersions,
|
||||
items = albumPage?.otherVersions,
|
||||
continuation = null
|
||||
)
|
||||
)
|
||||
|
|
|
@ -8,8 +8,13 @@ import androidx.compose.foundation.combinedClickable
|
|||
import androidx.compose.foundation.layout.Spacer
|
||||
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
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
@ -45,7 +50,6 @@ import it.vfsfitvnm.vimusic.ui.styling.px
|
|||
import it.vfsfitvnm.vimusic.utils.artistScreenTabIndexKey
|
||||
import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
import it.vfsfitvnm.vimusic.utils.forcePlay
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
import it.vfsfitvnm.youtubemusic.Innertube
|
||||
import it.vfsfitvnm.youtubemusic.models.bodies.BrowseBody
|
||||
|
@ -54,7 +58,9 @@ import it.vfsfitvnm.youtubemusic.requests.artistPage
|
|||
import it.vfsfitvnm.youtubemusic.requests.itemsPage
|
||||
import it.vfsfitvnm.youtubemusic.utils.from
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@ExperimentalFoundationApi
|
||||
|
@ -63,49 +69,43 @@ import kotlinx.coroutines.withContext
|
|||
fun ArtistScreen(browseId: String) {
|
||||
val saveableStateHolder = rememberSaveableStateHolder()
|
||||
|
||||
val (tabIndex, onTabIndexChanged) = rememberPreference(
|
||||
artistScreenTabIndexKey,
|
||||
defaultValue = 0
|
||||
)
|
||||
var tabIndex by rememberPreference(artistScreenTabIndexKey, defaultValue = 0)
|
||||
|
||||
val artist by produceSaveableState(
|
||||
initialValue = null,
|
||||
stateSaver = nullableSaver(ArtistSaver),
|
||||
) {
|
||||
Database
|
||||
.artist(browseId)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.collect { value = it }
|
||||
var artist by rememberSaveable(stateSaver = nullableSaver(ArtistSaver)) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
|
||||
val youtubeArtist by produceSaveableState(
|
||||
initialValue = null,
|
||||
stateSaver = nullableSaver(InnertubeArtistPageSaver),
|
||||
tabIndex < 4
|
||||
) {
|
||||
if (value != null || (tabIndex == 4 && withContext(Dispatchers.IO) {
|
||||
Database.artistTimestamp(
|
||||
browseId
|
||||
)
|
||||
} != null)) return@produceSaveableState
|
||||
var artistPage by rememberSaveable(stateSaver = nullableSaver(InnertubeArtistPageSaver)) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
Innertube.artistPage(BrowseBody(browseId = browseId))
|
||||
}?.onSuccess { artistPage ->
|
||||
value = artistPage
|
||||
LaunchedEffect(Unit) {
|
||||
Database
|
||||
.artist(browseId)
|
||||
.combine(snapshotFlow { tabIndex }.map { it != 4 }) { artist, mustFetch -> artist to mustFetch }
|
||||
.distinctUntilChanged()
|
||||
.collect { (currentArtist, mustFetch) ->
|
||||
artist = currentArtist
|
||||
|
||||
query {
|
||||
Database.upsert(
|
||||
Artist(
|
||||
id = browseId,
|
||||
name = artistPage.name,
|
||||
thumbnailUrl = artistPage.thumbnail?.url,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
bookmarkedAt = artist?.bookmarkedAt
|
||||
)
|
||||
)
|
||||
if (artistPage == null && (currentArtist?.timestamp == null || mustFetch)) {
|
||||
withContext(Dispatchers.IO) {
|
||||
Innertube.artistPage(BrowseBody(browseId = browseId))
|
||||
?.onSuccess { currentArtistPage ->
|
||||
artistPage = currentArtistPage
|
||||
|
||||
Database.upsert(
|
||||
Artist(
|
||||
id = browseId,
|
||||
name = currentArtistPage.name,
|
||||
thumbnailUrl = currentArtistPage.thumbnail?.url,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
bookmarkedAt = currentArtist?.bookmarkedAt
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
|
@ -181,7 +181,7 @@ fun ArtistScreen(browseId: String) {
|
|||
topIconButtonId = R.drawable.chevron_back,
|
||||
onTopIconButtonClick = pop,
|
||||
tabIndex = tabIndex,
|
||||
onTabChanged = onTabIndexChanged,
|
||||
onTabChanged = { tabIndex = it },
|
||||
tabColumnContent = { Item ->
|
||||
Item(0, "Overview", R.drawable.sparkles)
|
||||
Item(1, "Songs", R.drawable.musical_notes)
|
||||
|
@ -193,13 +193,13 @@ fun ArtistScreen(browseId: String) {
|
|||
saveableStateHolder.SaveableStateProvider(key = currentTabIndex) {
|
||||
when (currentTabIndex) {
|
||||
0 -> ArtistOverview(
|
||||
youtubeArtistPage = youtubeArtist,
|
||||
youtubeArtistPage = artistPage,
|
||||
thumbnailContent = thumbnailContent,
|
||||
headerContent = headerContent,
|
||||
onAlbumClick = { albumRoute(it) },
|
||||
onViewAllSongsClick = { onTabIndexChanged(1) },
|
||||
onViewAllAlbumsClick = { onTabIndexChanged(2) },
|
||||
onViewAllSinglesClick = { onTabIndexChanged(3) },
|
||||
onViewAllSongsClick = { tabIndex = 1 },
|
||||
onViewAllAlbumsClick = { tabIndex = 2 },
|
||||
onViewAllSinglesClick = { tabIndex = 3 },
|
||||
)
|
||||
|
||||
1 -> {
|
||||
|
@ -211,14 +211,14 @@ fun ArtistScreen(browseId: String) {
|
|||
ItemsPage(
|
||||
stateSaver = InnertubeSongsPageSaver,
|
||||
headerContent = headerContent,
|
||||
itemsPageProvider = youtubeArtist?.let {
|
||||
itemsPageProvider = artistPage?.let {
|
||||
({ continuation ->
|
||||
continuation?.let {
|
||||
Innertube.itemsPage(
|
||||
body = ContinuationBody(continuation = continuation),
|
||||
fromMusicResponsiveListItemRenderer = Innertube.SongItem::from,
|
||||
)
|
||||
} ?: youtubeArtist
|
||||
} ?: artistPage
|
||||
?.songsEndpoint
|
||||
?.takeIf { it.browseId != null }
|
||||
?.let { endpoint ->
|
||||
|
@ -232,7 +232,7 @@ fun ArtistScreen(browseId: String) {
|
|||
}
|
||||
?: Result.success(
|
||||
Innertube.ItemsPage(
|
||||
items = youtubeArtist?.songs,
|
||||
items = artistPage?.songs,
|
||||
continuation = null
|
||||
)
|
||||
)
|
||||
|
@ -275,14 +275,14 @@ fun ArtistScreen(browseId: String) {
|
|||
stateSaver = InnertubeAlbumsPageSaver,
|
||||
headerContent = headerContent,
|
||||
emptyItemsText = "This artist didn't release any album",
|
||||
itemsPageProvider = youtubeArtist?.let {
|
||||
itemsPageProvider = artistPage?.let {
|
||||
({ continuation ->
|
||||
continuation?.let {
|
||||
Innertube.itemsPage(
|
||||
body = ContinuationBody(continuation = continuation),
|
||||
fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from,
|
||||
)
|
||||
} ?: youtubeArtist
|
||||
} ?: artistPage
|
||||
?.albumsEndpoint
|
||||
?.takeIf { it.browseId != null }
|
||||
?.let { endpoint ->
|
||||
|
@ -296,7 +296,7 @@ fun ArtistScreen(browseId: String) {
|
|||
}
|
||||
?: Result.success(
|
||||
Innertube.ItemsPage(
|
||||
items = youtubeArtist?.albums,
|
||||
items = artistPage?.albums,
|
||||
continuation = null
|
||||
)
|
||||
)
|
||||
|
@ -325,14 +325,14 @@ fun ArtistScreen(browseId: String) {
|
|||
stateSaver = InnertubeAlbumsPageSaver,
|
||||
headerContent = headerContent,
|
||||
emptyItemsText = "This artist didn't release any single",
|
||||
itemsPageProvider = youtubeArtist?.let {
|
||||
itemsPageProvider = artistPage?.let {
|
||||
({ continuation ->
|
||||
continuation?.let {
|
||||
Innertube.itemsPage(
|
||||
body = ContinuationBody(continuation = continuation),
|
||||
fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from,
|
||||
)
|
||||
} ?: youtubeArtist
|
||||
} ?: artistPage
|
||||
?.singlesEndpoint
|
||||
?.takeIf { it.browseId != null }
|
||||
?.let { endpoint ->
|
||||
|
@ -346,7 +346,7 @@ fun ArtistScreen(browseId: String) {
|
|||
}
|
||||
?: Result.success(
|
||||
Innertube.ItemsPage(
|
||||
items = youtubeArtist?.singles,
|
||||
items = artistPage?.singles,
|
||||
continuation = null
|
||||
)
|
||||
)
|
||||
|
|
|
@ -9,8 +9,11 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.foundation.combinedClickable
|
||||
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.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
|
@ -29,11 +32,6 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.unit.dp
|
||||
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.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.only
|
||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.enums.SongSortBy
|
||||
|
|
|
@ -21,10 +21,11 @@ import androidx.compose.foundation.layout.width
|
|||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
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.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
|
||||
|
@ -47,7 +48,6 @@ import it.vfsfitvnm.vimusic.ui.styling.favoritesIcon
|
|||
import it.vfsfitvnm.vimusic.utils.bold
|
||||
import it.vfsfitvnm.vimusic.utils.forceSeekToNext
|
||||
import it.vfsfitvnm.vimusic.utils.forceSeekToPrevious
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.rememberRepeatMode
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||
|
@ -76,16 +76,16 @@ fun Controls(
|
|||
mutableStateOf<Long?>(null)
|
||||
}
|
||||
|
||||
val likedAt by produceSaveableState<Long?>(
|
||||
initialValue = null,
|
||||
stateSaver = autoSaver(),
|
||||
mediaId
|
||||
) {
|
||||
var likedAt by rememberSaveable {
|
||||
mutableStateOf<Long?>(null)
|
||||
}
|
||||
|
||||
LaunchedEffect(mediaId) {
|
||||
Database
|
||||
.likedAt(mediaId)
|
||||
.flowOn(Dispatchers.IO)
|
||||
.distinctUntilChanged()
|
||||
.collect { value = it }
|
||||
.collect { likedAt = it }
|
||||
}
|
||||
|
||||
val shouldBePlayingTransition = updateTransition(shouldBePlaying, label = "shouldBePlaying")
|
||||
|
|
|
@ -7,8 +7,11 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
|
|||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
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.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
|
@ -22,8 +25,11 @@ 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
|
||||
import androidx.compose.ui.draw.paint
|
||||
|
@ -41,9 +47,6 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.core.net.toUri
|
||||
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.models.SearchQuery
|
||||
import it.vfsfitvnm.vimusic.query
|
||||
|
@ -57,7 +60,6 @@ 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.produceSaveableOneShotState
|
||||
import it.vfsfitvnm.vimusic.utils.produceSaveableState
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
import it.vfsfitvnm.youtubemusic.Innertube
|
||||
|
@ -90,13 +92,15 @@ fun OnlineSearch(
|
|||
.collect { value = it }
|
||||
}
|
||||
|
||||
val suggestionsResult by produceSaveableOneShotState(
|
||||
initialValue = null,
|
||||
stateSaver = resultSaver(autoSaver<List<String>?>()),
|
||||
textFieldValue.text
|
||||
) {
|
||||
var suggestionsResult by rememberSaveable(stateSaver = resultSaver(autoSaver<List<String>?>())) {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
|
||||
LaunchedEffect(textFieldValue.text) {
|
||||
if (textFieldValue.text.isNotEmpty()) {
|
||||
value = Innertube.searchSuggestions(SearchSuggestionsBody(input = textFieldValue.text))
|
||||
delay(200)
|
||||
suggestionsResult =
|
||||
Innertube.searchSuggestions(SearchSuggestionsBody(input = textFieldValue.text))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,9 @@ import androidx.compose.runtime.LaunchedEffect
|
|||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.ProduceStateScope
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.Saver
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
|
@ -51,31 +49,6 @@ fun <T> produceSaveableState(
|
|||
return state
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> produceSaveableOneShotState(
|
||||
initialValue: T,
|
||||
stateSaver: Saver<T, out Any>,
|
||||
key1: Any?,
|
||||
@BuilderInference producer: suspend ProduceStateScope<T>.() -> Unit
|
||||
): State<T> {
|
||||
val state = rememberSaveable(stateSaver = stateSaver) {
|
||||
mutableStateOf(initialValue)
|
||||
}
|
||||
|
||||
var produced by rememberSaveable(key1) {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
LaunchedEffect(key1) {
|
||||
if (!produced) {
|
||||
ProduceSaveableStateScope(state, coroutineContext).producer()
|
||||
produced = true
|
||||
}
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> produceSaveableState(
|
||||
initialValue: T,
|
||||
|
|
Loading…
Reference in a new issue