mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-10 00:50:49 +01:00
Support scrolling playback on recorded audio before sending.
This commit is contained in:
parent
3bd4a4ccd3
commit
5168d715ce
@ -786,6 +786,18 @@ class TimelineFragment @Inject constructor(
|
||||
updateRecordingUiState(RecordingUiState.Draft)
|
||||
}
|
||||
|
||||
override fun onVoiceWaveformTouchedUp(percentage: Float, duration: Int) {
|
||||
messageComposerViewModel.handle(
|
||||
MessageComposerAction.VoiceWaveformTouchedUp(VoiceMessagePlaybackTracker.RECORDING_ID, duration, percentage)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onVoiceWaveformMoved(percentage: Float, duration: Int) {
|
||||
messageComposerViewModel.handle(
|
||||
MessageComposerAction.VoiceWaveformTouchedUp(VoiceMessagePlaybackTracker.RECORDING_ID, duration, percentage)
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateRecordingUiState(state: RecordingUiState) {
|
||||
messageComposerViewModel.handle(
|
||||
MessageComposerAction.OnVoiceRecordingUiStateChanged(state))
|
||||
@ -2051,12 +2063,12 @@ class TimelineFragment @Inject constructor(
|
||||
messageComposerViewModel.handle(MessageComposerAction.PlayOrPauseVoicePlayback(eventId, messageAudioContent))
|
||||
}
|
||||
|
||||
override fun onVoiceWaveformTouchedUp(eventId: String, messageAudioContent: MessageAudioContent, percentage: Float) {
|
||||
messageComposerViewModel.handle(MessageComposerAction.VoiceWaveformTouchedUp(eventId, messageAudioContent, percentage))
|
||||
override fun onVoiceWaveformTouchedUp(eventId: String, duration: Int, percentage: Float) {
|
||||
messageComposerViewModel.handle(MessageComposerAction.VoiceWaveformTouchedUp(eventId, duration, percentage))
|
||||
}
|
||||
|
||||
override fun onVoiceWaveformMovedTo(eventId: String, messageAudioContent: MessageAudioContent, percentage: Float) {
|
||||
messageComposerViewModel.handle(MessageComposerAction.VoiceWaveformMovedTo(eventId, messageAudioContent, percentage))
|
||||
override fun onVoiceWaveformMovedTo(eventId: String, duration: Int, percentage: Float) {
|
||||
messageComposerViewModel.handle(MessageComposerAction.VoiceWaveformMovedTo(eventId, duration, percentage))
|
||||
}
|
||||
|
||||
private fun onShareActionClicked(action: EventSharedAction.Share) {
|
||||
|
@ -40,6 +40,6 @@ sealed class MessageComposerAction : VectorViewModelAction {
|
||||
data class PlayOrPauseVoicePlayback(val eventId: String, val messageAudioContent: MessageAudioContent) : MessageComposerAction()
|
||||
object PlayOrPauseRecordingPlayback : MessageComposerAction()
|
||||
data class EndAllVoiceActions(val deleteRecord: Boolean = true) : MessageComposerAction()
|
||||
data class VoiceWaveformTouchedUp(val eventId: String, val messageAudioContent: MessageAudioContent, val percentage: Float) : MessageComposerAction()
|
||||
data class VoiceWaveformMovedTo(val eventId: String, val messageAudioContent: MessageAudioContent, val percentage: Float) : MessageComposerAction()
|
||||
data class VoiceWaveformTouchedUp(val eventId: String, val duration: Int, val percentage: Float) : MessageComposerAction()
|
||||
data class VoiceWaveformMovedTo(val eventId: String, val duration: Int, val percentage: Float) : MessageComposerAction()
|
||||
}
|
||||
|
@ -864,15 +864,11 @@ class MessageComposerViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private fun handleVoiceWaveformTouchedUp(action: MessageComposerAction.VoiceWaveformTouchedUp) {
|
||||
val duration = (action.messageAudioContent.audioInfo?.duration ?: 0)
|
||||
val toMillisecond = (action.percentage * duration).toInt()
|
||||
voiceMessageHelper.movePlaybackTo(action.eventId, toMillisecond, duration)
|
||||
voiceMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration)
|
||||
}
|
||||
|
||||
private fun handleVoiceWaveformMovedTo(action: MessageComposerAction.VoiceWaveformMovedTo) {
|
||||
val duration = (action.messageAudioContent.audioInfo?.duration ?: 0)
|
||||
val toMillisecond = (action.percentage * duration).toInt()
|
||||
voiceMessageHelper.movePlaybackTo(action.eventId, toMillisecond, duration)
|
||||
voiceMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration)
|
||||
}
|
||||
|
||||
private fun handleEntersBackground(composerText: String) {
|
||||
|
@ -171,13 +171,13 @@ class VoiceMessageHelper @Inject constructor(
|
||||
}
|
||||
|
||||
fun stopPlayback() {
|
||||
playbackTracker.stopPlayback(VoiceMessagePlaybackTracker.RECORDING_ID)
|
||||
playbackTracker.pausePlayback(VoiceMessagePlaybackTracker.RECORDING_ID)
|
||||
mediaPlayer?.stop()
|
||||
stopPlaybackTicker()
|
||||
}
|
||||
|
||||
fun movePlaybackTo(id: String, toMillisecond: Int, totalDuration: Int) {
|
||||
val percentage = toMillisecond.toFloat() / totalDuration
|
||||
fun movePlaybackTo(id: String, percentage: Float, totalDuration: Int) {
|
||||
val toMillisecond = (totalDuration * percentage).toInt()
|
||||
playbackTracker.updateCurrentPlaybackTime(id, toMillisecond, percentage)
|
||||
|
||||
stopPlayback()
|
||||
|
@ -53,6 +53,8 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
||||
fun onDeleteVoiceMessage()
|
||||
fun onRecordingLimitReached()
|
||||
fun onRecordingWaveformClicked()
|
||||
fun onVoiceWaveformTouchedUp(percentage: Float, duration: Int)
|
||||
fun onVoiceWaveformMoved(percentage: Float, duration: Int)
|
||||
}
|
||||
|
||||
@Inject lateinit var clock: Clock
|
||||
@ -65,6 +67,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
||||
private var recordingTicker: CountUpTimer? = null
|
||||
private var lastKnownState: RecordingUiState? = null
|
||||
private var dragState: DraggingState = DraggingState.Ignored
|
||||
private var recordingDuration: Long = 0
|
||||
|
||||
init {
|
||||
inflate(this.context, R.layout.view_voice_message_recorder, this)
|
||||
@ -95,7 +98,6 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
||||
override fun onDeleteVoiceMessage() = callback.onDeleteVoiceMessage()
|
||||
override fun onWaveformClicked() {
|
||||
when (lastKnownState) {
|
||||
RecordingUiState.Draft -> callback.onVoicePlaybackButtonClicked()
|
||||
is RecordingUiState.Recording,
|
||||
is RecordingUiState.Locked -> callback.onRecordingWaveformClicked()
|
||||
}
|
||||
@ -105,6 +107,18 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
||||
override fun onMicButtonDrag(nextDragStateCreator: (DraggingState) -> DraggingState) {
|
||||
onDrag(dragState, newDragState = nextDragStateCreator(dragState))
|
||||
}
|
||||
|
||||
override fun onVoiceWaveformTouchedUp(percentage: Float) {
|
||||
if (lastKnownState == RecordingUiState.Draft) {
|
||||
callback.onVoiceWaveformTouchedUp(percentage, recordingDuration.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVoiceWaveformMoved(percentage: Float) {
|
||||
if (lastKnownState == RecordingUiState.Draft) {
|
||||
callback.onVoiceWaveformMoved(percentage, recordingDuration.toInt())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -203,6 +217,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
private fun stopRecordingTicker() {
|
||||
recordingDuration = recordingTicker?.elapsedTime() ?: 0
|
||||
recordingTicker?.stop()
|
||||
recordingTicker = null
|
||||
}
|
||||
|
@ -60,8 +60,21 @@ class VoiceMessageViews(
|
||||
actions.onDeleteVoiceMessage()
|
||||
}
|
||||
|
||||
views.voicePlaybackWaveform.setOnClickListener {
|
||||
actions.onWaveformClicked()
|
||||
views.voicePlaybackWaveform.setOnTouchListener { view, motionEvent ->
|
||||
when (motionEvent.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
actions.onWaveformClicked()
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
val percentage = getTouchedPositionPercentage(motionEvent, view)
|
||||
actions.onVoiceWaveformTouchedUp(percentage)
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
val percentage = getTouchedPositionPercentage(motionEvent, view)
|
||||
actions.onVoiceWaveformMoved(percentage)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
views.voicePlaybackControlButton.setOnClickListener {
|
||||
@ -70,6 +83,8 @@ class VoiceMessageViews(
|
||||
observeMicButton(actions)
|
||||
}
|
||||
|
||||
private fun getTouchedPositionPercentage(motionEvent: MotionEvent, view: View) = motionEvent.x / view.width
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun observeMicButton(actions: Actions) {
|
||||
val draggableStateProcessor = DraggableStateProcessor(resources, dimensionConverter)
|
||||
@ -332,7 +347,7 @@ class VoiceMessageViews(
|
||||
|
||||
fun renderRecordingWaveform(amplitudeList: Array<Int>) {
|
||||
views.voicePlaybackWaveform.doOnLayout { waveFormView ->
|
||||
val waveformColor = ThemeUtils.getColor(waveFormView.context, R.attr.vctr_content_secondary)
|
||||
val waveformColor = ThemeUtils.getColor(waveFormView.context, R.attr.vctr_content_quaternary)
|
||||
amplitudeList.iterator().forEach {
|
||||
(waveFormView as AudioWaveformView).add(AudioWaveformView.FFT(it.toFloat(), waveformColor))
|
||||
}
|
||||
@ -355,5 +370,7 @@ class VoiceMessageViews(
|
||||
fun onDeleteVoiceMessage()
|
||||
fun onWaveformClicked()
|
||||
fun onVoicePlaybackButtonClicked()
|
||||
fun onVoiceWaveformTouchedUp(percentage: Float)
|
||||
fun onVoiceWaveformMoved(percentage: Float)
|
||||
}
|
||||
}
|
||||
|
@ -138,8 +138,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
||||
fun getPreviewUrlRetriever(): PreviewUrlRetriever
|
||||
|
||||
fun onVoiceControlButtonClicked(eventId: String, messageAudioContent: MessageAudioContent)
|
||||
fun onVoiceWaveformTouchedUp(eventId: String, messageAudioContent: MessageAudioContent, percentage: Float)
|
||||
fun onVoiceWaveformMovedTo(eventId: String, messageAudioContent: MessageAudioContent, percentage: Float)
|
||||
fun onVoiceWaveformTouchedUp(eventId: String, duration: Int, percentage: Float)
|
||||
fun onVoiceWaveformMovedTo(eventId: String, duration: Int, percentage: Float)
|
||||
}
|
||||
|
||||
interface ReactionPillCallback {
|
||||
|
@ -359,11 +359,13 @@ class MessageItemFactory @Inject constructor(
|
||||
|
||||
val waveformTouchListener: MessageVoiceItem.WaveformTouchListener = object : MessageVoiceItem.WaveformTouchListener {
|
||||
override fun onWaveformTouchedUp(percentage: Float) {
|
||||
params.callback?.onVoiceWaveformTouchedUp(informationData.eventId, messageContent, percentage)
|
||||
val duration = messageContent.audioInfo?.duration ?: 0
|
||||
params.callback?.onVoiceWaveformTouchedUp(informationData.eventId, duration, percentage)
|
||||
}
|
||||
|
||||
override fun onWaveformMovedTo(percentage: Float) {
|
||||
params.callback?.onVoiceWaveformMovedTo(informationData.eventId, messageContent, percentage)
|
||||
val duration = messageContent.audioInfo?.duration ?: 0
|
||||
params.callback?.onVoiceWaveformMovedTo(informationData.eventId, duration, percentage)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user