From bff2c6ea93baa8575ed27ac4106f66dc192a71ec Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 13 Jul 2021 15:47:52 +0200 Subject: [PATCH] Better handling of Paused/Play state --- .../detail/composer/VoiceMessageHelper.kt | 4 +- .../helper/VoiceMessagePlaybackTracker.kt | 65 +++++++++---------- .../detail/timeline/item/MessageVoiceItem.kt | 18 ++--- 3 files changed, 42 insertions(+), 45 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt index 51a2fc7150..2c53140d4a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt @@ -138,7 +138,7 @@ class VoiceMessageHelper @Inject constructor( fun startOrPausePlayback(id: String, file: File) { stopPlayback() if (playbackTracker.getPlaybackState(id) is VoiceMessagePlaybackTracker.Listener.State.Playing) { - playbackTracker.stopPlayback(id) + playbackTracker.pausePlayback(id) } else { playbackTracker.startPlayback(id) startPlayback(id, file) @@ -224,7 +224,7 @@ class VoiceMessageHelper @Inject constructor( playbackTracker.updateCurrentPlaybackTime(id, currentPosition) } else -> { - playbackTracker.stopPlayback(id = id, rememberPlaybackTime = false) + playbackTracker.stopPlayback(id) stopPlaybackTimer() } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt index 746dea13f7..1196a845e3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt @@ -31,7 +31,7 @@ class VoiceMessagePlaybackTracker @Inject constructor() { fun track(id: String, listener: Listener) { listeners[id] = listener - val currentState = states[id] ?: Listener.State.Idle(0) + val currentState = states[id] ?: Listener.State.Idle mainHandler.post { listener.onUpdate(currentState) } @@ -43,56 +43,51 @@ class VoiceMessagePlaybackTracker @Inject constructor() { fun makeAllPlaybacksIdle() { listeners.keys.forEach { key -> - val currentPlaybackTime = getPlaybackTime(key) - states[key] = Listener.State.Idle(currentPlaybackTime) - mainHandler.post { - listeners[key]?.onUpdate(Listener.State.Idle(currentPlaybackTime)) - } + setState(key, Listener.State.Idle) + } + } + + /** + * Set state and notify the listeners + */ + private fun setState(key: String, state: Listener.State) { + states[key] = state + mainHandler.post { + listeners[key]?.onUpdate(state) } } fun startPlayback(id: String) { val currentPlaybackTime = getPlaybackTime(id) val currentState = Listener.State.Playing(currentPlaybackTime) - states[id] = currentState - mainHandler.post { - listeners[id]?.onUpdate(currentState) - } - // Make active playback IDLE + setState(id, currentState) + // Pause any active playback states .filter { it.key != id } - .filter { it.value is Listener.State.Playing } .keys .forEach { key -> - val playbackTime = getPlaybackTime(key) - val state = Listener.State.Idle(playbackTime) - states[key] = state - mainHandler.post { - listeners[key]?.onUpdate(state) + val state = states[key] + if (state is Listener.State.Playing) { + setState(key, Listener.State.Paused(state.playbackTime)) } } } - fun stopPlayback(id: String, rememberPlaybackTime: Boolean = true) { - val currentPlaybackTime = if (rememberPlaybackTime) getPlaybackTime(id) else 0 - states[id] = Listener.State.Idle(currentPlaybackTime) - mainHandler.post { - listeners[id]?.onUpdate(states[id]!!) - } + fun pausePlayback(id: String) { + val currentPlaybackTime = getPlaybackTime(id) + setState(id, Listener.State.Paused(currentPlaybackTime)) + } + + fun stopPlayback(id: String) { + setState(id, Listener.State.Idle) } fun updateCurrentPlaybackTime(id: String, time: Int) { - states[id] = Listener.State.Playing(time) - mainHandler.post { - listeners[id]?.onUpdate(states[id]!!) - } + setState(id, Listener.State.Playing(time)) } fun updateCurrentRecording(id: String, amplitudeList: List) { - states[id] = Listener.State.Recording(amplitudeList) - mainHandler.post { - listeners[id]?.onUpdate(states[id]!!) - } + setState(id, Listener.State.Recording(amplitudeList)) } fun getPlaybackState(id: String) = states[id] @@ -100,14 +95,15 @@ class VoiceMessagePlaybackTracker @Inject constructor() { fun getPlaybackTime(id: String): Int { return when (val state = states[id]) { is Listener.State.Playing -> state.playbackTime - is Listener.State.Idle -> state.playbackTime + is Listener.State.Paused -> state.playbackTime + /* Listener.State.Idle, */ else -> 0 } } fun clear() { listeners.forEach { - it.value.onUpdate(Listener.State.Idle(0)) + it.value.onUpdate(Listener.State.Idle) } listeners.clear() states.clear() @@ -122,8 +118,9 @@ class VoiceMessagePlaybackTracker @Inject constructor() { fun onUpdate(state: State) sealed class State { - data class Idle(val playbackTime: Int) : State() + object Idle : State() data class Playing(val playbackTime: Int) : State() + data class Paused(val playbackTime: Int) : State() data class Recording(val amplitudeList: List) : State() } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt index a59208e47f..a8e931e315 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt @@ -74,8 +74,6 @@ abstract class MessageVoiceItem : AbsMessageItem() { holder.progressLayout.isVisible = false } - holder.voicePlaybackTime.text = formatPlaybackTime(duration) - holder.voicePlaybackWaveform.post { holder.voicePlaybackWaveform.recreate() waveform.forEach { amplitude -> @@ -88,20 +86,17 @@ abstract class MessageVoiceItem : AbsMessageItem() { voiceMessagePlaybackTracker.track(attributes.informationData.eventId, object : VoiceMessagePlaybackTracker.Listener { override fun onUpdate(state: VoiceMessagePlaybackTracker.Listener.State) { when (state) { - is VoiceMessagePlaybackTracker.Listener.State.Idle -> renderIdleState(holder, state) + is VoiceMessagePlaybackTracker.Listener.State.Idle -> renderIdleState(holder) is VoiceMessagePlaybackTracker.Listener.State.Playing -> renderPlayingState(holder, state) + is VoiceMessagePlaybackTracker.Listener.State.Paused -> renderPausedState(holder, state) } } }) } - private fun renderIdleState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Idle) { + private fun renderIdleState(holder: Holder) { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) - if (state.playbackTime > 0) { - holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime) - } else { - holder.voicePlaybackTime.text = formatPlaybackTime(duration) - } + holder.voicePlaybackTime.text = formatPlaybackTime(duration) } private fun renderPlayingState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Playing) { @@ -109,6 +104,11 @@ abstract class MessageVoiceItem : AbsMessageItem() { holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime) } + private fun renderPausedState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Paused) { + holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) + holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime) + } + private fun formatPlaybackTime(time: Int) = DateUtils.formatElapsedTime((time / 1000).toLong()) override fun unbind(holder: Holder) {