From aec7b733454a2a669571437e6ce3f5497663ee33 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 8 Apr 2019 15:53:02 +0200 Subject: [PATCH] Introduce room member service --- .../matrix/android/api/session/room/Room.kt | 9 +-- .../room/members/RoomMembersService.kt | 52 ++++++++++++++++ .../internal/session/room/DefaultRoom.kt | 16 ++--- .../internal/session/room/RoomFactory.kt | 8 +-- .../internal/session/room/RoomModule.kt | 2 +- .../room/members/DefaultRoomMembersService.kt | 61 +++++++++++++++++++ .../session/room/members/RoomMembers.kt | 16 ++++- 7 files changed, 138 insertions(+), 26 deletions(-) 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/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 20ec0d534a..f119df9412 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 0000000000..e589de5cfc --- /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/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt index ae6255a123..952a1ecac7 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,35 +20,31 @@ 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.RealmLiveData 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 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 { + ReadService by readService, + RoomMembersService by roomMembersService { override val roomSummary: LiveData by lazy { val liveRealmData = RealmLiveData(monarchy.realmConfiguration) { realm -> @@ -59,8 +55,4 @@ internal 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 b30ba3eebd..1d91121e45 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 @@ -33,7 +33,6 @@ import im.vector.matrix.android.internal.task.TaskExecutor 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, @@ -45,15 +44,16 @@ internal class RoomFactory(private val loadRoomMembersTask: LoadRoomMembersTask, val timelineEventFactory = TimelineEventFactory(roomMemberExtractor) val timelineService = DefaultTimelineService(roomId, monarchy, taskExecutor, contextOfEventTask, timelineEventFactory, paginationTask) val sendService = DefaultSendService(roomId, eventFactory, monarchy) + val roomMembersService = DefaultRoomMembersService(roomId, monarchy, loadRoomMembersTask, taskExecutor) val readService = DefaultReadService(roomId, monarchy, 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 34515d30da..f75302ffdf 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 @@ -63,7 +63,7 @@ class RoomModule { } scope(DefaultSession.SCOPE) { - RoomFactory(get(), get(), get(), get(), get(), get(), get(), get()) + RoomFactory(get(), get(), get(), get(), get(), get(), get()) } scope(DefaultSession.SCOPE) { 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 0000000000..a7b944970a --- /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 1bbb792db8..6c6d78ed2e 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,7 @@ 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, @@ -47,10 +48,21 @@ internal class RoomMembers(private val realm: Realm, } } - 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!! }