diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt index 429d7882..0cda93e8 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomSummary.kt @@ -31,7 +31,8 @@ data class RoomSummary( val isDirect: Boolean = false, val lastMessage: Event? = null, val otherMemberIds: List = emptyList(), - var notificationCount: Int = 0, - var highlightCount: Int = 0, - var tags: List = emptyList() + val notificationCount: Int = 0, + val highlightCount: Int = 0, + val tags: List = emptyList(), + val membership: MyMembership = MyMembership.NONE ) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt index 28470455..e666d2de 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt @@ -86,10 +86,9 @@ internal fun ChunkEntity.add(roomId: String, isUnlinked: Boolean = false) { assertIsManaged() - if (event.eventId.isNullOrEmpty() || this.events.fastContains(event.eventId)) { + if (event.eventId != null && events.fastContains(event.eventId)) { return } - var currentDisplayIndex = lastDisplayIndex(direction, 0) if (direction == PaginationDirection.FORWARDS) { currentDisplayIndex += 1 diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt index 3d83881a..0ce70699 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.database.mapper import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.UnsignedData import im.vector.matrix.android.internal.database.model.EventEntity +import java.util.* internal object EventMapper { @@ -26,7 +27,7 @@ internal object EventMapper { fun map(event: Event, roomId: String): EventEntity { val eventEntity = EventEntity() - eventEntity.eventId = event.eventId ?: "" + eventEntity.eventId = event.eventId ?: UUID.randomUUID().toString() eventEntity.roomId = event.roomId ?: roomId eventEntity.content = ContentMapper.map(event.content) val resolvedPrevContent = event.prevContent ?: event.unsignedData?.prevContent diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt index 9243d1de..03035128 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt @@ -37,7 +37,8 @@ internal object RoomSummaryMapper { otherMemberIds = roomSummaryEntity.otherMemberIds.toList(), highlightCount = roomSummaryEntity.highlightCount, notificationCount = roomSummaryEntity.notificationCount, - tags = tags + tags = tags, + membership = roomSummaryEntity.membership ) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt index 9f9c66f0..322c414f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/RoomSummaryEntity.kt @@ -16,9 +16,12 @@ package im.vector.matrix.android.internal.database.model +import im.vector.matrix.android.api.session.room.model.MyMembership import io.realm.RealmList import io.realm.RealmObject +import io.realm.annotations.Ignore import io.realm.annotations.PrimaryKey +import kotlin.properties.Delegates internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "", var displayName: String? = "", @@ -35,6 +38,13 @@ internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "", var tags: RealmList = RealmList() ) : RealmObject() { + private var membershipStr: String = MyMembership.NONE.name + + @delegate:Ignore + var membership: MyMembership by Delegates.observable(MyMembership.valueOf(membershipStr)) { _, _, newValue -> + membershipStr = newValue.name + } + companion object } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt index c8ed0ee9..33f4a97e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt @@ -21,6 +21,7 @@ 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.EventType import im.vector.matrix.android.api.session.events.model.toModel +import im.vector.matrix.android.api.session.room.model.MyMembership import im.vector.matrix.android.api.session.room.model.RoomTopicContent import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity @@ -41,11 +42,12 @@ internal class RoomSummaryUpdater(private val credentials: Credentials, fun update(realm: Realm, roomId: String, + membership: MyMembership? = null, roomSummary: RoomSyncSummary? = null, unreadNotifications: RoomSyncUnreadNotifications? = null) { val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() - ?: realm.createObject(roomId) + ?: realm.createObject(roomId) if (roomSummary != null) { if (roomSummary.heroes.isNotEmpty()) { @@ -65,6 +67,9 @@ internal class RoomSummaryUpdater(private val credentials: Credentials, if (unreadNotifications?.notificationCount != null) { roomSummaryEntity.notificationCount = unreadNotifications.notificationCount } + if (membership != null) { + roomSummaryEntity.membership = membership + } val lastEvent = EventEntity.latestEvent(realm, roomId, includedTypes = listOf(EventType.MESSAGE)) val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).prev()?.asDomain() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index 24dff339..9fa34eca 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -67,7 +67,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, val rooms = when (handlingStrategy) { is HandlingStrategy.JOINED -> handlingStrategy.data.map { handleJoinedRoom(realm, it.key, it.value) } is HandlingStrategy.INVITED -> handlingStrategy.data.map { handleInvitedRoom(realm, it.key, it.value) } - is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftRoom(it.key, it.value) } + is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftRoom(realm, it.key, it.value) } } realm.insertOrUpdate(rooms) } @@ -84,7 +84,6 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, if (roomEntity.membership == MyMembership.INVITED) { roomEntity.chunks.deleteAllFromRealm() } - roomEntity.membership = MyMembership.JOINED val lastChunk = ChunkEntity.findLastLiveChunkFromRoom(realm, roomId) @@ -119,7 +118,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, } } } - roomSummaryUpdater.update(realm, roomId, roomSync.summary, roomSync.unreadNotifications) + roomSummaryUpdater.update(realm, roomId, MyMembership.JOINED, roomSync.summary, roomSync.unreadNotifications) if (roomSync.ephemeral != null && roomSync.ephemeral.events.isNotEmpty()) { handleEphemeral(realm, roomId, roomSync.ephemeral) @@ -128,7 +127,6 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, if (roomSync.accountData != null && roomSync.accountData.events.isNullOrEmpty().not()) { handleRoomAccountDataEvents(realm, roomId, roomSync.accountData) } - return roomEntity } @@ -136,26 +134,28 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, roomId: String, roomSync: InvitedRoomSync): RoomEntity { - Timber.v("Handle invited sync for room $roomId") - - val roomEntity = RoomEntity() - roomEntity.roomId = roomId + val roomEntity = RoomEntity.where(realm, roomId).findFirst() + ?: realm.createObject(roomId) roomEntity.membership = MyMembership.INVITED if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) { val chunkEntity = handleTimelineEvents(realm, roomId, roomSync.inviteState.events) roomEntity.addOrUpdate(chunkEntity) } + roomSummaryUpdater.update(realm, roomId, MyMembership.INVITED) return roomEntity } - // TODO : handle it - private fun handleLeftRoom(roomId: String, + private fun handleLeftRoom(realm: Realm, + roomId: String, roomSync: RoomSync): RoomEntity { - return RoomEntity().apply { - this.roomId = roomId - this.membership = MyMembership.LEFT - } + val roomEntity = RoomEntity.where(realm, roomId).findFirst() + ?: realm.createObject(roomId) + + roomEntity.membership = MyMembership.LEFT + roomEntity.chunks.deleteAllFromRealm() + roomSummaryUpdater.update(realm, roomId, MyMembership.LEFT, roomSync.summary, roomSync.unreadNotifications) + return roomEntity } private fun handleTimelineEvents(realm: Realm, diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewModel.kt index 656617bb..b6972549 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewModel.kt @@ -24,6 +24,7 @@ import com.airbnb.mvrx.ViewModelContext import com.jakewharton.rxrelay2.BehaviorRelay import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.group.model.GroupSummary +import im.vector.matrix.android.api.session.room.model.MyMembership import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.matrix.rx.rx @@ -153,6 +154,7 @@ class RoomListViewModel(initialState: RoomListViewState, } private fun buildRoomSummaries(rooms: List): RoomSummaries { + val invites = ArrayList() val favourites = ArrayList() val directChats = ArrayList() val groupRooms = ArrayList() @@ -160,17 +162,20 @@ class RoomListViewModel(initialState: RoomListViewState, val serverNotices = ArrayList() for (room in rooms) { + if (room.membership == MyMembership.LEFT) continue val tags = room.tags.map { it.name } when { tags.contains(RoomTag.ROOM_TAG_SERVER_NOTICE) -> serverNotices.add(room) tags.contains(RoomTag.ROOM_TAG_FAVOURITE) -> favourites.add(room) tags.contains(RoomTag.ROOM_TAG_LOW_PRIORITY) -> lowPriorities.add(room) room.isDirect -> directChats.add(room) + room.membership == MyMembership.INVITED -> invites.add(room) else -> groupRooms.add(room) } } return RoomSummaries().apply { + put(RoomCategory.INVITE, invites.sortedWith(roomSummaryComparator)) put(RoomCategory.FAVOURITE, favourites.sortedWith(roomSummaryComparator)) put(RoomCategory.DIRECT, directChats.sortedWith(roomSummaryComparator)) put(RoomCategory.GROUP, groupRooms.sortedWith(roomSummaryComparator)) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewState.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewState.kt index 6d84c683..164b6d3b 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewState.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomListViewState.kt @@ -26,15 +26,17 @@ import im.vector.riotredesign.R data class RoomListViewState( val asyncRooms: Async = Uninitialized, val visibleRoomId: String? = null, + val isInviteExpanded: Boolean = true, val isFavouriteRoomsExpanded: Boolean = true, - val isDirectRoomsExpanded: Boolean = false, - val isGroupRoomsExpanded: Boolean = false, - val isLowPriorityRoomsExpanded: Boolean = false, - val isServerNoticeRoomsExpanded: Boolean = false + val isDirectRoomsExpanded: Boolean = true, + val isGroupRoomsExpanded: Boolean = true, + val isLowPriorityRoomsExpanded: Boolean = true, + val isServerNoticeRoomsExpanded: Boolean = true ) : MvRxState { fun isCategoryExpanded(roomCategory: RoomCategory): Boolean { return when (roomCategory) { + RoomCategory.INVITE -> isInviteExpanded RoomCategory.FAVOURITE -> isFavouriteRoomsExpanded RoomCategory.DIRECT -> isDirectRoomsExpanded RoomCategory.GROUP -> isGroupRoomsExpanded @@ -45,6 +47,7 @@ data class RoomListViewState( fun toggle(roomCategory: RoomCategory): RoomListViewState { return when (roomCategory) { + RoomCategory.INVITE -> copy(isInviteExpanded = !isInviteExpanded) RoomCategory.FAVOURITE -> copy(isFavouriteRoomsExpanded = !isFavouriteRoomsExpanded) RoomCategory.DIRECT -> copy(isDirectRoomsExpanded = !isDirectRoomsExpanded) RoomCategory.GROUP -> copy(isGroupRoomsExpanded = !isGroupRoomsExpanded) @@ -57,6 +60,7 @@ data class RoomListViewState( typealias RoomSummaries = LinkedHashMap> enum class RoomCategory(@StringRes val titleRes: Int) { + INVITE(R.string.invitations_header), FAVOURITE(R.string.bottom_action_favourites), DIRECT(R.string.bottom_action_people), GROUP(R.string.bottom_action_rooms),