Sharing things to RiotX: sort list by recent room first (#771)
This commit is contained in:
parent
0b74863c6d
commit
3c2fa40b58
|
@ -1,5 +1,6 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
|
@ -5,7 +5,7 @@ Features ✨:
|
|||
- Enable encryption in unencrypted rooms, from the room settings (#212)
|
||||
|
||||
Improvements 🙌:
|
||||
-
|
||||
- Sharing things to RiotX: sort list by recent room first (#771)
|
||||
|
||||
Other changes:
|
||||
-
|
||||
|
|
|
@ -45,7 +45,8 @@ data class RoomSummary(
|
|||
val readMarkerId: String? = null,
|
||||
val userDrafts: List<UserDraft> = emptyList(),
|
||||
var isEncrypted: Boolean,
|
||||
val typingRoomMemberIds: List<String> = emptyList()
|
||||
val typingRoomMemberIds: List<String> = emptyList(),
|
||||
val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS
|
||||
) {
|
||||
|
||||
val isVersioned: Boolean
|
||||
|
@ -53,4 +54,8 @@ data class RoomSummary(
|
|||
|
||||
val hasNewMessages: Boolean
|
||||
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.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class RoomSummaryMapper @Inject constructor(
|
||||
|
@ -74,7 +74,8 @@ internal class RoomSummaryMapper @Inject constructor(
|
|||
canonicalAlias = roomSummaryEntity.canonicalAlias,
|
||||
aliases = roomSummaryEntity.aliases.toList(),
|
||||
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
|
||||
|
||||
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 io.realm.RealmList
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.PrimaryKey
|
||||
|
||||
internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
||||
var displayName: String? = "",
|
||||
var avatarUrl: String? = "",
|
||||
var topic: String? = "",
|
||||
var latestPreviewableEvent: TimelineEventEntity? = null,
|
||||
var heroes: RealmList<String> = RealmList(),
|
||||
var joinedMembersCount: Int? = 0,
|
||||
var invitedMembersCount: Int? = 0,
|
||||
var isDirect: Boolean = false,
|
||||
var directUserId: String? = null,
|
||||
var otherMemberIds: RealmList<String> = RealmList(),
|
||||
var notificationCount: Int = 0,
|
||||
var highlightCount: Int = 0,
|
||||
var readMarkerId: String? = null,
|
||||
var hasUnreadMessages: Boolean = false,
|
||||
var tags: RealmList<RoomTagEntity> = RealmList(),
|
||||
var userDrafts: UserDraftsEntity? = null,
|
||||
var breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS,
|
||||
var canonicalAlias: String? = null,
|
||||
var aliases: RealmList<String> = RealmList(),
|
||||
// this is required for querying
|
||||
var flatAliases: String = "",
|
||||
var isEncrypted: Boolean = false,
|
||||
var typingUserIds: RealmList<String> = RealmList()
|
||||
internal open class RoomSummaryEntity(
|
||||
@PrimaryKey var roomId: String = "",
|
||||
var displayName: String? = "",
|
||||
var avatarUrl: String? = "",
|
||||
var topic: String? = "",
|
||||
var latestPreviewableEvent: TimelineEventEntity? = null,
|
||||
var heroes: RealmList<String> = RealmList(),
|
||||
var joinedMembersCount: Int? = 0,
|
||||
var invitedMembersCount: Int? = 0,
|
||||
var isDirect: Boolean = false,
|
||||
var directUserId: String? = null,
|
||||
var otherMemberIds: RealmList<String> = RealmList(),
|
||||
var notificationCount: Int = 0,
|
||||
var highlightCount: Int = 0,
|
||||
var readMarkerId: String? = null,
|
||||
var hasUnreadMessages: Boolean = false,
|
||||
var tags: RealmList<RoomTagEntity> = RealmList(),
|
||||
var userDrafts: UserDraftsEntity? = null,
|
||||
var breadcrumbsIndex: Int = RoomSummary.NOT_IN_BREADCRUMBS,
|
||||
var canonicalAlias: String? = null,
|
||||
var aliases: RealmList<String> = RealmList(),
|
||||
// this is required for querying
|
||||
var flatAliases: String = "",
|
||||
var isEncrypted: Boolean = false,
|
||||
var typingUserIds: RealmList<String> = RealmList()
|
||||
) : RealmObject() {
|
||||
|
||||
private var membershipStr: String = Membership.NONE.name
|
||||
|
@ -66,7 +68,5 @@ internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
|||
versioningStateStr = value.name
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val NOT_IN_BREADCRUMBS = -1
|
||||
}
|
||||
companion object
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ internal class DefaultRoomService @Inject constructor(private val monarchy: Mona
|
|||
return RoomSummaryEntity.where(realm)
|
||||
.isNotEmpty(RoomSummaryEntityFields.DISPLAY_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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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.session.events.model.toModel
|
||||
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.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.getOrCreate
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
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.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.UpdateUserAccountDataTask
|
||||
import io.realm.Realm
|
||||
|
@ -177,10 +187,10 @@ internal class UserAccountDataSyncHandler @Inject constructor(
|
|||
// Update the room summaries
|
||||
// Reset all the indexes...
|
||||
RoomSummaryEntity.where(realm)
|
||||
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummaryEntity.NOT_IN_BREADCRUMBS)
|
||||
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummary.NOT_IN_BREADCRUMBS)
|
||||
.findAll()
|
||||
.forEach {
|
||||
it.breadcrumbsIndex = RoomSummaryEntity.NOT_IN_BREADCRUMBS
|
||||
it.breadcrumbsIndex = RoomSummary.NOT_IN_BREADCRUMBS
|
||||
}
|
||||
|
||||
// ...and apply new indexes
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package im.vector.matrix.android.internal.session.user.accountdata
|
||||
|
||||
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.RoomSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
|
||||
|
@ -50,10 +51,10 @@ internal class DefaultSaveBreadcrumbsTask @Inject constructor(
|
|||
// Update the room summaries
|
||||
// Reset all the indexes...
|
||||
RoomSummaryEntity.where(realm)
|
||||
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummaryEntity.NOT_IN_BREADCRUMBS)
|
||||
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummary.NOT_IN_BREADCRUMBS)
|
||||
.findAll()
|
||||
.forEach {
|
||||
it.breadcrumbsIndex = RoomSummaryEntity.NOT_IN_BREADCRUMBS
|
||||
it.breadcrumbsIndex = RoomSummary.NOT_IN_BREADCRUMBS
|
||||
}
|
||||
|
||||
// ...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> {
|
||||
|
||||
override fun compare(leftRoomSummary: RoomSummary?, rightRoomSummary: RoomSummary?): Int {
|
||||
var rightTimestamp = 0L
|
||||
var leftTimestamp = 0L
|
||||
if (null != leftRoomSummary) {
|
||||
leftTimestamp = leftRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
||||
}
|
||||
if (null != rightRoomSummary) {
|
||||
rightTimestamp = rightRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
||||
}
|
||||
return if (rightRoomSummary?.latestPreviewableEvent?.root == null) {
|
||||
-1
|
||||
} else if (leftRoomSummary?.latestPreviewableEvent?.root == null) {
|
||||
1
|
||||
} else {
|
||||
val deltaTimestamp = rightTimestamp - leftTimestamp
|
||||
if (deltaTimestamp > 0) {
|
||||
1
|
||||
} else if (deltaTimestamp < 0) {
|
||||
-1
|
||||
} else {
|
||||
0
|
||||
return when {
|
||||
rightRoomSummary?.latestPreviewableEvent?.root == null -> -1
|
||||
leftRoomSummary?.latestPreviewableEvent?.root == null -> 1
|
||||
else -> {
|
||||
val rightTimestamp = rightRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
||||
val leftTimestamp = leftRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
||||
|
||||
val deltaTimestamp = rightTimestamp - leftTimestamp
|
||||
|
||||
when {
|
||||
deltaTimestamp > 0 -> 1
|
||||
deltaTimestamp < 0 -> -1
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import im.vector.riotx.ActiveSessionDataSource
|
|||
import im.vector.riotx.core.platform.EmptyAction
|
||||
import im.vector.riotx.core.platform.EmptyViewEvents
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
import im.vector.riotx.features.home.room.list.BreadcrumbsRoomComparator
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
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,
|
||||
private val sessionObservableStore: ActiveSessionDataSource,
|
||||
private val shareRoomListObservableStore: ShareRoomListDataSource)
|
||||
private val shareRoomListObservableStore: ShareRoomListDataSource,
|
||||
private val breadcrumbsRoomComparator: BreadcrumbsRoomComparator)
|
||||
: VectorViewModel<IncomingShareState, EmptyAction, EmptyViewEvents>(initialState) {
|
||||
|
||||
@AssistedInject.Factory
|
||||
|
@ -69,6 +71,9 @@ class IncomingShareViewModel @AssistedInject constructor(@Assisted initialState:
|
|||
?: Observable.just(emptyList())
|
||||
}
|
||||
.throttleLast(300, TimeUnit.MILLISECONDS)
|
||||
.map {
|
||||
it.sortedWith(breadcrumbsRoomComparator)
|
||||
}
|
||||
.subscribe {
|
||||
shareRoomListObservableStore.post(it)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue