Merge pull request #6073 from vector-im/feature/eric/improve-back-navigation

Adds up navigation in spaces
This commit is contained in:
Eric Decanini 2022-05-30 10:38:28 +02:00 committed by GitHub
commit b8c0c61a4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 98 additions and 78 deletions

1
changelog.d/6073.feature Normal file
View File

@ -0,0 +1 @@
Adds up navigation in spaces

View File

@ -72,6 +72,8 @@ class AppStateHandler @Inject constructor(
val selectedRoomGroupingFlow = selectedSpaceDataSource.stream()
private val spaceBackstack = ArrayDeque<String?>()
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
@ -87,12 +89,16 @@ class AppStateHandler @Inject constructor(
}
}
fun setCurrentSpace(spaceId: String?, session: Session? = null, persistNow: Boolean = false) {
fun setCurrentSpace(spaceId: String?, session: Session? = null, persistNow: Boolean = false, isForwardNavigation: Boolean = true) {
val currentSpace = (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.BySpace)?.space()
val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
if (selectedSpaceDataSource.currentValue?.orNull() is RoomGroupingMethod.BySpace &&
spaceId == selectedSpaceDataSource.currentValue?.orNull()?.space()?.roomId) return
if (currentSpace != null && spaceId == currentSpace.roomId) return
val spaceSum = spaceId?.let { uSession.getRoomSummary(spaceId) }
if (isForwardNavigation) {
spaceBackstack.addLast(currentSpace?.roomId)
}
if (persistNow) {
uiStateRepository.storeGroupingMethod(true, uSession.sessionId)
uiStateRepository.storeSelectedSpace(spaceSum?.roomId, uSession.sessionId)
@ -151,6 +157,8 @@ class AppStateHandler @Inject constructor(
}.launchIn(session.coroutineScope)
}
fun getSpaceBackstack() = spaceBackstack
fun safeActiveSpaceId(): String? {
return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.BySpace)?.spaceSummary?.roomId
}

View File

@ -199,43 +199,13 @@ class HomeActivity :
when (sharedAction) {
is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START)
is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START)
is HomeActivitySharedAction.OpenGroup -> {
views.drawerLayout.closeDrawer(GravityCompat.START)
// Temporary
// When switching from space to group or group to space, we need to reload the fragment
// To be removed when dropping legacy groups
if (sharedAction.clearFragment) {
replaceFragment(views.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true)
} else {
// nop
}
// we might want to delay that to avoid having the drawer animation lagging
// would be probably better to let the drawer do that? in the on closed callback?
}
is HomeActivitySharedAction.OpenSpacePreview -> {
startActivity(SpacePreviewActivity.newIntent(this, sharedAction.spaceId))
}
is HomeActivitySharedAction.AddSpace -> {
createSpaceResultLauncher.launch(SpaceCreationActivity.newIntent(this))
}
is HomeActivitySharedAction.ShowSpaceSettings -> {
// open bottom sheet
SpaceSettingsMenuBottomSheet
.newInstance(sharedAction.spaceId, object : SpaceSettingsMenuBottomSheet.InteractionListener {
override fun onShareSpaceSelected(spaceId: String) {
ShareSpaceBottomSheet.show(supportFragmentManager, spaceId)
}
})
.show(supportFragmentManager, "SPACE_SETTINGS")
}
is HomeActivitySharedAction.OpenSpaceInvite -> {
SpaceInviteBottomSheet.newInstance(sharedAction.spaceId)
.show(supportFragmentManager, "SPACE_INVITE")
}
HomeActivitySharedAction.SendSpaceFeedBack -> {
bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK)
}
is HomeActivitySharedAction.OpenGroup -> openGroup(sharedAction.shouldClearFragment)
is HomeActivitySharedAction.OpenSpacePreview -> startActivity(SpacePreviewActivity.newIntent(this, sharedAction.spaceId))
is HomeActivitySharedAction.AddSpace -> createSpaceResultLauncher.launch(SpaceCreationActivity.newIntent(this))
is HomeActivitySharedAction.ShowSpaceSettings -> showSpaceSettings(sharedAction.spaceId)
is HomeActivitySharedAction.OpenSpaceInvite -> openSpaceInvite(sharedAction.spaceId)
HomeActivitySharedAction.SendSpaceFeedBack -> bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK)
HomeActivitySharedAction.CloseGroup -> closeGroup()
}
}
.launchIn(lifecycleScope)
@ -272,6 +242,37 @@ class HomeActivity :
homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted)
}
private fun openGroup(shouldClearFragment: Boolean) {
views.drawerLayout.closeDrawer(GravityCompat.START)
// When switching from space to group or group to space, we need to reload the fragment
if (shouldClearFragment) {
replaceFragment(views.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true)
} else {
// do nothing
}
}
private fun showSpaceSettings(spaceId: String) {
// open bottom sheet
SpaceSettingsMenuBottomSheet
.newInstance(spaceId, object : SpaceSettingsMenuBottomSheet.InteractionListener {
override fun onShareSpaceSelected(spaceId: String) {
ShareSpaceBottomSheet.show(supportFragmentManager, spaceId)
}
})
.show(supportFragmentManager, "SPACE_SETTINGS")
}
private fun openSpaceInvite(spaceId: String) {
SpaceInviteBottomSheet.newInstance(spaceId)
.show(supportFragmentManager, "SPACE_INVITE")
}
private fun closeGroup() {
views.drawerLayout.openDrawer(GravityCompat.START)
}
private fun handleShowAnalyticsOptIn() {
navigator.openAnalyticsOptIn(this)
}

