Convert state enum to sealed interface

This commit is contained in:
Florian Renaud 2023-01-10 10:34:45 +01:00
parent e384669d85
commit f8852856c6
3 changed files with 47 additions and 47 deletions

View file

@ -63,10 +63,10 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem
playPauseButton.setOnClickListener { playPauseButton.setOnClickListener {
if (player.currentVoiceBroadcast == voiceBroadcast) { if (player.currentVoiceBroadcast == voiceBroadcast) {
when (player.playingState) { when (player.playingState) {
VoiceBroadcastPlayer.State.PLAYING, VoiceBroadcastPlayer.State.Playing,
VoiceBroadcastPlayer.State.BUFFERING -> callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.Pause) VoiceBroadcastPlayer.State.Buffering -> callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.Pause)
VoiceBroadcastPlayer.State.PAUSED, VoiceBroadcastPlayer.State.Paused,
VoiceBroadcastPlayer.State.IDLE -> callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.PlayOrResume(voiceBroadcast)) VoiceBroadcastPlayer.State.Idle -> callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.PlayOrResume(voiceBroadcast))
} }
} else { } else {
callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.PlayOrResume(voiceBroadcast)) callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.PlayOrResume(voiceBroadcast))
@ -100,17 +100,17 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem
private fun renderPlayingState(holder: Holder, state: VoiceBroadcastPlayer.State) { private fun renderPlayingState(holder: Holder, state: VoiceBroadcastPlayer.State) {
with(holder) { with(holder) {
bufferingView.isVisible = state == VoiceBroadcastPlayer.State.BUFFERING bufferingView.isVisible = state == VoiceBroadcastPlayer.State.Buffering
voiceBroadcastMetadata.isVisible = state != VoiceBroadcastPlayer.State.BUFFERING voiceBroadcastMetadata.isVisible = state != VoiceBroadcastPlayer.State.Buffering
when (state) { when (state) {
VoiceBroadcastPlayer.State.PLAYING, VoiceBroadcastPlayer.State.Playing,
VoiceBroadcastPlayer.State.BUFFERING -> { VoiceBroadcastPlayer.State.Buffering -> {
playPauseButton.setImageResource(R.drawable.ic_play_pause_pause) playPauseButton.setImageResource(R.drawable.ic_play_pause_pause)
playPauseButton.contentDescription = view.resources.getString(R.string.a11y_pause_voice_broadcast) playPauseButton.contentDescription = view.resources.getString(R.string.a11y_pause_voice_broadcast)
} }
VoiceBroadcastPlayer.State.IDLE, VoiceBroadcastPlayer.State.Idle,
VoiceBroadcastPlayer.State.PAUSED -> { VoiceBroadcastPlayer.State.Paused -> {
playPauseButton.setImageResource(R.drawable.ic_play_pause_play) playPauseButton.setImageResource(R.drawable.ic_play_pause_play)
playPauseButton.contentDescription = view.resources.getString(R.string.a11y_play_voice_broadcast) playPauseButton.contentDescription = view.resources.getString(R.string.a11y_play_voice_broadcast)
} }

View file

@ -26,7 +26,7 @@ interface VoiceBroadcastPlayer {
val currentVoiceBroadcast: VoiceBroadcast? val currentVoiceBroadcast: VoiceBroadcast?
/** /**
* The current playing [State], [State.IDLE] by default. * The current playing [State], [State.Idle] by default.
*/ */
val playingState: State val playingState: State
@ -68,11 +68,11 @@ interface VoiceBroadcastPlayer {
/** /**
* Player states. * Player states.
*/ */
enum class State { sealed interface State {
PLAYING, object Playing : State
PAUSED, object Paused : State
BUFFERING, object Buffering : State
IDLE object Idle : State
} }
/** /**

View file

@ -79,7 +79,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
} }
} }
override var playingState = State.IDLE override var playingState: State = State.Idle
@MainThread @MainThread
set(value) { set(value) {
if (field != value) { if (field != value) {
@ -96,7 +96,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
val hasChanged = currentVoiceBroadcast != voiceBroadcast val hasChanged = currentVoiceBroadcast != voiceBroadcast
when { when {
hasChanged -> startPlayback(voiceBroadcast) hasChanged -> startPlayback(voiceBroadcast)
playingState == State.PAUSED -> resumePlayback() playingState == State.Paused -> resumePlayback()
else -> Unit else -> Unit
} }
} }
@ -107,7 +107,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
override fun stop() { override fun stop() {
// Update state // Update state
playingState = State.IDLE playingState = State.Idle
// Stop and release media players // Stop and release media players
stopPlayer() stopPlayer()
@ -129,7 +129,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
listeners[voiceBroadcast.voiceBroadcastId]?.add(listener) ?: run { listeners[voiceBroadcast.voiceBroadcastId]?.add(listener) ?: run {
listeners[voiceBroadcast.voiceBroadcastId] = CopyOnWriteArrayList<Listener>().apply { add(listener) } listeners[voiceBroadcast.voiceBroadcastId] = CopyOnWriteArrayList<Listener>().apply { add(listener) }
} }
listener.onPlayingStateChanged(if (voiceBroadcast == currentVoiceBroadcast) playingState else State.IDLE) listener.onPlayingStateChanged(if (voiceBroadcast == currentVoiceBroadcast) playingState else State.Idle)
listener.onLiveModeChanged(voiceBroadcast == currentVoiceBroadcast) listener.onLiveModeChanged(voiceBroadcast == currentVoiceBroadcast)
} }
@ -139,11 +139,11 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
private fun startPlayback(voiceBroadcast: VoiceBroadcast) { private fun startPlayback(voiceBroadcast: VoiceBroadcast) {
// Stop listening previous voice broadcast if any // Stop listening previous voice broadcast if any
if (playingState != State.IDLE) stop() if (playingState != State.Idle) stop()
currentVoiceBroadcast = voiceBroadcast currentVoiceBroadcast = voiceBroadcast
playingState = State.BUFFERING playingState = State.Buffering
observeVoiceBroadcastStateEvent(voiceBroadcast) observeVoiceBroadcastStateEvent(voiceBroadcast)
} }
@ -175,13 +175,13 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
private fun onPlaylistUpdated() { private fun onPlaylistUpdated() {
when (playingState) { when (playingState) {
State.PLAYING, State.Playing,
State.PAUSED -> { State.Paused -> {
if (nextMediaPlayer == null && !isPreparingNextPlayer) { if (nextMediaPlayer == null && !isPreparingNextPlayer) {
prepareNextMediaPlayer() prepareNextMediaPlayer()
} }
} }
State.BUFFERING -> { State.Buffering -> {
val nextItem = if (isLiveListening && playlist.currentSequence == null) { val nextItem = if (isLiveListening && playlist.currentSequence == null) {
// live listening, jump to the last item if playback has not started // live listening, jump to the last item if playback has not started
playlist.lastOrNull() playlist.lastOrNull()
@ -193,7 +193,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
startPlayback(nextItem.startTime) startPlayback(nextItem.startTime)
} }
} }
State.IDLE -> Unit // Should not happen State.Idle -> Unit // Should not happen
} }
} }
@ -213,7 +213,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
if (sequencePosition > 0) { if (sequencePosition > 0) {
mp.seekTo(sequencePosition) mp.seekTo(sequencePosition)
} }
playingState = State.PLAYING playingState = State.Playing
prepareNextMediaPlayer() prepareNextMediaPlayer()
} }
} catch (failure: Throwable) { } catch (failure: Throwable) {
@ -224,7 +224,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
} }
private fun pausePlayback() { private fun pausePlayback() {
playingState = State.PAUSED // This will trigger a playing state update and save the current position playingState = State.Paused // This will trigger a playing state update and save the current position
if (currentMediaPlayer != null) { if (currentMediaPlayer != null) {
currentMediaPlayer?.pause() currentMediaPlayer?.pause()
} else { } else {
@ -234,7 +234,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
private fun resumePlayback() { private fun resumePlayback() {
if (currentMediaPlayer != null) { if (currentMediaPlayer != null) {
playingState = State.PLAYING playingState = State.Playing
currentMediaPlayer?.start() currentMediaPlayer?.start()
} else { } else {
val savedPosition = currentVoiceBroadcast?.voiceBroadcastId?.let { playbackTracker.getPlaybackTime(it) } ?: 0 val savedPosition = currentVoiceBroadcast?.voiceBroadcastId?.let { playbackTracker.getPlaybackTime(it) } ?: 0
@ -247,11 +247,11 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
voiceBroadcast != currentVoiceBroadcast -> { voiceBroadcast != currentVoiceBroadcast -> {
playbackTracker.updatePausedAtPlaybackTime(voiceBroadcast.voiceBroadcastId, positionMillis, positionMillis.toFloat() / duration) playbackTracker.updatePausedAtPlaybackTime(voiceBroadcast.voiceBroadcastId, positionMillis, positionMillis.toFloat() / duration)
} }
playingState == State.PLAYING || playingState == State.BUFFERING -> { playingState == State.Playing || playingState == State.Buffering -> {
updateLiveListeningMode(positionMillis) updateLiveListeningMode(positionMillis)
startPlayback(positionMillis) startPlayback(positionMillis)
} }
playingState == State.IDLE || playingState == State.PAUSED -> { playingState == State.Idle || playingState == State.Paused -> {
stopPlayer() stopPlayer()
playbackTracker.updatePausedAtPlaybackTime(voiceBroadcast.voiceBroadcastId, positionMillis, positionMillis.toFloat() / duration) playbackTracker.updatePausedAtPlaybackTime(voiceBroadcast.voiceBroadcastId, positionMillis, positionMillis.toFloat() / duration)
} }
@ -267,15 +267,15 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
isPreparingNextPlayer = false isPreparingNextPlayer = false
nextMediaPlayer = mp nextMediaPlayer = mp
when (playingState) { when (playingState) {
State.PLAYING, State.Playing,
State.PAUSED -> { State.Paused -> {
currentMediaPlayer?.setNextMediaPlayer(mp) currentMediaPlayer?.setNextMediaPlayer(mp)
} }
State.BUFFERING -> { State.Buffering -> {
mp.start() mp.start()
onNextMediaPlayerStarted(mp) onNextMediaPlayerStarted(mp)
} }
State.IDLE -> stopPlayer() State.Idle -> stopPlayer()
} }
} }
} }
@ -327,10 +327,10 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
currentVoiceBroadcast?.voiceBroadcastId?.let { voiceBroadcastId -> currentVoiceBroadcast?.voiceBroadcastId?.let { voiceBroadcastId ->
// Start or stop playback ticker // Start or stop playback ticker
when (playingState) { when (playingState) {
State.PLAYING -> playbackTicker.startPlaybackTicker(voiceBroadcastId) State.Playing -> playbackTicker.startPlaybackTicker(voiceBroadcastId)
State.PAUSED, State.Paused,
State.BUFFERING, State.Buffering,
State.IDLE -> playbackTicker.stopPlaybackTicker(voiceBroadcastId) State.Idle -> playbackTicker.stopPlaybackTicker(voiceBroadcastId)
} }
// Notify state change to all the listeners attached to the current voice broadcast id // Notify state change to all the listeners attached to the current voice broadcast id
listeners[voiceBroadcastId]?.forEach { listener -> listener.onPlayingStateChanged(playingState) } listeners[voiceBroadcastId]?.forEach { listener -> listener.onPlayingStateChanged(playingState) }
@ -348,7 +348,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
// the current voice broadcast is not live (ended) // the current voice broadcast is not live (ended)
mostRecentVoiceBroadcastEvent?.isLive != true -> false mostRecentVoiceBroadcastEvent?.isLive != true -> false
// the player is stopped or paused // the player is stopped or paused
playingState == State.IDLE || playingState == State.PAUSED -> false playingState == State.Idle || playingState == State.Paused -> false
seekPosition != null -> { seekPosition != null -> {
val seekDirection = seekPosition.compareTo(getCurrentPlaybackPosition() ?: 0) val seekDirection = seekPosition.compareTo(getCurrentPlaybackPosition() ?: 0)
val newSequence = playlist.findByPosition(seekPosition)?.sequence val newSequence = playlist.findByPosition(seekPosition)?.sequence
@ -374,13 +374,13 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
private fun onLiveListeningChanged(isLiveListening: Boolean) { private fun onLiveListeningChanged(isLiveListening: Boolean) {
// Live has ended and last chunk has been reached, we can stop the playback // Live has ended and last chunk has been reached, we can stop the playback
if (!isLiveListening && playingState == State.BUFFERING && playlist.currentSequence == mostRecentVoiceBroadcastEvent?.content?.lastChunkSequence) { if (!isLiveListening && playingState == State.Buffering && playlist.currentSequence == mostRecentVoiceBroadcastEvent?.content?.lastChunkSequence) {
stop() stop()
} }
} }
private fun onNextMediaPlayerStarted(mp: MediaPlayer) { private fun onNextMediaPlayerStarted(mp: MediaPlayer) {
playingState = State.PLAYING playingState = State.Playing
playlist.currentSequence = playlist.currentSequence?.inc() playlist.currentSequence = playlist.currentSequence?.inc()
currentMediaPlayer = mp currentMediaPlayer = mp
nextMediaPlayer = null nextMediaPlayer = null
@ -427,7 +427,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
stop() stop()
} else { } else {
// Enter in buffering mode and release current media player // Enter in buffering mode and release current media player
playingState = State.BUFFERING playingState = State.Buffering
currentMediaPlayer?.release() currentMediaPlayer?.release()
currentMediaPlayer = null currentMediaPlayer = null
} }
@ -462,18 +462,18 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
val playbackTime = getCurrentPlaybackPosition() val playbackTime = getCurrentPlaybackPosition()
val percentage = getCurrentPlaybackPercentage() val percentage = getCurrentPlaybackPercentage()
when (playingState) { when (playingState) {
State.PLAYING -> { State.Playing -> {
if (playbackTime != null && percentage != null) { if (playbackTime != null && percentage != null) {
playbackTracker.updatePlayingAtPlaybackTime(id, playbackTime, percentage) playbackTracker.updatePlayingAtPlaybackTime(id, playbackTime, percentage)
} }
} }
State.PAUSED, State.Paused,
State.BUFFERING -> { State.Buffering -> {
if (playbackTime != null && percentage != null) { if (playbackTime != null && percentage != null) {
playbackTracker.updatePausedAtPlaybackTime(id, playbackTime, percentage) playbackTracker.updatePausedAtPlaybackTime(id, playbackTime, percentage)
} }
} }
State.IDLE -> { State.Idle -> {
if (playbackTime == null || percentage == null || (playlist.duration - playbackTime) < 50) { if (playbackTime == null || percentage == null || (playlist.duration - playbackTime) < 50) {
playbackTracker.stopPlayback(id) playbackTracker.stopPlayback(id)
} else { } else {