Inject new ViewModel in the fragment V2 + add use cases
This commit is contained in:
		
							parent
							
								
									801eef3ce7
								
							
						
					
					
						commit
						3a73e72b16
					
				@ -17,6 +17,7 @@
 | 
				
			|||||||
package im.vector.app.features.settings.devices
 | 
					package im.vector.app.features.settings.devices
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import im.vector.app.core.di.ActiveSessionHolder
 | 
					import im.vector.app.core.di.ActiveSessionHolder
 | 
				
			||||||
 | 
					import im.vector.app.features.settings.devices.v2.CurrentSessionCrossSigningInfo
 | 
				
			||||||
import javax.inject.Inject
 | 
					import javax.inject.Inject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GetCurrentSessionCrossSigningInfoUseCase @Inject constructor(
 | 
					class GetCurrentSessionCrossSigningInfoUseCase @Inject constructor(
 | 
				
			||||||
@ -28,7 +29,7 @@ class GetCurrentSessionCrossSigningInfoUseCase @Inject constructor(
 | 
				
			|||||||
        val isCrossSigningInitialized = session.cryptoService().crossSigningService().isCrossSigningInitialized()
 | 
					        val isCrossSigningInitialized = session.cryptoService().crossSigningService().isCrossSigningInitialized()
 | 
				
			||||||
        val isCrossSigningVerified = session.cryptoService().crossSigningService().isCrossSigningVerified()
 | 
					        val isCrossSigningVerified = session.cryptoService().crossSigningService().isCrossSigningVerified()
 | 
				
			||||||
        return CurrentSessionCrossSigningInfo(
 | 
					        return CurrentSessionCrossSigningInfo(
 | 
				
			||||||
                deviceId = session.sessionParams.deviceId,
 | 
					                deviceId = session.sessionParams.deviceId.orEmpty(),
 | 
				
			||||||
                isCrossSigningInitialized = isCrossSigningInitialized,
 | 
					                isCrossSigningInitialized = isCrossSigningInitialized,
 | 
				
			||||||
                isCrossSigningVerified = isCrossSigningVerified
 | 
					                isCrossSigningVerified = isCrossSigningVerified
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package im.vector.app.features.settings.devices
 | 
					package im.vector.app.features.settings.devices
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import im.vector.app.features.settings.devices.v2.CurrentSessionCrossSigningInfo
 | 
				
			||||||
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
 | 
					import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
 | 
				
			||||||
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
 | 
					import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
 | 
				
			||||||
import javax.inject.Inject
 | 
					import javax.inject.Inject
 | 
				
			||||||
 | 
				
			|||||||
@ -14,13 +14,13 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package im.vector.app.features.settings.devices
 | 
					package im.vector.app.features.settings.devices.v2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Used to hold some info about the cross signing of the current Session.
 | 
					 * Used to hold some info about the cross signing of the current Session.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
data class CurrentSessionCrossSigningInfo(
 | 
					data class CurrentSessionCrossSigningInfo(
 | 
				
			||||||
        val deviceId: String?,
 | 
					        val deviceId: String = "",
 | 
				
			||||||
        val isCrossSigningInitialized: Boolean,
 | 
					        val isCrossSigningInitialized: Boolean = false,
 | 
				
			||||||
        val isCrossSigningVerified: Boolean,
 | 
					        val isCrossSigningVerified: Boolean = false,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -17,29 +17,22 @@
 | 
				
			|||||||
package im.vector.app.features.settings.devices.v2
 | 
					package im.vector.app.features.settings.devices.v2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.airbnb.mvrx.MavericksViewModelFactory
 | 
					import com.airbnb.mvrx.MavericksViewModelFactory
 | 
				
			||||||
 | 
					import com.airbnb.mvrx.Success
 | 
				
			||||||
import dagger.assisted.Assisted
 | 
					import dagger.assisted.Assisted
 | 
				
			||||||
import dagger.assisted.AssistedFactory
 | 
					import dagger.assisted.AssistedFactory
 | 
				
			||||||
import dagger.assisted.AssistedInject
 | 
					import dagger.assisted.AssistedInject
 | 
				
			||||||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
 | 
					import im.vector.app.core.di.MavericksAssistedViewModelFactory
 | 
				
			||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
 | 
					import im.vector.app.core.di.hiltMavericksViewModelFactory
 | 
				
			||||||
import im.vector.app.core.platform.VectorViewModel
 | 
					import im.vector.app.core.platform.VectorViewModel
 | 
				
			||||||
import im.vector.app.core.resources.StringProvider
 | 
					import kotlinx.coroutines.flow.launchIn
 | 
				
			||||||
import im.vector.app.features.login.ReAuthHelper
 | 
					import kotlinx.coroutines.flow.onEach
 | 
				
			||||||
import im.vector.app.features.settings.devices.GetCurrentSessionCrossSigningInfoUseCase
 | 
					import org.matrix.android.sdk.api.extensions.orFalse
 | 
				
			||||||
import im.vector.app.features.settings.devices.GetEncryptionTrustLevelForDeviceUseCase
 | 
					 | 
				
			||||||
import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
 | 
					 | 
				
			||||||
import org.matrix.android.sdk.api.Matrix
 | 
					 | 
				
			||||||
import org.matrix.android.sdk.api.session.Session
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO add unit tests
 | 
				
			||||||
class DevicesViewModel @AssistedInject constructor(
 | 
					class DevicesViewModel @AssistedInject constructor(
 | 
				
			||||||
        @Assisted initialState: DevicesViewState,
 | 
					        @Assisted initialState: DevicesViewState,
 | 
				
			||||||
        private val session: Session,
 | 
					        private val getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
 | 
				
			||||||
        private val reAuthHelper: ReAuthHelper,
 | 
					        private val getDeviceFullInfoListUseCase: GetDeviceFullInfoListUseCase,
 | 
				
			||||||
        private val stringProvider: StringProvider,
 | 
					 | 
				
			||||||
        private val matrix: Matrix,
 | 
					 | 
				
			||||||
        private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
 | 
					 | 
				
			||||||
        getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
 | 
					 | 
				
			||||||
        private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase,
 | 
					 | 
				
			||||||
) : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvent>(initialState) {
 | 
					) : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvent>(initialState) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @AssistedFactory
 | 
					    @AssistedFactory
 | 
				
			||||||
@ -49,8 +42,43 @@ class DevicesViewModel @AssistedInject constructor(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    companion object : MavericksViewModelFactory<DevicesViewModel, DevicesViewState> by hiltMavericksViewModelFactory()
 | 
					    companion object : MavericksViewModelFactory<DevicesViewModel, DevicesViewState> by hiltMavericksViewModelFactory()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    init {
 | 
				
			||||||
 | 
					        observeCurrentSessionCrossSigningInfo()
 | 
				
			||||||
 | 
					        observeDevices()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun observeCurrentSessionCrossSigningInfo() {
 | 
				
			||||||
 | 
					        getCurrentSessionCrossSigningInfoUseCase.execute()
 | 
				
			||||||
 | 
					                .onEach { crossSigningInfo ->
 | 
				
			||||||
 | 
					                    setState {
 | 
				
			||||||
 | 
					                        copy(currentSessionCrossSigningInfo = crossSigningInfo)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                .launchIn(viewModelScope)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun observeDevices() {
 | 
				
			||||||
 | 
					        getDeviceFullInfoListUseCase.execute()
 | 
				
			||||||
 | 
					                .execute { async ->
 | 
				
			||||||
 | 
					                    if (async is Success) {
 | 
				
			||||||
 | 
					                        val deviceFullInfoList = async.invoke()
 | 
				
			||||||
 | 
					                        val unverifiedSessionsCount = deviceFullInfoList.count { !it.cryptoDeviceInfo?.trustLevel?.isVerified().orFalse() }
 | 
				
			||||||
 | 
					                        val inactiveSessionsCount = deviceFullInfoList.count { it.isInactive }
 | 
				
			||||||
 | 
					                        copy(
 | 
				
			||||||
 | 
					                                devices = async,
 | 
				
			||||||
 | 
					                                unverifiedSessionsCount = unverifiedSessionsCount,
 | 
				
			||||||
 | 
					                                inactiveSessionsCount = inactiveSessionsCount,
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        copy(
 | 
				
			||||||
 | 
					                                devices = async
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun handle(action: DevicesAction) {
 | 
					    override fun handle(action: DevicesAction) {
 | 
				
			||||||
        when(action) {
 | 
					        when (action) {
 | 
				
			||||||
            is DevicesAction.MarkAsManuallyVerified -> handleMarkAsManuallyVerifiedAction()
 | 
					            is DevicesAction.MarkAsManuallyVerified -> handleMarkAsManuallyVerifiedAction()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -21,10 +21,9 @@ import com.airbnb.mvrx.MavericksState
 | 
				
			|||||||
import com.airbnb.mvrx.Uninitialized
 | 
					import com.airbnb.mvrx.Uninitialized
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data class DevicesViewState(
 | 
					data class DevicesViewState(
 | 
				
			||||||
        val myDeviceId: String = "",
 | 
					        val currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo = CurrentSessionCrossSigningInfo(),
 | 
				
			||||||
        val devices: Async<List<DeviceFullInfo>> = Uninitialized,
 | 
					        val devices: Async<List<DeviceFullInfo>> = Uninitialized,
 | 
				
			||||||
        val hasAccountCrossSigning: Boolean = false,
 | 
					 | 
				
			||||||
        val accountCrossSigningIsTrusted: Boolean = false,
 | 
					 | 
				
			||||||
        val unverifiedSessionsCount: Int = 0,
 | 
					        val unverifiedSessionsCount: Int = 0,
 | 
				
			||||||
        val inactiveSessionsCount: Int = 0,
 | 
					        val inactiveSessionsCount: Int = 0,
 | 
				
			||||||
 | 
					        val isLoading: Boolean = false,
 | 
				
			||||||
) : MavericksState
 | 
					) : MavericksState
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.core.di.ActiveSessionHolder
 | 
				
			||||||
 | 
					import im.vector.app.features.settings.devices.v2.CurrentSessionCrossSigningInfo
 | 
				
			||||||
 | 
					import kotlinx.coroutines.flow.Flow
 | 
				
			||||||
 | 
					import kotlinx.coroutines.flow.emptyFlow
 | 
				
			||||||
 | 
					import kotlinx.coroutines.flow.map
 | 
				
			||||||
 | 
					import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
 | 
				
			||||||
 | 
					import org.matrix.android.sdk.api.util.Optional
 | 
				
			||||||
 | 
					import org.matrix.android.sdk.flow.flow
 | 
				
			||||||
 | 
					import javax.inject.Inject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO add unit tests
 | 
				
			||||||
 | 
					class GetCurrentSessionCrossSigningInfoUseCase @Inject constructor(
 | 
				
			||||||
 | 
					        private val activeSessionHolder: ActiveSessionHolder,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun execute(): Flow<CurrentSessionCrossSigningInfo> {
 | 
				
			||||||
 | 
					        return activeSessionHolder.getSafeActiveSession()
 | 
				
			||||||
 | 
					                ?.let { session ->
 | 
				
			||||||
 | 
					                    session.flow().liveCrossSigningInfo(session.myUserId)
 | 
				
			||||||
 | 
					                            .map { convertToSigningInfo(session.sessionParams.deviceId.orEmpty(), it) }
 | 
				
			||||||
 | 
					                } ?: emptyFlow()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun convertToSigningInfo(deviceId: String, mxCrossSigningInfo: Optional<MXCrossSigningInfo>): CurrentSessionCrossSigningInfo {
 | 
				
			||||||
 | 
					        return CurrentSessionCrossSigningInfo(
 | 
				
			||||||
 | 
					                deviceId = deviceId,
 | 
				
			||||||
 | 
					                isCrossSigningInitialized = mxCrossSigningInfo.getOrNull() != null,
 | 
				
			||||||
 | 
					                isCrossSigningVerified = mxCrossSigningInfo.getOrNull()?.isTrusted() == true
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.core.di.ActiveSessionHolder
 | 
				
			||||||
 | 
					import im.vector.app.features.settings.devices.GetEncryptionTrustLevelForDeviceUseCase
 | 
				
			||||||
 | 
					import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
 | 
				
			||||||
 | 
					import kotlinx.coroutines.flow.Flow
 | 
				
			||||||
 | 
					import kotlinx.coroutines.flow.combine
 | 
				
			||||||
 | 
					import kotlinx.coroutines.flow.distinctUntilChanged
 | 
				
			||||||
 | 
					import kotlinx.coroutines.flow.emptyFlow
 | 
				
			||||||
 | 
					import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
 | 
				
			||||||
 | 
					import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
 | 
				
			||||||
 | 
					import org.matrix.android.sdk.flow.flow
 | 
				
			||||||
 | 
					import javax.inject.Inject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO add unit tests
 | 
				
			||||||
 | 
					class GetDeviceFullInfoListUseCase @Inject constructor(
 | 
				
			||||||
 | 
					        private val activeSessionHolder: ActiveSessionHolder,
 | 
				
			||||||
 | 
					        private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
 | 
				
			||||||
 | 
					        private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase,
 | 
				
			||||||
 | 
					        private val getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun execute(): Flow<List<DeviceFullInfo>> {
 | 
				
			||||||
 | 
					        return activeSessionHolder.getSafeActiveSession()?.let { session ->
 | 
				
			||||||
 | 
					            val deviceFullInfoFlow = combine(
 | 
				
			||||||
 | 
					                    getCurrentSessionCrossSigningInfoUseCase.execute(),
 | 
				
			||||||
 | 
					                    session.flow().liveUserCryptoDevices(session.myUserId),
 | 
				
			||||||
 | 
					                    session.flow().liveMyDevicesInfo()
 | 
				
			||||||
 | 
					            ) { currentSessionCrossSigningInfo, cryptoList, infoList ->
 | 
				
			||||||
 | 
					                convertToDeviceFullInfoList(currentSessionCrossSigningInfo, cryptoList, infoList)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            deviceFullInfoFlow.distinctUntilChanged()
 | 
				
			||||||
 | 
					        } ?: emptyFlow()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun convertToDeviceFullInfoList(
 | 
				
			||||||
 | 
					            currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo,
 | 
				
			||||||
 | 
					            cryptoList: List<CryptoDeviceInfo>,
 | 
				
			||||||
 | 
					            infoList: List<DeviceInfo>,
 | 
				
			||||||
 | 
					    ): List<DeviceFullInfo> {
 | 
				
			||||||
 | 
					        return infoList
 | 
				
			||||||
 | 
					                .sortedByDescending { it.lastSeenTs }
 | 
				
			||||||
 | 
					                .map { deviceInfo ->
 | 
				
			||||||
 | 
					                    val cryptoDeviceInfo = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }
 | 
				
			||||||
 | 
					                    val trustLevelForShield = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo)
 | 
				
			||||||
 | 
					                    val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs ?: 0)
 | 
				
			||||||
 | 
					                    DeviceFullInfo(deviceInfo, cryptoDeviceInfo, trustLevelForShield, isInactive)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -24,8 +24,6 @@ import android.view.ViewGroup
 | 
				
			|||||||
import android.widget.Toast
 | 
					import android.widget.Toast
 | 
				
			||||||
import androidx.appcompat.app.AppCompatActivity
 | 
					import androidx.appcompat.app.AppCompatActivity
 | 
				
			||||||
import androidx.core.view.isVisible
 | 
					import androidx.core.view.isVisible
 | 
				
			||||||
import com.airbnb.mvrx.Async
 | 
					 | 
				
			||||||
import com.airbnb.mvrx.Loading
 | 
					 | 
				
			||||||
import com.airbnb.mvrx.Success
 | 
					import com.airbnb.mvrx.Success
 | 
				
			||||||
import com.airbnb.mvrx.fragmentViewModel
 | 
					import com.airbnb.mvrx.fragmentViewModel
 | 
				
			||||||
import com.airbnb.mvrx.withState
 | 
					import com.airbnb.mvrx.withState
 | 
				
			||||||
@ -39,10 +37,6 @@ import im.vector.app.core.resources.DrawableProvider
 | 
				
			|||||||
import im.vector.app.databinding.FragmentSettingsDevicesBinding
 | 
					import im.vector.app.databinding.FragmentSettingsDevicesBinding
 | 
				
			||||||
import im.vector.app.features.crypto.recover.SetupMode
 | 
					import im.vector.app.features.crypto.recover.SetupMode
 | 
				
			||||||
import im.vector.app.features.crypto.verification.VerificationBottomSheet
 | 
					import im.vector.app.features.crypto.verification.VerificationBottomSheet
 | 
				
			||||||
import im.vector.app.features.settings.devices.DeviceFullInfo
 | 
					 | 
				
			||||||
import im.vector.app.features.settings.devices.DevicesAction
 | 
					 | 
				
			||||||
import im.vector.app.features.settings.devices.DevicesViewEvents
 | 
					 | 
				
			||||||
import im.vector.app.features.settings.devices.DevicesViewModel
 | 
					 | 
				
			||||||
import im.vector.app.features.settings.devices.v2.list.OtherSessionsController
 | 
					import im.vector.app.features.settings.devices.v2.list.OtherSessionsController
 | 
				
			||||||
import im.vector.app.features.settings.devices.v2.list.SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS
 | 
					import im.vector.app.features.settings.devices.v2.list.SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS
 | 
				
			||||||
import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationViewState
 | 
					import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationViewState
 | 
				
			||||||
@ -93,27 +87,27 @@ class VectorSettingsDevicesFragment :
 | 
				
			|||||||
    private fun observeViewEvents() {
 | 
					    private fun observeViewEvents() {
 | 
				
			||||||
        viewModel.observeViewEvents {
 | 
					        viewModel.observeViewEvents {
 | 
				
			||||||
            when (it) {
 | 
					            when (it) {
 | 
				
			||||||
                is DevicesViewEvents.Loading -> showLoading(it.message)
 | 
					                is DevicesViewEvent.Loading -> showLoading(it.message)
 | 
				
			||||||
                is DevicesViewEvents.Failure -> showFailure(it.throwable)
 | 
					                is DevicesViewEvent.Failure -> showFailure(it.throwable)
 | 
				
			||||||
                is DevicesViewEvents.RequestReAuth -> Unit // TODO. Next PR
 | 
					                is DevicesViewEvent.RequestReAuth -> Unit // TODO. Next PR
 | 
				
			||||||
                is DevicesViewEvents.PromptRenameDevice -> Unit // TODO. Next PR
 | 
					                is DevicesViewEvent.PromptRenameDevice -> Unit // TODO. Next PR
 | 
				
			||||||
                is DevicesViewEvents.ShowVerifyDevice -> {
 | 
					                is DevicesViewEvent.ShowVerifyDevice -> {
 | 
				
			||||||
                    VerificationBottomSheet.withArgs(
 | 
					                    VerificationBottomSheet.withArgs(
 | 
				
			||||||
                            roomId = null,
 | 
					                            roomId = null,
 | 
				
			||||||
                            otherUserId = it.userId,
 | 
					                            otherUserId = it.userId,
 | 
				
			||||||
                            transactionId = it.transactionId
 | 
					                            transactionId = it.transactionId
 | 
				
			||||||
                    ).show(childFragmentManager, "REQPOP")
 | 
					                    ).show(childFragmentManager, "REQPOP")
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                is DevicesViewEvents.SelfVerification -> {
 | 
					                is DevicesViewEvent.SelfVerification -> {
 | 
				
			||||||
                    VerificationBottomSheet.forSelfVerification(it.session)
 | 
					                    VerificationBottomSheet.forSelfVerification(it.session)
 | 
				
			||||||
                            .show(childFragmentManager, "REQPOP")
 | 
					                            .show(childFragmentManager, "REQPOP")
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                is DevicesViewEvents.ShowManuallyVerify -> {
 | 
					                is DevicesViewEvent.ShowManuallyVerify -> {
 | 
				
			||||||
                    ManuallyVerifyDialog.show(requireActivity(), it.cryptoDeviceInfo) {
 | 
					                    ManuallyVerifyDialog.show(requireActivity(), it.cryptoDeviceInfo) {
 | 
				
			||||||
                        viewModel.handle(DevicesAction.MarkAsManuallyVerified(it.cryptoDeviceInfo))
 | 
					                        viewModel.handle(DevicesAction.MarkAsManuallyVerified(it.cryptoDeviceInfo))
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                is DevicesViewEvents.PromptResetSecrets -> {
 | 
					                is DevicesViewEvent.PromptResetSecrets -> {
 | 
				
			||||||
                    navigator.open4SSetup(requireContext(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET)
 | 
					                    navigator.open4SSetup(requireContext(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -151,10 +145,11 @@ class VectorSettingsDevicesFragment :
 | 
				
			|||||||
    override fun invalidate() = withState(viewModel) { state ->
 | 
					    override fun invalidate() = withState(viewModel) { state ->
 | 
				
			||||||
        if (state.devices is Success) {
 | 
					        if (state.devices is Success) {
 | 
				
			||||||
            val devices = state.devices()
 | 
					            val devices = state.devices()
 | 
				
			||||||
 | 
					            val currentDeviceId = state.currentSessionCrossSigningInfo.deviceId
 | 
				
			||||||
            val currentDeviceInfo = devices?.firstOrNull {
 | 
					            val currentDeviceInfo = devices?.firstOrNull {
 | 
				
			||||||
                it.deviceInfo.deviceId == state.myDeviceId
 | 
					                it.deviceInfo.deviceId == currentDeviceId
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            val otherDevices = devices?.filter { it.deviceInfo.deviceId != state.myDeviceId }
 | 
					            val otherDevices = devices?.filter { it.deviceInfo.deviceId != currentDeviceId }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            renderSecurityRecommendations(state.inactiveSessionsCount, state.unverifiedSessionsCount)
 | 
					            renderSecurityRecommendations(state.inactiveSessionsCount, state.unverifiedSessionsCount)
 | 
				
			||||||
            renderCurrentDevice(currentDeviceInfo)
 | 
					            renderCurrentDevice(currentDeviceInfo)
 | 
				
			||||||
@ -165,7 +160,7 @@ class VectorSettingsDevicesFragment :
 | 
				
			|||||||
            hideOtherSessionsView()
 | 
					            hideOtherSessionsView()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        handleRequestStatus(state.request)
 | 
					        handleLoadingStatus(state.isLoading)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun renderSecurityRecommendations(inactiveSessionsCount: Int, unverifiedSessionsCount: Int) {
 | 
					    private fun renderSecurityRecommendations(inactiveSessionsCount: Int, unverifiedSessionsCount: Int) {
 | 
				
			||||||
@ -254,10 +249,7 @@ class VectorSettingsDevicesFragment :
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun handleRequestStatus(unIgnoreRequest: Async<Unit>) {
 | 
					    private fun handleLoadingStatus(isLoading: Boolean) {
 | 
				
			||||||
        views.waitingView.root.isVisible = when (unIgnoreRequest) {
 | 
					        views.waitingView.root.isVisible = isLoading
 | 
				
			||||||
            is Loading -> true
 | 
					 | 
				
			||||||
            else -> false
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@ import im.vector.app.core.epoxy.noResultItem
 | 
				
			|||||||
import im.vector.app.core.resources.ColorProvider
 | 
					import im.vector.app.core.resources.ColorProvider
 | 
				
			||||||
import im.vector.app.core.resources.DrawableProvider
 | 
					import im.vector.app.core.resources.DrawableProvider
 | 
				
			||||||
import im.vector.app.core.resources.StringProvider
 | 
					import im.vector.app.core.resources.StringProvider
 | 
				
			||||||
import im.vector.app.features.settings.devices.DeviceFullInfo
 | 
					import im.vector.app.features.settings.devices.v2.DeviceFullInfo
 | 
				
			||||||
import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
 | 
					import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
 | 
				
			||||||
import javax.inject.Inject
 | 
					import javax.inject.Inject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,7 +60,7 @@ class OtherSessionsController @Inject constructor(
 | 
				
			|||||||
                            SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS,
 | 
					                            SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS,
 | 
				
			||||||
                            formattedLastActivityDate
 | 
					                            formattedLastActivityDate
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                } else if (device.trustLevelForShield == RoomEncryptionTrustLevel.Trusted) {
 | 
					                } else if (device.roomEncryptionTrustLevel == RoomEncryptionTrustLevel.Trusted) {
 | 
				
			||||||
                    stringProvider.getString(R.string.device_manager_other_sessions_description_verified, formattedLastActivityDate)
 | 
					                    stringProvider.getString(R.string.device_manager_other_sessions_description_verified, formattedLastActivityDate)
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    stringProvider.getString(R.string.device_manager_other_sessions_description_unverified, formattedLastActivityDate)
 | 
					                    stringProvider.getString(R.string.device_manager_other_sessions_description_unverified, formattedLastActivityDate)
 | 
				
			||||||
@ -71,7 +71,7 @@ class OtherSessionsController @Inject constructor(
 | 
				
			|||||||
                otherSessionItem {
 | 
					                otherSessionItem {
 | 
				
			||||||
                    id(device.deviceInfo.deviceId)
 | 
					                    id(device.deviceInfo.deviceId)
 | 
				
			||||||
                    deviceType(DeviceType.UNKNOWN) // TODO. We don't have this info yet. Update accordingly.
 | 
					                    deviceType(DeviceType.UNKNOWN) // TODO. We don't have this info yet. Update accordingly.
 | 
				
			||||||
                    roomEncryptionTrustLevel(device.trustLevelForShield)
 | 
					                    roomEncryptionTrustLevel(device.roomEncryptionTrustLevel)
 | 
				
			||||||
                    sessionName(device.deviceInfo.displayName)
 | 
					                    sessionName(device.deviceInfo.displayName)
 | 
				
			||||||
                    sessionDescription(description)
 | 
					                    sessionDescription(description)
 | 
				
			||||||
                    sessionDescriptionDrawable(descriptionDrawable)
 | 
					                    sessionDescriptionDrawable(descriptionDrawable)
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@ import im.vector.app.R
 | 
				
			|||||||
import im.vector.app.core.extensions.cleanup
 | 
					import im.vector.app.core.extensions.cleanup
 | 
				
			||||||
import im.vector.app.core.extensions.configureWith
 | 
					import im.vector.app.core.extensions.configureWith
 | 
				
			||||||
import im.vector.app.databinding.ViewOtherSessionsBinding
 | 
					import im.vector.app.databinding.ViewOtherSessionsBinding
 | 
				
			||||||
import im.vector.app.features.settings.devices.DeviceFullInfo
 | 
					import im.vector.app.features.settings.devices.v2.DeviceFullInfo
 | 
				
			||||||
import javax.inject.Inject
 | 
					import javax.inject.Inject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@AndroidEntryPoint
 | 
					@AndroidEntryPoint
 | 
				
			||||||
 | 
				
			|||||||
@ -57,7 +57,7 @@ class SessionInfoView @JvmOverloads constructor(
 | 
				
			|||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        renderDeviceInfo(sessionInfoViewState.deviceFullInfo.deviceInfo.displayName.orEmpty())
 | 
					        renderDeviceInfo(sessionInfoViewState.deviceFullInfo.deviceInfo.displayName.orEmpty())
 | 
				
			||||||
        renderVerificationStatus(
 | 
					        renderVerificationStatus(
 | 
				
			||||||
                sessionInfoViewState.deviceFullInfo.trustLevelForShield,
 | 
					                sessionInfoViewState.deviceFullInfo.roomEncryptionTrustLevel,
 | 
				
			||||||
                sessionInfoViewState.isCurrentSession,
 | 
					                sessionInfoViewState.isCurrentSession,
 | 
				
			||||||
                sessionInfoViewState.isLearnMoreLinkVisible,
 | 
					                sessionInfoViewState.isLearnMoreLinkVisible,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package im.vector.app.features.settings.devices.v2.list
 | 
					package im.vector.app.features.settings.devices.v2.list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import im.vector.app.features.settings.devices.DeviceFullInfo
 | 
					import im.vector.app.features.settings.devices.v2.DeviceFullInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data class SessionInfoViewState(
 | 
					data class SessionInfoViewState(
 | 
				
			||||||
        val isCurrentSession: Boolean,
 | 
					        val isCurrentSession: Boolean,
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ package im.vector.app.features.settings.devices.v2.overview
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import androidx.lifecycle.asFlow
 | 
					import androidx.lifecycle.asFlow
 | 
				
			||||||
import im.vector.app.core.di.ActiveSessionHolder
 | 
					import im.vector.app.core.di.ActiveSessionHolder
 | 
				
			||||||
import im.vector.app.features.settings.devices.DeviceFullInfo
 | 
					import im.vector.app.features.settings.devices.v2.DeviceFullInfo
 | 
				
			||||||
import im.vector.app.features.settings.devices.GetCurrentSessionCrossSigningInfoUseCase
 | 
					import im.vector.app.features.settings.devices.GetCurrentSessionCrossSigningInfoUseCase
 | 
				
			||||||
import im.vector.app.features.settings.devices.GetEncryptionTrustLevelForDeviceUseCase
 | 
					import im.vector.app.features.settings.devices.GetEncryptionTrustLevelForDeviceUseCase
 | 
				
			||||||
import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
 | 
					import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
 | 
				
			||||||
@ -51,7 +51,7 @@ class GetDeviceFullInfoUseCase @Inject constructor(
 | 
				
			|||||||
                    DeviceFullInfo(
 | 
					                    DeviceFullInfo(
 | 
				
			||||||
                            deviceInfo = info,
 | 
					                            deviceInfo = info,
 | 
				
			||||||
                            cryptoDeviceInfo = cryptoInfo,
 | 
					                            cryptoDeviceInfo = cryptoInfo,
 | 
				
			||||||
                            trustLevelForShield = roomEncryptionTrustLevel,
 | 
					                            roomEncryptionTrustLevel = roomEncryptionTrustLevel,
 | 
				
			||||||
                            isInactive = isInactive
 | 
					                            isInactive = isInactive
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,7 @@ import im.vector.app.core.platform.VectorBaseFragment
 | 
				
			|||||||
import im.vector.app.core.resources.ColorProvider
 | 
					import im.vector.app.core.resources.ColorProvider
 | 
				
			||||||
import im.vector.app.core.resources.DrawableProvider
 | 
					import im.vector.app.core.resources.DrawableProvider
 | 
				
			||||||
import im.vector.app.databinding.FragmentSessionOverviewBinding
 | 
					import im.vector.app.databinding.FragmentSessionOverviewBinding
 | 
				
			||||||
import im.vector.app.features.settings.devices.DeviceFullInfo
 | 
					import im.vector.app.features.settings.devices.v2.DeviceFullInfo
 | 
				
			||||||
import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
 | 
					import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
 | 
				
			||||||
import javax.inject.Inject
 | 
					import javax.inject.Inject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,7 @@ package im.vector.app.features.settings.devices.v2.overview
 | 
				
			|||||||
import com.airbnb.mvrx.Async
 | 
					import com.airbnb.mvrx.Async
 | 
				
			||||||
import com.airbnb.mvrx.MavericksState
 | 
					import com.airbnb.mvrx.MavericksState
 | 
				
			||||||
import com.airbnb.mvrx.Uninitialized
 | 
					import com.airbnb.mvrx.Uninitialized
 | 
				
			||||||
import im.vector.app.features.settings.devices.DeviceFullInfo
 | 
					import im.vector.app.features.settings.devices.v2.DeviceFullInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data class SessionOverviewViewState(
 | 
					data class SessionOverviewViewState(
 | 
				
			||||||
        val deviceId: String,
 | 
					        val deviceId: String,
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package im.vector.app.features.settings.devices
 | 
					package im.vector.app.features.settings.devices
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import im.vector.app.features.settings.devices.v2.CurrentSessionCrossSigningInfo
 | 
				
			||||||
import im.vector.app.test.fakes.FakeActiveSessionHolder
 | 
					import im.vector.app.test.fakes.FakeActiveSessionHolder
 | 
				
			||||||
import io.mockk.every
 | 
					import io.mockk.every
 | 
				
			||||||
import io.mockk.mockk
 | 
					import io.mockk.mockk
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package im.vector.app.features.settings.devices
 | 
					package im.vector.app.features.settings.devices
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import im.vector.app.features.settings.devices.v2.CurrentSessionCrossSigningInfo
 | 
				
			||||||
import io.mockk.every
 | 
					import io.mockk.every
 | 
				
			||||||
import io.mockk.mockk
 | 
					import io.mockk.mockk
 | 
				
			||||||
import io.mockk.verify
 | 
					import io.mockk.verify
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ package im.vector.app.features.settings.devices.v2.overview
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import androidx.lifecycle.MutableLiveData
 | 
					import androidx.lifecycle.MutableLiveData
 | 
				
			||||||
import androidx.lifecycle.asFlow
 | 
					import androidx.lifecycle.asFlow
 | 
				
			||||||
import im.vector.app.features.settings.devices.CurrentSessionCrossSigningInfo
 | 
					import im.vector.app.features.settings.devices.v2.CurrentSessionCrossSigningInfo
 | 
				
			||||||
import im.vector.app.features.settings.devices.DeviceFullInfo
 | 
					import im.vector.app.features.settings.devices.DeviceFullInfo
 | 
				
			||||||
import im.vector.app.features.settings.devices.GetCurrentSessionCrossSigningInfoUseCase
 | 
					import im.vector.app.features.settings.devices.GetCurrentSessionCrossSigningInfoUseCase
 | 
				
			||||||
import im.vector.app.features.settings.devices.GetEncryptionTrustLevelForDeviceUseCase
 | 
					import im.vector.app.features.settings.devices.GetEncryptionTrustLevelForDeviceUseCase
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user