Browse Source

Merge pull request #1671 from vector-im/jonny/voice-message-fixes

Fix voice message preview player playing after delete/send
pull/1674/head
jonnyandrew 11 months ago committed by GitHub
parent
commit
b046493a7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenter.kt
  2. 45
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/voicemessages/composer/VoiceMessageComposerPresenterTest.kt
  3. 6
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/media/FakeWaveformFactory.kt
  4. 2
      libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt
  5. 2
      libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessagePreview.kt

6
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenter.kt

@ -149,6 +149,7 @@ class VoiceMessageComposerPresenter @Inject constructor(
return@lambda return@lambda
} }
isSending = true isSending = true
player.pause()
appCoroutineScope.sendMessage( appCoroutineScope.sendMessage(
file = finishedState.file, file = finishedState.file,
mimeType = finishedState.mimeType, mimeType = finishedState.mimeType,
@ -165,7 +166,10 @@ class VoiceMessageComposerPresenter @Inject constructor(
is VoiceMessageComposerEvents.SendVoiceMessage -> localCoroutineScope.launch { is VoiceMessageComposerEvents.SendVoiceMessage -> localCoroutineScope.launch {
onSendButtonPress() onSendButtonPress()
} }
VoiceMessageComposerEvents.DeleteVoiceMessage -> localCoroutineScope.deleteRecording() VoiceMessageComposerEvents.DeleteVoiceMessage -> {
player.pause()
localCoroutineScope.deleteRecording()
}
VoiceMessageComposerEvents.DismissPermissionsRationale -> onDismissPermissionsRationale() VoiceMessageComposerEvents.DismissPermissionsRationale -> onDismissPermissionsRationale()
VoiceMessageComposerEvents.AcceptPermissionRationale -> onAcceptPermissionsRationale() VoiceMessageComposerEvents.AcceptPermissionRationale -> onAcceptPermissionsRationale()
is VoiceMessageComposerEvents.LifecycleEvent -> onLifecycleEvent(event.event) is VoiceMessageComposerEvents.LifecycleEvent -> onLifecycleEvent(event.event)

45
features/messages/impl/src/test/kotlin/io/element/android/features/messages/voicemessages/composer/VoiceMessageComposerPresenterTest.kt

@ -209,6 +209,28 @@ class VoiceMessageComposerPresenterTest {
} }
} }
@Test
fun `present - delete while playing`() = runTest {
val presenter = createVoiceMessageComposerPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
awaitItem().eventSink(VoiceMessageComposerEvents.RecordButtonEvent(PressEvent.PressStart))
awaitItem().eventSink(VoiceMessageComposerEvents.RecordButtonEvent(PressEvent.LongPressEnd))
awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play))
awaitItem().eventSink(VoiceMessageComposerEvents.DeleteVoiceMessage)
awaitItem().apply {
assertThat(voiceMessageState).isEqualTo(aPreviewState(isPlaying = false))
}
val finalState = awaitItem()
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
testPauseAndDestroy(finalState)
}
}
@Test @Test
fun `present - send recording`() = runTest { fun `present - send recording`() = runTest {
val presenter = createVoiceMessageComposerPresenter() val presenter = createVoiceMessageComposerPresenter()
@ -229,6 +251,29 @@ class VoiceMessageComposerPresenterTest {
} }
} }
@Test
fun `present - send while playing`() = runTest {
val presenter = createVoiceMessageComposerPresenter()
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
awaitItem().eventSink(VoiceMessageComposerEvents.RecordButtonEvent(PressEvent.PressStart))
awaitItem().eventSink(VoiceMessageComposerEvents.RecordButtonEvent(PressEvent.LongPressEnd))
awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play))
awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
assertThat(awaitItem().voiceMessageState).isEqualTo(aPreviewState(
isSending = true, isPlaying = false,
))
val finalState = awaitItem()
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
assertThat(matrixRoom.sendMediaCount).isEqualTo(1)
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
testPauseAndDestroy(finalState)
}
}
@Test @Test
fun `present - send recording before previous completed, waits`() = runTest { fun `present - send recording before previous completed, waits`() = runTest {
val presenter = createVoiceMessageComposerPresenter() val presenter = createVoiceMessageComposerPresenter()

6
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/media/FakeWaveformFactory.kt

@ -20,17 +20,15 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList
import kotlin.random.Random import kotlin.random.Random
object FakeWaveformFactory { /**
/**
* Generate a waveform for testing purposes. * Generate a waveform for testing purposes.
* *
* The waveform is a list of floats between 0 and 1. * The waveform is a list of floats between 0 and 1.
* *
* @param length The length of the waveform. * @param length The length of the waveform.
*/ */
fun createFakeWaveform(length: Int = 1000): ImmutableList<Float> { fun createFakeWaveform(length: Int = 1000): ImmutableList<Float> {
val random = Random(seed = 2) val random = Random(seed = 2)
return List(length) { random.nextFloat() } return List(length) { random.nextFloat() }
.toPersistentList() .toPersistentList()
}
} }

2
libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt

@ -48,7 +48,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.components.media.FakeWaveformFactory.createFakeWaveform import io.element.android.libraries.designsystem.components.media.createFakeWaveform
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.applyScaleUp import io.element.android.libraries.designsystem.text.applyScaleUp

2
libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessagePreview.kt

@ -34,8 +34,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.components.media.FakeWaveformFactory.createFakeWaveform
import io.element.android.libraries.designsystem.components.media.WaveformPlaybackView import io.element.android.libraries.designsystem.components.media.WaveformPlaybackView
import io.element.android.libraries.designsystem.components.media.createFakeWaveform
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.applyScaleUp import io.element.android.libraries.designsystem.text.applyScaleUp

Loading…
Cancel
Save