Merge pull request #7707 from vector-im/feature/mna/rename-and-signout-action-current-session
[Session manager] Add actions to rename and signout current session (PSG-885)
This commit is contained in:
commit
c580090f20
1
changelog.d/7697.feature
Normal file
1
changelog.d/7697.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
[Session manager] Add actions to rename and signout current session
|
@ -52,6 +52,7 @@ import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationVie
|
|||||||
import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationViewState
|
import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationViewState
|
||||||
import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
|
import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
|
||||||
import im.vector.app.features.settings.devices.v2.signout.BuildConfirmSignoutDialogUseCase
|
import im.vector.app.features.settings.devices.v2.signout.BuildConfirmSignoutDialogUseCase
|
||||||
|
import im.vector.app.features.workers.signout.SignOutUiWorker
|
||||||
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
|
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
|
||||||
@ -101,6 +102,7 @@ class VectorSettingsDevicesFragment :
|
|||||||
|
|
||||||
initWaitingView()
|
initWaitingView()
|
||||||
initCurrentSessionHeaderView()
|
initCurrentSessionHeaderView()
|
||||||
|
initCurrentSessionView()
|
||||||
initOtherSessionsHeaderView()
|
initOtherSessionsHeaderView()
|
||||||
initOtherSessionsView()
|
initOtherSessionsView()
|
||||||
initSecurityRecommendationsView()
|
initSecurityRecommendationsView()
|
||||||
@ -144,6 +146,14 @@ class VectorSettingsDevicesFragment :
|
|||||||
private fun initCurrentSessionHeaderView() {
|
private fun initCurrentSessionHeaderView() {
|
||||||
views.deviceListHeaderCurrentSession.setOnMenuItemClickListener { menuItem ->
|
views.deviceListHeaderCurrentSession.setOnMenuItemClickListener { menuItem ->
|
||||||
when (menuItem.itemId) {
|
when (menuItem.itemId) {
|
||||||
|
R.id.currentSessionHeaderRename -> {
|
||||||
|
navigateToRenameCurrentSession()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
R.id.currentSessionHeaderSignout -> {
|
||||||
|
confirmSignoutCurrentSession()
|
||||||
|
true
|
||||||
|
}
|
||||||
R.id.currentSessionHeaderSignoutOtherSessions -> {
|
R.id.currentSessionHeaderSignoutOtherSessions -> {
|
||||||
confirmMultiSignoutOtherSessions()
|
confirmMultiSignoutOtherSessions()
|
||||||
true
|
true
|
||||||
@ -153,6 +163,26 @@ class VectorSettingsDevicesFragment :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun navigateToRenameCurrentSession() = withState(viewModel) { state ->
|
||||||
|
val currentDeviceId = state.currentSessionCrossSigningInfo.deviceId
|
||||||
|
if (currentDeviceId.isNotEmpty()) {
|
||||||
|
viewNavigator.navigateToRenameSession(
|
||||||
|
context = requireActivity(),
|
||||||
|
deviceId = currentDeviceId,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun confirmSignoutCurrentSession() {
|
||||||
|
activity?.let { SignOutUiWorker(it).perform() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initCurrentSessionView() {
|
||||||
|
views.deviceListCurrentSession.viewVerifyButton.debouncedClicks {
|
||||||
|
viewModel.handle(DevicesAction.VerifyCurrentSession)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun initOtherSessionsHeaderView() {
|
private fun initOtherSessionsHeaderView() {
|
||||||
views.deviceListHeaderOtherSessions.setOnMenuItemClickListener { menuItem ->
|
views.deviceListHeaderOtherSessions.setOnMenuItemClickListener { menuItem ->
|
||||||
when (menuItem.itemId) {
|
when (menuItem.itemId) {
|
||||||
@ -351,15 +381,28 @@ class VectorSettingsDevicesFragment :
|
|||||||
|
|
||||||
private fun renderCurrentSessionView(currentDeviceInfo: DeviceFullInfo?, hasOtherDevices: Boolean) {
|
private fun renderCurrentSessionView(currentDeviceInfo: DeviceFullInfo?, hasOtherDevices: Boolean) {
|
||||||
currentDeviceInfo?.let {
|
currentDeviceInfo?.let {
|
||||||
|
renderCurrentSessionHeaderView(hasOtherDevices)
|
||||||
|
renderCurrentSessionListView(it)
|
||||||
|
} ?: run {
|
||||||
|
hideCurrentSessionView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderCurrentSessionHeaderView(hasOtherDevices: Boolean) {
|
||||||
views.deviceListHeaderCurrentSession.isVisible = true
|
views.deviceListHeaderCurrentSession.isVisible = true
|
||||||
val colorDestructive = colorProvider.getColorFromAttribute(R.attr.colorError)
|
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)
|
val signoutOtherSessionsItem = views.deviceListHeaderCurrentSession.menu.findItem(R.id.currentSessionHeaderSignoutOtherSessions)
|
||||||
signoutOtherSessionsItem.setTextColor(colorDestructive)
|
signoutOtherSessionsItem.setTextColor(colorDestructive)
|
||||||
signoutOtherSessionsItem.isVisible = hasOtherDevices
|
signoutOtherSessionsItem.isVisible = hasOtherDevices
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderCurrentSessionListView(currentDeviceInfo: DeviceFullInfo) {
|
||||||
views.deviceListCurrentSession.isVisible = true
|
views.deviceListCurrentSession.isVisible = true
|
||||||
val viewState = SessionInfoViewState(
|
val viewState = SessionInfoViewState(
|
||||||
isCurrentSession = true,
|
isCurrentSession = true,
|
||||||
deviceFullInfo = it
|
deviceFullInfo = currentDeviceInfo
|
||||||
)
|
)
|
||||||
views.deviceListCurrentSession.render(viewState, dateFormatter, drawableProvider, colorProvider, stringProvider)
|
views.deviceListCurrentSession.render(viewState, dateFormatter, drawableProvider, colorProvider, stringProvider)
|
||||||
views.deviceListCurrentSession.debouncedClicks {
|
views.deviceListCurrentSession.debouncedClicks {
|
||||||
@ -368,12 +411,6 @@ class VectorSettingsDevicesFragment :
|
|||||||
views.deviceListCurrentSession.viewDetailsButton.debouncedClicks {
|
views.deviceListCurrentSession.viewDetailsButton.debouncedClicks {
|
||||||
currentDeviceInfo.deviceInfo.deviceId?.let { deviceId -> navigateToSessionOverview(deviceId) }
|
currentDeviceInfo.deviceInfo.deviceId?.let { deviceId -> navigateToSessionOverview(deviceId) }
|
||||||
}
|
}
|
||||||
views.deviceListCurrentSession.viewVerifyButton.debouncedClicks {
|
|
||||||
viewModel.handle(DevicesAction.VerifyCurrentSession)
|
|
||||||
}
|
|
||||||
} ?: run {
|
|
||||||
hideCurrentSessionView()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateToSessionOverview(deviceId: String) {
|
private fun navigateToSessionOverview(deviceId: String) {
|
||||||
|
@ -20,6 +20,7 @@ import android.content.Context
|
|||||||
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
||||||
import im.vector.app.features.settings.devices.v2.othersessions.OtherSessionsActivity
|
import im.vector.app.features.settings.devices.v2.othersessions.OtherSessionsActivity
|
||||||
import im.vector.app.features.settings.devices.v2.overview.SessionOverviewActivity
|
import im.vector.app.features.settings.devices.v2.overview.SessionOverviewActivity
|
||||||
|
import im.vector.app.features.settings.devices.v2.rename.RenameSessionActivity
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class VectorSettingsDevicesViewNavigator @Inject constructor() {
|
class VectorSettingsDevicesViewNavigator @Inject constructor() {
|
||||||
@ -38,4 +39,8 @@ class VectorSettingsDevicesViewNavigator @Inject constructor() {
|
|||||||
OtherSessionsActivity.newIntent(context, titleResourceId, defaultFilter, excludeCurrentDevice)
|
OtherSessionsActivity.newIntent(context, titleResourceId, defaultFilter, excludeCurrentDevice)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun navigateToRenameSession(context: Context, deviceId: String) {
|
||||||
|
context.startActivity(RenameSessionActivity.newIntent(context, deviceId))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,16 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:ignore="AlwaysShowAction">
|
tools:ignore="AlwaysShowAction">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/currentSessionHeaderRename"
|
||||||
|
android:title="@string/device_manager_session_rename"
|
||||||
|
app:showAsAction="withText|never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/currentSessionHeaderSignout"
|
||||||
|
android:title="@string/logout"
|
||||||
|
app:showAsAction="withText|never" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/currentSessionHeaderSignoutOtherSessions"
|
android:id="@+id/currentSessionHeaderSignoutOtherSessions"
|
||||||
android:title="@string/device_manager_signout_all_other_sessions"
|
android:title="@string/device_manager_signout_all_other_sessions"
|
||||||
|
@ -20,12 +20,12 @@ import android.content.Intent
|
|||||||
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
||||||
import im.vector.app.features.settings.devices.v2.othersessions.OtherSessionsActivity
|
import im.vector.app.features.settings.devices.v2.othersessions.OtherSessionsActivity
|
||||||
import im.vector.app.features.settings.devices.v2.overview.SessionOverviewActivity
|
import im.vector.app.features.settings.devices.v2.overview.SessionOverviewActivity
|
||||||
|
import im.vector.app.features.settings.devices.v2.rename.RenameSessionActivity
|
||||||
import im.vector.app.test.fakes.FakeContext
|
import im.vector.app.test.fakes.FakeContext
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.mockkObject
|
import io.mockk.mockkObject
|
||||||
import io.mockk.unmockkAll
|
import io.mockk.unmockkAll
|
||||||
import io.mockk.verify
|
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -43,6 +43,7 @@ class VectorSettingsDevicesViewNavigatorTest {
|
|||||||
fun setUp() {
|
fun setUp() {
|
||||||
mockkObject(SessionOverviewActivity.Companion)
|
mockkObject(SessionOverviewActivity.Companion)
|
||||||
mockkObject(OtherSessionsActivity.Companion)
|
mockkObject(OtherSessionsActivity.Companion)
|
||||||
|
mockkObject(RenameSessionActivity.Companion)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@ -52,26 +53,41 @@ class VectorSettingsDevicesViewNavigatorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given a session id when navigating to overview then it starts the correct activity`() {
|
fun `given a session id when navigating to overview then it starts the correct activity`() {
|
||||||
|
// Given
|
||||||
val intent = givenIntentForSessionOverview(A_SESSION_ID)
|
val intent = givenIntentForSessionOverview(A_SESSION_ID)
|
||||||
context.givenStartActivity(intent)
|
context.givenStartActivity(intent)
|
||||||
|
|
||||||
|
// When
|
||||||
vectorSettingsDevicesViewNavigator.navigateToSessionOverview(context.instance, A_SESSION_ID)
|
vectorSettingsDevicesViewNavigator.navigateToSessionOverview(context.instance, A_SESSION_ID)
|
||||||
|
|
||||||
verify {
|
// Then
|
||||||
context.instance.startActivity(intent)
|
context.verifyStartActivity(intent)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given an intent when navigating to other sessions list then it starts the correct activity`() {
|
fun `given an intent when navigating to other sessions list then it starts the correct activity`() {
|
||||||
|
// Given
|
||||||
val intent = givenIntentForOtherSessions(A_TITLE_RESOURCE_ID, A_DEFAULT_FILTER, true)
|
val intent = givenIntentForOtherSessions(A_TITLE_RESOURCE_ID, A_DEFAULT_FILTER, true)
|
||||||
context.givenStartActivity(intent)
|
context.givenStartActivity(intent)
|
||||||
|
|
||||||
|
// When
|
||||||
vectorSettingsDevicesViewNavigator.navigateToOtherSessions(context.instance, A_TITLE_RESOURCE_ID, A_DEFAULT_FILTER, true)
|
vectorSettingsDevicesViewNavigator.navigateToOtherSessions(context.instance, A_TITLE_RESOURCE_ID, A_DEFAULT_FILTER, true)
|
||||||
|
|
||||||
verify {
|
// Then
|
||||||
context.instance.startActivity(intent)
|
context.verifyStartActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given an intent when navigating to rename session screen then it starts the correct activity`() {
|
||||||
|
// Given
|
||||||
|
val intent = givenIntentForRenameSession(A_SESSION_ID)
|
||||||
|
context.givenStartActivity(intent)
|
||||||
|
|
||||||
|
// When
|
||||||
|
vectorSettingsDevicesViewNavigator.navigateToRenameSession(context.instance, A_SESSION_ID)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
context.verifyStartActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun givenIntentForSessionOverview(sessionId: String): Intent {
|
private fun givenIntentForSessionOverview(sessionId: String): Intent {
|
||||||
@ -85,4 +101,10 @@ class VectorSettingsDevicesViewNavigatorTest {
|
|||||||
every { OtherSessionsActivity.newIntent(context.instance, titleResourceId, defaultFilter, excludeCurrentDevice) } returns intent
|
every { OtherSessionsActivity.newIntent(context.instance, titleResourceId, defaultFilter, excludeCurrentDevice) } returns intent
|
||||||
return intent
|
return intent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun givenIntentForRenameSession(sessionId: String): Intent {
|
||||||
|
val intent = mockk<Intent>()
|
||||||
|
every { RenameSessionActivity.newIntent(context.instance, sessionId) } returns intent
|
||||||
|
return intent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import io.mockk.every
|
|||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.mockkObject
|
import io.mockk.mockkObject
|
||||||
import io.mockk.unmockkAll
|
import io.mockk.unmockkAll
|
||||||
import io.mockk.verify
|
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -47,14 +46,15 @@ class OtherSessionsViewNavigatorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given a device id when navigating to overview then it starts the correct activity`() {
|
fun `given a device id when navigating to overview then it starts the correct activity`() {
|
||||||
|
// Given
|
||||||
val intent = givenIntentForDeviceOverview(A_DEVICE_ID)
|
val intent = givenIntentForDeviceOverview(A_DEVICE_ID)
|
||||||
context.givenStartActivity(intent)
|
context.givenStartActivity(intent)
|
||||||
|
|
||||||
|
// When
|
||||||
otherSessionsViewNavigator.navigateToSessionOverview(context.instance, A_DEVICE_ID)
|
otherSessionsViewNavigator.navigateToSessionOverview(context.instance, A_DEVICE_ID)
|
||||||
|
|
||||||
verify {
|
// Then
|
||||||
context.instance.startActivity(intent)
|
context.verifyStartActivity(intent)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun givenIntentForDeviceOverview(deviceId: String): Intent {
|
private fun givenIntentForDeviceOverview(deviceId: String): Intent {
|
||||||
|
@ -60,9 +60,7 @@ class SessionOverviewViewNavigatorTest {
|
|||||||
sessionOverviewViewNavigator.goToSessionDetails(context.instance, A_SESSION_ID)
|
sessionOverviewViewNavigator.goToSessionDetails(context.instance, A_SESSION_ID)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
verify {
|
context.verifyStartActivity(intent)
|
||||||
context.instance.startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -75,9 +73,7 @@ class SessionOverviewViewNavigatorTest {
|
|||||||
sessionOverviewViewNavigator.goToRenameSession(context.instance, A_SESSION_ID)
|
sessionOverviewViewNavigator.goToRenameSession(context.instance, A_SESSION_ID)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
verify {
|
context.verifyStartActivity(intent)
|
||||||
context.instance.startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -24,9 +24,9 @@ import android.net.ConnectivityManager
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.ParcelFileDescriptor
|
import android.os.ParcelFileDescriptor
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.just
|
import io.mockk.justRun
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.runs
|
import io.mockk.verify
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
class FakeContext(
|
class FakeContext(
|
||||||
@ -73,7 +73,11 @@ class FakeContext(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun givenStartActivity(intent: Intent) {
|
fun givenStartActivity(intent: Intent) {
|
||||||
every { instance.startActivity(intent) } just runs
|
justRun { instance.startActivity(intent) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun verifyStartActivity(intent: Intent) {
|
||||||
|
verify { instance.startActivity(intent) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun givenClipboardManager(): FakeClipboardManager {
|
fun givenClipboardManager(): FakeClipboardManager {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user