filtered room list at home (#6724)
This commit is contained in:
parent
fa8f72c909
commit
e0e21d4282
|
@ -0,0 +1 @@
|
||||||
|
added filter tabs for new App layout's Home screen
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="Widget.Vector.TabLayout" parent="Widget.MaterialComponents.TabLayout">
|
||||||
|
<item name="materialThemeOverlay">@style/ThemeOverlay.Vector.HomeFilterTabLayout</item>
|
||||||
|
<item name="tabTextAppearance">@style/TextAppearance.Vector.FilterTabTextAppearance</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="TextAppearance.Vector.FilterTabTextAppearance" parent="TextAppearance.Vector.Subtitle">
|
||||||
|
<item name="textAllCaps">false</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="ThemeOverlay.Vector.HomeFilterTabLayout" parent="Theme.Vector.Launcher">
|
||||||
|
<item name="colorSurface">?vctr_toolbar_background</item>
|
||||||
|
<item name="colorOnSurface">?vctr_content_secondary</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -17,6 +17,7 @@
|
||||||
package im.vector.app.features.home.room.list.home
|
package im.vector.app.features.home.room.list.home
|
||||||
|
|
||||||
import im.vector.app.core.platform.VectorViewModelAction
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
|
import im.vector.app.features.home.room.list.home.filter.HomeRoomFilter
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
|
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
|
||||||
|
|
||||||
|
@ -25,4 +26,5 @@ sealed class HomeRoomListAction : VectorViewModelAction {
|
||||||
data class ChangeRoomNotificationState(val roomId: String, val notificationState: RoomNotificationState) : HomeRoomListAction()
|
data class ChangeRoomNotificationState(val roomId: String, val notificationState: RoomNotificationState) : HomeRoomListAction()
|
||||||
data class ToggleTag(val roomId: String, val tag: String) : HomeRoomListAction()
|
data class ToggleTag(val roomId: String, val tag: String) : HomeRoomListAction()
|
||||||
data class LeaveRoom(val roomId: String) : HomeRoomListAction()
|
data class LeaveRoom(val roomId: String) : HomeRoomListAction()
|
||||||
|
data class ChangeRoomFilter(val filter: HomeRoomFilter) : HomeRoomListAction()
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,14 +37,14 @@ import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.core.resources.UserPreferencesProvider
|
import im.vector.app.core.resources.UserPreferencesProvider
|
||||||
import im.vector.app.databinding.FragmentRoomListBinding
|
import im.vector.app.databinding.FragmentRoomListBinding
|
||||||
import im.vector.app.features.analytics.plan.ViewRoom
|
import im.vector.app.features.analytics.plan.ViewRoom
|
||||||
import im.vector.app.features.home.RoomListDisplayMode
|
|
||||||
import im.vector.app.features.home.room.list.RoomListAnimator
|
import im.vector.app.features.home.room.list.RoomListAnimator
|
||||||
import im.vector.app.features.home.room.list.RoomListListener
|
import im.vector.app.features.home.room.list.RoomListListener
|
||||||
import im.vector.app.features.home.room.list.RoomSummaryItemFactory
|
import im.vector.app.features.home.room.list.RoomSummaryItemFactory
|
||||||
import im.vector.app.features.home.room.list.RoomSummaryPagedController
|
|
||||||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
|
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
|
||||||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction
|
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction
|
||||||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
|
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
|
||||||
|
import im.vector.app.features.home.room.list.home.filter.HomeFilteredRoomsController
|
||||||
|
import im.vector.app.features.home.room.list.home.filter.HomeRoomFilter
|
||||||
import im.vector.app.features.home.room.list.home.recent.RecentRoomCarouselController
|
import im.vector.app.features.home.room.list.home.recent.RecentRoomCarouselController
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
@ -207,28 +207,36 @@ class HomeRoomListFragment @Inject constructor(
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAdapterForData(data: HomeRoomSection): EpoxyControllerAdapter {
|
private fun getAdapterForData(section: HomeRoomSection): EpoxyControllerAdapter {
|
||||||
return when (data) {
|
return when (section) {
|
||||||
is HomeRoomSection.RoomSummaryData -> {
|
is HomeRoomSection.RoomSummaryData -> {
|
||||||
RoomSummaryPagedController(
|
HomeFilteredRoomsController(
|
||||||
roomSummaryItemFactory,
|
roomSummaryItemFactory,
|
||||||
RoomListDisplayMode.ROOMS
|
showFilters = section.showFilters,
|
||||||
).also { controller ->
|
).also { controller ->
|
||||||
controller.listener = this
|
controller.listener = this
|
||||||
data.list.observe(viewLifecycleOwner) { list ->
|
controller.onFilterChanged = ::onRoomFilterChanged
|
||||||
|
section.filtersData.onEach {
|
||||||
|
controller.submitFiltersData(it)
|
||||||
|
}.launchIn(lifecycleScope)
|
||||||
|
section.list.observe(viewLifecycleOwner) { list ->
|
||||||
controller.submitList(list)
|
controller.submitList(list)
|
||||||
}
|
}
|
||||||
}.adapter
|
}.adapter
|
||||||
}
|
}
|
||||||
is HomeRoomSection.RecentRoomsData -> recentRoomCarouselController.also { controller ->
|
is HomeRoomSection.RecentRoomsData -> recentRoomCarouselController.also { controller ->
|
||||||
controller.listener = this
|
controller.listener = this
|
||||||
data.list.observe(viewLifecycleOwner) { list ->
|
section.list.observe(viewLifecycleOwner) { list ->
|
||||||
controller.submitList(list)
|
controller.submitList(list)
|
||||||
}
|
}
|
||||||
}.adapter
|
}.adapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onRoomFilterChanged(filter: HomeRoomFilter) {
|
||||||
|
roomListViewModel.handle(HomeRoomListAction.ChangeRoomFilter(filter))
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleSelectRoom(event: HomeRoomListViewEvents.SelectRoom, isInviteAlreadyAccepted: Boolean) {
|
private fun handleSelectRoom(event: HomeRoomListViewEvents.SelectRoom, isInviteAlreadyAccepted: Boolean) {
|
||||||
navigator.openRoom(
|
navigator.openRoom(
|
||||||
context = requireActivity(),
|
context = requireActivity(),
|
||||||
|
|
|
@ -27,33 +27,38 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.platform.StateView
|
import im.vector.app.core.platform.StateView
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.home.room.list.home.filter.HomeRoomFilter
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import org.matrix.android.sdk.api.query.SpaceFilter
|
import org.matrix.android.sdk.api.query.RoomCategoryFilter
|
||||||
|
import org.matrix.android.sdk.api.query.RoomTagQueryFilter
|
||||||
import org.matrix.android.sdk.api.query.toActiveSpaceOrNoFilter
|
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.Session
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
|
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.RoomSummaryQueryParams
|
||||||
|
import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
|
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
|
||||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.state.isPublic
|
import org.matrix.android.sdk.api.session.room.state.isPublic
|
||||||
|
import org.matrix.android.sdk.flow.flow
|
||||||
|
|
||||||
class HomeRoomListViewModel @AssistedInject constructor(
|
class HomeRoomListViewModel @AssistedInject constructor(
|
||||||
@Assisted initialState: HomeRoomListViewState,
|
@Assisted initialState: HomeRoomListViewState,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val spaceStateHandler: SpaceStateHandler,
|
private val spaceStateHandler: SpaceStateHandler,
|
||||||
private val vectorPreferences: VectorPreferences,
|
|
||||||
) : VectorViewModel<HomeRoomListViewState, HomeRoomListAction, HomeRoomListViewEvents>(initialState) {
|
) : VectorViewModel<HomeRoomListViewState, HomeRoomListAction, HomeRoomListViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
@ -73,6 +78,8 @@ class HomeRoomListViewModel @AssistedInject constructor(
|
||||||
private val _sections = MutableSharedFlow<Set<HomeRoomSection>>(replay = 1)
|
private val _sections = MutableSharedFlow<Set<HomeRoomSection>>(replay = 1)
|
||||||
val sections = _sections.asSharedFlow()
|
val sections = _sections.asSharedFlow()
|
||||||
|
|
||||||
|
private var filteredPagedRoomSummariesLive: UpdatableLivePageResult? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
configureSections()
|
configureSections()
|
||||||
}
|
}
|
||||||
|
@ -81,7 +88,7 @@ class HomeRoomListViewModel @AssistedInject constructor(
|
||||||
val newSections = mutableSetOf<HomeRoomSection>()
|
val newSections = mutableSetOf<HomeRoomSection>()
|
||||||
|
|
||||||
newSections.add(getRecentRoomsSection())
|
newSections.add(getRecentRoomsSection())
|
||||||
newSections.add(getAllRoomsSection())
|
newSections.add(getFilteredRoomsSection())
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_sections.emit(newSections)
|
_sections.emit(newSections)
|
||||||
|
@ -104,15 +111,21 @@ class HomeRoomListViewModel @AssistedInject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAllRoomsSection(): HomeRoomSection.RoomSummaryData {
|
private fun getFilteredRoomsSection(): HomeRoomSection.RoomSummaryData {
|
||||||
val builder = RoomSummaryQueryParams.Builder().also {
|
val builder = RoomSummaryQueryParams.Builder().also {
|
||||||
it.memberships = listOf(Membership.JOIN)
|
it.memberships = listOf(Membership.JOIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
val filteredPagedRoomSummariesLive = session.roomService().getFilteredPagedRoomSummariesLive(
|
val params = getFilteredQueryParams(HomeRoomFilter.ALL, builder.build())
|
||||||
builder.build(),
|
val sortOrder = RoomSortOrder.ACTIVITY // #6506
|
||||||
pagedListConfig
|
|
||||||
)
|
val liveResults = session.roomService().getFilteredPagedRoomSummariesLive(
|
||||||
|
params,
|
||||||
|
pagedListConfig,
|
||||||
|
sortOrder
|
||||||
|
).also {
|
||||||
|
this.filteredPagedRoomSummariesLive = it
|
||||||
|
}
|
||||||
|
|
||||||
spaceStateHandler.getSelectedSpaceFlow()
|
spaceStateHandler.getSelectedSpaceFlow()
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
|
@ -121,20 +134,83 @@ class HomeRoomListViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
.onEach { selectedSpaceOption ->
|
.onEach { selectedSpaceOption ->
|
||||||
val selectedSpace = selectedSpaceOption.orNull()
|
val selectedSpace = selectedSpaceOption.orNull()
|
||||||
filteredPagedRoomSummariesLive.queryParams = filteredPagedRoomSummariesLive.queryParams.copy(
|
liveResults.queryParams = liveResults.queryParams.copy(
|
||||||
spaceFilter = getSpaceFilter(selectedSpaceId = selectedSpace?.roomId)
|
spaceFilter = selectedSpace?.roomId.toActiveSpaceOrNoFilter()
|
||||||
)
|
)
|
||||||
}.launchIn(viewModelScope)
|
}.launchIn(viewModelScope)
|
||||||
|
|
||||||
return HomeRoomSection.RoomSummaryData(
|
return HomeRoomSection.RoomSummaryData(
|
||||||
list = filteredPagedRoomSummariesLive.livePagedList
|
list = liveResults.livePagedList,
|
||||||
|
showFilters = true, // #6506
|
||||||
|
filtersData = getFiltersDataFlow()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSpaceFilter(selectedSpaceId: String?): SpaceFilter {
|
private fun getFiltersDataFlow(): SharedFlow<List<HomeRoomFilter>> {
|
||||||
return when {
|
val flow = MutableSharedFlow<List<HomeRoomFilter>>(replay = 1)
|
||||||
vectorPreferences.prefSpacesShowAllRoomInHome() -> selectedSpaceId.toActiveSpaceOrNoFilter()
|
|
||||||
else -> selectedSpaceId.toActiveSpaceOrOrphanRooms()
|
val favouritesFlow = session.flow()
|
||||||
|
.liveRoomSummaries(
|
||||||
|
RoomSummaryQueryParams.Builder().also { builder ->
|
||||||
|
builder.roomTagQueryFilter = RoomTagQueryFilter(true, null, null)
|
||||||
|
}.build()
|
||||||
|
)
|
||||||
|
.map { it.isNotEmpty() }
|
||||||
|
.distinctUntilChanged()
|
||||||
|
|
||||||
|
val dmsFLow = session.flow()
|
||||||
|
.liveRoomSummaries(
|
||||||
|
RoomSummaryQueryParams.Builder().also { builder ->
|
||||||
|
builder.memberships = listOf(Membership.JOIN)
|
||||||
|
builder.roomCategoryFilter = RoomCategoryFilter.ONLY_DM
|
||||||
|
}.build()
|
||||||
|
)
|
||||||
|
.map { it.isNotEmpty() }
|
||||||
|
.distinctUntilChanged()
|
||||||
|
|
||||||
|
favouritesFlow.combine(dmsFLow) { hasFavourite, hasDm ->
|
||||||
|
hasFavourite to hasDm
|
||||||
|
}.onEach { (hasFavourite, hasDm) ->
|
||||||
|
val filtersData = mutableListOf(
|
||||||
|
HomeRoomFilter.ALL,
|
||||||
|
HomeRoomFilter.UNREADS
|
||||||
|
)
|
||||||
|
if (hasFavourite) {
|
||||||
|
filtersData.add(
|
||||||
|
HomeRoomFilter.FAVOURITES
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (hasDm) {
|
||||||
|
filtersData.add(
|
||||||
|
HomeRoomFilter.PEOPlE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
flow.emit(filtersData)
|
||||||
|
}.launchIn(viewModelScope)
|
||||||
|
|
||||||
|
return flow
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFilteredQueryParams(filter: HomeRoomFilter, currentParams: RoomSummaryQueryParams): RoomSummaryQueryParams {
|
||||||
|
return when (filter) {
|
||||||
|
HomeRoomFilter.ALL -> currentParams.copy(
|
||||||
|
roomCategoryFilter = null,
|
||||||
|
roomTagQueryFilter = null
|
||||||
|
)
|
||||||
|
HomeRoomFilter.UNREADS -> currentParams.copy(
|
||||||
|
roomCategoryFilter = RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS,
|
||||||
|
roomTagQueryFilter = RoomTagQueryFilter(null, false, null)
|
||||||
|
)
|
||||||
|
HomeRoomFilter.FAVOURITES ->
|
||||||
|
currentParams.copy(
|
||||||
|
roomCategoryFilter = null,
|
||||||
|
roomTagQueryFilter = RoomTagQueryFilter(true, null, null)
|
||||||
|
)
|
||||||
|
HomeRoomFilter.PEOPlE -> currentParams.copy(
|
||||||
|
roomCategoryFilter = RoomCategoryFilter.ONLY_DM,
|
||||||
|
roomTagQueryFilter = null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +220,13 @@ class HomeRoomListViewModel @AssistedInject constructor(
|
||||||
is HomeRoomListAction.LeaveRoom -> handleLeaveRoom(action)
|
is HomeRoomListAction.LeaveRoom -> handleLeaveRoom(action)
|
||||||
is HomeRoomListAction.ChangeRoomNotificationState -> handleChangeNotificationMode(action)
|
is HomeRoomListAction.ChangeRoomNotificationState -> handleChangeNotificationMode(action)
|
||||||
is HomeRoomListAction.ToggleTag -> handleToggleTag(action)
|
is HomeRoomListAction.ToggleTag -> handleToggleTag(action)
|
||||||
|
is HomeRoomListAction.ChangeRoomFilter -> handleChangeRoomFilter(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleChangeRoomFilter(action: HomeRoomListAction.ChangeRoomFilter) {
|
||||||
|
filteredPagedRoomSummariesLive?.let { liveResults ->
|
||||||
|
liveResults.queryParams = getFilteredQueryParams(action.filter, liveResults.queryParams)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,15 @@ package im.vector.app.features.home.room.list.home
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
|
import im.vector.app.features.home.room.list.home.filter.HomeRoomFilter
|
||||||
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
|
||||||
sealed class HomeRoomSection {
|
sealed class HomeRoomSection {
|
||||||
data class RoomSummaryData(
|
data class RoomSummaryData(
|
||||||
val list: LiveData<PagedList<RoomSummary>>
|
val list: LiveData<PagedList<RoomSummary>>,
|
||||||
|
val showFilters: Boolean,
|
||||||
|
val filtersData: SharedFlow<List<HomeRoomFilter>>
|
||||||
) : HomeRoomSection()
|
) : HomeRoomSection()
|
||||||
|
|
||||||
data class RecentRoomsData(
|
data class RecentRoomsData(
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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.app.features.home.room.list.home.filter
|
||||||
|
|
||||||
|
import com.airbnb.epoxy.EpoxyModel
|
||||||
|
import com.airbnb.epoxy.paging.PagedListEpoxyController
|
||||||
|
import im.vector.app.core.utils.createUIHandler
|
||||||
|
import im.vector.app.features.home.RoomListDisplayMode
|
||||||
|
import im.vector.app.features.home.room.list.RoomListListener
|
||||||
|
import im.vector.app.features.home.room.list.RoomSummaryItemFactory
|
||||||
|
import im.vector.app.features.home.room.list.RoomSummaryItemPlaceHolder_
|
||||||
|
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
|
||||||
|
class HomeFilteredRoomsController(
|
||||||
|
private val roomSummaryItemFactory: RoomSummaryItemFactory,
|
||||||
|
private val showFilters: Boolean,
|
||||||
|
) : PagedListEpoxyController<RoomSummary>(
|
||||||
|
// Important it must match the PageList builder notify Looper
|
||||||
|
modelBuildingHandler = createUIHandler()
|
||||||
|
) {
|
||||||
|
|
||||||
|
private var roomChangeMembershipStates: Map<String, ChangeMembershipState>? = null
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
// ideally we could search for visible models and update only those
|
||||||
|
requestForcedModelBuild()
|
||||||
|
}
|
||||||
|
|
||||||
|
var listener: RoomListListener? = null
|
||||||
|
var onFilterChanged: ((HomeRoomFilter) -> Unit)? = null
|
||||||
|
|
||||||
|
private var filtersData: List<HomeRoomFilter>? = null
|
||||||
|
|
||||||
|
override fun addModels(models: List<EpoxyModel<*>>) {
|
||||||
|
val host = this
|
||||||
|
if (showFilters) {
|
||||||
|
roomFilterHeaderItem {
|
||||||
|
id("filter_header")
|
||||||
|
filtersData(host.filtersData)
|
||||||
|
onFilterChangedListener(host.onFilterChanged)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.addModels(models)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun submitFiltersData(data: List<HomeRoomFilter>) {
|
||||||
|
this.filtersData = data
|
||||||
|
requestForcedModelBuild()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildItemModel(currentPosition: Int, item: RoomSummary?): EpoxyModel<*> {
|
||||||
|
item ?: return RoomSummaryItemPlaceHolder_().apply { id(currentPosition) }
|
||||||
|
return roomSummaryItemFactory.create(item, roomChangeMembershipStates.orEmpty(), emptySet(), RoomListDisplayMode.ROOMS, listener)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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.app.features.home.room.list.home.filter
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import im.vector.app.R
|
||||||
|
|
||||||
|
enum class HomeRoomFilter(@StringRes val titleRes: Int) {
|
||||||
|
ALL(R.string.room_list_filter_all),
|
||||||
|
UNREADS(R.string.room_list_filter_unreads),
|
||||||
|
FAVOURITES(R.string.room_list_filter_favourites),
|
||||||
|
PEOPlE(R.string.room_list_filter_people),
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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.app.features.home.room.list.home.filter
|
||||||
|
|
||||||
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||||
|
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||||
|
|
||||||
|
@EpoxyModelClass
|
||||||
|
abstract class RoomFilterHeaderItem : VectorEpoxyModel<RoomFilterHeaderItem.Holder>(R.layout.item_home_filter_tabs) {
|
||||||
|
|
||||||
|
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||||
|
var onFilterChangedListener: ((HomeRoomFilter) -> Unit)? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var filtersData: List<HomeRoomFilter>? = null
|
||||||
|
|
||||||
|
override fun bind(holder: Holder) {
|
||||||
|
super.bind(holder)
|
||||||
|
with(holder.tabLayout) {
|
||||||
|
removeAllTabs()
|
||||||
|
|
||||||
|
filtersData?.forEach { filter ->
|
||||||
|
addTab(newTab().setText(filter.titleRes).setTag(filter))
|
||||||
|
}
|
||||||
|
|
||||||
|
addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||||
|
override fun onTabSelected(tab: TabLayout.Tab?) {
|
||||||
|
(tab?.tag as? HomeRoomFilter)?.let { filter ->
|
||||||
|
onFilterChangedListener?.invoke(filter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabUnselected(tab: TabLayout.Tab?) = Unit
|
||||||
|
override fun onTabReselected(tab: TabLayout.Tab?) = Unit
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unbind(holder: Holder) {
|
||||||
|
holder.tabLayout.clearOnTabSelectedListeners()
|
||||||
|
super.unbind(holder)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Holder : VectorEpoxyHolder() {
|
||||||
|
val tabLayout by bind<TabLayout>(R.id.home_filter_tabs_tabs)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:viewBindingIgnore="true">
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/home_filter_tabs_tabs"
|
||||||
|
style="@style/Widget.Vector.TabLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?vctr_content_quaternary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1610,6 +1610,11 @@
|
||||||
<!-- Note to translators: for RTL languages, the + will be at the bottom left. Please translate "bottom left" instead of "bottom right". Thanks! -->
|
<!-- Note to translators: for RTL languages, the + will be at the bottom left. Please translate "bottom left" instead of "bottom right". Thanks! -->
|
||||||
<string name="room_list_rooms_empty_body">Your rooms will be displayed here. Tap the + at the bottom right to find existing ones or start some of your own.</string>
|
<string name="room_list_rooms_empty_body">Your rooms will be displayed here. Tap the + at the bottom right to find existing ones or start some of your own.</string>
|
||||||
|
|
||||||
|
<string name="room_list_filter_all">All</string>
|
||||||
|
<string name="room_list_filter_unreads">Unreads</string>
|
||||||
|
<string name="room_list_filter_favourites">Favourites</string>
|
||||||
|
<string name="room_list_filter_people">People</string>
|
||||||
|
|
||||||
<string name="title_activity_emoji_reaction_picker">Reactions</string>
|
<string name="title_activity_emoji_reaction_picker">Reactions</string>
|
||||||
<string name="message_add_reaction">Add Reaction</string>
|
<string name="message_add_reaction">Add Reaction</string>
|
||||||
<string name="message_view_reaction">View Reactions</string>
|
<string name="message_view_reaction">View Reactions</string>
|
||||||
|
|
Loading…
Reference in New Issue