diff --git a/changelog.d/7130.bugfix b/changelog.d/7130.bugfix new file mode 100644 index 0000000000..1e4045ad76 --- /dev/null +++ b/changelog.d/7130.bugfix @@ -0,0 +1 @@ + Fix empty verification bottom sheet. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/SessionExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/SessionExtensions.kt index a15e73eb88..96dac27618 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/SessionExtensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/SessionExtensions.kt @@ -32,5 +32,13 @@ fun Session.getRoomSummary(roomIdOrAlias: String): RoomSummary? = roomService(). /** * Get a user using the UserService of a Session. + * @param userId the userId to look for. + * @return a user with userId or null if the User is not known yet by the SDK. + * See [org.matrix.android.sdk.api.session.user.UserService.resolveUser] to ensure that a User is retrieved. */ fun Session.getUser(userId: String): User? = userService().getUser(userId) + +/** + * Similar to [getUser], but fallback to a User without details if the User is not known by the SDK, or if Session is null. + */ +fun Session?.getUserOrDefault(userId: String): User = this?.userService()?.getUser(userId) ?: User(userId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt index 0c5465e12a..7075023798 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt @@ -29,7 +29,7 @@ interface UserService { /** * Get a user from a userId. * @param userId the userId to look for. - * @return a user with userId or null + * @return a user with userId or null if the User is not known yet by the SDK. See [resolveUser] to ensure that a User is retrieved. */ fun getUser(userId: String): User? diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt index 36ee47ca06..61ebc82767 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt @@ -37,11 +37,10 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.getUser +import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.permalinks.PermalinkParser import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams -import org.matrix.android.sdk.api.session.user.model.User class CreateDirectRoomViewModel @AssistedInject constructor( @Assisted initialState: CreateDirectRoomViewState, @@ -78,11 +77,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor( _viewEvents.post(CreateDirectRoomViewEvents.DmSelf) } else { // Try to get user from known users and fall back to creating a User object from MXID - val qrInvitee = if (session.getUser(mxid) != null) { - session.getUser(mxid)!! - } else { - User(mxid, null, null) - } + val qrInvitee = session.getUserOrDefault(mxid) onSubmitInvitees(setOf(PendingSelection.UserPendingSelection(qrInvitee))) } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt index 91bb3fa7f2..3406a86d1e 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt @@ -31,6 +31,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificatio import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState +import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.util.toMatrixItem import timber.log.Timber import javax.inject.Inject @@ -67,8 +68,8 @@ class IncomingVerificationRequestHandler @Inject constructor( when (tx.state) { is VerificationTxState.OnStarted -> { // Add a notification for every incoming request - val user = session?.userService()?.getUser(tx.otherUserId) - val name = user?.toMatrixItem()?.getBestName() ?: tx.otherUserId + val user = session.getUserOrDefault(tx.otherUserId).toMatrixItem() + val name = user.getBestName() val alert = VerificationVectorAlert( uid, context.getString(R.string.sas_incoming_request_notif_title), @@ -86,7 +87,7 @@ class IncomingVerificationRequestHandler @Inject constructor( } ) .apply { - viewBinder = VerificationVectorAlert.ViewBinder(user?.toMatrixItem(), avatarRenderer.get()) + viewBinder = VerificationVectorAlert.ViewBinder(user, avatarRenderer.get()) contentAction = Runnable { (weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { it.navigator.performDeviceVerification(it, tx.otherUserId, tx.transactionId) @@ -131,8 +132,8 @@ class IncomingVerificationRequestHandler @Inject constructor( // XXX this is a bit hard coded :/ popupAlertManager.cancelAlert("review_login") } - val user = session?.userService()?.getUser(pr.otherUserId)?.toMatrixItem() - val name = user?.getBestName() ?: pr.otherUserId + val user = session.getUserOrDefault(pr.otherUserId).toMatrixItem() + val name = user.getBestName() val description = if (name == pr.otherUserId) { name } else { diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt index eae868eb26..38b72f2022 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt @@ -152,29 +152,25 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment - state.otherUserMxItem?.let { matrixItem -> - if (state.isMe) { - avatarRenderer.render(matrixItem, views.otherUserAvatarImageView) - if (state.sasTransactionState == VerificationTxState.Verified || - state.qrTransactionState == VerificationTxState.Verified || - state.verifiedFromPrivateKeys) { - views.otherUserShield.render(RoomEncryptionTrustLevel.Trusted) - } else { - views.otherUserShield.render(RoomEncryptionTrustLevel.Warning) - } - views.otherUserNameText.text = getString( - if (state.selfVerificationMode) R.string.crosssigning_verify_this_session else R.string.crosssigning_verify_session - ) + avatarRenderer.render(state.otherUserMxItem, views.otherUserAvatarImageView) + if (state.isMe) { + if (state.sasTransactionState == VerificationTxState.Verified || + state.qrTransactionState == VerificationTxState.Verified || + state.verifiedFromPrivateKeys) { + views.otherUserShield.render(RoomEncryptionTrustLevel.Trusted) } else { - avatarRenderer.render(matrixItem, views.otherUserAvatarImageView) - - if (state.sasTransactionState == VerificationTxState.Verified || state.qrTransactionState == VerificationTxState.Verified) { - views.otherUserNameText.text = getString(R.string.verification_verified_user, matrixItem.getBestName()) - views.otherUserShield.render(RoomEncryptionTrustLevel.Trusted) - } else { - views.otherUserNameText.text = getString(R.string.verification_verify_user, matrixItem.getBestName()) - views.otherUserShield.render(null) - } + views.otherUserShield.render(RoomEncryptionTrustLevel.Warning) + } + views.otherUserNameText.text = getString( + if (state.selfVerificationMode) R.string.crosssigning_verify_this_session else R.string.crosssigning_verify_session + ) + } else { + if (state.sasTransactionState == VerificationTxState.Verified || state.qrTransactionState == VerificationTxState.Verified) { + views.otherUserNameText.text = getString(R.string.verification_verified_user, state.otherUserMxItem.getBestName()) + views.otherUserShield.render(RoomEncryptionTrustLevel.Trusted) + } else { + views.otherUserNameText.text = getString(R.string.verification_verify_user, state.otherUserMxItem.getBestName()) + views.otherUserShield.render(null) } } @@ -235,7 +231,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment = Uninitialized, val pendingLocalId: String? = null, val sasTransactionState: VerificationTxState? = null, @@ -92,7 +93,8 @@ data class VerificationBottomSheetViewState( otherUserId = args.otherUserId, verificationId = args.verificationId, roomId = args.roomId, - selfVerificationMode = args.selfVerificationMode + selfVerificationMode = args.selfVerificationMode, + otherUserMxItem = MatrixItem.UserItem(args.otherUserId), ) } @@ -126,7 +128,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } } - val userItem = session.getUser(initialState.otherUserId) + fetchOtherUserProfile(initialState.otherUserId) var autoReady = false val pr = if (initialState.selfVerificationMode) { @@ -160,7 +162,6 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( setState { copy( - otherUserMxItem = userItem?.toMatrixItem(), sasTransactionState = sasTx?.state, qrTransactionState = qrTx?.state, transactionId = pr?.transactionId ?: initialState.verificationId, @@ -183,6 +184,28 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } } + private fun fetchOtherUserProfile(otherUserId: String) { + session.getUser(otherUserId)?.toMatrixItem()?.let { + setState { + copy( + otherUserMxItem = it + ) + } + } + // Always fetch the latest User data + viewModelScope.launch { + tryOrNull { session.userService().resolveUser(otherUserId) } + ?.toMatrixItem() + ?.let { + setState { + copy( + otherUserMxItem = it + ) + } + } + } + } + override fun onCleared() { session.cryptoService().verificationService().removeListener(this) super.onCleared() @@ -216,12 +239,12 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( private fun cancelAllPendingVerifications(state: VerificationBottomSheetViewState) { session.cryptoService() - .verificationService().getExistingVerificationRequest(state.otherUserMxItem?.id ?: "", state.transactionId)?.let { + .verificationService().getExistingVerificationRequest(state.otherUserId, state.transactionId)?.let { session.cryptoService().verificationService().cancelVerificationRequest(it) } session.cryptoService() .verificationService() - .getExistingTransaction(state.otherUserMxItem?.id ?: "", state.transactionId ?: "") + .getExistingTransaction(state.otherUserId, state.transactionId ?: "") ?.cancel(CancelCode.User) } @@ -249,7 +272,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } override fun handle(action: VerificationAction) = withState { state -> - val otherUserId = state.otherUserMxItem?.id ?: return@withState + val otherUserId = state.otherUserId val roomId = state.roomId ?: session.roomService().getExistingDirectRoomWithUser(otherUserId) @@ -514,7 +537,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( override fun transactionUpdated(tx: VerificationTransaction) = withState { state -> if (state.selfVerificationMode && state.transactionId == null) { // is this an incoming with that user - if (tx.isIncoming && tx.otherUserId == state.otherUserMxItem?.id) { + if (tx.isIncoming && tx.otherUserId == state.otherUserId) { // Also auto accept incoming if needed! if (tx is IncomingSasVerificationTransaction) { if (tx.uxState == IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { @@ -564,7 +587,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( if (state.selfVerificationMode && state.pendingRequest.invoke() == null && state.transactionId == null) { // is this an incoming with that user - if (pr.isIncoming && pr.otherUserId == state.otherUserMxItem?.id) { + if (pr.isIncoming && pr.otherUserId == state.otherUserId) { if (!pr.isReady) { // auto ready in this case, as we are waiting // TODO, can I be here in DM mode? in this case should test if roomID is null? diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelController.kt index 1adafe2760..600d5e1be1 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelController.kt @@ -26,6 +26,7 @@ import im.vector.app.core.utils.colorizeMatchingText import im.vector.app.features.crypto.verification.VerificationBottomSheetViewState import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationActionItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem +import im.vector.app.features.displayname.getBestName import im.vector.lib.core.utils.epoxy.charsequence.EpoxyCharSequence import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import javax.inject.Inject @@ -60,8 +61,8 @@ class VerificationCancelController @Inject constructor( } } } else { - val otherUserID = state.otherUserMxItem?.id ?: "" - val otherDisplayName = state.otherUserMxItem?.displayName ?: "" + val otherUserID = state.otherUserId + val otherDisplayName = state.otherUserMxItem.getBestName() bottomSheetVerificationNoticeItem { id("notice") notice( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt index 45f7908446..9f908d83f6 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt @@ -78,7 +78,7 @@ class VerificationChooseMethodFragment : override fun doVerifyBySas() = withState(sharedViewModel) { state -> sharedViewModel.handle( VerificationAction.StartSASVerification( - state.otherUserMxItem?.id ?: "", + state.otherUserId, state.pendingRequest.invoke()?.transactionId ?: "" ) ) @@ -130,7 +130,7 @@ class VerificationChooseMethodFragment : private fun onRemoteQrCodeScanned(remoteQrCode: String) = withState(sharedViewModel) { state -> sharedViewModel.handle( VerificationAction.RemoteQrCodeScanned( - state.otherUserMxItem?.id ?: "", + state.otherUserId, state.pendingRequest.invoke()?.transactionId ?: "", remoteQrCode ) diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt index 98b163f4e3..bf514249d8 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt @@ -136,7 +136,7 @@ class VerificationEmojiCodeController @Inject constructor( if (state.isWaitingFromOther) { bottomSheetVerificationWaitingItem { id("waiting") - title(host.stringProvider.getString(R.string.verification_request_waiting_for, state.otherUser?.getBestName() ?: "")) + title(host.stringProvider.getString(R.string.verification_request_waiting_for, state.otherUser.getBestName())) } } else { bottomSheetVerificationActionItem { diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt index 1e1a8d0710..58b5c01923 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt @@ -68,13 +68,13 @@ class VerificationEmojiCodeFragment : } override fun onMatchButtonTapped() = withState(viewModel) { state -> - val otherUserId = state.otherUser?.id ?: return@withState + val otherUserId = state.otherUser.id val txId = state.transactionId ?: return@withState sharedViewModel.handle(VerificationAction.SASMatchAction(otherUserId, txId)) } override fun onDoNotMatchButtonTapped() = withState(viewModel) { state -> - val otherUserId = state.otherUser?.id ?: return@withState + val otherUserId = state.otherUser.id val txId = state.transactionId ?: return@withState sharedViewModel.handle(VerificationAction.SASDoNotMatchAction(otherUserId, txId)) } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt index db9a8fed4a..6761d98a55 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt @@ -40,13 +40,13 @@ import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTra import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.session.getUser +import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem data class VerificationEmojiCodeViewState( val transactionId: String?, - val otherUser: MatrixItem? = null, + val otherUser: MatrixItem, val supportsEmoji: Boolean = true, val emojiDescription: Async> = Uninitialized, val decimalDescription: Async = Uninitialized, @@ -59,15 +59,13 @@ class VerificationEmojiCodeViewModel @AssistedInject constructor( ) : VectorViewModel(initialState), VerificationService.Listener { init { - withState { state -> - refreshStateFromTx( - session.cryptoService().verificationService() - .getExistingTransaction( - state.otherUser?.id ?: "", state.transactionId - ?: "" - ) as? SasVerificationTransaction - ) - } + refreshStateFromTx( + session.cryptoService().verificationService() + .getExistingTransaction( + otherUserId = initialState.otherUser.id, + tid = initialState.transactionId ?: "" + ) as? SasVerificationTransaction + ) session.cryptoService().verificationService().addListener(this) } @@ -165,10 +163,10 @@ class VerificationEmojiCodeViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { - override fun initialState(viewModelContext: ViewModelContext): VerificationEmojiCodeViewState? { + override fun initialState(viewModelContext: ViewModelContext): VerificationEmojiCodeViewState { val args = viewModelContext.args() val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() - val matrixItem = session.getUser(args.otherUserId)?.toMatrixItem() + val matrixItem = session.getUserOrDefault(args.otherUserId).toMatrixItem() return VerificationEmojiCodeViewState( transactionId = args.verificationId, diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt index 71d64b99bc..639ebac29e 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt @@ -54,7 +54,7 @@ class VerificationQrScannedByOtherController @Inject constructor( if (state.isMe) { notice(host.stringProvider.getString(R.string.qr_code_scanned_self_verif_notice).toEpoxyCharSequence()) } else { - val name = state.otherUserMxItem?.getBestName() ?: "" + val name = state.otherUserMxItem.getBestName() notice(host.stringProvider.getString(R.string.qr_code_scanned_by_other_notice, name).toEpoxyCharSequence()) } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt index e050c5bfb0..185ee48351 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt @@ -52,7 +52,6 @@ class VerificationRequestController @Inject constructor( override fun buildModels() { val state = viewState ?: return - val matrixItem = viewState?.otherUserMxItem ?: return val host = this if (state.selfVerificationMode) { @@ -107,11 +106,9 @@ class VerificationRequestController @Inject constructor( if (state.isMe) { stringProvider.getString(R.string.verify_new_session_notice) } else { - matrixItem.let { - stringProvider.getString(R.string.verification_request_notice, it.id) - .toSpannable() - .colorizeMatchingText(it.id, colorProvider.getColorFromAttribute(R.attr.vctr_notice_text_color)) - } + stringProvider.getString(R.string.verification_request_notice, state.otherUserId) + .toSpannable() + .colorizeMatchingText(state.otherUserId, colorProvider.getColorFromAttribute(R.attr.vctr_notice_text_color)) } bottomSheetVerificationNoticeItem { @@ -138,7 +135,7 @@ class VerificationRequestController @Inject constructor( is Loading -> { bottomSheetVerificationWaitingItem { id("waiting") - title(host.stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName())) + title(host.stringProvider.getString(R.string.verification_request_waiting_for, state.otherUserMxItem.getBestName())) } } is Success -> { @@ -151,7 +148,7 @@ class VerificationRequestController @Inject constructor( } else { bottomSheetVerificationWaitingItem { id("waiting") - title(host.stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName())) + title(host.stringProvider.getString(R.string.verification_request_waiting_for, state.otherUserMxItem.getBestName())) } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt index 6887451a76..a466759eae 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt @@ -64,9 +64,7 @@ class VerificationRequestFragment : } override fun onClickOnVerificationStart(): Unit = withState(viewModel) { state -> - state.otherUserMxItem?.id?.let { otherUserId -> - viewModel.handle(VerificationAction.RequestVerificationByDM(otherUserId, state.roomId)) - } + viewModel.handle(VerificationAction.RequestVerificationByDM(state.otherUserId, state.roomId)) } override fun onClickRecoverFromPassphrase() { diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 46b7efbb97..dd27b5550c 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -514,7 +514,7 @@ class HomeActivity : ) } - private fun promptSecurityEvent(userItem: MatrixItem.UserItem?, titleRes: Int, descRes: Int, action: ((VectorBaseActivity<*>) -> Unit)) { + private fun promptSecurityEvent(userItem: MatrixItem.UserItem, titleRes: Int, descRes: Int, action: ((VectorBaseActivity<*>) -> Unit)) { popupAlertManager.postVectorAlert( VerificationVectorAlert( uid = "upgradeSecurity", diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt index e0b9e8ceb5..4147cf7186 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt @@ -20,13 +20,13 @@ import im.vector.app.core.platform.VectorViewEvents import org.matrix.android.sdk.api.util.MatrixItem sealed interface HomeActivityViewEvents : VectorViewEvents { - data class AskPasswordToInitCrossSigning(val userItem: MatrixItem.UserItem?) : HomeActivityViewEvents + data class AskPasswordToInitCrossSigning(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents data class CurrentSessionNotVerified( - val userItem: MatrixItem.UserItem?, + val userItem: MatrixItem.UserItem, val waitForIncomingRequest: Boolean = true, ) : HomeActivityViewEvents data class CurrentSessionCannotBeVerified( - val userItem: MatrixItem.UserItem?, + val userItem: MatrixItem.UserItem, ) : HomeActivityViewEvents data class OnCrossSignedInvalidated(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents object PromptToEnableSessionPush : HomeActivityViewEvents diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 6aba9eefcf..cbe531ea71 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -60,7 +60,7 @@ import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.api.session.getUser +import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.session.pushrules.RuleIds import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams @@ -312,10 +312,10 @@ class HomeActivityViewModel @AssistedInject constructor( } else { // cross signing keys have been reset // Trigger a popup to re-verify - // Note: user can be null in case of logout - session.getUser(session.myUserId) - ?.toMatrixItem() - ?.let { user -> + // Note: user can be unknown in case of logout + session.getUserOrDefault(session.myUserId) + .toMatrixItem() + .let { user -> _viewEvents.post(HomeActivityViewEvents.OnCrossSignedInvalidated(user)) } } @@ -396,7 +396,7 @@ class HomeActivityViewModel @AssistedInject constructor( // New session _viewEvents.post( HomeActivityViewEvents.CurrentSessionNotVerified( - session.getUser(session.myUserId)?.toMatrixItem(), + session.getUserOrDefault(session.myUserId).toMatrixItem(), // Always send request instead of waiting for an incoming as per recent EW changes false ) @@ -404,7 +404,7 @@ class HomeActivityViewModel @AssistedInject constructor( } else { _viewEvents.post( HomeActivityViewEvents.CurrentSessionCannotBeVerified( - session.getUser(session.myUserId)?.toMatrixItem(), + session.getUserOrDefault(session.myUserId).toMatrixItem(), ) ) } @@ -424,7 +424,7 @@ class HomeActivityViewModel @AssistedInject constructor( // Check this is not an SSO account if (session.homeServerCapabilitiesService().getHomeServerCapabilities().canChangePassword) { // Ask password to the user: Upgrade security - _viewEvents.post(HomeActivityViewEvents.AskPasswordToInitCrossSigning(session.getUser(session.myUserId)?.toMatrixItem())) + _viewEvents.post(HomeActivityViewEvents.AskPasswordToInitCrossSigning(session.getUserOrDefault(session.myUserId).toMatrixItem())) } // Else (SSO) just ignore for the moment } else { diff --git a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt index 34bdc5fcd3..855c47f4bb 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt @@ -21,10 +21,13 @@ import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized +import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import dagger.hilt.EntryPoints import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.SingletonEntryPoint import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -40,14 +43,14 @@ import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo -import org.matrix.android.sdk.api.session.getUser +import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow import timber.log.Timber data class UnknownDevicesState( - val myMatrixItem: MatrixItem.UserItem? = null, + val myMatrixItem: MatrixItem.UserItem, val unknownSessions: Async> = Uninitialized ) : MavericksState @@ -73,7 +76,15 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor( override fun create(initialState: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel } - companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { + override fun initialState(viewModelContext: ViewModelContext): UnknownDevicesState { + val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() + + return UnknownDevicesState( + myMatrixItem = session.getUserOrDefault(session.myUserId).toMatrixItem() + ) + } + } private val ignoredDeviceList = ArrayList() @@ -118,7 +129,7 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor( .execute { async -> // Timber.v("## Detector trigger passed distinct") copy( - myMatrixItem = session.getUser(session.myUserId)?.toMatrixItem(), + myMatrixItem = session.getUserOrDefault(session.myUserId).toMatrixItem(), unknownSessions = async ) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/HomeRoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/HomeRoomListViewModel.kt index 83ffc482ad..e06815b5fd 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/home/HomeRoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/HomeRoomListViewModel.kt @@ -32,6 +32,7 @@ import im.vector.app.core.platform.StateView import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.DrawableProvider import im.vector.app.core.resources.StringProvider +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.room.list.home.header.HomeRoomFilter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow @@ -53,6 +54,7 @@ import org.matrix.android.sdk.api.query.RoomTagQueryFilter import org.matrix.android.sdk.api.query.toActiveSpaceOrNoFilter import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.getRoom +import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult @@ -62,6 +64,7 @@ import org.matrix.android.sdk.api.session.room.model.tag.RoomTag import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.room.state.isPublic import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow class HomeRoomListViewModel @AssistedInject constructor( @@ -298,7 +301,7 @@ class HomeRoomListViewModel @AssistedInject constructor( isBigImage = true ) } else { - val userName = session.userService().getUser(session.myUserId)?.displayName ?: "" + val userName = session.getUserOrDefault(session.myUserId).toMatrixItem().getBestName() StateView.State.Empty( title = stringProvider.getString(R.string.home_empty_no_rooms_title, userName), message = stringProvider.getString(R.string.home_empty_no_rooms_message), diff --git a/vector/src/main/java/im/vector/app/features/popup/VerificationVectorAlert.kt b/vector/src/main/java/im/vector/app/features/popup/VerificationVectorAlert.kt index 6848bbb1f3..c2ecbe04b3 100644 --- a/vector/src/main/java/im/vector/app/features/popup/VerificationVectorAlert.kt +++ b/vector/src/main/java/im/vector/app/features/popup/VerificationVectorAlert.kt @@ -38,13 +38,13 @@ class VerificationVectorAlert( override val layoutRes = R.layout.alerter_verification_layout class ViewBinder( - private val matrixItem: MatrixItem?, + private val matrixItem: MatrixItem, private val avatarRenderer: AvatarRenderer ) : VectorAlert.ViewBinder { override fun bind(view: View) { val views = AlerterVerificationLayoutBinding.bind(view) - matrixItem?.let { avatarRenderer.render(it, views.ivUserAvatar, GlideApp.with(view.context.applicationContext)) } + avatarRenderer.render(matrixItem, views.ivUserAvatar, GlideApp.with(view.context.applicationContext)) } } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt index 9cd456b5d7..9786d80ae7 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt @@ -47,6 +47,7 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.getRoom +import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes import org.matrix.android.sdk.api.session.room.model.Membership @@ -272,7 +273,7 @@ class SpaceListViewModel @AssistedInject constructor( ?.safeOrder() } val inviterIds = spaces.mapNotNull { it.inviterId } - val inviters = inviterIds.mapNotNull { session.userService().getUser(it) } + val inviters = inviterIds.map { session.getUserOrDefault(it) } copy( asyncSpaces = asyncSpaces, spaces = spaces,