Old layout: Sort order setting to show unreads on top

Setting is in options menu.
Different setting for home than for spaces, to allow e.g. having unreads on
top only for home.

Change-Id: Ib390a5601ab78ba8372a4c3161311a52d1016b48
This commit is contained in:
SpiritCroc 2022-10-12 17:54:34 +02:00
parent 2d710923a1
commit 6a626ea3be
14 changed files with 226 additions and 25 deletions

View File

@ -200,4 +200,7 @@
<string name="settings_follow_system_locale_summary">When changing the system language, also change the app\'s language</string>
<string name="labs_enable_new_app_layout_summary_sc">Element\'s new simplified layout with optional tabs</string>
<string name="home_layout_preferences_sort_unread">Unread</string>
</resources>

View File

@ -0,0 +1,26 @@
package de.spiritcroc.android.sdk.internal.database.migration
import de.spiritcroc.android.sdk.internal.util.database.ScRealmMigrator
import io.realm.DynamicRealm
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
internal class MigrateScSessionTo007(realm: DynamicRealm) : ScRealmMigrator(realm, 7) {
override fun doMigrate(realm: DynamicRealm) {
realm.schema.get("RoomSummaryEntity")
?.addField(RoomSummaryEntityFields.TREAT_AS_UNREAD_LEVEL, Int::class.java)
?.transform { obj ->
val unreadCount = tryOrNull { obj.getInt(RoomSummaryEntityFields.UNREAD_COUNT) }
val treatAsUnreadLevel = RoomSummaryEntity.calculateUnreadLevel(
obj.getInt(RoomSummaryEntityFields.HIGHLIGHT_COUNT),
obj.getInt(RoomSummaryEntityFields.NOTIFICATION_COUNT),
obj.getBoolean(RoomSummaryEntityFields.MARKED_UNREAD),
unreadCount
)
obj.setInt(RoomSummaryEntityFields.TREAT_AS_UNREAD_LEVEL, treatAsUnreadLevel)
}
?.addIndex(RoomSummaryEntityFields.TREAT_AS_UNREAD_LEVEL)
}
}

View File

@ -30,6 +30,11 @@ enum class RoomSortOrder {
*/
ACTIVITY,
/**
* Show unread above read
*/
UNREAD_AND_ACTIVITY,
/**
* Sort room list by room priority and last activity: favorite room first, low priority room last,
* then descending last activity.

View File

@ -22,6 +22,7 @@ import de.spiritcroc.android.sdk.internal.database.migration.MigrateScSessionTo0
import de.spiritcroc.android.sdk.internal.database.migration.MigrateScSessionTo004
import de.spiritcroc.android.sdk.internal.database.migration.MigrateScSessionTo005
import de.spiritcroc.android.sdk.internal.database.migration.MigrateScSessionTo006
import de.spiritcroc.android.sdk.internal.database.migration.MigrateScSessionTo007
import io.realm.DynamicRealm
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo001
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo002
@ -80,7 +81,7 @@ internal class RealmSessionStoreMigration @Inject constructor(
companion object {
// SC-specific DB changes on top of Element
private val scSchemaVersion = 6L
private val scSchemaVersion = 7L
private val scSchemaVersionOffset = (1L shl 12)
val schemaVersion = 37L +
@ -144,5 +145,6 @@ internal class RealmSessionStoreMigration @Inject constructor(
if (oldScVersion <= 3) MigrateScSessionTo004(realm).perform()
if (oldScVersion <= 4) MigrateScSessionTo005(realm).perform()
if (oldScVersion <= 5) MigrateScSessionTo006(realm).perform()
if (oldScVersion <= 6) MigrateScSessionTo007(realm).perform()
}
}

View File

@ -21,6 +21,7 @@ import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.Index
import io.realm.annotations.PrimaryKey
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
import org.matrix.android.sdk.api.session.room.model.Membership
@ -122,16 +123,19 @@ internal open class RoomSummaryEntity(
var notificationCount: Int = 0
set(value) {
if (value != field) field = value
updateTreatAsUnread()
}
var highlightCount: Int = 0
set(value) {
if (value != field) field = value
updateTreatAsUnread()
}
var unreadCount: Int? = null
set(value) {
if (value != field) field = value
updateTreatAsUnread()
}
/* -> safeUnreadCount
get() {
@ -193,9 +197,25 @@ internal open class RoomSummaryEntity(
var markedUnread: Boolean = false
set(value) {
if (value != field) field = value
if (value != field) {
field = value
updateTreatAsUnread()
}
}
/**
* SchildiChat: Helper var so we can sort depending on how "unread" a chat is: mentions > {notifications, marked unread} > unreads > all read
* Make sure to call `updateTreatAsUnread()` when necessary.
*/
@Index
private var treatAsUnreadLevel: Int = calculateUnreadLevel()
private fun updateTreatAsUnread() {
treatAsUnreadLevel = calculateUnreadLevel()
}
private fun calculateUnreadLevel(): Int {
return calculateUnreadLevel(highlightCount, notificationCount, markedUnread, unreadCount)
}
private var tags: RealmList<RoomTagEntity> = RealmList()
fun tags(): List<RoomTagEntity> = tags
@ -377,7 +397,23 @@ internal open class RoomSummaryEntity(
}
}
companion object
companion object {
private const val UNREAD_LEVEL_HIGHLIGHT = 4
private const val UNREAD_LEVEL_NOTIFIED = 3
private const val UNREAD_LEVEL_MARKED_UNREAD = UNREAD_LEVEL_NOTIFIED
private const val UNREAD_LEVEL_SILENT_UNREAD = 1
private const val UNREAD_LEVEL_NONE = 0
fun calculateUnreadLevel(highlightCount: Int, notificationCount: Int, markedUnread: Boolean, unreadCount: Int?): Int {
return when {
highlightCount > 0 -> UNREAD_LEVEL_HIGHLIGHT
notificationCount > 0 -> UNREAD_LEVEL_NOTIFIED
markedUnread -> UNREAD_LEVEL_MARKED_UNREAD
unreadCount?.let { it > 0 }.orFalse() -> UNREAD_LEVEL_SILENT_UNREAD
else -> UNREAD_LEVEL_NONE
}
}
}
// Keep sync with RoomSummary.scHasUnreadMessages!

