diff --git a/CHANGES.md b/CHANGES.md index e28b70ac03..2111d369e9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,11 +7,13 @@ Features ✨: Improvements 🙌: - Give user the possibility to prevent accidental call (#1869) - Display device information (name, id and key) in Cryptography setting screen (#1784) + - Ensure users do not accidentally ignore other users (#1890) Bugfix 🐛: - Fix invisible toolbar (Status.im theme) (#1746) - Fix relative date time formatting (#822) - Fix crash reported by RageShake + - Fix refreshing of sessions list when another session is logged out Translations 🗣: - Add PlayStore description resources in the Triple-T format, to let Weblate handle them diff --git a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt index e269f1a4e0..45efd125ee 100644 --- a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt +++ b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt @@ -71,7 +71,7 @@ class RxSession(private val session: Session) { } } - fun liveMyDeviceInfo(): Observable> { + fun liveMyDevicesInfo(): Observable> { return session.cryptoService().getLiveMyDevicesInfo().asObservable() .startWithCallable { session.cryptoService().getMyDevicesInfo() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UploadSignatureQueryBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UploadSignatureQueryBuilder.kt index d2300be114..dbb2822cdd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UploadSignatureQueryBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UploadSignatureQueryBuilder.kt @@ -39,11 +39,8 @@ internal data class UploadSignatureQueryBuilder( fun build(): Map> { val map = HashMap>() - val usersList = ( - deviceInfoList.map { it.userId } - + signingKeyInfoList - .map { it.userId } - ).distinct() + val usersList = (deviceInfoList.map { it.userId } + signingKeyInfoList.map { it.userId }) + .distinct() usersList.forEach { userID -> val userMap = HashMap() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt index 2c3f75fe06..b47a25187b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateIgnoredUserIdsTask.kt @@ -18,14 +18,14 @@ package org.matrix.android.sdk.internal.session.user.accountdata import com.zhuinden.monarchy.Monarchy +import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.internal.database.model.IgnoredUserEntity import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.sync.model.accountdata.IgnoredUsersContent -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface UpdateIgnoredUserIdsTask : Task { @@ -51,7 +51,7 @@ internal class DefaultUpdateIgnoredUserIdsTask @Inject constructor( { it.userId } ).toMutableSet() - val original = ignoredUserIds.toList() + val original = ignoredUserIds.toSet() ignoredUserIds.removeAll { it in params.userIdsToUnIgnore } ignoredUserIds.addAll(params.userIdsToIgnore) diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapAccountPasswordFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapAccountPasswordFragment.kt index 744a2de761..ccf2d67701 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapAccountPasswordFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapAccountPasswordFragment.kt @@ -66,7 +66,7 @@ class BootstrapAccountPasswordFragment @Inject constructor( .disposeOnDestroyView() bootstrapAccountPasswordEditText.textChanges() - .distinct() + .distinctUntilChanged() .subscribe { if (!it.isNullOrBlank()) { bootstrapAccountPasswordTil.error = null diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index 77446cdf60..ad0209845f 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -61,7 +61,7 @@ class ShortcutsHandler @Inject constructor( return homeRoomListStore .observe() - .distinct() + .distinctUntilChanged() .observeOn(Schedulers.computation()) .subscribe { rooms -> val shortcuts = rooms 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 18d396c83d..eeb1639045 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 @@ -100,7 +100,7 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted Observable.combineLatest, List, Optional, List>( session.rx().liveUserCryptoDevices(session.myUserId), - session.rx().liveMyDeviceInfo(), + session.rx().liveMyDevicesInfo(), session.rx().liveCrossSigningPrivateKeys(), Function3 { cryptoList, infoList, pInfo -> // Timber.v("## Detector trigger ${cryptoList.map { "${it.deviceId} ${it.trustLevel}" }}") @@ -133,12 +133,13 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted } session.rx().liveUserCryptoDevices(session.myUserId) - .distinct() + .distinctUntilChanged() .throttleLast(5_000, TimeUnit.MILLISECONDS) .subscribe { // If we have a new crypto device change, we might want to trigger refresh of device info session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) - }.disposeOnClear() + } + .disposeOnClear() // trigger a refresh of lastSeen / last Ip session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index 6f7e39af43..424731fdb0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -1491,7 +1491,7 @@ class RoomDetailFragment @Inject constructor( promptReasonToReportContent(action) } is EventSharedAction.IgnoreUser -> { - roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(action.senderId)) + action.senderId?.let { askConfirmationToIgnoreUser(it) } } is EventSharedAction.OnUrlClicked -> { onUrlClicked(action.url, action.title) @@ -1507,12 +1507,21 @@ class RoomDetailFragment @Inject constructor( startActivity(KeysBackupRestoreActivity.intent(it)) } } - else -> { - Toast.makeText(context, "Action $action is not implemented yet", Toast.LENGTH_LONG).show() - } } } + private fun askConfirmationToIgnoreUser(senderId: String) { + AlertDialog.Builder(requireContext()) + .setTitle(R.string.room_participants_action_ignore_title) + .setMessage(R.string.room_participants_action_ignore_prompt_msg) + .setNegativeButton(R.string.cancel, null) + .setPositiveButton(R.string.room_participants_action_ignore) { _, _ -> + roomDetailViewModel.handle(RoomDetailAction.IgnoreUser(senderId)) + } + .show() + .withColoredButton(DialogInterface.BUTTON_POSITIVE) + } + /** * Insert a user displayName in the message editor. * diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt index 9bf5347876..f2f108b3e4 100644 --- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt @@ -37,10 +37,10 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(@Assisted privat init { Observable.combineLatest, Optional, Pair, Optional>>( - session.rx().liveMyDeviceInfo(), + session.rx().liveMyDevicesInfo(), session.rx().liveCrossSigningInfo(session.myUserId), - BiFunction { myDeviceInfo, mxCrossSigningInfo -> - (myDeviceInfo to mxCrossSigningInfo) + BiFunction { myDevicesInfo, mxCrossSigningInfo -> + myDevicesInfo to mxCrossSigningInfo } ) .execute { data -> diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt index cd5b739322..6f5bd909c7 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt @@ -81,7 +81,7 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As copy(deviceInfo = Loading()) } - session.rx().liveMyDeviceInfo() + session.rx().liveMyDevicesInfo() .map { devices -> devices.firstOrNull { it.deviceId == deviceId } ?: DeviceInfo(deviceId = deviceId) } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index 511ece1e55..237c8c218d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -103,7 +103,7 @@ class DevicesViewModel @AssistedInject constructor( Observable.combineLatest, List, List>( session.rx().liveUserCryptoDevices(session.myUserId), - session.rx().liveMyDeviceInfo(), + session.rx().liveMyDevicesInfo(), BiFunction { cryptoList, infoList -> infoList .sortedByDescending { it.lastSeenTs } @@ -113,7 +113,7 @@ class DevicesViewModel @AssistedInject constructor( } } ) - .distinct() + .distinctUntilChanged() .execute { async -> copy( devices = async @@ -137,12 +137,14 @@ class DevicesViewModel @AssistedInject constructor( // } session.rx().liveUserCryptoDevices(session.myUserId) - .distinct() + .map { it.size } + .distinctUntilChanged() .throttleLast(5_000, TimeUnit.MILLISECONDS) .subscribe { // If we have a new crypto device change, we might want to trigger refresh of device info session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) - }.disposeOnClear() + } + .disposeOnClear() // session.rx().liveUserCryptoDevices(session.myUserId) // .execute { diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 6fa7d61945..7f1189390a 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1801,7 +1801,7 @@ "Report this content" "Reason for reporting this content" "REPORT" - "BLOCK USER" + "IGNORE USER" "Content reported" "This content was reported.\n\nIf you don't want to see any more content from this user, you can block him to hide his messages" @@ -1814,7 +1814,7 @@ There is no network connection right now - Block user + Ignore user "All messages (noisy)" "All messages"