lifting directory local echo merging to its own class
This commit is contained in:
parent
9048f9fb0c
commit
a21f3a1663
|
@ -0,0 +1,53 @@
|
|||
package app.dapk.st.engine
|
||||
|
||||
import app.dapk.st.matrix.common.RoomId
|
||||
import app.dapk.st.matrix.common.RoomMember
|
||||
import app.dapk.st.matrix.common.UserId
|
||||
import app.dapk.st.matrix.common.asString
|
||||
import app.dapk.st.matrix.message.MessageService
|
||||
import app.dapk.st.matrix.room.RoomService
|
||||
|
||||
internal typealias DirectoryMergeWithLocalEchosUseCase = suspend (OverviewState, UserId, Map<RoomId, List<MessageService.LocalEcho>>) -> OverviewState
|
||||
|
||||
internal class DirectoryMergeWithLocalEchosUseCaseImpl(
|
||||
private val roomService: RoomService,
|
||||
) : DirectoryMergeWithLocalEchosUseCase {
|
||||
|
||||
override suspend fun invoke(overview: OverviewState, selfId: UserId, echos: Map<RoomId, List<MessageService.LocalEcho>>): OverviewState {
|
||||
return when {
|
||||
echos.isEmpty() -> overview
|
||||
else -> overview.map {
|
||||
when (val roomEchos = echos[it.roomId]) {
|
||||
null -> it
|
||||
else -> it.mergeWithLocalEchos(
|
||||
member = roomService.findMember(it.roomId, selfId) ?: RoomMember(
|
||||
selfId,
|
||||
null,
|
||||
avatarUrl = null,
|
||||
),
|
||||
echos = roomEchos,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun RoomOverview.mergeWithLocalEchos(member: RoomMember, echos: List<MessageService.LocalEcho>): RoomOverview {
|
||||
val latestEcho = echos.maxByOrNull { it.timestampUtc }
|
||||
return if (latestEcho != null && latestEcho.timestampUtc > (this.lastMessage?.utcTimestamp ?: 0)) {
|
||||
this.copy(
|
||||
lastMessage = RoomOverview.LastMessage(
|
||||
content = when (val message = latestEcho.message) {
|
||||
is MessageService.Message.TextMessage -> message.content.body.asString()
|
||||
is MessageService.Message.ImageMessage -> "\uD83D\uDCF7"
|
||||
},
|
||||
utcTimestamp = latestEcho.timestampUtc,
|
||||
author = member,
|
||||
)
|
||||
)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package app.dapk.st.engine
|
||||
|
||||
import app.dapk.st.core.extensions.combine
|
||||
import app.dapk.st.matrix.common.*
|
||||
import app.dapk.st.matrix.common.CredentialsStore
|
||||
import app.dapk.st.matrix.message.MessageService
|
||||
import app.dapk.st.matrix.room.RoomService
|
||||
import app.dapk.st.matrix.sync.RoomStore
|
||||
|
@ -15,9 +15,9 @@ import kotlinx.coroutines.flow.map
|
|||
internal class DirectoryUseCase(
|
||||
private val syncService: SyncService,
|
||||
private val messageService: MessageService,
|
||||
private val roomService: RoomService,
|
||||
private val credentialsStore: CredentialsStore,
|
||||
private val roomStore: RoomStore,
|
||||
private val mergeLocalEchosUseCase: DirectoryMergeWithLocalEchosUseCaseImpl
|
||||
) {
|
||||
|
||||
fun state(): Flow<DirectoryState> {
|
||||
|
@ -30,7 +30,7 @@ internal class DirectoryUseCase(
|
|||
syncService.events(),
|
||||
roomStore.observeMuted(),
|
||||
) { _, overviewState, localEchos, unread, events, muted ->
|
||||
overviewState.mergeWithLocalEchos(localEchos, userId).map { roomOverview ->
|
||||
mergeLocalEchosUseCase.invoke(overviewState, userId, localEchos).map { roomOverview ->
|
||||
DirectoryItem(
|
||||
overview = roomOverview,
|
||||
unreadCount = UnreadCount(unread[roomOverview.roomId] ?: 0),
|
||||
|
@ -41,42 +41,4 @@ internal class DirectoryUseCase(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun OverviewState.mergeWithLocalEchos(localEchos: Map<RoomId, List<MessageService.LocalEcho>>, userId: UserId): OverviewState {
|
||||
return when {
|
||||
localEchos.isEmpty() -> this
|
||||
else -> this.map {
|
||||
when (val roomEchos = localEchos[it.roomId]) {
|
||||
null -> it
|
||||
else -> it.mergeWithLocalEchos(
|
||||
member = roomService.findMember(it.roomId, userId) ?: RoomMember(
|
||||
userId,
|
||||
null,
|
||||
avatarUrl = null,
|
||||
),
|
||||
echos = roomEchos,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun RoomOverview.mergeWithLocalEchos(member: RoomMember, echos: List<MessageService.LocalEcho>): RoomOverview {
|
||||
val latestEcho = echos.maxByOrNull { it.timestampUtc }
|
||||
return if (latestEcho != null && latestEcho.timestampUtc > (this.lastMessage?.utcTimestamp ?: 0)) {
|
||||
this.copy(
|
||||
lastMessage = RoomOverview.LastMessage(
|
||||
content = when (val message = latestEcho.message) {
|
||||
is MessageService.Message.TextMessage -> message.content.body.asString()
|
||||
is MessageService.Message.ImageMessage -> "\uD83D\uDCF7"
|
||||
},
|
||||
utcTimestamp = latestEcho.timestampUtc,
|
||||
author = member,
|
||||
)
|
||||
)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -173,14 +173,14 @@ class MatrixEngine internal constructor(
|
|||
DirectoryUseCase(
|
||||
matrix.syncService(),
|
||||
matrix.messageService(),
|
||||
matrix.roomService(),
|
||||
credentialsStore,
|
||||
roomStore
|
||||
roomStore,
|
||||
DirectoryMergeWithLocalEchosUseCaseImpl(matrix.roomService()),
|
||||
)
|
||||
}
|
||||
val timelineUseCase = unsafeLazy {
|
||||
val matrix = lazyMatrix.value
|
||||
val mergeWithLocalEchosUseCase = MergeWithLocalEchosUseCaseImpl(LocalEchoMapper(MetaMapper()))
|
||||
val mergeWithLocalEchosUseCase = TimelineMergeWithLocalEchosUseCaseImpl(LocalEchoMapper(MetaMapper()))
|
||||
val timeline = TimelineUseCaseImpl(matrix.syncService(), matrix.messageService(), matrix.roomService(), mergeWithLocalEchosUseCase)
|
||||
ReadMarkingTimeline(roomStore, credentialsStore, timeline, matrix.roomService())
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ import app.dapk.st.matrix.common.EventId
|
|||
import app.dapk.st.matrix.common.RoomMember
|
||||
import app.dapk.st.matrix.message.MessageService
|
||||
|
||||
internal typealias MergeWithLocalEchosUseCase = (RoomState, RoomMember, List<MessageService.LocalEcho>) -> RoomState
|
||||
internal typealias TimelineMergeWithLocalEchosUseCase = (RoomState, RoomMember, List<MessageService.LocalEcho>) -> RoomState
|
||||
|
||||
internal class MergeWithLocalEchosUseCaseImpl(
|
||||
internal class TimelineMergeWithLocalEchosUseCaseImpl(
|
||||
private val localEventMapper: LocalEchoMapper,
|
||||
) : MergeWithLocalEchosUseCase {
|
||||
) : TimelineMergeWithLocalEchosUseCase {
|
||||
|
||||
override fun invoke(roomState: RoomState, member: RoomMember, echos: List<MessageService.LocalEcho>): RoomState {
|
||||
val echosByEventId = echos.associateBy { it.eventId }
|
||||
|
|
|
@ -16,7 +16,7 @@ internal class TimelineUseCaseImpl(
|
|||
private val syncService: SyncService,
|
||||
private val messageService: MessageService,
|
||||
private val roomService: RoomService,
|
||||
private val mergeWithLocalEchosUseCase: MergeWithLocalEchosUseCase
|
||||
private val timelineMergeWithLocalEchosUseCase: TimelineMergeWithLocalEchosUseCase,
|
||||
) : ObserveTimelineUseCase {
|
||||
|
||||
override fun invoke(roomId: RoomId, userId: UserId): Flow<MessengerPageState> {
|
||||
|
@ -30,7 +30,7 @@ internal class TimelineUseCaseImpl(
|
|||
roomState = when {
|
||||
localEchos.isEmpty() -> roomState
|
||||
else -> {
|
||||
mergeWithLocalEchosUseCase.invoke(
|
||||
timelineMergeWithLocalEchosUseCase.invoke(
|
||||
roomState,
|
||||
roomService.findMember(roomId, userId) ?: userId.toFallbackMember(),
|
||||
localEchos,
|
||||
|
|
|
@ -17,7 +17,7 @@ private val ANOTHER_ROOM_MESSAGE_EVENT = A_ROOM_MESSAGE_EVENT.copy(eventId = anE
|
|||
class MergeWithLocalEchosUseCaseTest {
|
||||
|
||||
private val fakeLocalEchoMapper = fake.FakeLocalEventMapper()
|
||||
private val mergeWithLocalEchosUseCase = MergeWithLocalEchosUseCaseImpl(fakeLocalEchoMapper.instance)
|
||||
private val mergeWithLocalEchosUseCase = TimelineMergeWithLocalEchosUseCaseImpl(fakeLocalEchoMapper.instance)
|
||||
|
||||
@Test
|
||||
fun `given no local echos, when merging text message, then returns original state`() {
|
||||
|
|
|
@ -113,7 +113,7 @@ suspend fun <T> Flow<T>.test(scope: CoroutineScope) = FlowTestObserver(scope, th
|
|||
this.collect()
|
||||
}
|
||||
|
||||
class FakeMergeWithLocalEchosUseCase : MergeWithLocalEchosUseCase by mockk() {
|
||||
class FakeMergeWithLocalEchosUseCase : TimelineMergeWithLocalEchosUseCase by mockk() {
|
||||
fun givenMerging(roomState: RoomState, roomMember: RoomMember, echos: List<MessageService.LocalEcho>) = every {
|
||||
this@FakeMergeWithLocalEchosUseCase.invoke(roomState.engine(), roomMember, echos)
|
||||
}.delegateReturn()
|
||||
|
|
Loading…
Reference in New Issue