浏览代码

Tweak code

vfsfitvnm 2 年之前
父节点
当前提交
df36075c3e

+ 0 - 3
app/src/main/kotlin/it/vfsfitvnm/vimusic/Database.kt

@@ -153,9 +153,6 @@ interface Database {
     @Query("SELECT * FROM Artist WHERE id = :id")
     @Query("SELECT * FROM Artist WHERE id = :id")
     fun artist(id: String): Flow<Artist?>
     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")
     @Query("SELECT * FROM Artist WHERE bookmarkedAt IS NOT NULL ORDER BY name DESC")
     fun artistsByNameDesc(): Flow<List<Artist>>
     fun artistsByNameDesc(): Flow<List<Artist>>
 
 

+ 55 - 55
app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/album/AlbumScreen.kt

@@ -6,10 +6,13 @@ import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.saveable.rememberSaveableStateHolder
 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.Modifier
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.unit.dp
 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.LocalAppearance
 import it.vfsfitvnm.vimusic.ui.styling.px
 import it.vfsfitvnm.vimusic.ui.styling.px
 import it.vfsfitvnm.vimusic.utils.asMediaItem
 import it.vfsfitvnm.vimusic.utils.asMediaItem
-import it.vfsfitvnm.vimusic.utils.produceSaveableState
 import it.vfsfitvnm.youtubemusic.Innertube
 import it.vfsfitvnm.youtubemusic.Innertube
 import it.vfsfitvnm.youtubemusic.models.bodies.BrowseBody
 import it.vfsfitvnm.youtubemusic.models.bodies.BrowseBody
 import it.vfsfitvnm.youtubemusic.requests.albumPage
 import it.vfsfitvnm.youtubemusic.requests.albumPage
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.withContext
 import kotlinx.coroutines.withContext
 
 
 @ExperimentalFoundationApi
 @ExperimentalFoundationApi
@@ -52,63 +54,61 @@ import kotlinx.coroutines.withContext
 fun AlbumScreen(browseId: String) {
 fun AlbumScreen(browseId: String) {
     val saveableStateHolder = rememberSaveableStateHolder()
     val saveableStateHolder = rememberSaveableStateHolder()
 
 
-    val (tabIndex, onTabChanged) = rememberSaveable {
+    var tabIndex by rememberSaveable {
         mutableStateOf(0)
         mutableStateOf(0)
     }
     }
 
 
-    val album by produceSaveableState(
-        initialValue = null,
-        stateSaver = nullableSaver(AlbumSaver),
-    ) {
+    var album by rememberSaveable(stateSaver = nullableSaver(AlbumSaver)) {
+        mutableStateOf(null)
+    }
+
+    var albumPage by rememberSaveable(stateSaver = nullableSaver(InnertubePlaylistOrAlbumPageSaver)) {
+        mutableStateOf(null)
+    }
+
+    LaunchedEffect(Unit) {
         Database
         Database
             .album(browseId)
             .album(browseId)
-            .flowOn(Dispatchers.IO)
-            .collect { value = it }
-    }
+            .combine(snapshotFlow { tabIndex }) { album, tabIndex -> album to tabIndex }
+            .collect { (currentAlbum, tabIndex) ->
+                album = currentAlbum
+
+                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()
+                                )
+                            }
+                    }
 
 
-    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
-
-        withContext(Dispatchers.IO) {
-            Innertube.albumPage(BrowseBody(browseId = browseId))
-        }?.onSuccess { albumPage ->
-            value = albumPage
-
-            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()
-                )
+                }
             }
             }
