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/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt index ae6255a1..952a1eca 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 b30ba3ee..1d91121e 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 34515d30..f75302ff 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 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 1bbb792d..6c6d78ed 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!! }