mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-07 15:48:38 +01:00
Timeline event: handle displayName/avatar [WIP]
This commit is contained in:
parent
c503445092
commit
78951b9155
@ -18,17 +18,28 @@ package im.vector.matrix.android.internal.database.helper
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.api.session.room.send.SendState
|
||||
import im.vector.matrix.android.internal.database.mapper.ContentMapper
|
||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.mapper.toEntity
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields
|
||||
import im.vector.matrix.android.internal.database.query.find
|
||||
import im.vector.matrix.android.internal.database.query.next
|
||||
import im.vector.matrix.android.internal.database.query.prev
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.Sort
|
||||
|
||||
// By default if a chunk is empty we consider it unlinked
|
||||
@ -64,11 +75,11 @@ internal fun ChunkEntity.merge(roomId: String,
|
||||
this.isLastBackward = chunkToMerge.isLastBackward
|
||||
eventsToMerge = chunkToMerge.timelineEvents.sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.DESCENDING)
|
||||
}
|
||||
eventsToMerge.forEach {
|
||||
it.root?.let { root ->
|
||||
add(roomId, root.asDomain(), direction, isUnlinked = isUnlinked)
|
||||
}
|
||||
val events = eventsToMerge.mapNotNull { it.root?.asDomain() }
|
||||
events.forEach { event ->
|
||||
add(roomId, event, direction, isUnlinked = isUnlinked)
|
||||
}
|
||||
updateSenderDataFor(roomId, isUnlinked, events)
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.addAll(roomId: String,
|
||||
@ -81,13 +92,35 @@ internal fun ChunkEntity.addAll(roomId: String,
|
||||
events.forEach { event ->
|
||||
add(roomId, event, direction, stateIndexOffset, isUnlinked)
|
||||
}
|
||||
updateSenderDataFor(roomId, isUnlinked, events)
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.add(roomId: String,
|
||||
event: Event,
|
||||
direction: PaginationDirection,
|
||||
stateIndexOffset: Int = 0,
|
||||
isUnlinked: Boolean = false) {
|
||||
private fun ChunkEntity.updateSenderDataFor(roomId: String, isUnlinked: Boolean, events: List<Event>) {
|
||||
for (event in events) {
|
||||
val eventId = event.eventId ?: continue
|
||||
val timelineEventEntity = timelineEvents.find(eventId) ?: continue
|
||||
val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst() ?: continue
|
||||
val stateIndex = timelineEventEntity.root?.stateIndex ?: continue
|
||||
val senderId = timelineEventEntity.root?.sender ?: continue
|
||||
|
||||
val senderRoomMemberContent = when {
|
||||
stateIndex <= 0 -> timelineEvents.build(senderId, isUnlinked).next(from = stateIndex)?.root?.prevContent
|
||||
else -> timelineEvents.build(senderId, isUnlinked).prev(since = stateIndex)?.root?.content
|
||||
}
|
||||
val fallbackContent = senderRoomMemberContent
|
||||
?: roomEntity.untimelinedStateEvents.build(senderId).prev(since = stateIndex)?.content
|
||||
val senderRoomMember: RoomMember? = ContentMapper.map(fallbackContent).toModel()
|
||||
timelineEventEntity.senderAvatar = senderRoomMember?.avatarUrl
|
||||
timelineEventEntity.senderName = senderRoomMember?.displayName
|
||||
timelineEventEntity.isUniqueDisplayName = RoomMembers(realm, roomId).isUniqueDisplayName(senderRoomMember?.displayName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ChunkEntity.add(roomId: String,
|
||||
event: Event,
|
||||
direction: PaginationDirection,
|
||||
stateIndexOffset: Int = 0,
|
||||
isUnlinked: Boolean = false) {
|
||||
|
||||
assertIsManaged()
|
||||
if (event.eventId != null && timelineEvents.find(event.eventId) != null) {
|
||||
@ -128,6 +161,19 @@ internal fun ChunkEntity.add(roomId: String,
|
||||
timelineEvents.add(position, eventEntity)
|
||||
}
|
||||
|
||||
private fun RealmList<TimelineEventEntity>.build(sender: String, isUnlinked: Boolean): RealmQuery<TimelineEventEntity> {
|
||||
return where()
|
||||
.equalTo(TimelineEventEntityFields.ROOT.STATE_KEY, sender)
|
||||
.equalTo(TimelineEventEntityFields.ROOT.TYPE, EventType.STATE_ROOM_MEMBER)
|
||||
.equalTo(TimelineEventEntityFields.ROOT.IS_UNLINKED, isUnlinked)
|
||||
}
|
||||
|
||||
private fun RealmList<EventEntity>.build(sender: String): RealmQuery<EventEntity> {
|
||||
return where()
|
||||
.equalTo(EventEntityFields.STATE_KEY, sender)
|
||||
.equalTo(EventEntityFields.TYPE, EventType.STATE_ROOM_MEMBER)
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.lastDisplayIndex(direction: PaginationDirection, defaultValue: Int = 0): Int {
|
||||
return when (direction) {
|
||||
PaginationDirection.FORWARDS -> forwardsDisplayIndex
|
||||
|
@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||
import im.vector.matrix.android.internal.database.query.fastContains
|
||||
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
||||
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||
|
||||
|
||||
internal fun RoomEntity.deleteOnCascade(chunkEntity: ChunkEntity) {
|
||||
@ -58,13 +59,19 @@ internal fun RoomEntity.addStateEvents(stateEvents: List<Event>,
|
||||
|
||||
internal fun RoomEntity.addSendingEvent(event: Event) {
|
||||
assertIsManaged()
|
||||
val senderId = event.senderId ?: return
|
||||
val eventEntity = event.toEntity(roomId).apply {
|
||||
this.sendState = SendState.UNSENT
|
||||
}
|
||||
val roomMembers = RoomMembers(realm, roomId)
|
||||
val myUser = roomMembers.get(senderId)
|
||||
val timelineEventEntity = TimelineEventEntity().also {
|
||||
it.root = eventEntity
|
||||
it.eventId = event.eventId ?: ""
|
||||
it.roomId = roomId
|
||||
it.senderName = myUser?.displayName
|
||||
it.senderAvatar = myUser?.avatarUrl
|
||||
it.isUniqueDisplayName = roomMembers.isUniqueDisplayName(myUser?.displayName)
|
||||
}
|
||||
sendingTimelineEvents.add(0, timelineEventEntity)
|
||||
}
|
||||
|
@ -16,13 +16,9 @@
|
||||
|
||||
package im.vector.matrix.android.internal.database.query
|
||||
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity.LinkFilterMode.*
|
||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmQuery
|
||||
|
@ -19,7 +19,6 @@ package im.vector.matrix.android.internal.database.query
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity.LinkFilterMode.*
|
||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields
|
||||
@ -38,9 +37,9 @@ internal fun TimelineEventEntity.Companion.where(realm: Realm, eventIds: List<St
|
||||
}
|
||||
|
||||
internal fun TimelineEventEntity.Companion.where(realm: Realm,
|
||||
roomId: String? = null,
|
||||
type: String? = null,
|
||||
linkFilterMode: EventEntity.LinkFilterMode = LINKED_ONLY): RealmQuery<TimelineEventEntity> {
|
||||
roomId: String? = null,
|
||||
type: String? = null,
|
||||
linkFilterMode: EventEntity.LinkFilterMode = LINKED_ONLY): RealmQuery<TimelineEventEntity> {
|
||||
val query = realm.where<TimelineEventEntity>()
|
||||
if (roomId != null) {
|
||||
query.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
|
||||
@ -78,6 +77,33 @@ internal fun TimelineEventEntity.Companion.latestEvent(realm: Realm,
|
||||
?.findFirst()
|
||||
}
|
||||
|
||||
internal fun RealmQuery<TimelineEventEntity>.next(from: Int? = null, strict: Boolean = true): TimelineEventEntity? {
|
||||
if (from != null) {
|
||||
if (strict) {
|
||||
this.greaterThan(TimelineEventEntityFields.ROOT.STATE_INDEX, from)
|
||||
} else {
|
||||
this.greaterThanOrEqualTo(TimelineEventEntityFields.ROOT.STATE_INDEX, from)
|
||||
}
|
||||
}
|
||||
return this
|
||||
.sort(TimelineEventEntityFields.ROOT.STATE_INDEX, Sort.ASCENDING)
|
||||
.findFirst()
|
||||
}
|
||||
|
||||
internal fun RealmQuery<TimelineEventEntity>.prev(since: Int? = null, strict: Boolean = false): TimelineEventEntity? {
|
||||
if (since != null) {
|
||||
if (strict) {
|
||||
this.lessThan(TimelineEventEntityFields.ROOT.STATE_INDEX, since)
|
||||
} else {
|
||||
this.lessThanOrEqualTo(TimelineEventEntityFields.ROOT.STATE_INDEX, since)
|
||||
}
|
||||
}
|
||||
return this
|
||||
.sort(TimelineEventEntityFields.ROOT.STATE_INDEX, Sort.DESCENDING)
|
||||
.findFirst()
|
||||
}
|
||||
|
||||
|
||||
internal fun RealmList<TimelineEventEntity>.find(eventId: String): TimelineEventEntity? {
|
||||
return this.where().equalTo(TimelineEventEntityFields.ROOT.EVENT_ID, eventId).findFirst()
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import im.vector.matrix.android.api.session.room.Room
|
||||
import im.vector.matrix.android.internal.database.mapper.RoomSummaryMapper
|
||||
import im.vector.matrix.android.internal.session.room.membership.DefaultMembershipService
|
||||
import im.vector.matrix.android.internal.session.room.membership.LoadRoomMembersTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.SenderRoomMemberExtractor
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.leaving.LeaveRoomTask
|
||||
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.session.room.membership
|
||||
|
||||
internal object SenderRoomMemberExtractor {
|
||||
|
||||
/*
|
||||
fun extractFrom(event: Event, realm: Realm): RoomMember? {
|
||||
val roomId = event.roomId
|
||||
val sender = event.senderId ?: return null
|
||||
// If the event is unlinked we want to fetch unlinked state events
|
||||
val unlinked = event.isUnlinked
|
||||
val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst() ?: return null
|
||||
|
||||
// When not synced, we should grab the live RoomMember event
|
||||
return if (event.sendState != SendState.SYNCED) {
|
||||
RoomMembers(realm, roomId).get(sender)
|
||||
} else {
|
||||
val chunkEntity = ChunkEntity.findIncludingEvent(realm, event.eventId)
|
||||
val content = when {
|
||||
chunkEntity == null -> null
|
||||
event.stateIndex <= 0 -> baseQuery(chunkEntity.events, sender, unlinked).next(from = event.stateIndex)?.prevContent
|
||||
else -> baseQuery(chunkEntity.events, sender, unlinked).prev(since = event.stateIndex)?.content
|
||||
}
|
||||
val fallbackContent = content
|
||||
?: baseQuery(roomEntity.untimelinedStateEvents, sender, unlinked).prev(since = event.stateIndex)?.content
|
||||
ContentMapper.map(fallbackContent).toModel()
|
||||
}
|
||||
}
|
||||
|
||||
private fun baseQuery(list: RealmList<EventEntity>,
|
||||
sender: String,
|
||||
isUnlinked: Boolean): RealmQuery<EventEntity> {
|
||||
return list
|
||||
.where()
|
||||
.equalTo(EventEntityFields.STATE_KEY, sender)
|
||||
.equalTo(EventEntityFields.TYPE, EventType.STATE_ROOM_MEMBER)
|
||||
.equalTo(EventEntityFields.IS_UNLINKED, isUnlinked)
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user