Merge pull request #883 from vector-im/feature/share
Improve the room list when sharing to RiotX
This commit is contained in:
commit
75e39535bc
1
.idea/codeStyles/codeStyleConfig.xml
generated
1
.idea/codeStyles/codeStyleConfig.xml
generated
@ -1,5 +1,6 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
<state>
|
<state>
|
||||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||||
</state>
|
</state>
|
||||||
</component>
|
</component>
|
@ -5,7 +5,7 @@ Features ✨:
|
|||||||
- Enable encryption in unencrypted rooms, from the room settings (#212)
|
- Enable encryption in unencrypted rooms, from the room settings (#212)
|
||||||
|
|
||||||
Improvements 🙌:
|
Improvements 🙌:
|
||||||
-
|
- Sharing things to RiotX: sort list by recent room first (#771)
|
||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
-
|
-
|
||||||
|
@ -45,7 +45,8 @@ data class RoomSummary(
|
|||||||
val readMarkerId: String? = null,
|
val readMarkerId: String? = null,
|
||||||
val userDrafts: List<UserDraft> = emptyList(),
|
val userDrafts: List<UserDraft> = emptyList(),
|
||||||
var isEncrypted: Boolean,
|
var isEncrypted: Boolean,
|
||||||
val typingRoomMemberIds: List<String> = emptyList()
|
val typingRoomMemberIds: List<String> = emptyList(),
|
||||||
|
val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val isVersioned: Boolean
|
val isVersioned: Boolean
|
||||||
@ -53,4 +54,8 @@ data class RoomSummary(
|
|||||||
|
|
||||||
val hasNewMessages: Boolean
|
val hasNewMessages: Boolean
|
||||||
get() = notificationCount != 0
|
get() = notificationCount != 0
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val NOT_IN_BREADCRUMBS = -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ 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.android.api.session.room.model.tag.RoomTag
|
||||||
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
|
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class RoomSummaryMapper @Inject constructor(
|
internal class RoomSummaryMapper @Inject constructor(
|
||||||
@ -74,7 +74,8 @@ internal class RoomSummaryMapper @Inject constructor(
|
|||||||
canonicalAlias = roomSummaryEntity.canonicalAlias,
|
canonicalAlias = roomSummaryEntity.canonicalAlias,
|
||||||
aliases = roomSummaryEntity.aliases.toList(),
|
aliases = roomSummaryEntity.aliases.toList(),
|
||||||
isEncrypted = roomSummaryEntity.isEncrypted,
|
isEncrypted = roomSummaryEntity.isEncrypted,
|
||||||
typingRoomMemberIds = roomSummaryEntity.typingUserIds.toList()
|
typingRoomMemberIds = roomSummaryEntity.typingUserIds.toList(),
|
||||||
|
breadcrumbsIndex = roomSummaryEntity.breadcrumbsIndex
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,35 +17,37 @@
|
|||||||
package im.vector.matrix.android.internal.database.model
|
package im.vector.matrix.android.internal.database.model
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.room.model.Membership
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.matrix.android.api.session.room.model.VersioningState
|
import im.vector.matrix.android.api.session.room.model.VersioningState
|
||||||
import io.realm.RealmList
|
import io.realm.RealmList
|
||||||
import io.realm.RealmObject
|
import io.realm.RealmObject
|
||||||
import io.realm.annotations.PrimaryKey
|
import io.realm.annotations.PrimaryKey
|
||||||
|
|
||||||
internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
internal open class RoomSummaryEntity(
|
||||||
var displayName: String? = "",
|
@PrimaryKey var roomId: String = "",
|
||||||
var avatarUrl: String? = "",
|
var displayName: String? = "",
|
||||||
var topic: String? = "",
|
var avatarUrl: String? = "",
|
||||||
var latestPreviewableEvent: TimelineEventEntity? = null,
|
var topic: String? = "",
|
||||||
var heroes: RealmList<String> = RealmList(),
|
var latestPreviewableEvent: TimelineEventEntity? = null,
|
||||||
var joinedMembersCount: Int? = 0,
|
var heroes: RealmList<String> = RealmList(),
|
||||||
var invitedMembersCount: Int? = 0,
|
var joinedMembersCount: Int? = 0,
|
||||||
var isDirect: Boolean = false,
|
var invitedMembersCount: Int? = 0,
|
||||||
var directUserId: String? = null,
|
var isDirect: Boolean = false,
|
||||||
var otherMemberIds: RealmList<String> = RealmList(),
|
var directUserId: String? = null,
|
||||||
var notificationCount: Int = 0,
|
var otherMemberIds: RealmList<String> = RealmList(),
|
||||||
var highlightCount: Int = 0,
|
var notificationCount: Int = 0,
|
||||||
var readMarkerId: String? = null,
|
var highlightCount: Int = 0,
|
||||||
var hasUnreadMessages: Boolean = false,
|
var readMarkerId: String? = null,
|
||||||
var tags: RealmList<RoomTagEntity> = RealmList(),
|
var hasUnreadMessages: Boolean = false,
|
||||||
var userDrafts: UserDraftsEntity? = null,
|
var tags: RealmList<RoomTagEntity> = RealmList(),
|
||||||
var breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS,
|
var userDrafts: UserDraftsEntity? = null,
|
||||||
var canonicalAlias: String? = null,
|
var breadcrumbsIndex: Int = RoomSummary.NOT_IN_BREADCRUMBS,
|
||||||
var aliases: RealmList<String> = RealmList(),
|
var canonicalAlias: String? = null,
|
||||||
// this is required for querying
|
var aliases: RealmList<String> = RealmList(),
|
||||||
var flatAliases: String = "",
|
// this is required for querying
|
||||||
var isEncrypted: Boolean = false,
|
var flatAliases: String = "",
|
||||||
var typingUserIds: RealmList<String> = RealmList()
|
var isEncrypted: Boolean = false,
|
||||||
|
var typingUserIds: RealmList<String> = RealmList()
|
||||||
) : RealmObject() {
|
) : RealmObject() {
|
||||||
|
|
||||||
private var membershipStr: String = Membership.NONE.name
|
private var membershipStr: String = Membership.NONE.name
|
||||||
@ -66,7 +68,5 @@ internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
|||||||
versioningStateStr = value.name
|
versioningStateStr = value.name
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object
|
||||||
const val NOT_IN_BREADCRUMBS = -1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ internal class DefaultRoomService @Inject constructor(private val monarchy: Mona
|
|||||||
return RoomSummaryEntity.where(realm)
|
return RoomSummaryEntity.where(realm)
|
||||||
.isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME)
|
.isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME)
|
||||||
.notEqualTo(RoomSummaryEntityFields.VERSIONING_STATE_STR, VersioningState.UPGRADED_ROOM_JOINED.name)
|
.notEqualTo(RoomSummaryEntityFields.VERSIONING_STATE_STR, VersioningState.UPGRADED_ROOM_JOINED.name)
|
||||||
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummaryEntity.NOT_IN_BREADCRUMBS)
|
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummary.NOT_IN_BREADCRUMBS)
|
||||||
.sort(RoomSummaryEntityFields.BREADCRUMBS_INDEX)
|
.sort(RoomSummaryEntityFields.BREADCRUMBS_INDEX)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,16 +21,26 @@ import im.vector.matrix.android.api.pushrules.RuleScope
|
|||||||
import im.vector.matrix.android.api.pushrules.RuleSetKey
|
import im.vector.matrix.android.api.pushrules.RuleSetKey
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMemberContent
|
import im.vector.matrix.android.api.session.room.model.RoomMemberContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.matrix.android.internal.database.mapper.PushRulesMapper
|
import im.vector.matrix.android.internal.database.mapper.PushRulesMapper
|
||||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
import im.vector.matrix.android.internal.database.model.*
|
import im.vector.matrix.android.internal.database.model.BreadcrumbsEntity
|
||||||
|
import im.vector.matrix.android.internal.database.model.IgnoredUserEntity
|
||||||
|
import im.vector.matrix.android.internal.database.model.PushRulesEntity
|
||||||
|
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.getDirectRooms
|
import im.vector.matrix.android.internal.database.query.getDirectRooms
|
||||||
import im.vector.matrix.android.internal.database.query.getOrCreate
|
import im.vector.matrix.android.internal.database.query.getOrCreate
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
import im.vector.matrix.android.internal.di.UserId
|
import im.vector.matrix.android.internal.di.UserId
|
||||||
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
|
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
|
||||||
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
|
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
|
||||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.*
|
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataBreadcrumbs
|
||||||
|
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataDirectMessages
|
||||||
|
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataFallback
|
||||||
|
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIgnoredUsers
|
||||||
|
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataPushRules
|
||||||
|
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataSync
|
||||||
import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper
|
import im.vector.matrix.android.internal.session.user.accountdata.DirectChatsHelper
|
||||||
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
|
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
@ -177,10 +187,10 @@ internal class UserAccountDataSyncHandler @Inject constructor(
|
|||||||
// Update the room summaries
|
// Update the room summaries
|
||||||
// Reset all the indexes...
|
// Reset all the indexes...
|
||||||
RoomSummaryEntity.where(realm)
|
RoomSummaryEntity.where(realm)
|
||||||
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummaryEntity.NOT_IN_BREADCRUMBS)
|
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummary.NOT_IN_BREADCRUMBS)
|
||||||
.findAll()
|
.findAll()
|
||||||
.forEach {
|
.forEach {
|
||||||
it.breadcrumbsIndex = RoomSummaryEntity.NOT_IN_BREADCRUMBS
|
it.breadcrumbsIndex = RoomSummary.NOT_IN_BREADCRUMBS
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...and apply new indexes
|
// ...and apply new indexes
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package im.vector.matrix.android.internal.session.user.accountdata
|
package im.vector.matrix.android.internal.session.user.accountdata
|
||||||
|
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.matrix.android.internal.database.model.BreadcrumbsEntity
|
import im.vector.matrix.android.internal.database.model.BreadcrumbsEntity
|
||||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
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.model.RoomSummaryEntityFields
|
||||||
@ -50,10 +51,10 @@ internal class DefaultSaveBreadcrumbsTask @Inject constructor(
|
|||||||
// Update the room summaries
|
// Update the room summaries
|
||||||
// Reset all the indexes...
|
// Reset all the indexes...
|
||||||
RoomSummaryEntity.where(realm)
|
RoomSummaryEntity.where(realm)
|
||||||
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummaryEntity.NOT_IN_BREADCRUMBS)
|
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummary.NOT_IN_BREADCRUMBS)
|
||||||
.findAll()
|
.findAll()
|
||||||
.forEach {
|
.forEach {
|
||||||
it.breadcrumbsIndex = RoomSummaryEntity.NOT_IN_BREADCRUMBS
|
it.breadcrumbsIndex = RoomSummary.NOT_IN_BREADCRUMBS
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...and apply new indexes
|
// ...and apply new indexes
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.riotx.features.home.room.list
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class BreadcrumbsRoomComparator @Inject constructor(
|
||||||
|
private val chronologicalRoomComparator: ChronologicalRoomComparator
|
||||||
|
) : Comparator<RoomSummary> {
|
||||||
|
|
||||||
|
override fun compare(leftRoomSummary: RoomSummary?, rightRoomSummary: RoomSummary?): Int {
|
||||||
|
val leftBreadcrumbsIndex = leftRoomSummary?.breadcrumbsIndex ?: RoomSummary.NOT_IN_BREADCRUMBS
|
||||||
|
val rightBreadcrumbsIndex = rightRoomSummary?.breadcrumbsIndex ?: RoomSummary.NOT_IN_BREADCRUMBS
|
||||||
|
|
||||||
|
return if (leftBreadcrumbsIndex == RoomSummary.NOT_IN_BREADCRUMBS) {
|
||||||
|
if (rightBreadcrumbsIndex == RoomSummary.NOT_IN_BREADCRUMBS) {
|
||||||
|
chronologicalRoomComparator.compare(leftRoomSummary, rightRoomSummary)
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rightBreadcrumbsIndex == RoomSummary.NOT_IN_BREADCRUMBS) {
|
||||||
|
-1
|
||||||
|
} else {
|
||||||
|
leftBreadcrumbsIndex - rightBreadcrumbsIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -22,26 +22,20 @@ import javax.inject.Inject
|
|||||||
class ChronologicalRoomComparator @Inject constructor() : Comparator<RoomSummary> {
|
class ChronologicalRoomComparator @Inject constructor() : Comparator<RoomSummary> {
|
||||||
|
|
||||||
override fun compare(leftRoomSummary: RoomSummary?, rightRoomSummary: RoomSummary?): Int {
|
override fun compare(leftRoomSummary: RoomSummary?, rightRoomSummary: RoomSummary?): Int {
|
||||||
var rightTimestamp = 0L
|
return when {
|
||||||
var leftTimestamp = 0L
|
rightRoomSummary?.latestPreviewableEvent?.root == null -> -1
|
||||||
if (null != leftRoomSummary) {
|
leftRoomSummary?.latestPreviewableEvent?.root == null -> 1
|
||||||
leftTimestamp = leftRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
else -> {
|
||||||
}
|
val rightTimestamp = rightRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
||||||
if (null != rightRoomSummary) {
|
val leftTimestamp = leftRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
||||||
rightTimestamp = rightRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
|
||||||
}
|
val deltaTimestamp = rightTimestamp - leftTimestamp
|
||||||
return if (rightRoomSummary?.latestPreviewableEvent?.root == null) {
|
|
||||||
-1
|
when {
|
||||||
} else if (leftRoomSummary?.latestPreviewableEvent?.root == null) {
|
deltaTimestamp > 0 -> 1
|
||||||
1
|
deltaTimestamp < 0 -> -1
|
||||||
} else {
|
else -> 0
|
||||||
val deltaTimestamp = rightTimestamp - leftTimestamp
|
}
|
||||||
if (deltaTimestamp > 0) {
|
|
||||||
1
|
|
||||||
} else if (deltaTimestamp < 0) {
|
|
||||||
-1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ 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.android.api.session.room.model.tag.RoomTag
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.core.utils.DataSource
|
import im.vector.riotx.core.utils.DataSource
|
||||||
|
import im.vector.riotx.features.home.RoomListDisplayMode
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -202,35 +203,54 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun buildRoomSummaries(rooms: List<RoomSummary>): RoomSummaries {
|
private fun buildRoomSummaries(rooms: List<RoomSummary>): RoomSummaries {
|
||||||
// Set up init size on directChats and groupRooms as they are the biggest ones
|
if (displayMode == RoomListDisplayMode.SHARE) {
|
||||||
val invites = ArrayList<RoomSummary>()
|
val recentRooms = ArrayList<RoomSummary>(20)
|
||||||
val favourites = ArrayList<RoomSummary>()
|
val otherRooms = ArrayList<RoomSummary>(rooms.size)
|
||||||
val directChats = ArrayList<RoomSummary>(rooms.size)
|
|
||||||
val groupRooms = ArrayList<RoomSummary>(rooms.size)
|
|
||||||
val lowPriorities = ArrayList<RoomSummary>()
|
|
||||||
val serverNotices = ArrayList<RoomSummary>()
|
|
||||||
|
|
||||||
rooms
|
rooms
|
||||||
.filter { roomListDisplayModeFilter.test(it) }
|
.filter { roomListDisplayModeFilter.test(it) }
|
||||||
.forEach { room ->
|
.forEach { room ->
|
||||||
val tags = room.tags.map { it.name }
|
when (room.breadcrumbsIndex) {
|
||||||
when {
|
RoomSummary.NOT_IN_BREADCRUMBS -> otherRooms.add(room)
|
||||||
room.membership == Membership.INVITE -> invites.add(room)
|
else -> recentRooms.add(room)
|
||||||
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)
|
|
||||||
else -> groupRooms.add(room)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return RoomSummaries().apply {
|
return RoomSummaries().apply {
|
||||||
put(RoomCategory.INVITE, invites)
|
put(RoomCategory.RECENT_ROOMS, recentRooms)
|
||||||
put(RoomCategory.FAVOURITE, favourites)
|
put(RoomCategory.OTHER_ROOMS, otherRooms)
|
||||||
put(RoomCategory.DIRECT, directChats)
|
}
|
||||||
put(RoomCategory.GROUP, groupRooms)
|
} else {
|
||||||
put(RoomCategory.LOW_PRIORITY, lowPriorities)
|
// Set up init size on directChats and groupRooms as they are the biggest ones
|
||||||
put(RoomCategory.SERVER_NOTICE, serverNotices)
|
val invites = ArrayList<RoomSummary>()
|
||||||
|
val favourites = ArrayList<RoomSummary>()
|
||||||
|
val directChats = ArrayList<RoomSummary>(rooms.size)
|
||||||
|
val groupRooms = ArrayList<RoomSummary>(rooms.size)
|
||||||
|
val lowPriorities = ArrayList<RoomSummary>()
|
||||||
|
val serverNotices = ArrayList<RoomSummary>()
|
||||||
|
|
||||||
|
rooms
|
||||||
|
.filter { roomListDisplayModeFilter.test(it) }
|
||||||
|
.forEach { room ->
|
||||||
|
val tags = room.tags.map { it.name }
|
||||||
|
when {
|
||||||
|
room.membership == Membership.INVITE -> invites.add(room)
|
||||||
|
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)
|
||||||
|
else -> groupRooms.add(room)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RoomSummaries().apply {
|
||||||
|
put(RoomCategory.INVITE, invites)
|
||||||
|
put(RoomCategory.FAVOURITE, favourites)
|
||||||
|
put(RoomCategory.DIRECT, directChats)
|
||||||
|
put(RoomCategory.GROUP, groupRooms)
|
||||||
|
put(RoomCategory.LOW_PRIORITY, lowPriorities)
|
||||||
|
put(RoomCategory.SERVER_NOTICE, serverNotices)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,10 @@ data class RoomListViewState(
|
|||||||
val isDirectRoomsExpanded: Boolean = true,
|
val isDirectRoomsExpanded: Boolean = true,
|
||||||
val isGroupRoomsExpanded: Boolean = true,
|
val isGroupRoomsExpanded: Boolean = true,
|
||||||
val isLowPriorityRoomsExpanded: Boolean = true,
|
val isLowPriorityRoomsExpanded: Boolean = true,
|
||||||
val isServerNoticeRoomsExpanded: Boolean = true
|
val isServerNoticeRoomsExpanded: Boolean = true,
|
||||||
|
// For sharing
|
||||||
|
val isRecentExpanded: Boolean = true,
|
||||||
|
val isOtherExpanded: Boolean = true
|
||||||
) : MvRxState {
|
) : MvRxState {
|
||||||
|
|
||||||
constructor(args: RoomListParams) : this(displayMode = args.displayMode)
|
constructor(args: RoomListParams) : this(displayMode = args.displayMode)
|
||||||
@ -56,6 +59,8 @@ data class RoomListViewState(
|
|||||||
RoomCategory.GROUP -> isGroupRoomsExpanded
|
RoomCategory.GROUP -> isGroupRoomsExpanded
|
||||||
RoomCategory.LOW_PRIORITY -> isLowPriorityRoomsExpanded
|
RoomCategory.LOW_PRIORITY -> isLowPriorityRoomsExpanded
|
||||||
RoomCategory.SERVER_NOTICE -> isServerNoticeRoomsExpanded
|
RoomCategory.SERVER_NOTICE -> isServerNoticeRoomsExpanded
|
||||||
|
RoomCategory.RECENT_ROOMS -> isRecentExpanded
|
||||||
|
RoomCategory.OTHER_ROOMS -> isOtherExpanded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +72,8 @@ data class RoomListViewState(
|
|||||||
RoomCategory.GROUP -> copy(isGroupRoomsExpanded = !isGroupRoomsExpanded)
|
RoomCategory.GROUP -> copy(isGroupRoomsExpanded = !isGroupRoomsExpanded)
|
||||||
RoomCategory.LOW_PRIORITY -> copy(isLowPriorityRoomsExpanded = !isLowPriorityRoomsExpanded)
|
RoomCategory.LOW_PRIORITY -> copy(isLowPriorityRoomsExpanded = !isLowPriorityRoomsExpanded)
|
||||||
RoomCategory.SERVER_NOTICE -> copy(isServerNoticeRoomsExpanded = !isServerNoticeRoomsExpanded)
|
RoomCategory.SERVER_NOTICE -> copy(isServerNoticeRoomsExpanded = !isServerNoticeRoomsExpanded)
|
||||||
|
RoomCategory.RECENT_ROOMS -> copy(isRecentExpanded = !isRecentExpanded)
|
||||||
|
RoomCategory.OTHER_ROOMS -> copy(isOtherExpanded = !isOtherExpanded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +93,11 @@ enum class RoomCategory(@StringRes val titleRes: Int) {
|
|||||||
DIRECT(R.string.bottom_action_people_x),
|
DIRECT(R.string.bottom_action_people_x),
|
||||||
GROUP(R.string.bottom_action_rooms),
|
GROUP(R.string.bottom_action_rooms),
|
||||||
LOW_PRIORITY(R.string.low_priority_header),
|
LOW_PRIORITY(R.string.low_priority_header),
|
||||||
SERVER_NOTICE(R.string.system_alerts_header)
|
SERVER_NOTICE(R.string.system_alerts_header),
|
||||||
|
|
||||||
|
// For Sharing
|
||||||
|
RECENT_ROOMS(R.string.room_list_sharing_header_recent_rooms),
|
||||||
|
OTHER_ROOMS(R.string.room_list_sharing_header_other_rooms)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun RoomSummaries?.isNullOrEmpty(): Boolean {
|
fun RoomSummaries?.isNullOrEmpty(): Boolean {
|
||||||
|
@ -59,39 +59,9 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
|||||||
override fun buildModels() {
|
override fun buildModels() {
|
||||||
val nonNullViewState = viewState ?: return
|
val nonNullViewState = viewState ?: return
|
||||||
when (nonNullViewState.displayMode) {
|
when (nonNullViewState.displayMode) {
|
||||||
RoomListDisplayMode.FILTERED,
|
RoomListDisplayMode.FILTERED -> buildFilteredRooms(nonNullViewState)
|
||||||
RoomListDisplayMode.SHARE -> {
|
RoomListDisplayMode.SHARE -> buildShareRooms(nonNullViewState)
|
||||||
buildFilteredRooms(nonNullViewState)
|
else -> buildRooms(nonNullViewState)
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
var showHelp = false
|
|
||||||
val roomSummaries = nonNullViewState.asyncFilteredRooms()
|
|
||||||
roomSummaries?.forEach { (category, summaries) ->
|
|
||||||
if (summaries.isEmpty()) {
|
|
||||||
return@forEach
|
|
||||||
} else {
|
|
||||||
val isExpanded = nonNullViewState.isCategoryExpanded(category)
|
|
||||||
buildRoomCategory(nonNullViewState, summaries, category.titleRes, nonNullViewState.isCategoryExpanded(category)) {
|
|
||||||
listener?.onToggleRoomCategory(category)
|
|
||||||
}
|
|
||||||
if (isExpanded) {
|
|
||||||
buildRoomModels(summaries,
|
|
||||||
nonNullViewState.joiningRoomsIds,
|
|
||||||
nonNullViewState.joiningErrorRoomsIds,
|
|
||||||
nonNullViewState.rejectingRoomsIds,
|
|
||||||
nonNullViewState.rejectingErrorRoomsIds)
|
|
||||||
// Never set showHelp to true for invitation
|
|
||||||
if (category != RoomCategory.INVITE) {
|
|
||||||
showHelp = userPreferencesProvider.shouldShowLongClickOnRoomHelp()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showHelp) {
|
|
||||||
buildLongClickHelp()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,9 +79,69 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
|||||||
viewState.rejectingRoomsIds,
|
viewState.rejectingRoomsIds,
|
||||||
viewState.rejectingErrorRoomsIds)
|
viewState.rejectingErrorRoomsIds)
|
||||||
|
|
||||||
when {
|
addFilterFooter(viewState)
|
||||||
viewState.displayMode == RoomListDisplayMode.FILTERED -> addFilterFooter(viewState)
|
}
|
||||||
filteredSummaries.isEmpty() -> addEmptyFooter()
|
|
||||||
|
private fun buildShareRooms(viewState: RoomListViewState) {
|
||||||
|
var hasResult = false
|
||||||
|
val roomSummaries = viewState.asyncFilteredRooms()
|
||||||
|
|
||||||
|
roomListNameFilter.filter = viewState.roomFilter
|
||||||
|
|
||||||
|
roomSummaries?.forEach { (category, summaries) ->
|
||||||
|
val filteredSummaries = summaries
|
||||||
|
.filter { it.membership == Membership.JOIN && roomListNameFilter.test(it) }
|
||||||
|
|
||||||
|
if (filteredSummaries.isEmpty()) {
|
||||||
|
return@forEach
|
||||||
|
} else {
|
||||||
|
hasResult = true
|
||||||
|
val isExpanded = viewState.isCategoryExpanded(category)
|
||||||
|
buildRoomCategory(viewState, emptyList(), category.titleRes, viewState.isCategoryExpanded(category)) {
|
||||||
|
listener?.onToggleRoomCategory(category)
|
||||||
|
}
|
||||||
|
if (isExpanded) {
|
||||||
|
buildRoomModels(filteredSummaries,
|
||||||
|
emptySet(),
|
||||||
|
emptySet(),
|
||||||
|
emptySet(),
|
||||||
|
emptySet()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasResult) {
|
||||||
|
addNoResultItem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildRooms(viewState: RoomListViewState) {
|
||||||
|
var showHelp = false
|
||||||
|
val roomSummaries = viewState.asyncFilteredRooms()
|
||||||
|
roomSummaries?.forEach { (category, summaries) ->
|
||||||
|
if (summaries.isEmpty()) {
|
||||||
|
return@forEach
|
||||||
|
} else {
|
||||||
|
val isExpanded = viewState.isCategoryExpanded(category)
|
||||||
|
buildRoomCategory(viewState, summaries, category.titleRes, viewState.isCategoryExpanded(category)) {
|
||||||
|
listener?.onToggleRoomCategory(category)
|
||||||
|
}
|
||||||
|
if (isExpanded) {
|
||||||
|
buildRoomModels(summaries,
|
||||||
|
viewState.joiningRoomsIds,
|
||||||
|
viewState.joiningErrorRoomsIds,
|
||||||
|
viewState.rejectingRoomsIds,
|
||||||
|
viewState.rejectingErrorRoomsIds)
|
||||||
|
// Never set showHelp to true for invitation
|
||||||
|
if (category != RoomCategory.INVITE) {
|
||||||
|
showHelp = userPreferencesProvider.shouldShowLongClickOnRoomHelp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showHelp) {
|
||||||
|
buildLongClickHelp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +160,7 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addEmptyFooter() {
|
private fun addNoResultItem() {
|
||||||
noResultItem {
|
noResultItem {
|
||||||
id("no_result")
|
id("no_result")
|
||||||
text(stringProvider.getString(R.string.no_result_placeholder))
|
text(stringProvider.getString(R.string.no_result_placeholder))
|
||||||
@ -142,9 +172,6 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
|||||||
@StringRes titleRes: Int,
|
@StringRes titleRes: Int,
|
||||||
isExpanded: Boolean,
|
isExpanded: Boolean,
|
||||||
mutateExpandedState: () -> Unit) {
|
mutateExpandedState: () -> Unit) {
|
||||||
if (summaries.isEmpty()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO should add some business logic later
|
// TODO should add some business logic later
|
||||||
val unreadCount = if (summaries.isEmpty()) {
|
val unreadCount = if (summaries.isEmpty()) {
|
||||||
0
|
0
|
||||||
|
@ -44,7 +44,9 @@ class IncomingShareActivity :
|
|||||||
@Inject lateinit var sessionHolder: ActiveSessionHolder
|
@Inject lateinit var sessionHolder: ActiveSessionHolder
|
||||||
@Inject lateinit var incomingShareViewModelFactory: IncomingShareViewModel.Factory
|
@Inject lateinit var incomingShareViewModelFactory: IncomingShareViewModel.Factory
|
||||||
private lateinit var attachmentsHelper: AttachmentsHelper
|
private lateinit var attachmentsHelper: AttachmentsHelper
|
||||||
private val incomingShareViewModel: IncomingShareViewModel by viewModel()
|
// Do not remove, even if not used, it instantiates the view model
|
||||||
|
@Suppress("unused")
|
||||||
|
private val viewModel: IncomingShareViewModel by viewModel()
|
||||||
private val roomListFragment: RoomListFragment?
|
private val roomListFragment: RoomListFragment?
|
||||||
get() {
|
get() {
|
||||||
return supportFragmentManager.findFragmentById(R.id.shareRoomListFragmentContainer) as? RoomListFragment
|
return supportFragmentManager.findFragmentById(R.id.shareRoomListFragmentContainer) as? RoomListFragment
|
||||||
|
@ -28,6 +28,7 @@ import im.vector.riotx.ActiveSessionDataSource
|
|||||||
import im.vector.riotx.core.platform.EmptyAction
|
import im.vector.riotx.core.platform.EmptyAction
|
||||||
import im.vector.riotx.core.platform.EmptyViewEvents
|
import im.vector.riotx.core.platform.EmptyViewEvents
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
|
import im.vector.riotx.features.home.room.list.BreadcrumbsRoomComparator
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -39,7 +40,8 @@ data class IncomingShareState(private val dummy: Boolean = false) : MvRxState
|
|||||||
*/
|
*/
|
||||||
class IncomingShareViewModel @AssistedInject constructor(@Assisted initialState: IncomingShareState,
|
class IncomingShareViewModel @AssistedInject constructor(@Assisted initialState: IncomingShareState,
|
||||||
private val sessionObservableStore: ActiveSessionDataSource,
|
private val sessionObservableStore: ActiveSessionDataSource,
|
||||||
private val shareRoomListObservableStore: ShareRoomListDataSource)
|
private val shareRoomListObservableStore: ShareRoomListDataSource,
|
||||||
|
private val breadcrumbsRoomComparator: BreadcrumbsRoomComparator)
|
||||||
: VectorViewModel<IncomingShareState, EmptyAction, EmptyViewEvents>(initialState) {
|
: VectorViewModel<IncomingShareState, EmptyAction, EmptyViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedInject.Factory
|
@AssistedInject.Factory
|
||||||
@ -69,6 +71,9 @@ class IncomingShareViewModel @AssistedInject constructor(@Assisted initialState:
|
|||||||
?: Observable.just(emptyList())
|
?: Observable.just(emptyList())
|
||||||
}
|
}
|
||||||
.throttleLast(300, TimeUnit.MILLISECONDS)
|
.throttleLast(300, TimeUnit.MILLISECONDS)
|
||||||
|
.map {
|
||||||
|
it.sortedWith(breadcrumbsRoomComparator)
|
||||||
|
}
|
||||||
.subscribe {
|
.subscribe {
|
||||||
shareRoomListObservableStore.post(it)
|
shareRoomListObservableStore.post(it)
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,9 @@
|
|||||||
|
|
||||||
<string name="unignore">Unignore</string>
|
<string name="unignore">Unignore</string>
|
||||||
|
|
||||||
|
<string name="room_list_sharing_header_recent_rooms">Recent rooms</string>
|
||||||
|
<string name="room_list_sharing_header_other_rooms">Other rooms</string>
|
||||||
|
|
||||||
<!-- Title for category in the settings which affect what is displayed in the timeline (ex: show read receipts, etc.) -->
|
<!-- Title for category in the settings which affect what is displayed in the timeline (ex: show read receipts, etc.) -->
|
||||||
<string name="settings_category_timeline">Timeline</string>
|
<string name="settings_category_timeline">Timeline</string>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user