Timeline merging: branch virtual room (still some issues to deal with)

This commit is contained in:
ganfra 2021-06-11 19:27:07 +02:00
parent 6d9c49462a
commit b7dd7ef3e0
5 changed files with 34 additions and 14 deletions

View file

@ -27,12 +27,14 @@ import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
class CallUserMapper(private val session: Session, private val protocolsChecker: CallProtocolsChecker) { class CallUserMapper(private val session: Session, private val protocolsChecker: CallProtocolsChecker) {
fun nativeRoomForVirtualRoom(roomId: String): String? { fun nativeRoomForVirtualRoom(roomId: String): String? {
if(!protocolsChecker.supportVirtualRooms) return null
val virtualRoom = session.getRoom(roomId) ?: return null val virtualRoom = session.getRoom(roomId) ?: return null
val virtualRoomEvent = virtualRoom.getAccountDataEvent(RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM) val virtualRoomEvent = virtualRoom.getAccountDataEvent(RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM)
return virtualRoomEvent?.content?.toModel<RoomVirtualContent>()?.nativeRoomId return virtualRoomEvent?.content?.toModel<RoomVirtualContent>()?.nativeRoomId
} }
fun virtualRoomForNativeRoom(roomId: String): String? { fun virtualRoomForNativeRoom(roomId: String): String? {
if(!protocolsChecker.supportVirtualRooms) return null
val virtualRoomEvents = session.accountDataService().getRoomAccountDataEvents(setOf(RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM)) val virtualRoomEvents = session.accountDataService().getRoomAccountDataEvents(setOf(RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM))
return virtualRoomEvents.firstOrNull { return virtualRoomEvents.firstOrNull {
val virtualRoomContent = it.content.toModel<RoomVirtualContent>() val virtualRoomContent = it.content.toModel<RoomVirtualContent>()

View file

@ -1614,8 +1614,7 @@ class RoomDetailFragment @Inject constructor(
override fun onEventLongClicked(informationData: MessageInformationData, messageContent: Any?, view: View): Boolean { override fun onEventLongClicked(informationData: MessageInformationData, messageContent: Any?, view: View): Boolean {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
val roomId = roomDetailArgs.roomId val roomId = roomDetailViewModel.timeline.getTimelineEventWithId(informationData.eventId)?.roomId ?: return false
this.view?.hideKeyboard() this.view?.hideKeyboard()
MessageActionsBottomSheet MessageActionsBottomSheet

View file

@ -16,6 +16,7 @@
package im.vector.app.features.home.room.detail.timeline.factory package im.vector.app.features.home.room.detail.timeline.factory
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.features.call.vectorCallService
import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
@ -26,6 +27,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.RoomSummariesHold
import im.vector.app.features.home.room.detail.timeline.item.CallTileTimelineItem import im.vector.app.features.home.room.detail.timeline.item.CallTileTimelineItem
import im.vector.app.features.home.room.detail.timeline.item.CallTileTimelineItem_ import im.vector.app.features.home.room.detail.timeline.item.CallTileTimelineItem_
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent
@ -38,6 +40,7 @@ import org.matrix.android.sdk.api.util.toMatrixItem
import javax.inject.Inject import javax.inject.Inject
class CallItemFactory @Inject constructor( class CallItemFactory @Inject constructor(
private val session: Session,
private val messageColorProvider: MessageColorProvider, private val messageColorProvider: MessageColorProvider,
private val messageInformationDataFactory: MessageInformationDataFactory, private val messageInformationDataFactory: MessageInformationDataFactory,
private val messageItemAttributesFactory: MessageItemAttributesFactory, private val messageItemAttributesFactory: MessageItemAttributesFactory,
@ -132,7 +135,8 @@ class CallItemFactory @Inject constructor(
isStillActive: Boolean, isStillActive: Boolean,
callback: TimelineEventController.Callback? callback: TimelineEventController.Callback?
): CallTileTimelineItem? { ): CallTileTimelineItem? {
val userOfInterest = roomSummariesHolder.get(roomId)?.toMatrixItem() ?: return null val correctedRoomId = session.vectorCallService.userMapper.nativeRoomForVirtualRoom(roomId) ?:roomId
val userOfInterest = roomSummariesHolder.get(correctedRoomId)?.toMatrixItem() ?: return null
val attributes = messageItemAttributesFactory.create(null, informationData, callback).let { val attributes = messageItemAttributesFactory.create(null, informationData, callback).let {
CallTileTimelineItem.Attributes( CallTileTimelineItem.Attributes(
callId = callId, callId = callId,

View file

@ -35,21 +35,21 @@ private val secondaryTimelineAllowedTypes = listOf(
class TimelineFactory @Inject constructor(private val session: Session, private val timelineSettingsFactory: TimelineSettingsFactory) { class TimelineFactory @Inject constructor(private val session: Session, private val timelineSettingsFactory: TimelineSettingsFactory) {
fun createTimeline(coroutineScope: CoroutineScope, room: Room, eventId: String?): Timeline { fun createTimeline(coroutineScope: CoroutineScope, mainRoom: Room, eventId: String?): Timeline {
val settings = timelineSettingsFactory.create() val settings = timelineSettingsFactory.create()
if (!session.vectorCallService.protocolChecker.supportVirtualRooms) { if (!session.vectorCallService.protocolChecker.supportVirtualRooms) {
return room.createTimeline(eventId, settings) return mainRoom.createTimeline(eventId, settings)
} }
val virtualRoomId = session.vectorCallService.userMapper.virtualRoomForNativeRoom(room.roomId) val virtualRoomId = session.vectorCallService.userMapper.virtualRoomForNativeRoom(mainRoom.roomId)
return if (virtualRoomId == null) { return if (virtualRoomId == null) {
room.createTimeline(eventId, settings) mainRoom.createTimeline(eventId, settings)
} else { } else {
val virtualRoom = session.getRoom(virtualRoomId)!! val virtualRoom = session.getRoom(virtualRoomId)!!
MergedTimelines( MergedTimelines(
coroutineScope, coroutineScope = coroutineScope,
room.createTimeline(eventId, settings), mainTimeline = mainRoom.createTimeline(eventId, settings),
secondaryTimelineParams = MergedTimelines.SecondaryTimelineParams( secondaryTimelineParams = MergedTimelines.SecondaryTimelineParams(
virtualRoom.createTimeline(null, settings), timeline = virtualRoom.createTimeline(null, settings),
shouldFilterTypes = true, shouldFilterTypes = true,
allowedTypes = secondaryTimelineAllowedTypes allowedTypes = secondaryTimelineAllowedTypes
) )

View file

@ -23,6 +23,7 @@ import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.sync.withPermit
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.room.sender.SenderInfo
import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.Timeline
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
@ -155,15 +156,22 @@ class MergedTimelines(
val mainItr = mainTimelineEvents.toList().listIterator() val mainItr = mainTimelineEvents.toList().listIterator()
val secondaryItr = secondaryTimelineEvents.toList().listIterator() val secondaryItr = secondaryTimelineEvents.toList().listIterator()
var index = 0 var index = 0
var correctedSenderInfo: SenderInfo? = mainTimelineEvents.firstOrNull()?.senderInfo
if (mainTimelineEvents.isEmpty() && mainTimeline.hasMoreToLoad(Timeline.Direction.BACKWARDS)) {
return
}
if (secondaryTimelineEvents.isEmpty() && secondaryTimeline.hasMoreToLoad(Timeline.Direction.BACKWARDS)) {
return
}
while (merged.size < mainTimelineEvents.size + secondaryTimelineEvents.size) { while (merged.size < mainTimelineEvents.size + secondaryTimelineEvents.size) {
if (mainItr.hasNext()) { if (mainItr.hasNext()) {
val nextMain = mainItr.next() val nextMain = mainItr.next()
correctedSenderInfo = nextMain.senderInfo
if (secondaryItr.hasNext()) { if (secondaryItr.hasNext()) {
val nextSecondary = secondaryItr.next() val nextSecondary = secondaryItr.next()
if (nextSecondary.root.originServerTs ?: 0 > nextMain.root.originServerTs ?: 0) { if (nextSecondary.root.originServerTs ?: 0 > nextMain.root.originServerTs ?: 0) {
positionsMapping[nextSecondary.eventId] = index positionsMapping[nextSecondary.eventId] = index
merged.add(nextSecondary) merged.add(nextSecondary.correctBeforeMerging(correctedSenderInfo))
mainItr.previous() mainItr.previous()
} else { } else {
positionsMapping[nextMain.eventId] = index positionsMapping[nextMain.eventId] = index
@ -177,13 +185,13 @@ class MergedTimelines(
} else if (secondaryItr.hasNext()) { } else if (secondaryItr.hasNext()) {
val nextSecondary = secondaryItr.next() val nextSecondary = secondaryItr.next()
positionsMapping[nextSecondary.eventId] = index positionsMapping[nextSecondary.eventId] = index
merged.add(nextSecondary) merged.add(nextSecondary.correctBeforeMerging(correctedSenderInfo))
} }
index++ index++
} }
mergedEvents.apply { mergedEvents.apply {
clear() clear()
addAll(mergedEvents) addAll(merged)
} }
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
listenersMapping.keys.forEach { listener -> listenersMapping.keys.forEach { listener ->
@ -191,4 +199,11 @@ class MergedTimelines(
} }
} }
} }
private fun TimelineEvent.correctBeforeMerging(correctedSenderInfo: SenderInfo?): TimelineEvent {
return copy(
senderInfo = correctedSenderInfo ?: senderInfo,
readReceipts = emptyList()
)
}
} }