mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-27 03:49:04 +03:00
better management of collapsing for room controllers
This commit is contained in:
parent
4d7aeff54a
commit
7921a81b8e
6 changed files with 177 additions and 35 deletions
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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
|
||||
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
import timber.log.Timber
|
||||
|
||||
fun EpoxyController.setCollapsed(collapsed: Boolean) {
|
||||
if (this is CollapsableControllerExtension) {
|
||||
this.collapsed = collapsed
|
||||
} else {
|
||||
Timber.w("Try to collapse a controller that do not support collapse state")
|
||||
}
|
||||
}
|
||||
|
||||
interface CollapsableControllerExtension {
|
||||
var collapsed: Boolean
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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
|
||||
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
|
||||
abstract class CollapsableTypedEpoxyController<T>
|
||||
: EpoxyController(), CollapsableControllerExtension {
|
||||
|
||||
private var currentData: T? = null
|
||||
private var allowModelBuildRequests = false
|
||||
|
||||
override var collapsed: Boolean = false
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
allowModelBuildRequests = true
|
||||
requestModelBuild()
|
||||
allowModelBuildRequests = false
|
||||
}
|
||||
}
|
||||
|
||||
fun setData(data: T?) {
|
||||
currentData = data
|
||||
allowModelBuildRequests = true
|
||||
requestModelBuild()
|
||||
allowModelBuildRequests = false
|
||||
}
|
||||
|
||||
override fun requestModelBuild() {
|
||||
check(allowModelBuildRequests) {
|
||||
("You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a "
|
||||
+ "model refresh with new data.")
|
||||
}
|
||||
super.requestModelBuild()
|
||||
}
|
||||
|
||||
override fun moveModel(fromPosition: Int, toPosition: Int) {
|
||||
allowModelBuildRequests = true
|
||||
super.moveModel(fromPosition, toPosition)
|
||||
allowModelBuildRequests = false
|
||||
}
|
||||
|
||||
override fun requestDelayedModelBuild(delayMs: Int) {
|
||||
check(allowModelBuildRequests) {
|
||||
("You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a "
|
||||
+ "model refresh with new data.")
|
||||
}
|
||||
super.requestDelayedModelBuild(delayMs)
|
||||
}
|
||||
|
||||
fun getCurrentData(): T? {
|
||||
return currentData
|
||||
}
|
||||
|
||||
override fun buildModels() {
|
||||
check(isBuildingModels()) {
|
||||
("You cannot call `buildModels` directly. Call `setData` instead to trigger a model "
|
||||
+ "refresh with new data.")
|
||||
}
|
||||
if (collapsed) {
|
||||
buildModels(null)
|
||||
} else {
|
||||
buildModels(currentData)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun buildModels(data: T?)
|
||||
}
|
|
@ -108,10 +108,10 @@ class RoomListFragment @Inject constructor(
|
|||
sharedActionViewModel = activityViewModelProvider.get(RoomListQuickActionsSharedActionViewModel::class.java)
|
||||
roomListViewModel.observeViewEvents {
|
||||
when (it) {
|
||||
is RoomListViewEvents.Loading -> showLoading(it.message)
|
||||
is RoomListViewEvents.Failure -> showFailure(it.throwable)
|
||||
is RoomListViewEvents.Loading -> showLoading(it.message)
|
||||
is RoomListViewEvents.Failure -> showFailure(it.throwable)
|
||||
is RoomListViewEvents.SelectRoom -> handleSelectRoom(it)
|
||||
is RoomListViewEvents.Done -> Unit
|
||||
is RoomListViewEvents.Done -> Unit
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
|
@ -132,21 +132,15 @@ class RoomListFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun refreshCollapseStates() {
|
||||
var contentInsertIndex = 1
|
||||
roomListViewModel.sections.forEachIndexed { index, roomsSection ->
|
||||
val actualBlock = adapterInfosList[index]
|
||||
val isRoomSectionExpanded = roomsSection.isExpanded.value.orTrue()
|
||||
if (actualBlock.section.isExpanded && !isRoomSectionExpanded) {
|
||||
// we have to remove the content adapter
|
||||
concatAdapter?.removeAdapter(actualBlock.contentAdapter.adapter)
|
||||
// mark controller as collapsed
|
||||
actualBlock.contentAdapter.setCollapsed(true)
|
||||
} else if (!actualBlock.section.isExpanded && isRoomSectionExpanded) {
|
||||
// we must add it back!
|
||||
concatAdapter?.addAdapter(contentInsertIndex, actualBlock.contentAdapter.adapter)
|
||||
}
|
||||
contentInsertIndex = if (isRoomSectionExpanded) {
|
||||
contentInsertIndex + 2
|
||||
} else {
|
||||
contentInsertIndex + 1
|
||||
// we must expand!
|
||||
actualBlock.contentAdapter.setCollapsed(false)
|
||||
}
|
||||
actualBlock.section = actualBlock.section.copy(
|
||||
isExpanded = isRoomSectionExpanded
|
||||
|
|
|
@ -16,12 +16,11 @@
|
|||
|
||||
package im.vector.app.features.home.room.list
|
||||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
|
||||
class RoomSummaryListController(
|
||||
private val roomSummaryItemFactory: RoomSummaryItemFactory
|
||||
) : TypedEpoxyController<List<RoomSummary>>() {
|
||||
) : CollapsableTypedEpoxyController<List<RoomSummary>>() {
|
||||
|
||||
var listener: RoomListListener? = null
|
||||
|
||||
|
|
|
@ -21,31 +21,13 @@ import com.airbnb.epoxy.paging.PagedListEpoxyController
|
|||
import im.vector.app.core.utils.createUIHandler
|
||||
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomSummaryPagedControllerFactory @Inject constructor(
|
||||
private val roomSummaryItemFactory: RoomSummaryItemFactory
|
||||
) {
|
||||
|
||||
fun createRoomSummaryPagedController(): RoomSummaryPagedController {
|
||||
return RoomSummaryPagedController(roomSummaryItemFactory)
|
||||
}
|
||||
|
||||
fun createRoomSummaryListController(): RoomSummaryListController {
|
||||
return RoomSummaryListController(roomSummaryItemFactory)
|
||||
}
|
||||
|
||||
fun createSuggestedRoomListController(): SuggestedRoomListController {
|
||||
return SuggestedRoomListController(roomSummaryItemFactory)
|
||||
}
|
||||
}
|
||||
|
||||
class RoomSummaryPagedController(
|
||||
private val roomSummaryItemFactory: RoomSummaryItemFactory
|
||||
) : PagedListEpoxyController<RoomSummary>(
|
||||
) : PagedListEpoxyController<RoomSummary> (
|
||||
// Important it must match the PageList builder notify Looper
|
||||
modelBuildingHandler = createUIHandler()
|
||||
) {
|
||||
), CollapsableControllerExtension {
|
||||
|
||||
var listener: RoomListListener? = null
|
||||
|
||||
|
@ -56,6 +38,22 @@ class RoomSummaryPagedController(
|
|||
requestForcedModelBuild()
|
||||
}
|
||||
|
||||
override var collapsed = false
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
requestForcedModelBuild()
|
||||
}
|
||||
}
|
||||
|
||||
override fun addModels(models: List<EpoxyModel<*>>) {
|
||||
if (collapsed) {
|
||||
super.addModels(emptyList())
|
||||
} else {
|
||||
super.addModels(models)
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildItemModel(currentPosition: Int, item: RoomSummary?): EpoxyModel<*> {
|
||||
// for place holder if enabled
|
||||
item ?: return roomSummaryItemFactory.createRoomItem(
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomSummaryPagedControllerFactory @Inject constructor(
|
||||
private val roomSummaryItemFactory: RoomSummaryItemFactory
|
||||
) {
|
||||
|
||||
fun createRoomSummaryPagedController(): RoomSummaryPagedController {
|
||||
return RoomSummaryPagedController(roomSummaryItemFactory)
|
||||
}
|
||||
|
||||
fun createRoomSummaryListController(): RoomSummaryListController {
|
||||
return RoomSummaryListController(roomSummaryItemFactory)
|
||||
}
|
||||
|
||||
fun createSuggestedRoomListController(): SuggestedRoomListController {
|
||||
return SuggestedRoomListController(roomSummaryItemFactory)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue