[WIP] Emoji Reactions

This commit is contained in:
Valere
2019-05-07 14:02:15 +02:00
parent a64f509872
commit 56a2a3a065
60 changed files with 1985 additions and 194 deletions

View File

@ -0,0 +1,23 @@
/*
* 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.api.session.room
import im.vector.matrix.android.api.session.events.model.Event
interface RoomEventService {
fun getEvent(eventId: String?) : Event
}

View File

@ -16,6 +16,7 @@
package im.vector.matrix.android.api.session.room.model.message
interface MessageContent {
val type: String
val body: String

View File

@ -18,9 +18,13 @@ package im.vector.matrix.android.api.session.room.send
enum class SendState {
UNKNOWN,
// the event has not been sent
UNSENT,
// the event is encrypting
ENCRYPTING,
// the event is currently sending
SENDING,
// the event has been sent
SENT,
SYNCED;

View File

@ -17,6 +17,7 @@
package im.vector.matrix.android.api.session.room.timeline
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.room.model.RoomMember
import im.vector.matrix.android.api.session.room.send.SendState
@ -59,4 +60,8 @@ data class TimelineEvent(
inline fun <reified T> getMetadata(key: String): T? {
return metadata[key] as T?
}
fun isEncrypted() : Boolean {
return EventType.ENCRYPTED == root.type
}
}

View File

@ -30,4 +30,6 @@ interface TimelineService {
*/
fun createTimeline(eventId: String?, allowedTypes: List<String>? = null): Timeline
fun getTimeLineEvent(eventId: String): TimelineEvent?
}

View File

@ -28,17 +28,18 @@ import im.vector.matrix.android.internal.database.query.findIncludingEvent
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 io.realm.Realm
import io.realm.RealmList
import io.realm.RealmQuery
internal class SenderRoomMemberExtractor(private val roomId: String) {
fun extractFrom(event: EventEntity): RoomMember? {
fun extractFrom(event: EventEntity, realm: Realm = event.realm): RoomMember? {
val sender = event.sender ?: return null
// If the event is unlinked we want to fetch unlinked state events
val unlinked = event.isUnlinked
val roomEntity = RoomEntity.where(event.realm, roomId = roomId).findFirst() ?: return null
val chunkEntity = ChunkEntity.findIncludingEvent(event.realm, event.eventId)
val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst() ?: return null
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

View File

@ -18,8 +18,12 @@ package im.vector.matrix.android.internal.session.room.timeline
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.room.timeline.Timeline
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.session.room.timeline.TimelineService
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.util.fetchMappedCopied
internal class DefaultTimelineService(private val roomId: String,
private val monarchy: Monarchy,
@ -33,4 +37,12 @@ internal class DefaultTimelineService(private val roomId: String,
return DefaultTimeline(roomId, eventId, monarchy.realmConfiguration, taskExecutor, contextOfEventTask, timelineEventFactory, paginationTask, allowedTypes)
}
override fun getTimeLineEvent(eventId: String): TimelineEvent? {
return monarchy.fetchMappedCopied({
EventEntity.where(it, eventId = eventId).findFirst()
}, { entity, realm ->
timelineEventFactory.create(entity, realm)
})
}
}

View File

@ -20,16 +20,17 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.session.room.members.SenderRoomMemberExtractor
import io.realm.Realm
internal class TimelineEventFactory(private val roomMemberExtractor: SenderRoomMemberExtractor) {
private val cached = mutableMapOf<String, SenderData>()
fun create(eventEntity: EventEntity): TimelineEvent {
fun create(eventEntity: EventEntity, realm: Realm = eventEntity.realm): TimelineEvent {
val sender = eventEntity.sender
val cacheKey = sender + eventEntity.stateIndex
val senderData = cached.getOrPut(cacheKey) {
val senderRoomMember = roomMemberExtractor.extractFrom(eventEntity)
val senderRoomMember = roomMemberExtractor.extractFrom(eventEntity,realm)
SenderData(senderRoomMember?.displayName, senderRoomMember?.avatarUrl)
}
return TimelineEvent(

View File

@ -42,6 +42,17 @@ fun <T : RealmModel> Monarchy.fetchCopied(query: (Realm) -> T?): T? {
return fetch(query, true)
}
fun <U, T : RealmModel> Monarchy.fetchMappedCopied(query: (Realm) -> T?, map: (T, realm: Realm) -> U): U? {
val ref = AtomicReference<U?>()
doWithRealm { realm ->
val result = query.invoke(realm)?.let {
map(realm.copyFromRealm(it), realm)
}
ref.set(result)
}
return ref.get()
}
private fun <T : RealmModel> Monarchy.fetch(query: (Realm) -> T?, copyFromRealm: Boolean): T? {
val ref = AtomicReference<T>()
doWithRealm { realm ->