From 2d006f87256644087409bbc102156e7b1894055e Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 10 Nov 2022 15:59:28 +0100 Subject: [PATCH] Bind listener to live playback flag --- .../MessageVoiceBroadcastListeningItem.kt | 10 +++++- .../listening/VoiceBroadcastPlayer.kt | 9 +++-- .../listening/VoiceBroadcastPlayerImpl.kt | 33 ++++++++++++++++--- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceBroadcastListeningItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceBroadcastListeningItem.kt index b114f95f97..7c7e69f320 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceBroadcastListeningItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceBroadcastListeningItem.kt @@ -44,7 +44,15 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem } private fun bindVoiceBroadcastItem(holder: Holder) { - playerListener = VoiceBroadcastPlayer.Listener { renderPlayingState(holder, it) } + playerListener = object : VoiceBroadcastPlayer.Listener { + override fun onPlayingStateChanged(state: VoiceBroadcastPlayer.State) { + renderPlayingState(holder, state) + } + + override fun onLiveModeChanged(isLive: Boolean) { + renderLiveIndicator(holder) + } + } player.addListener(voiceBroadcast, playerListener) bindSeekBar(holder) bindButtons(holder) diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayer.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayer.kt index 02e843965f..0de88e9992 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayer.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayer.kt @@ -78,10 +78,15 @@ interface VoiceBroadcastPlayer { /** * Listener related to [VoiceBroadcastPlayer]. */ - fun interface Listener { + interface Listener { /** * Notify about [VoiceBroadcastPlayer.playingState] changes. */ - fun onStateChanged(state: State) + fun onPlayingStateChanged(state: State) = Unit + + /** + * Notify about [VoiceBroadcastPlayer.isLiveListening] changes. + */ + fun onLiveModeChanged(isLive: Boolean) = Unit } } diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt index 573a178c78..56c80ddfb1 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt @@ -121,7 +121,8 @@ class VoiceBroadcastPlayerImpl @Inject constructor( listeners[voiceBroadcast.voiceBroadcastId]?.add(listener) ?: run { listeners[voiceBroadcast.voiceBroadcastId] = CopyOnWriteArrayList().apply { add(listener) } } - listener.onStateChanged(if (voiceBroadcast == currentVoiceBroadcast) playingState else State.IDLE) + listener.onPlayingStateChanged(if (voiceBroadcast == currentVoiceBroadcast) playingState else State.IDLE) + listener.onLiveModeChanged(if (voiceBroadcast == currentVoiceBroadcast) isLiveListening else false) } override fun removeListener(voiceBroadcast: VoiceBroadcast, listener: Listener) { @@ -318,17 +319,41 @@ class VoiceBroadcastPlayerImpl @Inject constructor( State.IDLE -> playbackTicker.stopPlaybackTicker(voiceBroadcastId) } // Notify state change to all the listeners attached to the current voice broadcast id - listeners[voiceBroadcastId]?.forEach { listener -> listener.onStateChanged(playingState) } + listeners[voiceBroadcastId]?.forEach { listener -> listener.onPlayingStateChanged(playingState) } } } - private fun updateLiveListeningMode(playbackPosition: Int? = null) { + /** + * Update the live listening state according to: + * - the voice broadcast state, + * - the playing state, + * - the potential seek position. + */ + private fun updateLiveListeningMode(seekPosition: Int? = null) { isLiveListening = when { + // the current voice broadcast is not live (ended) !currentVoiceBroadcastEvent?.isLive.orFalse() -> false + // the player is stopped or paused playingState == State.IDLE || playingState == State.PAUSED -> false - playbackPosition != null -> playlist.findByPosition(playbackPosition)?.sequence == playlist.lastOrNull()?.sequence + // the user has sought + seekPosition != null -> { + val seekDirection = seekPosition.compareTo(getCurrentPlaybackPosition() ?: 0) + when { + // backward + seekDirection < 0 -> false + // forward: check if new sequence is the last one + else -> playlist.findByPosition(seekPosition)?.sequence == playlist.lastOrNull()?.sequence + } + } + // otherwise, stay in live or go in live if we reached the last sequence else -> isLiveListening || playlist.currentSequence == playlist.lastOrNull()?.sequence } + + currentVoiceBroadcast?.voiceBroadcastId?.let { voiceBroadcastId -> + // Notify live mode change to all the listeners attached to the current voice broadcast id + listeners[voiceBroadcastId]?.forEach { listener -> listener.onLiveModeChanged(isLiveListening) } + + } } private fun getCurrentPlaybackPosition(): Int? {