forked from GitHub-Mirror/riotX-android
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.Event
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
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.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.asDomain
|
||||||
import im.vector.matrix.android.internal.database.mapper.toEntity
|
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.ChunkEntity
|
||||||
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
|
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.TimelineEventEntity
|
||||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields
|
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.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.database.query.where
|
||||||
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
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 im.vector.matrix.android.internal.session.room.timeline.PaginationDirection
|
||||||
|
import io.realm.RealmList
|
||||||
|
import io.realm.RealmQuery
|
||||||
import io.realm.Sort
|
import io.realm.Sort
|
||||||
|
|
||||||
// By default if a chunk is empty we consider it unlinked
|
// 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
|
this.isLastBackward = chunkToMerge.isLastBackward
|
||||||
eventsToMerge = chunkToMerge.timelineEvents.sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.DESCENDING)
|
eventsToMerge = chunkToMerge.timelineEvents.sort(TimelineEventEntityFields.ROOT.DISPLAY_INDEX, Sort.DESCENDING)
|
||||||
}
|
}
|
||||||
eventsToMerge.forEach {
|
val events = eventsToMerge.mapNotNull { it.root?.asDomain() }
|
||||||
it.root?.let { root ->
|
events.forEach { event ->
|
||||||
add(roomId, root.asDomain(), direction, isUnlinked = isUnlinked)
|
add(roomId, event, direction, isUnlinked = isUnlinked)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
updateSenderDataFor(roomId, isUnlinked, events)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ChunkEntity.addAll(roomId: String,
|
internal fun ChunkEntity.addAll(roomId: String,
|
||||||
@ -81,13 +92,35 @@ internal fun ChunkEntity.addAll(roomId: String,
|
|||||||
events.forEach { event ->
|
events.forEach { event ->
|
||||||
add(roomId, event, direction, stateIndexOffset, isUnlinked)
|
add(roomId, event, direction, stateIndexOffset, isUnlinked)
|
||||||
}
|
}
|
||||||
|
updateSenderDataFor(roomId, isUnlinked, events)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ChunkEntity.add(roomId: String,
|
private fun ChunkEntity.updateSenderDataFor(roomId: String, isUnlinked: Boolean, events: List<Event>) {
|
||||||
event: Event,
|
for (event in events) {
|
||||||
direction: PaginationDirection,
|
val eventId = event.eventId ?: continue
|
||||||
stateIndexOffset: Int = 0,
|
val timelineEventEntity = timelineEvents.find(eventId) ?: continue
|
||||||
isUnlinked: Boolean = false) {
|
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()
|
assertIsManaged()
|
||||||
if (event.eventId != null && timelineEvents.find(event.eventId) != null) {
|
if (event.eventId != null && timelineEvents.find(event.eventId) != null) {
|
||||||
@ -128,6 +161,19 @@ internal fun ChunkEntity.add(roomId: String,
|
|||||||
timelineEvents.add(position, eventEntity)
|
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 {
|
internal fun ChunkEntity.lastDisplayIndex(direction: PaginationDirection, defaultValue: Int = 0): Int {
|
||||||
return when (direction) {
|
return when (direction) {
|
||||||
PaginationDirection.FORWARDS -> forwardsDisplayIndex
|
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.model.TimelineEventEntity
|
||||||
import im.vector.matrix.android.internal.database.query.fastContains
|
import im.vector.matrix.android.internal.database.query.fastContains
|
||||||
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
import im.vector.matrix.android.internal.extensions.assertIsManaged
|
||||||
|
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
|
||||||
|
|
||||||
|
|
||||||
internal fun RoomEntity.deleteOnCascade(chunkEntity: ChunkEntity) {
|
internal fun RoomEntity.deleteOnCascade(chunkEntity: ChunkEntity) {
|
||||||
@ -58,13 +59,19 @@ internal fun RoomEntity.addStateEvents(stateEvents: List<Event>,
|
|||||||
|
|
||||||
internal fun RoomEntity.addSendingEvent(event: Event) {
|
internal fun RoomEntity.addSendingEvent(event: Event) {
|
||||||
assertIsManaged()
|
assertIsManaged()
|
||||||
|
val senderId = event.senderId ?: return
|
||||||
val eventEntity = event.toEntity(roomId).apply {
|
val eventEntity = event.toEntity(roomId).apply {
|
||||||
this.sendState = SendState.UNSENT
|
this.sendState = SendState.UNSENT
|
||||||
}
|
}
|
||||||
|
val roomMembers = RoomMembers(realm, roomId)
|
||||||
|
val myUser = roomMembers.get(senderId)
|
||||||
val timelineEventEntity = TimelineEventEntity().also {
|
val timelineEventEntity = TimelineEventEntity().also {
|
||||||
it.root = eventEntity
|
it.root = eventEntity
|
||||||
it.eventId = event.eventId ?: ""
|
it.eventId = event.eventId ?: ""
|
||||||
it.roomId = roomId
|
it.roomId = roomId
|
||||||
|
it.senderName = myUser?.displayName
|
||||||
|
it.senderAvatar = myUser?.avatarUrl
|
||||||
|
it.isUniqueDisplayName = roomMembers.isUniqueDisplayName(myUser?.displayName)
|
||||||
}
|
}
|
||||||
sendingTimelineEvents.add(0, timelineEventEntity)
|
sendingTimelineEvents.add(0, timelineEventEntity)
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,9 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.internal.database.query
|
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
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntity.LinkFilterMode.*
|
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.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.Realm
|
||||||
import io.realm.RealmList
|
import io.realm.RealmList
|
||||||
import io.realm.RealmQuery
|
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.ChunkEntity
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
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.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.RoomEntity
|
||||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
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.model.TimelineEventEntityFields
|
||||||
@ -38,9 +37,9 @@ internal fun TimelineEventEntity.Companion.where(realm: Realm, eventIds: List<St
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun TimelineEventEntity.Companion.where(realm: Realm,
|
internal fun TimelineEventEntity.Companion.where(realm: Realm,
|
||||||
roomId: String? = null,
|
roomId: String? = null,
|
||||||
type: String? = null,
|
type: String? = null,
|
||||||
linkFilterMode: EventEntity.LinkFilterMode = LINKED_ONLY): RealmQuery<TimelineEventEntity> {
|
linkFilterMode: EventEntity.LinkFilterMode = LINKED_ONLY): RealmQuery<TimelineEventEntity> {
|
||||||
val query = realm.where<TimelineEventEntity>()
|
val query = realm.where<TimelineEventEntity>()
|
||||||
if (roomId != null) {
|
if (roomId != null) {
|
||||||
query.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
|
query.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
|
||||||
@ -78,6 +77,33 @@ internal fun TimelineEventEntity.Companion.latestEvent(realm: Realm,
|
|||||||
?.findFirst()
|
?.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? {
|
internal fun RealmList<TimelineEventEntity>.find(eventId: String): TimelineEventEntity? {
|
||||||
return this.where().equalTo(TimelineEventEntityFields.ROOT.EVENT_ID, eventId).findFirst()
|
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.database.mapper.RoomSummaryMapper
|
||||||
import im.vector.matrix.android.internal.session.room.membership.DefaultMembershipService
|
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.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.InviteTask
|
||||||
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
||||||
import im.vector.matrix.android.internal.session.room.membership.leaving.LeaveRoomTask
|
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…
Reference in New Issue
Block a user