diff --git a/changelog.d/7693.feature b/changelog.d/7693.feature
new file mode 100644
index 0000000000..271964db82
--- /dev/null
+++ b/changelog.d/7693.feature
@@ -0,0 +1 @@
+[Session manager] Add action to signout all the other session
diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml
index 4158ff31bc..609cdac233 100644
--- a/library/ui-strings/src/main/res/values/strings.xml
+++ b/library/ui-strings/src/main/res/values/strings.xml
@@ -3363,6 +3363,7 @@
- Sign out of %1$d session
- Sign out of %1$d sessions
+ Sign out of all other sessions
Show IP address
Hide IP address
Sign out of this session
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 b27d8a7270..d748600416 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
@@ -53,6 +53,7 @@ import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationVie
import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
import im.vector.app.features.settings.devices.v2.signout.BuildConfirmSignoutDialogUseCase
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
+import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
import javax.inject.Inject
@@ -99,6 +100,7 @@ class VectorSettingsDevicesFragment :
super.onViewCreated(view, savedInstanceState)
initWaitingView()
+ initCurrentSessionHeaderView()
initOtherSessionsHeaderView()
initOtherSessionsView()
initSecurityRecommendationsView()
@@ -139,6 +141,18 @@ class VectorSettingsDevicesFragment :
views.waitingView.waitingStatusText.isVisible = true
}
+ private fun initCurrentSessionHeaderView() {
+ views.deviceListHeaderCurrentSession.setOnMenuItemClickListener { menuItem ->
+ when (menuItem.itemId) {
+ R.id.currentSessionHeaderSignoutOtherSessions -> {
+ confirmMultiSignoutOtherSessions()
+ true
+ }
+ else -> false
+ }
+ }
+ }
+
private fun initOtherSessionsHeaderView() {
views.deviceListHeaderOtherSessions.setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) {
@@ -247,7 +261,7 @@ class VectorSettingsDevicesFragment :
val otherDevices = devices?.filter { it.deviceInfo.deviceId != currentDeviceId }
renderSecurityRecommendations(state.inactiveSessionsCount, state.unverifiedSessionsCount, isCurrentSessionVerified)
- renderCurrentDevice(currentDeviceInfo)
+ renderCurrentSessionView(currentDeviceInfo, hasOtherDevices = otherDevices?.isNotEmpty().orFalse())
renderOtherSessionsView(otherDevices, state.isShowingIpAddress)
} else {
hideSecurityRecommendations()
@@ -310,11 +324,11 @@ class VectorSettingsDevicesFragment :
hideOtherSessionsView()
} else {
views.deviceListHeaderOtherSessions.isVisible = true
- val color = colorProvider.getColorFromAttribute(R.attr.colorError)
+ val colorDestructive = colorProvider.getColorFromAttribute(R.attr.colorError)
val multiSignoutItem = views.deviceListHeaderOtherSessions.menu.findItem(R.id.otherSessionsHeaderMultiSignout)
val nbDevices = otherDevices.size
multiSignoutItem.title = stringProvider.getQuantityString(R.plurals.device_manager_other_sessions_multi_signout_all, nbDevices, nbDevices)
- multiSignoutItem.setTextColor(color)
+ multiSignoutItem.setTextColor(colorDestructive)
views.deviceListOtherSessions.isVisible = true
val devices = if (isShowingIpAddress) otherDevices else otherDevices.map { it.copy(deviceInfo = it.deviceInfo.copy(lastSeenIp = null)) }
views.deviceListOtherSessions.render(
@@ -327,7 +341,7 @@ class VectorSettingsDevicesFragment :
} else {
stringProvider.getString(R.string.device_manager_other_sessions_show_ip_address)
}
- }
+ }
}
private fun hideOtherSessionsView() {
@@ -335,9 +349,13 @@ class VectorSettingsDevicesFragment :
views.deviceListOtherSessions.isVisible = false
}
- private fun renderCurrentDevice(currentDeviceInfo: DeviceFullInfo?) {
+ private fun renderCurrentSessionView(currentDeviceInfo: DeviceFullInfo?, hasOtherDevices: Boolean) {
currentDeviceInfo?.let {
views.deviceListHeaderCurrentSession.isVisible = true
+ val colorDestructive = colorProvider.getColorFromAttribute(R.attr.colorError)
+ val signoutOtherSessionsItem = views.deviceListHeaderCurrentSession.menu.findItem(R.id.currentSessionHeaderSignoutOtherSessions)
+ signoutOtherSessionsItem.setTextColor(colorDestructive)
+ signoutOtherSessionsItem.isVisible = hasOtherDevices
views.deviceListCurrentSession.isVisible = true
val viewState = SessionInfoViewState(
isCurrentSession = true,
diff --git a/vector/src/main/res/layout/fragment_settings_devices.xml b/vector/src/main/res/layout/fragment_settings_devices.xml
index 8134774887..731049f3a2 100644
--- a/vector/src/main/res/layout/fragment_settings_devices.xml
+++ b/vector/src/main/res/layout/fragment_settings_devices.xml
@@ -67,6 +67,7 @@
app:layout_constraintTop_toBottomOf="@id/deviceListSecurityRecommendationsDivider"
app:sessionsListHeaderDescription=""
app:sessionsListHeaderHasLearnMoreLink="false"
+ app:sessionsListHeaderMenu="@menu/menu_current_session_header"
app:sessionsListHeaderTitle="@string/device_manager_current_session_title" />
+