ViewPager: never react to own space-changes
Change-Id: I45a1fd1e9ec6048dffdc4d54e8022d53afc627ff
This commit is contained in:
parent
f50b21d9b7
commit
e21f9443d5
|
@ -19,6 +19,7 @@ package im.vector.app
|
|||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import arrow.core.Option
|
||||
import arrow.core.getOrElse
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.utils.BehaviorDataSource
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
|
@ -28,7 +29,9 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
|
@ -59,16 +62,21 @@ class AppStateHandler @Inject constructor(
|
|||
) : DefaultLifecycleObserver {
|
||||
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
||||
private val selectedSpaceDataSource = BehaviorDataSource<Option<RoomGroupingMethod>>(Option.empty())
|
||||
///private val selectedSpaceDataSource = BehaviorDataSource<Option<RoomGroupingMethod>>(Option.empty())
|
||||
|
||||
val selectedRoomGroupingFlow = selectedSpaceDataSource.stream()
|
||||
// SchildiChat: the boolean means pendingSwipe and defaults to false. Set to true for swiping spaces, so you want to ignore updates which have pendingSwipe = true.
|
||||
// Call it different then the upstream one so we don't forget adding `first` to upstream's logic.
|
||||
private val selectedSpaceDataSourceSc = BehaviorDataSource<Option<Pair<RoomGroupingMethod, Boolean>>>(Option.empty())
|
||||
|
||||
val selectedRoomGroupingFlow = selectedSpaceDataSourceSc.stream().map { it.map { it.first } }
|
||||
val selectedRoomGroupingFlowIgnoreSwipe = selectedSpaceDataSourceSc.stream().filter { it.getOrElse{ null }?.second != true }.map { it.map { it.first } }
|
||||
|
||||
fun getCurrentRoomGroupingMethod(): RoomGroupingMethod? {
|
||||
// XXX we should somehow make it live :/ just a work around
|
||||
// For example just after creating a space and switching to it the
|
||||
// name in the app Bar could show Empty Room, and it will not update unless you
|
||||
// switch space
|
||||
return selectedSpaceDataSource.currentValue?.orNull()?.let {
|
||||
return selectedSpaceDataSourceSc.currentValue?.orNull()?.first?.let {
|
||||
if (it is RoomGroupingMethod.BySpace) {
|
||||
// try to refresh sum?
|
||||
it.spaceSummary?.roomId?.let { activeSessionHolder.getSafeActiveSession()?.getRoomSummary(it) }?.let {
|
||||
|
@ -78,10 +86,10 @@ class AppStateHandler @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun setCurrentSpace(spaceId: String?, session: Session? = null, persistNow: Boolean = false) {
|
||||
fun setCurrentSpace(spaceId: String?, session: Session? = null, persistNow: Boolean = false, pendingSwipe: Boolean = false) {
|
||||
val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
|
||||
if (selectedSpaceDataSource.currentValue?.orNull() is RoomGroupingMethod.BySpace &&
|
||||
spaceId == selectedSpaceDataSource.currentValue?.orNull()?.space()?.roomId) return
|
||||
if (selectedSpaceDataSourceSc.currentValue?.orNull()?.first is RoomGroupingMethod.BySpace &&
|
||||
spaceId == selectedSpaceDataSourceSc.currentValue?.orNull()?.first?.space()?.roomId) return
|
||||
val spaceSum = spaceId?.let { uSession.getRoomSummary(spaceId) }
|
||||
|
||||
if (persistNow) {
|
||||
|
@ -89,7 +97,7 @@ class AppStateHandler @Inject constructor(
|
|||
uiStateRepository.storeSelectedSpace(spaceSum?.roomId, uSession.sessionId)
|
||||
}
|
||||
|
||||
selectedSpaceDataSource.post(Option.just(RoomGroupingMethod.BySpace(spaceSum)))
|
||||
selectedSpaceDataSourceSc.post(Option.just(Pair(RoomGroupingMethod.BySpace(spaceSum), pendingSwipe)))
|
||||
if (spaceId != null) {
|
||||
uSession.coroutineScope.launch(Dispatchers.IO) {
|
||||
tryOrNull {
|
||||
|
@ -101,10 +109,10 @@ class AppStateHandler @Inject constructor(
|
|||
|
||||
fun setCurrentGroup(groupId: String?, session: Session? = null) {
|
||||
val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
|
||||
if (selectedSpaceDataSource.currentValue?.orNull() is RoomGroupingMethod.ByLegacyGroup &&
|
||||
groupId == selectedSpaceDataSource.currentValue?.orNull()?.group()?.groupId) return
|
||||
if (selectedSpaceDataSourceSc.currentValue?.orNull()?.first is RoomGroupingMethod.ByLegacyGroup &&
|
||||
groupId == selectedSpaceDataSourceSc.currentValue?.orNull()?.first?.group()?.groupId) return
|
||||
val activeGroup = groupId?.let { uSession.getGroupSummary(groupId) }
|
||||
selectedSpaceDataSource.post(Option.just(RoomGroupingMethod.ByLegacyGroup(activeGroup)))
|
||||
selectedSpaceDataSourceSc.post(Option.just(Pair(RoomGroupingMethod.ByLegacyGroup(activeGroup), false)))
|
||||
if (groupId != null) {
|
||||
uSession.coroutineScope.launch {
|
||||
tryOrNull {
|
||||
|
@ -131,11 +139,11 @@ class AppStateHandler @Inject constructor(
|
|||
}
|
||||
|
||||
fun safeActiveSpaceId(): String? {
|
||||
return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.BySpace)?.spaceSummary?.roomId
|
||||
return (selectedSpaceDataSourceSc.currentValue?.orNull()?.first as? RoomGroupingMethod.BySpace)?.spaceSummary?.roomId
|
||||
}
|
||||
|
||||
fun safeActiveGroupId(): String? {
|
||||
return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId
|
||||
return (selectedSpaceDataSourceSc.currentValue?.orNull()?.first as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId
|
||||
}
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
|
@ -145,7 +153,7 @@ class AppStateHandler @Inject constructor(
|
|||
override fun onPause(owner: LifecycleOwner) {
|
||||
coroutineScope.coroutineContext.cancelChildren()
|
||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||
when (val currentMethod = selectedSpaceDataSource.currentValue?.orNull() ?: RoomGroupingMethod.BySpace(null)) {
|
||||
when (val currentMethod = selectedSpaceDataSourceSc.currentValue?.orNull()?.first ?: RoomGroupingMethod.BySpace(null)) {
|
||||
is RoomGroupingMethod.BySpace -> {
|
||||
uiStateRepository.storeGroupingMethod(true, session.sessionId)
|
||||
uiStateRepository.storeSelectedSpace(currentMethod.spaceSummary?.roomId, session.sessionId)
|
||||
|
|
|
@ -105,7 +105,6 @@ class HomeDetailFragment @Inject constructor(
|
|||
private var pagerSpaces: List<String?>? = null
|
||||
private var pagerTab: HomeTab? = null
|
||||
private var pagerPagingEnabled: Boolean = false
|
||||
private val pendingSpaceIds = mutableListOf<String?>()
|
||||
|
||||
override fun getMenuRes() = R.menu.room_list
|
||||
|
||||
|
@ -163,8 +162,7 @@ class HomeDetailFragment @Inject constructor(
|
|||
}
|
||||
}
|
||||
val selectedId = getSpaceIdForPageIndex(position)
|
||||
pendingSpaceIds.add(selectedId)
|
||||
appStateHandler.setCurrentSpace(selectedId)
|
||||
appStateHandler.setCurrentSpace(selectedId, pendingSwipe = true)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -225,7 +223,7 @@ class HomeDetailFragment @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
viewModel.onEach(HomeDetailViewState::roomGroupingMethod, HomeDetailViewState::rootSpacesOrdered, HomeDetailViewState::currentTab) { roomGroupingMethod, rootSpacesOrdered, currentTab ->
|
||||
viewModel.onEach(HomeDetailViewState::roomGroupingMethodIgnoreSwipe, HomeDetailViewState::rootSpacesOrdered, HomeDetailViewState::currentTab) { roomGroupingMethod, rootSpacesOrdered, currentTab ->
|
||||
setupViewPager(roomGroupingMethod, rootSpacesOrdered, currentTab)
|
||||
}
|
||||
|
||||
|
@ -529,13 +527,6 @@ class HomeDetailFragment @Inject constructor(
|
|||
if (!changed) {
|
||||
if (pagingEnabled) {
|
||||
// No need to re-setup pager, just check for selected page
|
||||
// Discard state changes that we created ourselves by swiping on the pager
|
||||
while (pendingSpaceIds.size > 0) {
|
||||
val pendingSpaceId = pendingSpaceIds.removeAt(0)
|
||||
if (pendingSpaceId == selectedSpaceId) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if (selectedIndex != null) {
|
||||
if (selectedIndex != views.roomListContainerPager.currentItem) {
|
||||
// post() mitigates a case where we could end up in an endless loop circling around the same few spaces
|
||||
|
@ -566,7 +557,6 @@ class HomeDetailFragment @Inject constructor(
|
|||
pagerTab = tab
|
||||
pagerPagingEnabled = pagingEnabled
|
||||
initialPageSelected = false
|
||||
pendingSpaceIds.clear()
|
||||
|
||||
// OFFSCREEN_PAGE_LIMIT_DEFAULT: default recyclerview caching mechanism instead of explicit fixed prefetching
|
||||
//views.roomListContainerPager.offscreenPageLimit = 2
|
||||
|
|
|
@ -212,6 +212,12 @@ class HomeDetailViewModel @AssistedInject constructor(
|
|||
roomGroupingMethod = it.orNull() ?: RoomGroupingMethod.BySpace(null)
|
||||
)
|
||||
}
|
||||
appStateHandler.selectedRoomGroupingFlowIgnoreSwipe
|
||||
.setOnEach {
|
||||
copy(
|
||||
roomGroupingMethodIgnoreSwipe = it.orNull() ?: RoomGroupingMethod.BySpace(null)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeRoomSummaries() {
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.matrix.android.sdk.api.util.MatrixItem
|
|||
|
||||
data class HomeDetailViewState(
|
||||
val roomGroupingMethod: RoomGroupingMethod = RoomGroupingMethod.BySpace(null),
|
||||
val roomGroupingMethodIgnoreSwipe: RoomGroupingMethod = RoomGroupingMethod.BySpace(null),
|
||||
val myMatrixItem: MatrixItem? = null,
|
||||
val asyncRooms: Async<List<RoomSummary>> = Uninitialized,
|
||||
val currentTab: HomeTab = HomeTab.RoomList(RoomListDisplayMode.ALL),
|
||||
|
|
Loading…
Reference in New Issue