Skip to content

Reduce API of JoinedRoom, caller must use the Timeline API from liveTimeline instead #4731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class SendLocationPresenter @Inject constructor(
when (mode) {
SendLocationState.Mode.PinLocation -> {
val geoUri = event.cameraPosition.toGeoUri()
room.sendLocation(
room.liveTimeline.sendLocation(
body = generateBody(geoUri),
geoUri = geoUri,
description = null,
Expand All @@ -119,7 +119,7 @@ class SendLocationPresenter @Inject constructor(
}
SendLocationState.Mode.SenderLocation -> {
val geoUri = event.toGeoUri()
room.sendLocation(
room.liveTimeline.sendLocation(
body = generateBody(geoUri),
geoUri = geoUri,
description = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.core.aBuildMeta
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.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.WarmUpRule
Expand Down Expand Up @@ -266,7 +267,9 @@ class SendLocationPresenterTest {
Result.success(Unit)
}
val joinedRoom = FakeJoinedRoom(
sendLocationResult = sendLocationResult,
liveTimeline = FakeTimeline().apply {
sendLocationLambda = sendLocationResult
},
)
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
fakePermissionsPresenter.givenState(
Expand Down Expand Up @@ -327,7 +330,9 @@ class SendLocationPresenterTest {
Result.success(Unit)
}
val joinedRoom = FakeJoinedRoom(
sendLocationResult = sendLocationResult,
liveTimeline = FakeTimeline().apply {
sendLocationLambda = sendLocationResult
},
)
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
fakePermissionsPresenter.givenState(
Expand Down Expand Up @@ -388,7 +393,9 @@ class SendLocationPresenterTest {
Result.success(Unit)
}
val joinedRoom = FakeJoinedRoom(
sendLocationResult = sendLocationResult,
liveTimeline = FakeTimeline().apply {
sendLocationLambda = sendLocationResult
},
)
val sendLocationPresenter = createSendLocationPresenter(joinedRoom)
fakePermissionsPresenter.givenState(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ class MessageComposerPresenter @AssistedInject constructor(
resetComposer(markdownTextEditorState, richTextEditorState, fromEdit = capturedMode is MessageComposerMode.Edit)
when (capturedMode) {
is MessageComposerMode.Attachment,
is MessageComposerMode.Normal -> room.sendMessage(
is MessageComposerMode.Normal -> room.liveTimeline.sendMessage(
body = message.markdown,
htmlBody = message.html,
intentionalMentions = message.intentionalMentions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* Please see LICENSE files in the repository root for full details.
*/

@file:OptIn(ExperimentalCoroutinesApi::class)

package io.element.android.features.messages.impl

import androidx.lifecycle.Lifecycle
Expand Down Expand Up @@ -96,6 +98,7 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Rule
Expand Down Expand Up @@ -173,12 +176,14 @@ class MessagesPresenterTest {
skipItems(1)
val initialState = awaitItem()
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
advanceUntilIdle()
assert(toggleReactionSuccess)
.isCalledOnce()
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
// No crashes when sending a reaction failed
timeline.apply { toggleReactionLambda = toggleReactionFailure }
timeline.toggleReactionLambda = toggleReactionFailure
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
advanceUntilIdle()
assert(toggleReactionFailure)
.isCalledOnce()
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
Expand Down Expand Up @@ -209,6 +214,7 @@ class MessagesPresenterTest {
val initialState = awaitItem()
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
advanceUntilIdle()
assert(toggleReactionSuccess)
.isCalledExactly(2)
.withSequence(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.permalink.FakePermalinkBuilder
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.MediaSender
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
Expand Down Expand Up @@ -108,15 +109,18 @@ class AttachmentsPreviewPresenterTest {
fun `present - send media success scenario`() = runTest {
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
Result.success(FakeMediaUploadHandler())
}
val room = FakeJoinedRoom(
progressCallbackValues = listOf(
Pair(0, 10),
Pair(5, 10),
Pair(10, 10)
),
sendFileResult = sendFileResult,
liveTimeline = FakeTimeline(
progressCallbackValues = listOf(
Pair(0, 10),
Pair(5, 10),
Pair(10, 10)
),
).apply {
sendFileLambda = sendFileResult
},
)
val onDoneListener = lambdaRecorder<Unit> { }
val presenter = createAttachmentsPreviewPresenter(
Expand Down Expand Up @@ -146,10 +150,12 @@ class AttachmentsPreviewPresenterTest {
fun `present - send media after pre-processing success scenario`() = runTest {
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
Result.success(FakeMediaUploadHandler())
}
val room = FakeJoinedRoom(
sendFileResult = sendFileResult,
liveTimeline = FakeTimeline().apply {
sendFileLambda = sendFileResult
},
)
val onDoneListener = lambdaRecorder<Unit> { }
val processLatch = CompletableDeferred<Unit>()
Expand Down Expand Up @@ -182,10 +188,12 @@ class AttachmentsPreviewPresenterTest {
fun `present - send media before pre-processing success scenario`() = runTest {
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
Result.success(FakeMediaUploadHandler())
}
Result.success(FakeMediaUploadHandler())
}
val room = FakeJoinedRoom(
sendFileResult = sendFileResult,
liveTimeline = FakeTimeline().apply {
sendFileLambda = sendFileResult
},
)
val onDoneListener = lambdaRecorder<Unit> { }
val processLatch = CompletableDeferred<Unit>()
Expand Down Expand Up @@ -298,7 +306,9 @@ class AttachmentsPreviewPresenterTest {
givenImageResult()
}
val room = FakeJoinedRoom(
sendImageResult = sendImageResult,
liveTimeline = FakeTimeline().apply {
sendImageLambda = sendImageResult
},
)
val onDoneListener = lambdaRecorder<Unit> { }
val presenter = createAttachmentsPreviewPresenter(
Expand Down Expand Up @@ -340,7 +350,9 @@ class AttachmentsPreviewPresenterTest {
givenVideoResult()
}
val room = FakeJoinedRoom(
sendVideoResult = sendVideoResult,
liveTimeline = FakeTimeline().apply {
sendVideoLambda = sendVideoResult
},
)
val onDoneListener = lambdaRecorder<Unit> { }
val presenter = createAttachmentsPreviewPresenter(
Expand Down Expand Up @@ -382,7 +394,9 @@ class AttachmentsPreviewPresenterTest {
givenAudioResult()
}
val room = FakeJoinedRoom(
sendAudioResult = sendAudioResult,
liveTimeline = FakeTimeline().apply {
sendAudioLambda = sendAudioResult
},
)
val onDoneListener = lambdaRecorder<Unit> { }
val presenter = createAttachmentsPreviewPresenter(
Expand Down Expand Up @@ -416,10 +430,12 @@ class AttachmentsPreviewPresenterTest {
val failure = MediaPreProcessor.Failure(null)
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
Result.failure(failure)
}
Result.failure(failure)
}
val room = FakeJoinedRoom(
sendFileResult = sendFileResult,
liveTimeline = FakeTimeline().apply {
sendFileLambda = sendFileResult
},
)
val presenter = createAttachmentsPreviewPresenter(room = room, mediaUploadOnSendQueueEnabled = false)
moleculeFlow(RecompositionMode.Immediate) {
Expand All @@ -445,11 +461,13 @@ class AttachmentsPreviewPresenterTest {
val failure = MediaPreProcessor.Failure(null)
val sendFileResult =
lambdaRecorder<File, FileInfo, String?, String?, ProgressCallback?, ReplyParameters?, Result<FakeMediaUploadHandler>> { _, _, _, _, _, _ ->
Result.failure(failure)
}
Result.failure(failure)
}
val onDoneListenerResult = lambdaRecorder<Unit> {}
val room = FakeJoinedRoom(
sendFileResult = sendFileResult,
liveTimeline = FakeTimeline().apply {
sendFileLambda = sendFileResult
},
)
val presenter = createAttachmentsPreviewPresenter(room = room, mediaUploadOnSendQueueEnabled = true, onDoneListener = onDoneListenerResult)
moleculeFlow(RecompositionMode.Immediate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,9 @@ class MessageComposerPresenterTest {
val presenter = createPresenter(
coroutineScope = this,
room = FakeJoinedRoom(
sendMessageResult = { _, _, _ -> Result.success(Unit) },
liveTimeline = FakeTimeline().apply {
sendMessageLambda = { _, _, _ -> Result.success(Unit) }
},
typingNoticeResult = { Result.success(Unit) }
),
)
Expand Down Expand Up @@ -418,7 +420,9 @@ class MessageComposerPresenterTest {
coroutineScope = this,
isRichTextEditorEnabled = false,
room = FakeJoinedRoom(
sendMessageResult = { _, _, _ -> Result.success(Unit) },
liveTimeline = FakeTimeline().apply {
sendMessageLambda = { _, _, _ -> Result.success(Unit) }
},
typingNoticeResult = { Result.success(Unit) }
),
)
Expand Down Expand Up @@ -1118,16 +1122,16 @@ class MessageComposerPresenterTest {
val editMessageLambda = lambdaRecorder { _: EventOrTransactionId, _: String, _: String?, _: List<IntentionalMention> ->
Result.success(Unit)
}
val sendMessageResult = lambdaRecorder { _: String, _: String?, _: List<IntentionalMention> ->
Result.success(Unit)
}
val timeline = FakeTimeline().apply {
this.replyMessageLambda = replyMessageLambda
this.editMessageLambda = editMessageLambda
}
val sendMessageResult = lambdaRecorder { _: String, _: String?, _: List<IntentionalMention> ->
Result.success(Unit)
sendMessageLambda = sendMessageResult
}
val room = FakeJoinedRoom(
liveTimeline = timeline,
sendMessageResult = sendMessageResult,
typingNoticeResult = { Result.success(Unit) }
)
val presenter = createPresenter(room = room, coroutineScope = this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.test.media.FakeMediaUploadHandler
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.mediaupload.api.MediaSender
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
Expand All @@ -45,6 +46,7 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
Expand All @@ -65,7 +67,9 @@ class VoiceMessageComposerPresenterTest {
Result.success(FakeMediaUploadHandler())
}
private val joinedRoom = FakeJoinedRoom(
sendVoiceMessageResult = sendVoiceMessageResult
liveTimeline = FakeTimeline().apply {
sendVoiceMessageLambda = sendVoiceMessageResult
},
)
private val mediaPreProcessor = FakeMediaPreProcessor().apply { givenAudioResult() }
private val mediaSender = MediaSender(mediaPreProcessor, joinedRoom, InMemorySessionPreferencesStore())
Expand Down Expand Up @@ -295,7 +299,6 @@ class VoiceMessageComposerPresenterTest {
awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop))
awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
assertThat(awaitItem().voiceMessageState).isEqualTo(aPreviewState().toSendingState())

val finalState = awaitItem()
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
sendVoiceMessageResult.assertions().isCalledOnce()
Expand All @@ -317,7 +320,7 @@ class VoiceMessageComposerPresenterTest {
awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop))
awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
skipItems(1) // Sending state

advanceUntilIdle()
// Now reply with a voice message
messageComposerContext.composerMode = aReplyMode()
awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start))
Expand Down Expand Up @@ -653,7 +656,7 @@ class VoiceMessageComposerPresenterTest {
permissionsPresenter: PermissionsPresenter = createFakePermissionsPresenter(),
): VoiceMessageComposerPresenter {
return VoiceMessageComposerPresenter(
this,
backgroundScope,
voiceRecorder,
analyticsService,
mediaSender,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
private val analyticsService: AnalyticsService,
) : EndPollAction {
override suspend fun execute(pollStartId: EventId): Result<Unit> {
return room.endPoll(
return room.liveTimeline.endPoll(

Check warning on line 25 in features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/actions/DefaultEndPollAction.kt

View check run for this annotation

Codecov / codecov/patch

features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/actions/DefaultEndPollAction.kt#L25

Added line #L25 was not covered by tests
pollStartId = pollStartId,
text = "The poll with event id: $pollStartId has ended."
).onSuccess {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
private val analyticsService: AnalyticsService,
) : SendPollResponseAction {
override suspend fun execute(pollStartId: EventId, answerId: String): Result<Unit> {
return room.sendPollResponse(
return room.liveTimeline.sendPollResponse(

Check warning on line 25 in features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/actions/DefaultSendPollResponseAction.kt

View check run for this annotation

Codecov / codecov/patch

features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/actions/DefaultSendPollResponseAction.kt#L25

Added line #L25 was not covered by tests
pollStartId = pollStartId,
answers = listOf(answerId),
).onSuccess {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class PollRepository @Inject constructor(
pollKind: PollKind,
maxSelections: Int,
): Result<Unit> = when (existingPollId) {
null -> room.createPoll(
null -> room.liveTimeline.createPoll(
question = question,
answers = answers,
maxSelections = maxSelections,
Expand Down
Loading
Loading