Use kotlin.time.Duration instead of java.time.Duration. Also use Duration in TimelineItemVideoContent, like in TimelineItemAudioContent and TimelineItemVoiceContent
This commit is contained in:
parent
de3362798e
commit
04be1f0385
20 changed files with 57 additions and 45 deletions
|
|
@ -47,8 +47,8 @@ import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageT
|
||||||
import io.element.android.libraries.matrix.ui.messages.toHtmlDocument
|
import io.element.android.libraries.matrix.ui.messages.toHtmlDocument
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import java.time.Duration
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration
|
||||||
|
|
||||||
class TimelineItemContentMessageFactory @Inject constructor(
|
class TimelineItemContentMessageFactory @Inject constructor(
|
||||||
private val fileSizeFormatter: FileSizeFormatter,
|
private val fileSizeFormatter: FileSizeFormatter,
|
||||||
|
|
@ -104,7 +104,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||||
mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream,
|
mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream,
|
||||||
width = messageType.info?.width?.toInt(),
|
width = messageType.info?.width?.toInt(),
|
||||||
height = messageType.info?.height?.toInt(),
|
height = messageType.info?.height?.toInt(),
|
||||||
duration = messageType.info?.duration?.toMillis() ?: 0L,
|
duration = messageType.info?.duration ?: Duration.ZERO,
|
||||||
blurHash = messageType.info?.blurhash,
|
blurHash = messageType.info?.blurhash,
|
||||||
aspectRatio = aspectRatio,
|
aspectRatio = aspectRatio,
|
||||||
formattedFileSize = fileSizeFormatter.format(messageType.info?.size ?: 0),
|
formattedFileSize = fileSizeFormatter.format(messageType.info?.size ?: 0),
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ package io.element.android.features.messages.impl.timeline.model.event
|
||||||
|
|
||||||
import io.element.android.features.messages.impl.media.helper.formatFileExtensionAndSize
|
import io.element.android.features.messages.impl.media.helper.formatFileExtensionAndSize
|
||||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
import java.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
data class TimelineItemAudioContent(
|
data class TimelineItemAudioContent(
|
||||||
val body: String,
|
val body: String,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ package io.element.android.features.messages.impl.timeline.model.event
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
import java.time.Duration
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
open class TimelineItemAudioContentProvider : PreviewParameterProvider<TimelineItemAudioContent> {
|
open class TimelineItemAudioContentProvider : PreviewParameterProvider<TimelineItemAudioContent> {
|
||||||
override val values: Sequence<TimelineItemAudioContent>
|
override val values: Sequence<TimelineItemAudioContent>
|
||||||
|
|
@ -35,6 +35,6 @@ fun aTimelineItemAudioContent(fileName: String = "A sound.mp3") = TimelineItemAu
|
||||||
mimeType = MimeTypes.Pdf,
|
mimeType = MimeTypes.Pdf,
|
||||||
formattedFileSize = "100kB",
|
formattedFileSize = "100kB",
|
||||||
fileExtension = "mp3",
|
fileExtension = "mp3",
|
||||||
duration = Duration.ofMillis(100),
|
duration = 100.milliseconds,
|
||||||
mediaSource = MediaSource(""),
|
mediaSource = MediaSource(""),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,11 @@
|
||||||
package io.element.android.features.messages.impl.timeline.model.event
|
package io.element.android.features.messages.impl.timeline.model.event
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
|
import kotlin.time.Duration
|
||||||
|
|
||||||
data class TimelineItemVideoContent(
|
data class TimelineItemVideoContent(
|
||||||
val body: String,
|
val body: String,
|
||||||
val duration: Long,
|
val duration: Duration,
|
||||||
val videoSource: MediaSource,
|
val videoSource: MediaSource,
|
||||||
val thumbnailSource: MediaSource?,
|
val thumbnailSource: MediaSource?,
|
||||||
val aspectRatio: Float?,
|
val aspectRatio: Float?,
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
import io.element.android.libraries.matrix.ui.components.A_BLUR_HASH
|
import io.element.android.libraries.matrix.ui.components.A_BLUR_HASH
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
open class TimelineItemVideoContentProvider : PreviewParameterProvider<TimelineItemVideoContent> {
|
open class TimelineItemVideoContentProvider : PreviewParameterProvider<TimelineItemVideoContent> {
|
||||||
override val values: Sequence<TimelineItemVideoContent>
|
override val values: Sequence<TimelineItemVideoContent>
|
||||||
|
|
@ -35,7 +36,7 @@ fun aTimelineItemVideoContent() = TimelineItemVideoContent(
|
||||||
thumbnailSource = null,
|
thumbnailSource = null,
|
||||||
blurHash = A_BLUR_HASH,
|
blurHash = A_BLUR_HASH,
|
||||||
aspectRatio = 0.5f,
|
aspectRatio = 0.5f,
|
||||||
duration = 100,
|
duration = 100.milliseconds,
|
||||||
videoSource = MediaSource(""),
|
videoSource = MediaSource(""),
|
||||||
height = 300,
|
height = 300,
|
||||||
width = 150,
|
width = 150,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ package io.element.android.features.messages.impl.timeline.model.event
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import java.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
data class TimelineItemVoiceContent(
|
data class TimelineItemVoiceContent(
|
||||||
val eventId: EventId?,
|
val eventId: EventId?,
|
||||||
|
|
|
||||||
|
|
@ -21,21 +21,23 @@ import io.element.android.libraries.core.mimetype.MimeTypes
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
import kotlinx.collections.immutable.toPersistentList
|
import kotlinx.collections.immutable.toPersistentList
|
||||||
import java.time.Duration
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
import kotlin.time.Duration.Companion.minutes
|
||||||
|
|
||||||
open class TimelineItemVoiceContentProvider : PreviewParameterProvider<TimelineItemVoiceContent> {
|
open class TimelineItemVoiceContentProvider : PreviewParameterProvider<TimelineItemVoiceContent> {
|
||||||
override val values: Sequence<TimelineItemVoiceContent>
|
override val values: Sequence<TimelineItemVoiceContent>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aTimelineItemVoiceContent(
|
aTimelineItemVoiceContent(
|
||||||
durationMs = 1,
|
duration = 1.milliseconds,
|
||||||
waveform = listOf(),
|
waveform = listOf(),
|
||||||
),
|
),
|
||||||
aTimelineItemVoiceContent(
|
aTimelineItemVoiceContent(
|
||||||
durationMs = 10_000,
|
duration = 10_000.milliseconds,
|
||||||
waveform = listOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f, 8f, 7f, 6f, 5f, 4f, 3f, 2f, 1f, 0f),
|
waveform = listOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f, 8f, 7f, 6f, 5f, 4f, 3f, 2f, 1f, 0f),
|
||||||
),
|
),
|
||||||
aTimelineItemVoiceContent(
|
aTimelineItemVoiceContent(
|
||||||
durationMs = 1_800_000, // 30 minutes
|
duration = 30.minutes,
|
||||||
waveform = List(1024) { it / 1024f },
|
waveform = List(1024) { it / 1024f },
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -44,14 +46,14 @@ open class TimelineItemVoiceContentProvider : PreviewParameterProvider<TimelineI
|
||||||
fun aTimelineItemVoiceContent(
|
fun aTimelineItemVoiceContent(
|
||||||
eventId: String? = "\$anEventId",
|
eventId: String? = "\$anEventId",
|
||||||
body: String = "body doesn't really matter for a voice message",
|
body: String = "body doesn't really matter for a voice message",
|
||||||
durationMs: Long = 61_000,
|
duration: Duration = 61_000.milliseconds,
|
||||||
contentUri: String = "mxc://matrix.org/1234567890abcdefg",
|
contentUri: String = "mxc://matrix.org/1234567890abcdefg",
|
||||||
mimeType: String = MimeTypes.Ogg,
|
mimeType: String = MimeTypes.Ogg,
|
||||||
waveform: List<Float> = listOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f, 8f, 7f, 6f, 5f, 4f, 3f, 2f, 1f, 0f),
|
waveform: List<Float> = listOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f, 8f, 7f, 6f, 5f, 4f, 3f, 2f, 1f, 0f),
|
||||||
) = TimelineItemVoiceContent(
|
) = TimelineItemVoiceContent(
|
||||||
eventId = eventId?.let { EventId(it) },
|
eventId = eventId?.let { EventId(it) },
|
||||||
body = body,
|
body = body,
|
||||||
duration = Duration.ofMillis(durationMs),
|
duration = duration,
|
||||||
mediaSource = MediaSource(contentUri),
|
mediaSource = MediaSource(contentUri),
|
||||||
mimeType = mimeType,
|
mimeType = mimeType,
|
||||||
waveform = waveform.toPersistentList(),
|
waveform = waveform.toPersistentList(),
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ class VoiceMessageComposerPlayer @Inject constructor(
|
||||||
progress = 0f,
|
progress = 0f,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this player is currently playing.
|
* Whether this player is currently playing.
|
||||||
*/
|
*/
|
||||||
|
|
@ -212,7 +213,6 @@ class VoiceMessageComposerPlayer @Inject constructor(
|
||||||
val isStopped get() = this.playState == PlayState.Stopped
|
val isStopped get() = this.playState == PlayState.Stopped
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum class PlayState {
|
enum class PlayState {
|
||||||
/**
|
/**
|
||||||
* The player is stopped, i.e. it has just been initialised.
|
* The player is stopped, i.e. it has just been initialised.
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ class VoiceMessagePresenter @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val duration by remember {
|
val duration by remember {
|
||||||
derivedStateOf { playerState.duration ?: content.duration.toMillis() }
|
derivedStateOf { playerState.duration ?: content.duration.inWholeMilliseconds }
|
||||||
}
|
}
|
||||||
val progress by remember {
|
val progress by remember {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,7 @@ class MessagesPresenterTest {
|
||||||
val mediaMessage = aMessageEvent(
|
val mediaMessage = aMessageEvent(
|
||||||
content = TimelineItemVideoContent(
|
content = TimelineItemVideoContent(
|
||||||
body = "video.mp4",
|
body = "video.mp4",
|
||||||
duration = 10L,
|
duration = 10.milliseconds,
|
||||||
videoSource = MediaSource(AN_AVATAR_URL),
|
videoSource = MediaSource(AN_AVATAR_URL),
|
||||||
thumbnailSource = MediaSource(AN_AVATAR_URL),
|
thumbnailSource = MediaSource(AN_AVATAR_URL),
|
||||||
mimeType = MimeTypes.Mp4,
|
mimeType = MimeTypes.Mp4,
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,8 @@ import io.element.android.libraries.matrix.ui.components.A_BLUR_HASH
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.time.Duration
|
import kotlin.time.Duration
|
||||||
import java.time.Duration.ofMinutes
|
import kotlin.time.Duration.Companion.minutes
|
||||||
|
|
||||||
class TimelineItemContentMessageFactoryTest {
|
class TimelineItemContentMessageFactoryTest {
|
||||||
|
|
||||||
|
|
@ -140,7 +140,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||||
)
|
)
|
||||||
val expected = TimelineItemVideoContent(
|
val expected = TimelineItemVideoContent(
|
||||||
body = "body",
|
body = "body",
|
||||||
duration = 0,
|
duration = Duration.ZERO,
|
||||||
videoSource = MediaSource(url = "url", json = null),
|
videoSource = MediaSource(url = "url", json = null),
|
||||||
thumbnailSource = null,
|
thumbnailSource = null,
|
||||||
aspectRatio = null,
|
aspectRatio = null,
|
||||||
|
|
@ -163,7 +163,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||||
body = "body.mp4",
|
body = "body.mp4",
|
||||||
source = MediaSource("url"),
|
source = MediaSource("url"),
|
||||||
info = VideoInfo(
|
info = VideoInfo(
|
||||||
duration = ofMinutes(1),
|
duration = 1.minutes,
|
||||||
height = 100,
|
height = 100,
|
||||||
width = 300,
|
width = 300,
|
||||||
mimetype = MimeTypes.Mp4,
|
mimetype = MimeTypes.Mp4,
|
||||||
|
|
@ -184,7 +184,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||||
)
|
)
|
||||||
val expected = TimelineItemVideoContent(
|
val expected = TimelineItemVideoContent(
|
||||||
body = "body.mp4",
|
body = "body.mp4",
|
||||||
duration = 60_000,
|
duration = 1.minutes,
|
||||||
videoSource = MediaSource(url = "url", json = null),
|
videoSource = MediaSource(url = "url", json = null),
|
||||||
thumbnailSource = MediaSource("url_thumbnail"),
|
thumbnailSource = MediaSource("url_thumbnail"),
|
||||||
aspectRatio = 3f,
|
aspectRatio = 3f,
|
||||||
|
|
@ -226,7 +226,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||||
body = "body.mp3",
|
body = "body.mp3",
|
||||||
source = MediaSource("url"),
|
source = MediaSource("url"),
|
||||||
info = AudioInfo(
|
info = AudioInfo(
|
||||||
duration = ofMinutes(1),
|
duration = 1.minutes,
|
||||||
size = 123L,
|
size = 123L,
|
||||||
mimetype = MimeTypes.Mp3,
|
mimetype = MimeTypes.Mp3,
|
||||||
)
|
)
|
||||||
|
|
@ -237,7 +237,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||||
)
|
)
|
||||||
val expected = TimelineItemAudioContent(
|
val expected = TimelineItemAudioContent(
|
||||||
body = "body.mp3",
|
body = "body.mp3",
|
||||||
duration = ofMinutes(1),
|
duration = 1.minutes,
|
||||||
mediaSource = MediaSource(url = "url", json = null),
|
mediaSource = MediaSource(url = "url", json = null),
|
||||||
mimeType = MimeTypes.Mp3,
|
mimeType = MimeTypes.Mp3,
|
||||||
formattedFileSize = "123 Bytes",
|
formattedFileSize = "123 Bytes",
|
||||||
|
|
@ -274,12 +274,13 @@ class TimelineItemContentMessageFactoryTest {
|
||||||
body = "body.ogg",
|
body = "body.ogg",
|
||||||
source = MediaSource("url"),
|
source = MediaSource("url"),
|
||||||
info = AudioInfo(
|
info = AudioInfo(
|
||||||
duration = ofMinutes(1),
|
duration = 1.minutes,
|
||||||
size = 123L,
|
size = 123L,
|
||||||
mimetype = MimeTypes.Ogg,
|
mimetype = MimeTypes.Ogg,
|
||||||
),
|
),
|
||||||
details = AudioDetails(
|
details = AudioDetails(
|
||||||
duration = ofMinutes(1), waveform = listOf(1f, 2f)
|
duration = 1.minutes,
|
||||||
|
waveform = listOf(1f, 2f),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
@ -289,7 +290,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||||
val expected = TimelineItemVoiceContent(
|
val expected = TimelineItemVoiceContent(
|
||||||
eventId = AN_EVENT_ID,
|
eventId = AN_EVENT_ID,
|
||||||
body = "body.ogg",
|
body = "body.ogg",
|
||||||
duration = ofMinutes(1),
|
duration = 1.minutes,
|
||||||
mediaSource = MediaSource(url = "url", json = null),
|
mediaSource = MediaSource(url = "url", json = null),
|
||||||
mimeType = MimeTypes.Ogg,
|
mimeType = MimeTypes.Ogg,
|
||||||
waveform = listOf(1f, 2f).toImmutableList()
|
waveform = listOf(1f, 2f).toImmutableList()
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
class VoiceMessagePresenterTest {
|
class VoiceMessagePresenterTest {
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -49,7 +50,7 @@ class VoiceMessagePresenterTest {
|
||||||
fun `pressing play downloads and plays`() = runTest {
|
fun `pressing play downloads and plays`() = runTest {
|
||||||
val presenter = createVoiceMessagePresenter(
|
val presenter = createVoiceMessagePresenter(
|
||||||
mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000),
|
mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000),
|
||||||
content = aTimelineItemVoiceContent(durationMs = 2_000),
|
content = aTimelineItemVoiceContent(duration = 2_000.milliseconds),
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -87,7 +88,7 @@ class VoiceMessagePresenterTest {
|
||||||
mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000),
|
mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000),
|
||||||
voiceMessageMediaRepo = FakeVoiceMessageMediaRepo().apply { shouldFail = true },
|
voiceMessageMediaRepo = FakeVoiceMessageMediaRepo().apply { shouldFail = true },
|
||||||
analyticsService = analyticsService,
|
analyticsService = analyticsService,
|
||||||
content = aTimelineItemVoiceContent(durationMs = 2_000),
|
content = aTimelineItemVoiceContent(duration = 2_000.milliseconds),
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -123,7 +124,7 @@ class VoiceMessagePresenterTest {
|
||||||
fun `pressing pause while playing pauses`() = runTest {
|
fun `pressing pause while playing pauses`() = runTest {
|
||||||
val presenter = createVoiceMessagePresenter(
|
val presenter = createVoiceMessagePresenter(
|
||||||
mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000),
|
mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000),
|
||||||
content = aTimelineItemVoiceContent(durationMs = 2_000),
|
content = aTimelineItemVoiceContent(duration = 2_000.milliseconds),
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -172,7 +173,7 @@ class VoiceMessagePresenterTest {
|
||||||
fun `seeking before play`() = runTest {
|
fun `seeking before play`() = runTest {
|
||||||
val presenter = createVoiceMessagePresenter(
|
val presenter = createVoiceMessagePresenter(
|
||||||
mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000),
|
mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000),
|
||||||
content = aTimelineItemVoiceContent(durationMs = 10_000),
|
content = aTimelineItemVoiceContent(duration = 10_000.milliseconds),
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -196,7 +197,7 @@ class VoiceMessagePresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `seeking after play`() = runTest {
|
fun `seeking after play`() = runTest {
|
||||||
val presenter = createVoiceMessagePresenter(
|
val presenter = createVoiceMessagePresenter(
|
||||||
content = aTimelineItemVoiceContent(durationMs = 10_000),
|
content = aTimelineItemVoiceContent(duration = 10_000.milliseconds),
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.api.media
|
package io.element.android.libraries.matrix.api.media
|
||||||
|
|
||||||
import java.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
data class AudioDetails(
|
data class AudioDetails(
|
||||||
val duration: Duration,
|
val duration: Duration,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.api.media
|
package io.element.android.libraries.matrix.api.media
|
||||||
|
|
||||||
import java.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
data class AudioInfo(
|
data class AudioInfo(
|
||||||
val duration: Duration?,
|
val duration: Duration?,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.api.media
|
package io.element.android.libraries.matrix.api.media
|
||||||
|
|
||||||
import java.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
data class VideoInfo(
|
data class VideoInfo(
|
||||||
val duration: Duration?,
|
val duration: Duration?,
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,17 @@
|
||||||
package io.element.android.libraries.matrix.impl.media
|
package io.element.android.libraries.matrix.impl.media
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.media.AudioDetails
|
import io.element.android.libraries.matrix.api.media.AudioDetails
|
||||||
|
import kotlin.time.toJavaDuration
|
||||||
|
import kotlin.time.toKotlinDuration
|
||||||
import org.matrix.rustcomponents.sdk.UnstableAudioDetailsContent as RustAudioDetails
|
import org.matrix.rustcomponents.sdk.UnstableAudioDetailsContent as RustAudioDetails
|
||||||
|
|
||||||
fun RustAudioDetails.map(): AudioDetails = AudioDetails(
|
fun RustAudioDetails.map(): AudioDetails = AudioDetails(
|
||||||
duration = duration,
|
duration = duration.toKotlinDuration(),
|
||||||
waveform = waveform.fromMSC3246range(),
|
waveform = waveform.fromMSC3246range(),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun AudioDetails.map(): RustAudioDetails = RustAudioDetails(
|
fun AudioDetails.map(): RustAudioDetails = RustAudioDetails(
|
||||||
duration = duration,
|
duration = duration.toJavaDuration(),
|
||||||
waveform = waveform.toMSC3246range()
|
waveform = waveform.toMSC3246range()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,18 @@
|
||||||
package io.element.android.libraries.matrix.impl.media
|
package io.element.android.libraries.matrix.impl.media
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.media.AudioInfo
|
import io.element.android.libraries.matrix.api.media.AudioInfo
|
||||||
|
import kotlin.time.toJavaDuration
|
||||||
|
import kotlin.time.toKotlinDuration
|
||||||
import org.matrix.rustcomponents.sdk.AudioInfo as RustAudioInfo
|
import org.matrix.rustcomponents.sdk.AudioInfo as RustAudioInfo
|
||||||
|
|
||||||
fun RustAudioInfo.map(): AudioInfo = AudioInfo(
|
fun RustAudioInfo.map(): AudioInfo = AudioInfo(
|
||||||
duration = duration,
|
duration = duration?.toKotlinDuration(),
|
||||||
size = size?.toLong(),
|
size = size?.toLong(),
|
||||||
mimetype = mimetype
|
mimetype = mimetype
|
||||||
)
|
)
|
||||||
|
|
||||||
fun AudioInfo.map(): RustAudioInfo = RustAudioInfo(
|
fun AudioInfo.map(): RustAudioInfo = RustAudioInfo(
|
||||||
duration = duration,
|
duration = duration?.toJavaDuration(),
|
||||||
size = size?.toULong(),
|
size = size?.toULong(),
|
||||||
mimetype = mimetype,
|
mimetype = mimetype,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,12 @@
|
||||||
package io.element.android.libraries.matrix.impl.media
|
package io.element.android.libraries.matrix.impl.media
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.media.VideoInfo
|
import io.element.android.libraries.matrix.api.media.VideoInfo
|
||||||
|
import kotlin.time.toJavaDuration
|
||||||
|
import kotlin.time.toKotlinDuration
|
||||||
import org.matrix.rustcomponents.sdk.VideoInfo as RustVideoInfo
|
import org.matrix.rustcomponents.sdk.VideoInfo as RustVideoInfo
|
||||||
|
|
||||||
fun RustVideoInfo.map(): VideoInfo = VideoInfo(
|
fun RustVideoInfo.map(): VideoInfo = VideoInfo(
|
||||||
duration = duration,
|
duration = duration?.toKotlinDuration(),
|
||||||
height = height?.toLong(),
|
height = height?.toLong(),
|
||||||
width = width?.toLong(),
|
width = width?.toLong(),
|
||||||
mimetype = mimetype,
|
mimetype = mimetype,
|
||||||
|
|
@ -31,7 +33,7 @@ fun RustVideoInfo.map(): VideoInfo = VideoInfo(
|
||||||
)
|
)
|
||||||
|
|
||||||
fun VideoInfo.map(): RustVideoInfo = RustVideoInfo(
|
fun VideoInfo.map(): RustVideoInfo = RustVideoInfo(
|
||||||
duration = duration,
|
duration = duration?.toJavaDuration(),
|
||||||
height = height?.toULong(),
|
height = height?.toULong(),
|
||||||
width = width?.toULong(),
|
width = width?.toULong(),
|
||||||
mimetype = mimetype,
|
mimetype = mimetype,
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,9 @@ import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.time.Duration
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
class AndroidMediaPreProcessor @Inject constructor(
|
class AndroidMediaPreProcessor @Inject constructor(
|
||||||
|
|
@ -269,6 +270,6 @@ fun ImageCompressionResult.toImageInfo(mimeType: String, thumbnailResult: Thumbn
|
||||||
|
|
||||||
private fun MediaMetadataRetriever.extractDuration(): Duration {
|
private fun MediaMetadataRetriever.extractDuration(): Duration {
|
||||||
val durationInMs = extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLong() ?: 0L
|
val durationInMs = extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLong() ?: 0L
|
||||||
return Duration.ofMillis(durationInMs)
|
return durationInMs.milliseconds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import io.element.android.libraries.mediaupload.api.MediaUploadInfo
|
||||||
import io.element.android.tests.testutils.simulateLongTask
|
import io.element.android.tests.testutils.simulateLongTask
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
import kotlin.time.toJavaDuration
|
|
||||||
|
|
||||||
class FakeMediaPreProcessor : MediaPreProcessor {
|
class FakeMediaPreProcessor : MediaPreProcessor {
|
||||||
|
|
||||||
|
|
@ -63,7 +62,7 @@ class FakeMediaPreProcessor : MediaPreProcessor {
|
||||||
MediaUploadInfo.Audio(
|
MediaUploadInfo.Audio(
|
||||||
file = File("audio.ogg"),
|
file = File("audio.ogg"),
|
||||||
audioInfo = AudioInfo(
|
audioInfo = AudioInfo(
|
||||||
duration = 1000.seconds.toJavaDuration(),
|
duration = 1000.seconds,
|
||||||
size = 1000,
|
size = 1000,
|
||||||
mimetype = "audio/ogg",
|
mimetype = "audio/ogg",
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue