Better handling of Paused/Play state

This commit is contained in:
Benoit Marty 2021-07-13 15:47:52 +02:00
parent 7937c9945b
commit bff2c6ea93
3 changed files with 42 additions and 45 deletions

View file

@ -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()
}
}

View file

@ -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<Int>) {
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<Int>) : State()
}
}

View file

@ -74,8 +74,6 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() {
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<MessageVoiceItem.Holder>() {
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<MessageVoiceItem.Holder>() {
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) {