From 73172c6cb348ade35da52b0247231b020474e724 Mon Sep 17 00:00:00 2001 From: Chris Arriola Date: Thu, 25 Apr 2024 13:36:23 -0700 Subject: [PATCH 1/4] [Jetcaster]: Display latest episodes for all subscribed podcasts in library. --- .../jetcaster/core/model/LibraryInfo.kt | 5 ++-- .../core/model/PodcastCategoryFilterResult.kt | 7 +---- .../core/model/PodcastToEpisodeInfo.kt | 6 ++++ .../data/database/model/EpisodeToPodcast.kt | 6 ++-- .../domain/PodcastCategoryFilterUseCase.kt | 4 +-- .../PodcastCategoryFilterUseCaseTest.kt | 4 +-- .../com/example/jetcaster/ui/home/Home.kt | 10 +++---- .../jetcaster/ui/home/HomeViewModel.kt | 16 ++++++----- .../example/jetcaster/ui/home/PreviewData.kt | 6 ++-- .../jetcaster/ui/home/library/Library.kt | 28 ++++++------------- 10 files changed, 41 insertions(+), 51 deletions(-) create mode 100644 Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastToEpisodeInfo.kt diff --git a/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/LibraryInfo.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/LibraryInfo.kt index a502a0bb2..5731b07f8 100644 --- a/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/LibraryInfo.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/LibraryInfo.kt @@ -17,6 +17,5 @@ package com.example.jetcaster.core.model data class LibraryInfo( - val podcast: PodcastInfo? = null, - val episodes: List = emptyList() -) + val episodes: List = emptyList() +) : List by episodes diff --git a/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastCategoryFilterResult.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastCategoryFilterResult.kt index e1d27306e..c0e6761ed 100644 --- a/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastCategoryFilterResult.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastCategoryFilterResult.kt @@ -21,10 +21,5 @@ package com.example.jetcaster.core.model */ data class PodcastCategoryFilterResult( val topPodcasts: List = emptyList(), - val episodes: List = emptyList() -) - -data class PodcastCategoryEpisode( - val episode: EpisodeInfo, - val podcast: PodcastInfo, + val episodes: List = emptyList() ) diff --git a/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastToEpisodeInfo.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastToEpisodeInfo.kt new file mode 100644 index 000000000..cbd004e47 --- /dev/null +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastToEpisodeInfo.kt @@ -0,0 +1,6 @@ +package com.example.jetcaster.core.model + +data class PodcastToEpisodeInfo( + val episode: EpisodeInfo, + val podcast: PodcastInfo, +) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/EpisodeToPodcast.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/EpisodeToPodcast.kt index 4646849ac..666f11710 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/EpisodeToPodcast.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/database/model/EpisodeToPodcast.kt @@ -20,7 +20,7 @@ import androidx.room.Embedded import androidx.room.Ignore import androidx.room.Relation import com.example.jetcaster.core.model.PlayerEpisode -import com.example.jetcaster.core.model.PodcastCategoryEpisode +import com.example.jetcaster.core.model.PodcastToEpisodeInfo import java.util.Objects class EpisodeToPodcast { @@ -62,8 +62,8 @@ fun EpisodeToPodcast.toPlayerEpisode(): PlayerEpisode = podcastImageUrl = podcast.imageUrl ?: "", ) -fun EpisodeToPodcast.asPodcastCategoryEpisode(): PodcastCategoryEpisode = - PodcastCategoryEpisode( +fun EpisodeToPodcast.asPodcastToEpisodeInfo(): PodcastToEpisodeInfo = + PodcastToEpisodeInfo( episode = episode.asExternalModel(), podcast = podcast.asExternalModel(), ) diff --git a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCase.kt b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCase.kt index 71e3d160a..8daaa99fd 100644 --- a/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCase.kt +++ b/Jetcaster/core/src/main/java/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCase.kt @@ -18,7 +18,7 @@ package com.example.jetcaster.core.data.domain import com.example.jetcaster.core.data.database.model.Category import com.example.jetcaster.core.data.database.model.asExternalModel -import com.example.jetcaster.core.data.database.model.asPodcastCategoryEpisode +import com.example.jetcaster.core.data.database.model.asPodcastToEpisodeInfo import com.example.jetcaster.core.data.repository.CategoryStore import com.example.jetcaster.core.model.CategoryInfo import com.example.jetcaster.core.model.PodcastCategoryFilterResult @@ -52,7 +52,7 @@ class PodcastCategoryFilterUseCase @Inject constructor( return combine(recentPodcastsFlow, episodesFlow) { topPodcasts, episodes -> PodcastCategoryFilterResult( topPodcasts = topPodcasts.map { it.asExternalModel() }, - episodes = episodes.map { it.asPodcastCategoryEpisode() } + episodes = episodes.map { it.asPodcastToEpisodeInfo() } ) } } diff --git a/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCaseTest.kt b/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCaseTest.kt index 9c4d3b84f..c2cb968be 100644 --- a/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCaseTest.kt +++ b/Jetcaster/core/src/test/kotlin/com/example/jetcaster/core/data/domain/PodcastCategoryFilterUseCaseTest.kt @@ -22,7 +22,7 @@ import com.example.jetcaster.core.data.database.model.EpisodeToPodcast import com.example.jetcaster.core.data.database.model.Podcast import com.example.jetcaster.core.data.database.model.PodcastWithExtraInfo import com.example.jetcaster.core.data.database.model.asExternalModel -import com.example.jetcaster.core.data.database.model.asPodcastCategoryEpisode +import com.example.jetcaster.core.data.database.model.asPodcastToEpisodeInfo import com.example.jetcaster.core.data.repository.TestCategoryStore import java.time.OffsetDateTime import kotlinx.coroutines.flow.first @@ -109,7 +109,7 @@ class PodcastCategoryFilterUseCaseTest { result.topPodcasts ) assertEquals( - testEpisodeToPodcast.map { it.asPodcastCategoryEpisode() }, + testEpisodeToPodcast.map { it.asPodcastToEpisodeInfo() }, result.episodes ) } diff --git a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/Home.kt b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/Home.kt index bfa3b20ba..d7898e17c 100644 --- a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/Home.kt +++ b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/Home.kt @@ -121,12 +121,12 @@ import com.example.jetcaster.util.fullWidthItem import com.example.jetcaster.util.isCompact import com.example.jetcaster.util.quantityStringResource import com.example.jetcaster.util.radialGradientScrim -import java.time.Duration -import java.time.LocalDateTime -import java.time.OffsetDateTime import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.launch +import java.time.Duration +import java.time.LocalDateTime +import java.time.OffsetDateTime data class HomeState( val windowSizeClass: WindowSizeClass, @@ -921,7 +921,7 @@ private fun PreviewHomeContent() { ), podcastCategoryFilterResult = PodcastCategoryFilterResult( topPodcasts = PreviewPodcasts, - episodes = PreviewPodcastCategoryEpisodes + episodes = PreviewPodcastEpisodes ), library = LibraryInfo(), onCategorySelected = {}, @@ -957,7 +957,7 @@ private fun PreviewHomeContentExpanded() { ), podcastCategoryFilterResult = PodcastCategoryFilterResult( topPodcasts = PreviewPodcasts, - episodes = PreviewPodcastCategoryEpisodes + episodes = PreviewPodcastEpisodes ), library = LibraryInfo(), onCategorySelected = {}, diff --git a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt index 5d1775519..9092b4641 100644 --- a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt +++ b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt @@ -21,6 +21,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.example.jetcaster.core.data.database.model.EpisodeToPodcast import com.example.jetcaster.core.data.database.model.asExternalModel +import com.example.jetcaster.core.data.database.model.asPodcastToEpisodeInfo import com.example.jetcaster.core.data.domain.FilterableCategoriesUseCase import com.example.jetcaster.core.data.domain.PodcastCategoryFilterUseCase import com.example.jetcaster.core.data.repository.EpisodeStore @@ -35,7 +36,6 @@ import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.core.player.EpisodePlayer import com.example.jetcaster.core.util.combine import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList @@ -45,6 +45,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.launch +import javax.inject.Inject @OptIn(ExperimentalCoroutinesApi::class) @@ -70,6 +71,8 @@ class HomeViewModel @Inject constructor( // Holds the view state if the UI is refreshing for new data private val refreshing = MutableStateFlow(false) + private val followedPodcasts = podcastStore.followedPodcastsSortedByLastEpisode(limit = 10) + val state: StateFlow get() = _state @@ -80,7 +83,7 @@ class HomeViewModel @Inject constructor( combine( homeCategories, selectedHomeCategory, - podcastStore.followedPodcastsSortedByLastEpisode(limit = 10), + followedPodcasts, refreshing, _selectedCategory.flatMapLatest { selectedCategory -> filterableCategoriesUseCase(selectedCategory) @@ -88,9 +91,9 @@ class HomeViewModel @Inject constructor( _selectedCategory.flatMapLatest { podcastCategoryFilterUseCase(it) }, - selectedLibraryPodcast.flatMapLatest { - episodeStore.episodesInPodcast( - podcastUri = it?.uri ?: "", + followedPodcasts.flatMapLatest { podcast -> + episodeStore.episodesInPodcasts( + podcastUris = podcast.map { it.podcast.uri }, limit = 20 ) } @@ -175,8 +178,7 @@ class HomeViewModel @Inject constructor( private fun List.asLibrary(): LibraryInfo = LibraryInfo( - podcast = this.firstOrNull()?.podcast?.asExternalModel(), - episodes = this.map { it.episode.asExternalModel() } + episodes = this.map { it.asPodcastToEpisodeInfo() } ) enum class HomeCategory { diff --git a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/PreviewData.kt b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/PreviewData.kt index f4ef9e6df..5c0c537e0 100644 --- a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/PreviewData.kt +++ b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/PreviewData.kt @@ -18,8 +18,8 @@ package com.example.jetcaster.ui.home import com.example.jetcaster.core.model.CategoryInfo import com.example.jetcaster.core.model.EpisodeInfo -import com.example.jetcaster.core.model.PodcastCategoryEpisode import com.example.jetcaster.core.model.PodcastInfo +import com.example.jetcaster.core.model.PodcastToEpisodeInfo import java.time.OffsetDateTime import java.time.ZoneOffset @@ -58,8 +58,8 @@ val PreviewEpisodes = listOf( ) ) -val PreviewPodcastCategoryEpisodes = listOf( - PodcastCategoryEpisode( +val PreviewPodcastEpisodes = listOf( + PodcastToEpisodeInfo( podcast = PreviewPodcasts[0], episode = PreviewEpisodes[0], ) diff --git a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/library/Library.kt b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/library/Library.kt index f425042ae..495eb035c 100644 --- a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/library/Library.kt +++ b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/library/Library.kt @@ -40,12 +40,6 @@ fun LazyListScope.libraryItems( navigateToPlayer: (EpisodeInfo) -> Unit, onQueueEpisode: (PlayerEpisode) -> Unit ) { - val podcast = library.podcast - if (podcast == null || library.episodes.isEmpty()) { - // TODO: Empty state - return - } - item { Text( text = stringResource(id = R.string.latest_episodes), @@ -58,12 +52,12 @@ fun LazyListScope.libraryItems( } items( - library.episodes, - key = { it.uri } + library, + key = { it.episode.uri } ) { item -> EpisodeListItem( - episode = item, - podcast = podcast, + episode = item.episode, + podcast = item.podcast, onClick = navigateToPlayer, onQueueEpisode = onQueueEpisode, modifier = Modifier.fillParentMaxWidth(), @@ -76,12 +70,6 @@ fun LazyGridScope.libraryItems( navigateToPlayer: (EpisodeInfo) -> Unit, onQueueEpisode: (PlayerEpisode) -> Unit ) { - val podcast = library.podcast - if (podcast == null || library.episodes.isEmpty()) { - // TODO: Empty state - return - } - fullWidthItem { Text( text = stringResource(id = R.string.latest_episodes), @@ -94,12 +82,12 @@ fun LazyGridScope.libraryItems( } items( - library.episodes, - key = { it.uri } + library, + key = { it.episode.uri } ) { item -> EpisodeListItem( - episode = item, - podcast = podcast, + episode = item.episode, + podcast = item.podcast, onClick = navigateToPlayer, onQueueEpisode = onQueueEpisode, modifier = Modifier.fillMaxWidth() From a6ebcbf5eff9993789cfa801407a70c63509e8df Mon Sep 17 00:00:00 2001 From: arriolac Date: Thu, 25 Apr 2024 20:40:31 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=A4=96=20Apply=20Spotless?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jetcaster/core/model/PodcastToEpisodeInfo.kt | 16 ++++++++++++++++ .../java/com/example/jetcaster/ui/home/Home.kt | 6 +++--- .../example/jetcaster/ui/home/HomeViewModel.kt | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastToEpisodeInfo.kt b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastToEpisodeInfo.kt index cbd004e47..9f93bd3c7 100644 --- a/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastToEpisodeInfo.kt +++ b/Jetcaster/core/model/src/main/java/com/example/jetcaster/core/model/PodcastToEpisodeInfo.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.example.jetcaster.core.model data class PodcastToEpisodeInfo( diff --git a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/Home.kt b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/Home.kt index d7898e17c..4dbcb40e2 100644 --- a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/Home.kt +++ b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/Home.kt @@ -121,12 +121,12 @@ import com.example.jetcaster.util.fullWidthItem import com.example.jetcaster.util.isCompact import com.example.jetcaster.util.quantityStringResource import com.example.jetcaster.util.radialGradientScrim -import kotlinx.collections.immutable.PersistentList -import kotlinx.collections.immutable.toPersistentList -import kotlinx.coroutines.launch import java.time.Duration import java.time.LocalDateTime import java.time.OffsetDateTime +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.toPersistentList +import kotlinx.coroutines.launch data class HomeState( val windowSizeClass: WindowSizeClass, diff --git a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt index 9092b4641..a917e0336 100644 --- a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt +++ b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt @@ -36,6 +36,7 @@ import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.core.player.EpisodePlayer import com.example.jetcaster.core.util.combine import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList @@ -45,7 +46,6 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.launch -import javax.inject.Inject @OptIn(ExperimentalCoroutinesApi::class) From 6f80d1f8dab6076f0bcf035d8506fbdf53ed3514 Mon Sep 17 00:00:00 2001 From: Chris Arriola Date: Fri, 26 Apr 2024 09:49:52 -0700 Subject: [PATCH 3/4] Use .shareIn for subscribed podcasts. --- .../com/example/jetcaster/ui/home/HomeViewModel.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt index a917e0336..73cfa3560 100644 --- a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt +++ b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt @@ -36,16 +36,18 @@ import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.core.player.EpisodePlayer import com.example.jetcaster.core.util.combine import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.launch +import javax.inject.Inject @OptIn(ExperimentalCoroutinesApi::class) @@ -71,7 +73,8 @@ class HomeViewModel @Inject constructor( // Holds the view state if the UI is refreshing for new data private val refreshing = MutableStateFlow(false) - private val followedPodcasts = podcastStore.followedPodcastsSortedByLastEpisode(limit = 10) + private val subscribedPodcasts = podcastStore.followedPodcastsSortedByLastEpisode(limit = 10) + .shareIn(viewModelScope, SharingStarted.WhileSubscribed()) val state: StateFlow get() = _state @@ -83,7 +86,7 @@ class HomeViewModel @Inject constructor( combine( homeCategories, selectedHomeCategory, - followedPodcasts, + subscribedPodcasts, refreshing, _selectedCategory.flatMapLatest { selectedCategory -> filterableCategoriesUseCase(selectedCategory) @@ -91,9 +94,9 @@ class HomeViewModel @Inject constructor( _selectedCategory.flatMapLatest { podcastCategoryFilterUseCase(it) }, - followedPodcasts.flatMapLatest { podcast -> + subscribedPodcasts.flatMapLatest { podcasts -> episodeStore.episodesInPodcasts( - podcastUris = podcast.map { it.podcast.uri }, + podcastUris = podcasts.map { it.podcast.uri }, limit = 20 ) } From f1231a4a322726ab03c0bb1ce783e92a2f805a15 Mon Sep 17 00:00:00 2001 From: arriolac Date: Fri, 26 Apr 2024 18:55:51 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=A4=96=20Apply=20Spotless?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/example/jetcaster/ui/home/HomeViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt index 73cfa3560..bc0eecd59 100644 --- a/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt +++ b/Jetcaster/mobile/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt @@ -36,6 +36,7 @@ import com.example.jetcaster.core.model.PodcastInfo import com.example.jetcaster.core.player.EpisodePlayer import com.example.jetcaster.core.util.combine import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList @@ -47,7 +48,6 @@ import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.launch -import javax.inject.Inject @OptIn(ExperimentalCoroutinesApi::class)