Enable fast backward/forward buttons

This commit is contained in:
Florian Renaud 2022-11-05 00:29:11 +01:00
parent c5e6eb0d0e
commit aa8eec221a
3 changed files with 47 additions and 29 deletions

View file

@ -28,6 +28,7 @@ import im.vector.app.R
import im.vector.app.core.epoxy.onClick import im.vector.app.core.epoxy.onClick
import im.vector.app.features.home.room.detail.RoomDetailAction.VoiceBroadcastAction import im.vector.app.features.home.room.detail.RoomDetailAction.VoiceBroadcastAction
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker.Listener.State
import im.vector.app.features.voicebroadcast.listening.VoiceBroadcastPlayer import im.vector.app.features.voicebroadcast.listening.VoiceBroadcastPlayer
import im.vector.app.features.voicebroadcast.views.VoiceBroadcastMetadataView import im.vector.app.features.voicebroadcast.views.VoiceBroadcastMetadataView
@ -48,6 +49,32 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem
} }
player.addListener(voiceBroadcast, playerListener) player.addListener(voiceBroadcast, playerListener)
bindSeekBar(holder) bindSeekBar(holder)
bindButtons(holder)
}
private fun bindButtons(holder: Holder) {
with(holder) {
playPauseButton.onClick {
when (player.playingState) {
VoiceBroadcastPlayer.State.PLAYING -> {
callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.Pause)
}
VoiceBroadcastPlayer.State.PAUSED,
VoiceBroadcastPlayer.State.IDLE -> {
callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.PlayOrResume(voiceBroadcast))
}
VoiceBroadcastPlayer.State.BUFFERING -> Unit
}
}
fastBackwardButton.onClick {
val newPos = seekBar.progress.minus(30_000).coerceIn(0, duration)
callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.SeekTo(voiceBroadcast, newPos, duration))
}
fastForwardButton.onClick {
val newPos = seekBar.progress.plus(30_000).coerceIn(0, duration)
callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.SeekTo(voiceBroadcast, newPos, duration))
}
}
} }
override fun renderMetadata(holder: Holder) { override fun renderMetadata(holder: Holder) {
@ -63,20 +90,15 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem
bufferingView.isVisible = state == VoiceBroadcastPlayer.State.BUFFERING bufferingView.isVisible = state == VoiceBroadcastPlayer.State.BUFFERING
playPauseButton.isVisible = state != VoiceBroadcastPlayer.State.BUFFERING playPauseButton.isVisible = state != VoiceBroadcastPlayer.State.BUFFERING
fastBackwardButton.isInvisible = true
fastForwardButton.isInvisible = true
when (state) { when (state) {
VoiceBroadcastPlayer.State.PLAYING -> { VoiceBroadcastPlayer.State.PLAYING -> {
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)
playPauseButton.onClick { callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.Pause) }
} }
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)
playPauseButton.onClick { callback?.onTimelineItemAction(VoiceBroadcastAction.Listening.PlayOrResume(voiceBroadcast)) }
} }
VoiceBroadcastPlayer.State.BUFFERING -> Unit VoiceBroadcastPlayer.State.BUFFERING -> Unit
} }
@ -99,25 +121,24 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem
} }
}) })
playbackTracker.track(voiceBroadcast.voiceBroadcastId, object : AudioMessagePlaybackTracker.Listener { playbackTracker.track(voiceBroadcast.voiceBroadcastId, object : AudioMessagePlaybackTracker.Listener {
override fun onUpdate(state: AudioMessagePlaybackTracker.Listener.State) { override fun onUpdate(state: State) {
when (state) { renderBackwardForwardButtons(holder, state)
is AudioMessagePlaybackTracker.Listener.State.Paused -> { if (!isUserSeeking) {
if (!isUserSeeking) { holder.seekBar.progress = playbackTracker.getPlaybackTime(voiceBroadcast.voiceBroadcastId)
holder.seekBar.progress = state.playbackTime
}
}
is AudioMessagePlaybackTracker.Listener.State.Playing -> {
if (!isUserSeeking) {
holder.seekBar.progress = state.playbackTime
}
}
AudioMessagePlaybackTracker.Listener.State.Idle -> Unit
is AudioMessagePlaybackTracker.Listener.State.Recording -> Unit
} }
} }
}) })
} }
private fun renderBackwardForwardButtons(holder: Holder, playbackState: State) {
val isPlayingOrPaused = playbackState is State.Playing || playbackState is State.Paused
val playbackTime = playbackTracker.getPlaybackTime(voiceBroadcast.voiceBroadcastId)
val canBackward = isPlayingOrPaused && playbackTime > 0
val canForward = isPlayingOrPaused && playbackTime < duration
holder.fastBackwardButton.isInvisible = !canBackward
holder.fastForwardButton.isInvisible = !canForward
}
private fun formatPlaybackTime(time: Int) = DateUtils.formatElapsedTime((time / 1000).toLong()) private fun formatPlaybackTime(time: Int) = DateUtils.formatElapsedTime((time / 1000).toLong())
override fun unbind(holder: Holder) { override fun unbind(holder: Holder) {

View file

@ -371,7 +371,6 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
private fun onPlaybackTick(id: String) { private fun onPlaybackTick(id: String) {
val currentItem = playlist.currentItem ?: return val currentItem = playlist.currentItem ?: return
val itemStartTime = currentItem.startTime val itemStartTime = currentItem.startTime
val duration = playlist.duration
when (playingState) { when (playingState) {
State.PLAYING, State.PLAYING,
State.PAUSED -> { State.PAUSED -> {
@ -383,15 +382,13 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
playbackTracker.updatePausedAtPlaybackTime(id, position, percentage) playbackTracker.updatePausedAtPlaybackTime(id, position, percentage)
} }
} }
State.BUFFERING, State.BUFFERING -> {
State.IDLE -> {
val playbackTime = playbackTracker.getPlaybackTime(id) val playbackTime = playbackTracker.getPlaybackTime(id)
val percentage = playbackTracker.getPercentage(id) val percentage = playbackTracker.getPercentage(id)
if (playingState == State.IDLE && duration > 0 && (duration - playbackTime) < 100) { playbackTracker.updatePausedAtPlaybackTime(id, playbackTime, percentage)
playbackTracker.stopPlayback(id) }
} else { State.IDLE -> {
playbackTracker.updatePausedAtPlaybackTime(id, playbackTime, percentage) playbackTracker.stopPlayback(id)
}
} }
} }
} }

View file

@ -100,7 +100,7 @@
android:id="@+id/fastBackwardButton" android:id="@+id/fastBackwardButton"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:background="@android:color/transparent" android:background="@drawable/bg_rounded_button"
android:contentDescription="@string/a11y_voice_broadcast_fast_backward" android:contentDescription="@string/a11y_voice_broadcast_fast_backward"
android:src="@drawable/ic_player_backward_30" android:src="@drawable/ic_player_backward_30"
app:tint="?vctr_content_secondary" /> app:tint="?vctr_content_secondary" />
@ -127,7 +127,7 @@
android:id="@+id/fastForwardButton" android:id="@+id/fastForwardButton"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:background="@android:color/transparent" android:background="@drawable/bg_rounded_button"
android:contentDescription="@string/a11y_voice_broadcast_fast_forward" android:contentDescription="@string/a11y_voice_broadcast_fast_forward"
android:src="@drawable/ic_player_forward_30" android:src="@drawable/ic_player_forward_30"
app:tint="?vctr_content_secondary" /> app:tint="?vctr_content_secondary" />