mirror of
https://github.com/element-hq/element-android
synced 2024-12-18 23:34:12 +03:00
Merge pull request #6877 from vector-im/feature/eric/new-layout-navigation
Space Switching Back Navigation
This commit is contained in:
commit
b5debe92c0
25 changed files with 333 additions and 79 deletions
1
changelog.d/6871.feature
Normal file
1
changelog.d/6871.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Improves Developer Mode Debug Button UX and adds it to New App Layout
|
1
changelog.d/6877.wip
Normal file
1
changelog.d/6877.wip
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[New Layout] Adds back navigation through spaces
|
|
@ -51,11 +51,13 @@ interface SpaceStateHandler : DefaultLifecycleObserver {
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current backstack of spaces (via their id).
|
* Gets the Space ID of the space on top of the backstack.
|
||||||
*
|
*
|
||||||
* null may be an entry in the ArrayDeque to indicate the root space (All Chats)
|
* May return null to indicate the All Chats space.
|
||||||
*/
|
*/
|
||||||
fun getSpaceBackstack(): ArrayDeque<String?>
|
fun popSpaceBackstack(): String?
|
||||||
|
|
||||||
|
fun getSpaceBackstack(): List<String?>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a flow of the selected space for clients to react immediately to space changes.
|
* Gets a flow of the selected space for clients to react immediately to space changes.
|
||||||
|
|
|
@ -23,6 +23,7 @@ import im.vector.app.core.utils.BehaviorDataSource
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.plan.UserProperties
|
import im.vector.app.features.analytics.plan.UserProperties
|
||||||
import im.vector.app.features.session.coroutineScope
|
import im.vector.app.features.session.coroutineScope
|
||||||
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import im.vector.app.features.ui.UiStateRepository
|
import im.vector.app.features.ui.UiStateRepository
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -52,13 +53,13 @@ class SpaceStateHandlerImpl @Inject constructor(
|
||||||
private val sessionDataSource: ActiveSessionDataSource,
|
private val sessionDataSource: ActiveSessionDataSource,
|
||||||
private val uiStateRepository: UiStateRepository,
|
private val uiStateRepository: UiStateRepository,
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val analyticsTracker: AnalyticsTracker
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
|
private val vectorPreferences: VectorPreferences,
|
||||||
) : SpaceStateHandler {
|
) : SpaceStateHandler {
|
||||||
|
|
||||||
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
||||||
private val selectedSpaceDataSource = BehaviorDataSource<Option<RoomSummary>>(Option.empty())
|
private val selectedSpaceDataSource = BehaviorDataSource<Option<RoomSummary>>(Option.empty())
|
||||||
private val selectedSpaceFlow = selectedSpaceDataSource.stream()
|
private val selectedSpaceFlow = selectedSpaceDataSource.stream()
|
||||||
private val spaceBackstack = ArrayDeque<String?>()
|
|
||||||
|
|
||||||
override fun getCurrentSpace(): RoomSummary? {
|
override fun getCurrentSpace(): RoomSummary? {
|
||||||
return selectedSpaceDataSource.currentValue?.orNull()?.let { spaceSummary ->
|
return selectedSpaceDataSource.currentValue?.orNull()?.let { spaceSummary ->
|
||||||
|
@ -73,26 +74,26 @@ class SpaceStateHandlerImpl @Inject constructor(
|
||||||
isForwardNavigation: Boolean,
|
isForwardNavigation: Boolean,
|
||||||
) {
|
) {
|
||||||
val activeSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
|
val activeSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
|
||||||
val currentSpace = selectedSpaceDataSource.currentValue?.orNull()
|
val spaceToLeave = selectedSpaceDataSource.currentValue?.orNull()
|
||||||
val spaceSummary = spaceId?.let { activeSession.getRoomSummary(spaceId) }
|
val spaceToSet = spaceId?.let { activeSession.getRoomSummary(spaceId) }
|
||||||
val sameSpaceSelected = currentSpace != null && spaceId == currentSpace.roomId
|
val sameSpaceSelected = spaceId == spaceToLeave?.roomId
|
||||||
|
|
||||||
if (sameSpaceSelected) {
|
if (sameSpaceSelected) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isForwardNavigation) {
|
if (isForwardNavigation) {
|
||||||
spaceBackstack.addLast(currentSpace?.roomId)
|
addToBackstack(spaceToLeave, spaceToSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (persistNow) {
|
if (persistNow) {
|
||||||
uiStateRepository.storeSelectedSpace(spaceSummary?.roomId, activeSession.sessionId)
|
uiStateRepository.storeSelectedSpace(spaceToSet?.roomId, activeSession.sessionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spaceSummary == null) {
|
if (spaceToSet == null) {
|
||||||
selectedSpaceDataSource.post(Option.empty())
|
selectedSpaceDataSource.post(Option.empty())
|
||||||
} else {
|
} else {
|
||||||
selectedSpaceDataSource.post(Option.just(spaceSummary))
|
selectedSpaceDataSource.post(Option.just(spaceToSet))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spaceId != null) {
|
if (spaceId != null) {
|
||||||
|
@ -104,6 +105,17 @@ class SpaceStateHandlerImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addToBackstack(spaceToLeave: RoomSummary?, spaceToSet: RoomSummary?) {
|
||||||
|
// Only add to the backstack if the space to set is not All Chats, else clear the backstack
|
||||||
|
if (spaceToSet != null) {
|
||||||
|
val currentPersistedBackstack = vectorPreferences.getSpaceBackstack().toMutableList()
|
||||||
|
currentPersistedBackstack.add(spaceToLeave?.roomId)
|
||||||
|
vectorPreferences.setSpaceBackstack(currentPersistedBackstack)
|
||||||
|
} else {
|
||||||
|
vectorPreferences.setSpaceBackstack(emptyList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun observeActiveSession() {
|
private fun observeActiveSession() {
|
||||||
sessionDataSource.stream()
|
sessionDataSource.stream()
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
|
@ -127,7 +139,15 @@ class SpaceStateHandlerImpl @Inject constructor(
|
||||||
}.launchIn(session.coroutineScope)
|
}.launchIn(session.coroutineScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSpaceBackstack() = spaceBackstack
|
override fun popSpaceBackstack(): String? {
|
||||||
|
vectorPreferences.getSpaceBackstack().toMutableList().apply {
|
||||||
|
val poppedSpaceId = removeLast()
|
||||||
|
vectorPreferences.setSpaceBackstack(this)
|
||||||
|
return poppedSpaceId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSpaceBackstack() = vectorPreferences.getSpaceBackstack()
|
||||||
|
|
||||||
override fun getSelectedSpaceFlow() = selectedSpaceFlow
|
override fun getSelectedSpaceFlow() = selectedSpaceFlow
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.extensions.hideKeyboard
|
import im.vector.app.core.extensions.hideKeyboard
|
||||||
import im.vector.app.core.extensions.registerStartForActivityResult
|
import im.vector.app.core.extensions.registerStartForActivityResult
|
||||||
import im.vector.app.core.extensions.replaceFragment
|
import im.vector.app.core.extensions.replaceFragment
|
||||||
|
import im.vector.app.core.extensions.restart
|
||||||
import im.vector.app.core.extensions.validateBackPressed
|
import im.vector.app.core.extensions.validateBackPressed
|
||||||
import im.vector.app.core.platform.VectorBaseActivity
|
import im.vector.app.core.platform.VectorBaseActivity
|
||||||
import im.vector.app.core.platform.VectorMenuProvider
|
import im.vector.app.core.platform.VectorMenuProvider
|
||||||
|
@ -56,6 +57,8 @@ import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
import im.vector.app.features.analytics.plan.ViewRoom
|
import im.vector.app.features.analytics.plan.ViewRoom
|
||||||
import im.vector.app.features.crypto.recover.SetupMode
|
import im.vector.app.features.crypto.recover.SetupMode
|
||||||
import im.vector.app.features.disclaimer.showDisclaimerDialog
|
import im.vector.app.features.disclaimer.showDisclaimerDialog
|
||||||
|
import im.vector.app.features.home.room.list.actions.RoomListSharedAction
|
||||||
|
import im.vector.app.features.home.room.list.actions.RoomListSharedActionViewModel
|
||||||
import im.vector.app.features.home.room.list.home.layout.HomeLayoutSettingBottomDialogFragment
|
import im.vector.app.features.home.room.list.home.layout.HomeLayoutSettingBottomDialogFragment
|
||||||
import im.vector.app.features.matrixto.MatrixToBottomSheet
|
import im.vector.app.features.matrixto.MatrixToBottomSheet
|
||||||
import im.vector.app.features.matrixto.OriginOfMatrixTo
|
import im.vector.app.features.matrixto.OriginOfMatrixTo
|
||||||
|
@ -110,6 +113,7 @@ class HomeActivity :
|
||||||
VectorMenuProvider {
|
VectorMenuProvider {
|
||||||
|
|
||||||
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
||||||
|
private lateinit var roomListSharedActionViewModel: RoomListSharedActionViewModel
|
||||||
|
|
||||||
private val homeActivityViewModel: HomeActivityViewModel by viewModel()
|
private val homeActivityViewModel: HomeActivityViewModel by viewModel()
|
||||||
|
|
||||||
|
@ -136,6 +140,8 @@ class HomeActivity :
|
||||||
@Inject lateinit var fcmHelper: FcmHelper
|
@Inject lateinit var fcmHelper: FcmHelper
|
||||||
@Inject lateinit var nightlyProxy: NightlyProxy
|
@Inject lateinit var nightlyProxy: NightlyProxy
|
||||||
|
|
||||||
|
private var isNewAppLayoutEnabled: Boolean = false // delete once old app layout is removed
|
||||||
|
|
||||||
private val createSpaceResultLauncher = registerStartForActivityResult { activityResult ->
|
private val createSpaceResultLauncher = registerStartForActivityResult { activityResult ->
|
||||||
if (activityResult.resultCode == Activity.RESULT_OK) {
|
if (activityResult.resultCode == Activity.RESULT_OK) {
|
||||||
val spaceId = SpaceCreationActivity.getCreatedSpaceId(activityResult.data)
|
val spaceId = SpaceCreationActivity.getCreatedSpaceId(activityResult.data)
|
||||||
|
@ -155,8 +161,9 @@ class HomeActivity :
|
||||||
navigator.switchToSpace(
|
navigator.switchToSpace(
|
||||||
context = this,
|
context = this,
|
||||||
spaceId = spaceId,
|
spaceId = spaceId,
|
||||||
postSwitchOption
|
postSwitchOption,
|
||||||
)
|
)
|
||||||
|
roomListSharedActionViewModel.post(RoomListSharedAction.CloseBottomSheet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,6 +200,7 @@ class HomeActivity :
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
isNewAppLayoutEnabled = vectorFeatures.isNewAppLayoutEnabled()
|
||||||
analyticsScreenName = MobileScreen.ScreenName.Home
|
analyticsScreenName = MobileScreen.ScreenName.Home
|
||||||
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
|
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
|
||||||
unifiedPushHelper.register(this) {
|
unifiedPushHelper.register(this) {
|
||||||
|
@ -205,6 +213,7 @@ class HomeActivity :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sharedActionViewModel = viewModelProvider[HomeSharedActionViewModel::class.java]
|
sharedActionViewModel = viewModelProvider[HomeSharedActionViewModel::class.java]
|
||||||
|
roomListSharedActionViewModel = viewModelProvider[RoomListSharedActionViewModel::class.java]
|
||||||
views.drawerLayout.addDrawerListener(drawerListener)
|
views.drawerLayout.addDrawerListener(drawerListener)
|
||||||
if (isFirstCreation()) {
|
if (isFirstCreation()) {
|
||||||
if (vectorFeatures.isNewAppLayoutEnabled()) {
|
if (vectorFeatures.isNewAppLayoutEnabled()) {
|
||||||
|
@ -561,6 +570,14 @@ class HomeActivity :
|
||||||
|
|
||||||
// Check nightly
|
// Check nightly
|
||||||
nightlyProxy.onHomeResumed()
|
nightlyProxy.onHomeResumed()
|
||||||
|
|
||||||
|
checkNewAppLayoutFlagChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkNewAppLayoutFlagChange() {
|
||||||
|
if (buildMeta.isDebug && vectorFeatures.isNewAppLayoutEnabled() != isNewAppLayoutEnabled) {
|
||||||
|
restart()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMenuRes() = if (vectorFeatures.isNewAppLayoutEnabled()) R.menu.menu_new_home else R.menu.menu_home
|
override fun getMenuRes() = if (vectorFeatures.isNewAppLayoutEnabled()) R.menu.menu_new_home else R.menu.menu_home
|
||||||
|
|
|
@ -186,7 +186,7 @@ class HomeDetailFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateBack() {
|
private fun navigateBack() {
|
||||||
val previousSpaceId = spaceStateHandler.getSpaceBackstack().removeLastOrNull()
|
val previousSpaceId = spaceStateHandler.popSpaceBackstack()
|
||||||
val parentSpaceId = spaceStateHandler.getCurrentSpace()?.flattenParentIds?.lastOrNull()
|
val parentSpaceId = spaceStateHandler.getCurrentSpace()?.flattenParentIds?.lastOrNull()
|
||||||
setCurrentSpace(previousSpaceId ?: parentSpaceId)
|
setCurrentSpace(previousSpaceId ?: parentSpaceId)
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,10 +116,14 @@ class HomeDrawerFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug menu
|
// Debug menu
|
||||||
views.homeDrawerHeaderDebugView.isVisible = buildMeta.isDebug && vectorPreferences.developerMode()
|
|
||||||
views.homeDrawerHeaderDebugView.debouncedClicks {
|
views.homeDrawerHeaderDebugView.debouncedClicks {
|
||||||
sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
|
sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
|
||||||
navigator.openDebug(requireActivity())
|
navigator.openDebug(requireActivity())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
views.homeDrawerHeaderDebugView.isVisible = buildMeta.isDebug && vectorPreferences.developerMode()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,12 @@ import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.airbnb.mvrx.activityViewModel
|
import com.airbnb.mvrx.activityViewModel
|
||||||
import com.airbnb.mvrx.fragmentViewModel
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.SpaceStateHandler
|
import im.vector.app.SpaceStateHandler
|
||||||
|
@ -35,6 +37,7 @@ import im.vector.app.core.platform.OnBackPressed
|
||||||
import im.vector.app.core.platform.VectorBaseActivity
|
import im.vector.app.core.platform.VectorBaseActivity
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.core.platform.VectorMenuProvider
|
import im.vector.app.core.platform.VectorMenuProvider
|
||||||
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.core.resources.ColorProvider
|
import im.vector.app.core.resources.ColorProvider
|
||||||
import im.vector.app.core.ui.views.CurrentCallsView
|
import im.vector.app.core.ui.views.CurrentCallsView
|
||||||
import im.vector.app.core.ui.views.CurrentCallsViewPresenter
|
import im.vector.app.core.ui.views.CurrentCallsViewPresenter
|
||||||
|
@ -74,6 +77,7 @@ class NewHomeDetailFragment :
|
||||||
@Inject lateinit var vectorPreferences: VectorPreferences
|
@Inject lateinit var vectorPreferences: VectorPreferences
|
||||||
@Inject lateinit var spaceStateHandler: SpaceStateHandler
|
@Inject lateinit var spaceStateHandler: SpaceStateHandler
|
||||||
@Inject lateinit var session: Session
|
@Inject lateinit var session: Session
|
||||||
|
@Inject lateinit var buildMeta: BuildMeta
|
||||||
|
|
||||||
private val viewModel: HomeDetailViewModel by fragmentViewModel()
|
private val viewModel: HomeDetailViewModel by fragmentViewModel()
|
||||||
private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
|
private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
|
||||||
|
@ -127,6 +131,7 @@ class NewHomeDetailFragment :
|
||||||
setupToolbar()
|
setupToolbar()
|
||||||
setupKeysBackupBanner()
|
setupKeysBackupBanner()
|
||||||
setupActiveCallView()
|
setupActiveCallView()
|
||||||
|
setupDebugButton()
|
||||||
|
|
||||||
childFragmentManager.commitTransaction {
|
childFragmentManager.commitTransaction {
|
||||||
add(R.id.roomListContainer, HomeRoomListFragment::class.java, null, HOME_ROOM_LIST_FRAGMENT_TAG)
|
add(R.id.roomListContainer, HomeRoomListFragment::class.java, null, HOME_ROOM_LIST_FRAGMENT_TAG)
|
||||||
|
@ -169,12 +174,6 @@ class NewHomeDetailFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateBack() {
|
|
||||||
val previousSpaceId = spaceStateHandler.getSpaceBackstack().removeLastOrNull()
|
|
||||||
val parentSpaceId = spaceStateHandler.getCurrentSpace()?.flattenParentIds?.lastOrNull()
|
|
||||||
setCurrentSpace(previousSpaceId ?: parentSpaceId)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setCurrentSpace(spaceId: String?) {
|
private fun setCurrentSpace(spaceId: String?) {
|
||||||
spaceStateHandler.setCurrentSpace(spaceId, isForwardNavigation = false)
|
spaceStateHandler.setCurrentSpace(spaceId, isForwardNavigation = false)
|
||||||
sharedActionViewModel.post(HomeActivitySharedAction.OnCloseSpace)
|
sharedActionViewModel.post(HomeActivitySharedAction.OnCloseSpace)
|
||||||
|
@ -189,6 +188,7 @@ class NewHomeDetailFragment :
|
||||||
super.onResume()
|
super.onResume()
|
||||||
callManager.checkForProtocolsSupportIfNeeded()
|
callManager.checkForProtocolsSupportIfNeeded()
|
||||||
refreshSpaceState()
|
refreshSpaceState()
|
||||||
|
refreshDebugButtonState()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun refreshSpaceState() {
|
private fun refreshSpaceState() {
|
||||||
|
@ -298,6 +298,21 @@ class NewHomeDetailFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupDebugButton() {
|
||||||
|
views.debugButton.debouncedClicks {
|
||||||
|
sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
|
||||||
|
navigator.openDebug(requireActivity())
|
||||||
|
}
|
||||||
|
|
||||||
|
views.appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
|
||||||
|
views.debugButton.isVisible = verticalOffset == 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshDebugButtonState() {
|
||||||
|
views.debugButton.isVisible = buildMeta.isDebug && vectorPreferences.developerMode()
|
||||||
|
}
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* KeysBackupBanner Listener
|
* KeysBackupBanner Listener
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
@ -337,13 +352,16 @@ class NewHomeDetailFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed(toolbarButton: Boolean) = if (spaceStateHandler.getCurrentSpace() != null) {
|
override fun onBackPressed(toolbarButton: Boolean) = if (spaceStateHandler.isRoot()) {
|
||||||
navigateBack()
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
false
|
||||||
|
} else {
|
||||||
|
val lastSpace = spaceStateHandler.popSpaceBackstack()
|
||||||
|
spaceStateHandler.setCurrentSpace(lastSpace, isForwardNavigation = false)
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun SpaceStateHandler.isRoot() = getSpaceBackstack().isEmpty()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val HOME_ROOM_LIST_FRAGMENT_TAG = "TAG_HOME_ROOM_LIST"
|
private const val HOME_ROOM_LIST_FRAGMENT_TAG = "TAG_HOME_ROOM_LIST"
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,13 +176,25 @@ class DefaultNavigator @Inject constructor(
|
||||||
startActivity(context, intent, buildTask)
|
startActivity(context, intent, buildTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun switchToSpace(context: Context, spaceId: String, postSwitchSpaceAction: Navigator.PostSwitchSpaceAction) {
|
override fun switchToSpace(
|
||||||
|
context: Context,
|
||||||
|
spaceId: String,
|
||||||
|
postSwitchSpaceAction: Navigator.PostSwitchSpaceAction,
|
||||||
|
) {
|
||||||
if (sessionHolder.getSafeActiveSession()?.getRoomSummary(spaceId) == null) {
|
if (sessionHolder.getSafeActiveSession()?.getRoomSummary(spaceId) == null) {
|
||||||
fatalError("Trying to open an unknown space $spaceId", vectorPreferences.failFast())
|
fatalError("Trying to open an unknown space $spaceId", vectorPreferences.failFast())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
spaceStateHandler.setCurrentSpace(spaceId)
|
spaceStateHandler.setCurrentSpace(spaceId)
|
||||||
when (postSwitchSpaceAction) {
|
handlePostSwitchAction(context, spaceId, postSwitchSpaceAction)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePostSwitchAction(
|
||||||
|
context: Context,
|
||||||
|
spaceId: String,
|
||||||
|
action: Navigator.PostSwitchSpaceAction,
|
||||||
|
) {
|
||||||
|
when (action) {
|
||||||
Navigator.PostSwitchSpaceAction.None -> {
|
Navigator.PostSwitchSpaceAction.None -> {
|
||||||
// go back to home if we are showing room details?
|
// go back to home if we are showing room details?
|
||||||
// This is a bit ugly, but the navigator is supposed to know about the activity stack
|
// This is a bit ugly, but the navigator is supposed to know about the activity stack
|
||||||
|
@ -198,9 +210,9 @@ class DefaultNavigator @Inject constructor(
|
||||||
}
|
}
|
||||||
is Navigator.PostSwitchSpaceAction.OpenDefaultRoom -> {
|
is Navigator.PostSwitchSpaceAction.OpenDefaultRoom -> {
|
||||||
val args = TimelineArgs(
|
val args = TimelineArgs(
|
||||||
postSwitchSpaceAction.roomId,
|
action.roomId,
|
||||||
eventId = null,
|
eventId = null,
|
||||||
openShareSpaceForId = spaceId.takeIf { postSwitchSpaceAction.showShareSheet }
|
openShareSpaceForId = spaceId.takeIf { action.showShareSheet }
|
||||||
)
|
)
|
||||||
val intent = RoomDetailActivity.newIntent(context, args, false)
|
val intent = RoomDetailActivity.newIntent(context, args, false)
|
||||||
startActivity(context, intent, false)
|
startActivity(context, intent, false)
|
||||||
|
|
|
@ -68,7 +68,11 @@ interface Navigator {
|
||||||
data class OpenDefaultRoom(val roomId: String, val showShareSheet: Boolean) : PostSwitchSpaceAction()
|
data class OpenDefaultRoom(val roomId: String, val showShareSheet: Boolean) : PostSwitchSpaceAction()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun switchToSpace(context: Context, spaceId: String, postSwitchSpaceAction: PostSwitchSpaceAction)
|
fun switchToSpace(
|
||||||
|
context: Context,
|
||||||
|
spaceId: String,
|
||||||
|
postSwitchSpaceAction: PostSwitchSpaceAction,
|
||||||
|
)
|
||||||
|
|
||||||
fun openSpacePreview(context: Context, spaceId: String)
|
fun openSpacePreview(context: Context, spaceId: String)
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ class VectorPreferences @Inject constructor(
|
||||||
const val SETTINGS_ALLOW_INTEGRATIONS_KEY = "SETTINGS_ALLOW_INTEGRATIONS_KEY"
|
const val SETTINGS_ALLOW_INTEGRATIONS_KEY = "SETTINGS_ALLOW_INTEGRATIONS_KEY"
|
||||||
const val SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY = "SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY"
|
const val SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY = "SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY"
|
||||||
const val SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY = "SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY"
|
const val SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY = "SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY"
|
||||||
|
const val SETTINGS_PERSISTED_SPACE_BACKSTACK = "SETTINGS_PERSISTED_SPACE_BACKSTACK"
|
||||||
|
|
||||||
const val SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT = "SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT"
|
const val SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT = "SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT"
|
||||||
// const val SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY = "SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY"
|
// const val SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY = "SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY"
|
||||||
|
@ -1126,6 +1127,25 @@ class VectorPreferences @Inject constructor(
|
||||||
.apply()
|
.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the space backstack that is used for up navigation.
|
||||||
|
* This needs to be persisted because navigating up through spaces should work across sessions.
|
||||||
|
*
|
||||||
|
* Only the IDs of the spaces are stored.
|
||||||
|
*/
|
||||||
|
fun setSpaceBackstack(spaceBackstack: List<String?>) {
|
||||||
|
val spaceIdsJoined = spaceBackstack.takeIf { it.isNotEmpty() }?.joinToString(",")
|
||||||
|
defaultPrefs.edit().putString(SETTINGS_PERSISTED_SPACE_BACKSTACK, spaceIdsJoined).apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the space backstack used for up navigation.
|
||||||
|
*/
|
||||||
|
fun getSpaceBackstack(): List<String?> {
|
||||||
|
val spaceIdsJoined = defaultPrefs.getString(SETTINGS_PERSISTED_SPACE_BACKSTACK, null)
|
||||||
|
return spaceIdsJoined?.takeIf { it.isNotEmpty() }?.split(",").orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
fun showLiveSenderInfo(): Boolean {
|
fun showLiveSenderInfo(): Boolean {
|
||||||
return defaultPrefs.getBoolean(SETTINGS_TIMELINE_SHOW_LIVE_SENDER_INFO, getDefault(R.bool.settings_timeline_show_live_sender_info_default))
|
return defaultPrefs.getBoolean(SETTINGS_TIMELINE_SHOW_LIVE_SENDER_INFO, getDefault(R.bool.settings_timeline_show_live_sender_info_default))
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,6 @@ class NewSpaceSummaryController @Inject constructor(
|
||||||
homeCount: RoomAggregateNotificationCount,
|
homeCount: RoomAggregateNotificationCount,
|
||||||
expandedStates: Map<String, Boolean>,
|
expandedStates: Map<String, Boolean>,
|
||||||
) {
|
) {
|
||||||
newSpaceListHeaderItem {
|
|
||||||
id("space_list_header")
|
|
||||||
}
|
|
||||||
|
|
||||||
addHomeItem(selectedSpace == null, homeCount)
|
addHomeItem(selectedSpace == null, homeCount)
|
||||||
addSpaces(spaceSummaries, selectedSpace, rootSpaces, expandedStates)
|
addSpaces(spaceSummaries, selectedSpace, rootSpaces, expandedStates)
|
||||||
addCreateItem()
|
addCreateItem()
|
||||||
|
|
|
@ -65,7 +65,7 @@ class SpaceListViewModel @AssistedInject constructor(
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val autoAcceptInvites: AutoAcceptInvites,
|
private val autoAcceptInvites: AutoAcceptInvites,
|
||||||
private val analyticsTracker: AnalyticsTracker
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
) : VectorViewModel<SpaceListViewState, SpaceListAction, SpaceListViewEvents>(initialState) {
|
) : VectorViewModel<SpaceListViewState, SpaceListAction, SpaceListViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
@ -88,9 +88,7 @@ class SpaceListViewModel @AssistedInject constructor(
|
||||||
spaceStateHandler.getSelectedSpaceFlow()
|
spaceStateHandler.getSelectedSpaceFlow()
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.setOnEach { selectedSpaceOption ->
|
.setOnEach { selectedSpaceOption ->
|
||||||
copy(
|
copy(selectedSpace = selectedSpaceOption.orNull())
|
||||||
selectedSpace = selectedSpaceOption.orNull()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX there should be a way to refactor this and share it
|
// XXX there should be a way to refactor this and share it
|
||||||
|
|
|
@ -74,6 +74,19 @@
|
||||||
|
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
</com.google.android.material.appbar.MaterialToolbar>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/debug_button"
|
||||||
|
style="@style/VectorDebug"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/ic_settings_x"
|
||||||
|
app:tint="?colorPrimary"
|
||||||
|
tools:ignore="MissingPrefix" />
|
||||||
|
|
||||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
style="@style/TextAppearance.Vector.Body.Medium"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@drawable/bg_space_item"
|
|
||||||
android:ellipsize="middle"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text="@string/change_space"
|
|
||||||
android:textAllCaps="true"
|
|
||||||
android:textColor="?vctr_content_tertiary"
|
|
||||||
android:textSize="14sp"
|
|
||||||
tools:viewBindingIgnore="true" />
|
|
|
@ -139,7 +139,6 @@
|
||||||
<string name="all_chats">All Chats</string>
|
<string name="all_chats">All Chats</string>
|
||||||
<string name="start_chat">Start Chat</string>
|
<string name="start_chat">Start Chat</string>
|
||||||
<string name="create_room">Create Room</string>
|
<string name="create_room">Create Room</string>
|
||||||
<string name="change_space">Change Space</string>
|
|
||||||
<string name="explore_rooms">Explore Rooms</string>
|
<string name="explore_rooms">Explore Rooms</string>
|
||||||
<string name="a11y_expand_space_children">Expand space children</string>
|
<string name="a11y_expand_space_children">Expand space children</string>
|
||||||
<string name="a11y_collapse_space_children">Collapse space children</string>
|
<string name="a11y_collapse_space_children">Collapse space children</string>
|
||||||
|
|
|
@ -21,11 +21,13 @@ import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||||
import im.vector.app.test.fakes.FakeAnalyticsTracker
|
import im.vector.app.test.fakes.FakeAnalyticsTracker
|
||||||
import im.vector.app.test.fakes.FakeSession
|
import im.vector.app.test.fakes.FakeSession
|
||||||
import im.vector.app.test.fakes.FakeUiStateRepository
|
import im.vector.app.test.fakes.FakeUiStateRepository
|
||||||
|
import im.vector.app.test.fakes.FakeVectorPreferences
|
||||||
import im.vector.app.test.fixtures.RoomSummaryFixture.aRoomSummary
|
import im.vector.app.test.fixtures.RoomSummaryFixture.aRoomSummary
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.amshove.kluent.shouldBe
|
import org.amshove.kluent.shouldBe
|
||||||
import org.amshove.kluent.shouldBeEqualTo
|
import org.amshove.kluent.shouldBeEqualTo
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
internal class SpaceStateHandlerImplTest {
|
internal class SpaceStateHandlerImplTest {
|
||||||
|
@ -38,14 +40,21 @@ internal class SpaceStateHandlerImplTest {
|
||||||
private val uiStateRepository = FakeUiStateRepository()
|
private val uiStateRepository = FakeUiStateRepository()
|
||||||
private val activeSessionHolder = FakeActiveSessionHolder(session)
|
private val activeSessionHolder = FakeActiveSessionHolder(session)
|
||||||
private val analyticsTracker = FakeAnalyticsTracker()
|
private val analyticsTracker = FakeAnalyticsTracker()
|
||||||
|
private val vectorPreferences = FakeVectorPreferences()
|
||||||
|
|
||||||
private val spaceStateHandler = SpaceStateHandlerImpl(
|
private val spaceStateHandler = SpaceStateHandlerImpl(
|
||||||
sessionDataSource.instance,
|
sessionDataSource.instance,
|
||||||
uiStateRepository,
|
uiStateRepository,
|
||||||
activeSessionHolder.instance,
|
activeSessionHolder.instance,
|
||||||
analyticsTracker,
|
analyticsTracker,
|
||||||
|
vectorPreferences.instance,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
vectorPreferences.givenSpaceBackstack(emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given selected space doesn't exist, when getCurrentSpace, then return null`() {
|
fun `given selected space doesn't exist, when getCurrentSpace, then return null`() {
|
||||||
val currentSpace = spaceStateHandler.getCurrentSpace()
|
val currentSpace = spaceStateHandler.getCurrentSpace()
|
||||||
|
@ -77,33 +86,33 @@ internal class SpaceStateHandlerImplTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given is forward navigation and no current space, when setCurrentSpace, then null added to backstack`() {
|
fun `given not in space and is forward navigation, when setCurrentSpace, then null added to backstack`() {
|
||||||
spaceStateHandler.setCurrentSpace(spaceId, session, isForwardNavigation = true)
|
spaceStateHandler.setCurrentSpace(spaceId, session, isForwardNavigation = true)
|
||||||
|
|
||||||
val backstack = spaceStateHandler.getSpaceBackstack()
|
vectorPreferences.verifySetSpaceBackstack(listOf(null))
|
||||||
|
|
||||||
backstack.size shouldBe 1
|
|
||||||
backstack.first() shouldBe null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given is forward navigation and is in space, when setCurrentSpace, then previous space added to backstack`() {
|
fun `given in space and is forward navigation, when setCurrentSpace, then previous space added to backstack`() {
|
||||||
spaceStateHandler.setCurrentSpace(spaceId, session, isForwardNavigation = true)
|
spaceStateHandler.setCurrentSpace(spaceId, session, isForwardNavigation = true)
|
||||||
spaceStateHandler.setCurrentSpace("secondSpaceId", session, isForwardNavigation = true)
|
spaceStateHandler.setCurrentSpace("secondSpaceId", session, isForwardNavigation = true)
|
||||||
|
|
||||||
val backstack = spaceStateHandler.getSpaceBackstack()
|
vectorPreferences.verifySetSpaceBackstack(listOf(spaceId))
|
||||||
|
|
||||||
backstack.size shouldBe 2
|
|
||||||
backstack shouldBeEqualTo listOf(null, spaceId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given is not forward navigation, when setCurrentSpace, then previous space not added to backstack`() {
|
fun `given is not forward navigation, when setCurrentSpace, then previous space not added to backstack`() {
|
||||||
spaceStateHandler.setCurrentSpace(spaceId, session, isForwardNavigation = false)
|
spaceStateHandler.setCurrentSpace(spaceId, session, isForwardNavigation = false)
|
||||||
|
|
||||||
val backstack = spaceStateHandler.getSpaceBackstack()
|
vectorPreferences.verifySetSpaceBackstack(listOf(spaceId), inverse = true)
|
||||||
|
}
|
||||||
|
|
||||||
backstack.size shouldBe 0
|
@Test
|
||||||
|
fun `given navigating to all chats, when setCurrentSpace, then backstack cleared`() {
|
||||||
|
spaceStateHandler.setCurrentSpace(spaceId, session)
|
||||||
|
spaceStateHandler.setCurrentSpace(null, session)
|
||||||
|
|
||||||
|
vectorPreferences.verifySetSpaceBackstack(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* 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.navigation
|
||||||
|
|
||||||
|
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||||
|
import im.vector.app.test.fakes.FakeAnalyticsTracker
|
||||||
|
import im.vector.app.test.fakes.FakeContext
|
||||||
|
import im.vector.app.test.fakes.FakeDebugNavigator
|
||||||
|
import im.vector.app.test.fakes.FakeSpaceStateHandler
|
||||||
|
import im.vector.app.test.fakes.FakeSupportedVerificationMethodsProvider
|
||||||
|
import im.vector.app.test.fakes.FakeVectorFeatures
|
||||||
|
import im.vector.app.test.fakes.FakeVectorPreferences
|
||||||
|
import im.vector.app.test.fakes.FakeWidgetArgsBuilder
|
||||||
|
import im.vector.app.test.fixtures.RoomSummaryFixture.aRoomSummary
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
internal class DefaultNavigatorTest {
|
||||||
|
|
||||||
|
private val sessionHolder = FakeActiveSessionHolder()
|
||||||
|
private val vectorPreferences = FakeVectorPreferences()
|
||||||
|
private val widgetArgsBuilder = FakeWidgetArgsBuilder()
|
||||||
|
private val spaceStateHandler = FakeSpaceStateHandler()
|
||||||
|
private val supportedVerificationMethodsProvider = FakeSupportedVerificationMethodsProvider()
|
||||||
|
private val features = FakeVectorFeatures()
|
||||||
|
private val analyticsTracker = FakeAnalyticsTracker()
|
||||||
|
private val debugNavigator = FakeDebugNavigator()
|
||||||
|
|
||||||
|
private val navigator = DefaultNavigator(
|
||||||
|
sessionHolder.instance,
|
||||||
|
vectorPreferences.instance,
|
||||||
|
widgetArgsBuilder.instance,
|
||||||
|
spaceStateHandler,
|
||||||
|
supportedVerificationMethodsProvider.instance,
|
||||||
|
features,
|
||||||
|
analyticsTracker,
|
||||||
|
debugNavigator,
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The below test is by no means all that we want to test in [DefaultNavigator].
|
||||||
|
* Please add relevant tests as you make changes to or related to other functions in the class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `when switchToSpace, then current space set`() {
|
||||||
|
val spaceId = "space-id"
|
||||||
|
val spaceSummary = aRoomSummary(spaceId)
|
||||||
|
sessionHolder.fakeSession.fakeRoomService.getRoomSummaryReturns(spaceSummary)
|
||||||
|
|
||||||
|
navigator.switchToSpace(FakeContext().instance, spaceId, Navigator.PostSwitchSpaceAction.None)
|
||||||
|
|
||||||
|
spaceStateHandler.verifySetCurrentSpace(spaceId)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* 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.test.fakes
|
||||||
|
|
||||||
|
import im.vector.app.core.debug.DebugNavigator
|
||||||
|
import io.mockk.mockk
|
||||||
|
|
||||||
|
class FakeDebugNavigator : DebugNavigator by mockk()
|
|
@ -16,12 +16,18 @@
|
||||||
|
|
||||||
package im.vector.app.test.fakes
|
package im.vector.app.test.fakes
|
||||||
|
|
||||||
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import org.matrix.android.sdk.api.session.room.RoomService
|
import org.matrix.android.sdk.api.session.room.RoomService
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
|
||||||
class FakeRoomService(
|
class FakeRoomService(
|
||||||
private val fakeRoom: FakeRoom = FakeRoom()
|
private val fakeRoom: FakeRoom = FakeRoom()
|
||||||
) : RoomService by mockk() {
|
) : RoomService by mockk() {
|
||||||
|
|
||||||
override fun getRoom(roomId: String) = fakeRoom
|
override fun getRoom(roomId: String) = fakeRoom
|
||||||
|
|
||||||
|
fun getRoomSummaryReturns(roomSummary: RoomSummary?) {
|
||||||
|
every { getRoomSummary(any()) } returns roomSummary
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ class FakeSession(
|
||||||
val fakeProfileService: FakeProfileService = FakeProfileService(),
|
val fakeProfileService: FakeProfileService = FakeProfileService(),
|
||||||
val fakeHomeServerCapabilitiesService: FakeHomeServerCapabilitiesService = FakeHomeServerCapabilitiesService(),
|
val fakeHomeServerCapabilitiesService: FakeHomeServerCapabilitiesService = FakeHomeServerCapabilitiesService(),
|
||||||
val fakeSharedSecretStorageService: FakeSharedSecretStorageService = FakeSharedSecretStorageService(),
|
val fakeSharedSecretStorageService: FakeSharedSecretStorageService = FakeSharedSecretStorageService(),
|
||||||
private val fakeRoomService: FakeRoomService = FakeRoomService(),
|
val fakeRoomService: FakeRoomService = FakeRoomService(),
|
||||||
private val fakeEventService: FakeEventService = FakeEventService(),
|
private val fakeEventService: FakeEventService = FakeEventService(),
|
||||||
) : Session by mockk(relaxed = true) {
|
) : Session by mockk(relaxed = true) {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 New Vector Ltd
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -14,14 +14,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.spaces
|
package im.vector.app.test.fakes
|
||||||
|
|
||||||
import com.airbnb.epoxy.EpoxyModelClass
|
import im.vector.app.SpaceStateHandler
|
||||||
import im.vector.app.R
|
import io.mockk.mockk
|
||||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
import io.mockk.verify
|
||||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
|
||||||
|
|
||||||
@EpoxyModelClass
|
class FakeSpaceStateHandler : SpaceStateHandler by mockk(relaxUnitFun = true) {
|
||||||
abstract class NewSpaceListHeaderItem : VectorEpoxyModel<NewSpaceListHeaderItem.Holder>(R.layout.item_new_space_list_header) {
|
|
||||||
class Holder : VectorEpoxyHolder()
|
fun verifySetCurrentSpace(spaceId: String) {
|
||||||
|
verify { setCurrentSpace(spaceId) }
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* 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.test.fakes
|
||||||
|
|
||||||
|
import im.vector.app.features.crypto.verification.SupportedVerificationMethodsProvider
|
||||||
|
import io.mockk.mockk
|
||||||
|
|
||||||
|
class FakeSupportedVerificationMethodsProvider {
|
||||||
|
|
||||||
|
val instance = mockk<SupportedVerificationMethodsProvider>()
|
||||||
|
}
|
|
@ -19,12 +19,21 @@ package im.vector.app.test.fakes
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
|
import io.mockk.verify
|
||||||
|
|
||||||
class FakeVectorPreferences {
|
class FakeVectorPreferences {
|
||||||
|
|
||||||
val instance = mockk<VectorPreferences>()
|
val instance = mockk<VectorPreferences>(relaxUnitFun = true)
|
||||||
|
|
||||||
fun givenUseCompleteNotificationFormat(value: Boolean) {
|
fun givenUseCompleteNotificationFormat(value: Boolean) {
|
||||||
every { instance.useCompleteNotificationFormat() } returns value
|
every { instance.useCompleteNotificationFormat() } returns value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun givenSpaceBackstack(value: List<String?>) {
|
||||||
|
every { instance.getSpaceBackstack() } returns value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun verifySetSpaceBackstack(value: List<String?>, inverse: Boolean = false) {
|
||||||
|
verify(inverse = inverse) { instance.setSpaceBackstack(value) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* 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.test.fakes
|
||||||
|
|
||||||
|
import im.vector.app.features.widgets.WidgetArgsBuilder
|
||||||
|
import io.mockk.mockk
|
||||||
|
|
||||||
|
class FakeWidgetArgsBuilder {
|
||||||
|
|
||||||
|
val instance = mockk<WidgetArgsBuilder>()
|
||||||
|
}
|
Loading…
Reference in a new issue