-
Notifications
You must be signed in to change notification settings - Fork 731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Toggle IP address visibility (PSG-860) #7546
Conversation
# Conflicts: # vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt
# Conflicts: # vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt
} | ||
|
||
private fun refreshIpAddressVisibility() { | ||
val shouldShowIpAddress = sharedPreferences.getBoolean(VectorPreferences.SETTINGS_SESSION_MANAGER_SHOW_IP_ADDRESS, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should either define the default value for this preference somewhere in VectorPreferences or create a method to retrieve this setting so that it can be reused accross the screens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, done.
setState { | ||
copy(isShowingIpAddress = !isShowingIpAddress) | ||
} | ||
sharedPreferences.edit { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to encapsulate the domain layer code inside a UseCase. I would see 2 options in prefered order:
- if we have a way to observe settings in the app, we should have a usecase to observe the ip address visiblity setting and another one to toggle the setting.
- if we don't have a way to observe settings, we should have a usecase to set the setting to a certain value.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created a use case to set the value.
@@ -72,6 +73,7 @@ class DevicesViewModelTest { | |||
private val fakeInterceptSignoutFlowResponseUseCase = mockk<InterceptSignoutFlowResponseUseCase>() | |||
private val fakePendingAuthHandler = FakePendingAuthHandler() | |||
private val fakeRefreshDevicesUseCase = mockk<RefreshDevicesUseCase>(relaxUnitFun = true) | |||
private val fakeSharedPreferences = FakeSharedPreferences() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New tests should be added:
- to cover the new toggle visibility action
- to cover the update of viewState at the initialization
@@ -187,6 +189,7 @@ class SessionInfoView @JvmOverloads constructor( | |||
views.sessionInfoLastActivityTextView.isGone = true | |||
} | |||
views.sessionInfoLastIPAddressTextView.setTextOrHide(deviceInfo.lastSeenIp?.takeIf { isLastSeenDetailsVisible }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could write instead:
views.sessionInfoLastIPAddressTextView.setTextOrHide(deviceInfo.lastSeenIp?.takeIf { isLastSeenDetailsVisible && isShowingIpAddress })
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, done.
} | ||
|
||
private fun handleToggleIpAddressVisibility() = withState { state -> | ||
val isShowingIpAddress = state.isShowingIpAddress |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same remark for adding a reusable usecase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored.
@@ -66,6 +67,7 @@ class OtherSessionsViewModelTest { | |||
private val fakeRefreshDevicesUseCase = mockk<RefreshDevicesUseCase>(relaxed = true) | |||
private val fakeSignoutSessionsUseCase = FakeSignoutSessionsUseCase() | |||
private val fakePendingAuthHandler = FakePendingAuthHandler() | |||
private val fakeSharedPreferences = FakeSharedPreferences() | |||
|
|||
private fun createViewModel(viewState: OtherSessionsViewState = OtherSessionsViewState(defaultArgs)) = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add units tests to cover the new action and the change of the viewState in the initialization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think tests have not been added for this ViewModel
.
} | ||
|
||
private fun handleToggleIpAddressVisibility() = withState { state -> | ||
val isShowingIpAddress = state.isShowingIpAddress |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same remark for the need of a usecase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored.
@@ -103,6 +106,7 @@ class SessionOverviewViewModelTest { | |||
A_SESSION_ID_1, | |||
notificationsStatus | |||
) | |||
fakeSharedPreferences.givenSessionManagerShowIpAddress(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same remark for the missing new unit tests.
app:layout_constraintEnd_toEndOf="@id/otherSessionNameTextView" | ||
app:layout_constraintStart_toStartOf="@id/otherSessionNameTextView" | ||
app:layout_constraintTop_toBottomOf="@id/otherSessionNameTextView" | ||
tools:text="@string/device_manager_verification_status_verified" /> | ||
|
||
<TextView |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should update some constraints on this layout:
- For the view with id
otherSessionItemBackground
we should replaceapp:layout_constraintBottom_toBottomOf="@id/otherSessionVerificationStatusImageView"
byapp:layout_constraintBottom_toBottomOf="@id/otherSessionIpAddressTextView"
- For the view with id
otherSessionNameTextView
we should replaceapp:layout_constraintTop_toTopOf="@id/otherSessionDeviceTypeImageView"
byapp:layout_constraintTop_toTopOf="@id/otherSessionItemBackground"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When testing it, I have found a small bug which could be fixed by observing the setting as I suggested instead of getting the setting value when ViewModel
is initialized. To reproduce the bug:
- Make sure the IP address is not visible
- Go to the other sessions list
- Go to a session overview screen
- From this screen, show the IP address
- Press back
- We can see IP address are not displayed since the
ViewModel
is using the setting value when theViewModel
was created.
@@ -51,6 +51,7 @@ | |||
<bool name="settings_labs_rich_text_editor_default">false</bool> | |||
<bool name="settings_labs_enable_voice_broadcast_visible">true</bool> | |||
<bool name="settings_labs_enable_voice_broadcast_default">false</bool> | |||
<bool name="settings_device_manager_show_ip_address">false</bool> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding the default value here. But I think it should not be in the labs section, maybe in a new section Level 3: Security & Privacy, Sessions
?
@@ -1228,4 +1231,14 @@ class VectorPreferences @Inject constructor( | |||
return vectorFeatures.isVoiceBroadcastEnabled() && | |||
defaultPrefs.getBoolean(SETTINGS_LABS_VOICE_BROADCAST_KEY, getDefault(R.bool.settings_labs_enable_voice_broadcast_default)) | |||
} | |||
|
|||
fun showIpAddressInDeviceManagerScreens(): Boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small question about naming, should we align the methods and preference setting names on SessionManager
instead of DeviceManager
?
import im.vector.app.features.settings.VectorPreferences | ||
import javax.inject.Inject | ||
|
||
class ToggleIpAddressVisibilityUseCase @Inject constructor( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add unit tests for this new use case.
@@ -77,6 +79,8 @@ class SessionOverviewViewModelTest { | |||
private val togglePushNotificationUseCase = FakeTogglePushNotificationUseCase() | |||
private val fakeGetNotificationsStatusUseCase = FakeGetNotificationsStatusUseCase() | |||
private val notificationsStatus = NotificationsStatus.ENABLED | |||
private val fakeVectorPreferences = FakeVectorPreferences() | |||
private val toggleIpAddressVisibilityUseCase = mockk<ToggleIpAddressVisibilityUseCase>() | |||
|
|||
private fun createViewModel() = SessionOverviewViewModel( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New tests should also be added for this ViewModel
. Maybe a FakeToggleIpAddressVisibilityUseCase
can be created to reuse it in the other ViewModel
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates! I have added some small comments we should handle before merge.
|
SonarCloud Quality Gate failed. |
Type of change
Content
In new Session Management screens we should hide the IP addresses of devices by default for the sake of privacy (in case users may demo these screens to someone else etc.). In this PR, we will provide a menu item to be able to toggle the visibility of IP addresses. Once a user selects to show or hide the IP addresses then this option is saved to the shared preferences and will be reflected to the screens on next app launches.
Motivation and context
Screenshots / GIFs
toggle_ip_address.mp4
Tests
Tested devices
Checklist