From 8941e6396c555b0fa17230ad4629356875d04837 Mon Sep 17 00:00:00 2001 From: Benoit Marty <benoit@matrix.org> Date: Tue, 22 Aug 2023 12:04:38 +0200 Subject: [PATCH] Hide multi signout if we have an external account manager (#8616) --- .../settings/devices/v2/DevicesViewModel.kt | 14 +++++++++++++- .../settings/devices/v2/DevicesViewState.kt | 1 + .../v2/VectorSettingsDevicesFragment.kt | 18 +++++++++++------- .../v2/othersessions/OtherSessionsFragment.kt | 11 ++++++++--- .../v2/othersessions/OtherSessionsViewModel.kt | 14 +++++++++++++- .../v2/othersessions/OtherSessionsViewState.kt | 1 + 6 files changed, 47 insertions(+), 12 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt index f2e6b25f32..369150d45e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt @@ -40,7 +40,7 @@ import timber.log.Timber class DevicesViewModel @AssistedInject constructor( @Assisted initialState: DevicesViewState, - activeSessionHolder: ActiveSessionHolder, + private val activeSessionHolder: ActiveSessionHolder, private val getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase, private val getDeviceFullInfoListUseCase: GetDeviceFullInfoListUseCase, private val refreshDevicesOnCryptoDevicesChangeUseCase: RefreshDevicesOnCryptoDevicesChangeUseCase, @@ -69,6 +69,18 @@ class DevicesViewModel @AssistedInject constructor( refreshDeviceList() refreshIpAddressVisibility() observePreferences() + initExternalAccountManagementUrl() + } + + private fun initExternalAccountManagementUrl() { + setState { + copy( + externalAccountManagementUrl = activeSessionHolder.getSafeActiveSession() + ?.homeServerCapabilitiesService() + ?.getHomeServerCapabilities() + ?.externalAccountManagementUrl + ) + } } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt index 75d0f132bb..863ecd17a3 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt @@ -26,6 +26,7 @@ data class DevicesViewState( val devices: Async<DeviceFullInfoList> = Uninitialized, val isLoading: Boolean = false, val isShowingIpAddress: Boolean = false, + val externalAccountManagementUrl: String? = null, ) : MavericksState data class DeviceFullInfoList( diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt index ec21970f94..2850064609 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt @@ -290,8 +290,8 @@ class VectorSettingsDevicesFragment : val unverifiedSessionsCount = deviceFullInfoList?.unverifiedSessionsCount ?: 0 renderSecurityRecommendations(inactiveSessionsCount, unverifiedSessionsCount) - renderCurrentSessionView(currentDeviceInfo, hasOtherDevices = otherDevices?.isNotEmpty().orFalse()) - renderOtherSessionsView(otherDevices, state.isShowingIpAddress) + renderCurrentSessionView(currentDeviceInfo, hasOtherDevices = otherDevices?.isNotEmpty().orFalse(), state) + renderOtherSessionsView(otherDevices, state) } else { hideSecurityRecommendations() hideCurrentSessionView() @@ -347,13 +347,16 @@ class VectorSettingsDevicesFragment : hideInactiveSessionsRecommendation() } - private fun renderOtherSessionsView(otherDevices: List<DeviceFullInfo>?, isShowingIpAddress: Boolean) { + private fun renderOtherSessionsView(otherDevices: List<DeviceFullInfo>?, state: DevicesViewState) { + val isShowingIpAddress = state.isShowingIpAddress if (otherDevices.isNullOrEmpty()) { hideOtherSessionsView() } else { views.deviceListHeaderOtherSessions.isVisible = true val colorDestructive = colorProvider.getColorFromAttribute(R.attr.colorError) val multiSignoutItem = views.deviceListHeaderOtherSessions.menu.findItem(R.id.otherSessionsHeaderMultiSignout) + // Hide multi signout if we have an external account manager + multiSignoutItem.isVisible = state.externalAccountManagementUrl == null val nbDevices = otherDevices.size multiSignoutItem.title = stringProvider.getQuantityString(R.plurals.device_manager_other_sessions_multi_signout_all, nbDevices, nbDevices) multiSignoutItem.setTextColor(colorDestructive) @@ -377,23 +380,24 @@ class VectorSettingsDevicesFragment : views.deviceListOtherSessions.isVisible = false } - private fun renderCurrentSessionView(currentDeviceInfo: DeviceFullInfo?, hasOtherDevices: Boolean) { + private fun renderCurrentSessionView(currentDeviceInfo: DeviceFullInfo?, hasOtherDevices: Boolean, state: DevicesViewState) { currentDeviceInfo?.let { - renderCurrentSessionHeaderView(hasOtherDevices) + renderCurrentSessionHeaderView(hasOtherDevices, state) renderCurrentSessionListView(it) } ?: run { hideCurrentSessionView() } } - private fun renderCurrentSessionHeaderView(hasOtherDevices: Boolean) { + private fun renderCurrentSessionHeaderView(hasOtherDevices: Boolean, state: DevicesViewState) { views.deviceListHeaderCurrentSession.isVisible = true val colorDestructive = colorProvider.getColorFromAttribute(R.attr.colorError) val signoutSessionItem = views.deviceListHeaderCurrentSession.menu.findItem(R.id.currentSessionHeaderSignout) signoutSessionItem.setTextColor(colorDestructive) val signoutOtherSessionsItem = views.deviceListHeaderCurrentSession.menu.findItem(R.id.currentSessionHeaderSignoutOtherSessions) signoutOtherSessionsItem.setTextColor(colorDestructive) - signoutOtherSessionsItem.isVisible = hasOtherDevices + // Hide signout other sessions if we have an external account manager + signoutOtherSessionsItem.isVisible = hasOtherDevices && state.externalAccountManagementUrl == null } private fun renderCurrentSessionListView(currentDeviceInfo: DeviceFullInfo) { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsFragment.kt index 78075ca185..f935cb83ab 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsFragment.kt @@ -103,10 +103,15 @@ class OtherSessionsFragment : val nbDevices = viewState.devices()?.size ?: 0 stringProvider.getQuantityString(R.plurals.device_manager_other_sessions_multi_signout_all, nbDevices, nbDevices) } - multiSignoutItem.isVisible = if (viewState.isSelectModeEnabled) { - viewState.devices.invoke()?.any { it.isSelected }.orFalse() + multiSignoutItem.isVisible = if (viewState.externalAccountManagementUrl != null) { + // Hide multi signout if we have an external account manager + false } else { - viewState.devices.invoke()?.isNotEmpty().orFalse() + if (viewState.isSelectModeEnabled) { + viewState.devices.invoke()?.any { it.isSelected }.orFalse() + } else { + viewState.devices.invoke()?.isNotEmpty().orFalse() + } } val showAsActionFlag = if (viewState.isSelectModeEnabled) MenuItem.SHOW_AS_ACTION_IF_ROOM else MenuItem.SHOW_AS_ACTION_NEVER multiSignoutItem.setShowAsAction(showAsActionFlag or MenuItem.SHOW_AS_ACTION_WITH_TEXT) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsViewModel.kt index a5282e7ba2..3d41850027 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsViewModel.kt @@ -41,7 +41,7 @@ import timber.log.Timber class OtherSessionsViewModel @AssistedInject constructor( @Assisted private val initialState: OtherSessionsViewState, - activeSessionHolder: ActiveSessionHolder, + private val activeSessionHolder: ActiveSessionHolder, private val getDeviceFullInfoListUseCase: GetDeviceFullInfoListUseCase, private val signoutSessionsUseCase: SignoutSessionsUseCase, private val pendingAuthHandler: PendingAuthHandler, @@ -65,6 +65,18 @@ class OtherSessionsViewModel @AssistedInject constructor( observeDevices(initialState.currentFilter) refreshIpAddressVisibility() observePreferences() + initExternalAccountManagementUrl() + } + + private fun initExternalAccountManagementUrl() { + setState { + copy( + externalAccountManagementUrl = activeSessionHolder.getSafeActiveSession() + ?.homeServerCapabilitiesService() + ?.getHomeServerCapabilities() + ?.externalAccountManagementUrl + ) + } } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsViewState.kt index f4dd3640ee..ccb3e57f41 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/othersessions/OtherSessionsViewState.kt @@ -29,6 +29,7 @@ data class OtherSessionsViewState( val isSelectModeEnabled: Boolean = false, val isLoading: Boolean = false, val isShowingIpAddress: Boolean = false, + val externalAccountManagementUrl: String? = null, ) : MavericksState { constructor(args: OtherSessionsArgs) : this(excludeCurrentDevice = args.excludeCurrentDevice)