Skip to content

Commit

Permalink
Handle case when Favourite episodes are still loading reliably (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
mr3y-the-programmer authored Aug 9, 2024
1 parent 1cff27a commit 68ee43a
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.mr3y.podcaster.ui.presenter.favorites

import com.mr3y.podcaster.core.model.Episode

data class FavoritesUIState(
val isLoading: Boolean,
val favorites: List<Episode>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package com.mr3y.podcaster.ui.presenter.favorites

import android.annotation.SuppressLint
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import app.cash.molecule.RecompositionMode
import app.cash.molecule.launchMolecule
import com.mr3y.podcaster.core.data.PodcastsRepository
Expand All @@ -26,7 +30,15 @@ class FavoritesViewModel @Inject constructor(
@Composable
internal fun FavoritesPresenter(
repository: PodcastsRepository,
): List<Episode> {
): FavoritesUIState {
var isLoading by remember { mutableStateOf(true) }
val favorites by repository.getFavouriteEpisodes().collectAsState(initial = emptyList())
return favorites

LaunchedEffect(Unit) {
repository.countFavouriteEpisodes().apply {
isLoading = false
}
}

return FavoritesUIState(isLoading, favorites)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import com.mr3y.podcaster.LocalStrings
import com.mr3y.podcaster.core.model.Episode
import com.mr3y.podcaster.core.sampledata.Episodes
import com.mr3y.podcaster.ui.components.CoilImage
import com.mr3y.podcaster.ui.components.LoadingIndicator
import com.mr3y.podcaster.ui.components.LocalAnimatedVisibilityScope
import com.mr3y.podcaster.ui.components.LocalSharedTransitionScope
import com.mr3y.podcaster.ui.components.TopBar
Expand All @@ -50,6 +51,7 @@ import com.mr3y.podcaster.ui.components.rememberHtmlToAnnotatedString
import com.mr3y.podcaster.ui.components.rememberSharedContentState
import com.mr3y.podcaster.ui.components.renderInSharedTransitionScopeOverlay
import com.mr3y.podcaster.ui.components.sharedElement
import com.mr3y.podcaster.ui.presenter.favorites.FavoritesUIState
import com.mr3y.podcaster.ui.presenter.favorites.FavoritesViewModel
import com.mr3y.podcaster.ui.preview.DynamicColorsParameterProvider
import com.mr3y.podcaster.ui.preview.PodcasterPreview
Expand All @@ -66,9 +68,9 @@ fun FavoritesScreen(
modifier: Modifier = Modifier,
viewModel: FavoritesViewModel = hiltViewModel(),
) {
val favorites by viewModel.state.collectAsStateWithLifecycle()
val state by viewModel.state.collectAsStateWithLifecycle()
FavoritesScreen(
favorites = favorites,
state = state,
onEpisodeClick = onEpisodeClick,
onNavigateUp = onNavigateUp,
externalContentPadding = contentPadding,
Expand All @@ -79,7 +81,7 @@ fun FavoritesScreen(

@Composable
fun FavoritesScreen(
favorites: List<Episode>,
state: FavoritesUIState,
onEpisodeClick: (episodeId: Long, artworkUrl: String) -> Unit,
onNavigateUp: () -> Unit,
externalContentPadding: PaddingValues,
Expand Down Expand Up @@ -114,16 +116,21 @@ fun FavoritesScreen(
containerColor = MaterialTheme.colorScheme.surface,
modifier = modifier,
) { contentPadding ->
val contentModifier = Modifier
.padding(contentPadding)
.padding(horizontal = 16.dp)
.fillMaxSize()

FavoriteList(
favorites = favorites,
onEpisodeClick = onEpisodeClick,
externalContentPadding = externalContentPadding,
modifier = Modifier
.padding(contentPadding)
.padding(horizontal = 16.dp)
.fillMaxSize(),
)
if (state.isLoading) {
LoadingIndicator(modifier = contentModifier)
} else {
FavoriteList(
favorites = state.favorites,
onEpisodeClick = onEpisodeClick,
externalContentPadding = externalContentPadding,
modifier = contentModifier,
)
}
}
}

Expand Down Expand Up @@ -227,7 +234,7 @@ fun FavoritesScreenPreview(
) {
PodcasterTheme(dynamicColor = isDynamicColorsOn) {
FavoritesScreen(
favorites = Episodes.slice(0..2),
state = FavoritesUIState(isLoading = false, Episodes.slice(0..2)),
onEpisodeClick = { _, _ -> },
onNavigateUp = { },
externalContentPadding = PaddingValues(0.dp),
Expand All @@ -242,7 +249,7 @@ fun FavoritesScreenPreview(
fun FavoritesScreenEmptyFavoritesPreview() {
PodcasterTheme(dynamicColor = false) {
FavoritesScreen(
favorites = emptyList(),
state = FavoritesUIState(isLoading = false, emptyList()),
onEpisodeClick = { _, _ -> },
onNavigateUp = { },
externalContentPadding = PaddingValues(0.dp),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ interface PodcastsRepository {

fun getFavouriteEpisodes(): Flow<List<Episode>>

fun countFavouriteEpisodes(): Long

fun addEpisodeToQueue(episode: Episode)

fun replaceEpisodeInQueue(newEpisode: Episode, oldEpisodeId: Long)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ class DefaultPodcastsRepository @Inject constructor(

override fun getFavouriteEpisodes(): Flow<List<Episode>> = podcastsDao.getFavouriteEpisodes()

override fun countFavouriteEpisodes() = podcastsDao.countFavouriteEpisodes()

override fun addEpisodeToQueue(episode: Episode) {
podcastsDao.addEpisodeToQueue(episode)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ interface PodcastsDao {

fun getFavouriteEpisodes(): Flow<List<Episode>>

fun countFavouriteEpisodes(): Long

fun addEpisodeToQueue(episode: Episode)

fun replaceEpisodeInQueue(newEpisode: Episode, oldEpisodeId: Long)
Expand Down Expand Up @@ -361,6 +363,10 @@ class DefaultPodcastsDao @Inject constructor(
return database.episodeEntityQueries.getFavouriteEpisodes(mapper = ::mapToEpisode).asFlow().mapToList(dispatcher)
}

override fun countFavouriteEpisodes(): Long {
return database.episodeEntityQueries.countFavouriteEpisodes().executeAsOne()
}

override fun addEpisodeToQueue(episode: Episode) {
if (isEpisodeAvailableNonObservable(episode.id)) {
database.queueEntityQueries.insertNewQueueEpisode(episode.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ SELECT * FROM episodeEntity WHERE id == :id;
getFavouriteEpisodes:
SELECT * FROM episodeEntity WHERE isFavourite == 1;

countFavouriteEpisodes:
SELECT count(*) FROM episodeEntity WHERE isFavourite == 1;

hasEpisode:
SELECT 1 FROM episodeEntity WHERE id = :id;

Expand Down

0 comments on commit 68ee43a

Please sign in to comment.