-        }
     }
     }
 
 
     RouteHandler(listenToGlobalEmitter = true) {
     RouteHandler(listenToGlobalEmitter = true) {
@@ -184,7 +184,7 @@ fun AlbumScreen(browseId: String) {
                 topIconButtonId = R.drawable.chevron_back,
                 topIconButtonId = R.drawable.chevron_back,
                 onTopIconButtonClick = pop,
                 onTopIconButtonClick = pop,
                 tabIndex = tabIndex,
                 tabIndex = tabIndex,
-                onTabChanged = onTabChanged,
+                onTabChanged = { tabIndex = it },
                 tabColumnContent = { Item ->
                 tabColumnContent = { Item ->
                     Item(0, "Songs", R.drawable.musical_notes)
                     Item(0, "Songs", R.drawable.musical_notes)
                     Item(1, "Other versions", R.drawable.disc)
                     Item(1, "Other versions", R.drawable.disc)
@@ -208,11 +208,11 @@ fun AlbumScreen(browseId: String) {
                                 initialPlaceholderCount = 1,
                                 initialPlaceholderCount = 1,
                                 continuationPlaceholderCount = 1,
                                 continuationPlaceholderCount = 1,
                                 emptyItemsText = "This album doesn't have any alternative version",
                                 emptyItemsText = "This album doesn't have any alternative version",
-                                itemsPageProvider = innertubeAlbum?.let {
+                                itemsPageProvider = albumPage?.let {
                                     ({
                                     ({
                                         Result.success(
                                         Result.success(
                                             Innertube.ItemsPage(
                                             Innertube.ItemsPage(
-                                                items = innertubeAlbum?.otherVersions,
+                                                items = albumPage?.otherVersions,
                                                 continuation = null
                                                 continuation = null
                                             )
                                             )
                                         )
                                         )

+ 53 - 53
app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/artist/ArtistScreen.kt

@@ -8,8 +8,13 @@ import androidx.compose.foundation.combinedClickable
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 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.saveable.rememberSaveableStateHolder
+import androidx.compose.runtime.setValue
+import androidx.compose.runtime.snapshotFlow
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.unit.dp
 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.artistScreenTabIndexKey
 import it.vfsfitvnm.vimusic.utils.asMediaItem
 import it.vfsfitvnm.vimusic.utils.asMediaItem
 import it.vfsfitvnm.vimusic.utils.forcePlay
 import it.vfsfitvnm.vimusic.utils.forcePlay
-import it.vfsfitvnm.vimusic.utils.produceSaveableState
 import it.vfsfitvnm.vimusic.utils.rememberPreference
 import it.vfsfitvnm.vimusic.utils.rememberPreference
 import it.vfsfitvnm.youtubemusic.Innertube
 import it.vfsfitvnm.youtubemusic.Innertube
 import it.vfsfitvnm.youtubemusic.models.bodies.BrowseBody
 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.requests.itemsPage
 import it.vfsfitvnm.youtubemusic.utils.from
 import it.vfsfitvnm.youtubemusic.utils.from
 import kotlinx.coroutines.Dispatchers
 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
 import kotlinx.coroutines.withContext
 
 
 @ExperimentalFoundationApi
 @ExperimentalFoundationApi
@@ -63,49 +69,43 @@ import kotlinx.coroutines.withContext
 fun ArtistScreen(browseId: String) {
 fun ArtistScreen(browseId: String) {
     val saveableStateHolder = rememberSaveableStateHolder()
     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)
+    }
+
+    LaunchedEffect(Unit) {
+        Database
+            .artist(browseId)
+            .combine(snapshotFlow { tabIndex }.map { it != 4 }) { artist, mustFetch -> artist to mustFetch }
+            .distinctUntilChanged()
+            .collect { (currentArtist, mustFetch) ->
+                artist = currentArtist
 
 
-        withContext(Dispatchers.IO) {
-            Innertube.artistPage(BrowseBody(browseId = browseId))
-        }?.onSuccess { artistPage ->
-            value = artistPage
+                if (artistPage == null && (currentArtist?.timestamp == null || mustFetch)) {
+                    withContext(Dispatchers.IO) {
+                        Innertube.artistPage(BrowseBody(browseId = browseId))
+                            ?.onSuccess { currentArtistPage ->
+                                artistPage = currentArtistPage
 
 
-            query {
-                Database.upsert(
-                    Artist(
-                        id = browseId,
-                        name = artistPage.name,
-                        thumbnailUrl = artistPage.thumbnail?.url,
-                        timestamp = System.currentTimeMillis(),
-                        bookmarkedAt = artist?.bookmarkedAt
-                    )
-                )
+                                Database.upsert(
+                                    Artist(
+                                        id = browseId,
+                                        name = currentArtistPage.name,
+                                        thumbnailUrl = currentArtistPage.thumbnail?.url,
+                                        timestamp = System.currentTimeMillis(),
+                                        bookmarkedAt = currentArtist?.bookmarkedAt
+                                    )
+                                )
+                            }
+                    }
+                }
             }
             }
-        }
     }
     }
 
 
     RouteHandler(listenToGlobalEmitter = true) {
     RouteHandler(listenToGlobalEmitter = true) {
@@ -181,7 +181,7 @@ fun ArtistScreen(browseId: String) {
                 topIconButtonId = R.drawable.chevron_back,
                 topIconButtonId = R.drawable.chevron_back,
                 onTopIconButtonClick = pop,
                 onTopIconButtonClick = pop,
                 tabIndex = tabIndex,
                 tabIndex = tabIndex,
-                onTabChanged = onTabIndexChanged,
+                onTabChanged = { tabIndex = it },
                 tabColumnContent = { Item ->
                 tabColumnContent = { Item ->
                     Item(0, "Overview", R.drawable.sparkles)
                     Item(0, "Overview", R.drawable.sparkles)
                     Item(1, "Songs", R.drawable.musical_notes)
                     Item(1, "Songs", R.drawable.musical_notes)
@@ -193,13 +193,13 @@ fun ArtistScreen(browseId: String) {
                 saveableStateHolder.SaveableStateProvider(key = currentTabIndex) {
                 saveableStateHolder.SaveableStateProvider(key = currentTabIndex) {
                     when (currentTabIndex) {
                     when (currentTabIndex) {
                         0 -> ArtistOverview(
                         0 -> ArtistOverview(
-                            youtubeArtistPage = youtubeArtist,
+                            youtubeArtistPage = artistPage,
                             thumbnailContent = thumbnailContent,
                             thumbnailContent = thumbnailContent,
                             headerContent = headerContent,
                             headerContent = headerContent,
                             onAlbumClick = { albumRoute(it) },
                             onAlbumClick = { albumRoute(it) },
-                            onViewAllSongsClick = { onTabIndexChanged(1) },
-                            onViewAllAlbumsClick = { onTabIndexChanged(2) },
-                            onViewAllSinglesClick = { onTabIndexChanged(3) },
+                            onViewAllSongsClick = { tabIndex = 1 },
+                            onViewAllAlbumsClick = { tabIndex = 2 },
+                            onViewAllSinglesClick = { tabIndex = 3 },
                         )
                         )
 
 
                         1 -> {
                         1 -> {
@@ -211,14 +211,14 @@ fun ArtistScreen(browseId: String) {
                             ItemsPage(
                             ItemsPage(
                                 stateSaver = InnertubeSongsPageSaver,
                                 stateSaver = InnertubeSongsPageSaver,
                                 headerContent = headerContent,
                                 headerContent = headerContent,
-                                itemsPageProvider = youtubeArtist?.let {
+                                itemsPageProvider = artistPage?.let {
                                     ({ continuation ->
                                     ({ continuation ->
                                         continuation?.let {
                                         continuation?.let {
                                             Innertube.itemsPage(
                                             Innertube.itemsPage(
                                                 body = ContinuationBody(continuation = continuation),
                                                 body = ContinuationBody(continuation = continuation),
                                                 fromMusicResponsiveListItemRenderer = Innertube.SongItem::from,
                                                 fromMusicResponsiveListItemRenderer = Innertube.SongItem::from,
                                             )
                                             )
-                                        } ?: youtubeArtist
+                                        } ?: artistPage
                                             ?.songsEndpoint
                                             ?.songsEndpoint
                                             ?.takeIf { it.browseId != null }
                                             ?.takeIf { it.browseId != null }
                                             ?.let { endpoint ->
                                             ?.let { endpoint ->
@@ -232,7 +232,7 @@ fun ArtistScreen(browseId: String) {
                                             }
                                             }
                                         ?: Result.success(
                                         ?: Result.success(
                                             Innertube.ItemsPage(
                                             Innertube.ItemsPage(
-                                                items = youtubeArtist?.songs,
+                                                items = artistPage?.songs,
                                                 continuation = null
                                                 continuation = null
                                             )
                                             )
                                         )
                                         )
@@ -275,14 +275,14 @@ fun ArtistScreen(browseId: String) {
                                 stateSaver = InnertubeAlbumsPageSaver,
                                 stateSaver = InnertubeAlbumsPageSaver,
                                 headerContent = headerContent,
                                 headerContent = headerContent,
                                 emptyItemsText = "This artist didn't release any album",
                                 emptyItemsText = "This artist didn't release any album",
-                                itemsPageProvider = youtubeArtist?.let {
+                                itemsPageProvider = artistPage?.let {
                                     ({ continuation ->
                                     ({ continuation ->
                                         continuation?.let {
                                         continuation?.let {
                                             Innertube.itemsPage(
                                             Innertube.itemsPage(
                                                 body = ContinuationBody(continuation = continuation),
                                                 body = ContinuationBody(continuation = continuation),
                                                 fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from,
                                                 fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from,
                                             )
                                             )
-                                        } ?: youtubeArtist
+                                        } ?: artistPage
                                             ?.albumsEndpoint
                                             ?.albumsEndpoint
                                             ?.takeIf { it.browseId != null }
                                             ?.takeIf { it.browseId != null }
                                             ?.let { endpoint ->
                                             ?.let { endpoint ->
@@ -296,7 +296,7 @@ fun ArtistScreen(browseId: String) {
                                             }
                                             }
                                         ?: Result.success(
                                         ?: Result.success(
                                             Innertube.ItemsPage(
                                             Innertube.ItemsPage(
-                                                items = youtubeArtist?.albums,
+                                                items = artistPage?.albums,
                                                 continuation = null
                                                 continuation = null
                                             )
                                             )
                                         )
                                         )
@@ -325,14 +325,14 @@ fun ArtistScreen(browseId: String) {
                                 stateSaver = InnertubeAlbumsPageSaver,
                                 stateSaver = InnertubeAlbumsPageSaver,
                                 headerContent = headerContent,
                                 headerContent = headerContent,
                                 emptyItemsText = "This artist didn't release any single",
                                 emptyItemsText = "This artist didn't release any single",
-                                itemsPageProvider = youtubeArtist?.let {
+                                itemsPageProvider = artistPage?.let {
                                     ({ continuation ->
                                     ({ continuation ->
                                         continuation?.let {
                                         continuation?.let {
                                             Innertube.itemsPage(
                                             Innertube.itemsPage(
                                                 body = ContinuationBody(continuation = continuation),
                                                 body = ContinuationBody(continuation = continuation),
                                                 fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from,
                                                 fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from,
                                             )
                                             )
-                                        } ?: youtubeArtist
+                                        } ?: artistPage
                                             ?.singlesEndpoint
                                             ?.singlesEndpoint
                                             ?.takeIf { it.browseId != null }
                                             ?.takeIf { it.browseId != null }
                                             ?.let { endpoint ->
                                             ?.let { endpoint ->
@@ -346,7 +346,7 @@ fun ArtistScreen(browseId: String) {
                                             }
                                             }
                                         ?: Result.success(
                                         ?: Result.success(
                                             Innertube.ItemsPage(
                                             Innertube.ItemsPage(
-                                                items = youtubeArtist?.singles,
+                                                items = artistPage?.singles,
                                                 continuation = null
                                                 continuation = null
                                             )
                                             )
                                         )
                                         )

+ 3 - 5
app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/home/HomeSongs.kt

@@ -9,8 +9,11 @@ import androidx.compose.foundation.background
 import androidx.compose.foundation.combinedClickable
 import androidx.compose.foundation.combinedClickable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Spacer
 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.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.only
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.LazyColumn
@@ -29,11 +32,6 @@ import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
 import it.vfsfitvnm.vimusic.Database
 import it.vfsfitvnm.vimusic.Database
 import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
 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.LocalPlayerServiceBinder
 import it.vfsfitvnm.vimusic.R
 import it.vfsfitvnm.vimusic.R
 import it.vfsfitvnm.vimusic.enums.SongSortBy
 import it.vfsfitvnm.vimusic.enums.SongSortBy

+ 8 - 8
app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/player/Controls.kt

@@ -21,10 +21,11 @@ import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 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.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 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.bold
 import it.vfsfitvnm.vimusic.utils.forceSeekToNext
 import it.vfsfitvnm.vimusic.utils.forceSeekToNext
 import it.vfsfitvnm.vimusic.utils.forceSeekToPrevious
 import it.vfsfitvnm.vimusic.utils.forceSeekToPrevious
-import it.vfsfitvnm.vimusic.utils.produceSaveableState
 import it.vfsfitvnm.vimusic.utils.rememberRepeatMode
 import it.vfsfitvnm.vimusic.utils.rememberRepeatMode
 import it.vfsfitvnm.vimusic.utils.secondary
 import it.vfsfitvnm.vimusic.utils.secondary
 import it.vfsfitvnm.vimusic.utils.semiBold
 import it.vfsfitvnm.vimusic.utils.semiBold
@@ -76,16 +76,16 @@ fun Controls(
         mutableStateOf<Long?>(null)
         mutableStateOf<Long?>(null)
     }
     }
 
 
-    val likedAt by produceSaveableState<Long?>(
-        initialValue = null,
-        stateSaver = autoSaver(),
-        mediaId
-    ) {
+    var likedAt by rememberSaveable {
+        mutableStateOf<Long?>(null)
+    }
+
+    LaunchedEffect(mediaId) {
         Database
         Database
             .likedAt(mediaId)
             .likedAt(mediaId)
             .flowOn(Dispatchers.IO)
             .flowOn(Dispatchers.IO)
             .distinctUntilChanged()
             .distinctUntilChanged()
-            .collect { value = it }
+            .collect { likedAt = it }
     }
     }
 
 
     val shouldBePlayingTransition = updateTransition(shouldBePlaying, label = "shouldBePlaying")
     val shouldBePlayingTransition = updateTransition(shouldBePlaying, label = "shouldBePlaying")

+ 14 - 10
app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/search/OnlineSearch.kt

@@ -7,8 +7,11 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.WindowInsetsSides
+import androidx.compose.foundation.layout.asPaddingValues
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.only
 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.lazy.LazyColumn
 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.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.autoSaver
 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.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.paint
 import androidx.compose.ui.draw.paint
@@ -41,9 +47,6 @@ import androidx.compose.ui.unit.dp
 import androidx.core.net.toUri
 import androidx.core.net.toUri
 import it.vfsfitvnm.vimusic.Database
 import it.vfsfitvnm.vimusic.Database
 import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
 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.R
 import it.vfsfitvnm.vimusic.models.SearchQuery
 import it.vfsfitvnm.vimusic.models.SearchQuery
 import it.vfsfitvnm.vimusic.query
 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.align
 import it.vfsfitvnm.vimusic.utils.center
 import it.vfsfitvnm.vimusic.utils.center
 import it.vfsfitvnm.vimusic.utils.medium
 import it.vfsfitvnm.vimusic.utils.medium
-import it.vfsfitvnm.vimusic.utils.produceSaveableOneShotState
 import it.vfsfitvnm.vimusic.utils.produceSaveableState
 import it.vfsfitvnm.vimusic.utils.produceSaveableState
 import it.vfsfitvnm.vimusic.utils.secondary
 import it.vfsfitvnm.vimusic.utils.secondary
 import it.vfsfitvnm.youtubemusic.Innertube
 import it.vfsfitvnm.youtubemusic.Innertube
@@ -90,13 +92,15 @@ fun OnlineSearch(
             .collect { value = it }
             .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()) {
         if (textFieldValue.text.isNotEmpty()) {
-            value = Innertube.searchSuggestions(SearchSuggestionsBody(input = textFieldValue.text))
+            delay(200)
+            suggestionsResult =
+                Innertube.searchSuggestions(SearchSuggestionsBody(input = textFieldValue.text))
         }
         }
     }
     }
 
 

+ 0 - 27
app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/ProduceSaveableState.kt

@@ -7,11 +7,9 @@ import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.ProduceStateScope
 import androidx.compose.runtime.ProduceStateScope
 import androidx.compose.runtime.State
 import androidx.compose.runtime.State
-import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.saveable.rememberSaveable
-import androidx.compose.runtime.setValue
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.CoroutineContext
 import kotlin.experimental.ExperimentalTypeInference
 import kotlin.experimental.ExperimentalTypeInference
 import kotlinx.coroutines.suspendCancellableCoroutine
 import kotlinx.coroutines.suspendCancellableCoroutine
@@ -51,31 +49,6 @@ fun <T> produceSaveableState(
     return state
     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
 @Composable
 fun <T> produceSaveableState(
 fun <T> produceSaveableState(
     initialValue: T,
     initialValue: T,