Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class EpisodeStore(
fun episodesInPodcast(
podcastUri: String,
limit: Int = Integer.MAX_VALUE
): Flow<List<Episode>> {
): Flow<List<EpisodeToPodcast>> {
return episodesDao.episodesForPodcastUri(podcastUri, limit)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ abstract class EpisodesDao : BaseDao<Episode> {
abstract fun episodesForPodcastUri(
podcastUri: String,
limit: Int
): Flow<List<Episode>>
): Flow<List<EpisodeToPodcast>>

@Transaction
@Query(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,12 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import com.example.jetcaster.R
import com.example.jetcaster.data.Category
import com.example.jetcaster.data.EpisodeToPodcast
import com.example.jetcaster.data.PodcastWithExtraInfo
import com.example.jetcaster.ui.home.category.PodcastCategoryViewState
import com.example.jetcaster.ui.home.discover.DiscoverViewState
import com.example.jetcaster.ui.home.discover.discoverItems
import com.example.jetcaster.ui.home.library.libraryItems
import com.example.jetcaster.ui.theme.JetcasterTheme
import com.example.jetcaster.ui.theme.Keyline1
import com.example.jetcaster.ui.theme.MinContrastOfPrimaryVsSurface
Expand Down Expand Up @@ -108,6 +110,7 @@ fun Home(
selectedHomeCategory = viewState.selectedHomeCategory,
discoverViewState = viewState.discoverViewState,
podcastCategoryViewState = viewState.podcastCategoryViewState,
libraryEpisodes = viewState.libraryEpisodes,
onHomeCategorySelected = viewModel::onHomeCategorySelected,
onCategorySelected = viewModel::onCategorySelected,
onPodcastUnfollowed = viewModel::onPodcastUnfollowed,
Expand Down Expand Up @@ -173,6 +176,7 @@ fun Home(
homeCategories: List<HomeCategory>,
discoverViewState: DiscoverViewState,
podcastCategoryViewState: PodcastCategoryViewState,
libraryEpisodes: List<EpisodeToPodcast>,
modifier: Modifier = Modifier,
onPodcastUnfollowed: (String) -> Unit,
onHomeCategorySelected: (HomeCategory) -> Unit,
Expand Down Expand Up @@ -239,6 +243,7 @@ fun Home(
homeCategories = homeCategories,
discoverViewState = discoverViewState,
podcastCategoryViewState = podcastCategoryViewState,
libraryEpisodes = libraryEpisodes,
scrimColor = scrimColor,
pagerState = pagerState,
onPodcastUnfollowed = onPodcastUnfollowed,
Expand All @@ -260,6 +265,7 @@ private fun HomeContent(
homeCategories: List<HomeCategory>,
discoverViewState: DiscoverViewState,
podcastCategoryViewState: PodcastCategoryViewState,
libraryEpisodes: List<EpisodeToPodcast>,
scrimColor: Color,
pagerState: PagerState,
modifier: Modifier = Modifier,
Expand Down Expand Up @@ -303,7 +309,10 @@ private fun HomeContent(

when (selectedHomeCategory) {
HomeCategory.Library -> {
// TODO
libraryItems(
episodes = libraryEpisodes,
navigateToPlayer = navigateToPlayer
)
}

HomeCategory.Discover -> {
Expand Down Expand Up @@ -504,6 +513,7 @@ fun PreviewHomeContent() {
topPodcasts = PreviewPodcastsWithExtraInfo,
episodes = PreviewEpisodeToPodcasts,
),
libraryEpisodes = emptyList(),
onCategorySelected = {},
onPodcastUnfollowed = {},
navigateToPlayer = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import androidx.lifecycle.viewModelScope
import com.example.jetcaster.Graph
import com.example.jetcaster.data.Category
import com.example.jetcaster.data.CategoryStore
import com.example.jetcaster.data.EpisodeStore
import com.example.jetcaster.data.EpisodeToPodcast
import com.example.jetcaster.data.PodcastStore
import com.example.jetcaster.data.PodcastWithExtraInfo
import com.example.jetcaster.data.PodcastsRepository
Expand All @@ -43,7 +45,8 @@ import kotlinx.coroutines.launch
class HomeViewModel(
private val podcastsRepository: PodcastsRepository = Graph.podcastRepository,
private val categoryStore: CategoryStore = Graph.categoryStore,
private val podcastStore: PodcastStore = Graph.podcastStore
private val podcastStore: PodcastStore = Graph.podcastStore,
private val episodeStore: EpisodeStore = Graph.episodeStore
) : ViewModel() {
// Holds our currently selected home category
private val selectedHomeCategory = MutableStateFlow(HomeCategory.Discover)
Expand All @@ -56,6 +59,18 @@ class HomeViewModel(
// Holds the view state if the UI is refreshing for new data
private val refreshing = MutableStateFlow(false)

@OptIn(ExperimentalCoroutinesApi::class)
private val libraryEpisodes = podcastStore.followedPodcastsSortedByLastEpisode()
.flatMapLatest { followedPodcasts ->
combine(
followedPodcasts.map { p ->
episodeStore.episodesInPodcast(p.podcast.uri, 5)
}
) { allEpisodes ->
allEpisodes.toList().flatten().sortedByDescending { it.episode.published }
}
}

private val discover = combine(
categoryStore.categoriesSortedByPodcastCount()
.onEach { categories ->
Expand Down Expand Up @@ -110,20 +125,23 @@ class HomeViewModel(
podcastStore.followedPodcastsSortedByLastEpisode(limit = 20),
refreshing,
discover,
podcastCategory
podcastCategory,
libraryEpisodes
) { homeCategories,
selectedHomeCategory,
podcasts,
refreshing,
discoverViewState,
podcastCategoryViewState ->
podcastCategoryViewState,
libraryEpisodes ->
HomeViewState(
homeCategories = homeCategories,
selectedHomeCategory = selectedHomeCategory,
featuredPodcasts = podcasts.toPersistentList(),
refreshing = refreshing,
discoverViewState = discoverViewState,
podcastCategoryViewState = podcastCategoryViewState,
libraryEpisodes = libraryEpisodes,
errorMessage = null, /* TODO */
)
}.catch { throwable ->
Expand Down Expand Up @@ -181,5 +199,6 @@ data class HomeViewState(
val homeCategories: List<HomeCategory> = emptyList(),
val discoverViewState: DiscoverViewState = DiscoverViewState(),
val podcastCategoryViewState: PodcastCategoryViewState = PodcastCategoryViewState(),
val libraryEpisodes: List<EpisodeToPodcast> = emptyList(),
val errorMessage: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ import com.example.jetcaster.util.ToggleFollowPodcastIconButton
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle

data class PodcastCategoryViewState(
val topPodcasts: List<PodcastWithExtraInfo> = emptyList(),
val episodes: List<EpisodeToPodcast> = emptyList()
)
fun LazyListScope.podcastCategory(
topPodcasts: List<PodcastWithExtraInfo>,
episodes: List<EpisodeToPodcast>,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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.ui.home.library

import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.items
import androidx.compose.ui.Modifier
import com.example.jetcaster.data.EpisodeToPodcast
import com.example.jetcaster.ui.home.category.EpisodeListItem

fun LazyListScope.libraryItems(
episodes: List<EpisodeToPodcast>,
navigateToPlayer: (String) -> Unit
) {
if (episodes.isEmpty()) {
// TODO: Empty state
return
}

items(episodes, key = { it.episode.uri }) { item ->
EpisodeListItem(
episode = item.episode,
podcast = item.podcast,
onClick = navigateToPlayer,
modifier = Modifier.fillParentMaxWidth()
)
}
}
43 changes: 43 additions & 0 deletions Jetcaster/app/src/main/java/com/example/jetcaster/util/Flows.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,46 @@ fun <T1, T2, T3, T4, T5, T6, R> combine(
args[5] as T6,
)
}

/**
* Combines seven flows into a single flow by combining their latest values using the provided transform function.
*
* @param flow The first flow.
* @param flow2 The second flow.
* @param flow3 The third flow.
* @param flow4 The fourth flow.
* @param flow5 The fifth flow.
* @param flow6 The sixth flow.
* @param flow7 The seventh flow.
* @param transform The transform function to combine the latest values of the seven flows.
* @return A flow that emits the results of the transform function applied to the latest values of the seven flows.
*/
fun <T1, T2, T3, T4, T5, T6, T7, R> combine(
flow: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
flow4: Flow<T4>,
flow5: Flow<T5>,
flow6: Flow<T6>,
flow7: Flow<T7>,
transform: suspend (T1, T2, T3, T4, T5, T6, T7) -> R
): Flow<R> =
kotlinx.coroutines.flow.combine(
flow,
flow2,
flow3,
flow4,
flow5,
flow6,
flow7
) { args: Array<*> ->
transform(
args[0] as T1,
args[1] as T2,
args[2] as T3,
args[3] as T4,
args[4] as T5,
args[5] as T6,
args[6] as T7,
)
}