From 56af92d7598de8c50c83153d40cecce39ecd5fa4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 31 Jan 2019 20:40:32 +0100 Subject: [PATCH] Read receipts: start to work on retrieving them with the associated room member. --- .../room/detail/timeline/ReadReceiptsItem.kt | 39 ++++++++++ .../item_timeline_event_text_message.xml | 9 ++- .../layout/item_timeline_read_receipts.xml | 74 +++++++++++++++++++ .../main/java/im/vector/matrix/rx/RxRoom.kt | 6 ++ matrix-sdk-android/build.gradle | 2 +- .../matrix/android/api/session/room/Room.kt | 9 +-- .../room/members/RoomMembersService.kt | 52 +++++++++++++ .../api/session/room/model/ReadReceipt.kt | 2 +- .../api/session/room/read/ReadService.kt | 13 ++++ .../internal/database/model/EventEntity.kt | 3 +- .../query/ReadReceiptEntityQueries.kt | 5 ++ .../internal/session/room/DefaultRoom.kt | 21 ++---- .../internal/session/room/RoomFactory.kt | 10 +-- .../internal/session/room/RoomModule.kt | 10 +-- .../room/members/DefaultRoomMembersService.kt | 61 +++++++++++++++ .../session/room/members/RoomMembers.kt | 21 +++++- .../session/room/read/DefaultReadService.kt | 21 ++++++ 17 files changed, 317 insertions(+), 41 deletions(-) create mode 100644 app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/ReadReceiptsItem.kt create mode 100644 app/src/main/res/layout/item_timeline_read_receipts.xml create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/RoomMembersService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/DefaultRoomMembersService.kt diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/ReadReceiptsItem.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/ReadReceiptsItem.kt new file mode 100644 index 00000000..f027e10c --- /dev/null +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/ReadReceiptsItem.kt @@ -0,0 +1,39 @@ +/* + * + * * 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.riotredesign.features.home.room.detail.timeline + +import android.widget.ImageView +import android.widget.TextView +import im.vector.riotredesign.R +import im.vector.riotredesign.core.epoxy.KotlinModel + +class ReadReceiptsItem() : KotlinModel(R.layout.item_timeline_read_receipts) { + + private val moreText by bind(R.id.message_more_than_expected) + private val avatarReceipt1 by bind(R.id.message_avatar_receipt_1) + private val avatarReceipt2 by bind(R.id.message_avatar_receipt_1) + private val avatarReceipt3 by bind(R.id.message_avatar_receipt_1) + private val avatarReceipt4 by bind(R.id.message_avatar_receipt_1) + private val avatarReceipt5 by bind(R.id.message_avatar_receipt_1) + private val avatarReceipts = listOf(avatarReceipt1, avatarReceipt2, avatarReceipt3, avatarReceipt4, avatarReceipt5) + + override fun bind() { + + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/item_timeline_event_text_message.xml b/app/src/main/res/layout/item_timeline_event_text_message.xml index 016356f0..986c9e1a 100644 --- a/app/src/main/res/layout/item_timeline_event_text_message.xml +++ b/app/src/main/res/layout/item_timeline_event_text_message.xml @@ -55,11 +55,18 @@ android:layout_marginBottom="8dp" android:textColor="@color/dark_grey" android:textSize="14sp" - app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/messageMemberNameView" tools:text="Alright finished work, heading there in about 20 mins…
Ping me when you’re outside" /> + \ No newline at end of file diff --git a/app/src/main/res/layout/item_timeline_read_receipts.xml b/app/src/main/res/layout/item_timeline_read_receipts.xml new file mode 100644 index 00000000..bc229dce --- /dev/null +++ b/app/src/main/res/layout/item_timeline_read_receipts.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt index 054fb438..78358f9b 100644 --- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt +++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt @@ -1,3 +1,4 @@ + /* * Copyright 2019 New Vector Ltd * @@ -17,6 +18,7 @@ package im.vector.matrix.rx import im.vector.matrix.android.api.session.room.Room +import im.vector.matrix.android.api.session.room.model.ReadReceipt import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.timeline.TimelineData import io.reactivex.Observable @@ -31,6 +33,10 @@ class RxRoom(private val room: Room) { return room.timeline(eventId).asObservable() } + fun liveReadReceipts(): Observable> { + return room.readReceipts().asObservable() + } + } fun Room.rx(): RxRoom { diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 47e0f160..612f0f7b 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -10,7 +10,7 @@ buildscript { jcenter() } dependencies { - classpath "io.realm:realm-gradle-plugin:5.8.0" + classpath "io.realm:realm-gradle-plugin:5.9.0" } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt index 20ec0d53..f119df94 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt @@ -17,6 +17,7 @@ package im.vector.matrix.android.api.session.room import androidx.lifecycle.LiveData +import im.vector.matrix.android.api.session.room.members.RoomMembersService import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.read.ReadService import im.vector.matrix.android.api.session.room.send.SendService @@ -26,7 +27,7 @@ import im.vector.matrix.android.api.util.Cancelable /** * This interface defines methods to interact within a room. */ -interface Room : TimelineService, SendService, ReadService { +interface Room : TimelineService, SendService, ReadService, RoomMembersService { /** * The roomId of this room @@ -39,10 +40,4 @@ interface Room : TimelineService, SendService, ReadService { */ val roomSummary: LiveData - /** - * This methods load all room members if it was done yet. - * @return a [Cancelable] - */ - fun loadRoomMembersIfNeeded(): Cancelable - } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/RoomMembersService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/RoomMembersService.kt new file mode 100644 index 00000000..e589de5c --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/members/RoomMembersService.kt @@ -0,0 +1,52 @@ +/* + * + * * 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.members + +import androidx.lifecycle.LiveData +import im.vector.matrix.android.api.session.room.model.RoomMember +import im.vector.matrix.android.api.util.Cancelable + +/** + * This interface defines methods to retrieve room members of a room. It's implemented at the room level. + */ +interface RoomMembersService { + + /** + * This methods load all room members if it was done yet. + * @return a [Cancelable] + */ + fun loadRoomMembersIfNeeded(): Cancelable + + /** + * Return the roomMember with userId or null. + * @param userId the userId param to look for + * + * @return the roomMember with userId or null + */ + fun getRoomMember(userId: String): RoomMember? + + /** + * Return all the roomMembers of the room + * + * @return a [LiveData] of roomMember list. + */ + fun getRoomMembersLive(): LiveData> + + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/ReadReceipt.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/ReadReceipt.kt index 0516b1af..c32cb27c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/ReadReceipt.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/ReadReceipt.kt @@ -17,7 +17,7 @@ package im.vector.matrix.android.api.session.room.model data class ReadReceipt( - val userId: String, + val roomMember: RoomMember?, val eventId: String, val originServerTs: Long ) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/read/ReadService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/read/ReadService.kt index b7b78bc8..d12bc416 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/read/ReadService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/read/ReadService.kt @@ -16,7 +16,9 @@ package im.vector.matrix.android.api.session.room.read +import androidx.lifecycle.LiveData import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.room.model.ReadReceipt /** * This interface defines methods to handle read receipts and read marker in a room. It's implemented at the room level. @@ -38,4 +40,15 @@ interface ReadService { */ fun setReadMarker(fullyReadEventId: String, callback: MatrixCallback) + /** + * * @return the current list of read receipt as [LiveData] + */ + fun readReceipts(): LiveData> + + /** + * @param the eventId to look for receipt. + * * @return the receipt associated or null + */ + fun readReceipt(eventId: String): ReadReceipt? + } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/EventEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/EventEntity.kt index 0be7b106..9ef0c652 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/EventEntity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/EventEntity.kt @@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.database.model import io.realm.RealmObject import io.realm.RealmResults +import io.realm.annotations.Index import io.realm.annotations.LinkingObjects import io.realm.annotations.PrimaryKey import java.util.* @@ -28,7 +29,7 @@ internal open class EventEntity(@PrimaryKey var localId: String = UUID.randomUUI var type: String = "", var content: String? = null, var prevContent: String? = null, - var stateKey: String? = null, + @Index var stateKey: String? = null, var originServerTs: Long? = null, var sender: String? = null, var age: Long? = 0, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt index e5a1afb6..44359675 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt @@ -26,4 +26,9 @@ internal fun ReadReceiptEntity.Companion.where(realm: Realm, roomId: String, use return realm.where() .equalTo(ReadReceiptEntityFields.ROOM_ID, roomId) .equalTo(ReadReceiptEntityFields.USER_ID, userId) +} + +internal fun ReadReceiptEntity.Companion.where(realm: Realm, roomId: String): RealmQuery { + return realm.where() + .equalTo(ReadReceiptEntityFields.ROOM_ID, roomId) } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt index e241a9f6..c50b8303 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt @@ -20,34 +20,30 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Transformations import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.session.room.Room -import im.vector.matrix.android.api.session.room.model.Membership +import im.vector.matrix.android.api.session.room.members.RoomMembersService import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.read.ReadService import im.vector.matrix.android.api.session.room.send.SendService import im.vector.matrix.android.api.session.room.timeline.TimelineService -import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask -import im.vector.matrix.android.internal.task.TaskExecutor -import im.vector.matrix.android.internal.task.configureWith internal data class DefaultRoom( override val roomId: String, - private val loadRoomMembersTask: LoadRoomMembersTask, private val monarchy: Monarchy, private val timelineService: TimelineService, private val sendService: SendService, private val readService: ReadService, - private val taskExecutor: TaskExecutor + private val roomMembersService: RoomMembersService ) : Room, - TimelineService by timelineService, - SendService by sendService, - ReadService by readService { + TimelineService by timelineService, + SendService by sendService, + ReadService by readService, + RoomMembersService by roomMembersService { override val roomSummary: LiveData by lazy { val liveData = monarchy @@ -60,8 +56,5 @@ internal data class DefaultRoom( } } - override fun loadRoomMembersIfNeeded(): Cancelable { - val params = LoadRoomMembersTask.Params(roomId, Membership.LEAVE) - return loadRoomMembersTask.configureWith(params).executeBy(taskExecutor) - } + } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt index 6b2c796c..3f8e5387 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt @@ -17,8 +17,8 @@ package im.vector.matrix.android.internal.session.room import com.zhuinden.monarchy.Monarchy -import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.session.room.Room +import im.vector.matrix.android.internal.session.room.members.DefaultRoomMembersService import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask import im.vector.matrix.android.internal.session.room.members.RoomMemberExtractor import im.vector.matrix.android.internal.session.room.read.DefaultReadService @@ -35,7 +35,6 @@ import java.util.concurrent.Executors internal class RoomFactory(private val loadRoomMembersTask: LoadRoomMembersTask, private val monarchy: Monarchy, - private val credentials: Credentials, private val paginationTask: PaginationTask, private val contextOfEventTask: GetContextOfEventTask, private val setReadMarkersTask: SetReadMarkersTask, @@ -48,15 +47,16 @@ internal class RoomFactory(private val loadRoomMembersTask: LoadRoomMembersTask, val roomMemberExtractor = RoomMemberExtractor(monarchy, roomId) val timelineService = DefaultTimelineService(roomId, monarchy, taskExecutor, timelineBoundaryCallback, contextOfEventTask, roomMemberExtractor) val sendService = DefaultSendService(roomId, eventFactory, monarchy) - val readService = DefaultReadService(roomId, monarchy, setReadMarkersTask, taskExecutor) + val roomMembersService = DefaultRoomMembersService(roomId, monarchy, loadRoomMembersTask, taskExecutor) + val readService = DefaultReadService(roomId, monarchy, roomMembersService, setReadMarkersTask, taskExecutor) + return DefaultRoom( roomId, - loadRoomMembersTask, monarchy, timelineService, sendService, readService, - taskExecutor + roomMembersService ) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt index 716fd155..18fbbc6f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt @@ -22,11 +22,7 @@ import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTas import im.vector.matrix.android.internal.session.room.read.DefaultSetReadMarkersTask import im.vector.matrix.android.internal.session.room.read.SetReadMarkersTask import im.vector.matrix.android.internal.session.room.send.EventFactory -import im.vector.matrix.android.internal.session.room.timeline.DefaultGetContextOfEventTask -import im.vector.matrix.android.internal.session.room.timeline.DefaultPaginationTask -import im.vector.matrix.android.internal.session.room.timeline.GetContextOfEventTask -import im.vector.matrix.android.internal.session.room.timeline.PaginationTask -import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor +import im.vector.matrix.android.internal.session.room.timeline.* import org.koin.dsl.module.module import retrofit2.Retrofit @@ -57,7 +53,7 @@ class RoomModule { } scope(DefaultSession.SCOPE) { - DefaultSetReadMarkersTask(get(), get(),get()) as SetReadMarkersTask + DefaultSetReadMarkersTask(get(), get(), get()) as SetReadMarkersTask } scope(DefaultSession.SCOPE) { @@ -65,7 +61,7 @@ class RoomModule { } scope(DefaultSession.SCOPE) { - RoomFactory(get(), get(), get(), get(), get(), get(), get(), get()) + RoomFactory(get(), get(), get(), get(), get(), get(), get()) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/DefaultRoomMembersService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/DefaultRoomMembersService.kt new file mode 100644 index 00000000..a7b94497 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/DefaultRoomMembersService.kt @@ -0,0 +1,61 @@ +/* + * + * * 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.members + +import androidx.lifecycle.LiveData +import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.api.session.events.model.toModel +import im.vector.matrix.android.api.session.room.members.RoomMembersService +import im.vector.matrix.android.api.session.room.model.Membership +import im.vector.matrix.android.api.session.room.model.RoomMember +import im.vector.matrix.android.api.util.Cancelable +import im.vector.matrix.android.internal.database.mapper.asDomain +import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.task.configureWith +import im.vector.matrix.android.internal.util.fetchCopied + +internal class DefaultRoomMembersService(private val roomId: String, + private val monarchy: Monarchy, + private val loadRoomMembersTask: LoadRoomMembersTask, + private val taskExecutor: TaskExecutor +) : RoomMembersService { + + override fun loadRoomMembersIfNeeded(): Cancelable { + val params = LoadRoomMembersTask.Params(roomId, Membership.LEAVE) + return loadRoomMembersTask.configureWith(params).executeBy(taskExecutor) + } + + override fun getRoomMember(userId: String): RoomMember? { + val eventEntity = monarchy.fetchCopied { + RoomMembers(it, roomId).queryRoomMemberEvent(userId).findFirst() + } + return eventEntity?.asDomain()?.content.toModel() + } + + override fun getRoomMembersLive(): LiveData> { + return monarchy.findAllMappedWithChanges( + { + RoomMembers(it, roomId).queryRoomMembersEvent() + }, + { + it.asDomain().content.toModel()!! + } + ) + } +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/RoomMembers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/RoomMembers.kt index fab1f609..4a316b8b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/RoomMembers.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/RoomMembers.kt @@ -26,6 +26,8 @@ import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.query.where import io.realm.Realm +import io.realm.RealmQuery +import io.realm.Sort internal class RoomMembers(private val realm: Realm, private val roomId: String @@ -35,10 +37,21 @@ internal class RoomMembers(private val realm: Realm, RoomSummaryEntity.where(realm, roomId).findFirst() } - fun getLoaded(): Map { + fun queryRoomMembersEvent(): RealmQuery { return EventEntity .where(realm, roomId, EventType.STATE_ROOM_MEMBER) - .sort(EventEntityFields.STATE_INDEX) + .sort(EventEntityFields.STATE_INDEX, Sort.DESCENDING) + .distinct(EventEntityFields.STATE_KEY) + .isNotNull(EventEntityFields.CONTENT) + } + + fun queryRoomMemberEvent(userId: String): RealmQuery { + return queryRoomMembersEvent() + .equalTo(EventEntityFields.STATE_KEY, userId) + } + + fun getLoaded(): Map { + return queryRoomMembersEvent() .findAll() .map { it.asDomain() } .associateBy { it.stateKey!! } @@ -48,12 +61,12 @@ internal class RoomMembers(private val realm: Realm, fun getNumberOfJoinedMembers(): Int { return roomSummary?.joinedMembersCount - ?: getLoaded().filterValues { it.membership == Membership.JOIN }.size + ?: getLoaded().filterValues { it.membership == Membership.JOIN }.size } fun getNumberOfInvitedMembers(): Int { return roomSummary?.invitedMembersCount - ?: getLoaded().filterValues { it.membership == Membership.INVITE }.size + ?: getLoaded().filterValues { it.membership == Membership.INVITE }.size } fun getNumberOfMembers(): Int { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/DefaultReadService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/DefaultReadService.kt index 467e6117..3135a1cb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/DefaultReadService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/DefaultReadService.kt @@ -16,17 +16,23 @@ package im.vector.matrix.android.internal.session.room.read +import androidx.lifecycle.LiveData import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.room.members.RoomMembersService +import im.vector.matrix.android.api.session.room.model.ReadReceipt import im.vector.matrix.android.api.session.room.read.ReadService import im.vector.matrix.android.internal.database.model.EventEntity +import im.vector.matrix.android.internal.database.model.ReadReceiptEntity import im.vector.matrix.android.internal.database.query.latestEvent +import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.util.fetchCopied internal class DefaultReadService(private val roomId: String, private val monarchy: Monarchy, + private val roomMembersService: RoomMembersService, private val setReadMarkersTask: SetReadMarkersTask, private val taskExecutor: TaskExecutor) : ReadService { @@ -50,5 +56,20 @@ internal class DefaultReadService(private val roomId: String, return monarchy.fetchCopied { EventEntity.latestEvent(it, roomId) } } + override fun readReceipts(): LiveData> { + return monarchy.findAllMappedWithChanges( + { realm -> ReadReceiptEntity.where(realm, roomId) }, + { + val roomMember = roomMembersService.getRoomMember(it.userId) + ReadReceipt(roomMember, it.eventId, it.originServerTs.toLong()) + } + ) + } + override fun readReceipt(eventId: String): ReadReceipt? { + val readReceipt = monarchy.fetchCopied { ReadReceiptEntity.where(it, roomId).findFirst() } + ?: return null + val roomMember = roomMembersService.getRoomMember(readReceipt.userId) + return ReadReceipt(roomMember, readReceipt.eventId, readReceipt.originServerTs.toLong()) + } } \ No newline at end of file