forked from GitHub-Mirror/riotX-android
85 lines
3.9 KiB
Kotlin
85 lines
3.9 KiB
Kotlin
package im.vector.matrix.android.internal.session.room
|
|
|
|
import im.vector.matrix.android.api.auth.data.Credentials
|
|
import im.vector.matrix.android.api.session.events.model.*
|
|
import im.vector.matrix.android.api.session.room.model.annotation.ReactionContent
|
|
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
|
|
import im.vector.matrix.android.internal.database.model.ReactionAggregatedSummaryEntity
|
|
import im.vector.matrix.android.internal.database.query.create
|
|
import im.vector.matrix.android.internal.database.query.where
|
|
import io.realm.Realm
|
|
import timber.log.Timber
|
|
|
|
|
|
internal class EventRelationsAggregationUpdater(private val credentials: Credentials) {
|
|
|
|
fun update(realm: Realm, roomId: String, events: List<Event>?) {
|
|
events?.forEach { event ->
|
|
when (event.type) {
|
|
EventType.REACTION -> {
|
|
//we got a reaction!!
|
|
Timber.v("###REACTION in room $roomId for event ${event.eventId}")
|
|
handleReaction(event, roomId, realm)
|
|
}
|
|
EventType.MESSAGE -> {
|
|
event.unsignedData?.relations?.annotations?.let {
|
|
Timber.v("###REACTION Agreggation in room $roomId for event ${event.eventId}")
|
|
handleInitialAggregatedRelations(event, roomId, it, realm)
|
|
}
|
|
//TODO message edits
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun handleInitialAggregatedRelations(event: Event, roomId: String, aggregation: AggregatedAnnotation, realm: Realm) {
|
|
aggregation.chunk?.forEach {
|
|
if (it.type == EventType.REACTION) {
|
|
val eventId = event.eventId ?: ""
|
|
val existing = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
|
|
if (existing == null) {
|
|
val eventSummary = EventAnnotationsSummaryEntity.create(realm, eventId)
|
|
eventSummary.roomId = roomId
|
|
val sum = realm.createObject(ReactionAggregatedSummaryEntity::class.java)
|
|
sum.key = it.key
|
|
sum.firstTimestamp = event.originServerTs ?: 0 //TODO how to maintain order?
|
|
sum.count = it.count
|
|
eventSummary.reactionsSummary.add(sum)
|
|
} else {
|
|
//TODO how to handle that
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun handleReaction(event: Event, roomId: String, realm: Realm) {
|
|
event.content.toModel<ReactionContent>()?.let { content ->
|
|
//rel_type must be m.annotation
|
|
if (RelationType.ANNOTATION == content.relatesTo?.type) {
|
|
val reaction = content.relatesTo.key
|
|
val eventId = content.relatesTo.eventId
|
|
val eventSummary = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
|
|
?: EventAnnotationsSummaryEntity.create(realm, eventId).apply { this.roomId = roomId }
|
|
|
|
var sum = eventSummary.reactionsSummary.find { it.key == reaction }
|
|
if (sum == null) {
|
|
sum = realm.createObject(ReactionAggregatedSummaryEntity::class.java)
|
|
sum.key = reaction
|
|
sum.firstTimestamp = event.originServerTs ?: 0
|
|
sum.count = 1
|
|
sum.sourceEvents.add(event.eventId)
|
|
sum.addedByMe = sum.addedByMe || (credentials.userId == event.sender)
|
|
eventSummary.reactionsSummary.add(sum)
|
|
} else {
|
|
//is this a known event (is possible? pagination?)
|
|
if (!sum.sourceEvents.contains(eventId)) {
|
|
sum.count += 1
|
|
sum.sourceEvents.add(event.eventId)
|
|
sum.addedByMe = sum.addedByMe || (credentials.userId == event.sender)
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
} |