Browse Source

Track errors in VoiceMessagePresenter (#1667)

Story: https://github.com/vector-im/element-meta/issues/2085
pull/1674/head
Marco Romano 11 months ago committed by GitHub
parent
commit
81122ec33b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/VoiceMessageException.kt
  2. 16
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt
  3. 10
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/voicemessages/timeline/VoiceMessagePresenterTest.kt

3
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/VoiceMessageException.kt

@ -23,4 +23,7 @@ internal sealed class VoiceMessageException : Exception() { @@ -23,4 +23,7 @@ internal sealed class VoiceMessageException : Exception() {
data class PermissionMissing(
override val message: String?, override val cause: Throwable?
) : VoiceMessageException()
data class PlayMessageError(
override val message: String?, override val cause: Throwable?
) : VoiceMessageException()
}

16
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt

@ -33,11 +33,13 @@ import dagger.multibindings.IntoMap @@ -33,11 +33,13 @@ import dagger.multibindings.IntoMap
import io.element.android.features.messages.impl.timeline.di.TimelineItemEventContentKey
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactory
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
import io.element.android.features.messages.impl.voicemessages.VoiceMessageException
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingState
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.ui.utils.time.formatShort
import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.launch
import kotlin.time.Duration.Companion.milliseconds
@ -52,6 +54,7 @@ interface VoiceMessagePresenterModule { @@ -52,6 +54,7 @@ interface VoiceMessagePresenterModule {
class VoiceMessagePresenter @AssistedInject constructor(
voiceMessagePlayerFactory: VoiceMessagePlayer.Factory,
private val analyticsService: AnalyticsService,
@Assisted private val content: TimelineItemVoiceContent,
) : Presenter<VoiceMessageState> {
@ -102,7 +105,18 @@ class VoiceMessagePresenter @AssistedInject constructor( @@ -102,7 +105,18 @@ class VoiceMessagePresenter @AssistedInject constructor(
if (playerState.isPlaying) {
player.pause()
} else {
scope.launch { play.runUpdatingState { player.play() } }
scope.launch {
play.runUpdatingState(
errorTransform = {
analyticsService.trackError(
VoiceMessageException.PlayMessageError("Error while trying to play voice message", it)
)
it
},
) {
player.play()
}
}
}
}
is VoiceMessageEvents.Seek -> {

10
features/messages/impl/src/test/kotlin/io/element/android/features/messages/voicemessages/timeline/VoiceMessagePresenterTest.kt

@ -22,12 +22,15 @@ import app.cash.turbine.test @@ -22,12 +22,15 @@ import app.cash.turbine.test
import com.google.common.truth.Truth
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemVoiceContent
import io.element.android.features.messages.impl.voicemessages.VoiceMessageException
import io.element.android.features.messages.impl.voicemessages.timeline.DefaultVoiceMessagePlayer
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageEvents
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageMediaRepo
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessagePresenter
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageState
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analytics.test.FakeAnalyticsService
import kotlinx.coroutines.test.runTest
import org.junit.Test
@ -77,8 +80,10 @@ class VoiceMessagePresenterTest { @@ -77,8 +80,10 @@ class VoiceMessagePresenterTest {
@Test
fun `pressing play downloads and fails`() = runTest {
val analyticsService = FakeAnalyticsService()
val presenter = createVoiceMessagePresenter(
voiceMessageMediaRepo = FakeVoiceMessageMediaRepo().apply { shouldFail = true },
analyticsService = analyticsService,
content = aTimelineItemVoiceContent(durationMs = 2_000),
)
moleculeFlow(RecompositionMode.Immediate) {
@ -102,6 +107,9 @@ class VoiceMessagePresenterTest { @@ -102,6 +107,9 @@ class VoiceMessagePresenterTest {
Truth.assertThat(it.progress).isEqualTo(0f)
Truth.assertThat(it.time).isEqualTo("0:02")
}
analyticsService.trackedErrors.first().also {
Truth.assertThat(it).isInstanceOf(VoiceMessageException.PlayMessageError::class.java)
}
}
}
@ -190,6 +198,7 @@ class VoiceMessagePresenterTest { @@ -190,6 +198,7 @@ class VoiceMessagePresenterTest {
fun createVoiceMessagePresenter(
voiceMessageMediaRepo: VoiceMessageMediaRepo = FakeVoiceMessageMediaRepo(),
analyticsService: AnalyticsService = FakeAnalyticsService(),
content: TimelineItemVoiceContent = aTimelineItemVoiceContent(),
) = VoiceMessagePresenter(
voiceMessagePlayerFactory = { eventId, mediaSource, mimeType, body ->
@ -202,5 +211,6 @@ fun createVoiceMessagePresenter( @@ -202,5 +211,6 @@ fun createVoiceMessagePresenter(
body = body
)
},
analyticsService = analyticsService,
content = content,
)

Loading…
Cancel
Save