View File

@ -24,7 +24,8 @@ import im.vector.app.core.platform.VectorSharedAction
sealed class HomeActivitySharedAction : VectorSharedAction {
object OpenDrawer : HomeActivitySharedAction()
object CloseDrawer : HomeActivitySharedAction()
data class OpenGroup(val clearFragment: Boolean) : HomeActivitySharedAction()
data class OpenGroup(val shouldClearFragment: Boolean) : HomeActivitySharedAction()
object CloseGroup : HomeActivitySharedAction()
object AddSpace : HomeActivitySharedAction()
data class OpenSpacePreview(val spaceId: String) : HomeActivitySharedAction()
data class OpenSpaceInvite(val spaceId: String) : HomeActivitySharedAction()

View File

@ -33,6 +33,7 @@ import im.vector.app.R
import im.vector.app.RoomGroupingMethod
import im.vector.app.core.extensions.commitTransaction
import im.vector.app.core.extensions.toMvRxBundle
import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.resources.ColorProvider
@ -69,7 +70,8 @@ class HomeDetailFragment @Inject constructor(
private val appStateHandler: AppStateHandler
) : VectorBaseFragment<FragmentHomeDetailBinding>(),
KeysBackupBanner.Delegate,
CurrentCallsView.Callback {
CurrentCallsView.Callback,
OnBackPressed {
private val viewModel: HomeDetailViewModel by fragmentViewModel()
private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
@ -130,12 +132,8 @@ class HomeDetailFragment @Inject constructor(
viewModel.onEach(HomeDetailViewState::roomGroupingMethod) { roomGroupingMethod ->
when (roomGroupingMethod) {
is RoomGroupingMethod.ByLegacyGroup -> {
onGroupChange(roomGroupingMethod.groupSummary)
}
is RoomGroupingMethod.BySpace -> {
onSpaceChange(roomGroupingMethod.spaceSummary)
}
is RoomGroupingMethod.ByLegacyGroup -> onGroupChange(roomGroupingMethod.groupSummary)
is RoomGroupingMethod.BySpace -> onSpaceChange(roomGroupingMethod.spaceSummary)
}
}
@ -157,7 +155,6 @@ class HomeDetailFragment @Inject constructor(
unknownDeviceDetectorSharedViewModel.onEach { state ->
state.unknownSessions.invoke()?.let { unknownDevices ->
// Timber.v("## Detector Triggerred in fragment - ${unknownDevices.firstOrNull()}")
if (unknownDevices.firstOrNull()?.currentSessionTrust == true) {
val uid = "review_login"
alertManager.cancelAlert(uid)
@ -190,6 +187,27 @@ class HomeDetailFragment @Inject constructor(
}
}
private fun navigateBack() {
try {
val lastSpace = appStateHandler.getSpaceBackstack().removeLast()
setCurrentSpace(lastSpace)
} catch (e: NoSuchElementException) {
navigateUpOneSpace()
}
}
private fun setCurrentSpace(spaceId: String?) {
appStateHandler.setCurrentSpace(spaceId, isForwardNavigation = false)
sharedActionViewModel.post(HomeActivitySharedAction.CloseGroup)
}
private fun navigateUpOneSpace() {
val parentId = getCurrentSpace()?.flattenParentIds?.lastOrNull()
setCurrentSpace(parentId)
}
private fun getCurrentSpace() = (appStateHandler.getCurrentRoomGroupingMethod() as? RoomGroupingMethod.BySpace)?.spaceSummary
private fun handleCallStarted() {
dismissLoadingDialog()
val fragmentTag = HomeTab.DialPad.toFragmentTag()
@ -203,20 +221,16 @@ class HomeDetailFragment @Inject constructor(
override fun onResume() {
super.onResume()
// update notification tab if needed
updateTabVisibilitySafely(R.id.bottom_action_notification, vectorPreferences.labAddNotificationTab())
callManager.checkForProtocolsSupportIfNeeded()
refreshSpaceState()
}
// Current space/group is not live so at least refresh toolbar on resume
appStateHandler.getCurrentRoomGroupingMethod()?.let { roomGroupingMethod ->
when (roomGroupingMethod) {
is RoomGroupingMethod.ByLegacyGroup -> {
onGroupChange(roomGroupingMethod.groupSummary)
}
is RoomGroupingMethod.BySpace -> {
onSpaceChange(roomGroupingMethod.spaceSummary)
}
}
private fun refreshSpaceState() {
when (val roomGroupingMethod = appStateHandler.getCurrentRoomGroupingMethod()) {
is RoomGroupingMethod.ByLegacyGroup -> onGroupChange(roomGroupingMethod.groupSummary)
is RoomGroupingMethod.BySpace -> onSpaceChange(roomGroupingMethod.spaceSummary)
else -> Unit
}
}
@ -260,12 +274,12 @@ class HomeDetailFragment @Inject constructor(
viewBinder = VerificationVectorAlert.ViewBinder(user, avatarRenderer)
colorInt = colorProvider.getColorFromAttribute(R.attr.colorPrimary)
contentAction = Runnable {
(weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let {
(weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { activity ->
// mark as ignored to avoid showing it again
unknownDeviceDetectorSharedViewModel.handle(
UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(oldUnverified.mapNotNull { it.deviceId })
)
it.navigator.openSettings(it, EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS)
activity.navigator.openSettings(activity, EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS)
}
}
dismissedAction = Runnable {
@ -324,11 +338,11 @@ class HomeDetailFragment @Inject constructor(
withState(viewModel) {
when (it.roomGroupingMethod) {
is RoomGroupingMethod.ByLegacyGroup -> {
// nothing do far
// do nothing
}
is RoomGroupingMethod.BySpace -> {
it.roomGroupingMethod.spaceSummary?.let {
sharedActionViewModel.post(HomeActivitySharedAction.ShowSpaceSettings(it.roomId))
it.roomGroupingMethod.spaceSummary?.let { spaceSummary ->
sharedActionViewModel.post(HomeActivitySharedAction.ShowSpaceSettings(spaceSummary.roomId))
}
}
}
@ -348,17 +362,6 @@ class HomeDetailFragment @Inject constructor(
viewModel.handle(HomeDetailAction.SwitchTab(tab))
true
}
// val menuView = bottomNavigationView.getChildAt(0) as BottomNavigationMenuView
// bottomNavigationView.getOrCreateBadge()
// menuView.forEachIndexed { index, view ->
// val itemView = view as BottomNavigationItemView
// val badgeLayout = LayoutInflater.from(requireContext()).inflate(R.layout.vector_home_badge_unread_layout, menuView, false)
// val unreadCounterBadgeView: UnreadCounterBadgeView = badgeLayout.findViewById(R.id.actionUnreadCounterBadgeView)
// itemView.addView(badgeLayout)
// unreadCounterBadgeViews.add(index, unreadCounterBadgeView)
// }
}
private fun updateUIForTab(tab: HomeTab) {
@ -436,7 +439,6 @@ class HomeDetailFragment @Inject constructor(
}
override fun invalidate() = withState(viewModel) {
// Timber.v(it.toString())
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_people).render(it.notificationCountPeople, it.notificationHighlightPeople)
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_rooms).render(it.notificationCountRooms, it.notificationHighlightRooms)
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup)
@ -496,4 +498,11 @@ class HomeDetailFragment @Inject constructor(
}
return this
}
override fun onBackPressed(toolbarButton: Boolean) = if (getCurrentSpace() != null) {
navigateBack()
true
} else {
false
}
}

View File

@ -153,4 +153,4 @@
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/home_bottom_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>