View File

@ -30,6 +30,11 @@ internal fun RealmQuery<RoomSummaryEntity>.process(sortOrder: RoomSortOrder): Re
RoomSortOrder.ACTIVITY -> {
sort(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, Sort.DESCENDING)
}
RoomSortOrder.UNREAD_AND_ACTIVITY -> {
sort(
arrayOf(RoomSummaryEntityFields.TREAT_AS_UNREAD_LEVEL, RoomSummaryEntityFields.LAST_ACTIVITY_TIME),
arrayOf(Sort.DESCENDING, Sort.DESCENDING))
}
RoomSortOrder.PRIORITY_AND_ACTIVITY -> {
sort(
arrayOf(

View File

@ -23,8 +23,10 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.core.content.edit
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
@ -74,6 +76,7 @@ import im.vector.app.features.workers.signout.ServerBackupStatusAction
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
import org.matrix.android.sdk.api.session.room.RoomSortOrder
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import timber.log.Timber
import javax.inject.Inject
@ -124,6 +127,7 @@ class HomeDetailFragment :
private var pagerTab: HomeTab? = null
private var pagerPagingEnabled: Boolean = false
private var previousSelectedSpacePair: Pair<RoomSummary?, SelectSpaceFrom>? = null
private var roomSortOrderSettings: RoomSortOrderSettings? = null
override fun getMenuRes() = R.menu.room_list
@ -133,14 +137,64 @@ class HomeDetailFragment :
viewModel.handle(HomeDetailAction.MarkAllRoomsRead)
true
}
R.id.menu_room_sort_order_activity -> {
storeRoomSortOrder(RoomSortOrder.ACTIVITY)
updateViewPager()
true
}
R.id.menu_room_sort_order_unread -> {
storeRoomSortOrder(RoomSortOrder.UNREAD_AND_ACTIVITY)
updateViewPager()
true
}
else -> false
}
}
private fun currentEffectiveSpace(): String? {
return if (pagerPagingEnabled) {
getSpaceIdForPageIndex(views.roomListContainerPager.currentItem)
} else {
SPACE_ID_FOLLOW_APP
}
}
private fun storeRoomSortOrder(roomSortOrder: RoomSortOrder) {
val sharedPreferences = context?.let { PreferenceManager.getDefaultSharedPreferences(it) } ?: return
val space = currentEffectiveSpace()
val pref = if (space == null) VectorPreferences.SETTINGS_ROOM_SORT_ORDER_NULL else VectorPreferences.SETTINGS_ROOM_SORT_ORDER_NON_NULL
sharedPreferences.edit {
putString(pref, roomSortOrder.toString())
}
}
private fun updateViewPager() {
withState(viewModel) {
val selectedSpace = it.selectedSpaceIgnoreSwipe ?: return@withState
spaceStateHandler.persistSelectedSpace()
setupViewPager(selectedSpace, it.rootSpacesOrdered, it.currentTab)
}
}
override fun handlePrepareMenu(menu: Menu) {
withState(viewModel) { state ->
val isRoomList = state.currentTab is HomeTab.RoomList
menu.findItem(R.id.menu_home_mark_all_as_read).isVisible = isRoomList && hasUnreadRooms
menu.findItem(R.id.menu_room_sort_order).isVisible = true
// Room sort order
val space = currentEffectiveSpace()
val roomSortOrder =
if (space == null) {
roomSortOrderSettings?.nullSpace
} else {
roomSortOrderSettings?.space
}
when (roomSortOrder) {
RoomSortOrder.ACTIVITY -> menu.findItem(R.id.menu_room_sort_order_activity).isChecked = true
RoomSortOrder.UNREAD_AND_ACTIVITY -> menu.findItem(R.id.menu_room_sort_order_unread).isChecked = true
else -> Unit
}
}
}
@ -605,10 +659,11 @@ class HomeDetailFragment :
views.spaceBarRecyclerView.isVisible = false
}
val safeSpaces = if (pagingEnabled) unsafeSpaces else listOf()
val newRoomSortOrderSettings = loadRoomSortOrderSettings()
// Check if we need to recreate the adapter for a new tab
if (oldAdapter != null) {
val changed = pagerTab != tab || pagerSpaces != safeSpaces || pagerPagingEnabled != pagingEnabled
viewPagerDimber.i{ "has changed: $changed (${pagerTab != tab} ${pagerSpaces != safeSpaces} ${pagerPagingEnabled != pagingEnabled} $selectedIndex ${selectedSpacePair.second} ${views.roomListContainerPager.currentItem}) | $safeSpaces" }
val changed = pagerTab != tab || pagerSpaces != safeSpaces || pagerPagingEnabled != pagingEnabled || roomSortOrderSettings != newRoomSortOrderSettings
viewPagerDimber.i{ "has changed: $changed (${pagerTab != tab} ${pagerSpaces != safeSpaces} ${pagerPagingEnabled != pagingEnabled} ${roomSortOrderSettings != newRoomSortOrderSettings} $selectedIndex ${selectedSpacePair.second} ${views.roomListContainerPager.currentItem}) | $safeSpaces" }
if (!changed) {
// No need to re-setup pager, just check for selected page
if (pagingEnabled) {
@ -653,6 +708,7 @@ class HomeDetailFragment :
spaceStateHandler.persistSelectedSpace()
pagerSpaces = safeSpaces
pagerTab = tab
roomSortOrderSettings = newRoomSortOrderSettings
if (pagerPagingEnabled != pagingEnabled) {
pagerPagingEnabled = pagingEnabled
// Update counts which depend on pagerPagingEnabled
@ -691,10 +747,10 @@ class HomeDetailFragment :
val params = if (pagingEnabled) {
val spaceId = getSpaceIdForPageIndex(position)
viewPagerDimber.i{"Home pager: position $position -> space $spaceId"}
RoomListParams(tab.displayMode, spaceId).toMvRxBundle()
RoomListParams(tab.displayMode, spaceId, getRoomSortOrder(spaceId)).toMvRxBundle()
} else {
viewPagerDimber.i{"Home pager: paging disabled; position $position -> follow"}
RoomListParams(tab.displayMode, SPACE_ID_FOLLOW_APP).toMvRxBundle()
RoomListParams(tab.displayMode, SPACE_ID_FOLLOW_APP, getRoomSortOrder(SPACE_ID_FOLLOW_APP)).toMvRxBundle()
}
childFragmentManager.fragmentFactory.instantiate(activity!!.classLoader, RoomListFragment::class.java.name).apply {
arguments = params
@ -753,6 +809,26 @@ class HomeDetailFragment :
return if (position == 0) null else spaces[position-1]
}
data class RoomSortOrderSettings(val nullSpace: RoomSortOrder, val space: RoomSortOrder)
private fun loadRoomSortOrderSettings(): RoomSortOrderSettings? {
val sharedPreferences = context?.let { PreferenceManager.getDefaultSharedPreferences(it) } ?: return null
val default = RoomSortOrder.ACTIVITY
return RoomSortOrderSettings(
tryOrNull { sharedPreferences.getString(VectorPreferences.SETTINGS_ROOM_SORT_ORDER_NULL, null)?.let { RoomSortOrder.valueOf(it) } } ?: default,
tryOrNull { sharedPreferences.getString(VectorPreferences.SETTINGS_ROOM_SORT_ORDER_NON_NULL, null)?.let { RoomSortOrder.valueOf(it) } } ?: default,
)
}
private fun getRoomSortOrder(space: String?): RoomSortOrder {
return (
if (space == null)
roomSortOrderSettings?.nullSpace
else
roomSortOrderSettings?.space
) ?: RoomSortOrder.ACTIVITY
}
private fun createDialPadFragment(): Fragment {
val fragment = childFragmentManager.fragmentFactory.instantiate(vectorBaseActivity.classLoader, DialPadFragment::class.java.name)
return (fragment as DialPadFragment).apply {

View File

@ -123,6 +123,7 @@ class NewHomeDetailFragment :
val isRoomList = state.currentTab is HomeTab.RoomList
menu.findItem(R.id.menu_home_mark_all_as_read).isVisible = isRoomList && hasUnreadRooms
menu.findItem(R.id.menu_home_dialpad).isVisible = state.showDialPadTab
menu.findItem(R.id.menu_room_sort_order).isVisible = false
}
}

View File

@ -68,6 +68,8 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.extensions.orTrue
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.room.RoomSortOrder
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
@ -77,7 +79,8 @@ import javax.inject.Inject
@Parcelize
data class RoomListParams(
val displayMode: RoomListDisplayMode,
val explicitSpaceId: String? = SPACE_ID_FOLLOW_APP
val explicitSpaceId: String? = SPACE_ID_FOLLOW_APP,
val roomSortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY
) : Parcelable
@AndroidEntryPoint

View File

@ -51,6 +51,7 @@ import org.matrix.android.sdk.api.query.toActiveSpaceOrNoFilter
import org.matrix.android.sdk.api.query.toActiveSpaceOrOrphanRooms
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.getRoomSummary
import org.matrix.android.sdk.api.session.room.RoomSortOrder
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult
import org.matrix.android.sdk.api.session.room.model.Membership
@ -82,28 +83,28 @@ class RoomListSectionBuilder(
private val dimber = Dimber("ViewPager", DbgUtil.DBG_VIEW_PAGER)
fun buildSections(mode: RoomListDisplayMode, explicitSpaceId: String?): List<RoomsSection> {
fun buildSections(mode: RoomListDisplayMode, explicitSpaceId: String?, sortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY): List<RoomsSection> {
dimber.i { "Build sections for $mode, $explicitSpaceId" }
val sections = mutableListOf<RoomsSection>()
val activeSpaceAwareQueries = mutableListOf<RoomListViewModel.ActiveSpaceQueryUpdater>()
when (mode) {
RoomListDisplayMode.PEOPLE -> {
// 4 sections Invites / Fav / Dms / Low Priority
buildDmSections(sections, activeSpaceAwareQueries, explicitSpaceId)
buildDmSections(sections, activeSpaceAwareQueries, explicitSpaceId, sortOrder)
}
RoomListDisplayMode.ROOMS -> {
// 6 sections invites / Fav / Rooms / Low Priority / Server notice / Suggested rooms
buildRoomsSections(sections, activeSpaceAwareQueries, explicitSpaceId)
buildRoomsSections(sections, activeSpaceAwareQueries, explicitSpaceId, sortOrder)
}
RoomListDisplayMode.ALL -> {
buildUnifiedSections(sections, activeSpaceAwareQueries, explicitSpaceId)
buildUnifiedSections(sections, activeSpaceAwareQueries, explicitSpaceId, sortOrder)
}
RoomListDisplayMode.FILTERED -> {
// Used when searching for rooms
buildFilteredSection(sections)
}
RoomListDisplayMode.NOTIFICATIONS -> {
buildNotificationsSection(sections, activeSpaceAwareQueries, explicitSpaceId)
buildNotificationsSection(sections, activeSpaceAwareQueries, explicitSpaceId, sortOrder)
}
}
@ -125,13 +126,14 @@ class RoomListSectionBuilder(
return sections
}
private fun buildUnifiedSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>, explicitSpaceId: String?) {
private fun buildUnifiedSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>, explicitSpaceId: String?, sortOrder: RoomSortOrder) {
addSection(
sections = sections,
activeSpaceUpdaters = activeSpaceAwareQueries,
nameRes = R.string.invitations_header,
notifyOfLocalEcho = true,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL,
countRoomAsNotif = true
) {
@ -149,6 +151,7 @@ class RoomListSectionBuilder(
RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL
},
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder
) {
it.memberships = listOf(Membership.JOIN)
it.roomTagQueryFilter = RoomTagQueryFilter(true, null, null)
@ -160,6 +163,7 @@ class RoomListSectionBuilder(
nameRes = R.string.normal_priority_header,
notifyOfLocalEcho = false,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = if (onlyOrphansInHome) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL
} else {
@ -176,6 +180,7 @@ class RoomListSectionBuilder(
nameRes = R.string.low_priority_header,
notifyOfLocalEcho = false,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = if (onlyOrphansInHome) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL
} else {
@ -192,6 +197,7 @@ class RoomListSectionBuilder(
nameRes = R.string.system_alerts_header,
notifyOfLocalEcho = false,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = if (onlyOrphansInHome) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL
} else {
@ -208,7 +214,8 @@ class RoomListSectionBuilder(
private fun buildRoomsSections(
sections: MutableList<RoomsSection>,
activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>,
explicitSpaceId: String?
explicitSpaceId: String?,
sortOrder: RoomSortOrder
) {
if (autoAcceptInvites.showInvites()) {
addSection(
@ -217,6 +224,7 @@ class RoomListSectionBuilder(
nameRes = R.string.invitations_header,
notifyOfLocalEcho = true,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL,
countRoomAsNotif = true
) {
@ -236,6 +244,7 @@ class RoomListSectionBuilder(
RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL
},
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder
) {
it.memberships = listOf(Membership.JOIN)
it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS
@ -248,6 +257,7 @@ class RoomListSectionBuilder(
nameRes = R.string.bottom_action_rooms,
notifyOfLocalEcho = false,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = if (onlyOrphansInHome) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL
} else {
@ -265,6 +275,7 @@ class RoomListSectionBuilder(
nameRes = R.string.low_priority_header,
notifyOfLocalEcho = false,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = if (onlyOrphansInHome) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL
} else {
@ -282,6 +293,7 @@ class RoomListSectionBuilder(
nameRes = R.string.system_alerts_header,
notifyOfLocalEcho = false,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = if (onlyOrphansInHome) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL
} else {
@ -366,7 +378,8 @@ class RoomListSectionBuilder(
private fun buildDmSections(
sections: MutableList<RoomsSection>,
activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>,
explicitSpaceId: String?
explicitSpaceId: String?,
sortOrder: RoomSortOrder
) {
if (autoAcceptInvites.showInvites()) {
addSection(
@ -375,6 +388,7 @@ class RoomListSectionBuilder(
nameRes = R.string.invitations_header,
notifyOfLocalEcho = true,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = if (onlyOrphansInHome) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL
} else {
@ -397,7 +411,8 @@ class RoomListSectionBuilder(
} else {
RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL
},
explicitSpaceId = explicitSpaceId
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder
) {
it.memberships = listOf(Membership.JOIN)
it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM
@ -414,7 +429,8 @@ class RoomListSectionBuilder(
} else {
RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL
},
explicitSpaceId = explicitSpaceId
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder
) {
it.memberships = listOf(Membership.JOIN)
it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM
@ -431,7 +447,8 @@ class RoomListSectionBuilder(
} else {
RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL
},
explicitSpaceId = explicitSpaceId
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder
) {
it.memberships = listOf(Membership.JOIN)
it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM
@ -451,7 +468,8 @@ class RoomListSectionBuilder(
private fun buildNotificationsSection(
sections: MutableList<RoomsSection>,
activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>,
explicitSpaceId: String?
explicitSpaceId: String?,
sortOrder: RoomSortOrder
) {
if (autoAcceptInvites.showInvites()) {
addSection(
@ -460,6 +478,7 @@ class RoomListSectionBuilder(
nameRes = R.string.invitations_header,
notifyOfLocalEcho = true,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = if (onlyOrphansInHome) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL
} else {
@ -477,6 +496,7 @@ class RoomListSectionBuilder(
nameRes = R.string.bottom_action_rooms,
notifyOfLocalEcho = false,
explicitSpaceId = explicitSpaceId,
sortOrder = sortOrder,
spaceFilterStrategy = if (onlyOrphansInHome) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL
} else {
@ -522,6 +542,7 @@ class RoomListSectionBuilder(
spaceFilterStrategy: RoomListViewModel.SpaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.NONE,
countRoomAsNotif: Boolean = false,
explicitSpaceId: String?,
sortOrder: RoomSortOrder,
query: (RoomSummaryQueryParams.Builder) -> Unit
) {
withQueryParams(query) { roomQueryParams ->
@ -537,7 +558,8 @@ class RoomListSectionBuilder(
val name = stringProvider.getString(nameRes)
val filteredPagedRoomSummariesLive = session.roomService().getFilteredPagedRoomSummariesLive(
roomQueryParams.process(spaceFilterStrategy, spaceStateHandler.explicitOrSafeActiveSpaceId(explicitSpaceId)),
pagedListConfig
pagedListConfig,
sortOrder
)
when (spaceFilterStrategy) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL -> {

View File

@ -47,6 +47,7 @@ import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.getRoomSummary
import org.matrix.android.sdk.api.session.room.RoomSortOrder
import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
@ -152,8 +153,8 @@ class RoomListViewModel @AssistedInject constructor(
)
val sections: List<RoomsSection> by lazy {
viewPagerDimber.i { "Build sections for ${initialState.displayMode}, ${initialState.explicitSpaceId}" }
roomListSectionBuilder.buildSections(initialState.displayMode, initialState.explicitSpaceId)
viewPagerDimber.i { "Build sections for ${initialState.displayMode}, ${initialState.explicitSpaceId} ${initialState.roomSortOrder}" }
roomListSectionBuilder.buildSections(initialState.displayMode, initialState.explicitSpaceId, initialState.roomSortOrder)
}
override fun handle(action: RoomListAction) {

View File

@ -20,6 +20,7 @@ import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.Uninitialized
import im.vector.app.features.home.RoomListDisplayMode
import org.matrix.android.sdk.api.session.room.RoomSortOrder
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
@ -32,8 +33,9 @@ data class RoomListViewState(
val currentUserName: String? = null,
val asyncSelectedSpace: Async<RoomSummary?> = Uninitialized,
// In comparison to currentRoomGrouping, the explicit space id fixes a filter method that should not change afterwards
val explicitSpaceId: String? = null
val explicitSpaceId: String? = null,
val roomSortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY,
) : MavericksState {
constructor(args: RoomListParams) : this(displayMode = args.displayMode, explicitSpaceId = args.explicitSpaceId)
constructor(args: RoomListParams) : this(displayMode = args.displayMode, explicitSpaceId = args.explicitSpaceId, roomSortOrder = args.roomSortOrder)
}

View File

@ -248,6 +248,8 @@ class VectorPreferences @Inject constructor(
private const val SETTINGS_SPACE_BACK_NAVIGATION = "SETTINGS_SPACE_BACK_NAVIGATION"
const val SETTINGS_FOLLOW_SYSTEM_LOCALE = "SETTINGS_FOLLOW_SYSTEM_LOCALE"
const val SETTINGS_FORCE_ALLOW_BACKGROUND_SYNC = "SETTINGS_FORCE_ALLOW_BACKGROUND_SYNC"
const val SETTINGS_ROOM_SORT_ORDER_NULL = "SETTINGS_ROOM_SORT_ORDER_NULL"
const val SETTINGS_ROOM_SORT_ORDER_NON_NULL = "SETTINGS_ROOM_SORT_ORDER_NON_NULL"
private const val DID_ASK_TO_ENABLE_SESSION_PUSH = "DID_ASK_TO_ENABLE_SESSION_PUSH"

View File

@ -14,4 +14,21 @@
android:visible="false"
app:showAsAction="never"
tools:visible="true" />
<item
android:id="@+id/menu_room_sort_order"
android:title="@string/home_layout_preferences_sort_by"
app:showAsAction="never">
<menu>
<group
android:checkableBehavior="single">
<item
android:id="@+id/menu_room_sort_order_activity"
android:title="@string/home_layout_preferences_sort_activity" />
<item
android:id="@+id/menu_room_sort_order_unread"
android:title="@string/home_layout_preferences_sort_unread" />
</group>
</menu>
</item>
</menu>