Skip to content

Commit

Permalink
Introduce Event sink pattern (#48)
Browse files Browse the repository at this point in the history
* Use eventSink pattern in SubscriptionsScreen

* Use eventSink pattern in PodcastDetails Screen

* Use eventSink pattern in EpisodeDetails Screen

* Use eventSink pattern in Explore Screen
  • Loading branch information
mr3y-the-programmer authored Apr 26, 2024
1 parent 6d386f5 commit 3615d90
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 227 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,20 @@ sealed interface EpisodeDetailsUIEvent {
data object RefreshResultConsumed : EpisodeDetailsUIEvent

data object Retry : EpisodeDetailsUIEvent

data class PlayEpisode(val episode: Episode) : EpisodeDetailsUIEvent

data object Pause : EpisodeDetailsUIEvent

data class DownloadEpisode(val episode: Episode) : EpisodeDetailsUIEvent

data class ResumeDownloading(val episodeId: Long) : EpisodeDetailsUIEvent

data class PauseDownloading(val episodeId: Long) : EpisodeDetailsUIEvent

data class AddEpisodeToQueue(val episode: Episode) : EpisodeDetailsUIEvent

data class RemoveEpisodeFromQueue(val episodeId: Long) : EpisodeDetailsUIEvent

data object ErrorPlayingStatusConsumed : EpisodeDetailsUIEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ internal fun EpisodeDetailsPresenter(
}
}
EpisodeDetailsUIEvent.RefreshResultConsumed -> refreshResult = null
else -> {}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,14 @@ sealed interface PodcastDetailsUIEvent {
data object RefreshResultConsumed : PodcastDetailsUIEvent

data object Retry : PodcastDetailsUIEvent

data class PlayEpisode(val episode: Episode) : PodcastDetailsUIEvent

data object Pause : PodcastDetailsUIEvent

data class AddEpisodeToQueue(val episode: Episode) : PodcastDetailsUIEvent

data class RemoveEpisodeFromQueue(val episodeId: Long) : PodcastDetailsUIEvent

data object ErrorPlayingStatusConsumed : PodcastDetailsUIEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ internal fun PodcastDetailsPresenter(
isEpisodesLoading = false
}
}
else -> {}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.mr3y.podcaster.ui.presenter.subscriptions

import com.mr3y.podcaster.core.model.Episode
import com.mr3y.podcaster.core.model.EpisodeWithDownloadMetadata
import com.mr3y.podcaster.core.model.Podcast
import com.mr3y.podcaster.ui.presenter.RefreshResult
Expand All @@ -19,4 +20,16 @@ sealed interface SubscriptionsUIEvent {
data object Refresh : SubscriptionsUIEvent

data object RefreshResultConsumed : SubscriptionsUIEvent

data class ToggleAppTheme(val isDark: Boolean) : SubscriptionsUIEvent

data class PlayEpisode(val episode: Episode) : SubscriptionsUIEvent

data object Pause : SubscriptionsUIEvent

data class AddEpisodeToQueue(val episode: Episode) : SubscriptionsUIEvent

data class RemoveEpisodeFromQueue(val episodeId: Long) : SubscriptionsUIEvent

data object ErrorPlayingStatusConsumed : SubscriptionsUIEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ internal fun SubscriptionsPresenter(
}
}
is SubscriptionsUIEvent.RefreshResultConsumed -> refreshResult = null
else -> {}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import com.mr3y.podcaster.ui.components.TopBar
import com.mr3y.podcaster.ui.components.rememberHtmlToAnnotatedString
import com.mr3y.podcaster.ui.presenter.PodcasterAppState
import com.mr3y.podcaster.ui.presenter.RefreshResult
import com.mr3y.podcaster.ui.presenter.episodedetails.EpisodeDetailsUIEvent
import com.mr3y.podcaster.ui.presenter.episodedetails.EpisodeDetailsUIState
import com.mr3y.podcaster.ui.presenter.episodedetails.EpisodeDetailsViewModel
import com.mr3y.podcaster.ui.preview.DynamicColorsParameterProvider
Expand Down Expand Up @@ -99,21 +100,25 @@ fun EpisodeDetailsScreen(
EpisodeDetailsScreen(
state = state,
onNavigateUp = onNavigateUp,
onRetry = viewModel::retry,
onRefresh = viewModel::refresh,
onPlayEpisode = appState::play,
onPause = appState::pause,
onAddEpisodeToQueue = appState::addToQueue,
onRemoveEpisodeFromQueue = appState::removeFromQueue,
onDownloadingEpisode = appState::downloadEpisode,
onResumeDownloadingEpisode = appState::resumeDownloading,
onPauseDownloadingEpisode = appState::pauseDownloading,
isSelected = state.episode?.id == currentlyPlayingEpisode?.episode?.id,
playingStatus = currentlyPlayingEpisode?.playingStatus,
onConsumeErrorPlayingStatus = appState::consumeErrorPlayingStatus,
externalContentPadding = contentPadding,
excludedWindowInsets = excludedWindowInsets,
onConsumeResult = viewModel::consumeRefreshResult,
eventSink = { event ->
when(event) {
is EpisodeDetailsUIEvent.Refresh -> viewModel.refresh()
is EpisodeDetailsUIEvent.RefreshResultConsumed -> viewModel.consumeRefreshResult()
is EpisodeDetailsUIEvent.Retry -> viewModel.retry()
is EpisodeDetailsUIEvent.PlayEpisode -> appState.play(event.episode)
is EpisodeDetailsUIEvent.Pause -> appState.pause()
is EpisodeDetailsUIEvent.DownloadEpisode -> appState.downloadEpisode(event.episode)
is EpisodeDetailsUIEvent.ResumeDownloading -> appState.resumeDownloading(event.episodeId)
is EpisodeDetailsUIEvent.PauseDownloading -> appState.pauseDownloading(event.episodeId)
is EpisodeDetailsUIEvent.AddEpisodeToQueue -> appState.addToQueue(event.episode)
is EpisodeDetailsUIEvent.RemoveEpisodeFromQueue -> appState.removeFromQueue(event.episodeId)
is EpisodeDetailsUIEvent.ErrorPlayingStatusConsumed -> appState.consumeErrorPlayingStatus()
}
},
modifier = modifier,
)
}
Expand All @@ -122,21 +127,11 @@ fun EpisodeDetailsScreen(
fun EpisodeDetailsScreen(
state: EpisodeDetailsUIState,
onNavigateUp: () -> Unit,
onRetry: () -> Unit,
onRefresh: () -> Unit,
onPlayEpisode: (Episode) -> Unit,
onPause: () -> Unit,
onAddEpisodeToQueue: (Episode) -> Unit,
onRemoveEpisodeFromQueue: (episodeId: Long) -> Unit,
onDownloadingEpisode: (Episode) -> Unit,
onResumeDownloadingEpisode: (episodeId: Long) -> Unit,
onPauseDownloadingEpisode: (episodeId: Long) -> Unit,
isSelected: Boolean,
playingStatus: PlayingStatus?,
onConsumeErrorPlayingStatus: () -> Unit,
externalContentPadding: PaddingValues,
excludedWindowInsets: WindowInsets?,
onConsumeResult: () -> Unit,
eventSink: (EpisodeDetailsUIEvent) -> Unit,
modifier: Modifier = Modifier,
) {
val snackBarHostState = remember { SnackbarHostState() }
Expand All @@ -149,13 +144,13 @@ fun EpisodeDetailsScreen(
snackBarHostState.showSnackbar(
message = strings.episode_details_refresh_result_error,
)
onConsumeResult()
eventSink(EpisodeDetailsUIEvent.RefreshResultConsumed)
}
is RefreshResult.Mixed -> {
snackBarHostState.showSnackbar(
message = strings.episode_details_refresh_result_mixed,
)
onConsumeResult()
eventSink(EpisodeDetailsUIEvent.RefreshResultConsumed)
}
is RefreshResult.Ok, null -> {}
}
Expand All @@ -164,7 +159,7 @@ fun EpisodeDetailsScreen(
snackBarHostState.showSnackbar(
message = strings.generic_error_message,
)
onConsumeErrorPlayingStatus()
eventSink(EpisodeDetailsUIEvent.ErrorPlayingStatusConsumed)
}
else -> {}
}
Expand Down Expand Up @@ -200,7 +195,7 @@ fun EpisodeDetailsScreen(
}
PullToRefresh(
isRefreshingDone = !state.isRefreshing,
onRefresh = onRefresh,
onRefresh = { eventSink(EpisodeDetailsUIEvent.Refresh) },
) {
Scaffold(
topBar = {
Expand Down Expand Up @@ -243,7 +238,7 @@ fun EpisodeDetailsScreen(
}
state.episode == null -> {
Error(
onRetry = onRetry,
onRetry = { eventSink(EpisodeDetailsUIEvent.Retry) },
modifier = Modifier
.fillMaxSize()
.align(Alignment.Center),
Expand All @@ -257,14 +252,14 @@ fun EpisodeDetailsScreen(
Header(
episode = state.episode,
downloadMetadata = state.downloadMetadata,
onPlay = onPlayEpisode,
onPause = onPause,
onPlay = { eventSink(EpisodeDetailsUIEvent.PlayEpisode(it)) },
onPause = { eventSink(EpisodeDetailsUIEvent.Pause) },
queueEpisodes = state.queueEpisodesIds,
onAddEpisodeToQueue = onAddEpisodeToQueue,
onRemoveEpisodeFromQueue = onRemoveEpisodeFromQueue,
onDownloadingEpisode = onDownloadingEpisode,
onResumeDownloadingEpisode = onResumeDownloadingEpisode,
onPauseDownloadingEpisode = onPauseDownloadingEpisode,
onAddEpisodeToQueue = { eventSink(EpisodeDetailsUIEvent.AddEpisodeToQueue(it)) },
onRemoveEpisodeFromQueue = { eventSink(EpisodeDetailsUIEvent.RemoveEpisodeFromQueue(it)) },
onDownloadingEpisode = { eventSink(EpisodeDetailsUIEvent.DownloadEpisode(it)) },
onResumeDownloadingEpisode = { eventSink(EpisodeDetailsUIEvent.ResumeDownloading(it)) },
onPauseDownloadingEpisode = { eventSink(EpisodeDetailsUIEvent.PauseDownloading(it)) },
isSelected = isSelected,
playingStatus = playingStatus,
dominantColor = dominantColorState.color,
Expand Down Expand Up @@ -432,21 +427,11 @@ fun EpisodeDetailsScreenPreview(
downloadMetadata = DownloadMetadata,
),
onNavigateUp = {},
onRetry = {},
onRefresh = {},
onPlayEpisode = {},
onPause = {},
onAddEpisodeToQueue = {},
onRemoveEpisodeFromQueue = {},
onDownloadingEpisode = {},
onResumeDownloadingEpisode = {},
onPauseDownloadingEpisode = {},
isSelected = false,
playingStatus = null,
onConsumeErrorPlayingStatus = {},
externalContentPadding = PaddingValues(0.dp),
excludedWindowInsets = null,
onConsumeResult = {},
eventSink = {},
modifier = Modifier.fillMaxSize(),
)
}
Expand All @@ -466,21 +451,11 @@ fun EpisodeDetailsErrorPreview() {
downloadMetadata = null,
),
onNavigateUp = {},
onRetry = {},
onRefresh = {},
onPlayEpisode = {},
onPause = {},
onAddEpisodeToQueue = {},
onRemoveEpisodeFromQueue = {},
onDownloadingEpisode = {},
onResumeDownloadingEpisode = {},
onPauseDownloadingEpisode = {},
isSelected = false,
playingStatus = null,
onConsumeErrorPlayingStatus = {},
externalContentPadding = PaddingValues(0.dp),
excludedWindowInsets = null,
onConsumeResult = {},
eventSink = {},
modifier = Modifier.fillMaxSize(),
)
}
Expand Down
Loading

0 comments on commit 3615d90

Please sign in to comment.