mirror of
https://github.com/element-hq/element-android
synced 2024-11-23 18:05:36 +03:00
Merge pull request #7546 from vector-im/feature/ons/toggle_ip_address_visibility
Toggle IP address visibility (PSG-860)
This commit is contained in:
commit
0957b38329
29 changed files with 309 additions and 18 deletions
1
changelog.d/7546.feature
Normal file
1
changelog.d/7546.feature
Normal file
|
@ -0,0 +1 @@
|
|||
[Device Manager] Toggle IP address visibility
|
|
@ -3356,6 +3356,8 @@
|
|||
<item quantity="one">Sign out of %1$d session</item>
|
||||
<item quantity="other">Sign out of %1$d sessions</item>
|
||||
</plurals>
|
||||
<string name="device_manager_other_sessions_show_ip_address">Show IP address</string>
|
||||
<string name="device_manager_other_sessions_hide_ip_address">Hide IP address</string>
|
||||
<string name="device_manager_session_overview_signout">Sign out of this session</string>
|
||||
<string name="device_manager_session_details_title">Session details</string>
|
||||
<string name="device_manager_session_details_description">Application, device, and activity information.</string>
|
||||
|
|
|
@ -57,5 +57,7 @@
|
|||
|
||||
<!-- Level 1: Legals -->
|
||||
|
||||
<!-- Level 3: Security & Privacy, Sessions -->
|
||||
<bool name="settings_session_manager_show_ip_address">false</bool>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -209,6 +209,9 @@ class VectorPreferences @Inject constructor(
|
|||
private const val SETTINGS_SECURITY_USE_GRACE_PERIOD_FLAG = "SETTINGS_SECURITY_USE_GRACE_PERIOD_FLAG"
|
||||
const val SETTINGS_SECURITY_USE_COMPLETE_NOTIFICATIONS_FLAG = "SETTINGS_SECURITY_USE_COMPLETE_NOTIFICATIONS_FLAG"
|
||||
|
||||
// New Session Manager
|
||||
const val SETTINGS_SESSION_MANAGER_SHOW_IP_ADDRESS = "SETTINGS_SESSION_MANAGER_SHOW_IP_ADDRESS"
|
||||
|
||||
// other
|
||||
const val SETTINGS_MEDIA_SAVING_PERIOD_KEY = "SETTINGS_MEDIA_SAVING_PERIOD_KEY"
|
||||
private const val SETTINGS_MEDIA_SAVING_PERIOD_SELECTED_KEY = "SETTINGS_MEDIA_SAVING_PERIOD_SELECTED_KEY"
|
||||
|
@ -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 showIpAddressInSessionManagerScreens(): Boolean {
|
||||
return defaultPrefs.getBoolean(SETTINGS_SESSION_MANAGER_SHOW_IP_ADDRESS, getDefault(R.bool.settings_session_manager_show_ip_address))
|
||||
}
|
||||
|
||||
fun setIpAddressVisibilityInDeviceManagerScreens(isVisible: Boolean) {
|
||||
defaultPrefs.edit {
|
||||
putBoolean(VectorPreferences.SETTINGS_SESSION_MANAGER_SHOW_IP_ADDRESS, isVisible)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,4 +29,5 @@ sealed class DevicesAction : VectorViewModelAction {
|
|||
object VerifyCurrentSession : DevicesAction()
|
||||
data class MarkAsManuallyVerified(val cryptoDeviceInfo: CryptoDeviceInfo) : DevicesAction()
|
||||
object MultiSignoutOtherSessions : DevicesAction()
|
||||
object ToggleIpAddressVisibility : DevicesAction()
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package im.vector.app.features.settings.devices.v2
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.Success
|
||||
import dagger.assisted.Assisted
|
||||
|
@ -25,6 +26,7 @@ import im.vector.app.core.di.ActiveSessionHolder
|
|||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||
import im.vector.app.features.auth.PendingAuthHandler
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
||||
import im.vector.app.features.settings.devices.v2.signout.InterceptSignoutFlowResponseUseCase
|
||||
import im.vector.app.features.settings.devices.v2.signout.SignoutSessionsReAuthNeeded
|
||||
|
@ -49,7 +51,12 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
private val interceptSignoutFlowResponseUseCase: InterceptSignoutFlowResponseUseCase,
|
||||
private val pendingAuthHandler: PendingAuthHandler,
|
||||
refreshDevicesUseCase: RefreshDevicesUseCase,
|
||||
) : VectorSessionsListViewModel<DevicesViewState, DevicesAction, DevicesViewEvent>(initialState, activeSessionHolder, refreshDevicesUseCase) {
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val toggleIpAddressVisibilityUseCase: ToggleIpAddressVisibilityUseCase,
|
||||
) : VectorSessionsListViewModel<DevicesViewState,
|
||||
DevicesAction,
|
||||
DevicesViewEvent>(initialState, activeSessionHolder, refreshDevicesUseCase),
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : MavericksAssistedViewModelFactory<DevicesViewModel, DevicesViewState> {
|
||||
|
@ -63,6 +70,28 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
observeDevices()
|
||||
refreshDevicesOnCryptoDevicesChange()
|
||||
refreshDeviceList()
|
||||
refreshIpAddressVisibility()
|
||||
observePreferences()
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
refreshIpAddressVisibility()
|
||||
}
|
||||
|
||||
private fun observePreferences() {
|
||||
vectorPreferences.subscribeToChanges(this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
vectorPreferences.unsubscribeToChanges(this)
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun refreshIpAddressVisibility() {
|
||||
val shouldShowIpAddress = vectorPreferences.showIpAddressInSessionManagerScreens()
|
||||
setState {
|
||||
copy(isShowingIpAddress = shouldShowIpAddress)
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeCurrentSessionCrossSigningInfo() {
|
||||
|
@ -112,9 +141,14 @@ class DevicesViewModel @AssistedInject constructor(
|
|||
is DevicesAction.VerifyCurrentSession -> handleVerifyCurrentSessionAction()
|
||||
is DevicesAction.MarkAsManuallyVerified -> handleMarkAsManuallyVerifiedAction()
|
||||
DevicesAction.MultiSignoutOtherSessions -> handleMultiSignoutOtherSessions()
|
||||
DevicesAction.ToggleIpAddressVisibility -> handleToggleIpAddressVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleToggleIpAddressVisibility() {
|
||||
toggleIpAddressVisibilityUseCase.execute()
|
||||
}
|
||||
|
||||
private fun handleVerifyCurrentSessionAction() {
|
||||
viewModelScope.launch {
|
||||
val currentSessionCanBeVerified = checkIfCurrentSessionCanBeVerifiedUseCase.execute()
|
||||
|
|
|
@ -27,4 +27,5 @@ data class DevicesViewState(
|
|||
val unverifiedSessionsCount: Int = 0,
|
||||
val inactiveSessionsCount: Int = 0,
|
||||
val isLoading: Boolean = false,
|
||||
val isShowingIpAddress: Boolean = false,
|
||||
) : MavericksState
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.settings.devices.v2
|
||||
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import javax.inject.Inject
|
||||
|
||||
class ToggleIpAddressVisibilityUseCase @Inject constructor(
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
) {
|
||||
|
||||
fun execute() {
|
||||
val currentVisibility = vectorPreferences.showIpAddressInSessionManagerScreens()
|
||||
vectorPreferences.setIpAddressVisibilityInDeviceManagerScreens(!currentVisibility)
|
||||
}
|
||||
}
|
|
@ -146,11 +146,19 @@ class VectorSettingsDevicesFragment :
|
|||
confirmMultiSignoutOtherSessions()
|
||||
true
|
||||
}
|
||||
R.id.otherSessionsHeaderToggleIpAddress -> {
|
||||
handleToggleIpAddressVisibility()
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleToggleIpAddressVisibility() {
|
||||
viewModel.handle(DevicesAction.ToggleIpAddressVisibility)
|
||||
}
|
||||
|
||||
private fun confirmMultiSignoutOtherSessions() {
|
||||
activity?.let {
|
||||
buildConfirmSignoutDialogUseCase.execute(it, this::multiSignoutOtherSessions)
|
||||
|
@ -240,7 +248,7 @@ class VectorSettingsDevicesFragment :
|
|||
|
||||
renderSecurityRecommendations(state.inactiveSessionsCount, state.unverifiedSessionsCount, isCurrentSessionVerified)
|
||||
renderCurrentDevice(currentDeviceInfo)
|
||||
renderOtherSessionsView(otherDevices)
|
||||
renderOtherSessionsView(otherDevices, state.isShowingIpAddress)
|
||||
} else {
|
||||
hideSecurityRecommendations()
|
||||
hideCurrentSessionView()
|
||||
|
@ -297,7 +305,7 @@ class VectorSettingsDevicesFragment :
|
|||
hideInactiveSessionsRecommendation()
|
||||
}
|
||||
|
||||
private fun renderOtherSessionsView(otherDevices: List<DeviceFullInfo>?) {
|
||||
private fun renderOtherSessionsView(otherDevices: List<DeviceFullInfo>?, isShowingIpAddress: Boolean) {
|
||||
if (otherDevices.isNullOrEmpty()) {
|
||||
hideOtherSessionsView()
|
||||
} else {
|
||||
|
@ -308,12 +316,18 @@ class VectorSettingsDevicesFragment :
|
|||
multiSignoutItem.title = stringProvider.getQuantityString(R.plurals.device_manager_other_sessions_multi_signout_all, nbDevices, nbDevices)
|
||||
multiSignoutItem.setTextColor(color)
|
||||
views.deviceListOtherSessions.isVisible = true
|
||||
val devices = if (isShowingIpAddress) otherDevices else otherDevices.map { it.copy(deviceInfo = it.deviceInfo.copy(lastSeenIp = null)) }
|
||||
views.deviceListOtherSessions.render(
|
||||
devices = otherDevices.take(NUMBER_OF_OTHER_DEVICES_TO_RENDER),
|
||||
totalNumberOfDevices = otherDevices.size,
|
||||
showViewAll = otherDevices.size > NUMBER_OF_OTHER_DEVICES_TO_RENDER
|
||||
devices = devices.take(NUMBER_OF_OTHER_DEVICES_TO_RENDER),
|
||||
totalNumberOfDevices = devices.size,
|
||||
showViewAll = devices.size > NUMBER_OF_OTHER_DEVICES_TO_RENDER
|
||||
)
|
||||
}
|
||||
views.deviceListHeaderOtherSessions.menu.findItem(R.id.otherSessionsHeaderToggleIpAddress).title = if (isShowingIpAddress) {
|
||||
stringProvider.getString(R.string.device_manager_other_sessions_hide_ip_address)
|
||||
} else {
|
||||
stringProvider.getString(R.string.device_manager_other_sessions_show_ip_address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideOtherSessionsView() {
|
||||
|
|
|
@ -29,6 +29,7 @@ import im.vector.app.core.epoxy.ClickListener
|
|||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.DrawableProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
|
@ -69,6 +70,9 @@ abstract class OtherSessionItem : VectorEpoxyModel<OtherSessionItem.Holder>(R.la
|
|||
@EpoxyAttribute
|
||||
var selected: Boolean = false
|
||||
|
||||
@EpoxyAttribute
|
||||
var ipAddress: String? = null
|
||||
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
var clickListener: ClickListener? = null
|
||||
|
||||
|
@ -100,6 +104,7 @@ abstract class OtherSessionItem : VectorEpoxyModel<OtherSessionItem.Holder>(R.la
|
|||
holder.otherSessionDescriptionTextView.setTextColor(it)
|
||||
}
|
||||
holder.otherSessionDescriptionTextView.setCompoundDrawablesWithIntrinsicBounds(sessionDescriptionDrawable, null, null, null)
|
||||
holder.otherSessionIpAddressTextView.setTextOrHide(ipAddress)
|
||||
holder.otherSessionItemBackgroundView.isSelected = selected
|
||||
}
|
||||
|
||||
|
@ -108,6 +113,7 @@ abstract class OtherSessionItem : VectorEpoxyModel<OtherSessionItem.Holder>(R.la
|
|||
val otherSessionVerificationStatusImageView by bind<ShieldImageView>(R.id.otherSessionVerificationStatusImageView)
|
||||
val otherSessionNameTextView by bind<TextView>(R.id.otherSessionNameTextView)
|
||||
val otherSessionDescriptionTextView by bind<TextView>(R.id.otherSessionDescriptionTextView)
|
||||
val otherSessionIpAddressTextView by bind<TextView>(R.id.otherSessionIpAddressTextView)
|
||||
val otherSessionItemBackgroundView by bind<View>(R.id.otherSessionItemBackground)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ class OtherSessionsController @Inject constructor(
|
|||
sessionDescription(description)
|
||||
sessionDescriptionDrawable(descriptionDrawable)
|
||||
sessionDescriptionColor(descriptionColor)
|
||||
ipAddress(device.deviceInfo.lastSeenIp)
|
||||
stringProvider(host.stringProvider)
|
||||
colorProvider(host.colorProvider)
|
||||
drawableProvider(host.drawableProvider)
|
||||
|
|
|
@ -76,6 +76,7 @@ class SessionInfoView @JvmOverloads constructor(
|
|||
sessionInfoViewState.deviceFullInfo.isInactive,
|
||||
sessionInfoViewState.deviceFullInfo.deviceInfo,
|
||||
sessionInfoViewState.isLastSeenDetailsVisible,
|
||||
sessionInfoViewState.isShowingIpAddress,
|
||||
dateFormatter,
|
||||
drawableProvider,
|
||||
colorProvider,
|
||||
|
@ -157,6 +158,7 @@ class SessionInfoView @JvmOverloads constructor(
|
|||
isInactive: Boolean,
|
||||
deviceInfo: DeviceInfo,
|
||||
isLastSeenDetailsVisible: Boolean,
|
||||
isShowingIpAddress: Boolean,
|
||||
dateFormatter: VectorDateFormatter,
|
||||
drawableProvider: DrawableProvider,
|
||||
colorProvider: ColorProvider,
|
||||
|
@ -186,7 +188,7 @@ class SessionInfoView @JvmOverloads constructor(
|
|||
} else {
|
||||
views.sessionInfoLastActivityTextView.isGone = true
|
||||
}
|
||||
views.sessionInfoLastIPAddressTextView.setTextOrHide(deviceInfo.lastSeenIp?.takeIf { isLastSeenDetailsVisible })
|
||||
views.sessionInfoLastIPAddressTextView.setTextOrHide(deviceInfo.lastSeenIp?.takeIf { isLastSeenDetailsVisible && isShowingIpAddress })
|
||||
}
|
||||
|
||||
private fun renderDetailsButton(isDetailsButtonVisible: Boolean) {
|
||||
|
|
|
@ -25,4 +25,5 @@ data class SessionInfoViewState(
|
|||
val isDetailsButtonVisible: Boolean = true,
|
||||
val isLearnMoreLinkVisible: Boolean = false,
|
||||
val isLastSeenDetailsVisible: Boolean = false,
|
||||
val isShowingIpAddress: Boolean = false,
|
||||
)
|
||||
|
|
|
@ -33,4 +33,5 @@ sealed class OtherSessionsAction : VectorViewModelAction {
|
|||
object SelectAll : OtherSessionsAction()
|
||||
object DeselectAll : OtherSessionsAction()
|
||||
object MultiSignout : OtherSessionsAction()
|
||||
object ToggleIpAddressVisibility : OtherSessionsAction()
|
||||
}
|
||||
|
|
|
@ -85,6 +85,12 @@ class OtherSessionsFragment :
|
|||
menu.findItem(R.id.otherSessionsSelectAll).isVisible = isSelectModeEnabled
|
||||
menu.findItem(R.id.otherSessionsDeselectAll).isVisible = isSelectModeEnabled
|
||||
menu.findItem(R.id.otherSessionsSelect).isVisible = !isSelectModeEnabled && state.devices()?.isNotEmpty().orFalse()
|
||||
menu.findItem(R.id.otherSessionsToggleIpAddress).isVisible = !isSelectModeEnabled
|
||||
menu.findItem(R.id.otherSessionsToggleIpAddress).title = if (state.isShowingIpAddress) {
|
||||
getString(R.string.device_manager_other_sessions_hide_ip_address)
|
||||
} else {
|
||||
getString(R.string.device_manager_other_sessions_show_ip_address)
|
||||
}
|
||||
updateMultiSignoutMenuItem(menu, state)
|
||||
}
|
||||
}
|
||||
|
@ -130,10 +136,18 @@ class OtherSessionsFragment :
|
|||
confirmMultiSignout()
|
||||
true
|
||||
}
|
||||
R.id.otherSessionsToggleIpAddress -> {
|
||||
toggleIpAddressVisibility()
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleIpAddressVisibility() {
|
||||
viewModel.handle(OtherSessionsAction.ToggleIpAddressVisibility)
|
||||
}
|
||||
|
||||
private fun confirmMultiSignout() {
|
||||
activity?.let {
|
||||
buildConfirmSignoutDialogUseCase.execute(it, this::multiSignout)
|
||||
|
@ -213,7 +227,7 @@ class OtherSessionsFragment :
|
|||
updateLoading(state.isLoading)
|
||||
if (state.devices is Success) {
|
||||
val devices = state.devices.invoke()
|
||||
renderDevices(devices, state.currentFilter)
|
||||
renderDevices(devices, state.currentFilter, state.isShowingIpAddress)
|
||||
updateToolbar(devices, state.isSelectModeEnabled)
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +251,7 @@ class OtherSessionsFragment :
|
|||
toolbar?.title = title
|
||||
}
|
||||
|
||||
private fun renderDevices(devices: List<DeviceFullInfo>, currentFilter: DeviceManagerFilterType) {
|
||||
private fun renderDevices(devices: List<DeviceFullInfo>, currentFilter: DeviceManagerFilterType, isShowingIpAddress: Boolean) {
|
||||
views.otherSessionsFilterBadgeImageView.isVisible = currentFilter != DeviceManagerFilterType.ALL_SESSIONS
|
||||
views.otherSessionsSecurityRecommendationView.isVisible = currentFilter != DeviceManagerFilterType.ALL_SESSIONS
|
||||
views.deviceListHeaderOtherSessions.isVisible = currentFilter == DeviceManagerFilterType.ALL_SESSIONS
|
||||
|
@ -299,7 +313,8 @@ class OtherSessionsFragment :
|
|||
} else {
|
||||
views.deviceListOtherSessions.isVisible = true
|
||||
views.otherSessionsNotFoundLayout.isVisible = false
|
||||
views.deviceListOtherSessions.render(devices = devices, totalNumberOfDevices = devices.size, showViewAll = false)
|
||||
val mappedDevices = if (isShowingIpAddress) devices else devices.map { it.copy(deviceInfo = it.deviceInfo.copy(lastSeenIp = null)) }
|
||||
views.deviceListOtherSessions.render(devices = mappedDevices, totalNumberOfDevices = mappedDevices.size, showViewAll = false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package im.vector.app.features.settings.devices.v2.othersessions
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.Success
|
||||
import dagger.assisted.Assisted
|
||||
|
@ -25,8 +26,10 @@ import im.vector.app.core.di.ActiveSessionHolder
|
|||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||
import im.vector.app.features.auth.PendingAuthHandler
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.settings.devices.v2.GetDeviceFullInfoListUseCase
|
||||
import im.vector.app.features.settings.devices.v2.RefreshDevicesUseCase
|
||||
import im.vector.app.features.settings.devices.v2.ToggleIpAddressVisibilityUseCase
|
||||
import im.vector.app.features.settings.devices.v2.VectorSessionsListViewModel
|
||||
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
||||
import im.vector.app.features.settings.devices.v2.signout.SignoutSessionsReAuthNeeded
|
||||
|
@ -42,10 +45,12 @@ class OtherSessionsViewModel @AssistedInject constructor(
|
|||
private val getDeviceFullInfoListUseCase: GetDeviceFullInfoListUseCase,
|
||||
private val signoutSessionsUseCase: SignoutSessionsUseCase,
|
||||
private val pendingAuthHandler: PendingAuthHandler,
|
||||
refreshDevicesUseCase: RefreshDevicesUseCase
|
||||
refreshDevicesUseCase: RefreshDevicesUseCase,
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val toggleIpAddressVisibilityUseCase: ToggleIpAddressVisibilityUseCase,
|
||||
) : VectorSessionsListViewModel<OtherSessionsViewState, OtherSessionsAction, OtherSessionsViewEvents>(
|
||||
initialState, activeSessionHolder, refreshDevicesUseCase
|
||||
) {
|
||||
), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : MavericksAssistedViewModelFactory<OtherSessionsViewModel, OtherSessionsViewState> {
|
||||
|
@ -58,6 +63,28 @@ class OtherSessionsViewModel @AssistedInject constructor(
|
|||
|
||||
init {
|
||||
observeDevices(initialState.currentFilter)
|
||||
refreshIpAddressVisibility()
|
||||
observePreferences()
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
refreshIpAddressVisibility()
|
||||
}
|
||||
|
||||
private fun observePreferences() {
|
||||
vectorPreferences.subscribeToChanges(this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
vectorPreferences.unsubscribeToChanges(this)
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun refreshIpAddressVisibility() {
|
||||
val shouldShowIpAddress = vectorPreferences.showIpAddressInSessionManagerScreens()
|
||||
setState {
|
||||
copy(isShowingIpAddress = shouldShowIpAddress)
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeDevices(currentFilter: DeviceManagerFilterType) {
|
||||
|
@ -85,9 +112,14 @@ class OtherSessionsViewModel @AssistedInject constructor(
|
|||
OtherSessionsAction.DeselectAll -> handleDeselectAll()
|
||||
OtherSessionsAction.SelectAll -> handleSelectAll()
|
||||
OtherSessionsAction.MultiSignout -> handleMultiSignout()
|
||||
OtherSessionsAction.ToggleIpAddressVisibility -> handleToggleIpAddressVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleToggleIpAddressVisibility() {
|
||||
toggleIpAddressVisibilityUseCase.execute()
|
||||
}
|
||||
|
||||
private fun handleFilterDevices(action: OtherSessionsAction.FilterDevices) {
|
||||
setState {
|
||||
copy(
|
||||
|
|
|
@ -28,6 +28,7 @@ data class OtherSessionsViewState(
|
|||
val excludeCurrentDevice: Boolean = false,
|
||||
val isSelectModeEnabled: Boolean = false,
|
||||
val isLoading: Boolean = false,
|
||||
val isShowingIpAddress: Boolean = false,
|
||||
) : MavericksState {
|
||||
|
||||
constructor(args: OtherSessionsArgs) : this(excludeCurrentDevice = args.excludeCurrentDevice)
|
||||
|
|
|
@ -29,4 +29,5 @@ sealed class SessionOverviewAction : VectorViewModelAction {
|
|||
val deviceId: String,
|
||||
val enabled: Boolean,
|
||||
) : SessionOverviewAction()
|
||||
object ToggleIpAddressVisibility : SessionOverviewAction()
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices.v2.overview
|
|||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -156,16 +157,34 @@ class SessionOverviewFragment :
|
|||
|
||||
override fun getMenuRes() = R.menu.menu_session_overview
|
||||
|
||||
override fun handlePrepareMenu(menu: Menu) {
|
||||
withState(viewModel) { state ->
|
||||
menu.findItem(R.id.sessionOverviewToggleIpAddress).title = if (state.isShowingIpAddress) {
|
||||
getString(R.string.device_manager_other_sessions_hide_ip_address)
|
||||
} else {
|
||||
getString(R.string.device_manager_other_sessions_show_ip_address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleMenuItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.sessionOverviewRename -> {
|
||||
goToRenameSession()
|
||||
true
|
||||
}
|
||||
R.id.sessionOverviewToggleIpAddress -> {
|
||||
toggleIpAddressVisibility()
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleIpAddressVisibility() {
|
||||
viewModel.handle(SessionOverviewAction.ToggleIpAddressVisibility)
|
||||
}
|
||||
|
||||
private fun goToRenameSession() = withState(viewModel) { state ->
|
||||
viewNavigator.goToRenameSession(requireContext(), state.deviceId)
|
||||
}
|
||||
|
@ -206,6 +225,7 @@ class SessionOverviewFragment :
|
|||
isDetailsButtonVisible = false,
|
||||
isLearnMoreLinkVisible = deviceInfo.roomEncryptionTrustLevel != RoomEncryptionTrustLevel.Default,
|
||||
isLastSeenDetailsVisible = !isCurrentSession,
|
||||
isShowingIpAddress = viewState.isShowingIpAddress,
|
||||
)
|
||||
views.sessionOverviewInfo.render(infoViewState, dateFormatter, drawableProvider, colorProvider, stringProvider)
|
||||
views.sessionOverviewInfo.onLearnMoreClickListener = {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package im.vector.app.features.settings.devices.v2.overview
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.Success
|
||||
import dagger.assisted.Assisted
|
||||
|
@ -25,7 +26,9 @@ import im.vector.app.core.di.ActiveSessionHolder
|
|||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||
import im.vector.app.features.auth.PendingAuthHandler
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.settings.devices.v2.RefreshDevicesUseCase
|
||||
import im.vector.app.features.settings.devices.v2.ToggleIpAddressVisibilityUseCase
|
||||
import im.vector.app.features.settings.devices.v2.VectorSessionsListViewModel
|
||||
import im.vector.app.features.settings.devices.v2.notification.GetNotificationsStatusUseCase
|
||||
import im.vector.app.features.settings.devices.v2.notification.TogglePushNotificationUseCase
|
||||
|
@ -54,9 +57,11 @@ class SessionOverviewViewModel @AssistedInject constructor(
|
|||
private val togglePushNotificationUseCase: TogglePushNotificationUseCase,
|
||||
private val getNotificationsStatusUseCase: GetNotificationsStatusUseCase,
|
||||
refreshDevicesUseCase: RefreshDevicesUseCase,
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val toggleIpAddressVisibilityUseCase: ToggleIpAddressVisibilityUseCase,
|
||||
) : VectorSessionsListViewModel<SessionOverviewViewState, SessionOverviewAction, SessionOverviewViewEvent>(
|
||||
initialState, activeSessionHolder, refreshDevicesUseCase
|
||||
) {
|
||||
), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
companion object : MavericksViewModelFactory<SessionOverviewViewModel, SessionOverviewViewState> by hiltMavericksViewModelFactory()
|
||||
|
||||
|
@ -70,6 +75,27 @@ class SessionOverviewViewModel @AssistedInject constructor(
|
|||
observeSessionInfo(initialState.deviceId)
|
||||
observeCurrentSessionInfo()
|
||||
observeNotificationsStatus(initialState.deviceId)
|
||||
refreshIpAddressVisibility()
|
||||
observePreferences()
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
refreshIpAddressVisibility()
|
||||
}
|
||||
|
||||
private fun observePreferences() {
|
||||
vectorPreferences.subscribeToChanges(this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
vectorPreferences.unsubscribeToChanges(this)
|
||||
super.onCleared()
|
||||
}
|
||||
private fun refreshIpAddressVisibility() {
|
||||
val shouldShowIpAddress = vectorPreferences.showIpAddressInSessionManagerScreens()
|
||||
setState {
|
||||
copy(isShowingIpAddress = shouldShowIpAddress)
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshPushers() {
|
||||
|
@ -111,9 +137,14 @@ class SessionOverviewViewModel @AssistedInject constructor(
|
|||
is SessionOverviewAction.PasswordAuthDone -> handlePasswordAuthDone(action)
|
||||
SessionOverviewAction.ReAuthCancelled -> handleReAuthCancelled()
|
||||
is SessionOverviewAction.TogglePushNotifications -> handleTogglePusherAction(action)
|
||||
SessionOverviewAction.ToggleIpAddressVisibility -> handleToggleIpAddressVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleToggleIpAddressVisibility() {
|
||||
toggleIpAddressVisibilityUseCase.execute()
|
||||
}
|
||||
|
||||
private fun handleVerifySessionAction() = withState { viewState ->
|
||||
if (viewState.deviceInfo.invoke()?.isCurrentDevice.orFalse()) {
|
||||
handleVerifyCurrentSession()
|
||||
|
|
|
@ -28,6 +28,7 @@ data class SessionOverviewViewState(
|
|||
val deviceInfo: Async<DeviceFullInfo> = Uninitialized,
|
||||
val isLoading: Boolean = false,
|
||||
val notificationsStatus: NotificationsStatus = NotificationsStatus.NOT_SUPPORTED,
|
||||
val isShowingIpAddress: Boolean = false,
|
||||
) : MavericksState {
|
||||
constructor(args: SessionOverviewArgs) : this(
|
||||
deviceId = args.deviceId
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="@drawable/bg_other_session"
|
||||
app:layout_constraintBottom_toBottomOf="@id/otherSessionVerificationStatusImageView"
|
||||
app:layout_constraintBottom_toBottomOf="@id/otherSessionSeparator"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
@ -53,11 +53,12 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/otherSessionDeviceTypeImageView"
|
||||
app:layout_constraintTop_toTopOf="@id/otherSessionDeviceTypeImageView"
|
||||
app:layout_constraintTop_toTopOf="@id/otherSessionItemBackground"
|
||||
tools:text="Element Mobile: Android" />
|
||||
|
||||
<TextView
|
||||
|
@ -67,19 +68,31 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:drawablePadding="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/otherSessionDeviceTypeImageView"
|
||||
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
|
||||
android:id="@+id/otherSessionIpAddressTextView"
|
||||
style="@style/TextAppearance.Vector.Body.DevicesManagement"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:drawablePadding="8dp"
|
||||
app:layout_constraintEnd_toEndOf="@id/otherSessionNameTextView"
|
||||
app:layout_constraintStart_toStartOf="@id/otherSessionNameTextView"
|
||||
app:layout_constraintTop_toBottomOf="@id/otherSessionDescriptionTextView"
|
||||
tools:text="0.0.0.0" />
|
||||
|
||||
<View
|
||||
android:id="@+id/otherSessionSeparator"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="?vctr_content_quinary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@id/otherSessionNameTextView"
|
||||
app:layout_constraintTop_toBottomOf="@id/otherSessionItemBackground" />
|
||||
app:layout_constraintTop_toBottomOf="@id/otherSessionIpAddressTextView" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -9,6 +9,11 @@
|
|||
android:title="@string/device_manager_other_sessions_select"
|
||||
app:showAsAction="withText|never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/otherSessionsToggleIpAddress"
|
||||
android:title="@string/device_manager_other_sessions_show_ip_address"
|
||||
app:showAsAction="withText|never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/otherSessionsMultiSignout"
|
||||
android:title="@plurals/device_manager_other_sessions_multi_signout_all"
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="AlwaysShowAction">
|
||||
|
||||
<item
|
||||
android:id="@+id/otherSessionsHeaderToggleIpAddress"
|
||||
android:title="@string/device_manager_other_sessions_show_ip_address"
|
||||
app:showAsAction="withText|never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/otherSessionsHeaderMultiSignout"
|
||||
android:title="@plurals/device_manager_other_sessions_multi_signout_all"
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="AlwaysShowAction">
|
||||
|
||||
<item
|
||||
android:id="@+id/sessionOverviewToggleIpAddress"
|
||||
android:title="@string/device_manager_other_sessions_show_ip_address"
|
||||
app:showAsAction="withText|never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/sessionOverviewRename"
|
||||
android:title="@string/device_manager_session_rename"
|
||||
|
|
|
@ -29,15 +29,18 @@ import im.vector.app.features.settings.devices.v2.verification.GetCurrentSession
|
|||
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||
import im.vector.app.test.fakes.FakePendingAuthHandler
|
||||
import im.vector.app.test.fakes.FakeSignoutSessionsUseCase
|
||||
import im.vector.app.test.fakes.FakeVectorPreferences
|
||||
import im.vector.app.test.fakes.FakeVerificationService
|
||||
import im.vector.app.test.test
|
||||
import im.vector.app.test.testDispatcher
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.justRun
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.runs
|
||||
import io.mockk.unmockkAll
|
||||
import io.mockk.verify
|
||||
import io.mockk.verifyAll
|
||||
|
@ -72,6 +75,8 @@ class DevicesViewModelTest {
|
|||
private val fakeInterceptSignoutFlowResponseUseCase = mockk<InterceptSignoutFlowResponseUseCase>()
|
||||
private val fakePendingAuthHandler = FakePendingAuthHandler()
|
||||
private val fakeRefreshDevicesUseCase = mockk<RefreshDevicesUseCase>(relaxUnitFun = true)
|
||||
private val fakeVectorPreferences = FakeVectorPreferences()
|
||||
private val toggleIpAddressVisibilityUseCase = mockk<ToggleIpAddressVisibilityUseCase>()
|
||||
|
||||
private fun createViewModel(): DevicesViewModel {
|
||||
return DevicesViewModel(
|
||||
|
@ -85,6 +90,8 @@ class DevicesViewModelTest {
|
|||
interceptSignoutFlowResponseUseCase = fakeInterceptSignoutFlowResponseUseCase,
|
||||
pendingAuthHandler = fakePendingAuthHandler.instance,
|
||||
refreshDevicesUseCase = fakeRefreshDevicesUseCase,
|
||||
vectorPreferences = fakeVectorPreferences.instance,
|
||||
toggleIpAddressVisibilityUseCase = toggleIpAddressVisibilityUseCase,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -97,6 +104,7 @@ class DevicesViewModelTest {
|
|||
givenVerificationService()
|
||||
givenCurrentSessionCrossSigningInfo()
|
||||
givenDeviceFullInfoList(deviceId1 = A_DEVICE_ID_1, deviceId2 = A_DEVICE_ID_2)
|
||||
fakeVectorPreferences.givenSessionManagerShowIpAddress(false)
|
||||
}
|
||||
|
||||
private fun givenVerificationService(): FakeVerificationService {
|
||||
|
@ -343,6 +351,33 @@ class DevicesViewModelTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given the viewModel when initializing it then view state of ip address visibility is false`() {
|
||||
// When
|
||||
val viewModelTest = createViewModel().test()
|
||||
|
||||
// Then
|
||||
viewModelTest.assertLatestState { it.isShowingIpAddress == false }
|
||||
viewModelTest.finish()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given the viewModel when toggleIpAddressVisibility action is triggered then view state and preference change accordingly`() {
|
||||
// When
|
||||
val viewModel = createViewModel()
|
||||
val viewModelTest = viewModel.test()
|
||||
every { toggleIpAddressVisibilityUseCase.execute() } just runs
|
||||
every { fakeVectorPreferences.instance.setIpAddressVisibilityInDeviceManagerScreens(true) } just runs
|
||||
every { fakeVectorPreferences.instance.showIpAddressInSessionManagerScreens() } returns true
|
||||
|
||||
viewModel.handle(DevicesAction.ToggleIpAddressVisibility)
|
||||
viewModel.onSharedPreferenceChanged(null, null)
|
||||
|
||||
// Then
|
||||
viewModelTest.assertLatestState { it.isShowingIpAddress == true }
|
||||
viewModelTest.finish()
|
||||
}
|
||||
|
||||
private fun givenCurrentSessionCrossSigningInfo(): CurrentSessionCrossSigningInfo {
|
||||
val currentSessionCrossSigningInfo = mockk<CurrentSessionCrossSigningInfo>()
|
||||
every { currentSessionCrossSigningInfo.deviceId } returns A_CURRENT_DEVICE_ID
|
||||
|
|
|
@ -22,10 +22,12 @@ import com.airbnb.mvrx.test.MavericksTestRule
|
|||
import im.vector.app.features.settings.devices.v2.DeviceFullInfo
|
||||
import im.vector.app.features.settings.devices.v2.GetDeviceFullInfoListUseCase
|
||||
import im.vector.app.features.settings.devices.v2.RefreshDevicesUseCase
|
||||
import im.vector.app.features.settings.devices.v2.ToggleIpAddressVisibilityUseCase
|
||||
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
|
||||
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||
import im.vector.app.test.fakes.FakePendingAuthHandler
|
||||
import im.vector.app.test.fakes.FakeSignoutSessionsUseCase
|
||||
import im.vector.app.test.fakes.FakeVectorPreferences
|
||||
import im.vector.app.test.fakes.FakeVerificationService
|
||||
import im.vector.app.test.fixtures.aDeviceFullInfo
|
||||
import im.vector.app.test.test
|
||||
|
@ -66,6 +68,8 @@ class OtherSessionsViewModelTest {
|
|||
private val fakeRefreshDevicesUseCase = mockk<RefreshDevicesUseCase>(relaxed = true)
|
||||
private val fakeSignoutSessionsUseCase = FakeSignoutSessionsUseCase()
|
||||
private val fakePendingAuthHandler = FakePendingAuthHandler()
|
||||
private val fakeVectorPreferences = FakeVectorPreferences()
|
||||
private val toggleIpAddressVisibilityUseCase = mockk<ToggleIpAddressVisibilityUseCase>()
|
||||
|
||||
private fun createViewModel(viewState: OtherSessionsViewState = OtherSessionsViewState(defaultArgs)) =
|
||||
OtherSessionsViewModel(
|
||||
|
@ -75,6 +79,8 @@ class OtherSessionsViewModelTest {
|
|||
signoutSessionsUseCase = fakeSignoutSessionsUseCase.instance,
|
||||
pendingAuthHandler = fakePendingAuthHandler.instance,
|
||||
refreshDevicesUseCase = fakeRefreshDevicesUseCase,
|
||||
vectorPreferences = fakeVectorPreferences.instance,
|
||||
toggleIpAddressVisibilityUseCase = toggleIpAddressVisibilityUseCase,
|
||||
)
|
||||
|
||||
@Before
|
||||
|
@ -84,6 +90,7 @@ class OtherSessionsViewModelTest {
|
|||
every { SystemClock.elapsedRealtime() } returns 1234
|
||||
|
||||
givenVerificationService()
|
||||
fakeVectorPreferences.givenSessionManagerShowIpAddress(false)
|
||||
}
|
||||
|
||||
private fun givenVerificationService(): FakeVerificationService {
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.airbnb.mvrx.Success
|
|||
import com.airbnb.mvrx.test.MavericksTestRule
|
||||
import im.vector.app.features.settings.devices.v2.DeviceFullInfo
|
||||
import im.vector.app.features.settings.devices.v2.RefreshDevicesUseCase
|
||||
import im.vector.app.features.settings.devices.v2.ToggleIpAddressVisibilityUseCase
|
||||
import im.vector.app.features.settings.devices.v2.notification.NotificationsStatus
|
||||
import im.vector.app.features.settings.devices.v2.signout.InterceptSignoutFlowResponseUseCase
|
||||
import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase
|
||||
|
@ -30,6 +31,7 @@ import im.vector.app.test.fakes.FakeGetNotificationsStatusUseCase
|
|||
import im.vector.app.test.fakes.FakePendingAuthHandler
|
||||
import im.vector.app.test.fakes.FakeSignoutSessionsUseCase
|
||||
import im.vector.app.test.fakes.FakeTogglePushNotificationUseCase
|
||||
import im.vector.app.test.fakes.FakeVectorPreferences
|
||||
import im.vector.app.test.fakes.FakeVerificationService
|
||||
import im.vector.app.test.test
|
||||
import im.vector.app.test.testDispatcher
|
||||
|
@ -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(
|
||||
initialState = SessionOverviewViewState(args),
|
||||
|
@ -89,6 +93,8 @@ class SessionOverviewViewModelTest {
|
|||
refreshDevicesUseCase = refreshDevicesUseCase,
|
||||
togglePushNotificationUseCase = togglePushNotificationUseCase.instance,
|
||||
getNotificationsStatusUseCase = fakeGetNotificationsStatusUseCase.instance,
|
||||
vectorPreferences = fakeVectorPreferences.instance,
|
||||
toggleIpAddressVisibilityUseCase = toggleIpAddressVisibilityUseCase,
|
||||
)
|
||||
|
||||
@Before
|
||||
|
@ -103,6 +109,7 @@ class SessionOverviewViewModelTest {
|
|||
A_SESSION_ID_1,
|
||||
notificationsStatus
|
||||
)
|
||||
fakeVectorPreferences.givenSessionManagerShowIpAddress(false)
|
||||
}
|
||||
|
||||
private fun givenVerificationService(): FakeVerificationService {
|
||||
|
|
|
@ -52,4 +52,8 @@ class FakeVectorPreferences {
|
|||
fun verifySetNotificationEnabledForDevice(enabled: Boolean, inverse: Boolean = false) {
|
||||
verify(inverse = inverse) { instance.setNotificationEnabledForDevice(enabled) }
|
||||
}
|
||||
|
||||
fun givenSessionManagerShowIpAddress(showIpAddress: Boolean) {
|
||||
every { instance.showIpAddressInSessionManagerScreens() } returns showIpAddress
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue