Reduce API of JoinedRoom, caller must use the Timeline API from liveTimeline instead. (#4731)
This removes lots of boilerplate code.
This commit is contained in:
parent
c6f6c2cd65
commit
caf25894d6
20 changed files with 258 additions and 651 deletions
|
|
@ -101,7 +101,7 @@ class SendLocationPresenter @Inject constructor(
|
||||||
when (mode) {
|
when (mode) {
|
||||||
SendLocationState.Mode.PinLocation -> {
|
SendLocationState.Mode.PinLocation -> {
|
||||||
val geoUri = event.cameraPosition.toGeoUri()
|
val geoUri = event.cameraPosition.toGeoUri()
|
||||||
room.sendLocation(
|
room.liveTimeline.sendLocation(
|
||||||
body = generateBody(geoUri),
|
body = generateBody(geoUri),
|
||||||
geoUri = geoUri,
|
geoUri = geoUri,
|
||||||
description = null,
|
description = null,
|
||||||
|
|
@ -119,7 +119,7 @@ class SendLocationPresenter @Inject constructor(
|
||||||
}
|
}
|
||||||
SendLocationState.Mode.SenderLocation -> {
|
SendLocationState.Mode.SenderLocation -> {
|
||||||
val geoUri = event.toGeoUri()
|
val geoUri = event.toGeoUri()
|
||||||
room.sendLocation(
|
room.liveTimeline.sendLocation(
|
||||||
body = generateBody(geoUri),
|
body = generateBody(geoUri),
|
||||||
geoUri = geoUri,
|
geoUri = geoUri,
|
||||||
description = null,
|
description = null,
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTran
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
||||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
|
|
@ -266,7 +267,9 @@ class SendLocationPresenterTest {
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
val joinedRoom = FakeJoinedRoom(
|
val joinedRoom = FakeJoinedRoom(
|
||||||
sendLocationResult = sendLocationResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendLocationLambda = sendLocationResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
|
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
|
|
@ -327,7 +330,9 @@ class SendLocationPresenterTest {
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
val joinedRoom = FakeJoinedRoom(
|
val joinedRoom = FakeJoinedRoom(
|
||||||
sendLocationResult = sendLocationResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendLocationLambda = sendLocationResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
|
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
|
|
@ -388,7 +393,9 @@ class SendLocationPresenterTest {
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
val joinedRoom = FakeJoinedRoom(
|
val joinedRoom = FakeJoinedRoom(
|
||||||
sendLocationResult = sendLocationResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendLocationLambda = sendLocationResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
|
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ class MessageComposerPresenter @AssistedInject constructor(
|
||||||
resetComposer(markdownTextEditorState, richTextEditorState, fromEdit = capturedMode is MessageComposerMode.Edit)
|
resetComposer(markdownTextEditorState, richTextEditorState, fromEdit = capturedMode is MessageComposerMode.Edit)
|
||||||
when (capturedMode) {
|
when (capturedMode) {
|
||||||
is MessageComposerMode.Attachment,
|
is MessageComposerMode.Attachment,
|
||||||
is MessageComposerMode.Normal -> room.sendMessage(
|
is MessageComposerMode.Normal -> room.liveTimeline.sendMessage(
|
||||||
body = message.markdown,
|
body = message.markdown,
|
||||||
htmlBody = message.html,
|
htmlBody = message.html,
|
||||||
intentionalMentions = message.intentionalMentions
|
intentionalMentions = message.intentionalMentions
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
|
||||||
package io.element.android.features.messages.impl
|
package io.element.android.features.messages.impl
|
||||||
|
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
|
|
@ -96,6 +98,7 @@ import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
|
import kotlinx.coroutines.test.advanceUntilIdle
|
||||||
import kotlinx.coroutines.test.runCurrent
|
import kotlinx.coroutines.test.runCurrent
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
|
|
@ -173,12 +176,14 @@ class MessagesPresenterTest {
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
|
advanceUntilIdle()
|
||||||
assert(toggleReactionSuccess)
|
assert(toggleReactionSuccess)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
|
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
// No crashes when sending a reaction failed
|
// No crashes when sending a reaction failed
|
||||||
timeline.apply { toggleReactionLambda = toggleReactionFailure }
|
timeline.toggleReactionLambda = toggleReactionFailure
|
||||||
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
|
advanceUntilIdle()
|
||||||
assert(toggleReactionFailure)
|
assert(toggleReactionFailure)
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
|
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
|
|
@ -209,6 +214,7 @@ class MessagesPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
|
||||||
|
advanceUntilIdle()
|
||||||
assert(toggleReactionSuccess)
|
assert(toggleReactionSuccess)
|
||||||
.isCalledExactly(2)
|
.isCalledExactly(2)
|
||||||
.withSequence(
|
.withSequence(
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import io.element.android.libraries.matrix.test.A_CAPTION
|
||||||
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder
|
import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder
|
||||||
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
||||||
import io.element.android.libraries.mediaupload.api.MediaSender
|
import io.element.android.libraries.mediaupload.api.MediaSender
|
||||||
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
|
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
|
||||||
|
|
@ -108,15 +109,18 @@ class AttachmentsPreviewPresenterTest {
|
||||||
fun `present - send media success scenario`() = runTest {
|
fun `present - send media success scenario`() = runTest {
|
||||||
val sendFileResult =
|
val sendFileResult =
|
||||||
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
||||||
Result.success(FakeMediaUploadHandler())
|
Result.success(FakeMediaUploadHandler())
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
progressCallbackValues = listOf(
|
liveTimeline = FakeTimeline(
|
||||||
Pair(0, 10),
|
progressCallbackValues = listOf(
|
||||||
Pair(5, 10),
|
Pair(0, 10),
|
||||||
Pair(10, 10)
|
Pair(5, 10),
|
||||||
),
|
Pair(10, 10)
|
||||||
sendFileResult = sendFileResult,
|
),
|
||||||
|
).apply {
|
||||||
|
sendFileLambda = sendFileResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val onDoneListener = lambdaRecorder<Unit> { }
|
val onDoneListener = lambdaRecorder<Unit> { }
|
||||||
val presenter = createAttachmentsPreviewPresenter(
|
val presenter = createAttachmentsPreviewPresenter(
|
||||||
|
|
@ -146,10 +150,12 @@ class AttachmentsPreviewPresenterTest {
|
||||||
fun `present - send media after pre-processing success scenario`() = runTest {
|
fun `present - send media after pre-processing success scenario`() = runTest {
|
||||||
val sendFileResult =
|
val sendFileResult =
|
||||||
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
||||||
Result.success(FakeMediaUploadHandler())
|
Result.success(FakeMediaUploadHandler())
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendFileResult = sendFileResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendFileLambda = sendFileResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val onDoneListener = lambdaRecorder<Unit> { }
|
val onDoneListener = lambdaRecorder<Unit> { }
|
||||||
val processLatch = CompletableDeferred<Unit>()
|
val processLatch = CompletableDeferred<Unit>()
|
||||||
|
|
@ -182,10 +188,12 @@ class AttachmentsPreviewPresenterTest {
|
||||||
fun `present - send media before pre-processing success scenario`() = runTest {
|
fun `present - send media before pre-processing success scenario`() = runTest {
|
||||||
val sendFileResult =
|
val sendFileResult =
|
||||||
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
||||||
Result.success(FakeMediaUploadHandler())
|
Result.success(FakeMediaUploadHandler())
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendFileResult = sendFileResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendFileLambda = sendFileResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val onDoneListener = lambdaRecorder<Unit> { }
|
val onDoneListener = lambdaRecorder<Unit> { }
|
||||||
val processLatch = CompletableDeferred<Unit>()
|
val processLatch = CompletableDeferred<Unit>()
|
||||||
|
|
@ -298,7 +306,9 @@ class AttachmentsPreviewPresenterTest {
|
||||||
givenImageResult()
|
givenImageResult()
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendImageResult = sendImageResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendImageLambda = sendImageResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val onDoneListener = lambdaRecorder<Unit> { }
|
val onDoneListener = lambdaRecorder<Unit> { }
|
||||||
val presenter = createAttachmentsPreviewPresenter(
|
val presenter = createAttachmentsPreviewPresenter(
|
||||||
|
|
@ -340,7 +350,9 @@ class AttachmentsPreviewPresenterTest {
|
||||||
givenVideoResult()
|
givenVideoResult()
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendVideoResult = sendVideoResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendVideoLambda = sendVideoResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val onDoneListener = lambdaRecorder<Unit> { }
|
val onDoneListener = lambdaRecorder<Unit> { }
|
||||||
val presenter = createAttachmentsPreviewPresenter(
|
val presenter = createAttachmentsPreviewPresenter(
|
||||||
|
|
@ -382,7 +394,9 @@ class AttachmentsPreviewPresenterTest {
|
||||||
givenAudioResult()
|
givenAudioResult()
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendAudioResult = sendAudioResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendAudioLambda = sendAudioResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val onDoneListener = lambdaRecorder<Unit> { }
|
val onDoneListener = lambdaRecorder<Unit> { }
|
||||||
val presenter = createAttachmentsPreviewPresenter(
|
val presenter = createAttachmentsPreviewPresenter(
|
||||||
|
|
@ -416,10 +430,12 @@ class AttachmentsPreviewPresenterTest {
|
||||||
val failure = MediaPreProcessor.Failure(null)
|
val failure = MediaPreProcessor.Failure(null)
|
||||||
val sendFileResult =
|
val sendFileResult =
|
||||||
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
||||||
Result.failure(failure)
|
Result.failure(failure)
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendFileResult = sendFileResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendFileLambda = sendFileResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val presenter = createAttachmentsPreviewPresenter(room = room, mediaUploadOnSendQueueEnabled = false)
|
val presenter = createAttachmentsPreviewPresenter(room = room, mediaUploadOnSendQueueEnabled = false)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -445,11 +461,13 @@ class AttachmentsPreviewPresenterTest {
|
||||||
val failure = MediaPreProcessor.Failure(null)
|
val failure = MediaPreProcessor.Failure(null)
|
||||||
val sendFileResult =
|
val sendFileResult =
|
||||||
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
||||||
Result.failure(failure)
|
Result.failure(failure)
|
||||||
}
|
}
|
||||||
val onDoneListenerResult = lambdaRecorder<Unit> {}
|
val onDoneListenerResult = lambdaRecorder<Unit> {}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendFileResult = sendFileResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendFileLambda = sendFileResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val presenter = createAttachmentsPreviewPresenter(room = room, mediaUploadOnSendQueueEnabled = true, onDoneListener = onDoneListenerResult)
|
val presenter = createAttachmentsPreviewPresenter(room = room, mediaUploadOnSendQueueEnabled = true, onDoneListener = onDoneListenerResult)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
|
||||||
|
|
@ -384,7 +384,9 @@ class MessageComposerPresenterTest {
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
coroutineScope = this,
|
coroutineScope = this,
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
sendMessageResult = { _, _, _ -> Result.success(Unit) },
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendMessageLambda = { _, _, _ -> Result.success(Unit) }
|
||||||
|
},
|
||||||
typingNoticeResult = { Result.success(Unit) }
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -418,7 +420,9 @@ class MessageComposerPresenterTest {
|
||||||
coroutineScope = this,
|
coroutineScope = this,
|
||||||
isRichTextEditorEnabled = false,
|
isRichTextEditorEnabled = false,
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
sendMessageResult = { _, _, _ -> Result.success(Unit) },
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendMessageLambda = { _, _, _ -> Result.success(Unit) }
|
||||||
|
},
|
||||||
typingNoticeResult = { Result.success(Unit) }
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -1118,16 +1122,16 @@ class MessageComposerPresenterTest {
|
||||||
val editMessageLambda = lambdaRecorder { _: EventOrTransactionId, _: String, _: String?, _: List<IntentionalMention> ->
|
val editMessageLambda = lambdaRecorder { _: EventOrTransactionId, _: String, _: String?, _: List<IntentionalMention> ->
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
val timeline = FakeTimeline().apply {
|
|
||||||
this.replyMessageLambda = replyMessageLambda
|
|
||||||
this.editMessageLambda = editMessageLambda
|
|
||||||
}
|
|
||||||
val sendMessageResult = lambdaRecorder { _: String, _: String?, _: List<IntentionalMention> ->
|
val sendMessageResult = lambdaRecorder { _: String, _: String?, _: List<IntentionalMention> ->
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
}
|
}
|
||||||
|
val timeline = FakeTimeline().apply {
|
||||||
|
this.replyMessageLambda = replyMessageLambda
|
||||||
|
this.editMessageLambda = editMessageLambda
|
||||||
|
sendMessageLambda = sendMessageResult
|
||||||
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
liveTimeline = timeline,
|
liveTimeline = timeline,
|
||||||
sendMessageResult = sendMessageResult,
|
|
||||||
typingNoticeResult = { Result.success(Unit) }
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
)
|
)
|
||||||
val presenter = createPresenter(room = room, coroutineScope = this)
|
val presenter = createPresenter(room = room, coroutineScope = this)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import io.element.android.libraries.matrix.api.media.AudioInfo
|
||||||
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
|
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
|
||||||
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
||||||
import io.element.android.libraries.mediaupload.api.MediaSender
|
import io.element.android.libraries.mediaupload.api.MediaSender
|
||||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||||
|
|
@ -45,6 +46,7 @@ import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.collections.immutable.toPersistentList
|
import kotlinx.collections.immutable.toPersistentList
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
|
import kotlinx.coroutines.test.advanceUntilIdle
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
@ -65,7 +67,9 @@ class VoiceMessageComposerPresenterTest {
|
||||||
Result.success(FakeMediaUploadHandler())
|
Result.success(FakeMediaUploadHandler())
|
||||||
}
|
}
|
||||||
private val joinedRoom = FakeJoinedRoom(
|
private val joinedRoom = FakeJoinedRoom(
|
||||||
sendVoiceMessageResult = sendVoiceMessageResult
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendVoiceMessageLambda = sendVoiceMessageResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
private val mediaPreProcessor = FakeMediaPreProcessor().apply { givenAudioResult() }
|
private val mediaPreProcessor = FakeMediaPreProcessor().apply { givenAudioResult() }
|
||||||
private val mediaSender = MediaSender(mediaPreProcessor, joinedRoom, InMemorySessionPreferencesStore())
|
private val mediaSender = MediaSender(mediaPreProcessor, joinedRoom, InMemorySessionPreferencesStore())
|
||||||
|
|
@ -295,7 +299,6 @@ class VoiceMessageComposerPresenterTest {
|
||||||
awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop))
|
awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop))
|
||||||
awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
|
awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
|
||||||
assertThat(awaitItem().voiceMessageState).isEqualTo(aPreviewState().toSendingState())
|
assertThat(awaitItem().voiceMessageState).isEqualTo(aPreviewState().toSendingState())
|
||||||
|
|
||||||
val finalState = awaitItem()
|
val finalState = awaitItem()
|
||||||
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
||||||
sendVoiceMessageResult.assertions().isCalledOnce()
|
sendVoiceMessageResult.assertions().isCalledOnce()
|
||||||
|
|
@ -317,7 +320,7 @@ class VoiceMessageComposerPresenterTest {
|
||||||
awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop))
|
awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop))
|
||||||
awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
|
awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
|
||||||
skipItems(1) // Sending state
|
skipItems(1) // Sending state
|
||||||
|
advanceUntilIdle()
|
||||||
// Now reply with a voice message
|
// Now reply with a voice message
|
||||||
messageComposerContext.composerMode = aReplyMode()
|
messageComposerContext.composerMode = aReplyMode()
|
||||||
awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start))
|
awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start))
|
||||||
|
|
@ -653,7 +656,7 @@ class VoiceMessageComposerPresenterTest {
|
||||||
permissionsPresenter: PermissionsPresenter = createFakePermissionsPresenter(),
|
permissionsPresenter: PermissionsPresenter = createFakePermissionsPresenter(),
|
||||||
): VoiceMessageComposerPresenter {
|
): VoiceMessageComposerPresenter {
|
||||||
return VoiceMessageComposerPresenter(
|
return VoiceMessageComposerPresenter(
|
||||||
this,
|
backgroundScope,
|
||||||
voiceRecorder,
|
voiceRecorder,
|
||||||
analyticsService,
|
analyticsService,
|
||||||
mediaSender,
|
mediaSender,
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class DefaultEndPollAction @Inject constructor(
|
||||||
private val analyticsService: AnalyticsService,
|
private val analyticsService: AnalyticsService,
|
||||||
) : EndPollAction {
|
) : EndPollAction {
|
||||||
override suspend fun execute(pollStartId: EventId): Result<Unit> {
|
override suspend fun execute(pollStartId: EventId): Result<Unit> {
|
||||||
return room.endPoll(
|
return room.liveTimeline.endPoll(
|
||||||
pollStartId = pollStartId,
|
pollStartId = pollStartId,
|
||||||
text = "The poll with event id: $pollStartId has ended."
|
text = "The poll with event id: $pollStartId has ended."
|
||||||
).onSuccess {
|
).onSuccess {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class DefaultSendPollResponseAction @Inject constructor(
|
||||||
private val analyticsService: AnalyticsService,
|
private val analyticsService: AnalyticsService,
|
||||||
) : SendPollResponseAction {
|
) : SendPollResponseAction {
|
||||||
override suspend fun execute(pollStartId: EventId, answerId: String): Result<Unit> {
|
override suspend fun execute(pollStartId: EventId, answerId: String): Result<Unit> {
|
||||||
return room.sendPollResponse(
|
return room.liveTimeline.sendPollResponse(
|
||||||
pollStartId = pollStartId,
|
pollStartId = pollStartId,
|
||||||
answers = listOf(answerId),
|
answers = listOf(answerId),
|
||||||
).onSuccess {
|
).onSuccess {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class PollRepository @Inject constructor(
|
||||||
pollKind: PollKind,
|
pollKind: PollKind,
|
||||||
maxSelections: Int,
|
maxSelections: Int,
|
||||||
): Result<Unit> = when (existingPollId) {
|
): Result<Unit> = when (existingPollId) {
|
||||||
null -> room.createPoll(
|
null -> room.liveTimeline.createPoll(
|
||||||
question = question,
|
question = question,
|
||||||
answers = answers,
|
answers = answers,
|
||||||
maxSelections = maxSelections,
|
maxSelections = maxSelections,
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,9 @@ class CreatePollPresenterTest {
|
||||||
val createPollResult = lambdaRecorder<String, List<String>, Int, PollKind, Result<Unit>> { _, _, _, _ -> Result.success(Unit) }
|
val createPollResult = lambdaRecorder<String, List<String>, Int, PollKind, Result<Unit>> { _, _, _, _ -> Result.success(Unit) }
|
||||||
val presenter = createCreatePollPresenter(
|
val presenter = createCreatePollPresenter(
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
createPollResult = createPollResult
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
createPollLambda = createPollResult
|
||||||
|
},
|
||||||
),
|
),
|
||||||
mode = CreatePollMode.NewPoll,
|
mode = CreatePollMode.NewPoll,
|
||||||
)
|
)
|
||||||
|
|
@ -169,7 +171,9 @@ class CreatePollPresenterTest {
|
||||||
}
|
}
|
||||||
val presenter = createCreatePollPresenter(
|
val presenter = createCreatePollPresenter(
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
createPollResult = createPollResult
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
createPollLambda = createPollResult
|
||||||
|
},
|
||||||
),
|
),
|
||||||
mode = CreatePollMode.NewPoll,
|
mode = CreatePollMode.NewPoll,
|
||||||
)
|
)
|
||||||
|
|
@ -253,12 +257,8 @@ class CreatePollPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `when edit poll fails, error is tracked`() = runTest {
|
fun `when edit poll fails, error is tracked`() = runTest {
|
||||||
val error = Exception("cause")
|
val error = Exception("cause")
|
||||||
val editPollResult = lambdaRecorder { _: EventId, _: String, _: List<String>, _: Int, _: PollKind ->
|
|
||||||
Result.failure<Unit>(error)
|
|
||||||
}
|
|
||||||
val presenter = createCreatePollPresenter(
|
val presenter = createCreatePollPresenter(
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
editPollResult = editPollResult,
|
|
||||||
liveTimeline = timeline,
|
liveTimeline = timeline,
|
||||||
),
|
),
|
||||||
mode = CreatePollMode.EditPoll(pollEventId),
|
mode = CreatePollMode.EditPoll(pollEventId),
|
||||||
|
|
@ -276,7 +276,7 @@ class CreatePollPresenterTest {
|
||||||
awaitPollLoaded().eventSink(CreatePollEvents.SetAnswer(0, "A"))
|
awaitPollLoaded().eventSink(CreatePollEvents.SetAnswer(0, "A"))
|
||||||
awaitPollLoaded(newAnswer1 = "A").eventSink(CreatePollEvents.Save)
|
awaitPollLoaded(newAnswer1 = "A").eventSink(CreatePollEvents.Save)
|
||||||
advanceUntilIdle() // Wait for the coroutine to finish
|
advanceUntilIdle() // Wait for the coroutine to finish
|
||||||
assert(editPollLambda).isCalledOnce()
|
editPollLambda.assertions().isCalledOnce()
|
||||||
assertThat(fakeAnalyticsService.capturedEvents).isEmpty()
|
assertThat(fakeAnalyticsService.capturedEvents).isEmpty()
|
||||||
assertThat(fakeAnalyticsService.trackedErrors).hasSize(1)
|
assertThat(fakeAnalyticsService.trackedErrors).hasSize(1)
|
||||||
assertThat(fakeAnalyticsService.trackedErrors).containsExactly(
|
assertThat(fakeAnalyticsService.trackedErrors).containsExactly(
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ class SharePresenter @AssistedInject constructor(
|
||||||
onPlainText = { text ->
|
onPlainText = { text ->
|
||||||
roomIds
|
roomIds
|
||||||
.map { roomId ->
|
.map { roomId ->
|
||||||
matrixClient.getJoinedRoom(roomId)?.sendMessage(
|
matrixClient.getJoinedRoom(roomId)?.liveTimeline?.sendMessage(
|
||||||
body = text,
|
body = text,
|
||||||
htmlBody = null,
|
htmlBody = null,
|
||||||
intentionalMentions = emptyList(),
|
intentionalMentions = emptyList(),
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
||||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||||
import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore
|
import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore
|
||||||
|
|
@ -91,7 +92,9 @@ class SharePresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - send text ok`() = runTest {
|
fun `present - send text ok`() = runTest {
|
||||||
val joinedRoom = FakeJoinedRoom(
|
val joinedRoom = FakeJoinedRoom(
|
||||||
sendMessageResult = { _, _, _ -> Result.success(Unit) },
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendMessageLambda = { _, _, _ -> Result.success(Unit) }
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val matrixClient = FakeMatrixClient().apply {
|
val matrixClient = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, joinedRoom)
|
givenGetRoomResult(A_ROOM_ID, joinedRoom)
|
||||||
|
|
@ -122,7 +125,9 @@ class SharePresenterTest {
|
||||||
Result.success(FakeMediaUploadHandler())
|
Result.success(FakeMediaUploadHandler())
|
||||||
}
|
}
|
||||||
val joinedRoom = FakeJoinedRoom(
|
val joinedRoom = FakeJoinedRoom(
|
||||||
sendFileResult = sendFileResult,
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendFileLambda = sendFileResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val matrixClient = FakeMatrixClient().apply {
|
val matrixClient = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, joinedRoom)
|
givenGetRoomResult(A_ROOM_ID, joinedRoom)
|
||||||
|
|
|
||||||
|
|
@ -9,34 +9,21 @@ package io.element.android.libraries.matrix.api.room
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.core.DeviceId
|
import io.element.android.libraries.matrix.api.core.DeviceId
|
||||||
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.core.ProgressCallback
|
|
||||||
import io.element.android.libraries.matrix.api.core.RoomAlias
|
import io.element.android.libraries.matrix.api.core.RoomAlias
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
|
||||||
import io.element.android.libraries.matrix.api.core.SendHandle
|
import io.element.android.libraries.matrix.api.core.SendHandle
|
||||||
import io.element.android.libraries.matrix.api.core.TransactionId
|
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
||||||
import io.element.android.libraries.matrix.api.media.AudioInfo
|
|
||||||
import io.element.android.libraries.matrix.api.media.FileInfo
|
|
||||||
import io.element.android.libraries.matrix.api.media.ImageInfo
|
|
||||||
import io.element.android.libraries.matrix.api.media.MediaUploadHandler
|
|
||||||
import io.element.android.libraries.matrix.api.media.VideoInfo
|
|
||||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
|
||||||
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
||||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||||
import io.element.android.libraries.matrix.api.room.knock.KnockRequest
|
import io.element.android.libraries.matrix.api.room.knock.KnockRequest
|
||||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
|
||||||
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
|
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
|
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||||
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
|
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
|
||||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
interface JoinedRoom : BaseRoom {
|
interface JoinedRoom : BaseRoom {
|
||||||
val syncUpdateFlow: StateFlow<Long>
|
val syncUpdateFlow: StateFlow<Long>
|
||||||
|
|
@ -63,135 +50,14 @@ interface JoinedRoom : BaseRoom {
|
||||||
createTimelineParams: CreateTimelineParams,
|
createTimelineParams: CreateTimelineParams,
|
||||||
): Result<Timeline>
|
): Result<Timeline>
|
||||||
|
|
||||||
suspend fun sendMessage(body: String, htmlBody: String?, intentionalMentions: List<IntentionalMention>): Result<Unit>
|
|
||||||
|
|
||||||
suspend fun editMessage(eventId: EventId, body: String, htmlBody: String?, intentionalMentions: List<IntentionalMention>): Result<Unit>
|
suspend fun editMessage(eventId: EventId, body: String, htmlBody: String?, intentionalMentions: List<IntentionalMention>): Result<Unit>
|
||||||
|
|
||||||
suspend fun sendImage(
|
|
||||||
file: File,
|
|
||||||
thumbnailFile: File?,
|
|
||||||
imageInfo: ImageInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler>
|
|
||||||
|
|
||||||
suspend fun sendVideo(
|
|
||||||
file: File,
|
|
||||||
thumbnailFile: File?,
|
|
||||||
videoInfo: VideoInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler>
|
|
||||||
|
|
||||||
suspend fun sendAudio(
|
|
||||||
file: File,
|
|
||||||
audioInfo: AudioInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler>
|
|
||||||
|
|
||||||
suspend fun sendFile(
|
|
||||||
file: File,
|
|
||||||
fileInfo: FileInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler>
|
|
||||||
|
|
||||||
suspend fun sendVoiceMessage(
|
|
||||||
file: File,
|
|
||||||
audioInfo: AudioInfo,
|
|
||||||
waveform: List<Float>,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Share a location message in the room.
|
|
||||||
*
|
|
||||||
* @param body A human readable textual representation of the location.
|
|
||||||
* @param geoUri A geo URI (RFC 5870) representing the location e.g. `geo:51.5008,0.1247;u=35`.
|
|
||||||
* Respectively: latitude, longitude, and (optional) uncertainty.
|
|
||||||
* @param description Optional description of the location to display to the user.
|
|
||||||
* @param zoomLevel Optional zoom level to display the map at.
|
|
||||||
* @param assetType Optional type of the location asset.
|
|
||||||
* Set to SENDER if sharing own location. Set to PIN if sharing any location.
|
|
||||||
*/
|
|
||||||
suspend fun sendLocation(
|
|
||||||
body: String,
|
|
||||||
geoUri: String,
|
|
||||||
description: String? = null,
|
|
||||||
zoomLevel: Int? = null,
|
|
||||||
assetType: AssetType? = null,
|
|
||||||
): Result<Unit>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a poll in the room.
|
|
||||||
*
|
|
||||||
* @param question The question to ask.
|
|
||||||
* @param answers The list of answers.
|
|
||||||
* @param maxSelections The maximum number of answers that can be selected.
|
|
||||||
* @param pollKind The kind of poll to create.
|
|
||||||
*/
|
|
||||||
suspend fun createPoll(
|
|
||||||
question: String,
|
|
||||||
answers: List<String>,
|
|
||||||
maxSelections: Int,
|
|
||||||
pollKind: PollKind,
|
|
||||||
): Result<Unit>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Edit a poll in the room.
|
|
||||||
*
|
|
||||||
* @param pollStartId The event ID of the poll start event.
|
|
||||||
* @param question The question to ask.
|
|
||||||
* @param answers The list of answers.
|
|
||||||
* @param maxSelections The maximum number of answers that can be selected.
|
|
||||||
* @param pollKind The kind of poll to create.
|
|
||||||
*/
|
|
||||||
suspend fun editPoll(
|
|
||||||
pollStartId: EventId,
|
|
||||||
question: String,
|
|
||||||
answers: List<String>,
|
|
||||||
maxSelections: Int,
|
|
||||||
pollKind: PollKind,
|
|
||||||
): Result<Unit>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a response to a poll.
|
|
||||||
*
|
|
||||||
* @param pollStartId The event ID of the poll start event.
|
|
||||||
* @param answers The list of answer ids to send.
|
|
||||||
*/
|
|
||||||
suspend fun sendPollResponse(pollStartId: EventId, answers: List<String>): Result<Unit>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ends a poll in the room.
|
|
||||||
*
|
|
||||||
* @param pollStartId The event ID of the poll start event.
|
|
||||||
* @param text Fallback text of the poll end event.
|
|
||||||
*/
|
|
||||||
suspend fun endPoll(pollStartId: EventId, text: String): Result<Unit>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a typing notification.
|
* Send a typing notification.
|
||||||
* @param isTyping True if the user is typing, false otherwise.
|
* @param isTyping True if the user is typing, false otherwise.
|
||||||
*/
|
*/
|
||||||
suspend fun typingNotice(isTyping: Boolean): Result<Unit>
|
suspend fun typingNotice(isTyping: Boolean): Result<Unit>
|
||||||
|
|
||||||
suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit>
|
|
||||||
|
|
||||||
suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit>
|
|
||||||
|
|
||||||
suspend fun cancelSend(transactionId: TransactionId): Result<Unit>
|
|
||||||
|
|
||||||
suspend fun inviteUserById(id: UserId): Result<Unit>
|
suspend fun inviteUserById(id: UserId): Result<Unit>
|
||||||
|
|
||||||
suspend fun updateAvatar(mimeType: String, data: ByteArray): Result<Unit>
|
suspend fun updateAvatar(mimeType: String, data: ByteArray): Result<Unit>
|
||||||
|
|
|
||||||
|
|
@ -13,20 +13,11 @@ import io.element.android.libraries.core.extensions.mapFailure
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||||
import io.element.android.libraries.matrix.api.core.DeviceId
|
import io.element.android.libraries.matrix.api.core.DeviceId
|
||||||
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.core.ProgressCallback
|
|
||||||
import io.element.android.libraries.matrix.api.core.RoomAlias
|
import io.element.android.libraries.matrix.api.core.RoomAlias
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
|
||||||
import io.element.android.libraries.matrix.api.core.SendHandle
|
import io.element.android.libraries.matrix.api.core.SendHandle
|
||||||
import io.element.android.libraries.matrix.api.core.TransactionId
|
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
||||||
import io.element.android.libraries.matrix.api.media.AudioInfo
|
|
||||||
import io.element.android.libraries.matrix.api.media.FileInfo
|
|
||||||
import io.element.android.libraries.matrix.api.media.ImageInfo
|
|
||||||
import io.element.android.libraries.matrix.api.media.MediaUploadHandler
|
|
||||||
import io.element.android.libraries.matrix.api.media.VideoInfo
|
|
||||||
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
|
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
|
||||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
|
||||||
import io.element.android.libraries.matrix.api.room.BaseRoom
|
import io.element.android.libraries.matrix.api.room.BaseRoom
|
||||||
import io.element.android.libraries.matrix.api.room.CreateTimelineParams
|
import io.element.android.libraries.matrix.api.room.CreateTimelineParams
|
||||||
import io.element.android.libraries.matrix.api.room.IntentionalMention
|
import io.element.android.libraries.matrix.api.room.IntentionalMention
|
||||||
|
|
@ -35,14 +26,11 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationSettingsStat
|
||||||
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
||||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||||
import io.element.android.libraries.matrix.api.room.knock.KnockRequest
|
import io.element.android.libraries.matrix.api.room.knock.KnockRequest
|
||||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
|
||||||
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
|
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
|
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||||
import io.element.android.libraries.matrix.api.room.roomNotificationSettings
|
import io.element.android.libraries.matrix.api.room.roomNotificationSettings
|
||||||
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
|
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
|
||||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
||||||
import io.element.android.libraries.matrix.impl.core.RustSendHandle
|
import io.element.android.libraries.matrix.impl.core.RustSendHandle
|
||||||
|
|
@ -84,7 +72,6 @@ import org.matrix.rustcomponents.sdk.getElementCallRequiredPermissions
|
||||||
import org.matrix.rustcomponents.sdk.use
|
import org.matrix.rustcomponents.sdk.use
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uniffi.matrix_sdk.RoomPowerLevelChanges
|
import uniffi.matrix_sdk.RoomPowerLevelChanges
|
||||||
import java.io.File
|
|
||||||
import kotlin.coroutines.cancellation.CancellationException
|
import kotlin.coroutines.cancellation.CancellationException
|
||||||
import org.matrix.rustcomponents.sdk.IdentityStatusChange as RustIdentityStateChange
|
import org.matrix.rustcomponents.sdk.IdentityStatusChange as RustIdentityStateChange
|
||||||
import org.matrix.rustcomponents.sdk.KnockRequest as InnerKnockRequest
|
import org.matrix.rustcomponents.sdk.KnockRequest as InnerKnockRequest
|
||||||
|
|
@ -249,10 +236,6 @@ class JoinedRustRoom(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendMessage(body: String, htmlBody: String?, intentionalMentions: List<IntentionalMention>): Result<Unit> {
|
|
||||||
return liveTimeline.sendMessage(body, htmlBody, intentionalMentions)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun editMessage(
|
override suspend fun editMessage(
|
||||||
eventId: EventId,
|
eventId: EventId,
|
||||||
body: String,
|
body: String,
|
||||||
|
|
@ -266,159 +249,12 @@ class JoinedRustRoom(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendImage(
|
|
||||||
file: File,
|
|
||||||
thumbnailFile: File?,
|
|
||||||
imageInfo: ImageInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> {
|
|
||||||
return liveTimeline.sendImage(
|
|
||||||
file = file,
|
|
||||||
thumbnailFile = thumbnailFile,
|
|
||||||
imageInfo = imageInfo,
|
|
||||||
caption = caption,
|
|
||||||
formattedCaption = formattedCaption,
|
|
||||||
progressCallback = progressCallback,
|
|
||||||
replyParameters = replyParameters
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendVideo(
|
|
||||||
file: File,
|
|
||||||
thumbnailFile: File?,
|
|
||||||
videoInfo: VideoInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> {
|
|
||||||
return liveTimeline.sendVideo(
|
|
||||||
file = file,
|
|
||||||
thumbnailFile = thumbnailFile,
|
|
||||||
videoInfo = videoInfo,
|
|
||||||
caption = caption,
|
|
||||||
formattedCaption = formattedCaption,
|
|
||||||
progressCallback = progressCallback,
|
|
||||||
replyParameters = replyParameters
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendAudio(
|
|
||||||
file: File,
|
|
||||||
audioInfo: AudioInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> {
|
|
||||||
return liveTimeline.sendAudio(
|
|
||||||
file = file,
|
|
||||||
audioInfo = audioInfo,
|
|
||||||
caption = caption,
|
|
||||||
formattedCaption = formattedCaption,
|
|
||||||
progressCallback = progressCallback,
|
|
||||||
replyParameters = replyParameters,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendFile(
|
|
||||||
file: File,
|
|
||||||
fileInfo: FileInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> {
|
|
||||||
return liveTimeline.sendFile(
|
|
||||||
file = file,
|
|
||||||
fileInfo = fileInfo,
|
|
||||||
caption = caption,
|
|
||||||
formattedCaption = formattedCaption,
|
|
||||||
progressCallback = progressCallback,
|
|
||||||
replyParameters = replyParameters,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendVoiceMessage(
|
|
||||||
file: File,
|
|
||||||
audioInfo: AudioInfo,
|
|
||||||
waveform: List<Float>,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> {
|
|
||||||
return liveTimeline.sendVoiceMessage(
|
|
||||||
file = file,
|
|
||||||
audioInfo = audioInfo,
|
|
||||||
waveform = waveform,
|
|
||||||
progressCallback = progressCallback,
|
|
||||||
replyParameters = replyParameters,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendLocation(
|
|
||||||
body: String,
|
|
||||||
geoUri: String,
|
|
||||||
description: String?,
|
|
||||||
zoomLevel: Int?,
|
|
||||||
assetType: AssetType?,
|
|
||||||
): Result<Unit> {
|
|
||||||
return liveTimeline.sendLocation(body, geoUri, description, zoomLevel, assetType)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun createPoll(
|
|
||||||
question: String,
|
|
||||||
answers: List<String>,
|
|
||||||
maxSelections: Int,
|
|
||||||
pollKind: PollKind,
|
|
||||||
): Result<Unit> {
|
|
||||||
return liveTimeline.createPoll(question, answers, maxSelections, pollKind)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun editPoll(
|
|
||||||
pollStartId: EventId,
|
|
||||||
question: String,
|
|
||||||
answers: List<String>,
|
|
||||||
maxSelections: Int,
|
|
||||||
pollKind: PollKind,
|
|
||||||
): Result<Unit> {
|
|
||||||
return liveTimeline.editPoll(pollStartId, question, answers, maxSelections, pollKind)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendPollResponse(
|
|
||||||
pollStartId: EventId,
|
|
||||||
answers: List<String>
|
|
||||||
): Result<Unit> {
|
|
||||||
return liveTimeline.sendPollResponse(pollStartId, answers)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun endPoll(
|
|
||||||
pollStartId: EventId,
|
|
||||||
text: String
|
|
||||||
): Result<Unit> {
|
|
||||||
return liveTimeline.endPoll(pollStartId, text)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun typingNotice(isTyping: Boolean) = withContext(roomDispatcher) {
|
override suspend fun typingNotice(isTyping: Boolean) = withContext(roomDispatcher) {
|
||||||
runCatching {
|
runCatching {
|
||||||
innerRoom.typingNotice(isTyping)
|
innerRoom.typingNotice(isTyping)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> {
|
|
||||||
return liveTimeline.toggleReaction(emoji, eventOrTransactionId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> {
|
|
||||||
return liveTimeline.forwardEvent(eventId, roomIds)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun cancelSend(transactionId: TransactionId): Result<Unit> {
|
|
||||||
return liveTimeline.cancelSend(transactionId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun inviteUserById(id: UserId): Result<Unit> = withContext(roomDispatcher) {
|
override suspend fun inviteUserById(id: UserId): Result<Unit> = withContext(roomDispatcher) {
|
||||||
runCatching {
|
runCatching {
|
||||||
innerRoom.inviteUserById(id.value)
|
innerRoom.inviteUserById(id.value)
|
||||||
|
|
|
||||||
|
|
@ -12,17 +12,9 @@ import io.element.android.libraries.matrix.api.core.DeviceId
|
||||||
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.core.ProgressCallback
|
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
||||||
import io.element.android.libraries.matrix.api.core.RoomAlias
|
import io.element.android.libraries.matrix.api.core.RoomAlias
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
|
||||||
import io.element.android.libraries.matrix.api.core.SendHandle
|
import io.element.android.libraries.matrix.api.core.SendHandle
|
||||||
import io.element.android.libraries.matrix.api.core.TransactionId
|
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
import io.element.android.libraries.matrix.api.encryption.identity.IdentityStateChange
|
||||||
import io.element.android.libraries.matrix.api.media.AudioInfo
|
|
||||||
import io.element.android.libraries.matrix.api.media.FileInfo
|
|
||||||
import io.element.android.libraries.matrix.api.media.ImageInfo
|
|
||||||
import io.element.android.libraries.matrix.api.media.MediaUploadHandler
|
|
||||||
import io.element.android.libraries.matrix.api.media.VideoInfo
|
|
||||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
|
||||||
import io.element.android.libraries.matrix.api.room.BaseRoom
|
import io.element.android.libraries.matrix.api.room.BaseRoom
|
||||||
import io.element.android.libraries.matrix.api.room.CreateTimelineParams
|
import io.element.android.libraries.matrix.api.room.CreateTimelineParams
|
||||||
import io.element.android.libraries.matrix.api.room.IntentionalMention
|
import io.element.android.libraries.matrix.api.room.IntentionalMention
|
||||||
|
|
@ -33,16 +25,12 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationSettingsStat
|
||||||
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
||||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||||
import io.element.android.libraries.matrix.api.room.knock.KnockRequest
|
import io.element.android.libraries.matrix.api.room.knock.KnockRequest
|
||||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
|
||||||
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
|
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
|
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
|
||||||
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
|
||||||
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
|
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
|
||||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
|
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
||||||
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
|
||||||
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
|
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
|
||||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.tests.testutils.lambda.lambdaError
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
|
@ -53,7 +41,6 @@ import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class FakeJoinedRoom(
|
class FakeJoinedRoom(
|
||||||
val baseRoom: FakeBaseRoom = FakeBaseRoom(),
|
val baseRoom: FakeBaseRoom = FakeBaseRoom(),
|
||||||
|
|
@ -63,35 +50,16 @@ class FakeJoinedRoom(
|
||||||
override val roomTypingMembersFlow: Flow<List<UserId>> = MutableStateFlow(emptyList()),
|
override val roomTypingMembersFlow: Flow<List<UserId>> = MutableStateFlow(emptyList()),
|
||||||
override val identityStateChangesFlow: Flow<List<IdentityStateChange>> = MutableStateFlow(emptyList()),
|
override val identityStateChangesFlow: Flow<List<IdentityStateChange>> = MutableStateFlow(emptyList()),
|
||||||
override val roomNotificationSettingsStateFlow: StateFlow<RoomNotificationSettingsState> =
|
override val roomNotificationSettingsStateFlow: StateFlow<RoomNotificationSettingsState> =
|
||||||
MutableStateFlow(RoomNotificationSettingsState.Unknown),
|
MutableStateFlow(RoomNotificationSettingsState.Unknown),
|
||||||
override val knockRequestsFlow: Flow<List<KnockRequest>> = MutableStateFlow(emptyList()),
|
override val knockRequestsFlow: Flow<List<KnockRequest>> = MutableStateFlow(emptyList()),
|
||||||
private val roomNotificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
|
private val roomNotificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
|
||||||
private var createTimelineResult: (CreateTimelineParams) -> Result<Timeline> = { lambdaError() },
|
private var createTimelineResult: (CreateTimelineParams) -> Result<Timeline> = { lambdaError() },
|
||||||
private val sendMessageResult: (String, String?, List<IntentionalMention>) -> Result<Unit> = { _, _, _ -> lambdaError() },
|
|
||||||
private val editMessageLambda: (EventId, String, String?, List<IntentionalMention>) -> Result<Unit> = { _, _, _, _ -> lambdaError() },
|
private val editMessageLambda: (EventId, String, String?, List<IntentionalMention>) -> Result<Unit> = { _, _, _, _ -> lambdaError() },
|
||||||
private val sendImageResult: (File, File?, ImageInfo, String?, String?, ProgressCallback?, ReplyParameters?) -> Result<FakeMediaUploadHandler> =
|
|
||||||
{ _, _, _, _, _, _, _ -> lambdaError() },
|
|
||||||
private val sendVideoResult: (File, File?, VideoInfo, String?, String?, ProgressCallback?, ReplyParameters?) -> Result<FakeMediaUploadHandler> =
|
|
||||||
{ _, _, _, _, _, _, _ -> lambdaError() },
|
|
||||||
private val sendFileResult: (File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?) -> Result<FakeMediaUploadHandler> =
|
|
||||||
{ _, _, _, _, _, _ -> lambdaError() },
|
|
||||||
private val sendAudioResult: (File, AudioInfo, String?, String?, ProgressCallback?, ReplyParameters?) -> Result<FakeMediaUploadHandler> =
|
|
||||||
{ _, _, _, _, _, _ -> lambdaError() },
|
|
||||||
private val sendVoiceMessageResult: (File, AudioInfo, List<Float>, ProgressCallback?, ReplyParameters?) -> Result<FakeMediaUploadHandler> =
|
|
||||||
{ _, _, _, _, _ -> lambdaError() },
|
|
||||||
private val sendLocationResult: (String, String, String?, Int?, AssetType?) -> Result<Unit> = { _, _, _, _, _ -> lambdaError() },
|
|
||||||
private val sendCallNotificationIfNeededResult: () -> Result<Unit> = { lambdaError() },
|
private val sendCallNotificationIfNeededResult: () -> Result<Unit> = { lambdaError() },
|
||||||
private val progressCallbackValues: List<Pair<Long, Long>> = emptyList(),
|
private val progressCallbackValues: List<Pair<Long, Long>> = emptyList(),
|
||||||
private val createPollResult: (String, List<String>, Int, PollKind) -> Result<Unit> = { _, _, _, _ -> lambdaError() },
|
|
||||||
private val editPollResult: (EventId, String, List<String>, Int, PollKind) -> Result<Unit> = { _, _, _, _, _ -> lambdaError() },
|
|
||||||
private val sendPollResponseResult: (EventId, List<String>) -> Result<Unit> = { _, _ -> lambdaError() },
|
|
||||||
private val endPollResult: (EventId, String) -> Result<Unit> = { _, _ -> lambdaError() },
|
|
||||||
private val generateWidgetWebViewUrlResult: (MatrixWidgetSettings, String, String?, String?) -> Result<String> = { _, _, _, _ -> lambdaError() },
|
private val generateWidgetWebViewUrlResult: (MatrixWidgetSettings, String, String?, String?) -> Result<String> = { _, _, _, _ -> lambdaError() },
|
||||||
private val getWidgetDriverResult: (MatrixWidgetSettings) -> Result<MatrixWidgetDriver> = { lambdaError() },
|
private val getWidgetDriverResult: (MatrixWidgetSettings) -> Result<MatrixWidgetDriver> = { lambdaError() },
|
||||||
private val typingNoticeResult: (Boolean) -> Result<Unit> = { lambdaError() },
|
private val typingNoticeResult: (Boolean) -> Result<Unit> = { lambdaError() },
|
||||||
private val toggleReactionResult: (String, EventOrTransactionId) -> Result<Unit> = { _, _ -> lambdaError() },
|
|
||||||
private val forwardEventResult: (EventId, List<RoomId>) -> Result<Unit> = { _, _ -> lambdaError() },
|
|
||||||
private val cancelSendResult: (TransactionId) -> Result<Unit> = { lambdaError() },
|
|
||||||
private val inviteUserResult: (UserId) -> Result<Unit> = { lambdaError() },
|
private val inviteUserResult: (UserId) -> Result<Unit> = { lambdaError() },
|
||||||
private val setNameResult: (String) -> Result<Unit> = { lambdaError() },
|
private val setNameResult: (String) -> Result<Unit> = { lambdaError() },
|
||||||
private val setTopicResult: (String) -> Result<Unit> = { lambdaError() },
|
private val setTopicResult: (String) -> Result<Unit> = { lambdaError() },
|
||||||
|
|
@ -127,10 +95,6 @@ class FakeJoinedRoom(
|
||||||
createTimelineResult(createTimelineParams)
|
createTimelineResult(createTimelineParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendMessage(body: String, htmlBody: String?, intentionalMentions: List<IntentionalMention>): Result<Unit> = simulateLongTask {
|
|
||||||
sendMessageResult(body, htmlBody, intentionalMentions)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun editMessage(
|
override suspend fun editMessage(
|
||||||
eventId: EventId,
|
eventId: EventId,
|
||||||
body: String,
|
body: String,
|
||||||
|
|
@ -140,174 +104,10 @@ class FakeJoinedRoom(
|
||||||
editMessageLambda(eventId, body, htmlBody, intentionalMentions)
|
editMessageLambda(eventId, body, htmlBody, intentionalMentions)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendImage(
|
|
||||||
file: File,
|
|
||||||
thumbnailFile: File?,
|
|
||||||
imageInfo: ImageInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> = simulateLongTask {
|
|
||||||
simulateSendMediaProgress(progressCallback)
|
|
||||||
sendImageResult(
|
|
||||||
file,
|
|
||||||
thumbnailFile,
|
|
||||||
imageInfo,
|
|
||||||
caption,
|
|
||||||
formattedCaption,
|
|
||||||
progressCallback,
|
|
||||||
replyParameters,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendVideo(
|
|
||||||
file: File,
|
|
||||||
thumbnailFile: File?,
|
|
||||||
videoInfo: VideoInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> = simulateLongTask {
|
|
||||||
simulateSendMediaProgress(progressCallback)
|
|
||||||
sendVideoResult(
|
|
||||||
file,
|
|
||||||
thumbnailFile,
|
|
||||||
videoInfo,
|
|
||||||
caption,
|
|
||||||
formattedCaption,
|
|
||||||
progressCallback,
|
|
||||||
replyParameters,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendAudio(
|
|
||||||
file: File,
|
|
||||||
audioInfo: AudioInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> = simulateLongTask {
|
|
||||||
simulateSendMediaProgress(progressCallback)
|
|
||||||
sendAudioResult(
|
|
||||||
file,
|
|
||||||
audioInfo,
|
|
||||||
caption,
|
|
||||||
formattedCaption,
|
|
||||||
progressCallback,
|
|
||||||
replyParameters,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendFile(
|
|
||||||
file: File,
|
|
||||||
fileInfo: FileInfo,
|
|
||||||
caption: String?,
|
|
||||||
formattedCaption: String?,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> = simulateLongTask {
|
|
||||||
simulateSendMediaProgress(progressCallback)
|
|
||||||
sendFileResult(
|
|
||||||
file,
|
|
||||||
fileInfo,
|
|
||||||
caption,
|
|
||||||
formattedCaption,
|
|
||||||
progressCallback,
|
|
||||||
replyParameters,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendVoiceMessage(
|
|
||||||
file: File,
|
|
||||||
audioInfo: AudioInfo,
|
|
||||||
waveform: List<Float>,
|
|
||||||
progressCallback: ProgressCallback?,
|
|
||||||
replyParameters: ReplyParameters?,
|
|
||||||
): Result<MediaUploadHandler> = simulateLongTask {
|
|
||||||
simulateSendMediaProgress(progressCallback)
|
|
||||||
sendVoiceMessageResult(
|
|
||||||
file,
|
|
||||||
audioInfo,
|
|
||||||
waveform,
|
|
||||||
progressCallback,
|
|
||||||
replyParameters,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendLocation(
|
|
||||||
body: String,
|
|
||||||
geoUri: String,
|
|
||||||
description: String?,
|
|
||||||
zoomLevel: Int?,
|
|
||||||
assetType: AssetType?,
|
|
||||||
): Result<Unit> = simulateLongTask {
|
|
||||||
return sendLocationResult(
|
|
||||||
body,
|
|
||||||
geoUri,
|
|
||||||
description,
|
|
||||||
zoomLevel,
|
|
||||||
assetType,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun createPoll(question: String, answers: List<String>, maxSelections: Int, pollKind: PollKind): Result<Unit> = simulateLongTask {
|
|
||||||
return createPollResult(
|
|
||||||
question,
|
|
||||||
answers,
|
|
||||||
maxSelections,
|
|
||||||
pollKind,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun editPoll(
|
|
||||||
pollStartId: EventId,
|
|
||||||
question: String,
|
|
||||||
answers: List<String>,
|
|
||||||
maxSelections: Int,
|
|
||||||
pollKind: PollKind
|
|
||||||
): Result<Unit> = simulateLongTask {
|
|
||||||
return editPollResult(
|
|
||||||
pollStartId,
|
|
||||||
question,
|
|
||||||
answers,
|
|
||||||
maxSelections,
|
|
||||||
pollKind,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendPollResponse(pollStartId: EventId, answers: List<String>): Result<Unit> = simulateLongTask {
|
|
||||||
return sendPollResponseResult(
|
|
||||||
pollStartId,
|
|
||||||
answers,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun endPoll(pollStartId: EventId, text: String): Result<Unit> = simulateLongTask {
|
|
||||||
endPollResult(
|
|
||||||
pollStartId,
|
|
||||||
text,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun typingNotice(isTyping: Boolean): Result<Unit> = simulateLongTask {
|
override suspend fun typingNotice(isTyping: Boolean): Result<Unit> = simulateLongTask {
|
||||||
typingNoticeResult(isTyping)
|
typingNoticeResult(isTyping)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> = simulateLongTask {
|
|
||||||
toggleReactionResult(emoji, eventOrTransactionId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> = simulateLongTask {
|
|
||||||
forwardEventResult(eventId, roomIds)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun cancelSend(transactionId: TransactionId): Result<Unit> = simulateLongTask {
|
|
||||||
cancelSendResult(transactionId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun inviteUserById(id: UserId): Result<Unit> = simulateLongTask {
|
override suspend fun inviteUserById(id: UserId): Result<Unit> = simulateLongTask {
|
||||||
inviteUserResult(id)
|
inviteUserResult(id)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ package io.element.android.libraries.matrix.test.timeline
|
||||||
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.core.ProgressCallback
|
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.api.core.TransactionId
|
||||||
import io.element.android.libraries.matrix.api.media.AudioInfo
|
import io.element.android.libraries.matrix.api.media.AudioInfo
|
||||||
import io.element.android.libraries.matrix.api.media.FileInfo
|
import io.element.android.libraries.matrix.api.media.FileInfo
|
||||||
import io.element.android.libraries.matrix.api.media.ImageInfo
|
import io.element.android.libraries.matrix.api.media.ImageInfo
|
||||||
|
|
@ -26,6 +27,8 @@ import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransa
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.InReplyTo
|
import io.element.android.libraries.matrix.api.timeline.item.event.InReplyTo
|
||||||
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.tests.testutils.lambda.lambdaError
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.simulateLongTask
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
@ -47,23 +50,31 @@ class FakeTimeline(
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
override val membershipChangeEventReceived: Flow<Unit> = MutableSharedFlow(),
|
override val membershipChangeEventReceived: Flow<Unit> = MutableSharedFlow(),
|
||||||
|
private val progressCallbackValues: List<Pair<Long, Long>> = emptyList(),
|
||||||
|
private val cancelSendResult: (TransactionId) -> Result<Unit> = { lambdaError() },
|
||||||
) : Timeline {
|
) : Timeline {
|
||||||
var sendMessageLambda: (
|
var sendMessageLambda: (
|
||||||
body: String,
|
body: String,
|
||||||
htmlBody: String?,
|
htmlBody: String?,
|
||||||
intentionalMentions: List<IntentionalMention>,
|
intentionalMentions: List<IntentionalMention>,
|
||||||
) -> Result<Unit> = { _, _, _ ->
|
) -> Result<Unit> = { _, _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun cancelSend(transactionId: TransactionId): Result<Unit> = simulateLongTask {
|
||||||
|
cancelSendResult(transactionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendMessage(
|
override suspend fun sendMessage(
|
||||||
body: String,
|
body: String,
|
||||||
htmlBody: String?,
|
htmlBody: String?,
|
||||||
intentionalMentions: List<IntentionalMention>,
|
intentionalMentions: List<IntentionalMention>,
|
||||||
): Result<Unit> = sendMessageLambda(body, htmlBody, intentionalMentions)
|
): Result<Unit> = simulateLongTask {
|
||||||
|
sendMessageLambda(body, htmlBody, intentionalMentions)
|
||||||
|
}
|
||||||
|
|
||||||
var redactEventLambda: (eventOrTransactionId: EventOrTransactionId, reason: String?) -> Result<Unit> = { _, _ ->
|
var redactEventLambda: (eventOrTransactionId: EventOrTransactionId, reason: String?) -> Result<Unit> = { _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun redactEvent(
|
override suspend fun redactEvent(
|
||||||
|
|
@ -77,7 +88,7 @@ class FakeTimeline(
|
||||||
htmlBody: String?,
|
htmlBody: String?,
|
||||||
intentionalMentions: List<IntentionalMention>,
|
intentionalMentions: List<IntentionalMention>,
|
||||||
) -> Result<Unit> = { _, _, _, _ ->
|
) -> Result<Unit> = { _, _, _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun editMessage(
|
override suspend fun editMessage(
|
||||||
|
|
@ -117,7 +128,7 @@ class FakeTimeline(
|
||||||
intentionalMentions: List<IntentionalMention>,
|
intentionalMentions: List<IntentionalMention>,
|
||||||
fromNotification: Boolean,
|
fromNotification: Boolean,
|
||||||
) -> Result<Unit> = { _, _, _, _, _ ->
|
) -> Result<Unit> = { _, _, _, _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun replyMessage(
|
override suspend fun replyMessage(
|
||||||
|
|
@ -154,15 +165,18 @@ class FakeTimeline(
|
||||||
formattedCaption: String?,
|
formattedCaption: String?,
|
||||||
progressCallback: ProgressCallback?,
|
progressCallback: ProgressCallback?,
|
||||||
replyParameters: ReplyParameters?,
|
replyParameters: ReplyParameters?,
|
||||||
): Result<MediaUploadHandler> = sendImageLambda(
|
): Result<MediaUploadHandler> = simulateLongTask {
|
||||||
file,
|
simulateSendMediaProgress(progressCallback)
|
||||||
thumbnailFile,
|
sendImageLambda(
|
||||||
imageInfo,
|
file,
|
||||||
caption,
|
thumbnailFile,
|
||||||
formattedCaption,
|
imageInfo,
|
||||||
progressCallback,
|
caption,
|
||||||
replyParameters,
|
formattedCaption,
|
||||||
)
|
progressCallback,
|
||||||
|
replyParameters,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var sendVideoLambda: (
|
var sendVideoLambda: (
|
||||||
file: File,
|
file: File,
|
||||||
|
|
@ -184,15 +198,18 @@ class FakeTimeline(
|
||||||
formattedCaption: String?,
|
formattedCaption: String?,
|
||||||
progressCallback: ProgressCallback?,
|
progressCallback: ProgressCallback?,
|
||||||
replyParameters: ReplyParameters?,
|
replyParameters: ReplyParameters?,
|
||||||
): Result<MediaUploadHandler> = sendVideoLambda(
|
): Result<MediaUploadHandler> = simulateLongTask {
|
||||||
file,
|
simulateSendMediaProgress(progressCallback)
|
||||||
thumbnailFile,
|
sendVideoLambda(
|
||||||
videoInfo,
|
file,
|
||||||
caption,
|
thumbnailFile,
|
||||||
formattedCaption,
|
videoInfo,
|
||||||
progressCallback,
|
caption,
|
||||||
replyParameters,
|
formattedCaption,
|
||||||
)
|
progressCallback,
|
||||||
|
replyParameters,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var sendAudioLambda: (
|
var sendAudioLambda: (
|
||||||
file: File,
|
file: File,
|
||||||
|
|
@ -212,14 +229,17 @@ class FakeTimeline(
|
||||||
formattedCaption: String?,
|
formattedCaption: String?,
|
||||||
progressCallback: ProgressCallback?,
|
progressCallback: ProgressCallback?,
|
||||||
replyParameters: ReplyParameters?,
|
replyParameters: ReplyParameters?,
|
||||||
): Result<MediaUploadHandler> = sendAudioLambda(
|
): Result<MediaUploadHandler> = simulateLongTask {
|
||||||
file,
|
simulateSendMediaProgress(progressCallback)
|
||||||
audioInfo,
|
sendAudioLambda(
|
||||||
caption,
|
file,
|
||||||
formattedCaption,
|
audioInfo,
|
||||||
progressCallback,
|
caption,
|
||||||
replyParameters,
|
formattedCaption,
|
||||||
)
|
progressCallback,
|
||||||
|
replyParameters,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var sendFileLambda: (
|
var sendFileLambda: (
|
||||||
file: File,
|
file: File,
|
||||||
|
|
@ -239,14 +259,17 @@ class FakeTimeline(
|
||||||
formattedCaption: String?,
|
formattedCaption: String?,
|
||||||
progressCallback: ProgressCallback?,
|
progressCallback: ProgressCallback?,
|
||||||
replyParameters: ReplyParameters?,
|
replyParameters: ReplyParameters?,
|
||||||
): Result<MediaUploadHandler> = sendFileLambda(
|
): Result<MediaUploadHandler> = simulateLongTask {
|
||||||
file,
|
simulateSendMediaProgress(progressCallback)
|
||||||
fileInfo,
|
sendFileLambda(
|
||||||
caption,
|
file,
|
||||||
formattedCaption,
|
fileInfo,
|
||||||
progressCallback,
|
caption,
|
||||||
replyParameters,
|
formattedCaption,
|
||||||
)
|
progressCallback,
|
||||||
|
replyParameters,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var sendVoiceMessageLambda: (
|
var sendVoiceMessageLambda: (
|
||||||
file: File,
|
file: File,
|
||||||
|
|
@ -264,13 +287,16 @@ class FakeTimeline(
|
||||||
waveform: List<Float>,
|
waveform: List<Float>,
|
||||||
progressCallback: ProgressCallback?,
|
progressCallback: ProgressCallback?,
|
||||||
replyParameters: ReplyParameters?,
|
replyParameters: ReplyParameters?,
|
||||||
): Result<MediaUploadHandler> = sendVoiceMessageLambda(
|
): Result<MediaUploadHandler> = simulateLongTask {
|
||||||
file,
|
simulateSendMediaProgress(progressCallback)
|
||||||
audioInfo,
|
sendVoiceMessageLambda(
|
||||||
waveform,
|
file,
|
||||||
progressCallback,
|
audioInfo,
|
||||||
replyParameters,
|
waveform,
|
||||||
)
|
progressCallback,
|
||||||
|
replyParameters,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var sendLocationLambda: (
|
var sendLocationLambda: (
|
||||||
body: String,
|
body: String,
|
||||||
|
|
@ -279,7 +305,7 @@ class FakeTimeline(
|
||||||
zoomLevel: Int?,
|
zoomLevel: Int?,
|
||||||
assetType: AssetType?,
|
assetType: AssetType?,
|
||||||
) -> Result<Unit> = { _, _, _, _, _ ->
|
) -> Result<Unit> = { _, _, _, _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendLocation(
|
override suspend fun sendLocation(
|
||||||
|
|
@ -288,24 +314,30 @@ class FakeTimeline(
|
||||||
description: String?,
|
description: String?,
|
||||||
zoomLevel: Int?,
|
zoomLevel: Int?,
|
||||||
assetType: AssetType?,
|
assetType: AssetType?,
|
||||||
): Result<Unit> = sendLocationLambda(
|
): Result<Unit> = simulateLongTask {
|
||||||
body,
|
sendLocationLambda(
|
||||||
geoUri,
|
body,
|
||||||
description,
|
geoUri,
|
||||||
zoomLevel,
|
description,
|
||||||
assetType
|
zoomLevel,
|
||||||
)
|
assetType,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var toggleReactionLambda: (emoji: String, eventOrTransactionId: EventOrTransactionId) -> Result<Unit> = { _, _ -> Result.success(Unit) }
|
var toggleReactionLambda: (emoji: String, eventOrTransactionId: EventOrTransactionId) -> Result<Unit> = { _, _ -> lambdaError() }
|
||||||
|
|
||||||
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> = toggleReactionLambda(
|
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> = simulateLongTask {
|
||||||
emoji,
|
toggleReactionLambda(
|
||||||
eventOrTransactionId
|
emoji,
|
||||||
)
|
eventOrTransactionId,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var forwardEventLambda: (eventId: EventId, roomIds: List<RoomId>) -> Result<Unit> = { _, _ -> Result.success(Unit) }
|
var forwardEventLambda: (eventId: EventId, roomIds: List<RoomId>) -> Result<Unit> = { _, _ -> lambdaError() }
|
||||||
|
|
||||||
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> = forwardEventLambda(eventId, roomIds)
|
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> = simulateLongTask {
|
||||||
|
forwardEventLambda(eventId, roomIds)
|
||||||
|
}
|
||||||
|
|
||||||
var createPollLambda: (
|
var createPollLambda: (
|
||||||
question: String,
|
question: String,
|
||||||
|
|
@ -313,20 +345,17 @@ class FakeTimeline(
|
||||||
maxSelections: Int,
|
maxSelections: Int,
|
||||||
pollKind: PollKind,
|
pollKind: PollKind,
|
||||||
) -> Result<Unit> = { _, _, _, _ ->
|
) -> Result<Unit> = { _, _, _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createPoll(
|
override suspend fun createPoll(question: String, answers: List<String>, maxSelections: Int, pollKind: PollKind): Result<Unit> = simulateLongTask {
|
||||||
question: String,
|
createPollLambda(
|
||||||
answers: List<String>,
|
question,
|
||||||
maxSelections: Int,
|
answers,
|
||||||
pollKind: PollKind,
|
maxSelections,
|
||||||
): Result<Unit> = createPollLambda(
|
pollKind,
|
||||||
question,
|
)
|
||||||
answers,
|
}
|
||||||
maxSelections,
|
|
||||||
pollKind
|
|
||||||
)
|
|
||||||
|
|
||||||
var editPollLambda: (
|
var editPollLambda: (
|
||||||
pollStartId: EventId,
|
pollStartId: EventId,
|
||||||
|
|
@ -335,7 +364,7 @@ class FakeTimeline(
|
||||||
maxSelections: Int,
|
maxSelections: Int,
|
||||||
pollKind: PollKind,
|
pollKind: PollKind,
|
||||||
) -> Result<Unit> = { _, _, _, _, _ ->
|
) -> Result<Unit> = { _, _, _, _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun editPoll(
|
override suspend fun editPoll(
|
||||||
|
|
@ -343,44 +372,56 @@ class FakeTimeline(
|
||||||
question: String,
|
question: String,
|
||||||
answers: List<String>,
|
answers: List<String>,
|
||||||
maxSelections: Int,
|
maxSelections: Int,
|
||||||
pollKind: PollKind,
|
pollKind: PollKind
|
||||||
): Result<Unit> = editPollLambda(
|
): Result<Unit> = simulateLongTask {
|
||||||
pollStartId,
|
editPollLambda(
|
||||||
question,
|
pollStartId,
|
||||||
answers,
|
question,
|
||||||
maxSelections,
|
answers,
|
||||||
pollKind
|
maxSelections,
|
||||||
)
|
pollKind,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var sendPollResponseLambda: (
|
var sendPollResponseLambda: (
|
||||||
pollStartId: EventId,
|
pollStartId: EventId,
|
||||||
answers: List<String>,
|
answers: List<String>,
|
||||||
) -> Result<Unit> = { _, _ ->
|
) -> Result<Unit> = { _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendPollResponse(
|
override suspend fun sendPollResponse(
|
||||||
pollStartId: EventId,
|
pollStartId: EventId,
|
||||||
answers: List<String>,
|
answers: List<String>,
|
||||||
): Result<Unit> = sendPollResponseLambda(pollStartId, answers)
|
): Result<Unit> = simulateLongTask {
|
||||||
|
sendPollResponseLambda(
|
||||||
|
pollStartId,
|
||||||
|
answers,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var endPollLambda: (
|
var endPollLambda: (
|
||||||
pollStartId: EventId,
|
pollStartId: EventId,
|
||||||
text: String,
|
text: String,
|
||||||
) -> Result<Unit> = { _, _ ->
|
) -> Result<Unit> = { _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun endPoll(
|
override suspend fun endPoll(
|
||||||
pollStartId: EventId,
|
pollStartId: EventId,
|
||||||
text: String,
|
text: String,
|
||||||
): Result<Unit> = endPollLambda(pollStartId, text)
|
): Result<Unit> = simulateLongTask {
|
||||||
|
endPollLambda(
|
||||||
|
pollStartId,
|
||||||
|
text,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var sendReadReceiptLambda: (
|
var sendReadReceiptLambda: (
|
||||||
eventId: EventId,
|
eventId: EventId,
|
||||||
receiptType: ReceiptType,
|
receiptType: ReceiptType,
|
||||||
) -> Result<Unit> = { _, _ ->
|
) -> Result<Unit> = { _, _ ->
|
||||||
Result.success(Unit)
|
lambdaError()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendReadReceipt(
|
override suspend fun sendReadReceipt(
|
||||||
|
|
@ -417,5 +458,12 @@ class FakeTimeline(
|
||||||
closeCounter++
|
closeCounter++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun simulateSendMediaProgress(progressCallback: ProgressCallback?) {
|
||||||
|
progressCallbackValues.forEach { (current, total) ->
|
||||||
|
progressCallback?.onProgress(current, total)
|
||||||
|
delay(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString() = "FakeTimeline: $name"
|
override fun toString() = "FakeTimeline: $name"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.api.core.ProgressCallback
|
||||||
import io.element.android.libraries.matrix.api.media.MediaUploadHandler
|
import io.element.android.libraries.matrix.api.media.MediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||||
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
|
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
|
@ -49,7 +50,7 @@ class MediaSender @Inject constructor(
|
||||||
progressCallback: ProgressCallback?,
|
progressCallback: ProgressCallback?,
|
||||||
replyParameters: ReplyParameters?,
|
replyParameters: ReplyParameters?,
|
||||||
): Result<Unit> {
|
): Result<Unit> {
|
||||||
return room.sendMedia(
|
return room.liveTimeline.sendMedia(
|
||||||
uploadInfo = mediaUploadInfo,
|
uploadInfo = mediaUploadInfo,
|
||||||
progressCallback = progressCallback,
|
progressCallback = progressCallback,
|
||||||
caption = caption,
|
caption = caption,
|
||||||
|
|
@ -76,7 +77,7 @@ class MediaSender @Inject constructor(
|
||||||
compressIfPossible = compressIfPossible,
|
compressIfPossible = compressIfPossible,
|
||||||
)
|
)
|
||||||
.flatMapCatching { info ->
|
.flatMapCatching { info ->
|
||||||
room.sendMedia(
|
room.liveTimeline.sendMedia(
|
||||||
uploadInfo = info,
|
uploadInfo = info,
|
||||||
progressCallback = progressCallback,
|
progressCallback = progressCallback,
|
||||||
caption = caption,
|
caption = caption,
|
||||||
|
|
@ -108,7 +109,7 @@ class MediaSender @Inject constructor(
|
||||||
audioInfo = audioInfo,
|
audioInfo = audioInfo,
|
||||||
waveform = waveForm,
|
waveform = waveForm,
|
||||||
)
|
)
|
||||||
room.sendMedia(
|
room.liveTimeline.sendMedia(
|
||||||
uploadInfo = newInfo,
|
uploadInfo = newInfo,
|
||||||
progressCallback = progressCallback,
|
progressCallback = progressCallback,
|
||||||
caption = null,
|
caption = null,
|
||||||
|
|
@ -130,7 +131,7 @@ class MediaSender @Inject constructor(
|
||||||
ongoingUploadJobs.remove(Job)
|
ongoingUploadJobs.remove(Job)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun JoinedRoom.sendMedia(
|
private suspend fun Timeline.sendMedia(
|
||||||
uploadInfo: MediaUploadInfo,
|
uploadInfo: MediaUploadInfo,
|
||||||
progressCallback: ProgressCallback?,
|
progressCallback: ProgressCallback?,
|
||||||
caption: String?,
|
caption: String?,
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||||
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
|
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
|
||||||
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||||
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
||||||
import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore
|
import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore
|
||||||
|
|
@ -51,7 +52,9 @@ class MediaSenderTest {
|
||||||
Result.success(FakeMediaUploadHandler())
|
Result.success(FakeMediaUploadHandler())
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendImageResult = sendImageResult
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendImageLambda = sendImageResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val sender = createMediaSender(room = room)
|
val sender = createMediaSender(room = room)
|
||||||
|
|
||||||
|
|
@ -74,14 +77,22 @@ class MediaSenderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given a failure in the media upload when sending the whole process fails`() = runTest {
|
fun `given a failure in the media upload when sending the whole process fails`() = runTest {
|
||||||
|
val preProcessor = FakeMediaPreProcessor().apply {
|
||||||
|
givenImageResult()
|
||||||
|
}
|
||||||
val sendImageResult =
|
val sendImageResult =
|
||||||
lambdaRecorder { _: File, _: File?, _: ImageInfo, _: String?, _: String?, _: ProgressCallback?, _: ReplyParameters? ->
|
lambdaRecorder { _: File, _: File?, _: ImageInfo, _: String?, _: String?, _: ProgressCallback?, _: ReplyParameters? ->
|
||||||
Result.failure<FakeMediaUploadHandler>(Exception())
|
Result.failure<FakeMediaUploadHandler>(Exception())
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendImageResult = sendImageResult
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendImageLambda = sendImageResult
|
||||||
|
},
|
||||||
|
)
|
||||||
|
val sender = createMediaSender(
|
||||||
|
preProcessor = preProcessor,
|
||||||
|
room = room,
|
||||||
)
|
)
|
||||||
val sender = createMediaSender(room = room)
|
|
||||||
|
|
||||||
val uri = Uri.parse("content://image.jpg")
|
val uri = Uri.parse("content://image.jpg")
|
||||||
val result = sender.sendMedia(uri = uri, mimeType = MimeTypes.Jpeg)
|
val result = sender.sendMedia(uri = uri, mimeType = MimeTypes.Jpeg)
|
||||||
|
|
@ -94,10 +105,12 @@ class MediaSenderTest {
|
||||||
fun `given a cancellation in the media upload when sending the job is cancelled`() = runTest(StandardTestDispatcher()) {
|
fun `given a cancellation in the media upload when sending the job is cancelled`() = runTest(StandardTestDispatcher()) {
|
||||||
val sendFileResult =
|
val sendFileResult =
|
||||||
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
|
||||||
Result.success(FakeMediaUploadHandler())
|
Result.success(FakeMediaUploadHandler())
|
||||||
}
|
}
|
||||||
val room = FakeJoinedRoom(
|
val room = FakeJoinedRoom(
|
||||||
sendFileResult = sendFileResult
|
liveTimeline = FakeTimeline().apply {
|
||||||
|
sendFileLambda = sendFileResult
|
||||||
|
},
|
||||||
)
|
)
|
||||||
val sender = createMediaSender(room = room)
|
val sender = createMediaSender(room = room)
|
||||||
val sendJob = launch {
|
val sendJob = launch {
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ class NotificationBroadcastReceiverHandlerTest {
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
runCurrent()
|
advanceUntilIdle()
|
||||||
sendMessage.assertions()
|
sendMessage.assertions()
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value(A_MESSAGE), value(null), value(emptyList<IntentionalMention>()))
|
.with(value(A_MESSAGE), value(null), value(emptyList<IntentionalMention>()))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue