Add section header when displaying room list to share (#771)

This commit is contained in:
Benoit Marty 2020-01-21 19:02:41 +01:00
parent 3c2fa40b58
commit c971f18fc0
5 changed files with 132 additions and 69 deletions

View File

@ -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.riotx.core.platform.VectorViewModel
import im.vector.riotx.core.utils.DataSource
import im.vector.riotx.features.home.RoomListDisplayMode
import io.reactivex.schedulers.Schedulers
import timber.log.Timber
import javax.inject.Inject
@ -202,35 +203,54 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
}
private fun buildRoomSummaries(rooms: List<RoomSummary>): RoomSummaries {
// Set up init size on directChats and groupRooms as they are the biggest ones
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>()
if (displayMode == RoomListDisplayMode.SHARE) {
val recentRooms = ArrayList<RoomSummary>(20)
val otherRooms = ArrayList<RoomSummary>(rooms.size)
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)
rooms
.filter { roomListDisplayModeFilter.test(it) }
.forEach { room ->
when (room.breadcrumbsIndex) {
RoomSummary.NOT_IN_BREADCRUMBS -> otherRooms.add(room)
else -> recentRooms.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)
return RoomSummaries().apply {
put(RoomCategory.RECENT_ROOMS, recentRooms)
put(RoomCategory.OTHER_ROOMS, otherRooms)
}
} else {
// Set up init size on directChats and groupRooms as they are the biggest ones
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)
}
}
}
}

View File

@ -43,7 +43,10 @@ data class RoomListViewState(
val isDirectRoomsExpanded: Boolean = true,
val isGroupRoomsExpanded: 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 {
constructor(args: RoomListParams) : this(displayMode = args.displayMode)
@ -56,6 +59,8 @@ data class RoomListViewState(
RoomCategory.GROUP -> isGroupRoomsExpanded
RoomCategory.LOW_PRIORITY -> isLowPriorityRoomsExpanded
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.LOW_PRIORITY -> copy(isLowPriorityRoomsExpanded = !isLowPriorityRoomsExpanded)
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),
GROUP(R.string.bottom_action_rooms),
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 {

View File

@ -59,39 +59,9 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
override fun buildModels() {
val nonNullViewState = viewState ?: return
when (nonNullViewState.displayMode) {
RoomListDisplayMode.FILTERED,
RoomListDisplayMode.SHARE -> {
buildFilteredRooms(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()
}
}
RoomListDisplayMode.FILTERED -> buildFilteredRooms(nonNullViewState)
RoomListDisplayMode.SHARE -> buildShareRooms(nonNullViewState)
else -> buildRooms(nonNullViewState)
}
}
@ -109,9 +79,69 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
viewState.rejectingRoomsIds,
viewState.rejectingErrorRoomsIds)
when {
viewState.displayMode == RoomListDisplayMode.FILTERED -> addFilterFooter(viewState)
filteredSummaries.isEmpty() -> addEmptyFooter()
addFilterFooter(viewState)
}
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 {
id("no_result")
text(stringProvider.getString(R.string.no_result_placeholder))
@ -142,9 +172,6 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
@StringRes titleRes: Int,
isExpanded: Boolean,
mutateExpandedState: () -> Unit) {
if (summaries.isEmpty()) {
return
}
// TODO should add some business logic later
val unreadCount = if (summaries.isEmpty()) {
0

View File

@ -44,7 +44,9 @@ class IncomingShareActivity :
@Inject lateinit var sessionHolder: ActiveSessionHolder
@Inject lateinit var incomingShareViewModelFactory: IncomingShareViewModel.Factory
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?
get() {
return supportFragmentManager.findFragmentById(R.id.shareRoomListFragmentContainer) as? RoomListFragment

View File

@ -34,6 +34,9 @@
<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.) -->
<string name="settings_category_timeline">Timeline</string>