From 02e342849fa9af94044a60e9df4e6faf826bc705 Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Sun, 21 Jul 2019 23:23:56 +0100 Subject: [PATCH 01/34] Remove most usages of the java.util package Signed-off-by: Dominic Fischer --- .../android/internal/crypto/CryptoStoreHelper.kt | 4 ++-- .../api/comparators/DatedObjectComparators.kt | 1 - .../android/api/extensions/MatrixSdkExtensions.kt | 2 +- .../api/pushrules/RoomMemberCountCondition.kt | 12 ++++-------- .../android/api/session/pushers/PushersService.kt | 2 +- .../session/room/model/create/CreateRoomParams.kt | 5 ++--- .../matrix/android/api/util/SecretStoringUtils.kt | 2 +- .../matrix/android/internal/crypto/ObjectSigner.kt | 1 - .../crypto/algorithms/olm/MXOlmDecryption.kt | 1 - .../crypto/attachments/MXEncryptedAttachments.kt | 4 +--- .../android/internal/crypto/keysbackup/KeysBackup.kt | 6 ++---- .../internal/crypto/keysbackup/KeysBackupPassword.kt | 2 +- .../crypto/keysbackup/KeysBackupStateManager.kt | 1 - .../android/internal/crypto/model/MXDeviceInfo.kt | 1 - .../matrix/android/internal/crypto/model/MXKey.kt | 1 - .../internal/crypto/model/MXUsersDevicesMap.kt | 1 - .../internal/crypto/tasks/SendToDeviceTask.kt | 4 ++-- .../verification/DefaultSasVerificationService.kt | 2 +- .../android/internal/database/mapper/EventMapper.kt | 1 - .../internal/database/mapper/RoomSummaryMapper.kt | 2 +- .../android/internal/database/model/EventEntity.kt | 1 - .../matrix/android/internal/network/ssl/CertUtil.kt | 1 - .../android/internal/network/ssl/TLSSocketFactory.kt | 1 - .../content/DefaultContentUploadStateTracker.kt | 3 +-- .../internal/session/pushers/DefaultPusherService.kt | 2 +- .../session/room/send/LocalEchoEventFactory.kt | 2 +- .../android/internal/session/sync/RoomTagHandler.kt | 1 - .../matrix/android/internal/util/CancelableWork.kt | 2 +- .../matrix/android/internal/util/CompatUtil.kt | 2 +- .../android/internal/util/JsonCanonicalizer.kt | 2 +- 30 files changed, 25 insertions(+), 47 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreHelper.kt index cea612dd92..c0fc6c4454 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/CryptoStoreHelper.kt @@ -21,7 +21,7 @@ import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStore import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStoreModule import io.realm.RealmConfiguration -import java.util.* +import kotlin.random.Random internal class CryptoStoreHelper { @@ -35,7 +35,7 @@ internal class CryptoStoreHelper { } fun createCredential() = Credentials( - userId = "userId_" + Random().nextInt(), + userId = "userId_" + Random.nextInt(), homeServer = "http://matrix.org", accessToken = "access_token", refreshToken = null, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/comparators/DatedObjectComparators.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/comparators/DatedObjectComparators.kt index aad33ab7b9..c9245e7331 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/comparators/DatedObjectComparators.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/comparators/DatedObjectComparators.kt @@ -17,7 +17,6 @@ package im.vector.matrix.android.api.comparators import im.vector.matrix.android.api.interfaces.DatedObject -import java.util.* object DatedObjectComparators { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/extensions/MatrixSdkExtensions.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/extensions/MatrixSdkExtensions.kt index e2e53904ff..180d80c5c5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/extensions/MatrixSdkExtensions.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/extensions/MatrixSdkExtensions.kt @@ -19,7 +19,7 @@ package im.vector.matrix.android.api.extensions import im.vector.matrix.android.api.comparators.DatedObjectComparators import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo -import java.util.* +import java.util.Collections /* ========================================================================================== * MXDeviceInfo diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/RoomMemberCountCondition.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/RoomMemberCountCondition.kt index b2bed4c230..1c02d63d76 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/RoomMemberCountCondition.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/RoomMemberCountCondition.kt @@ -18,9 +18,8 @@ package im.vector.matrix.android.api.pushrules import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.room.RoomService import timber.log.Timber -import java.util.regex.Pattern -private val regex = Pattern.compile("^(==|<=|>=|<|>)?(\\d*)$") +private val regex = Regex("^(==|<=|>=|<|>)?(\\d*)$") class RoomMemberCountCondition(val `is`: String) : Condition(Kind.room_member_count) { @@ -56,12 +55,9 @@ class RoomMemberCountCondition(val `is`: String) : Condition(Kind.room_member_co */ private fun parseIsField(): Pair? { try { - val match = regex.matcher(`is`) - if (match.find()) { - val prefix = match.group(1) - val count = match.group(2).toInt() - return prefix to count - } + val match = regex.find(`is`) ?: return null + val (prefix, count) = match.destructured + return prefix to count.toInt() } catch (t: Throwable) { Timber.d(t) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/pushers/PushersService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/pushers/PushersService.kt index 1450dbb500..c905490432 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/pushers/PushersService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/pushers/PushersService.kt @@ -17,7 +17,7 @@ package im.vector.matrix.android.api.session.pushers import androidx.lifecycle.LiveData import im.vector.matrix.android.api.MatrixCallback -import java.util.* +import java.util.UUID interface PushersService { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt index 77c4fcf1e2..7fd4d109f6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt @@ -29,7 +29,6 @@ import im.vector.matrix.android.api.session.room.model.PowerLevels import im.vector.matrix.android.api.session.room.model.RoomDirectoryVisibility import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility import im.vector.matrix.android.internal.auth.data.ThreePidMedium -import java.util.* /** * Parameter to create a room, with facilities functions to configure it @@ -133,7 +132,7 @@ class CreateRoomParams { ) if (null == initialStates) { - initialStates = Arrays.asList(algoEvent) + initialStates = mutableListOf(algoEvent) } else { initialStates!!.add(algoEvent) } @@ -166,7 +165,7 @@ class CreateRoomParams { content = contentMap.toContent()) if (null == initialStates) { - initialStates = Arrays.asList(historyVisibilityEvent) + initialStates = mutableListOf(historyVisibilityEvent) } else { initialStates!!.add(historyVisibilityEvent) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt index 6dc0d789cc..7b66f7585b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt @@ -27,7 +27,7 @@ import java.math.BigInteger import java.security.KeyPairGenerator import java.security.KeyStore import java.security.SecureRandom -import java.util.* +import java.util.Calendar import javax.crypto.* import javax.crypto.spec.GCMParameterSpec import javax.crypto.spec.IvParameterSpec diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/ObjectSigner.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/ObjectSigner.kt index 7b8e01994c..ebed85aedf 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/ObjectSigner.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/ObjectSigner.kt @@ -18,7 +18,6 @@ package im.vector.matrix.android.internal.crypto import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.internal.session.SessionScope -import java.util.* import javax.inject.Inject internal class ObjectSigner @Inject constructor(private val credentials: Credentials, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt index 7b5a8cd498..0a0a158c56 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt @@ -32,7 +32,6 @@ import im.vector.matrix.android.internal.crypto.model.event.OlmPayloadContent import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.util.convertFromUTF8 import timber.log.Timber -import java.util.* internal class MXOlmDecryption( // The olm device interface diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt index d8c627097d..86ef488eac 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt @@ -26,7 +26,6 @@ import java.io.ByteArrayOutputStream import java.io.InputStream import java.security.MessageDigest import java.security.SecureRandom -import java.util.* import javax.crypto.Cipher import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec @@ -59,8 +58,7 @@ object MXEncryptedAttachments { // Half of the IV is random, the lower order bits are zeroed // such that the counter never wraps. // See https://github.com/matrix-org/matrix-ios-kit/blob/3dc0d8e46b4deb6669ed44f72ad79be56471354c/MatrixKit/Models/Room/MXEncryptedAttachments.m#L75 - val initVectorBytes = ByteArray(16) - Arrays.fill(initVectorBytes, 0.toByte()) + val initVectorBytes = ByteArray(16) { 0.toByte() } val ivRandomPart = ByteArray(8) secureRandom.nextBytes(ivRandomPart) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt index 88d9aec97f..5a4783c492 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt @@ -67,9 +67,9 @@ import org.matrix.olm.OlmPkEncryption import org.matrix.olm.OlmPkMessage import timber.log.Timber import java.security.InvalidParameterException -import java.util.* import javax.inject.Inject import kotlin.collections.HashMap +import kotlin.random.Random /** * A KeysBackup class instance manage incremental backup of e2e keys (megolm keys) @@ -115,8 +115,6 @@ internal class KeysBackup @Inject constructor( // The backup key being used. private var backupOlmPkEncryption: OlmPkEncryption? = null - private val random = Random() - private var backupAllGroupSessionsCallback: MatrixCallback? = null private var keysBackupStateListener: KeysBackupStateListener? = null @@ -842,7 +840,7 @@ internal class KeysBackup @Inject constructor( // Wait between 0 and 10 seconds, to avoid backup requests from // different clients hitting the server all at the same time when a // new key is sent - val delayInMs = random.nextInt(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS).toLong() + val delayInMs = Random.nextInt(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS).toLong() uiHandler.postDelayed({ backupKeys() }, delayInMs) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPassword.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPassword.kt index 51346c8993..12c618d032 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPassword.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupPassword.kt @@ -22,7 +22,7 @@ package im.vector.matrix.android.internal.crypto.keysbackup import androidx.annotation.WorkerThread import im.vector.matrix.android.api.listeners.ProgressListener import timber.log.Timber -import java.util.* +import java.util.UUID import javax.crypto.Mac import javax.crypto.spec.SecretKeySpec import kotlin.experimental.xor diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupStateManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupStateManager.kt index ff812e75c0..cd74d04a67 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupStateManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupStateManager.kt @@ -20,7 +20,6 @@ import android.os.Handler import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener import timber.log.Timber -import java.util.* internal class KeysBackupStateManager(private val uiHandler: Handler) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXDeviceInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXDeviceInfo.kt index a458cdfe03..36d6785e41 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXDeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXDeviceInfo.kt @@ -23,7 +23,6 @@ import com.squareup.moshi.JsonClass import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.internal.crypto.model.rest.DeviceKeys import java.io.Serializable -import java.util.* @JsonClass(generateAdapter = true) data class MXDeviceInfo( diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXKey.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXKey.kt index db0f26528b..7fd48f8bb8 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXKey.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXKey.kt @@ -18,7 +18,6 @@ package im.vector.matrix.android.internal.crypto.model import im.vector.matrix.android.api.util.JsonDict import timber.log.Timber -import java.util.* data class MXKey( /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXUsersDevicesMap.kt index a4b6e247a6..d3c76a1430 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXUsersDevicesMap.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXUsersDevicesMap.kt @@ -16,7 +16,6 @@ package im.vector.matrix.android.internal.crypto.model -import java.util.* class MXUsersDevicesMap { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendToDeviceTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendToDeviceTask.kt index 27559f7422..36fa3701fe 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendToDeviceTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/SendToDeviceTask.kt @@ -23,8 +23,8 @@ import im.vector.matrix.android.internal.crypto.model.rest.SendToDeviceBody import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.SessionScope import im.vector.matrix.android.internal.task.Task -import java.util.* import javax.inject.Inject +import kotlin.random.Random internal interface SendToDeviceTask : Task { data class Params( @@ -47,7 +47,7 @@ internal class DefaultSendToDeviceTask @Inject constructor(private val cryptoApi return executeRequest { apiCall = cryptoApi.sendToDevice( params.eventType, - params.transactionId ?: Random().nextInt(Integer.MAX_VALUE).toString(), + params.transactionId ?: Random.nextInt(Integer.MAX_VALUE).toString(), sendToDeviceBody ) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt index 54a4e14dc8..ac30f0253b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt @@ -43,7 +43,7 @@ import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import timber.log.Timber -import java.util.* +import java.util.UUID import javax.inject.Inject import kotlin.collections.HashMap diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt index 30346f789e..274a14ce0f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt @@ -26,7 +26,6 @@ import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResu import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.di.MoshiProvider import timber.log.Timber -import java.util.* internal object EventMapper { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt index 5f946e4291..1411d70c31 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/RoomSummaryMapper.kt @@ -22,7 +22,7 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult import im.vector.matrix.android.internal.database.model.RoomSummaryEntity -import java.util.* +import java.util.UUID import javax.inject.Inject internal class RoomSummaryMapper @Inject constructor( diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/EventEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/EventEntity.kt index ab10297fe6..60344f60a4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/EventEntity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/EventEntity.kt @@ -25,7 +25,6 @@ import io.realm.RealmResults import io.realm.annotations.Index import io.realm.annotations.LinkingObjects import io.realm.annotations.PrimaryKey -import java.util.* internal open class EventEntity(@Index var eventId: String = "", @Index var roomId: String = "", diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/CertUtil.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/CertUtil.kt index 64e941a6ed..976cbde17d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/CertUtil.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/CertUtil.kt @@ -24,7 +24,6 @@ import java.security.KeyStore import java.security.MessageDigest import java.security.cert.CertificateException import java.security.cert.X509Certificate -import java.util.* import javax.net.ssl.* import kotlin.experimental.and diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt index e249ed74c8..761a18c87a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt @@ -25,7 +25,6 @@ import java.net.UnknownHostException import java.security.KeyManagementException import java.security.NoSuchAlgorithmException import java.security.SecureRandom -import java.util.* import javax.net.ssl.SSLContext import javax.net.ssl.SSLSocket import javax.net.ssl.SSLSocketFactory diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUploadStateTracker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUploadStateTracker.kt index 4bb58fe74f..e44c8eb5ee 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUploadStateTracker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/DefaultContentUploadStateTracker.kt @@ -30,9 +30,8 @@ internal class DefaultContentUploadStateTracker @Inject constructor() : ContentU private val listeners = mutableMapOf>() override fun track(key: String, updateListener: ContentUploadStateTracker.UpdateListener) { - val listeners = listeners[key] ?: ArrayList() + val listeners = listeners.getOrPut(key) { ArrayList() } listeners.add(updateListener) - this.listeners[key] = listeners val currentState = states[key] ?: ContentUploadStateTracker.State.Idle mainHandler.post { updateListener.onUpdate(currentState) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt index 5d9af0d34a..d4449fe168 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt @@ -33,7 +33,7 @@ import im.vector.matrix.android.internal.task.toConfigurableTask import im.vector.matrix.android.internal.worker.WorkManagerUtil import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder import im.vector.matrix.android.internal.worker.WorkerParamsFactory -import java.util.* +import java.util.UUID import java.util.concurrent.TimeUnit import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt index c6b6864704..12d747fe33 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt @@ -39,7 +39,7 @@ import im.vector.matrix.android.internal.util.StringProvider import im.vector.matrix.android.internal.util.tryTransactionAsync import org.commonmark.parser.Parser import org.commonmark.renderer.html.HtmlRenderer -import java.util.* +import java.util.UUID import javax.inject.Inject /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomTagHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomTagHandler.kt index 49038eed3d..85f4ce7849 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomTagHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomTagHandler.kt @@ -22,7 +22,6 @@ import im.vector.matrix.android.internal.database.model.RoomTagEntity import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.session.SessionScope import io.realm.Realm -import java.util.* import javax.inject.Inject internal class RoomTagHandler @Inject constructor() { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CancelableWork.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CancelableWork.kt index ebd20ec6e1..ddaeb1fd9d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CancelableWork.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CancelableWork.kt @@ -19,7 +19,7 @@ package im.vector.matrix.android.internal.util import android.content.Context import androidx.work.WorkManager import im.vector.matrix.android.api.util.Cancelable -import java.util.* +import java.util.UUID internal class CancelableWork(private val context: Context, private val workId: UUID) : Cancelable { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CompatUtil.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CompatUtil.kt index e713c4357e..d0a5f2f82f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CompatUtil.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CompatUtil.kt @@ -34,7 +34,7 @@ import java.security.* import java.security.cert.CertificateException import java.security.spec.AlgorithmParameterSpec import java.security.spec.RSAKeyGenParameterSpec -import java.util.* +import java.util.Calendar import java.util.zip.GZIPOutputStream import javax.crypto.* import javax.crypto.spec.GCMParameterSpec diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/JsonCanonicalizer.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/JsonCanonicalizer.kt index 36c1ba1553..d8f059f43b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/JsonCanonicalizer.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/JsonCanonicalizer.kt @@ -22,7 +22,7 @@ import org.json.JSONArray import org.json.JSONException import org.json.JSONObject import timber.log.Timber -import java.util.* +import java.util.TreeSet /** * Build canonical Json From 215324a03ead47aa7d6632346a7aa5151ddd85dc Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Sun, 21 Jul 2019 23:41:03 +0100 Subject: [PATCH 02/34] Some kotlinification Signed-off-by: Dominic Fischer --- .../android/api/util/SecretStoringUtils.kt | 34 ++------------ .../crypto/algorithms/olm/MXOlmDecryption.kt | 33 +++----------- .../attachments/MXEncryptedAttachments.kt | 44 +++++++------------ .../android/internal/crypto/model/MXKey.kt | 6 +-- .../crypto/model/MXUsersDevicesMap.kt | 17 +++---- .../DefaultSasVerificationService.kt | 17 ++++--- .../internal/network/ssl/TLSSocketFactory.kt | 19 +++----- .../room/send/LocalEchoEventFactory.kt | 23 ++++++---- .../internal/session/sync/RoomTagHandler.kt | 12 +---- .../internal/util/JsonCanonicalizer.kt | 38 ++++++---------- 10 files changed, 77 insertions(+), 166 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt index 6dc0d789cc..4e36506e73 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/SecretStoringUtils.kt @@ -479,12 +479,7 @@ object SecretStoringUtils { val output = Cipher.getInstance(RSA_MODE) output.init(Cipher.DECRYPT_MODE, privateKeyEntry.privateKey) - val bos = ByteArrayOutputStream() - CipherInputStream(encrypted, output).use { - it.copyTo(bos) - } - - return bos.toByteArray() + return CipherInputStream(encrypted, output).use { it.readBytes() } } private fun formatMExtract(bis: InputStream): Pair { @@ -495,14 +490,7 @@ object SecretStoringUtils { val iv = ByteArray(ivSize) bis.read(iv, 0, ivSize) - - val bos = ByteArrayOutputStream() - var next = bis.read() - while (next != -1) { - bos.write(next) - next = bis.read() - } - val encrypted = bos.toByteArray() + val encrypted = bis.readBytes() return Pair(iv, encrypted) } @@ -530,14 +518,7 @@ object SecretStoringUtils { val iv = ByteArray(ivSize) bis.read(iv) - val bos = ByteArrayOutputStream() - - var next = bis.read() - while (next != -1) { - bos.write(next) - next = bis.read() - } - val encrypted = bos.toByteArray() + val encrypted = bis.readBytes() return Triple(encryptedKey, iv, encrypted) } @@ -579,14 +560,7 @@ object SecretStoringUtils { val iv = ByteArray(ivSize) bis.read(iv) - val bos = ByteArrayOutputStream() - - var next = bis.read() - while (next != -1) { - bos.write(next) - next = bis.read() - } - val encrypted = bos.toByteArray() + val encrypted = bis.readBytes() return Triple(salt, iv, encrypted) } } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt index 7b5a8cd498..05f0b71e32 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt @@ -165,33 +165,14 @@ internal class MXOlmDecryption( * @return payload, if decrypted successfully. */ private fun decryptMessage(message: JsonDict, theirDeviceIdentityKey: String): String? { - val sessionIdsSet = olmDevice.getSessionIds(theirDeviceIdentityKey) + val sessionIds = olmDevice.getSessionIds(theirDeviceIdentityKey) ?: emptySet() - val sessionIds: List - - if (null == sessionIdsSet) { - sessionIds = ArrayList() - } else { - sessionIds = ArrayList(sessionIdsSet) - } - - val messageBody = message["body"] as? String - var messageType: Int? = null - - val typeAsVoid = message["type"] - - if (null != typeAsVoid) { - if (typeAsVoid is Double) { - messageType = typeAsVoid.toInt() - } else if (typeAsVoid is Int) { - messageType = typeAsVoid - } else if (typeAsVoid is Long) { - messageType = typeAsVoid.toInt() - } - } - - if (null == messageBody || null == messageType) { - return null + val messageBody = message["body"] as? String ?: return null + val messageType = when (val typeAsVoid = message["type"]) { + is Double -> typeAsVoid.toInt() + is Int -> typeAsVoid + is Long -> typeAsVoid.toInt() + else -> return null } // Try each session in turn diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt index d8c627097d..e9193fa436 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt @@ -115,7 +115,7 @@ object MXEncryptedAttachments { encryptedByteArray = outStream.toByteArray() ) - Timber.v("Encrypt in " + (System.currentTimeMillis() - t0) + " ms") + Timber.v("Encrypt in ${System.currentTimeMillis() - t0} ms") return Try.just(result) } catch (oom: OutOfMemoryError) { Timber.e(oom, "## encryptAttachment failed") @@ -206,13 +206,13 @@ object MXEncryptedAttachments { val decryptedStream = ByteArrayInputStream(outStream.toByteArray()) outStream.close() - Timber.v("Decrypt in " + (System.currentTimeMillis() - t0) + " ms") + Timber.v("Decrypt in ${System.currentTimeMillis() - t0} ms") return decryptedStream } catch (oom: OutOfMemoryError) { - Timber.e(oom, "## decryptAttachment() : failed " + oom.message) + Timber.e(oom, "## decryptAttachment() : failed ${oom.message}") } catch (e: Exception) { - Timber.e(e, "## decryptAttachment() : failed " + e.message) + Timber.e(e, "## decryptAttachment() : failed ${e.message}") } try { @@ -228,34 +228,20 @@ object MXEncryptedAttachments { * Base64 URL conversion methods */ - private fun base64UrlToBase64(base64Url: String?): String? { - var result = base64Url - if (null != result) { - result = result.replace("-".toRegex(), "+") - result = result.replace("_".toRegex(), "/") - } - - return result + private fun base64UrlToBase64(base64Url: String): String { + return base64Url.replace('-', '+') + .replace('_', '/') } - private fun base64ToBase64Url(base64: String?): String? { - var result = base64 - if (null != result) { - result = result.replace("\n".toRegex(), "") - result = result.replace("\\+".toRegex(), "-") - result = result.replace("/".toRegex(), "_") - result = result.replace("=".toRegex(), "") - } - return result + private fun base64ToBase64Url(base64: String): String { + return base64.replace("\n".toRegex(), "") + .replace("\\+".toRegex(), "-") + .replace('/', '_') + .replace("=", "") } - private fun base64ToUnpaddedBase64(base64: String?): String? { - var result = base64 - if (null != result) { - result = result.replace("\n".toRegex(), "") - result = result.replace("=".toRegex(), "") - } - - return result + private fun base64ToUnpaddedBase64(base64: String): String { + return base64.replace("\n".toRegex(), "") + .replace("=", "") } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXKey.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXKey.kt index 69019fbbaa..1469feea7d 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXKey.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXKey.kt @@ -46,11 +46,7 @@ data class MXKey( * @return the signed data map */ fun signalableJSONDictionary(): Map { - val map = HashMap() - - map["key"] = value - - return map + return mapOf("key" to value) } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXUsersDevicesMap.kt index a4b6e247a6..13078d64af 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXUsersDevicesMap.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXUsersDevicesMap.kt @@ -27,7 +27,7 @@ class MXUsersDevicesMap { * @return the user Ids */ val userIds: List - get() = ArrayList(map.keys) + get() = map.keys.toList() val isEmpty: Boolean get() = map.isEmpty() @@ -40,7 +40,7 @@ class MXUsersDevicesMap { * @return the device ids list */ fun getUserDeviceIds(userId: String?): List? { - return if (userId?.isNotBlank() == true && map.containsKey(userId)) { + return if (!userId.isNullOrBlank() && map.containsKey(userId)) { map[userId]!!.keys.toList() } else null } @@ -53,7 +53,7 @@ class MXUsersDevicesMap { * @return the object */ fun getObject(userId: String?, deviceId: String?): E? { - return if (userId?.isNotBlank() == true && deviceId?.isNotBlank() == true && map.containsKey(userId)) { + return if (!userId.isNullOrBlank() && !deviceId.isNullOrBlank()) { map[userId]?.get(deviceId) } else null } @@ -67,11 +67,8 @@ class MXUsersDevicesMap { */ fun setObject(userId: String?, deviceId: String?, o: E?) { if (null != o && userId?.isNotBlank() == true && deviceId?.isNotBlank() == true) { - if (map[userId] == null) { - map[userId] = HashMap() - } - - map[userId]?.put(deviceId, o) + val devices = map.getOrPut(userId) { HashMap() } + devices[deviceId] = o } } @@ -82,7 +79,7 @@ class MXUsersDevicesMap { * @param userId the user id */ fun setObjects(userId: String?, objectsPerDevices: Map?) { - if (userId?.isNotBlank() == true) { + if (!userId.isNullOrBlank()) { if (null == objectsPerDevices) { map.remove(userId) } else { @@ -97,7 +94,7 @@ class MXUsersDevicesMap { * @param userId the user id. */ fun removeUserObjects(userId: String?) { - if (userId?.isNotBlank() == true) { + if (!userId.isNullOrBlank()) { map.remove(userId) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt index 54a4e14dc8..f3cfa42946 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt @@ -160,7 +160,7 @@ internal class DefaultSasVerificationService @Inject constructor(private val cre cancelTransaction( startReq.transactionID!!, otherUserId!!, - startReq?.fromDevice ?: event.getSenderKey()!!, + startReq.fromDevice ?: event.getSenderKey()!!, CancelCode.UnknownMethod ) } @@ -384,14 +384,13 @@ internal class DefaultSasVerificationService @Inject constructor(private val cre * This string must be unique for the pair of users performing verification for the duration that the transaction is valid */ private fun createUniqueIDForTransaction(userId: String, deviceID: String): String { - val buff = StringBuffer() - buff - .append(credentials.userId).append("|") - .append(credentials.deviceId).append("|") - .append(userId).append("|") - .append(deviceID).append("|") - .append(UUID.randomUUID().toString()) - return buff.toString() + return buildString { + append(credentials.userId).append("|") + append(credentials.deviceId).append("|") + append(userId).append("|") + append(deviceID).append("|") + append(UUID.randomUUID().toString()) + } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt index e249ed74c8..243c9950b6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt @@ -101,25 +101,16 @@ constructor(trustPinned: Array, acceptedTlsVersions: List() - - for (protocol in enabledProtocols) { - if (supportedProtocols.contains(protocol)) { - filteredEnabledProtocols.add(protocol) - } - } - - if (!filteredEnabledProtocols.isEmpty()) { + if (filteredEnabledProtocols.isNotEmpty()) { try { - sslSocket.enabledProtocols = filteredEnabledProtocols.toTypedArray() + socket.enabledProtocols = filteredEnabledProtocols.toTypedArray() } catch (e: Exception) { Timber.e(e) } - } } return socket diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt index df79d62e8b..f932c3c924 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt @@ -305,17 +305,22 @@ internal class LocalEchoEventFactory @Inject constructor(private val credentials } private fun buildReplyFallback(body: TextContent, originalSenderId: String?, newBodyText: String): String { - val lines = body.text.split("\n") - val replyFallback = StringBuffer("> <$originalSenderId>") - lines.forEachIndexed { index, s -> - if (index == 0) { - replyFallback.append(" $s") - } else { - replyFallback.append("\n> $s") + return buildString { + append("> <") + append(originalSenderId) + append(">") + + val lines = body.text.split("\n") + lines.forEachIndexed { index, s -> + if (index == 0) { + append(" $s") + } else { + append("\n> $s") + } } + append("\n\n") + append(newBodyText) } - replyFallback.append("\n\n").append(newBodyText) - return replyFallback.toString() } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomTagHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomTagHandler.kt index 49038eed3d..4d363af635 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomTagHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomTagHandler.kt @@ -31,16 +31,8 @@ internal class RoomTagHandler @Inject constructor() { if (content == null) { return } - val tags = ArrayList() - for (tagName in content.tags.keys) { - val params = content.tags[tagName] - val order = params?.get("order") - val tag = if (order is Double) { - RoomTagEntity(tagName, order) - } else { - RoomTagEntity(tagName, null) - } - tags.add(tag) + val tags = content.tags.entries.map { (tagName, params) -> + RoomTagEntity(tagName, params["order"] as? Double) } val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() ?: RoomSummaryEntity(roomId) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/JsonCanonicalizer.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/JsonCanonicalizer.kt index 36c1ba1553..42f82db8a1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/JsonCanonicalizer.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/JsonCanonicalizer.kt @@ -60,43 +60,33 @@ object JsonCanonicalizer { when (any) { is JSONArray -> { // Canonicalize each element of the array - val result = StringBuilder("[") - - for (i in 0 until any.length()) { - result.append(canonicalizeRecursive(any.get(i))) - if (i < any.length() - 1) { - result.append(",") - } + return (0 until any.length()).joinToString(separator = ",", prefix = "[", postfix = "]") { + canonicalizeRecursive(any.get(it)) } - - result.append("]") - - return result.toString() } is JSONObject -> { // Sort the attributes by name, and the canonicalize each element of the JSONObject - val result = StringBuilder("{") val attributes = TreeSet() for (entry in any.keys()) { attributes.add(entry) } - for (attribute in attributes.withIndex()) { - result.append("\"") - .append(attribute.value) - .append("\"") - .append(":") - .append(canonicalizeRecursive(any[attribute.value])) + return buildString { + append("{") + for ((index, value) in attributes.withIndex()) { + append("\"") + append(value) + append("\"") + append(":") + append(canonicalizeRecursive(any[value])) - if (attribute.index < attributes.size - 1) { - result.append(",") + if (index < attributes.size - 1) { + append(",") + } } + append("}") } - - result.append("}") - - return result.toString() } is String -> return JSONObject.quote(any) else -> return any.toString() From ed5faca5d2eb10e4fb30aaab40d8ed0d42a66bfe Mon Sep 17 00:00:00 2001 From: Valere Date: Sun, 18 Aug 2019 17:46:17 -0400 Subject: [PATCH 03/34] Slide-in reply icon is distorted --- CHANGES.md | 2 +- .../room/detail/RoomMessageTouchHelperCallback.kt | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 682c176b98..eae3bd53f2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,7 +11,7 @@ Other changes: - Bugfix: - - + - Slide-in reply icon is distorted (#423) Translations: - diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomMessageTouchHelperCallback.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomMessageTouchHelperCallback.kt index d30bad2f53..a7e617c05f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomMessageTouchHelperCallback.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomMessageTouchHelperCallback.kt @@ -191,12 +191,13 @@ class RoomMessageTouchHelperCallback(private val context: Context, } val y = (itemView.top + itemView.measuredHeight / 2).toFloat() - //magic numbers? + val hw = imageDrawable.intrinsicWidth / 2f + val hh = imageDrawable.intrinsicHeight / 2f imageDrawable.setBounds( - (x - convertToPx(12) * scale).toInt(), - (y - convertToPx(11) * scale).toInt(), - (x + convertToPx(12) * scale).toInt(), - (y + convertToPx(10) * scale).toInt() + (x - hw * scale).toInt(), + (y - hh * scale).toInt(), + (x + hw * scale).toInt(), + (y + hh * scale).toInt() ) imageDrawable.draw(canvas) imageDrawable.alpha = 255 From 7966ebef0359fb3cc26ebdf3c822cfa41e8517a9 Mon Sep 17 00:00:00 2001 From: Valere Date: Sun, 18 Aug 2019 15:12:59 -0400 Subject: [PATCH 04/34] Date change message repeats for each redaction until a normal message --- CHANGES.md | 2 +- .../detail/timeline/helper/TimelineDisplayableEvents.kt | 3 ++- .../detail/timeline/util/MessageInformationDataFactory.kt | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 682c176b98..d7533ee3d1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,7 +11,7 @@ Other changes: - Bugfix: - - + - Date change message repeats for each redaction until a normal message (#358) Translations: - diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt index fa0a71bde2..7307e0674d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt @@ -56,7 +56,8 @@ fun TimelineEvent.isDisplayable(showHiddenEvent: Boolean): Boolean { return false } if (root.content.isNullOrEmpty()) { - return false + //redacted events have empty content but are displayable + return root.unsignedData?.redactedEvent != null } //Edits should be filtered out! if (EventType.MESSAGE == root.type diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt index a00dd3fa9f..46887cad77 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt @@ -50,10 +50,10 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses val showInformation = addDaySeparator - || event.senderAvatar != nextEvent?.senderAvatar - || event.getDisambiguatedDisplayName() != nextEvent?.getDisambiguatedDisplayName() - || (nextEvent.root.getClearType() != EventType.MESSAGE && nextEvent.root.getClearType() != EventType.ENCRYPTED) - || isNextMessageReceivedMoreThanOneHourAgo + || event.senderAvatar != nextEvent?.senderAvatar + || event.getDisambiguatedDisplayName() != nextEvent?.getDisambiguatedDisplayName() + || (nextEvent.root.getClearType() != EventType.MESSAGE && nextEvent.root.getClearType() != EventType.ENCRYPTED) + || isNextMessageReceivedMoreThanOneHourAgo val time = dateFormatter.formatMessageHour(date) val avatarUrl = event.senderAvatar From d4161e9a1aa1b7fa85384039f70da8d3ed56fe4b Mon Sep 17 00:00:00 2001 From: Valere Date: Sun, 18 Aug 2019 17:30:41 -0400 Subject: [PATCH 05/34] Fix text diff removed linebreak --- CHANGES.md | 2 +- .../detail/timeline/action/ViewEditHistoryEpoxyController.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 682c176b98..436d45908d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,7 +11,7 @@ Other changes: - Bugfix: - - + - Fix text diff linebreak display (#441) Translations: - diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewEditHistoryEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewEditHistoryEpoxyController.kt index dab43108c2..0b311e7c37 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewEditHistoryEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewEditHistoryEpoxyController.kt @@ -113,7 +113,7 @@ class ViewEditHistoryEpoxyController(private val context: Context, when (it.operation) { diff_match_patch.Operation.DELETE -> { span { - text = it.text + text = it.text.replace("\n"," ") textColor = ContextCompat.getColor(context, R.color.vector_error_color) textDecorationLine = "line-through" } From 2be6058971d2bd2bcd5021cd0033b7121b5dd311 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 9 Jul 2019 10:13:56 +0200 Subject: [PATCH 06/34] accept non unicode reactions --- .../home/room/detail/timeline/action/MessageMenuViewModel.kt | 3 +-- .../room/detail/timeline/action/ViewReactionViewModel.kt | 2 +- .../detail/timeline/util/MessageInformationDataFactory.kt | 2 +- vector/src/main/res/layout/reaction_button.xml | 5 +++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageMenuViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageMenuViewModel.kt index ae8803f5c8..d89035b813 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageMenuViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/MessageMenuViewModel.kt @@ -35,7 +35,6 @@ import im.vector.riotx.R import im.vector.riotx.core.extensions.canReact import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.resources.StringProvider -import im.vector.riotx.core.utils.isSingleEmoji import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData @@ -244,7 +243,7 @@ class MessageMenuViewModel @AssistedInject constructor(@Assisted initialState: M //Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment if (event.root.getClearType() != EventType.MESSAGE) return false //TODO if user is admin or moderator - return event.annotations?.reactionsSummary?.any { isSingleEmoji(it.key) } ?: false + return event.annotations?.reactionsSummary?.isNotEmpty() ?: false } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionViewModel.kt index 9479c30783..221cc889f0 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionViewModel.kt @@ -90,7 +90,7 @@ class ViewReactionViewModel @AssistedInject constructor(@Assisted .flatMapSingle { summaries -> Observable .fromIterable(summaries.reactionsSummary) - .filter { reactionAggregatedSummary -> isSingleEmoji(reactionAggregatedSummary.key) } + //.filter { reactionAggregatedSummary -> isSingleEmoji(reactionAggregatedSummary.key) } .toReactionInfoList() } .execute { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt index 46887cad77..bfb0848df3 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt @@ -71,7 +71,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses memberName = formattedMemberName, showInformation = showInformation, orderedReactionList = event.annotations?.reactionsSummary - ?.filter { isSingleEmoji(it.key) } + //?.filter { isSingleEmoji(it.key) } ?.map { ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty()) }, diff --git a/vector/src/main/res/layout/reaction_button.xml b/vector/src/main/res/layout/reaction_button.xml index 3d2cd3c87a..ae1ec0a634 100644 --- a/vector/src/main/res/layout/reaction_button.xml +++ b/vector/src/main/res/layout/reaction_button.xml @@ -37,8 +37,9 @@ + tools:text="* Party Parrot Again *" /> Date: Sun, 18 Aug 2019 14:26:53 -0400 Subject: [PATCH 07/34] Use EmojiCompat to build EmojiSpans from text --- CHANGES.md | 4 ++-- vector/build.gradle | 2 ++ .../java/im/vector/riotx/VectorApplication.kt | 20 +++++++++++++++++++ .../timeline/action/ReactionInfoSimpleItem.kt | 4 ---- .../action/ViewReactionBottomSheet.kt | 4 +--- .../action/ViewReactionsEpoxyController.kt | 6 +++--- .../detail/timeline/item/AbsMessageItem.kt | 2 +- .../reactions/widget/ReactionButton.kt | 13 +++++------- .../src/main/res/layout/reaction_button.xml | 10 ++++++---- 9 files changed, 40 insertions(+), 25 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3a82647d10..a3b3776156 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,10 +5,10 @@ Features: - Display read receipts in timeline (#81) Improvements: - - + - Reactions: Reinstate the ability to react with non-unicode keys (#307) Other changes: - - + - Bugfix: - Fix text diff linebreak display (#441) diff --git a/vector/build.gradle b/vector/build.gradle index 2e5c1adc78..f8c800d15d 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -318,6 +318,8 @@ dependencies { implementation 'diff_match_patch:diff_match_patch:current' + implementation "androidx.emoji:emoji-appcompat:1.0.0" + // TESTS testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt index 66356ac0e8..4e09d790d7 100644 --- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt +++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt @@ -19,10 +19,13 @@ package im.vector.riotx import android.app.Application import android.content.Context import android.content.res.Configuration +import android.graphics.Color import android.os.Handler import android.os.HandlerThread import androidx.core.provider.FontRequest import androidx.core.provider.FontsContractCompat +import androidx.emoji.text.EmojiCompat +import androidx.emoji.text.FontRequestEmojiCompatConfig import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent @@ -105,6 +108,23 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration. ) FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler()) vectorConfiguration.initConfiguration() + + //Use emoji compat for the benefit of emoji spans + val config = FontRequestEmojiCompatConfig(this, fontRequest) + .setReplaceAll(true) // we want to replace all emojis with selected font +// .setEmojiSpanIndicatorEnabled(true) +// .setEmojiSpanIndicatorColor(Color.GREEN) + EmojiCompat.init(config) + .registerInitCallback(object : EmojiCompat.InitCallback() { + override fun onInitialized() { + Timber.v("Emoji compat onInitialized success ") + } + + override fun onFailed(throwable: Throwable?) { + Timber.e(throwable,"Failed to init EmojiCompat") + } + }) + NotificationUtils.createNotificationChannels(applicationContext) if (authenticator.hasAuthenticatedSessions() && !activeSessionHolder.hasActiveSession()) { val lastAuthenticatedSession = authenticator.getLastAuthenticatedSession()!! diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ReactionInfoSimpleItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ReactionInfoSimpleItem.kt index 10c2357d4f..e63ac29cc4 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ReactionInfoSimpleItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ReactionInfoSimpleItem.kt @@ -38,12 +38,8 @@ abstract class ReactionInfoSimpleItem : EpoxyModelWithHolder() { override fun buildModels(state: DisplayReactionsViewState) { @@ -50,9 +51,8 @@ class ViewReactionsEpoxyController(private val context: Context, private val emo state.mapReactionKeyToMemberList()?.forEach { reactionInfoSimpleItem { id(it.eventId) - emojiTypeFace(emojiCompatTypeface) timeStamp(it.timestamp) - reactionKey(it.reactionKey) + reactionKey(EmojiCompat.get().process(it.reactionKey)) authorDisplayName(it.authorName ?: it.authorId) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt index a394f47124..cf5f2517da 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -151,7 +151,7 @@ abstract class AbsMessageItem : BaseEventItem() { idToRefInFlow.add(reactionButton.id) reactionButton.reactionString = reaction.key reactionButton.reactionCount = reaction.count - reactionButton.emojiTypeFace = emojiTypeFace + //reactionButton.emojiTypeFace = emojiTypeFace reactionButton.setChecked(reaction.addedByMe) reactionButton.isEnabled = reaction.synced } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt index 0af910a06f..0644e9627f 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt @@ -35,6 +35,7 @@ import android.widget.TextView import androidx.annotation.ColorInt import androidx.annotation.ColorRes import androidx.core.content.ContextCompat +import androidx.emoji.text.EmojiCompat import im.vector.riotx.R import im.vector.riotx.core.utils.TextUtils @@ -58,12 +59,6 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut private var reactionSelector: View? = null - var emojiTypeFace: Typeface? = null - set(value) { - field = value - emojiView?.typeface = value ?: Typeface.DEFAULT - } - private var dotsView: DotsView private var circleView: CircleView var reactedListener: ReactedListener? = null @@ -82,7 +77,9 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut var reactionString = "😀" set(value) { field = value - emojiView?.text = field + //maybe cache this for performances? + val emojiSpanned = EmojiCompat.get().process(value) + emojiView?.text = emojiSpanned } private var animationScaleFactor: Float = 0.toFloat() @@ -104,7 +101,7 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut countTextView?.text = TextUtils.formatCountToShortDecimal(reactionCount) - emojiView?.typeface = this.emojiTypeFace ?: Typeface.DEFAULT +// emojiView?.typeface = this.emojiTypeFace ?: Typeface.DEFAULT val array = context.obtainStyledAttributes(attrs, R.styleable.ReactionButton, defStyleAttr, 0) diff --git a/vector/src/main/res/layout/reaction_button.xml b/vector/src/main/res/layout/reaction_button.xml index ae1ec0a634..7e715a7122 100644 --- a/vector/src/main/res/layout/reaction_button.xml +++ b/vector/src/main/res/layout/reaction_button.xml @@ -40,18 +40,20 @@ android:layout_width="wrap_content" android:layout_height="20dp" android:minWidth="20dp" - android:layout_gravity="center" android:layout_marginStart="6dp" android:layout_marginLeft="6dp" android:gravity="center" android:textColor="@color/black" android:textSize="13sp" + android:maxEms="10" + android:ellipsize="middle" + android:singleLine="true" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toStartOf="@id/reactionCount" - tools:text="* Party Parrot Again *" /> + tools:text="* Party Parrot Again * 👀" /> Date: Tue, 27 Aug 2019 16:50:02 +0200 Subject: [PATCH 08/34] Some video won't play VideoView fails to play some remote uri video on some device. For now video is downloaded locally in internal cache then played. This offers basic support before full media preview implementation --- CHANGES.md | 1 + .../features/media/VideoContentRenderer.kt | 36 ++++++++++++++++--- .../layout/activity_video_media_viewer.xml | 3 ++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a3b3776156..2c498851bc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Bugfix: - Fix text diff linebreak display (#441) - Date change message repeats for each redaction until a normal message (#358) - Slide-in reply icon is distorted (#423) + - Some video won't play Translations: - diff --git a/vector/src/main/java/im/vector/riotx/features/media/VideoContentRenderer.kt b/vector/src/main/java/im/vector/riotx/features/media/VideoContentRenderer.kt index 22650b0edf..0509a0d480 100644 --- a/vector/src/main/java/im/vector/riotx/features/media/VideoContentRenderer.kt +++ b/vector/src/main/java/im/vector/riotx/features/media/VideoContentRenderer.kt @@ -89,18 +89,44 @@ class VideoContentRenderer @Inject constructor(private val activeSessionHolder: }) } } else { - thumbnailView.isVisible = false - loadingView.isVisible = false val resolvedUrl = contentUrlResolver.resolveFullSize(data.url) if (resolvedUrl == null) { + thumbnailView.isVisible = false + loadingView.isVisible = false errorView.isVisible = true errorView.setText(R.string.unknown_error) } else { - videoView.isVisible = true - videoView.setVideoPath(resolvedUrl) - videoView.start() + + //Temporary code, some remote videos are not played by videoview setVideoUri + //So for now we download them then play + thumbnailView.isVisible = true + loadingView.isVisible = true + + activeSessionHolder.getActiveSession() + .downloadFile( + FileService.DownloadMode.FOR_INTERNAL_USE, + data.eventId, + data.filename, + data.url, + null, + object : MatrixCallback { + override fun onSuccess(data: File) { + thumbnailView.isVisible = false + loadingView.isVisible = false + videoView.isVisible = true + + videoView.setVideoPath(data.path) + videoView.start() + } + + override fun onFailure(failure: Throwable) { + loadingView.isVisible = false + errorView.isVisible = true + errorView.text = errorFormatter.toHumanReadable(failure) + } + }) } } } diff --git a/vector/src/main/res/layout/activity_video_media_viewer.xml b/vector/src/main/res/layout/activity_video_media_viewer.xml index f21e6daf5f..c68577bcd5 100644 --- a/vector/src/main/res/layout/activity_video_media_viewer.xml +++ b/vector/src/main/res/layout/activity_video_media_viewer.xml @@ -34,7 +34,9 @@ android:id="@+id/videoMediaViewerThumbnailView" android:layout_width="match_parent" android:layout_height="match_parent" + android:layout_gravity="center" android:visibility="gone" + android:scaleType="centerInside" tools:visibility="visible" /> Date: Tue, 27 Aug 2019 17:01:52 +0200 Subject: [PATCH 09/34] Fix / regression on e2e reply and edit of reply --- CHANGES.md | 1 + .../session/room/relation/DefaultRelationService.kt | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a3b3776156..d657337bdc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Bugfix: - Fix text diff linebreak display (#441) - Date change message repeats for each redaction until a normal message (#358) - Slide-in reply icon is distorted (#423) + - Regression / e2e replies not encrypted Translations: - diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt index addad44bf9..9640cd4e80 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt @@ -136,7 +136,7 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv } if (cryptoService.isRoomEncrypted(roomId)) { val encryptWork = createEncryptEventWork(event, listOf("m.relates_to")) - val workRequest = createSendEventWork(event) + val workRequest = createSendEventWork(event, false) TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest) return CancelableWork(context, encryptWork.id) @@ -162,7 +162,7 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv } if (cryptoService.isRoomEncrypted(roomId)) { val encryptWork = createEncryptEventWork(event, listOf("m.relates_to")) - val workRequest = createSendEventWork(event) + val workRequest = createSendEventWork(event, false) TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest) return CancelableWork(context, encryptWork.id) @@ -189,7 +189,7 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv if (cryptoService.isRoomEncrypted(roomId)) { val encryptWork = createEncryptEventWork(event, listOf("m.relates_to")) - val workRequest = createSendEventWork(event) + val workRequest = createSendEventWork(event, false) TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest) return CancelableWork(context, encryptWork.id) @@ -208,10 +208,10 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv return TimelineSendEventWorkCommon.createWork(sendWorkData, true) } - private fun createSendEventWork(event: Event): OneTimeWorkRequest { + private fun createSendEventWork(event: Event, startChain: Boolean = true): OneTimeWorkRequest { val sendContentWorkerParams = SendEventWorker.Params(credentials.userId, roomId, event) val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams) - return TimelineSendEventWorkCommon.createWork(sendWorkData, true) + return TimelineSendEventWorkCommon.createWork(sendWorkData, startChain) } override fun getEventSummaryLive(eventId: String): LiveData { From 166be4e289600be9898a47f02964391fb163165c Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 27 Aug 2019 15:36:44 +0200 Subject: [PATCH 10/34] Improve read receipt design --- .../DisplayReadReceiptsBottomSheet.kt | 2 +- .../main/res/drawable/pill_receipt_black.xml | 6 ++++ .../main/res/drawable/pill_receipt_dark.xml | 6 ++++ .../main/res/drawable/pill_receipt_light.xml | 6 ++++ .../res/layout/item_display_read_receipt.xml | 22 +++---------- .../res/layout/item_simple_reaction_info.xml | 18 ++--------- .../main/res/layout/view_read_receipts.xml | 31 ++++++++++++------- vector/src/main/res/values/attrs.xml | 1 + vector/src/main/res/values/strings_riotX.xml | 1 + vector/src/main/res/values/styles_riot.xml | 19 ++++++++++++ vector/src/main/res/values/theme_black.xml | 2 ++ vector/src/main/res/values/theme_dark.xml | 2 ++ vector/src/main/res/values/theme_light.xml | 2 ++ 13 files changed, 73 insertions(+), 45 deletions(-) create mode 100644 vector/src/main/res/drawable/pill_receipt_black.xml create mode 100644 vector/src/main/res/drawable/pill_receipt_dark.xml create mode 100644 vector/src/main/res/drawable/pill_receipt_light.xml diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt index b8c1519f4c..42ad166429 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt @@ -69,7 +69,7 @@ class DisplayReadReceiptsBottomSheet : VectorBaseBottomSheetDialogFragment() { val dividerItemDecoration = DividerItemDecoration(epoxyRecyclerView.context, LinearLayout.VERTICAL) epoxyRecyclerView.addItemDecoration(dividerItemDecoration) - bottomSheetTitle.text = getString(R.string.read_receipts_list) + bottomSheetTitle.text = getString(R.string.read_at) epoxyController.setData(displayReadReceiptArgs.readReceipts) } diff --git a/vector/src/main/res/drawable/pill_receipt_black.xml b/vector/src/main/res/drawable/pill_receipt_black.xml new file mode 100644 index 0000000000..e63903550d --- /dev/null +++ b/vector/src/main/res/drawable/pill_receipt_black.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/vector/src/main/res/drawable/pill_receipt_dark.xml b/vector/src/main/res/drawable/pill_receipt_dark.xml new file mode 100644 index 0000000000..5442f13985 --- /dev/null +++ b/vector/src/main/res/drawable/pill_receipt_dark.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/vector/src/main/res/drawable/pill_receipt_light.xml b/vector/src/main/res/drawable/pill_receipt_light.xml new file mode 100644 index 0000000000..66875dc1b1 --- /dev/null +++ b/vector/src/main/res/drawable/pill_receipt_light.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_display_read_receipt.xml b/vector/src/main/res/layout/item_display_read_receipt.xml index 9b4072ab76..2aa4485c4e 100644 --- a/vector/src/main/res/layout/item_display_read_receipt.xml +++ b/vector/src/main/res/layout/item_display_read_receipt.xml @@ -5,38 +5,26 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" + android:minHeight="40dp" android:orientation="horizontal" android:paddingStart="8dp" android:paddingEnd="8dp"> \ No newline at end of file diff --git a/vector/src/main/res/layout/item_simple_reaction_info.xml b/vector/src/main/res/layout/item_simple_reaction_info.xml index 06f94fc8cf..02a36fc6d0 100644 --- a/vector/src/main/res/layout/item_simple_reaction_info.xml +++ b/vector/src/main/res/layout/item_simple_reaction_info.xml @@ -6,6 +6,7 @@ android:gravity="center_vertical" android:orientation="horizontal" android:paddingStart="8dp" + android:minHeight="40dp" android:paddingEnd="8dp"> diff --git a/vector/src/main/res/layout/view_read_receipts.xml b/vector/src/main/res/layout/view_read_receipts.xml index e3cbc6ba06..f477a979ec 100644 --- a/vector/src/main/res/layout/view_read_receipts.xml +++ b/vector/src/main/res/layout/view_read_receipts.xml @@ -9,48 +9,55 @@ diff --git a/vector/src/main/res/values/attrs.xml b/vector/src/main/res/values/attrs.xml index 368c03c0c1..e9a4296add 100644 --- a/vector/src/main/res/values/attrs.xml +++ b/vector/src/main/res/values/attrs.xml @@ -88,6 +88,7 @@ + diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 118fde8442..23ea1e2f0b 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -2,5 +2,6 @@ + Read at \ No newline at end of file diff --git a/vector/src/main/res/values/styles_riot.xml b/vector/src/main/res/values/styles_riot.xml index 80f5148a6e..d1894254cd 100644 --- a/vector/src/main/res/values/styles_riot.xml +++ b/vector/src/main/res/values/styles_riot.xml @@ -319,4 +319,23 @@ @drawable/vector_label_background_light + + + + \ No newline at end of file diff --git a/vector/src/main/res/values/theme_black.xml b/vector/src/main/res/values/theme_black.xml index 7b582e20dc..129a2e9b1c 100644 --- a/vector/src/main/res/values/theme_black.xml +++ b/vector/src/main/res/values/theme_black.xml @@ -75,6 +75,8 @@ #FF4D4D4D + @drawable/pill_receipt_black + @color/riot_primary_background_color_black @color/primary_color_black diff --git a/vector/src/main/res/values/theme_dark.xml b/vector/src/main/res/values/theme_dark.xml index b5796eb9db..4143229293 100644 --- a/vector/src/main/res/values/theme_dark.xml +++ b/vector/src/main/res/values/theme_dark.xml @@ -163,6 +163,8 @@ @android:color/white @color/riot_primary_text_color_dark + @drawable/pill_receipt_dark + @drawable/direct_chat_circle_dark #FF454545 diff --git a/vector/src/main/res/values/theme_light.xml b/vector/src/main/res/values/theme_light.xml index 56f2b90be9..8d51486e76 100644 --- a/vector/src/main/res/values/theme_light.xml +++ b/vector/src/main/res/values/theme_light.xml @@ -163,6 +163,8 @@ @color/riot_primary_text_color_light @android:color/white + @drawable/pill_receipt_light + @drawable/direct_chat_circle_light #FFD3EFE1 From 1b394527b6a0a7cec012e3293db5b1b3253bc937 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 28 Aug 2019 10:22:51 +0200 Subject: [PATCH 11/34] cleaning + code review --- .../room/relation/DefaultRelationService.kt | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt index 9640cd4e80..0c8695cbcf 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt @@ -69,15 +69,11 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv .also { saveLocalEcho(it) } - val sendRelationWork = createSendRelationWork(event) + val sendRelationWork = createSendEventWork(event, true) TimelineSendEventWorkCommon.postWork(context, roomId, sendRelationWork) return CancelableWork(context, sendRelationWork.id) } - private fun createSendRelationWork(event: Event): OneTimeWorkRequest { - return createSendEventWork(event) - } - override fun undoReaction(reaction: String, targetEventId: String, myUserId: String)/*: Cancelable*/ { val params = FindReactionEventForUndoTask.Params( @@ -134,42 +130,42 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv .also { saveLocalEcho(it) } - if (cryptoService.isRoomEncrypted(roomId)) { + return if (cryptoService.isRoomEncrypted(roomId)) { val encryptWork = createEncryptEventWork(event, listOf("m.relates_to")) val workRequest = createSendEventWork(event, false) TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest) - return CancelableWork(context, encryptWork.id) + CancelableWork(context, encryptWork.id) } else { - val workRequest = createSendEventWork(event) + val workRequest = createSendEventWork(event, true) TimelineSendEventWorkCommon.postWork(context, roomId, workRequest) - return CancelableWork(context, workRequest.id) + CancelableWork(context, workRequest.id) } } override fun editReply(replyToEdit: TimelineEvent, - originalEvent: TimelineEvent, + originalTimelineEvent: TimelineEvent, newBodyText: String, compatibilityBodyText: String): Cancelable { val event = eventFactory .createReplaceTextOfReply(roomId, - replyToEdit, - originalEvent, - newBodyText, true, MessageType.MSGTYPE_TEXT, compatibilityBodyText) + replyToEdit, + originalTimelineEvent, + newBodyText, true, MessageType.MSGTYPE_TEXT, compatibilityBodyText) .also { saveLocalEcho(it) } - if (cryptoService.isRoomEncrypted(roomId)) { + return if (cryptoService.isRoomEncrypted(roomId)) { val encryptWork = createEncryptEventWork(event, listOf("m.relates_to")) val workRequest = createSendEventWork(event, false) TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest) - return CancelableWork(context, encryptWork.id) + CancelableWork(context, encryptWork.id) } else { - val workRequest = createSendEventWork(event) + val workRequest = createSendEventWork(event, true) TimelineSendEventWorkCommon.postWork(context, roomId, workRequest) - return CancelableWork(context, workRequest.id) + CancelableWork(context, workRequest.id) } } @@ -187,16 +183,16 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv saveLocalEcho(it) } ?: return null - if (cryptoService.isRoomEncrypted(roomId)) { + return if (cryptoService.isRoomEncrypted(roomId)) { val encryptWork = createEncryptEventWork(event, listOf("m.relates_to")) val workRequest = createSendEventWork(event, false) TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest) - return CancelableWork(context, encryptWork.id) + CancelableWork(context, encryptWork.id) } else { - val workRequest = createSendEventWork(event) + val workRequest = createSendEventWork(event, true) TimelineSendEventWorkCommon.postWork(context, roomId, workRequest) - return CancelableWork(context, workRequest.id) + CancelableWork(context, workRequest.id) } } @@ -208,7 +204,7 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv return TimelineSendEventWorkCommon.createWork(sendWorkData, true) } - private fun createSendEventWork(event: Event, startChain: Boolean = true): OneTimeWorkRequest { + private fun createSendEventWork(event: Event, startChain: Boolean): OneTimeWorkRequest { val sendContentWorkerParams = SendEventWorker.Params(credentials.userId, roomId, event) val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams) return TimelineSendEventWorkCommon.createWork(sendWorkData, startChain) @@ -220,7 +216,7 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv } return Transformations.map(liveEntity) { realmResults -> realmResults.firstOrNull()?.asDomain() - ?: EventAnnotationsSummary(eventId, emptyList(), null) + ?: EventAnnotationsSummary(eventId, emptyList(), null) } } @@ -233,7 +229,7 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv private fun saveLocalEcho(event: Event) { monarchy.writeAsync { realm -> val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst() - ?: return@writeAsync + ?: return@writeAsync roomEntity.addSendingEvent(event) } } From ea242f6737a819a665661391605ef47d3d2c14ab Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 28 Aug 2019 17:17:37 +0200 Subject: [PATCH 12/34] Hide ReadReceipt View when it is not relevant --- .../java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt | 4 ---- .../features/home/room/detail/timeline/item/AbsMessageItem.kt | 2 -- .../features/home/room/detail/timeline/item/BaseEventItem.kt | 2 ++ .../features/home/room/detail/timeline/item/DefaultItem.kt | 4 ++++ .../home/room/detail/timeline/item/MergedHeaderItem.kt | 4 ++++ .../features/home/room/detail/timeline/item/NoticeItem.kt | 2 -- vector/src/main/res/layout/item_timeline_event_base.xml | 4 +++- .../src/main/res/layout/item_timeline_event_base_noinfo.xml | 4 +++- 8 files changed, 16 insertions(+), 10 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt b/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt index 44d1ee6f70..15a54248d7 100644 --- a/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt +++ b/vector/src/main/java/im/vector/riotx/core/ui/views/ReadReceiptsView.kt @@ -21,11 +21,8 @@ import android.util.AttributeSet import android.view.View import android.widget.ImageView import android.widget.LinearLayout -import androidx.core.view.isInvisible import androidx.core.view.isVisible -import butterknife.ButterKnife import im.vector.riotx.R -import im.vector.riotx.core.utils.DebouncedClickListener import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.room.detail.timeline.item.ReadReceiptData import kotlinx.android.synthetic.main.view_read_receipts.view.* @@ -48,7 +45,6 @@ class ReadReceiptsView @JvmOverloads constructor( private fun setupView() { inflate(context, R.layout.view_read_receipts, this) - ButterKnife.bind(this) } fun render(readReceipts: List, avatarRenderer: AvatarRenderer, clickListener: OnClickListener) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt index cf5f2517da..2a4142e474 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -32,7 +32,6 @@ import com.airbnb.epoxy.EpoxyAttribute import im.vector.matrix.android.api.session.room.send.SendState import im.vector.riotx.R import im.vector.riotx.core.resources.ColorProvider -import im.vector.riotx.core.ui.views.ReadReceiptsView import im.vector.riotx.core.utils.DebouncedClickListener import im.vector.riotx.core.utils.DimensionUtils.dpToPx import im.vector.riotx.features.home.AvatarRenderer @@ -181,7 +180,6 @@ abstract class AbsMessageItem : BaseEventItem() { val avatarImageView by bind(R.id.messageAvatarImageView) val memberNameView by bind(R.id.messageMemberNameView) val timeView by bind(R.id.messageTimeView) - val readReceiptsView by bind(R.id.readReceiptsView) var reactionWrapper: ViewGroup? = null var reactionFlowHelper: Flow? = null } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/BaseEventItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/BaseEventItem.kt index 843f52b34c..96625d16b8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/BaseEventItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/BaseEventItem.kt @@ -24,6 +24,7 @@ import im.vector.riotx.R import im.vector.riotx.core.epoxy.VectorEpoxyHolder import im.vector.riotx.core.epoxy.VectorEpoxyModel import im.vector.riotx.core.platform.CheckableView +import im.vector.riotx.core.ui.views.ReadReceiptsView import im.vector.riotx.core.utils.DimensionUtils.dpToPx /** @@ -49,6 +50,7 @@ abstract class BaseEventItem : VectorEpoxyModel abstract class BaseHolder(@IdRes val stubId: Int) : VectorEpoxyHolder() { val leftGuideline by bind(R.id.messageStartGuideline) val checkableBackground by bind(R.id.messageSelectedBackground) + val readReceiptsView by bind(R.id.readReceiptsView) override fun bindView(itemView: View) { super.bindView(itemView) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt index 0b30facfae..e43c0a9508 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt @@ -17,6 +17,7 @@ package im.vector.riotx.features.home.room.detail.timeline.item import android.widget.TextView +import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R @@ -29,6 +30,9 @@ abstract class DefaultItem : BaseEventItem() { override fun bind(holder: Holder) { holder.messageView.text = text + + // TODO We should handle read receipt here as well + holder.readReceiptsView.isVisible = false } override fun getViewType() = STUB_ID diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedHeaderItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedHeaderItem.kt index 4f26f9bb11..03dd5a8a4a 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedHeaderItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MergedHeaderItem.kt @@ -21,6 +21,7 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.core.view.children +import androidx.core.view.isVisible import im.vector.riotx.R import im.vector.riotx.features.home.AvatarRenderer @@ -75,6 +76,9 @@ data class MergedHeaderItem(private val isCollapsed: Boolean, holder.separatorView.visibility = View.VISIBLE holder.expandView.setText(R.string.merged_events_collapse) } + + // No read receipt for this item + holder.readReceiptsView.isVisible = false } data class Data( diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/NoticeItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/NoticeItem.kt index 51a7b0ce38..2985049710 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/NoticeItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/NoticeItem.kt @@ -22,7 +22,6 @@ import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R -import im.vector.riotx.core.ui.views.ReadReceiptsView import im.vector.riotx.core.utils.DebouncedClickListener import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController @@ -72,7 +71,6 @@ abstract class NoticeItem : BaseEventItem() { class Holder : BaseHolder(STUB_ID) { val avatarImageView by bind(R.id.itemNoticeAvatarView) val noticeTextView by bind(R.id.itemNoticeTextView) - val readReceiptsView by bind(R.id.readReceiptsView) } companion object { diff --git a/vector/src/main/res/layout/item_timeline_event_base.xml b/vector/src/main/res/layout/item_timeline_event_base.xml index 2f0be78f38..8e42804c59 100644 --- a/vector/src/main/res/layout/item_timeline_event_base.xml +++ b/vector/src/main/res/layout/item_timeline_event_base.xml @@ -129,8 +129,10 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginBottom="4dp" + android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" /> + app:layout_constraintEnd_toEndOf="parent" + tools:visibility="visible" /> \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml b/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml index 7726839902..3f82c8db89 100644 --- a/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml +++ b/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml @@ -58,8 +58,10 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginBottom="4dp" + android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" /> + app:layout_constraintEnd_toEndOf="parent" + tools:visibility="visible" /> \ No newline at end of file From ef0362ba9cbf8eb41be177b6b7676343c370f80a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 28 Aug 2019 17:31:31 +0200 Subject: [PATCH 13/34] Display Read Receipt on unsupported events --- .../timeline/factory/DefaultItemFactory.kt | 17 +++++++++++++-- .../timeline/factory/TimelineItemFactory.kt | 9 ++------ .../room/detail/timeline/item/DefaultItem.kt | 21 ++++++++++++++++--- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/DefaultItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/DefaultItemFactory.kt index 05e4007e04..9adbfb8a1d 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/DefaultItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/DefaultItemFactory.kt @@ -17,21 +17,34 @@ package im.vector.riotx.features.home.room.detail.timeline.factory import im.vector.matrix.android.api.session.room.timeline.TimelineEvent +import im.vector.riotx.features.home.AvatarRenderer +import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController import im.vector.riotx.features.home.room.detail.timeline.item.DefaultItem import im.vector.riotx.features.home.room.detail.timeline.item.DefaultItem_ +import im.vector.riotx.features.home.room.detail.timeline.util.MessageInformationDataFactory import javax.inject.Inject -class DefaultItemFactory @Inject constructor(){ +class DefaultItemFactory @Inject constructor(private val avatarRenderer: AvatarRenderer, + private val informationDataFactory: MessageInformationDataFactory) { - fun create(event: TimelineEvent, highlight: Boolean, exception: Exception? = null): DefaultItem? { + fun create(event: TimelineEvent, + highlight: Boolean, + callback: TimelineEventController.Callback?, + exception: Exception? = null): DefaultItem? { val text = if (exception == null) { "${event.root.getClearType()} events are not yet handled" } else { "an exception occurred when rendering the event ${event.root.eventId}" } + + val informationData = informationDataFactory.create(event, null) + return DefaultItem_() .text(text) + .avatarRenderer(avatarRenderer) .highlighted(highlight) + .informationData(informationData) + .readReceiptsCallback(callback) } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt index b1ae595ea0..e9ce37f2b1 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/TimelineItemFactory.kt @@ -20,12 +20,7 @@ import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.riotx.core.epoxy.EmptyItem_ import im.vector.riotx.core.epoxy.VectorEpoxyModel -import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController -import im.vector.riotx.features.home.room.detail.timeline.helper.senderAvatar -import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData -import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem_ -import im.vector.riotx.features.home.room.detail.timeline.util.MessageInformationDataFactory import timber.log.Timber import javax.inject.Inject @@ -71,7 +66,7 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me // Unhandled event types (yet) EventType.STATE_ROOM_THIRD_PARTY_INVITE, - EventType.STICKER -> defaultItemFactory.create(event, highlight) + EventType.STICKER -> defaultItemFactory.create(event, highlight, callback) else -> { Timber.v("Type ${event.root.getClearType()} not handled") null @@ -79,7 +74,7 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me } } catch (e: Exception) { Timber.e(e, "failed to create message item") - defaultItemFactory.create(event, highlight, e) + defaultItemFactory.create(event, highlight, callback, e) } return (computedModel ?: EmptyItem_()) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt index e43c0a9508..ea1aa06484 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt @@ -16,23 +16,38 @@ package im.vector.riotx.features.home.room.detail.timeline.item +import android.view.View import android.widget.TextView -import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotx.R +import im.vector.riotx.core.utils.DebouncedClickListener +import im.vector.riotx.features.home.AvatarRenderer +import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController @EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo) abstract class DefaultItem : BaseEventItem() { + @EpoxyAttribute + lateinit var informationData: MessageInformationData + + @EpoxyAttribute + lateinit var avatarRenderer: AvatarRenderer + + @EpoxyAttribute + var readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null + + private val _readReceiptsClickListener = DebouncedClickListener(View.OnClickListener { + readReceiptsCallback?.onReadReceiptsClicked(informationData.readReceipts) + }) + @EpoxyAttribute var text: CharSequence? = null override fun bind(holder: Holder) { holder.messageView.text = text - // TODO We should handle read receipt here as well - holder.readReceiptsView.isVisible = false + holder.readReceiptsView.render(informationData.readReceipts, avatarRenderer, _readReceiptsClickListener) } override fun getViewType() = STUB_ID From c95223f5d24188363a4529d883ddf83ec88c72cf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 28 Aug 2019 18:17:37 +0200 Subject: [PATCH 14/34] Add long click support on unsupported event --- .../room/detail/timeline/factory/DefaultItemFactory.kt | 1 + .../home/room/detail/timeline/item/DefaultItem.kt | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/DefaultItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/DefaultItemFactory.kt index 9adbfb8a1d..ec7d9e1622 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/DefaultItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/DefaultItemFactory.kt @@ -44,6 +44,7 @@ class DefaultItemFactory @Inject constructor(private val avatarRenderer: AvatarR .avatarRenderer(avatarRenderer) .highlighted(highlight) .informationData(informationData) + .baseCallback(callback) .readReceiptsCallback(callback) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt index ea1aa06484..b4919494f6 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/DefaultItem.kt @@ -34,6 +34,13 @@ abstract class DefaultItem : BaseEventItem() { @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer + @EpoxyAttribute + var baseCallback: TimelineEventController.BaseCallback? = null + + private var longClickListener = View.OnLongClickListener { + return@OnLongClickListener baseCallback?.onEventLongClicked(informationData, null, it) == true + } + @EpoxyAttribute var readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null @@ -47,6 +54,7 @@ abstract class DefaultItem : BaseEventItem() { override fun bind(holder: Holder) { holder.messageView.text = text + holder.view.setOnLongClickListener(longClickListener) holder.readReceiptsView.render(informationData.readReceipts, avatarRenderer, _readReceiptsClickListener) } From ce5570105d8770904dfe02aadd8fd7840e190714 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 29 Aug 2019 10:36:45 +0200 Subject: [PATCH 15/34] Privacy: remove log of notifiable event (#519) --- CHANGES.md | 1 + .../riotx/features/notifications/PushRuleTriggerListener.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index dd9cc737ba..415cdff41d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Bugfix: - Slide-in reply icon is distorted (#423) - Regression / e2e replies not encrypted - Some video won't play + - Privacy: remove log of notifiable event (#519) Translations: - diff --git a/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt b/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt index d404b64c1e..555c8737c5 100644 --- a/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt +++ b/vector/src/main/java/im/vector/riotx/features/notifications/PushRuleTriggerListener.kt @@ -48,7 +48,7 @@ class PushRuleTriggerListener @Inject constructor( //TODO } else { notifiableEvent.noisy = !notificationAction.soundName.isNullOrBlank() - Timber.v("New event to notify $notifiableEvent tweaks:$notificationAction") + Timber.v("New event to notify") notificationDrawerManager.onNotifiableEventReceived(notifiableEvent) } } else { From 75266f42bbfce9da67378b035d22afc24e885f8a Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 29 Aug 2019 16:49:22 +0200 Subject: [PATCH 16/34] Fix / EmojiCompat not initialized --- .../java/im/vector/riotx/EmojiCompatHelper.kt | 68 +++++++++++++++++++ .../java/im/vector/riotx/VectorApplication.kt | 16 +---- .../action/ViewReactionsEpoxyController.kt | 3 +- .../reactions/widget/ReactionButton.kt | 5 +- 4 files changed, 73 insertions(+), 19 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt diff --git a/vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt b/vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt new file mode 100644 index 0000000000..9e4a6087d1 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2019 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.riotx + +import android.content.Context +import androidx.core.provider.FontRequest +import androidx.emoji.text.EmojiCompat +import androidx.emoji.text.FontRequestEmojiCompatConfig +import timber.log.Timber + +object EmojiCompatHelper { + + var initialized = false + + fun init(context: Context) { + val fontRequest = FontRequest( + "com.google.android.gms.fonts", + "com.google.android.gms", + "Noto Color Emoji Compat", + R.array.com_google_android_gms_fonts_certs + ) + //Use emoji compat for the benefit of emoji spans + val config = FontRequestEmojiCompatConfig(context, fontRequest) + // we want to replace all emojis with selected font + .setReplaceAll(true) + //Debug options +// .setEmojiSpanIndicatorEnabled(true) +// .setEmojiSpanIndicatorColor(Color.GREEN) + EmojiCompat.init(config) + .registerInitCallback(object : EmojiCompat.InitCallback() { + override fun onInitialized() { + Timber.v("Emoji compat onInitialized success ") + initialized = true + } + + override fun onFailed(throwable: Throwable?) { + Timber.e(throwable, "Failed to init EmojiCompat") + } + }) + } + + fun safeEmojiSpanify(sequence: CharSequence): CharSequence { + if (initialized) { + try { + return EmojiCompat.get().process(sequence) + } catch (throwable: Throwable) { + //Defensive coding against error (should not happend as it is initialized) + Timber.e(throwable, "Failed to init EmojiCompat") + return sequence + } + } else { + return sequence + } + } +} \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt index 4e09d790d7..36b4d58904 100644 --- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt +++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt @@ -109,21 +109,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration. FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler()) vectorConfiguration.initConfiguration() - //Use emoji compat for the benefit of emoji spans - val config = FontRequestEmojiCompatConfig(this, fontRequest) - .setReplaceAll(true) // we want to replace all emojis with selected font -// .setEmojiSpanIndicatorEnabled(true) -// .setEmojiSpanIndicatorColor(Color.GREEN) - EmojiCompat.init(config) - .registerInitCallback(object : EmojiCompat.InitCallback() { - override fun onInitialized() { - Timber.v("Emoji compat onInitialized success ") - } - - override fun onFailed(throwable: Throwable?) { - Timber.e(throwable,"Failed to init EmojiCompat") - } - }) + EmojiCompatHelper.init(this) NotificationUtils.createNotificationChannels(applicationContext) if (authenticator.hasAuthenticatedSessions() && !activeSessionHolder.hasActiveSession()) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt index 33e1d4dfda..3c2ff93ea9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt @@ -24,6 +24,7 @@ import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Incomplete import com.airbnb.mvrx.Success +import im.vector.riotx.EmojiCompatHelper import im.vector.riotx.R import im.vector.riotx.core.ui.list.genericFooterItem import im.vector.riotx.core.ui.list.genericLoaderItem @@ -52,7 +53,7 @@ class ViewReactionsEpoxyController(private val context: Context) reactionInfoSimpleItem { id(it.eventId) timeStamp(it.timestamp) - reactionKey(EmojiCompat.get().process(it.reactionKey)) + reactionKey(EmojiCompatHelper.safeEmojiSpanify(it.reactionKey)) authorDisplayName(it.authorName ?: it.authorId) } } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt index 0644e9627f..c9bfa2df31 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt @@ -21,7 +21,6 @@ import android.animation.AnimatorSet import android.animation.ObjectAnimator import android.content.Context import android.content.res.TypedArray -import android.graphics.Typeface import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.LayoutInflater @@ -35,7 +34,7 @@ import android.widget.TextView import androidx.annotation.ColorInt import androidx.annotation.ColorRes import androidx.core.content.ContextCompat -import androidx.emoji.text.EmojiCompat +import im.vector.riotx.EmojiCompatHelper import im.vector.riotx.R import im.vector.riotx.core.utils.TextUtils @@ -78,7 +77,7 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut set(value) { field = value //maybe cache this for performances? - val emojiSpanned = EmojiCompat.get().process(value) + val emojiSpanned = EmojiCompatHelper.safeEmojiSpanify(value) emojiView?.text = emojiSpanned } From 35817245cb80ecaf748d68adcc28efe42d60a830 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 29 Aug 2019 17:27:49 +0200 Subject: [PATCH 17/34] refactoring, code review --- ...ojiCompatHelper.kt => EmojiCompatWrapper.kt} | 17 ++++++++--------- .../java/im/vector/riotx/VectorApplication.kt | 6 ++---- .../im/vector/riotx/core/di/ScreenComponent.kt | 3 +++ .../im/vector/riotx/core/di/VectorComponent.kt | 3 +++ .../timeline/action/ViewReactionBottomSheet.kt | 4 +--- .../action/ViewReactionsEpoxyController.kt | 15 ++++++++------- .../features/reactions/widget/ReactionButton.kt | 14 ++++++++++++-- 7 files changed, 37 insertions(+), 25 deletions(-) rename vector/src/main/java/im/vector/riotx/{EmojiCompatHelper.kt => EmojiCompatWrapper.kt} (86%) diff --git a/vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt b/vector/src/main/java/im/vector/riotx/EmojiCompatWrapper.kt similarity index 86% rename from vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt rename to vector/src/main/java/im/vector/riotx/EmojiCompatWrapper.kt index 9e4a6087d1..b183284084 100644 --- a/vector/src/main/java/im/vector/riotx/EmojiCompatHelper.kt +++ b/vector/src/main/java/im/vector/riotx/EmojiCompatWrapper.kt @@ -16,22 +16,21 @@ package im.vector.riotx import android.content.Context +import androidx.appcompat.app.AppCompatActivity import androidx.core.provider.FontRequest import androidx.emoji.text.EmojiCompat import androidx.emoji.text.FontRequestEmojiCompatConfig import timber.log.Timber +import javax.inject.Inject +import javax.inject.Singleton -object EmojiCompatHelper { +@Singleton +class EmojiCompatWrapper @Inject constructor(private val context: Context) { - var initialized = false + private var initialized = false + + fun init(fontRequest: FontRequest) { - fun init(context: Context) { - val fontRequest = FontRequest( - "com.google.android.gms.fonts", - "com.google.android.gms", - "Noto Color Emoji Compat", - R.array.com_google_android_gms_fonts_certs - ) //Use emoji compat for the benefit of emoji spans val config = FontRequestEmojiCompatConfig(context, fontRequest) // we want to replace all emojis with selected font diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt index 36b4d58904..b62c44f58c 100644 --- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt +++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt @@ -19,13 +19,10 @@ package im.vector.riotx import android.app.Application import android.content.Context import android.content.res.Configuration -import android.graphics.Color import android.os.Handler import android.os.HandlerThread import androidx.core.provider.FontRequest import androidx.core.provider.FontsContractCompat -import androidx.emoji.text.EmojiCompat -import androidx.emoji.text.FontRequestEmojiCompatConfig import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent @@ -69,6 +66,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration. @Inject lateinit var authenticator: Authenticator @Inject lateinit var vectorConfiguration: VectorConfiguration @Inject lateinit var emojiCompatFontProvider: EmojiCompatFontProvider + @Inject lateinit var emojiCompatWrapper: EmojiCompatWrapper @Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler @Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var notificationDrawerManager: NotificationDrawerManager @@ -109,7 +107,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration. FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler()) vectorConfiguration.initConfiguration() - EmojiCompatHelper.init(this) + emojiCompatWrapper.init(fontRequest) NotificationUtils.createNotificationChannels(applicationContext) if (authenticator.hasAuthenticatedSessions() && !activeSessionHolder.hasActiveSession()) { diff --git a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt index ffde2bc263..6bfbddbabb 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/ScreenComponent.kt @@ -58,6 +58,7 @@ import im.vector.riotx.features.rageshake.BugReportActivity import im.vector.riotx.features.rageshake.BugReporter import im.vector.riotx.features.rageshake.RageShake import im.vector.riotx.features.reactions.EmojiReactionPickerActivity +import im.vector.riotx.features.reactions.widget.ReactionButton import im.vector.riotx.features.roomdirectory.PublicRoomsFragment import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity import im.vector.riotx.features.roomdirectory.createroom.CreateRoomActivity @@ -181,6 +182,8 @@ interface ScreenComponent { fun inject(displayReadReceiptsBottomSheet: DisplayReadReceiptsBottomSheet) + fun inject(reactionButton: ReactionButton) + @Component.Factory interface Factory { fun create(vectorComponent: VectorComponent, diff --git a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt index d1b87f0b82..7cbbc30673 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt @@ -24,6 +24,7 @@ import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.auth.Authenticator import im.vector.matrix.android.api.session.Session import im.vector.riotx.EmojiCompatFontProvider +import im.vector.riotx.EmojiCompatWrapper import im.vector.riotx.VectorApplication import im.vector.riotx.core.pushers.PushersManager import im.vector.riotx.features.configuration.VectorConfiguration @@ -70,6 +71,8 @@ interface VectorComponent { fun emojiCompatFontProvider(): EmojiCompatFontProvider + fun emojiCompatWrapper() : EmojiCompatWrapper + fun eventHtmlRenderer(): EventHtmlRenderer fun navigator(): Navigator diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionBottomSheet.kt index 9d21c89e2e..83d6178218 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionBottomSheet.kt @@ -46,9 +46,7 @@ class ViewReactionBottomSheet : VectorBaseBottomSheetDialogFragment() { @BindView(R.id.bottom_sheet_display_reactions_list) lateinit var epoxyRecyclerView: EpoxyRecyclerView - private val epoxyController by lazy { - ViewReactionsEpoxyController(requireContext()) - } + @Inject lateinit var epoxyController: ViewReactionsEpoxyController override fun injectWith(screenComponent: ScreenComponent) { screenComponent.inject(this) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt index 3c2ff93ea9..904a2395a0 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/action/ViewReactionsEpoxyController.kt @@ -17,22 +17,23 @@ package im.vector.riotx.features.home.room.detail.timeline.action import android.content.Context -import android.graphics.Typeface -import android.text.format.DateUtils -import androidx.emoji.text.EmojiCompat import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Incomplete import com.airbnb.mvrx.Success -import im.vector.riotx.EmojiCompatHelper +import im.vector.riotx.EmojiCompatWrapper import im.vector.riotx.R +import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.core.ui.list.genericFooterItem import im.vector.riotx.core.ui.list.genericLoaderItem +import javax.inject.Inject /** * Epoxy controller for reaction event list */ -class ViewReactionsEpoxyController(private val context: Context) +class ViewReactionsEpoxyController @Inject constructor( + private val stringProvider: StringProvider, + private val emojiCompatWrapper: EmojiCompatWrapper ) : TypedEpoxyController() { override fun buildModels(state: DisplayReactionsViewState) { @@ -45,7 +46,7 @@ class ViewReactionsEpoxyController(private val context: Context) is Fail -> { genericFooterItem { id("failure") - text(context.getString(R.string.unknown_error)) + text(stringProvider.getString(R.string.unknown_error)) } } is Success -> { @@ -53,7 +54,7 @@ class ViewReactionsEpoxyController(private val context: Context) reactionInfoSimpleItem { id(it.eventId) timeStamp(it.timestamp) - reactionKey(EmojiCompatHelper.safeEmojiSpanify(it.reactionKey)) + reactionKey(emojiCompatWrapper.safeEmojiSpanify(it.reactionKey)) authorDisplayName(it.authorName ?: it.authorId) } } diff --git a/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt index c9bfa2df31..483165ab49 100644 --- a/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/riotx/features/reactions/widget/ReactionButton.kt @@ -34,9 +34,11 @@ import android.widget.TextView import androidx.annotation.ColorInt import androidx.annotation.ColorRes import androidx.core.content.ContextCompat -import im.vector.riotx.EmojiCompatHelper +import im.vector.riotx.EmojiCompatWrapper import im.vector.riotx.R +import im.vector.riotx.core.di.HasScreenInjector import im.vector.riotx.core.utils.TextUtils +import javax.inject.Inject /** * An animated reaction button. @@ -46,6 +48,12 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut defStyleAttr: Int = 0) : FrameLayout(context, attrs, defStyleAttr), View.OnClickListener, View.OnLongClickListener { + init { + if (context is HasScreenInjector) { + context.injector().inject(this) + } + } + companion object { private val DECCELERATE_INTERPOLATOR = DecelerateInterpolator() private val ACCELERATE_DECELERATE_INTERPOLATOR = AccelerateDecelerateInterpolator() @@ -53,6 +61,8 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut } + @Inject lateinit var emojiCompatWrapper: EmojiCompatWrapper + private var emojiView: TextView? = null private var countTextView: TextView? = null @@ -77,7 +87,7 @@ class ReactionButton @JvmOverloads constructor(context: Context, attrs: Attribut set(value) { field = value //maybe cache this for performances? - val emojiSpanned = EmojiCompatHelper.safeEmojiSpanify(value) + val emojiSpanned = emojiCompatWrapper.safeEmojiSpanify(value) emojiView?.text = emojiSpanned } From 47d22a3d5e761277bf72274e91a7ec2918665cdf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 30 Aug 2019 11:21:26 +0200 Subject: [PATCH 18/34] Import translation from Riot and MatrixSDK --- .../src/main/res/values-bg/strings.xml | 5 + .../src/main/res/values-de/strings.xml | 61 + .../src/main/res/values-eu/strings.xml | 5 + .../src/main/res/values-fi/strings.xml | 5 + .../src/main/res/values-fr/strings.xml | 5 + .../src/main/res/values-hu/strings.xml | 5 + .../src/main/res/values-it/strings.xml | 5 + .../src/main/res/values-ko/strings.xml | 169 +- .../src/main/res/values-nl/strings.xml | 5 + .../src/main/res/values-pl/strings.xml | 41 +- .../src/main/res/values-pt/strings.xml | 6 + .../src/main/res/values-ru/strings.xml | 9 +- .../src/main/res/values-sk/strings.xml | 91 ++ .../src/main/res/values-sq/strings.xml | 22 + .../src/main/res/values-vls/strings.xml | 23 +- .../src/main/res/values-zh-rCN/strings.xml | 5 + .../src/main/res/values-zh-rTW/strings.xml | 5 + vector/src/main/res/values-bg/strings.xml | 15 +- vector/src/main/res/values-ca/strings.xml | 213 ++- vector/src/main/res/values-de/strings.xml | 111 +- vector/src/main/res/values-eu/strings.xml | 15 +- vector/src/main/res/values-fi/strings.xml | 81 +- vector/src/main/res/values-fr/strings.xml | 15 +- vector/src/main/res/values-hu/strings.xml | 15 +- vector/src/main/res/values-it/strings.xml | 15 +- vector/src/main/res/values-ko/strings.xml | 1423 ++++++++++++++++- vector/src/main/res/values-nl/strings.xml | 14 +- vector/src/main/res/values-pl/strings.xml | 30 +- vector/src/main/res/values-ru/strings.xml | 137 +- vector/src/main/res/values-sq/strings.xml | 49 +- vector/src/main/res/values-vls/strings.xml | 9 + vector/src/main/res/values-zh-rTW/strings.xml | 13 + vector/src/main/res/values/strings.xml | 13 + vector/src/main/res/values/strings_riotX.xml | 1 - 34 files changed, 2542 insertions(+), 94 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-bg/strings.xml b/matrix-sdk-android/src/main/res/values-bg/strings.xml index 743f38e649..85643c7ade 100644 --- a/matrix-sdk-android/src/main/res/values-bg/strings.xml +++ b/matrix-sdk-android/src/main/res/values-bg/strings.xml @@ -167,4 +167,9 @@ Начална синхронизация: \nИмпортиране на данни за профила + %s обнови тази стая. + + Изпращане на съобщение… + Изчисти опашката за изпращане + diff --git a/matrix-sdk-android/src/main/res/values-de/strings.xml b/matrix-sdk-android/src/main/res/values-de/strings.xml index 3c1b61b378..3f37ec35f6 100644 --- a/matrix-sdk-android/src/main/res/values-de/strings.xml +++ b/matrix-sdk-android/src/main/res/values-de/strings.xml @@ -105,4 +105,65 @@ Schwein Elefant Hase + %s hat diesen Raum aufgewertet. + + Panda + Hahn + Pinguin + Schildkröte + Fisch + Tintenfisch + Schmetterling + Blume + Baum + Kaktus + Pilz + Globus + Mond + Wolke + Feuer + Banane + Apfel + Erdbeere + Mais + Kuchen + Herz + Lächeln + Roboter + Hut + Brille + Schraubenschlüssel + Nikolaus + Daumen hoch + Regenschirm + Sanduhr + Uhr + Geschenk + Glühbirne + Buch + Stift + Büroklammer + Scheren + sperren + Schlüssel + Hammer + Telefon + Flagge + Zug + Fahrrad + Flugzeug + Rakete + Pokal + Ball + Gitarre + Trompete + Glocke + Anker + Kopfhörer + Ordner + Stecknadel + + Sende eine Nachricht… + Sendewarteschlange leeren + diff --git a/matrix-sdk-android/src/main/res/values-eu/strings.xml b/matrix-sdk-android/src/main/res/values-eu/strings.xml index 5339cf012f..25e0df10f4 100644 --- a/matrix-sdk-android/src/main/res/values-eu/strings.xml +++ b/matrix-sdk-android/src/main/res/values-eu/strings.xml @@ -167,4 +167,9 @@ Hasierako sinkronizazioa: \nKontuaren datuak inportatzen + %s erabiltzaileak gela hau eguneratu du. + + Mezua bidaltzen… + Garbitu bidalketa-ilara + diff --git a/matrix-sdk-android/src/main/res/values-fi/strings.xml b/matrix-sdk-android/src/main/res/values-fi/strings.xml index 2f3e73c720..1cfc499380 100644 --- a/matrix-sdk-android/src/main/res/values-fi/strings.xml +++ b/matrix-sdk-android/src/main/res/values-fi/strings.xml @@ -168,4 +168,9 @@ Alkusynkronointi: \nTuodaan tilin tietoja + %s päivitti tämän huoneen. + + Lähetetään viestiä… + Tyhjennä lähetysjono + diff --git a/matrix-sdk-android/src/main/res/values-fr/strings.xml b/matrix-sdk-android/src/main/res/values-fr/strings.xml index 5d211e0145..9541555d75 100644 --- a/matrix-sdk-android/src/main/res/values-fr/strings.xml +++ b/matrix-sdk-android/src/main/res/values-fr/strings.xml @@ -167,4 +167,9 @@ Synchronisation initiale : \nImportation des données du compte + %s a mis à niveau ce salon. + + Envoi du message… + Vider la file d’envoi + diff --git a/matrix-sdk-android/src/main/res/values-hu/strings.xml b/matrix-sdk-android/src/main/res/values-hu/strings.xml index b183a1b4a9..e3d4e88c60 100644 --- a/matrix-sdk-android/src/main/res/values-hu/strings.xml +++ b/matrix-sdk-android/src/main/res/values-hu/strings.xml @@ -166,4 +166,9 @@ Induló szinkronizáció: \nFiók adatok betöltése + %s frissítette ezt a szobát. + + Üzenet küldése… + Küldő sor ürítése + diff --git a/matrix-sdk-android/src/main/res/values-it/strings.xml b/matrix-sdk-android/src/main/res/values-it/strings.xml index 3f067c2a88..1edc038175 100644 --- a/matrix-sdk-android/src/main/res/values-it/strings.xml +++ b/matrix-sdk-android/src/main/res/values-it/strings.xml @@ -167,4 +167,9 @@ Sync iniziale: \nImportazione dati account + %s ha aggiornato questa stanza. + + Invio messaggio in corso … + Cancella la coda di invio + diff --git a/matrix-sdk-android/src/main/res/values-ko/strings.xml b/matrix-sdk-android/src/main/res/values-ko/strings.xml index faf1840a8d..30145e31a3 100644 --- a/matrix-sdk-android/src/main/res/values-ko/strings.xml +++ b/matrix-sdk-android/src/main/res/values-ko/strings.xml @@ -1,6 +1,173 @@ %1$s: %2$s - %s\'의 초대 + %s님의 초대 헤드폰 + %1$s님이 사진을 보냈습니다. + %1$s님이 스티커를 보냈습니다. + + %1$s님이 %2$s님을 초대했습니다 + %1$s님이 당신을 초대했습니다 + %1$s님이 참가했습니다 + %1$s님이 떠났습니다 + %1$s님이 초대를 거부했습니다 + %1$s님이 %2$s님을 추방했습니다 + %1$s님이 %2$s님의 차단을 풀었습니다 + %1$s님이 %2$s님을 차단했습니다 + %1$s님이 %2$s님의 초대를 취소했습니다 + %1$s님이 아바타를 변경했습니다 + %1$s님이 표시 이름을 %2$s(으)로 설정했습니다 + %1$s님이 표시 이름을 %2$s에서 %3$s(으)로 변경했습니다 + %1$s님이 표시 이름을 삭제했습니다 (%2$s) + %1$s님이 주제를 다음으로 변경했습니다: %2$s + %1$s님이 방 이름을 다음으로 변경했습니다: %2$s + %s님이 영상 통화를 걸었습니다. + %s님이 음성 통화를 걸었습니다. + %s님이 전화를 받았습니다. + %s님이 전화를 끊었습니다. + %1$s님이 이후 %2$s에게 방 기록을 공개했습니다 + 초대된 시점부터 모든 방 구성원. + 들어온 시점부터 모든 방 구성원. + 모든 방 구성원. + 누구나. + 알 수 없음 (%s). + %1$s님이 종단 간 암호화를 켰습니다 (%2$s) + %s님이 방을 업그레이드했습니다. + + %1$s님이 VoIP 회의를 요청했습니다 + VoIP 회의가 시작했습니다 + VoIP 회의가 끝났습니다 + + (아바타도 변경됨) + %1$s님이 방 이름을 삭제했습니다 + %1$s님이 방 주제를 삭제했습니다 + 메시지가 삭제되었습니다 + 메시지가 %1$s님에 의해 삭제되었습니다 + 메시지가 삭제되었습니다 [이유: %1$s] + 메시지가 %1$s님에 의해 삭제되었습니다 [이유: %2$s] + %1$s님이 프로필 %2$s을(를) 업데이트했습니다 + %1$s님이 %2$s님에게 방 초대를 보냈습니다 + %1$s님이 %2$s의 초대를 수락했습니다 + + ** 암호를 해독할 수 없음: %s ** + 발신인의 기기에서 이 메시지의 키를 보내지 않았습니다. + + 이 답장의 질문 + + 검열할 수 없습니다 + 메시지를 보낼 수 없습니다 + + 사진 업로드에 실패했습니다 + + 네트워크 오류 + Matrix 오류 + + 현재 빈 방에 다시 들어갈 수 없습니다. + + 암호화된 메시지 + + 이메일 주소 + 전화번호 + + 사진을 보냈습니다. + 동영상을 보냈습니다. + 오디오 파일을 보냈습니다. + 파일을 보냈습니다. + + %s에서 초대함 + 방 초대 + + %1$s님과 %2$s님 + + + %1$s님 외 %2$d명 + + + 빈 방 + + + + 고양이 + 사자 + + 유니콘 + 돼지 + 코끼리 + 토끼 + 판다 + 수탉 + 펭귄 + 거북 + 물고기 + 문어 + 나비 + + 나무 + 선인장 + 버섯 + 지구본 + + 구름 + + 바나나 + 사과 + 딸기 + 옥수수 + 피자 + 케이크 + 하트 + 웃음 + 로봇 + 모자 + 안경 + 스패너 + 산타클로스 + 좋아요 + 우산 + 모래시계 + 시계 + 선물 + 전구 + + 연필 + 클립 + 가위 + 자물쇠 + 열쇠 + 망치 + 전화기 + 깃발 + 기차 + 자전거 + 비행기 + 로켓 + 트로피 + + 기타 + 트럼펫 + + + 폴더 + + + 초기 동기화: +\n계정 가져오는 중… + 초기 동기화: +\n암호 가져오는 중 + 초기 동기화: +\n방 가져오는 중 + 초기 동기화: +\n들어간 방 가져오는 중 + 초기 동기화: +\n초대받은 방 가져오는 중 + 초기 동기화: +\n떠난 방 가져오는 중 + 초기 동기화: +\n커뮤니티 가져오는 중 + 초기 동기화: +\n계정 데이터 가져오는 중 + + 메시지 보내는 중… + 전송 대기 열 지우기 + diff --git a/matrix-sdk-android/src/main/res/values-nl/strings.xml b/matrix-sdk-android/src/main/res/values-nl/strings.xml index b46b79ea0e..c2d524e486 100644 --- a/matrix-sdk-android/src/main/res/values-nl/strings.xml +++ b/matrix-sdk-android/src/main/res/values-nl/strings.xml @@ -176,4 +176,9 @@ Initiële synchronisatie: \nAccountgegevens worden geïmporteerd + %s heeft dit gesprek opgewaardeerd. + + Bericht wordt verstuurd… + Uitgaande wachtrij legen + diff --git a/matrix-sdk-android/src/main/res/values-pl/strings.xml b/matrix-sdk-android/src/main/res/values-pl/strings.xml index 4a807028f3..4e1d256788 100644 --- a/matrix-sdk-android/src/main/res/values-pl/strings.xml +++ b/matrix-sdk-android/src/main/res/values-pl/strings.xml @@ -7,7 +7,7 @@ %1$s zaprosił(a) %2$s %1$s zaprosił(a) Cię %1$s dołączył(a) - %1$s wyszedł(-ła) + %1$s opuścił(a) %1$s odrzucił(a) zaproszenie %1$s wyrzucił(a) %2$s %1$s odblokował(a) %2$s @@ -17,11 +17,11 @@ %1$s zmienił(a) wyświetlaną nazwę z %2$s na %3$s %1$s usunął(-ęła) swoją wyświetlaną nazwę (%2$s) %1$s zmienił(a) temat na: %2$s - Nie udało się wysłać wiadomości + Nie można wysłać wiadomości - Nie udało się wysłać zdjęcia + Przesyłanie zdjęcia nie powiodło się - ogólne błędy + Błąd sieci Błąd Matrixa Wiadomość zaszyfrowana @@ -31,7 +31,7 @@ wszyscy członkowie pokoju. wszyscy. - %1$s zmienił(a) znawę pokoju na: %2$s + %1$s zmienił(a) nazwę pokoju na: %2$s %s zakończył(a) rozmowę. %1$s usunął(-ęła) nazwę pokoju %1$s usunął(-ęła) temat pokoju @@ -57,9 +57,9 @@ ** Nie można odszyfrować: %s ** - %s umieścił wideo rozmowe. - %s umieścił połączenie głosowe. - %1$s uczynił historię pokoju widoczną do %2$s + %s wykonał(a) rozmowę wideo. + %s wykonał(a) połączenie głosowe. + %1$s uczynił(a) przyszłą historię pokoju widoczną dla %2$s wszyscy członkowie pokoju, od momentu w którym zostali zaproszeni. wszyscy członkowie pokoju, od momentu w którym dołączyli. nieznane (%s). @@ -147,4 +147,29 @@ Mikołaj Prezent Młotek + %s zakutalizował(a) ten pokój. + + Kciuk w górę + Zamek + Piłka + Synchronizacja początkowa: +\nImportowanie konta… + Synchronizacja początkowa: +\nImportowanie kryptografii + Synchronizacja początkowa: +\nImportowanie Pokoi + Synchronizacja początkowa: +\nImportowanie dołączonych Pokoi + Synchronizacja początkowa: +\nImportowanie zaproszonych Pokoi + Synchronizacja początkowa: +\nImportowanie opuszczonych Pokoi + Synchronizacja początkowa: +\nImportowanie Społeczności + Synchronizacja początkowa: +\nImportowanie danych Konta + + Wysyłanie wiadomości… + Wyczyść kolejkę wysyłania + diff --git a/matrix-sdk-android/src/main/res/values-pt/strings.xml b/matrix-sdk-android/src/main/res/values-pt/strings.xml index adfed47e96..4bc90cf0cb 100644 --- a/matrix-sdk-android/src/main/res/values-pt/strings.xml +++ b/matrix-sdk-android/src/main/res/values-pt/strings.xml @@ -78,4 +78,10 @@ Sala vazia + %1$s enviou um sticker. + + %s fez o upgrade da sala. + + Mensagem removida + Mensagem removida por %1$s diff --git a/matrix-sdk-android/src/main/res/values-ru/strings.xml b/matrix-sdk-android/src/main/res/values-ru/strings.xml index 4563fa89f7..e0637ea671 100644 --- a/matrix-sdk-android/src/main/res/values-ru/strings.xml +++ b/matrix-sdk-android/src/main/res/values-ru/strings.xml @@ -169,9 +169,9 @@ \nИмпорт криптографии Начальная синхронизация: \nИмпорт комнат - Начальная синхронизация: + Синхронизация начата: \nИмпорт присоединенных комнат - Начальная синхронизация: + Синхронизация начата: \nИмпорт приглашенных комнат Начальная синхронизация: \nИмпорт покинутых комнат @@ -180,4 +180,9 @@ Начальная синхронизация: \nИмпорт данных учетной записи + %s обновил эту комнату. + + Отправка сообщения… + Очистить очередь отправки + diff --git a/matrix-sdk-android/src/main/res/values-sk/strings.xml b/matrix-sdk-android/src/main/res/values-sk/strings.xml index b7e9bb411a..d5c7d95fd6 100644 --- a/matrix-sdk-android/src/main/res/values-sk/strings.xml +++ b/matrix-sdk-android/src/main/res/values-sk/strings.xml @@ -82,4 +82,95 @@ + %s aktualizoval túto miestnosť. + + Správa odstránená + Správa odstránená používateľom %1$s + Správa odstránená [dôvod: %1$s] + Správa odstránená používateľom %1$s [dôvod: %2$s] + Pes + Mačka + Lev + Kôň + Jednorožec + Prasa + Slon + Zajac + Panda + Kohút + Tučniak + Korytnačka + Ryba + Chobotnica + Motýľ + Kvetina + Strom + Kaktus + Hríb + Zemeguľa + Mesiac + Oblak + Oheň + Banán + Jablko + Jahoda + Kukurica + Pizza + Koláč + Srdce + Úsmev + Robot + Klobúk + Okuliare + Skrutkovač + Mikuláš + Palec nahor + Dáždnik + Presýpacie hodiny + Hodiny + Darček + Žiarovka + Kniha + Ceruzka + Kancelárska sponka + Nožnice + Zámok + Kľúč + Kladivo + Telefón + Vlajka + Vlak + Bicykel + Lietadlo + Raketa + Trofej + Lopta + Gitara + Trúbka + Zvonček + Kotva + Schlúchadlá + Priečinok + Pin + + Úvodná synchronizácia: +\nPrebieha import účtu… + Úvodná synchronizácia: +\nPrebieha import šifrovacích kľúčov + Úvodná synchronizácia: +\nPrebieha import miestností + Úvodná synchronizácia: +\nPrebieha import miestností, do ktorých ste vstúpili + Úvodná synchronizácia: +\nPrebieha import pozvánok + Úvodná synchronizácia: +\nPrebieha import opustených miestností + Úvodná synchronizácia: +\nPrebieha import komunít + Úvodná synchronizácia: +\nPrebieha import údajov účtu + + Odosielanie správy… + Vymazať správy na odoslanie + diff --git a/matrix-sdk-android/src/main/res/values-sq/strings.xml b/matrix-sdk-android/src/main/res/values-sq/strings.xml index 7c182df3f0..03d5df2b81 100644 --- a/matrix-sdk-android/src/main/res/values-sq/strings.xml +++ b/matrix-sdk-android/src/main/res/values-sq/strings.xml @@ -146,4 +146,26 @@ Spirancë Kufje Dosje + %s e përmirësoi këtë dhomë. + + Njëkohësimi Fillestar: +\nPo importohet llogaria… + Njëkohësimi Fillestar: +\nPo importohet kriptografi + Njëkohësimi Fillestar: +\nPo importohen Dhoma + Njëkohësimi Fillestar: +\nPo importohen Dhoma Ku Është Bërë Hyrje + Njëkohësimi Fillestar: +\nPo importohen Dhoma Me Ftesë + Njëkohësimi Fillestar: +\nPo importohen Dhoma të Braktisura + Njëkohësimi Fillestar: +\nPo importohen Bashkësi + Njëkohësimi Fillestar: +\nPo importohet të Dhëna Llogarie + + Po dërgohet mesazh… + Spastro radhë pritjeje + diff --git a/matrix-sdk-android/src/main/res/values-vls/strings.xml b/matrix-sdk-android/src/main/res/values-vls/strings.xml index 29e66940a3..eb533e15a0 100644 --- a/matrix-sdk-android/src/main/res/values-vls/strings.xml +++ b/matrix-sdk-android/src/main/res/values-vls/strings.xml @@ -48,7 +48,7 @@ %1$s èt d’uutnodigienge vo %2$s anveird ** Kun nie ountsleuteln: %s ** - ’t Toestel van den afzender èt geen sleutels vo dit bericht gesteurd. + ’t Toestel van den afzender èt geen sleutels vo da bericht hier gesteurd. Als antwoord ip @@ -150,21 +150,26 @@ Mappe Pinne - Initiële synchronisoatie: + Initiële synchronisoasje: \nAccount wor geïmporteerd… - Initiële synchronisoatie: + Initiële synchronisoasje: \nCrypto wor geïmporteerd - Initiële synchronisoatie: + Initiële synchronisoasje: \nGesprekkn wordn geïmporteerd - Initiële synchronisoatie: + Initiële synchronisoasje: \nDeelgenoomn gesprekken wordn geïmporteerd - Initiële synchronisoatie: + Initiële synchronisoasje: \nUutgenodigde gesprekkn wordn geïmporteerd - Initiële synchronisoatie: + Initiële synchronisoasje: \nVerloatn gesprekkn wordn geïmporteerd - Initiële synchronisoatie: + Initiële synchronisoasje: \nGemeenschappn wordn geïmporteerd - Initiële synchronisoatie: + Initiële synchronisoasje: \nAccountgegeevns wordn geïmporteerd + %s èt da gesprek hier ipgewoardeerd. + + Bericht wor verstuurd… + Uutgoande wachtreeke leegn + diff --git a/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml b/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml index 70c990895b..3aed8858a3 100644 --- a/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml +++ b/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml @@ -162,4 +162,9 @@ 初始化同步: \n正在导入账号数据 + %s 升级了聊天室。 + + 正在发送消息… + 清除正在发送队列 + diff --git a/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml b/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml index 0a8f0b45f4..e0e66a80a0 100644 --- a/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml +++ b/matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml @@ -165,4 +165,9 @@ 初始化同步: \n正在匯入帳號資料 + %s 已升級此聊天室。 + + 正在傳送訊息…… + 清除傳送佇列 + diff --git a/vector/src/main/res/values-bg/strings.xml b/vector/src/main/res/values-bg/strings.xml index 7f93b37abc..d8570ef0a4 100644 --- a/vector/src/main/res/values-bg/strings.xml +++ b/vector/src/main/res/values-bg/strings.xml @@ -326,7 +326,7 @@ Съобщенията не са изпратени. %1$s или %2$s? Съобщението не е изпратено поради наличието на непознати устройства. %1$s или %2$s? Изпрати всички отново - откажи всички + Откажи всички Изпрати отново неизпратените съобщения Изтрий неизпратените съобщения Файлът не е намерен @@ -1600,4 +1600,17 @@ Връзката беше копирана + Мениджър на интеграции + + Не е конфигуриран мениджър на интеграции. + Добави по Matrix идентификатор + Създаване на стая… + Не са намерени резултати, използва \"Добави по Matrix идентификатор\" за търсене на сървъра. + Започнете да пишете, за да получите резултати + Филтрирай по потребител или ID… + + Присъединяване в стая… + + Виж историята на редакциите + diff --git a/vector/src/main/res/values-ca/strings.xml b/vector/src/main/res/values-ca/strings.xml index a73b7991af..ca7a2287b5 100644 --- a/vector/src/main/res/values-ca/strings.xml +++ b/vector/src/main/res/values-ca/strings.xml @@ -12,7 +12,7 @@ Tema negre - Sincronitzant + S\'està sincronitzant… Escolta esdeveniments Notificacions sorolloses Notificacions silencioses @@ -46,9 +46,10 @@ Reanomena Informa del contingut Trucada activa - " Conferència en curs.\nUniu-vos hi per %1$s o %2$s." - veu - vídeo + Conferència en curs. +\nUniu-vos hi per %1$s o %2$s. + Veu + Vídeo La trucada no es pot iniciar, prova-ho més tard Pot ser que algunes funcions no apareguin per manca de permisos… Es necessiten permisos per convidar a iniciar una conferència en aquesta sala @@ -84,11 +85,11 @@ Sales - Cerca sales - Cerca preferits - Cerca persones - Cerca sales - Cerca comunitats + Filtrar noms de sales + Filtrar preferits + Filtrar persones + Filtrar per noms de sala + Filtrar per nom de comunitats Convida @@ -137,7 +138,7 @@ Uneix-te a la sala Nom d\'usuari - Registra\'m + Crear un compte Entra Desconnecta URL del servidor @@ -235,7 +236,7 @@ - "Envia com " + Envia com Original Gran Mitjana @@ -283,7 +284,9 @@ Per tal de fer trucades de veu, el Riot necessita permís d\'accés al microfon. \n\nA la següent finestra emergent, doneu permís d\'accés per tal de poder fer la trucada. Per tal de fer vídeotrucades, el Riot necessita permís d\'accés a la càmera i al microfon.\n\nA la següent finestra emergent, doneu permís d\'accés per tal de poder fer la trucada. - Per tal de trobar altres usuaris de Matrix a partir dels seus correus electrònics o dels seus números de telefon, el Riot necessita permís d\'accés a l\'agenda de contactes.\n\nA la següent finestra emergent, doneu permís d\'accés per trobar amb quins contactes de la teva agenda pots contactar a partir de Riot. + Riot pot comprovar la vostra agenda de contactes per tal de trobar altres usuaris de Matrix basant-se en les seves adreces de correu i números de telèfon. +\n +\nSi accepteu compartir la vostra agenda de contactes amb aquesta finalitat, si us plau permeteu l\'accés de la següent finestra emergent. Per tal de trobar altres usuaris de Matrix a partir dels seus correus electrònics o dels seus números de telefon, el Riot necessita permís d\'accés a l\'agenda de contactes.\n\nPermeteu que Riot accedeixi als vostres contactes? No s\'ha realitzat l\'acció per falta de permisos @@ -370,7 +373,7 @@ Els missatges no s\'han enviat. %1$s o %2$s ara? Els missatges no s\'han enviat perquè hi ha disposistius desconeguts. %1$s o %2$s ara? Reenvia-ho tot - cancel·la-ho tot + Cancel·la-ho tot Reenvia els missatges no enviats Elimina els missatges no enviats No s\'ha trobat el fitxer @@ -542,9 +545,9 @@ Tingueu en compte que aquesta acció reiniciarà l\'aplicació i que pot trigar Aquest número de telèfon ja està en ús. Canvia la contrasenya - Contrasenya antiga + Contrasenya actual Contrasenya nova - Confirmeu la contrasenya + Confirmeu la nova contrasenya No s\'ha pogut actualitzar la contrasenya La contrasenya s\'ha actualitzat Mostra tots els missatges des de %s? @@ -889,7 +892,7 @@ Atenció: es podria eliminar aquest fitxer si es desinstal·la l\'aplicació.Si us plau, engega Riot a un altre dispositiu que pugui desencriptar el missatge de manera que pugui enviar la clau a aquest dispositiu. Normal - Motiu Status.im + Tema Status.im Manquen permisos per a dur a terme aquesta acció. Error @@ -924,7 +927,7 @@ En voleu afegir algun? Mostrar tots els missatges d\'aquest usuari? Tingueu en compte que aquesta acció reiniciarà l\'aplicació i pot trigar una estona. - "%1$s, " + "%1$s,· " %1$s i %2$s %1$s %2$s @@ -938,7 +941,7 @@ Tingueu en compte que aquesta acció reiniciarà l\'aplicació i pot trigar una Notificació de privacitat Privacitat reduïda L\'aplicació necessita permisos per funcionar en segon pla - • Les notificacions s\'envien via Google Cloud Messaging + • Les notificacions s\'envien via Firebase Cloud Messaging • Les notificacions contenen només meta dades • El contingut dels missatges de les notificacions s\'obté de forma segura des del servidor de Matrix • Les notificacions contenen meta dades i dades de missatges @@ -1246,7 +1249,7 @@ Aquest error és fora del control del Riot. No hi ha cap compte de Google al tel Les restriccions de rerefons són habilitades per al Riot. Les tasques que l\'aplicació intenta fer estaran restringides agressivament mentre estigui al rerefons, i això pot afectar les notificacions. %1$s - "Si un usuari deixa un dispositiu sense endollar i immòbil durant un període de temps, amb la pantalla apagada, el dispositiu entra en el mode Doze. Això impedeix les aplicacions d\'accedir a la xarxa i ajorna les seves tasques, sincronitzacions i alarmes estàndard. " + Si un usuari deixa un dispositiu sense endollar i immòbil durant un període de temps, amb la pantalla apagada, el dispositiu entra en el mode d\'estalvi d\'energia. Això impedeix les aplicacions d\'accedir a la xarxa i ajorna les seves tasques, sincronitzacions i alarmes estàndard. "Una aplicació de xat, sota el vostre control i totalment flexible. El Riot us permet comunicar-vos de la manera que preferiu. Fet per al [matrix] - l’estàndard per a la comunicació oberta i descentralitzada. Obteniu un compte gratuït de matrix.org, executeu el vostre servidor propi a https://modular.im, o empreu un altre servidor de Matrix. @@ -1385,7 +1388,7 @@ Per què triar Riot.im? Inicialitzar servei Ignorar - Registrar-se amb Single Sign-on + Iniciar sessió amb Single Sign-on Aquesta URL no està disponible , si us plau verifiqueu-la El vostre dispositiu està usant una versió obsoleta del protocol de seguretat TLS, vulnerable a atacs. Per a la vostra seguretat no us podreu connectar Envieu un missatge amb Enter @@ -1403,4 +1406,174 @@ Per què triar Riot.im? Resposta no vàlida en descobrir homeservers Usar Config + Verificar dispositiu + + Marcar com a llegit + Les app no necessita connectar-se al HomeServer en segon pla, hauria de reduir el consum de bateria + Administrador d\'integracions + + Reproduir el so de disparador + + IP desconeguda + + %1$s: 1 missatge + %1$s: %2$d missatges + + + %d notificacion + %d notificacions + + + Nou esdeveniment + Sala + Missatges nous + Nova invitació + Jo + ** Error en enviar - Si us plau obriu la sala + + Ho sentim, els dispositius amb SO Android inferior a 5.0 no suporten trucades multi-usuari amb Jitsi + + No heu configurat cap administrador d\'integracions. + Un nou dispositiu està sol·licitant claus d\'encriptació. +\nNom del dispositiu: %1$s +\nVist per última vegada: %s$s +\nSi no heu iniciat sessió en un altre dispositiu, ignoreu la sol·licitud. + Un dispositiu no verificat està sol·licitant claus d\'encriptació. +\nNom del dispositiu: %1$s +\nVist per última vegada: %s$s +\nSi no heu iniciat sessió en un altre dispositiu, ignoreu la sol·licitud. + + Verificar + Compartir + Sol·licitud de compartició de clau + Ignorar + + Ja existeix una còpia de seguretat al vostre HomeServer + Sembla que ja heu configurat una còpia de seguretat de claus des d\'un altre dispositiu. Voleu reemplaçar-la amb la que esteu creant\? + Reemplaçar + Aturar + + Comprovant l\'estat de la còpia de seguretat + Opcions d\'autocompleció del servidor + Riot ha detectat una configuració de servidor personalitzat pel domini del seu identificador d\'usuari \"%1$s\": +\n%2$s + Us heu desconnectat a causa de credencials incorrectes o caducades. + + Verificar comparant una cadena de text curta. + Per la màxima seguretat us recomanem fer això en persona o usar un altre medi de comunicació confiable. + Començar la verificació + Sol·licitud de verificació entrant + Verificar aquest dispositiu per marcar-lo com a confiable. Confiar en dispositius d\'amistats us dona un alleujament addicional quan useu missatges encriptats end-to-end. + Verificant aquest dispositiu el marcareu com a confiable, i també marcareu el vostre dispositiu com a confiable pel vostre company. + + Verificar aquest dispositiu confirmant els següents emojis que apareguin a la pantalla del vostre company + Verificar aquest dispositiu confirmant els següents números que sortiran a la pantalla del vostre company + + Heu rebut una sol·licitud de verificació entrant. + Veure sol·licitud + Esperant que el vostre company confirmi… + + Verificat! + Heu verificat aquest dispositiu amb èxit. + Els missatges segurs amb aquest usuari estan encriptats end-to-end i no serà possible llegir-los per tercers. + Entesos + + No surt res\? Encara no tots els clients suporten la verificació interactiva. Useu el mètode de verificació antic. + Useu el mètode antic de verificació. + + Verificació de clau + Sol·licitud cancel·lada + L\'altre part ha cancel·lat la verificació. +\n%s + S\'ha cancel·lat la verificació. +\nMotiu: %s + + Verificació de dispositiu interactiva + Sol·licitud de verificació + %s vol verificar el vostre dispositiu + + L\'usuari ha cancel·lat la verificació + El marge de temps pel procés de verificació ha expirat + El dispositiu no coneix la transacció + El dispositiu no pot acceptar un acord de claus amb mètodes hash, MAC o SAS + El compromís del hash no ha coincidit + El SAS no ha coincidit + El dispositiu ha rebut un missatge inesperat + S\'ha rebut un missatge invàlid + La clau no coincideix + L\'usuari no coincideix + Error desconegut + + + Editar + Respondre + + Tornar-ho a provar + Unir-se a una sala per començar usant l\'app. + Se t\'ha enviat una invitació + Convidat per %s + + Esteu al dia! + No teniu més missatges sense llegir + Benvingut a casa! + Posar-se al dia dels missatges sense llegir + Converses + Els vostres missatges directes es mostraran aquí + Sales + Les vostres sales es mostraran aquí + + Reaccions + Confirmar + M\'agrada + Afegir reacció + Veure reaccions + Reaccions + + Esdeveniment eliminat per l\'usuari + Esdeveniment moderat per l\'administrador de la sala + Última edició per %s el %s + + + Esdeveniment mal format, no es pot mostrar + Crear sala nova + No hi ha xarxa. Si us plau comproveu la vostra connexió a internet. + Canviar + Canviar de xarxa + Espereu, si us plau… + Totes les comunitats + + Aquesta sala no es pot pre-visualitzar + RiotX encara no suporta la pre-visualització de sales llegibles per tothom + + Sales + Missatges directes + + Sala nova + CREAR + Nom de la sala + Públic + Qualsevol podrà unir-se a aquesta sala + Directori de sales + Publicar aquesta sala al directori de sales + + Hi ha hagut un error rebent informació de confança + Hi ha hagut un error rebent dades de la còpia de seguretat de les claus + + Benvinguts a la beta! + Mentre RiotX estigui en les primeres etapes de desenvolupament, faltaran algunes funcions i podríeu experimentar alguns errors. + L\'última llista de característiques està sempre a %1$s, i si trobeu errors si us plau reporteu informe des de la part superior esquerra del menú d\'Inici, i el resoldrem tan aviat com puguem. + Descripció de la Play Store + Si trobeu errors si us plau envieu un informe d\'errors des de la part superior esquerra del menú d\'Inici, i el resoldrem tan aviat com puguem. + + Importar claus e2e des del fitxer \"%1$s\". + + Versió de l\'SDK de Matrix + Ja esteu veient aquesta sala! + + Reaccions ràpides + + General + Preferències + Seguretat i privadesa + Expert diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 912063a6ad..313ead3a27 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -210,7 +210,7 @@ Du wurdest auf allen Geräten abgemeldet und wirst keine Push-Benachrichtigungen - "Sende als " + Sende als Original Groß Mittel @@ -1551,4 +1551,113 @@ Wenn du diese neue Wiederherstellungsmethode nicht eingerichtet hast, kann ein A Raumverzeichnis Veröffentliche diesen Raum ins Raumverzeichnis + Integrationsmanager + + Kein Integrationsmanager konfiguriert. + Schlüsselfreigabe Anfordern + Es sieht so aus, als hätten Sie bereits ein Setup-Schlüssel-Backup von einem anderen Gerät. Möchten Sie es durch das ersetzen, das Sie gerade erstellen\? + Für maximale Sicherheit empfehlen wir, dies persönlich zu tun oder ein anderes vertrauenswürdiges Kommunikationsmittel zu verwenden. + Überprüfen Sie dieses Gerät, um es als vertrauenswürdig zu markieren. Das Vertrauen auf Geräte von Partnern gibt Ihnen zusätzliche Sicherheit, wenn Sie verschlüsselte End-to-End-Nachrichten verwenden. + Das Verifizieren dieses Benutzers wird seine Geräte als \"vertraut\" markieren und dein Gerät bei ihnen als \"vertraut\" markieren. + + Verifizieren Sie diesen Benutzer, indem Sie bestätigen, dass folgendes Emoji auf dessen Bildschirm erscheint. + Verifizieren Sie diesen Benutzer, indem Sie bestätigen, dass die folgende Nummer auf dessen Bildschirm erscheint. + + Es ist nichts aufgetaucht\? Noch nicht alle Clients unterstützen die interaktive Verifikation. . + Verwenden Sie die Alte-Überprüfung + + Das Gerät kennt diese Transaktion nicht + Die Hash-Verpflichtung stimmte nicht überein + Die SAS stimmte nicht überein + Wiederherstellungsschlüssel passt nicht + Der Benutzer Wiederherstellungsschlüssel passt nicht + Informieren Sie sich hier über ungelesene Nachrichten + Ihre direkte Konversation wird hier angezeigt + Fehlerhaftes Ereignis, kann nicht angezeigt werden + Beim Abrufen der Vertrauensinformationen ist ein Fehler aufgetreten + Beim Abrufen der Schlüsselsicherungsdaten ist ein Fehler aufgetreten + + Willkommen in der Beta! + Während sich RiotX in der frühen Entwicklung befindet, fehlen möglicherweise einige Funktionen und es können Fehler auftreten. + Play Store Beschreibung + Matrix SDK Version + Sonstige Hinweise Dritter + Sie sehen diesen Raum bereits! + + Schnelle Reaktionen + + Allgemein + Einstellungen + Sicherheit & Privatsphäre + Experte + Push-Regeln + Keine Push-Regeln definiert + Keine registrierten Push-Gateways + + Sprache & Video + Hilfe & Über + + + Token registrieren + + Mache einen Vorschlag + Bitte schreiben Sie Ihren Vorschlag unten. + Beschreiben Sie hier Ihren Vorschlag + Versteckte Ereignisse in der Zeitleiste anzeigen + + Direkte Nachrichten + + Warten… + Miniaturbild wird verschlüsselt… + Datei wird verschlüsselt… + (bearbeitet) + + Nachrichtenbearbeitung + Keine Änderungen gefunden + + Gespräche filtern… + Senden Sie eine neue Direktnachricht + Das Raumverzeichnis anzeigen + + Link in die Zwischenablage kopiert + + Nach Matrix-ID hinzufügen + Raum erstellen… + Bearbeitungsverlauf anzeigen + + Die andere Partei hat die Überprüfung abgebrochen. +\n%s + Das Gerät kann sich nicht auf eine Schlüsselvereinbarung, eine Hash-, eine MAC- oder eine SAS-Methode einigen + Die neueste Featureliste befindet sich immer in %1$s. Wenn Sie Fehler finden, senden Sie uns bitte einen Bericht im Menü oben links von \"Startseite\". Wir werden den Fehler so schnell wie möglich beheben. + Wenn Sie Fehler finden, senden Sie uns bitte einen Bericht im Menü oben links von \"Startseite\". Wir werden diese so schnell wie möglich beheben. + + Importieren Sie e2e-Schlüssel aus der Datei \"%1$s\". + + Vielen Dank, der Vorschlag wurde erfolgreich gesendet + Der Vorschlag konnte nicht gesendet werden (%s) + + RiotX - Matrix Client der nächsten Generation + Ein schnellerer und leichterer Client für Matrix mit den neuesten Android-Frameworks + Miniaturbild wird gesendet (%1$s / %2$s) + Datei wird gesendet (%1$s / %2$s) + + Datei %1$s wird heruntergeladen … + Die Datei %1$s wurde heruntergeladen! + + %1$s , um ein Konto zu erstellen. + Benutze die alte App + + + Können Sie nicht finden, wonach Sie suchen\? + Erstelle einen neuen Raum + Name oder ID (#Beispiel: matrix.org) + + Aktivieren Sie das Streichen, um in der Zeitleiste zu antworten + + Kein Ergebnis gefunden. Verwenden Sie Nach Matrix-ID hinzufügen, um auf dem Server zu suchen. + Beginnen Sie mit der Eingabe, um Ergebnisse zu erhalten + Filtern nach Benutzername oder ID… + + Raum betreten… + diff --git a/vector/src/main/res/values-eu/strings.xml b/vector/src/main/res/values-eu/strings.xml index 3fa892652b..f4c2b81ece 100644 --- a/vector/src/main/res/values-eu/strings.xml +++ b/vector/src/main/res/values-eu/strings.xml @@ -331,7 +331,7 @@ Ziur zaude? Bidali gabeko mezuak daude. %1$s edo %2$s orain? Mezuak ez dira bidali gailu ezezagunak daudelako. %1$s edo %2$s orain? Birbidali dena - utzi dena + Utzi dena Birbidali bidali gabeko mezuak Ezabatu bidali gabeko mezuak Ez da fitxategia aurkitu @@ -1607,4 +1607,17 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada. Esteka arbelera kopiatu da + Integrazio kudeatzailea + + Ez da integrazio kudeatzailerik konfiguratu. + Gehitu matrix ID bidez + Gela sortzen… + Ez da emaitzarik aurkitu, erabili gehitu matrix ID bidez zerbitzarian bilatzeko. + Hasi idazten emaitzak jasotzeko + Iragazi erabiltzaile-izena edo ID-a erabiliz… + + Gelara elkartzen… + + Ikusi edizioen historiala + diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml index 8855311473..60ddb267f4 100644 --- a/vector/src/main/res/values-fi/strings.xml +++ b/vector/src/main/res/values-fi/strings.xml @@ -111,7 +111,7 @@ Virheraportti lähetettiin Virheraporttia ei voitu lähettää (%s) Lähetetään (%s%%) - Sovellus kaatui viime kerralla. Haluaisitko tehdä kaatumisesta virheilmoituksen\? + Sovellus kaatui viime kerralla. Haluatko tehdä kaatumisesta virheilmoituksen\? Lähetä Luettu @@ -1533,4 +1533,83 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Asetukset Tietoturva ja yksityisyys + Olet ajan tasalla! + Viimeksi muokannut %s %s + + + Vaihda verkkoa + Katselet jo tätä huonetta! + + Yleiset + Ääni ja video + Ohje ja tietoa + + + Tee ehdotus + Kirjoita ehdotuksesi alle. + Kuvaile ehdotuksesi tässä + Kiitos, ehdotus on lähetetty + Ehdotuksen lähettäminen epäonnistui (%s) + + Näytä piilotetut tapahtumat aikajanalla + + RiotX - seuraavan sukupolven Matrix-asiakasohjelma + Nopeampi ja kevyempi Matrix-asiakasohjelma + Yksityisviestit + + Odotetaan… + Salataan tiedostoa… + Lähetetään tiedostoa (%1$s / %2$s) + + Ladataan tiedostoa %1$s… + Tiedosto %1$s ladattu! + + (muokattu) + + Käytä vanhaa sovellusta + + + Muokkauksia ei löytynyt + + Suodata keskusteluja… + Etkö löydä, mitä etsit\? + Luo uusi huone + Lähetä uusi yksityisviesti + Näytä huoneluettelo + + Linkki kopioitu leikepöydälle + + Luodaan huonetta… + Näet tuloksia kirjoittamalla jotain + Liitytään huoneeseen… + + Näytä muokkaushistoria + + Vahvista laite + + Vahvista + Avaimen jakopyyntö + Aloita vahvistaminen + Saapuva vahvistuspyyntö + Vastaanotit saapuvan vahvistuspyynnön. + Vahvistettu! + Vahvistit tämän laitteen onnistuneesti. + Avaimen vahvistus + Toinen osapuoli perui vahvistuksen. +\n%s + Vahvistus on peruttu. +\nSyy: %s + + Vuorovaikutteinen laitteen vahvistus + Vahvistuspyyntö + %s haluaa vahvistaa laitteesi + + Käyttäjä perui vahvistuksen + Vahvistustoimenpide aikakatkaistiin + Huoneluettelo + Julkaise tämä huone huoneluettelossa + + Play Storen kuvaus + Push-säännöt + %1$s luodaksesi tilin. diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 1b60f5a10a..5e7dbe8e6f 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -219,7 +219,7 @@ Envoyer un message chiffré… Envoyer un message (non chiffré)… Tout renvoyer - tout annuler + Tout annuler Renvoyer les messages non envoyés Supprimer les messages non envoyés Fichier non trouvé @@ -1612,4 +1612,17 @@ Si vous n’avez pas configuré de nouvelle méthode de récupération, un attaq Lien copié dans le presse-papiers + Gestionnaire d’intégrations + + Aucun gestionnaire d’intégrations n’est configuré. + Ajouter par identifiant matrix + Création du salon… + Aucun résultat trouvé, utilisez Ajouter par identifiant matrix pour chercher sur le serveur. + Entrez du texte pour avoir des résultats + Filtrer par nom d’utilisateur ou identifiant… + + En train de rejoindre le salon… + + Voir l’historique des éditions + diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 9f477da344..3d0174b9d8 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -329,7 +329,7 @@ Kérlek engedélyezd a hozzáférést a következő felugró ablakban, hogy tudj Üzenetek nem kerültek elküldésre. %1$s vagy %2$s most? Üzenetek nem kerültek elküldésre mert egy ismeretlen eszköz van jelen. %1$s vagy %2$s most? Összes újraküldése - Összes megszüntetése + Összes elvetése El nem küldött üzenetek újraküldése El nem küldött üzenetek törlése Fájl nem található @@ -1611,4 +1611,17 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró Hivatkozás a vágólapra másolva + Integrációs Menedzser + + Integrációs Menedzser nincs beállítva. + Hozzáadás matrix ID-vel + Szoba létrehozása… + Nincs találat, használd a „Hozzáadás matrix ID-vel”-t a szerveren való kereséshez. + A találatokhoz kezdj gépelni + Szűrés felhasználói névre vagy azonosítóra… + + Szobába belépés… + + Szerkesztési napló megtekintése + diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index c414f38dee..3719ba0f3d 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -362,7 +362,7 @@ Sicuro di procedere? Messaggi non inviati. %1$s o %2$s ora? Messaggi non inviati a causa di dispositivi sconosciuti qui presenti. %1$s o %2$s ora? Rispedisci tutto - annulla tutto + Annulla tutto Rinvia messaggi non spediti Elimina messaggi non spediti File non trovato @@ -1656,4 +1656,17 @@ Per essere certo di non perdere nulla, mantieni gli aggiornamenti attivi."Collegamento copiato negli appunti + Gestore dell\'integrazione + + Nessun gestore integrazione configurato. + Aggiungi per ID matrix + Creare una stanza … + Nessun risultato trovato, usa \"Aggiungi per ID matrix\" per cercare sul server. + Inizia a digitare per ottenere risultati + Filtra per nome utente o ID … + + Sto entrando nella stanza … + + Visualizza Modifica cronologia + diff --git a/vector/src/main/res/values-ko/strings.xml b/vector/src/main/res/values-ko/strings.xml index 5e357eb69b..188dd6ce36 100644 --- a/vector/src/main/res/values-ko/strings.xml +++ b/vector/src/main/res/values-ko/strings.xml @@ -1,36 +1,36 @@ ko - KO + KR 밝은 테마 어두운 테마 검정 테마 - 동기화하는중… + 동기화 중… 메시지 설정 - 보관 + 기록 버그 보고서 스티커 보내기 - 제3자 라이센스 + 제 3자 라이선스 - 불러오는중… + 불러오는 중… 취소 저장 떠나기 보내기 - 복사 + 복사하기 다시 보내기 - 지우기 + 삭제하기 인용 받기 공유 - 고유주소 + 퍼머링크 출처 보기 해독된 출처 보기 지우기 @@ -43,7 +43,7 @@ 권한이 없어졌기 때문에, 이 행동을 할 수 없습니다. 전화를 걸 수 없습니다 기기 정보 - 그래도 보내기 + 무시하고 보내기 또는 초대 미접속 @@ -53,8 +53,8 @@ 로그아웃 음성 통화하기 영상 통화하기 - 모두 읽음 표시하기 - 보관 + 모두 읽음으로 표시 + 기록 빠른 답장 열기 닫기 @@ -71,10 +71,10 @@ 커뮤니티 - + 방 이름 필터 시스템 알림 - 결과가 없습니다 + 결과 없음 로그 보내기 @@ -90,14 +90,14 @@ 로그인 로그아웃 홈서버 URL - 아이덴티티 서버 URL - 찾기 + ID 서버 URL + 검색 새 대화 시작하기 음성 통화 시작하기 영상 통화 시작하기 - 정말로 %s와 대화하고 싶으세요? + 정말로 %s님과 새 대화를 시작하시겠습니까\? 정말 음성통화를 시작하시겠어요? 정말 영상통화를 시작하시겠어요? @@ -111,12 +111,12 @@ 계정 만들기 제출하기 건너뛰기 - 이메일이나 이용자 이름 + 이메일이나 사용자 이름 비밀번호 새 비밀번호 - 이용자 이름 - 이용자가 당신을 찾고 재설정 비밀번호를 보낼 수 있게 이메일 주소를 적어주세요. - 이용자가 당신을 찾을 수 있게 계정에 전화번호를 추가해주세요. + 사용자 이름 + 사용자가 당신을 찾고 재 설정 비밀번호를 보낼 수 있게 이메일 주소를 적어주세요. + 사용자가 당신을 찾을 수 있게 계정에 전화번호를 추가해주세요. Status.im 테마 서비스 초기화 중 @@ -132,22 +132,22 @@ 키 백업이 끝나지 않았습니다, 기다려주세요… 지금 로그아웃하면 암호화된 메세지가 사라집니다 키 백업하기 - 정말이세요\? + 확신합니까\? 백업 머물기 넘기기 완료 정말 로그아웃하시겠어요\? - 읽었다고 표시 + 읽음으로 표시 Riot이 주소록에 접근할 수 없게 되어 있습니다 - %d 사람들 + %d 명의 사용자 초대 커뮤니티 최근에 애플리케이션이 충돌한 것 같습니다. 충돌 보고서를 열까요\? - 읽기 + 읽음 사용자 이름 음성 보내기 @@ -165,11 +165,11 @@ 새 비밀번호 확인 알맞지 않은 사용자 이름이나 비밀번호 비밀번호가 너무 짧아요 (최소 6자) - 유효한 이메일 주소가 아닌 것 같아요 - 유효한 전화번호가 아닌 것 같아요 + 올바른 이메일 주소가 아닙니다 + 올바른 전화번호가 아닙니다 비밀번호가 맞지 않아요 비밀번호를 잊어버리셨나요\? - 사용중인 사용자 이름입니다 + 사용 중인 사용자 이름입니다 홈서버: 비밀번호를 초기화하려면, 계정에 이메일을 등록해야합니다: 새 비밀번호를 입력해야합니다. @@ -178,4 +178,1373 @@ \n모든 기기에서 로그아웃되고 알림도 가지 않을 거에요. 다시 알림을 받으려면, 각 기기에 다시 로그인하세요. 모바일 + 이벤트 청취하기 + 키 백업이 진행 중입니다. 지금 로그아웃하면 암호화된 메시지에 접근할 수 없습니다. + 암호화된 메시지에 대한 접근을 읽지 않도록 모든 장치에서 보안 키 백업이 활성화되어 있어야 합니다. + 암호화된 메시지를 원하지 않습니다 + 키 백업 중… + 로그아웃하기 전에 키를 백업하지 않으면 암호화된 메시지에 접근할 수 없습니다. + + 말하기 + 지우기 + + 가져오기 + 현재 전화 + 회의 전화 진행 중. +\n%1$s 또는 %2$s로 참가하세요 + 이 방에서 회의를 시작하려면 초대할 권한이 필요합니다 + 회의 전화는 암호화된 방에서 지원하지 않습니다 + 무시하고 통화 + 수락하기 + 중단 + 무시 + + 세계 검색 + 즐겨찾기 필터 + 사람 필터 + 방 이름 필터 + 커뮤니티 이름 필터 + + 초대 + 중요하지 않음 + 대화 + 로컬 주소록 + 사용자 디렉토리 + Matrix 주소록만 + 대화 안 함 + 방 디렉토리 + 방 없음 + 이용할 수 있는 공공 방이 없음 + 그룹 없음 + + 문제를 진단하기 위해, 이 클라이언트의 로그는 버그 보고서와 함께 전송됩니다. 이 버그 보고서에는 로그와 스크린샷이 포함되면 공개적으로 표시되지 않습니다. 위의 텍스트만 보내려면 다음을 선택 해제하세요: + 좌절감에 휴대 전화를 흔들고 있는 것 같네요. 버그 보고서 화면을 열어보겠습니까\? + 분노의 흔들기로 버그 보고하기 + + 진행 (%s%%) + + 여기로 보내기 + 방 들어가기 + 계속… + 죄송합니다, 이 행동을 완료하기 위한 외부 애플리케이션이 없습니다. + + 통합 인증으로 로그인 + 재 설정 이메일 보내기 + 사용자가 당신을 찾을 수 있도록 계정에 이메일 주소 그리고/또는 전화번호를 추가하세요. +\n +\n이메일 주소로 비밀번호를 재 설정할 수도 있습니다. + 사용자가 당신을 찾을 수 있도록 계정에 이메일 주소 그리고 전화번호를 추가하세요. +\n +\n이메일 주소로 비밀번호를 재 설정할 수도 있습니다. + 사용자 이름은 문자, 숫자, 점, 하이픈 및 밑줄만 포함할 수 있습니다 + 비밀번호가 누락되었습니다 + 이 이메일 주소는 이미 정의되었습니다. + 이메일 주소가 누락되었습니다 + 전화번호가 누락되었습니다 + 이메일 주소나 전화번호가 누락되었습니다 + 옳지 않은 토큰 + 맞춤 서버 옵션을 사용하기 (고급) + 등록을 계속하려면 이메일을 확인하세요 + API가 존재하기 전까지는 이메일과 전화번호로 한 번에 등록할 수 없습니다. 오직 전화번호만 고려됩니다. +\n +\n설정에서 프로필에 이메일을 추가할 수 있습니다. + 이 홈서버는 당신이 로봇인지 아닌 지를 확인하고 싶습니다 + ID 서버: + 제 이메일 주소를 인증했습니다 + 계정에 연결된 이메일 주소를 입력해야 합니다. + 이메일 %s(으)로 전송했습니다. 이메일에 포함된 링크를 들어갔다면, 아래를 클릭해주세요. + 이메일 주소를 인증할 수 없습니다: 이메일에 있는 링크를 클릭했는 지 확인하세요 + 이 홈서버의 규칙을 숙지한 후 수락하세요: + + URL은 http[s]://로 시작해야 합니다 + 로그인할 수 없음: 네트워크 오류 + 로그인할 수 없음 + 등록할 수 없음: 네트워크 오류 + 등록할 수 없음 + 등록할 수 없음: 이메일 인증 실패 + 올바른 URL을 입력하세요 + 이 URL에 연결할 수 없습니다, 확인해주세요 + 기기가 오래된 TLS 보안 프로토콜을 사용하고 있습니다, 공격에 취약하며, 보안 상의 이유로 연결할 수 없습니다 + 옳지 않은 사용자 이름/비밀번호 + 지정된 액세스 토큰을 인식할 수 없습니다 + 잘못된 JSON + 올바른 JSON을 갖고 있지 않음 + 너무 많은 요청을 보냈습니다 + 이 사용자 이름은 이미 사용 중입니다 + 이메일 링크를 아직 클릭하지 않았습니다 + + 이 기기를 위한 종단간 암호화 키를 생성하고 공개 키를 홈서버에 제출하려면 다시 로그인해야 합니다. +\n한 번이면 됩니다. +\n불편을 드려 죄송합니다. + + 다른 기기에서 온 다시 요청된 암호 키. + + 키 요청을 보냈습니다. + + 요청 보냄 + 다른 기기에서 Riot을 설치해서 메시지를 암호화하고 이 기기로 키를 보내도록 합니다. + + 읽은 기록 읽기 + + 그룹 목록 + + + %d 구성원십 변경 + + + 이렇게 보내기 + 원본 + 크게 + 중간 + 작게 + + 다운로드를 취소하겠습니까\? + 업로드를 취소하겠습니까\? + %d초 + %1$d분 %2$d초 + + 어제 + 오늘 + + 방 이름 + 방 주제 + + 전화 + 오는 전화에 Riot 기본 벨소리를 사용합니다 + 오는 전화 벨소리 + 전화에 사용할 벨소리를 선택하세요: + + 전화 + 전화 연결됨 + 전화 연결 중… + 전화 종료됨 + 전화 중… + 오는 전화 + 오는 영상 통화 + 오는 음성 통화 + 전화 진행 중… + 영상 통화 진행 중… + + 상대방이 전화를 받지 못했습니다. + 미디어 연결 실패 + 카메라를 초기화할 수 없습니다 + 다른 곳에서 전화 응답 + + 사진이나 영상 찍기 + 영상을 촬영할 수 없음 + + 정보 + 첨부 파일을 보내고 저장하려면 Riot은 영상과 사진 보관함에 접근하는 권한이 필요합니다. +\n +\n당신의 휴대 전화에서 파일을 보내려면 다음 팝업에서 접근을 허용해주세요. + 사진을 찍고 영상 통화를 하려면 Riot은 카메라에 접근하는 권한이 필요합니다. + " +\n +\n전화를 하려면 다음 팝업에서 접근을 허용해주세요." + 음성 통화를 하려면 Riot은 마이크에 접근하는 권한이 필요합니다. + " +\n +\n전화를 하려면 다은 팝업에서 접근을 허용하세요." + 영상 통화를 하려면 Riot은 카메라와 마이크에 접근하는 권한이 필요합니다. +\n +\n전화를 하려면 다음 팝업에서 접근을 허용해주세요. + Riot은 당신의 주소록을 확인해서 이메일과 전화번호를 기반으로 다른 Matrix 사용자를 찾을 수 있습니다. 이런 이유로 주소록을 공유하는 것을 허용한다면, 다음 팝업에서 접근을 허용해주세요. + "Riot은 당신의 주소록을 확인하여 이메일과 전화번호를 기반으로 다른 Matrix 사용자를 찾을 수 있습니다. +\n +\n이런 이유로 주소록을 공유하는 것을 허용하겠습니까\?" + + 죄송합니다. 권한이 없어서, 작업이 수행되지 않았습니다 + + 저장됨 + 다운로드 폴더에 저장하겠습니까\? + + 아니오 + 계속 + + 삭제 + 참가 + 미리보기 + 받지 않기 + + 구성원 목록 + 헤더 열기 + 동기화 중… + 읽지 않은 첫 부분으로 이동하기. + + %s님이 이 방알 초대했습니다 + 이 초대장은 %s님이 보냈습니다, 이 계정과는 관련이 없습니다. +\n다른 계정으로 로그인하거나, 이 이메일을 계정에 추가할 수 있습니다. + %s 방으로 접근하려고 했습니다. 토론에 참여하기 위해 참가하는 것입니까\? + + 이 방의 미리보기입니다. 방 상호작용이 비활성화됩니다. + + 새 대화 + 구성원 추가 + + %d명의 활동 중인 구성원 + + + %d명의 구성원 + + 1명의 구성원 + + + %d초 + + + %d분 + + + %d시 + + + %d일 + + + 방 떠나기 + 방을 떠나겠습니까\? + 이 대화에서 %s을(를) 삭제하겠습니까\? + 만들기 + + 온라인 + 미접속 + 휴식 + %1$s 상태 + %2$s 전 %1$s 상태였음 + + 관리자 도구 + 전화 + 다이렉트 대화 + 기기 + + 초대 + 이 방 떠나기 + 이 방에서 삭제하기 + 차단 + 차단 해제 + 추방 + 일반 사용자로 재 설정 + 중재자 만들기 + 관리자 만들기 + 이 사용자의 모든 메시지 숨기기 + 이 사용자의 모든 메시지 보여주기 + 이 사용자의 모든 메시지를 보이겠습니까\? +\n +\n이 동작은 앱을 재시작하며 일정 시간이 걸릴 수 있습니다. + 사용자 ID, 이름 혹은 이메일 + 언급 + 기기 목록 보여주기 + 사용자를 자신과 동일한 권한 등급으로 승격시키는 것은 취소할 수 없습니다. +\n확신합니까\? + + + 이 사용자들을 이 대화에서 추방하겠습니까\? + + 이 사용자를 이 대화에서 차단하겠습니까\? + 이유 + + %s님을 이 대화에 초대하겠습니까\? + "%1$s님, " + %1$s님과 %2$s님 + %1$s %2$s님 + + ID로 초대 + 로컬 연락처 (%d) + 사용자 디렉토리 (%s) + Matrix 사용자만 + + ID로 사용자 초대 + 이메일 주소나 Matrix ID를 입력해주세요 + 이메일 혹은 Matrix ID + + 검색 + %s님이 입력 중… + %1$s님과 %2$s님이 입력 중… + %1$s님과 %2$s님 외 구성원들이 입력 중… + 암호화된 메시지 보내기… + (암호화 안 된) 메시지 보내기… + 암호화된 답장 보내기… + (암호화 안 된) 답장 보내기… + 서버와의 연결이 끊어졌습니다. + 메시지가 보내지지 않았습니다. %1$s, %2$s, 둘 중 어떤 것을 하겠습니까\? + 알 수 없는 기기가 있어 메시지가 보내지지 않았습니다. %1$s, %2$s, 둘 중 어느 것을 하겠습니까\? + 모두 다시 보내기 + 모두 취소하기 + 보내지지 않은 메시지 다시 보내기 + 보내지지 않은 메시지 삭제하기 + 파일을 찾을 수 없음 + 이 방에 글을 올릴 권한이 없습니다 + + %d개의 새 메시지 + + + 신뢰함 + 신뢰하지 않음 + 로그아웃 + 무시하기 + 핑거프린트 (%s): + 원격 서버의 신원을 인증할 수 없습니다. + 이는 누군가가 당신의 트래픽을 악의적으로 가로채고 있거나, 휴대 전화가 원격 서버에서 제공한 인증서를 신뢰하지 않는 것입니다. + 서버 관리자가 이것이 예상된다고 말한다면, 아래 핑거프린트가 해당 핑거프린트와 일치하는 지 확인하세요. + 인증서가 휴대 전화가 신뢰하는 인증서에서 변경되었습니다. 이것은 매우 비정상적입니다. 새 인증서에 수락하지 않는 것을 권합니다. + 이전 신뢰하던 인증서에서 신뢰하지 않는 인증서로 변경되었습니다. 서버가 인증서를 새로 갱신했을 수 있습니다. 예상되는 핑거프린트는 서버 관리자에게 문의하세요. + 서버 관리자가 위의 핑거프린트와 일치하는 것을 게시하는 경우에만 인증서를 수락할 수 있습니다. + + 방 세부 사항 + 사람 + 파일 + 설정 + + %d개 선택됨 + + 잘못된 ID입니다. 이메일 주소나 \'@localpart:domain\'와 같은 Matrix ID이어야 합니다 + 초대받음 + 참가함 + + 이 콘텐츠를 보고하는 이유 + 이 사용자의 모든 메시지를 숨기겠습니까\? +\n +\n이 동작은 앱을 다시 시작하며 일정 시간이 걸릴 수 있습니다. + 업로드 취소 + 다운로드 취소 + + 검색 + 방 구성원 필터 + 결과 없음 + + 메시지 + 사람 + 파일 + + 참가 + 디렉토리 + 즐겨찾기 + + 중요하지 않음 + 초대 + 대화 시작 + 방 만들기 + 방 참가하기 + 방 참가하기 + 방 ID나 방 별칭을 입력 + + 디렉토리 찾기 + + %d개의 방 + + + %2$s 검색 결과로 %1$s개의 방을 찾음 + + 디렉토리 검색 중… + + 모든 메시지 (소리) + 모든 메시지 + 언급만 + 무음 + 즐겨찾기 + 중요하지 않음 + 다이렉트 대화 + 대화 떠나기 + 잊기 + 홈 화면에 단축 아이콘 추가 + + 메시지 + 설정 + 버전 + 버전 %s + 이용 약관 + 제 3자 공지 + 저작권 + 개인 정보 정책 + + 프로필 사진 + 표시 이름 + 이메일 + 이메일 주소 추가 + 휴대 전화 + 전화번호 추가 + 애플리케이션 정보 + 시스템 설정에서 애플리케이션 정보를 표시하세요. + + + 고급 알림 설정 + 이벤트 별로 알림 중요도를 설정하고, 소리, LED, 진동을 설정하세요 + 이벤트 별 알림 중요도 + + 알림 개인 정보 + 알림 문제 해결 + 문제 해결 진단 + 테스트 실행 + 실행 중… (%2$d개 중 %1$d개 째) + 기본 진단은 괜찮습니다. 여전히 알림을 받지 못하고 있다면, 버그를 보고해서 우리가 조사할 수 있도록 도와주세요. + 1개 이상의 테스트가 실패했습니다, 제안된 수정을 시도하세요. + 1개 이상의 테스트가 실패했습니다, 버그를 보고해서 우리가 조사할 수 있도록 도와주세요. + + 시스템 설정. + 알림이 시스템 설정에서 켜집니다. + 알림이 시스템 설정에서 꺼집니다. +\n시스템 설정을 확인해주세요. + 설정 열기 + + 계정 설정. + 알림이 당신의 계정에서 켜집니다. + 알림이 당신의 계정에서 꺼집니다. +\n계정 설정을 확인해주세요. + 켜기 + + 기기 설정. + 알림이 이 기기에서 켜집니다. + 알림이 이 기기에서 허용되지 않습니다. +\nRiot 설정을 확인해주세요. + 켜기 + + 맞춤 설정. + 일부 메시지 유형은 조용하게 설정되어 있습니다 (소리가 없는 알림을 생성합니다). + 일부 알림이 맞춤 설정에서 꺼집니다. + 맞춤 규칙을 불러오는 데 실패했습니다, 다시 시도해주세요. + 설정 확인 + + Play 서비스 확인 + Google Play 서비스 APK는 최신 버전입니다. + Riot은 Google Play 서비스를 사용해 푸시 메시지를 보내지만 올바르게 설정되지 않은 모양입니다: +\n%1$s + Play 서비스 고치기 + + Firebase 토큰 + FCM 토큰이 성공적으로 검색되었습니다: +\n%1$s + FCM 토큰을 검색하는데 실패했습니다: +\n%1$s + [%1$s] +\n이 오류는 Riot의 통제 밖에 있으며 Google과 관련이 있습니다, 이 오류는 기기가 FCM에 등록된 앱이 너무 많다는 것을 나타냅니다. 오류는 수 많은 앱이 있는 경우에만 발생하고, 일반 사용자에게 영향을 미치지 않아야 합니다. + [%1$s] +\n이 오류는 Riot의 통제 밖입니다. 여러 이유로 발생할 수 있습니다. 나중에 다시 시도하면 작동할 지도 모릅니다, 시스템 설정에서 Google Play 서비스의 데이터 사용이 제한되었는지, 기기의 시간은 맞는 지 확인해보세요, 혹은 커스텀 롬 환경에서 발생할 수 있습니다. + [%1$s] +\n이 오류는 Riot의 통제 밖에 있습니다. 휴대 전화에 Google 계정이 없습니다. 계정 관리자를 열어 Google 계정을 추가하세요. + 계정 추가 + + 토큰 등록 + FCM 토큰이 성공적으로 홈서버에 등록되었습니다. + FCM 토큰을 홈서버에 등록 실패: +\n%1$s + + 알림 서비스 + 알림 서비스가 실행 중입니다. + 알림 서비스가 실행 중이 아닙니다. +\n애플리케이션을 다시 실행해보세요. + 서비스 시작 + + 알림 서비스 자동 다시 시작 + 서비스가 종료되고 자동으로 다시 시작되었습니다. + 서비스 다시 시작에 실패함 + + 부팅 시 시작 + 기기가 다시 시작되면 서비스가 시작됩니다. + 기기가 다시 시작될 때 서비스가 시작되지 않습니다, 다시 시작한 후 Riot을 한 번이라도 열지 않으면 알림을 받을 수 없습니다. + 부팅 시 시작 활성화 + + 백그라운드 제한 사항 확인 + Riot에 대한 백그라운드 제한 사항을 비활성화합니다. 이 테스트는 모바일 데이터를 사용해야 합니다 (WIFI 없음). +\n%1$s + Riot에 대한 백그라운드 제한 사항이 활성화됩니다. +\n앱이 백그라운드에서 작업하는 동안 앱이 시도하는 작업은 적극적으로 제한되며, 이는 알림에 영향을 줄 수 있습니다. +\n%1$s + 제한 사항 비활성화 + + 배터리 최적화 + Riot은 배터리 최적화의 영향을 받지 않습니다. + 사용자가 기기 화면을 끈 상태로 일정 시간 동안 연결되지 않은 상태로 두면, 기기는 Doze 모드에 들어갑니다. 이렇게 하면 앱이 네트워크에 접근하지 못하고 작업, 동기화 및 표준 경보가 지연됩니다. + 최적화 무시하기 + + 보통 + 감소된 개인 정보 보호 + 앱을 백그라운드에서 실행하려면 권한이 필요합니다 + 앱은 백그라운드에서 홈서버로 연결할 필요가 없고, 이는 배터리 사용량을 줄입니다 + • 알림은 Firebase 클라우드 메시징을 통해 보내집니다 + • 알림은 오직 메타데이터만 갖습니다 + • 알림의 메시지 내용은 Matrix 홈서버에서 안전하게 직접 배치됩니다 + • 알림은 메타데이터와 메시지 데이터를 갖습니다 + • 알림은 메시지 내용을 보여주지 않습니다 + + 알림 소리 + 이 계정에서 알림 켜기 + 이 기기에서 알림 켜기 + 3초 동안 화면을 켬 + 소리 알림 설정 + 전화 알림 설정 + 조용한 알림 설정 + LED 색상, 진동, 소리를 고르세요… + + + 내 표시 이름이 들어있는 메시지 + 내 사용자 이름이 들어있는 메시지 + 1:1 대화 메시지 + 그룹 대화 메시지 + 방에 초대받았을 때 + 전화 초대 + 봇에게 받은 메시지 + + 백그라운드 동기화 + 부팅 시 시작 + 백그라운드 동기화 켜기 + 동기화 요청 시간 초과 + 각 요청 간 딜레이 + + + + 버전 + olm 버전 + 이용 약관 + 제 3자 공지 + 저작권 + 개인 정보 정책 + 미디어 유지 + 캐시 지우기 + 미디어 캐시 지우기 + + 사용자 설정 + 알림 + 무시한 사용자 + 기타 + 고급 + 암호화 + 암호화 키 관리 + 알림 대상 + 로컬 주소록 + 주소록 권한 + 국제전화 나라 번호 + 홈 표시 + 알림을 놓친 방을 고정 + 읽지 않은 메시지가 있는 방 고정 + 기기 + 인라인 URL 미리보기 + 홈서버가 이 기능을 지원한다면 대화 내에서 링크를 미리 볼 수 있습니다. + 입력 중 알림 보내기 + 다른 사용자가 당신이 입력 중인 것을 알게 합니다. + 마크다운 형식 + 마크다운 문법을 사용해 메시지를 보내기 전에 형식을 지정합니다. 별표를 사용해 기울임 꼴 문자를 표시하는 고급 서식을 지정할 수 있습니다. + 모든 메시지에 타임스탬프 보여주기 + 12시간 단위를 사용하는 타임스탬프 보여주기 + 읽은 기록 보여주기 + 세부적인 목록으로 읽은 목록을 클릭하세요. + 참가 및 떠남 이벤트 보여주기 + 초대, 추방, 그리고 차단은 영향이 없습니다. + 계정 이벤트 보여주기 + 아바타와 표시 이름 변경도 포함합니다. + 사용자가 언급할 때 진동 + 보내기 전 미디어 미리보기 + 엔터 키로 메시지 보내기 + 가상 키보드의 엔터 버튼으로 줄 바꿈을 하는 대신 메시지를 보냅니다 + + 계정 비활성화 + 내 계정 비활성화 + + 알림 개인 정보 + Riot은 백그라운드에서 실행되어 알림을 안전하고 은밀하게 관리할 수 있습니다. 이것은 배터리 사용량에 영향을 줄 수 있습니다. + 권한 부여 + 다른 옵션을 선택하세요 + + 백그라운드 연결 + Riot은 신뢰가 있는 알림을 위해 낮은 영향의 백그라운드 연결을 유지해야 합니다. +\n다른 화면에서 Riot이 항상 백그라운드에서 실행하도록 허용하는 메시지가 표시됩니다, 수락해주세요. + 권한 부여 + + 정보 분석 + 정보 분석 데이터 보내기 + Riot은 애플리케이션을 개선할 수 있도록 익명의 분석을 수집합니다. + 분석을 활성화해서 Riot이 개선할 수 있도록 도와주세요. + 예, 저도 돕고 싶습니다! + + 데이터 절약 모드 + 데이터 절약 모드는 특정 필터를 적용하여 현재 상태 업데이트와 입력 중 알림을 걸러냅니다. + + 기기 세부 사항 + ID + 이름 + 기기 이름 + 마지막으로 본 순간 + %1$s @ %2$s + 이 작업은 추가 인증이 필요합니다. +\n계속하려면, 비밀번호를 입력하세요. + 인증 + 비밀번호: + 제출하기 + + 이것으로 로그인 + 홈서버 + ID 서버 + 통합 관리자 + + 사용자 인터페이스 + 언어 + 언어를 선택하세요 + + 인증 보류 중 + 이메일을 인증해서 거기에 있는 링크를 클릭하세요. 모두 끝나면, 계속하기를 클릭하세요. + 이메일 주소를 인증할 수 없습니다. 이메일을 인증해서 거기에 있는 링크를 클릭하세요. 모두 끝나면, 계속하기를 클릭하세요. + 이 이메일 주소는 이미 사용 중입니다. + 이 이메일 주소를 찾을 수 없습니다. + 이 전화번호는 이미 사용 중입니다. + 이메일 주소를 인증하는 중 오류가 발생했습니다. + + 비밀번호 + 비밀번호 변경 + 현재 비밀번호 + 새 비밀번호 + 새 비밀번호 확인 + 비밀번호 갱신 + 비밀번호 갱신 실패 + 비밀번호가 올바르지 않습니다 + 당신의 비밀번호가 갱신되었습니다 + %s님의 모든 메시지를 보이겠습니까\? +\n +\n이 동작은 앱을 다시 시작하고 일정 시간이 걸릴 수 있습니다. + 비밀번호가 맞지 않음 + + 이 알림 대상을 제거하겠습니까\? + + %1$s %2$s를 제거하겠습니까\? + + 나라를 선택하세요 + + 나라 + 나라를 선택해주세요 + 전화번호 + 선택한 나라에 올바르지 않은 전화번호 + 휴대 전화 인증 + 활성 코드가 담신 SMS를 보냈습니다. 코드를 아래에 입력하세요. + 활성 코드 입력 + 전화번호를 인증하는 중 오류 + 코드 + 전화번호를 인증하는 중 오류가 발생했습니다. + 추가 정보: %s + + 미디어 + 기본 압축 + 선택 + 기본 미디어 소스 + 선택 + 셔터 소리 재생하기 + + 재능 + 현재는 어떤 커뮤니티의 구성원이 아닙니다. + + 3일 + 1주 + 1달 + 영원히 + + 방 사진 + 방 이름 + 주제 + 방 태그 + 이것으로 태그됨: + + 즐겨찾기 + 중요하지 않음 + 없음 + + 접근성 및 가시성 + 이 방을 방 디렉토리에 놓기 + 알림 + 방 접근성 + 방 기록 읽기 권한 + 누가 기록을 읽을 수 있나요\? + 누가 이 방에 접근할 수 있나요\? + + 누구나 + (이 옵션을 선택한 시점부터) 구성원만 + (초대받은 시점부터) 구성원만 + (참가한 시점부터) 구성원만 + + 이 방에 링크를 타고 오려면 주소가 있어야 합니다. + 초대받은 사람들만 + 방의 링크를 아는 누구나, 손님 제외 + 방의 링크를 아는 누구나, 손님 포함 + + 차단한 사용자 + + 고급 + 이 방의 내부 ID + 주소 + 실험실 + 예기치 않은 방식으로 중단될 수 있는 실험적인 기능들입니다. 주의해서 사용하세요. + 종단간 암호화 + 종단간 암호화가 켜졌습니다 + 암호화를 켜기 위해 로그아웃을 해야 합니다. + 인증된 기기로만 암호화 + 이 기기로는 방에서 인증되지 않은 기기로 암호화된 메시지를 절대 보내지 마세요. + + 이 방은 로컬 주소가 없습니다 + 새 주소 (예: #foo:matrix.org) + + 이 방은 어떤 커뮤니티에도 재능을 표시하지 않습니다 + 새 커뮤니니 ID (예: +foo:matrix.org) + 올바르지 않은 커뮤니티 ID + \'%s\'은(는) 올바르지 않은 커뮤니티 ID입니다 + + + 올바르지 않은 별칭 형식 + \'%s\'은(는) 별칭에 올바르지 않은 형식입니다 + 이 방에 지정된 메인 주소가 없습니다. + 메인 주소 경고 + + 메인 주소로 설정 + 메인 주소로 설정 해제 + 방 ID 복사 + 방 주소 복사 + + 이 방에서 암호화가 켜졌습니다. + 이 방에서 암호화가 꺼졌습니다. + 암호화 활성화 +\n(경고: 다시 비활성화할 수 없음!) + + 디렉토리 + 테마 + + %s님이 이 방의 특정 지점을 불러오려 했으나 찾을 수 없었습니다. + + 종단간 암호화 정보 + + 이벤트 정보 + 사용자 ID + Curve25519 ID 키 + 청구된 Ed25519 핑거프린트 키 + 알고리즘 + 세션 ID + 암호 해독 오류 + + 발신자 기기 정보 + 기기 이름 + 이름 + 기기 ID + 기기 키 + 인증 + Ed25519 핑거프린트 + + 종단간 암호화 방 키 내보내기 + 방 키 내보내기 + 로컬 파일로 키 내보내기 + 내보내기 + 내보낸 키를 암호화하는 암호를 만드세요. 키를 가져오려면 같은 암호를 입력해야 합니다. + 종단간 암호화 방 키가 \'%s\'에 저장되었습니다. +\n +\n경고: 애플리케이션을 삭제하면 이 파일도 삭제됩니다. + + 암호화된 메시지 복구 + 키 백업 관리 + + 종단간 암호화 방 키 가져오기 + 방 키 가져오기 + 로컬 파일에서 키 가져오기 + 가져오기 + 인증된 기기로만 암호화 + 이 기기에서 인증되지 않은 기기로 절대 암호화된 메시지를 보내기 마세요. + %1$d/%2$d 키를 성공적으로 가져왔습니다. + + 인증되지 않음 + 인증됨 + 블랙리스트 대상 + + 알 수 없는 기기 + 알 수 없는 ip + 없음 + + 인증 + 인증하지 않음 + 블랙리스트 + 블랙리스트 제외 + + 인증 기기 + 이 기기가 신뢰할 수 있는 지 인증하려면, 다른 방법을 사용하려 소유자에게 문의하세요 (예: 현실에서 혹은 전화로) 그리고 이 기기의 사용자 설정에서 표시된 키가 아래에 있는 키와 맞는지 물어보세요: + 그것이 맞다면, 아래의 인증 버튼을 누르세요. 맞지 않다면, 다른 사람이 이 기기를 가로채고 있는 것이고 블랙리스트에 올려야 합니다. 앞으로 이 인증 절차는 더 정교해질 것입니다. + 키가 맞다는 것은 인증합니다 + + Riot은 이제 종단간 암호화를 지원하지만 활성화하려면 다시 로그인해야 합니다. +\n +\n지금 바로 하거나 나중에 애플리케이션 설정에서 할 수 있습니다. + + 알 수 없는 기기가 있는 방 + 이 방에는 인증되지 않은 알 수 없는 기기가 있습니다. +\n즉, 사용자에 속해 있다고 주장하는 기기라는 보장이 없습니다. +\n저희는 계속하기 전에 각 기기에 인증 절차를 하기를 권합니다, 하지만 원한다면 인증하지 않고 바로 메시지를 보낼 수 있습니다. +\n +\n알 수 없는 기기: + + 방 디렉토리 선택 + 서버를 이용할 수 없거나 과부하 상태입니다 + 공개 서버를 표시할 홈서버를 입력하세요 + 홈서버 URL + %s 서버의 모든 방 + 모든 기본 %s 방 + + 여기에 입력… + + + %d개의 읽지 않은 알림 메시지 + + + %d개의 읽지 않은 알림 메시지 + + + %d개의 방 + + + + %1$s: %2$d개의 메시지 + + + %d개의 알림 + + + %2$s에서 %1$s님 + 새 이벤트 + + 새 메시지 + 새 초대 + + ** 보내기 실패 - 방을 열어주세요 + + 기록 검색 + + 글씨 크기 + 매우 작게 + 작게 + 보통 + 크게 + 더 크게 + 매우 크게 + 가장 크게 + + 이 방에서 위젯을 다루려면 권한이 있어야 합니다 + 위젯 생성 실패 + %1$s을(를) %2$s님이 추가함 + %1$s을(를) %2$s님이 삭제함 + Jitsi로 회의 전화 만들기 + 이 방에서 위젯을 삭제하겠습니까\? + + %d개의 활성 위젯 + + + 죄송합니다, Jitsi로 회의 전화는 오래된 기기에서 지원하지 않습니다 (안드로이드 OS가 5.0 이하인 기기) + + 위젯을 만들 수 없습니다. + 요청을 보낼 수 없습니다. + 권한 등급은 양의 정수이어야 합니다. + 당신은 이 방에 등록되지 않았습니다. + 이 방에서 해당 작업을 할 권한이 없습니다. + 요청에 room_id가 없습니다. + 요청에 user_id가 없습니다. + 방 %s이(가) 보이지 않습니다. + 필수 매개 변수가 없습니다. + 매개 변수가 올바르지 않습니다. + 통합 관리자가 설정되지 않았습니다. + Matrix 앱 추가 + 기본 카메라 사용 + 맞춤 카메라 화면 대신 시스템 카메라를 실행합니다. + 키보드 엔터 키로 메시지 보내기 + 음성 메시지 보내기 + 이 옵션은 메시지를 기록하기 위한 제 3자 애플리케이션이 필요합니다. + + 새 기기 \'%s\'을(를) 추가했습니다, 여기에는 암호화 키가 필요합니다. + 새 기기에는 암호화 키가 필요합니다. +\n기기 이름: %1$s +\n마지막으로 본 순간: %2$s +\n다른 기기에서 로그인하지 않았다면, 이 요청을 무시하세요. + 인증되지 않은 기기 \'%s\'가 암호화 키를 요청했습니다. + 인증되지 않은 기기가 암호화 키를 요청했습니다. +\n기기 이름: %1$s +\n마지막으로 본 순간: %2$s +\n다른 기기에서 로그인하지 않았다면, 이 요청을 무시하세요. + + 인증 시작 + 인증 + 인증 없이 공유 + 공유 + 키 공유 요청 + 요청 무시하기 + 무시 + + 경고! + 회의 전화는 개발 중이며 신뢰할 수 없을 수 있습니다. + + 명령어 오류 + 인식할 수 없는 명령어: %s + \"%s\" 명령어는 더 많은 매개 변수가 필요하거나, 일부 매개 변수가 옳지 않습니다. + 동작 표시하기 + 주어진 ID로 사용자 차단하기 + 주어진 ID로 사용자 차단 해제하기 + 사용자의 권한 등급 정의하기 + 주어진 ID로 사용자 강등하기 + 주어진 ID 현재 방에 사용자 초대하기 + 주어진 별칭으로 방에 참가하기 + 방 떠나기 + 방 주제 설정하기 + 주어진 ID로 사용자 추방하기 + 표시 별명 바꾸기 + 마크다운 On/Off + Matrix 앱 관리 문제를 해결하려면 + + 마크다운이 켜졌습니다. + 마크다운이 꺼졌습니다. + + + 조용히 + 소리 + + 암호화된 메시지 + + 만들기 + 커뮤니티 만들기 + 커뮤니티 이름 + 예시 + 커뮤니티 ID + 예시 + + + 사람 + + 사용자 없음 + + + 참가함 + 초대받음 + 구성원 그룹 필터 + 방 그룹 필터 + + + %d명의 구성원 + + + + %d개의 방 + + 커뮤니티 관리자가 이 커뮤니티에 대한 자세한 설명을 제공하지 않았습니다. + + %2$s님에 의해 %1$s에서 추방당했습니다 + %2$s님에 의해 %1$s에서 차단됬습니다 + 이유: %1$s + 다시 참가하기 + 방 잊어버리기 + + 아바타 메모 + 아바타 공지 + 아바타 + + %1$s 홈서버를 계속 사용하려면 이용 약관을 검토하고 승인해야 합니다. + 지금 검토하기 + + 계정 비활성화 + 이것으로 계정은 영구적으로 사용할 수 없게 됩니다. 로그인할 수 없고 누구도 같은 사용자 ID로 다시 가입할 수 없게 됩니다. 이 계정으로 참가한 모든 방에서 떠나게 되고, ID 서버의 계정 세부 사항도 삭제됩니다. 이 행동은 돌이킬 수 없습니다. +\n +\n계정을 비활성화해도 기본적으로 보낸 메시지를 잊지 않습니다. 메시지를 잊기를 원한다면, 아래 상자를 선택하세요. +\n +\nMatrix의 메시지 가시성은 이메일과 유사합니다. 우리가 메시지를 잊는 것은 보낸 메시지가 모든 새 사용자 혹은 등록하지 않은 사용자와 공유하지 않는다는 것입니다, 하지만 이 메시지에 접근한 등록된 사용자는 이 사본으로 여전히 접근할 수 있을 것입니다. + 내 계정을 비활성화하면 내가 보낸 모든 메시지는 잊어주세요 (경고: 이것은 미래 사용자가 불완전한 대화를 읽게 됩니다) + 계속하려면, 비밀번호를 입력하세요: + 계정 비활성화 + + 사용자 이름을 입력하세요. + 비밀번호를 입력하세요. + 이 방은 교체되었으며 더 이상 활동하지 않습니다 + 대화는 여기서 계속됩니다 + 이 방은 다른 대화의 연장선입니다 + 오래된 메시지를 보려면 여기를 클릭 + + 리소스 한도 초과됨 + 관리자 연락 + + 서비스 관리자에게 연락 + + 이 홈서버가 리소스 한도를 초과해서 일부 사용자는 로그인할 수 없습니다. + 이 홈서버가 리소스 한도를 초과했습니다. + + 이 홈서버가 월 간 활성 사용자 한도를 초과해서 일부 사용자는 로그인할 수 없습니다. + 이 홈서버가 월 간 사용자 한도를 초과했습니다. + + 한도를 높이려면 %s하세요. + 이 서비스 사용을 계속하려면 %s하세요. + + 방 구성원 불러오기 지연 + 첫 화면에서 방 멤버만 불러옴으로써 퍼포먼스를 향상시킵니다. + 아직 홈서버가 방 구성원 불러오기 지연을 지원하지 않습니다. 나중에 시도하세요. + + 죄송합니다, 오류가 발생했습니다 + + 펼치기 + 접기 + + 정보 영역 보여주기 + 항상 + 메시지와 오류일 시 + 오류만 + + %1$s: + %1$s: %2$s + +%d + %d+ + 올바른 Google Play 서비스 APK를 찾을 수 없습니다. 알림이 제대로 작동하지 않을 수 있습니다. + + Riot.im - 대화하세요, 나만의 방식 + 우리는 항상 Riot.im을 변경하고 개선하고 있습니다. 전체 변경 내역은 여기서 찾을 수 있습니다: %1$s. 놓치지 않도록 업데이트를 켜 놓아주세요. + 전적으로 여러분의 통제 하에 있는 범용 보안 대화 앱. + 여러분의 통제 하에 완전히 유연한 대화 앱. Riot은 여러분이 원하는 방식으로 대화할 수 있도록 합니다. 개방형 분산 커뮤니티의 표준 - [matrix]를 위해 제작됨. +\n +\n무료 matrix.org 계정을 만들고, https://modular.im에서 자신만의 서버, 혹은 다른 Matrix 서버를 얻으세요. +\n +\n왜 Riot.im을 선택해야 하나요\? +\n +\n• 완전한 대화: 원하는 대로 팀이나 친구, 커뮤니티를 중심으로 방을 만드세요! 대화, 파일 공유, 위젯 추가와 음성 및 영상 통화 - 모두 무료입니다. +\n +\n• 강력한 통합: 여러분이 알고 사랑하는 도구와 함께 Riot.im을 사용하세요. Riot.im이라면 다른 대화 앱의 사용자와 그룹까지도 대화할 수 있습니다. +\n +\n• 개인 및 보안: 대화를 비밀로 유지하세요. 최첨단 종단간 암호화로 비밀 대화를 은밀하게 유지해줍니다. +\n +\n• 오픈 소스: Matrix로 만들어진 오픈 소스입니다. 자신의 데이터를 자신의 서버에 소유하거나, 신뢰하는 서버에 맡기세요. +\n +\n• 어디에 있든: 모든 기기나 https://riot.im에서 완전히 동기화된 메시지 기록으로 연락을 유지합니다. + + 암호 만들기 + 암호 확인 + 암호 입력 + 암호가 맞지 않음 + 암호를 입력하세요 + 암호가 너무 약합니다 + + Riot으로 복구 키를 생성하려면 암호를 지워주세요. + 이용할 수 있는 Matrix 세션이 없음 + + 암호화된 메시지를 잃지 마세요 + 암호화된 방의 메시지는 종단간 암호화로 보호됩니다. 자신과 수신자만이 메시지를 읽을 수 있는 키를 갖습니다. +\n +\n분실하지 않도록 키를 안전하게 백업해두세요. + 키 백업 시작 + (고급) + 수동으로 키 내보내기 + + 암호로 백업을 보호하세요. + 홈서버에 암호화된 키의 사본을 저장합니다. 보안을 유지하기 위해 암호로 백업을 보호하세요. +\n +\n보안을 최대한 끌어내려면, 암호는 계정 비밀번호와 다른 것이 좋습니다. + 암호 설정 + 백업 만들기 + 혹은 복구 키로 백업을 보호하여 안전한 곳에 보관하세요. + (고급) 복구 키와 함께 설정 + 성공 ! + 당신의 키가 백업됬습니다. + 복구 키는 안전망입니다 - 암호를 잊어버린다면 이걸로 암호화된 메시지에 대한 접근을 복구할 수 있습니다. +\n복구 키가 비밀번호 관리자 (혹은 금고)같은 어딘가에 매우 안전하게 있도록 유지하세요 + 복구 키가 비밀번호 관리자 (혹은 금고)같은 어딘가에 매우 안전하게 있도록 유지하세요 + 완료 + 사본을 만들었습니다 + 복구 키 저장 + 공유 + 파일로 저장 + 복구 키가 \'%s\'(으)로 저장되었습니다. +\n +\n경고: 이 파일은 애플리케이션이 삭제되면 함께 삭제됩니다. + + 백업이 이미 홈서버에 존재합니다 + 이미 키 백업을 다른 기기에 설정한 모양입니다. 만들고 있는 것으로 바꾸겠습니까\? + 바꾸기 + 멈추기 + + 사본을 만들어 주세요 + 복구 키 공유… + 암호를 사용해 복구 키를 생성하는 것은 시간이 걸릴 수 있습니다. + 복구 키 + 예기치 않은 오류 + 백업 시작함 + 이제 암호화 키가 백그라운드에서 홈서버로 백업됩니다. 처음 백업에는 몇 분이 걸릴 수 있습니다. + + + 확신합니까\? + 로그아웃을 하거나 이 기기를 잃어버리면 메시지에 접근할 수 없게 될지도 모릅니다. + + 백업 버전 가져오는 중… + 복구 암호를 사용해서 암호화된 메시지 기록을 풀기 + 복구 키를 사용 + 복구 암호가 기억나지 않는다면, %s할 수 있습니다. + + 복구 키를 사용해서 암호화된 메시지 기록을 풀기 + 복구 키 입력 + + 메시지 복구 + + 복구 키를 잃어버렸나요\? 설정에서 새로운 키를 만들 수 있습니다. + 이 암호로 백업을 해독할 수 없습니다: 올바른 복구 암호를 입력해서 인증해주세요. + 네트워크 오류: 인터넷 연결 상태를 확인하고 다시 시도해주세요. + + 백업 복구: + 복구 키 계산 중… + 키 다운로드 중… + 키 가져오는 중… + 기록 풀기 + 복구 키를 입력하세요 + 이 복구 키로 백업을 해독할 수 없습니다: 올바른 복구 키를 입력해서 인증하세요. + + 백업이 복구되었습니다 %s ! + %1$d개의 세션 키를 복구했고, 이 기기에서 알려지지 않은 %2$d개의 새 키를 추가함 + + %d개의 키와 함께 백업을 복구했습니다. + + + %d개의 새 키가 이 기기에 추가되었습니다. + + + 최신 복구 키 버전을 가져오는 데 실패했습니다 (%s). + 세션 암호화가 활성화되지 않았습니다 + + + 백업에서 복구 + 백업 삭제 + + 이 기기를 위한 키 백업이 올바르게 설정되었습니다. + 이 기기에서 키 백업이 활성화되지 않았습니다. + 이 기기에서 키가 아직 백업되지 않았습니다. + + 백업이 ID %s의 알 수 없는 기기의 서명이 있습니다. + 백업이 이 기기의 올바른 서명이 있습니다. + 백업이 인증된 기기 %s의 올바른 서명이 있습니다. + 백업이 인증되지 않은 기기 %s의 올바른 서명이 있습니다 + 백업이 인증된 기기 %s의 올바르지 않은 서명이 있습니다 + 백업이 인증되지 않은 기기 %s의 올바르지 않은 서명이 있습니다 + 백업에 대한 신뢰 정보를 주지 못했습니다 (%s). + + 이 기기에서 키 백업을 사용하려면, 지금 암호나 복구 키를 복구하세요. + 백업 삭제 중… + 백업 삭제에 실패함 (%s) + + 백업 상태 확인하기 + 백업 삭제 + 서버에서 백업한 암호화 키를 삭제하겠습니까\? 더 이상 복구 키를 사용해 암호화된 메시지 기록을 읽을 수 없습니다. + + 새 키 백업 + 새 보안 메시지 키 백업이 삭제되었습니다. +\n +\n새 복구 방법을 설정하지 않으면, 공격하는 사람이 계정에 접근하려 할 수도 있습니다. 설정에 가서 계정 비밀번호를 바꾸고 새로운 복구 방법을 설정하세요. + 접니다 + 암호화된 메시지를 잃지 마세요 + 키 백업 시작 + + 암호화된 메시지를 잃지 마세요 + 키 백업하기 + + 새 암호화된 메시지 키 + 키 백업에서 관리 + + 키 백업 중… + + 모든 키가 백업됨 + + %d개의 키를 백업 중… + + + 버전 + 알고리즘 + 서명 + + 잘못된 홈서버 검색 응답 + 자동 완성 서버 설정 + Riot이 userId 도메인 \"%1$s\"에 대한 맞춤 서버 설정을 감지했습니다: +\n%2$s + 설정 사용 + + 올바르지 않거나 만료된 자격 때문에 로그아웃되었습니다. + + 짧은 문장과 비교하여 확인하세요. + 보안을 최대화하려면, 상대방과 직접 대면하거나 신뢰할 수 있는 다른 대화 수단을 사용하는 것이 좋습니다. + 인증 시작 + 수신 확인 요청 + 이 기기를 확인하여 신뢰할 수 있는 것으로 표시하세요. 종단간 암호화 메시지를 사용하는 경우 상대방의 기기를 신뢰하면 안심할 수 있습니다. + 이 기기를 확인하여 신뢰할 수 있는 것으로 표시하세요, 그리고 당신의 기기도 상대방에게 신뢰할 수 있는 것으로 표시하세요. + + 다음 이모지가 상대방의 화면에 나타나는 것을 확인하는 것으로 이 기기를 인증합니다 + 다음 숫자가 상대방의 화면에 나타나는 것을 확인하는 것으로 이 기기를 인증합니다 + + 수신 확인 요청을 받았습니다. + 요청 보기 + 상대방이 확인하기를 기다리는 중… + + 인증되었습니다! + 성공적으로 이 기기를 인증했습니다. + 이 사용자 간의 보안 메시지는 종단간 암호화 되며 제 3자가 읽을 수 없습니다. + 알겠습니다 + + 아무것도 안 나타나나요\? 일부 클라이언트는 아직 대화 식 인증을 지원하지 않습니다. 옛날 인증 방식을 사용하세요. + 옛날 인증 방식 사용하기. + + 키 인증 + 요청 취소됨 + 상대방이 확인을 취소했습니다. +\n%s + 인증이 취소되었습니다. +\n이유: %s + + 상호작용 기기 인증 + 인증 요청 + %s님이 당신의 기기를 인증하고 싶습니다 + + 사용자가 인증을 취소했습니다 + 인증 과정 시간이 초과되었습니다 + 기기는 이 처리에 대해 모릅니다 + 기기는 키 계약, 해시, MAC 또는 SAS 방식에 동의할 수 없습니다 + 해시 커밋이 일치하지 않습니다 + SAS가 일치하지 않습니다 + 기기가 예기치 못한 메시지를 받았습니다 + 올바르지 않은 메시지를 받았습니다 + 키 맞지 않음 + 사용자 맞지 않음 + 알 수 없는 오류 + + + 편집 + 답장 + + 다시 시도 + 앱을 시작하면 방에 참가하기. + 초대장을 보냈습니다 + %1$s 님이 초대했습니다 + + 모두 읽었습니다! + 더 이상 읽지 않은 메시지가 없습니다 + 홈에 온 것을 환영합니다! + 여기부터 읽지 않은 메시지를 읽으세요 + 대화 + 다이렉트 메시지 대화가 여기에 표시됩니다 + + 방이 여기 표시됩니다 + + 리액션 + 동의 + 좋아요 + 리액션 추가 + 리액션 보기 + 리액션 + + 사용자가 삭제한 이벤트 + 방 관리자가 중재한 이벤트 + %s님이 %s에 마지막으로 편집함 + + + 잘못된 이벤트, 표시할 수 없음 + 새 방 만들기 + 네트워크 없음. 인터넷 연결 상태를 확인하세요. + 변경 + 네트워크 변경 + 기다려주세요… + 모든 커뮤니티 + + 이 방은 미리 볼 수 없습니다 + 세계가 읽을 수 있는 방의 미리보기는 아직 RiotX에서 지원하지 않습니다 + + + 다이렉트 메시지 + + 새 방 + 만들기 + 방 이름 + 공공 + 누구나 이 방에 참가할 수 있습니다 + 방 디렉토리 + 이 방을 방 디렉토리에 게시 + + 신뢰 정보를 얻는 과정에서 오류가 발생했습니다 + 키 백업 데이터를 얻는 과정에서 오류가 발생했습니다 + + 베타 버전에 온 것을 환영합니다! + RiotX가 개발 중에 있기에, 일부 기능이 부족하고 버그가 나올 수 있습니다. + 최신 기능 목록은 항상 %1$s에 있고, 버그를 발견했다면 홈의 왼쪽 위 메뉴에서 보고해주세요, 그러면 가능한 한 빨리 고치겠습니다. + Play 스토어 설명 + 버그를 발견했다면 홈의 왼쪽 위 메뉴에서 보고해주세요, 그러면 가능한 한 빨리 고치겠습니다. + + 파일 \"%1$s\"에서 종단간 암호화 키 가져옴. + + Matrix SDK 버전 + 다른 제 3자 공지 + 이 방을 이미 봤습니다! + + 빠른 리액션 + + 기본 + 환경 설정 + 보안 & 개인 + 전문가 + 푸시 규칙 + 푸시 규칙이 정의되지 않음 + 등록된 푸시 게이트웨이가 없음 + + app_id: + push_key: + app_display_name: + device_name: + Url: + Format: + + 음성 & 영상 + 도움 & 정보 + + + 등록 토큰 + + 제안하기 + 아래에 당신의 제안을 적어주세요. + 여기에 당신의 제안을 설명 + 감사합니다, 제안을 성공적으로 보냈습니다 + 제안을 보내는 데 실패함 (%s) + + 타임라인에서 숨겨진 이벤트 보여주기 + + RiotX - 차세대 Matrix 클라이언트 + 최신 안드로이드 프레임워크를 사용해 더 빠르고 가벼운 Matrix를 위한 클라이언트 + RiotX는 Matrix 프로토콜 (Matrix.org)을 위한 새 클라이언트입니다: 안전한 분산 통신을 위한 개방형 네트워크. RiotX는 Matrix 안드로이드 SDK의 Riot 안드로이드 클라이언트 전체 개정판을 기반으로 한 Riot 안드로이드 클라이언트의 전체 개정판입니다. +\n +\n면책 조항: 이것은 베타 버전입니다. RiotX는 현재 개발 중이고 한계가 있으며 (많지 않으면 좋겠지만) 버그가 있습니다. 모든 피드백은 환영합니다! +\n +\nRiotX 지원: • 존재하는 계정으로 로그인 • 방을 만들고 공공 방에 참가 • 초대를 수락하거나 거절 • 사용자 방 목록 • 방 세부 정보 보기 • 문자 메시지 보내기 • 첨부 파일 보내기 • 암호화된 방에서 메시지 읽고 쓰기 • 암호화: 종단간 암호화 키 백업, 고급 기기 인증, 키 공유 요청과 답장 • 푸시 알림 • 밝은 테마, 어두운 테마 그리고 검정 테마 +\n +\n아직 Riot의 모든 기능이 RiotX에 구현되지 않았습니다. 주요 없는 (그리고 곧 나올!) 기능: • 계정 만들기 • 방 설정 (방 구성원 목록 등) • 다이렉트 대화 방 만들기 • 전화 • 위젯 • … + + 다이렉트 메시지 + + 기다리세요… + 썸네일 암호화 중… + 썸네일 보내는 중 (%1$s / %2$s) + 파일 암호화 중… + 파일 보내는 중 (%1$s / %2$s) + + 파일 %1$s 다운로드하는 중… + 파일 %1$s을(를) 다운로드했습니다! + + (편집됨) + + 계정을 만들려면 %1$s하세요. + 예전 앱을 사용 + + + 메시지 편집 + 수정 사항이 없음 + + 대화 필터… + 원하는 것을 찾을 수 없나요\? + 새 방 만들기 + 새 다이렉트 메시지 보내기 + 방 디렉토리 보기 + + 이름 혹은 ID (#예시:matrix.org) + + 타임라인에서 스와이프로 답장 기능 켜기 + + 클립보드에 링크 복사 + + Matrix ID로 추가 + 방 만드는 중… + 결과가 없습니다, Matrix ID로 추가를 사용하여 서버를 검색하세요. + 결과를 얻기 위해 검색 시작 + 사용자 이름 또는 ID로 필터… + + 방에 참가하는 중… + + 편집 기록 보기 + diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index 5d57a54d04..778746b007 100755 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -155,7 +155,7 @@ Wachtwoord herhalen Nieuw wachtwoord bevestigen Verkeerde gebruikersnaam en/of wachtwoord - Gebruikersnamen mogen alleen letters, cijfers, punten en afbreek- en lage streepjes bevatten + Gebruikersnamen mogen alleen letters, cijfers, punten, koppeltekens en underscores bevatten Wachtwoord te kort (min 6) Wachtwoord ontbreekt Dit is geen geldig e-mailadres @@ -292,7 +292,7 @@ Afwijzen - Spring naar het eerste ongelezen bericht. + Ga naar het eerste ongelezen bericht. %s heeft u uitgenodigd in dit gesprek @@ -484,7 +484,7 @@ Cryptografie Meldingsdoelen Lokale contacten - Contacten-toestemming + Toegang geven tot lokale contacten Land voor telefoonboek Startscherm Gesprekken met gemiste meldingen vastprikken @@ -689,7 +689,7 @@ Alle lokale gesprekken op %s - Zoeken naar historische + Zoeken in de historiek Offline Gebruikerscatalogus @@ -903,8 +903,8 @@ Avatar - 1 ongelezen bericht waarin u vermeld staat - %d ongelezen berichten waarin u vermeld staat + 1 ongelezen bericht waarin u vermeld bent + %d ongelezen berichten waarin u vermeld bent Vermeldingsavatar Verstuur een sticker @@ -1208,7 +1208,7 @@ Als een gebruiker een apparaat los van de oplader een tijd laat stilliggen, met het scherm uitgeschakeld, gaat het apparaat in slaapmodus. Dit verhindert apps de toegang tot het netwerk, en stelt hun taken, synchronisaties en standaardalarmen uit. Optimalisatie negeren - De app heeft geen verbinding met de homeserver nodig in de achtergrond, dit zou accuverbruik moeten verlagen + De app heeft geen verbinding met de homeserver nodig in de achtergrond, dit zou het gebruik van de batterij moeten verlagen Lawaaiierige meldingen configureren Oproepmeldingen configureren Stille meldingen configureren diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index 3298e5ddf1..2b2198cd17 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -28,7 +28,7 @@ Przychodzące połączenie grupowe. \nDołącz z %1$s lub %2$s Głos - kamerą + Wideo Nie można rozpocząć połączenia, spróbuj ponownie później Ze względu na brak pewnych uprawnień, niektóre funkcje mogą nie działać… Musisz być uprawniony, aby rozpocząć połączenie grupowe @@ -287,7 +287,7 @@ Przyznaj dostęp w następnym oknie. Wyślij wiadomość (niezaszyfrowaną)… Utracono połączenie z serwerem. Wyślij ponownie wszystko - anuluj wszystko + Anuluj wszystko Wyślij niewysłane wiadomości ponownie Usuń niewysłane wiadomości Nie znaleziono pliku @@ -430,7 +430,7 @@ Zauważ, że ta czynność spowoduje ponowne uruchomienie aplikacji i może to t Kraj Wybierz kraj Numer telefonu - Weryfikacja numeru + Weryfikacja numeru telefonu Wprowadź kod aktywacyjny Wystąpił błąd podczas weryfikowania numeru telefonu Kod @@ -615,9 +615,9 @@ Zezwól na dostęp w następnym oknie aby móc wykonać połączenie. Przyznaj dostęp w następnym oknie. Riot może sprawdzić Twoją książkę adresową, aby znajdywać innych użytkowników Matrixa bazując na ich adresie e-mail i numerze telefonu. Jeśli zgadzasz się na udostępnienie Twojej książki adresowej w tym celu, zezwól na dostęp w następnym okienku. - Riot wymaga dostępu do kontaktów, aby znajdywać innych użytkowników Matrixa bazując na adresie e-mail i numerze telefonu. - -Zezwolić Riot na dostęp do kontaktów? + Riot wymaga dostępu do kontaktów, aby znajdywać innych użytkowników Matrixa bazując na adresie e-mail i numerze telefonu. +\n +\nZezwolić Riot na dostęp do kontaktów\? Lista uczestników Otwarty nagłówek @@ -1232,4 +1232,22 @@ Spróbuj uruchomić ponownie aplikację. Utwórz kopię zapasową Twoje urządzenie używa przestarzałego protokołu bezpieczeństwa TSL, podatnego na ataki, dlatego dla Twojego bezpieczeństwa nie będziesz mógł się połączyć Kopia zapasowa klucza została prawidłowo skonfigurowana dla tego urządzenia. + Inicjalizacja usługi + Zaloguj się za pomocą logowania jednorazowego + Ustaw ważność powiadomienia za pomocą wydarzeń, skonfiguruj dźwięk, diodę LED, wibracje + Ważność powiadomień ze względu na wydarzenie + + Powiadomienia diagnostyczne + Rozwiązywanie problemów + Diagnostyka podstawowa nie wykazała problemów. Jeżeli wciąż nie otrzymujesz powiadomień, prosimy o przesłanie raportu o błędach, w celu ich rozwiązania. + Aplikacja nie potrzebuje łączyć się z serwerem domowym w tle, powinno to zredukować użycie baterii + Jeżeli nie pamiętasz swoich danych odzystkiwania, możesz %s. + + Zgubiłeś (-łaś) swój klucz odzyskiwania\? Możesz ustawić nowy w ustawieniach. + Kopia zapasowa posiada poprawną sygnaturę z niezweryfikowanego urządzenia %s + Wykryto nową, bezpieczną kopię kluczy wiadomości. +\n +\nJeżeli nie ustawiałeś nowej metody odzyskiwania, atakujący mogą uzyskać dostęp do Twojego konta. Zmień hasło konta i ustaw nową metodę odzyskiwania jak najszybciej w Ustawieniach. + Jesteś na bieżąco! + Ten adres URL jest nieosiągalny, proszę sprawdź jego poprawność diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 90c2cba1b3..f62a760a9c 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -264,7 +264,7 @@ Email также позволит вам при необходимости во Riot необходимы разрешения на доступ к камере и микрофону для видеовызовов. Пожалуйста дайте разрешение в следующем окне для звонка. - Riot необходимы разрешения на доступ к контактам, чтобы найти других пользователей сети по email или телефонному номеру. Пожалуйста разрешите доступ в следующем окне, чтобы ваши контакты были доступны в приложении. + Riot может проверить вашу адресную книгу, чтобы найти других пользователей Matrix по их электронной почте и номерам телефонов. Если вы согласны поделиться своей адресной книгой для этой цели, пожалуйста, откройте доступ на следующем всплывающем окне. Riot может проверить Вашу адресную книгу, чтобы найти других пользователей сети по email или телефонному номеру. \n \nСогласны ли вы поделиться своей адресной книгой для этой цели\? @@ -352,7 +352,7 @@ Email также позволит вам при необходимости во Сообщения не отправлены. %1$s или %2$s сейчас? Сообщения, не отправлены из-за присутствия неизвестных устройств. %1$s или %2$s сейчас? Повторить отправку - удалить все + Удалить все Отправить неотправленные сообщения Удалить неотправленные сообщения Файл не найден @@ -917,9 +917,9 @@ Email также позволит вам при необходимости во Получить аватар Заметка аватара - Лычки + Флэр - Эта комната не показывает лычки сообществ + Эта комната не показывает флэр сообществ Конфиденциальность уведомлений Нормальный Приложение нуждается в разрешении на работу в фоновом режиме @@ -1584,6 +1584,133 @@ Email также позволит вам при необходимости во Реакция Соглашаться Нравиться - Добавить реакцию + Добавить действие Посмотреть реакции + Менеджер интеграции + + Менеджер интеграции не настроен. + Реакции + + Удаленное пользователем событие + Мероприятие, модерируемое администратором помещения + Последний раз редактировался %s на %s + + + Некорректное событие, не может быть отображено + Создать новую комнату + Сети нет. Пожалуйста, проверьте подключение к Интернету. + Изменить + Изменить сеть + Пожалуйста, подождите… + Все сообщества + + Эту комнату нельзя предварительно просмотреть + Комнаты + Прямые сообщения + + Новая комната + СОЗДАТЬ + Имя комнаты + Публичные + Любой сможет присоединиться к этой комнате + Каталог номеров + Опубликовать эту комнату в каталоге номеров + + Произошла ошибка при получении информации о доверии + Произошла ошибка при получении ключей резервного копирования данных + + Добро пожаловать в бету! + Пока RiotX находится в ранней стадии разработки, некоторые функции могут отсутствовать и вы можете столкнуться с ошибками. + Последний список функций всегда находится в %1$s, и если вы найдете ошибку, пожалуйста, отправьте отчет в верхнее левое меню Home, и мы исправим их так быстро, как только сможем. + Описание магазина + Если вы обнаружите ошибку, пожалуйста, отправьте сообщение в верхнее левое меню Home, и мы исправим ее так быстро, как только сможем. + + Импорт ключей e2e из файла \"%1$s\". + + Версия Matrix SDK + Другие уведомления третьих сторон + Вы уже просмотрели эту комнату! + + Быстрое реагирование + + Общее + Установки + Безопасность & Конфиденциальность + Профессионал + Нажать Правила + app_id: + push_key: + app_display_name: + device_name: + Url: + Формат: + + Голос & Видио + Помощь и информация + + + Регистрационный токен + + Сделайте предложение + Пожалуйста, напишите ваше предложение ниже. + Опишите ваше предложение здесь + Спасибо, предложение было успешно отправлено + Предложение не было отправлено (%s) + + Показать скрытые события в временной шкале + + RiotX - Matrix клиент следующего поколения + Быстрый и легкий клиент для Matrix с новейшими фреймворками Android + RiotX - это новый клиент для матричного протокола (Matrix.org): открытой сети для безопасной децентрализованной связи. RiotX - это полная перезапись Riot Android клиента, основанная на полной перезаписи Matrix Android SDK. +\n +\nОговорка: Это бета-версия. В настоящее время RiotX находится в активной разработке и содержит ограничения и (надеемся, не слишком много) ошибки. Мы будем рады любым отзывам! +\n +\nПоддержка RiotX: - Войти в существующую учетную запись - Создать комнату и присоединиться к общей комнате - Принять и отклонить приглашения - Список комнат пользователей - Просмотр сведений о комнате - Отправить текстовые сообщения - Отправить вложение - Читать и писать сообщения в зашифрованных комнатах - Криптографически: Резервное копирование клавиш E2E, предварительная проверка устройства, запрос и ответ на общий доступ к ключам - Нажмите уведомление - Светлые, темные и черные темы +\n +\nНе все функции RiotX пока реализованы в RiotX. Основные отсутствующие (и скоро появятся!) особенности: - Создание учетной записи - Настройки комнат (список членов комнат и т.д.) - Создание прямых чатов - Вызовы - Виджеты - .… + + Предварительный просмотр открытой комнаты в RiotX пока не поддерживается. + + Прямые сообщения + + Ждите… + Шифрование миниатюры… + Отправка миниатюр (%1$s / %2$s) + Файл шифруется… + Файл отправляется (%1$s / %2$s) + + Файл %1$s загружается… + Файл %1$s был загружен! + + (отредактированный) + + %1$s для создания учетной записи. + Используйте старое приложение + + + Редактирование сообщений + Редактирование не найдено + + Отфильтровывать разговоры… + Не можете найти то, что ищете\? + Создать новую комнату + Отправить новое прямое сообщение + Просмотр список комнат + + Имя или ID (#example:matrix.org) + + Включить свайп, для ответа в хронологии + + Ссылка скопирована в буфер обмена + + Добавить по matrix ID + Создание комнаты… + "Результат не найден, используйте добавить matrix ID для поиска на сервере." + Начните печатать, чтобы получить результат + Фильтр по имени пользователя или ID… + + Присоединение к комнате… + + Просмотреть историю изменений + diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 8ab796fc56..0b6381aa6f 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -314,7 +314,7 @@ Dërgoni një përgjigje (të pafshehtëzuar)… Humbi lidhja me shërbyesin. Ridërgoji krejt - anuloji krejt + Anuloji krejt Ridërgo mesazhet e padërguara Fshi mesazhet e padërguar S’u gjet kartelë @@ -1531,4 +1531,51 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani \n \nNë RiotX s’janë sendërtuar ende krejt veçoritë e Riot-it. Veçori kryesore që mungojnë (dhe që do të vijnë së shpejti!): • Krijim llogarish • Rregullime dhome (shfaqje anëtarësh dhome, etj.) • Krijim dhomash fjalosjeje të drejtpërdrejtë • Thirrje • Widget-es • … + Përgjegjës Integrimesh + + Pa përgjegjës Integrimesh të formësuar. + app_id: + push_key: + app_display_name: + device_name: + Mesazhe të Drejtpërdrejtë + + Po pritet… + Po fshehtëzohet miniatura… + Po dërgohet miniaturë (%1$s / %2$s) + Po fshehtëzohet kartelë… + Po dërgohet kartelë (%1$s / %2$s) + + Po shkarkohet kartelë %1$s… + Kartela %1$s u shkarkua! + + (u përpunua) + + %1$s që të krijohet një llogari. + Përdor aplikacionin e dikurshëm + + + Përpunime Mesazhi + S’u gjetën përpunime + + Filtroni biseda… + S’gjeni dot ç’po kërkoni\? + Krijoni dhomë të re + Dërgoni një mesazh të drejtpërdrejtë + Shihni drejtori dhomash + + Emër ose ID (#example:matrix.org) + + Lidhja u kopjua në të papastër + + Shtoni sipas ID-je matrix + Po krijohet dhomë… + S’u gjetën përfundime, përdorni “Shtoni sipas ID-je matrix” që të kërkohet në shërbyes. + Filloni të shtypni që të merrni përfundime + Filtrojini sipas emrash përdoruesish ose ID-sh… + + Po hyhet në dhomë… + + Shihni Historik Përpunimesh + diff --git a/vector/src/main/res/values-vls/strings.xml b/vector/src/main/res/values-vls/strings.xml index e07f432da0..ff27a8fa4c 100644 --- a/vector/src/main/res/values-vls/strings.xml +++ b/vector/src/main/res/values-vls/strings.xml @@ -37,4 +37,13 @@ Sleuterback-up gebruukn Zy je zeker\? Back-up moakn + Je goat den toegank tou je versleuterde berichtn kwytspeeln, tenzy da j’eerst een back-up van je sleuters makt vooraleer da je jen afmeldt. + + Licensjes van derde partyen + + Loadn… + + Oké + Annuleern + Ipsloan diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 5be107e95d..332e7a82a1 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -1564,4 +1564,17 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意 連結已複製到剪貼簿 + 整合管理員 + + 未設定整合管理員。 + 透過 matrix ID 新增 + 正在建立聊天室…… + 找不到結果,在伺服器上使用透過 matrix ID 新增。 + 開始輸入以取得結果 + 透過使用者名稱或 ID 過濾…… + + 正在加入聊天室…… + + 檢視編輯歷史 + diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index c701387dc1..8b83175784 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -95,6 +95,8 @@ Done Abort Ignore + Review + Decline Exit @@ -1099,6 +1101,7 @@ Use keyboard enter key to send message Send voice messages This option requires a third party application to record the messages. + To continue you need to accept the Terms of this service. You added a new device \'%s\', which is requesting encryption keys. @@ -1467,6 +1470,8 @@ Why choose Riot.im? Unknown Error + "Previous versions of Riot had a security bug which could give your Identity Server (%1$s) access to your account. If you trust %2$s, you can ignore this; otherwise please logout and login again.\n\nRead more details here:\nhttps://medium.com/@RiotChat/36b4792ea0d6" + Edit Reply @@ -1640,4 +1645,12 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming View Edit History + + Terms of Service + Review Terms + Be discoverable by others + Use Bots, bridges, widgets and sticker packs + + Read at + diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 23ea1e2f0b..118fde8442 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -2,6 +2,5 @@ - Read at \ No newline at end of file From 88095e4bd97354a531eab5b7aa47c9f0a27d5497 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 30 Aug 2019 14:54:15 +0200 Subject: [PATCH 19/34] Add entry in change file --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 415cdff41d..85596e51c0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ Bugfix: - Regression / e2e replies not encrypted - Some video won't play - Privacy: remove log of notifiable event (#519) + - Fix crash with EmojiCompat (#530) Translations: - From 58f878fca943877e23dfc6722294a28b4c8085f4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 30 Aug 2019 15:04:28 +0200 Subject: [PATCH 20/34] Prepare version 0.4.0 --- CHANGES.md | 9 --------- vector/build.gradle | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 85596e51c0..d22665cffd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,9 +7,6 @@ Features: Improvements: - Reactions: Reinstate the ability to react with non-unicode keys (#307) -Other changes: - - - Bugfix: - Fix text diff linebreak display (#441) - Date change message repeats for each redaction until a normal message (#358) @@ -19,12 +16,6 @@ Bugfix: - Privacy: remove log of notifiable event (#519) - Fix crash with EmojiCompat (#530) -Translations: - - - -Build: - - - Changes in RiotX 0.3.0 (2019-08-08) =================================================== diff --git a/vector/build.gradle b/vector/build.gradle index f8c800d15d..71d37da681 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -15,7 +15,7 @@ androidExtensions { } ext.versionMajor = 0 -ext.versionMinor = 3 +ext.versionMinor = 4 ext.versionPatch = 0 static def getGitTimestamp() { From 0ff0b014a9df667f48d42d8fc36972306edc68cc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 30 Aug 2019 15:07:04 +0200 Subject: [PATCH 21/34] Version++ (0.5.0) --- CHANGES.md | 21 +++++++++++++++++++++ vector/build.gradle | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index d22665cffd..0a089e81bb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,24 @@ +Changes in RiotX 0.5.0 (2019-XX-XX) +=================================================== + +Features: + - + +Improvements: + - + +Other changes: + - + +Bugfix: + - + +Translations: + - + +Build: + - + Changes in RiotX 0.4.0 (2019-XX-XX) =================================================== diff --git a/vector/build.gradle b/vector/build.gradle index 71d37da681..9d49827610 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -15,7 +15,7 @@ androidExtensions { } ext.versionMajor = 0 -ext.versionMinor = 4 +ext.versionMinor = 5 ext.versionPatch = 0 static def getGitTimestamp() { From fd6bbbd3b58acd78bb233d75e0a7ca211636dd86 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 30 Aug 2019 15:57:39 +0200 Subject: [PATCH 22/34] Fix issue with version name (Fixes #533) --- CHANGES.md | 2 +- vector/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0a089e81bb..aa494b723b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,7 +17,7 @@ Translations: - Build: - - + - Fix issue with version name (#533) Changes in RiotX 0.4.0 (2019-XX-XX) =================================================== diff --git a/vector/build.gradle b/vector/build.gradle index 9d49827610..c69b5e5538 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -51,7 +51,7 @@ static def gitRevisionDate() { } static def gitBranchName() { - def cmd = "git name-rev --name-only HEAD" + def cmd = "git rev-parse --abbrev-ref HEAD" return cmd.execute().text.trim() } From 6879cc8ca82c1c64f38c11264573d1d60b2dc658 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 2 Sep 2019 14:24:36 +0200 Subject: [PATCH 23/34] Fix crash due to missing informationData (#535) --- CHANGES.md | 2 +- .../timeline/factory/MessageItemFactory.kt | 82 +++++++------------ 2 files changed, 32 insertions(+), 52 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index aa494b723b..a129b28d6a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,7 +11,7 @@ Other changes: - Bugfix: - - + - Fix crash due to missing informationData (#535) Translations: - diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt index f3a93a8d6d..3c636bfa58 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -28,15 +28,7 @@ import im.vector.matrix.android.api.permalinks.MatrixLinkify import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan import im.vector.matrix.android.api.session.events.model.RelationType import im.vector.matrix.android.api.session.events.model.toModel -import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent -import im.vector.matrix.android.api.session.room.model.message.MessageContent -import im.vector.matrix.android.api.session.room.model.message.MessageEmoteContent -import im.vector.matrix.android.api.session.room.model.message.MessageFileContent -import im.vector.matrix.android.api.session.room.model.message.MessageImageContent -import im.vector.matrix.android.api.session.room.model.message.MessageNoticeContent -import im.vector.matrix.android.api.session.room.model.message.MessageTextContent -import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent -import im.vector.matrix.android.api.session.room.model.message.getFileUrl +import im.vector.matrix.android.api.session.room.model.message.* import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt @@ -47,26 +39,12 @@ import im.vector.riotx.core.epoxy.VectorEpoxyModel import im.vector.riotx.core.linkify.VectorLinkify import im.vector.riotx.core.resources.ColorProvider import im.vector.riotx.core.resources.StringProvider -import im.vector.riotx.core.resources.UserPreferencesProvider import im.vector.riotx.core.utils.DebouncedClickListener import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController import im.vector.riotx.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider -import im.vector.riotx.features.home.room.detail.timeline.helper.senderAvatar -import im.vector.riotx.features.home.room.detail.timeline.item.BlankItem_ -import im.vector.riotx.features.home.room.detail.timeline.item.DefaultItem -import im.vector.riotx.features.home.room.detail.timeline.item.DefaultItem_ -import im.vector.riotx.features.home.room.detail.timeline.item.MessageFileItem -import im.vector.riotx.features.home.room.detail.timeline.item.MessageFileItem_ -import im.vector.riotx.features.home.room.detail.timeline.item.MessageImageVideoItem -import im.vector.riotx.features.home.room.detail.timeline.item.MessageImageVideoItem_ -import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData -import im.vector.riotx.features.home.room.detail.timeline.item.MessageTextItem -import im.vector.riotx.features.home.room.detail.timeline.item.MessageTextItem_ -import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem_ -import im.vector.riotx.features.home.room.detail.timeline.item.RedactedMessageItem -import im.vector.riotx.features.home.room.detail.timeline.item.RedactedMessageItem_ +import im.vector.riotx.features.home.room.detail.timeline.item.* import im.vector.riotx.features.home.room.detail.timeline.util.MessageInformationDataFactory import im.vector.riotx.features.html.EventHtmlRenderer import im.vector.riotx.features.media.ImageContentRenderer @@ -103,32 +81,28 @@ class MessageItemFactory @Inject constructor( val messageContent: MessageContent = event.getLastMessageContent() - ?: //Malformed content, we should echo something on screen - return DefaultItem_().text(stringProvider.getString(R.string.malformed_message)) + ?: //Malformed content, we should echo something on screen + return buildNotHandledMessageItem(stringProvider.getString(R.string.malformed_message), + informationData, highlight, callback) if (messageContent.relatesTo?.type == RelationType.REPLACE - || event.isEncrypted() && event.root.content.toModel()?.relatesTo?.type == RelationType.REPLACE + || event.isEncrypted() && event.root.content.toModel()?.relatesTo?.type == RelationType.REPLACE ) { - // This is an edit event, we should it when debugging as a notice event + // This is an edit event, we should display it when debugging as a notice event return noticeItemFactory.create(event, highlight, callback) } // val all = event.root.toContent() // val ev = all.toModel() return when (messageContent) { - is MessageEmoteContent -> buildEmoteMessageItem(messageContent, - informationData, - highlight, - callback) - is MessageTextContent -> buildTextMessageItem(messageContent, - informationData, - highlight, - callback) + is MessageEmoteContent -> buildEmoteMessageItem(messageContent, informationData, highlight, callback) + is MessageTextContent -> buildTextMessageItem(messageContent, informationData, highlight, callback) is MessageImageContent -> buildImageMessageItem(messageContent, informationData, highlight, callback) is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback) is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback) is MessageFileContent -> buildFileMessageItem(messageContent, informationData, highlight, callback) is MessageAudioContent -> buildAudioMessageItem(messageContent, informationData, highlight, callback) - else -> buildNotHandledMessageItem(messageContent, highlight) + else -> buildNotHandledMessageItem("${messageContent.type} message events are not yet handled", + informationData, highlight, callback) } } @@ -157,7 +131,7 @@ class MessageItemFactory @Inject constructor( })) .longClickListener { view -> return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view) - ?: false + ?: false } } @@ -182,7 +156,7 @@ class MessageItemFactory @Inject constructor( })) .longClickListener { view -> return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view) - ?: false + ?: false } .clickListener( DebouncedClickListener(View.OnClickListener { _ -> @@ -190,11 +164,17 @@ class MessageItemFactory @Inject constructor( })) } - private fun buildNotHandledMessageItem(messageContent: MessageContent, highlight: Boolean): DefaultItem? { - val text = "${messageContent.type} message events are not yet handled" + private fun buildNotHandledMessageItem(text: String, + informationData: MessageInformationData, + highlight: Boolean, + callback: TimelineEventController.Callback?): DefaultItem? { return DefaultItem_() .text(text) + .avatarRenderer(avatarRenderer) .highlighted(highlight) + .informationData(informationData) + .baseCallback(callback) + .readReceiptsCallback(callback) } private fun buildImageMessageItem(messageContent: MessageImageContent, @@ -237,7 +217,7 @@ class MessageItemFactory @Inject constructor( })) .longClickListener { view -> return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view) - ?: false + ?: false } } @@ -250,7 +230,7 @@ class MessageItemFactory @Inject constructor( val thumbnailData = ImageContentRenderer.Data( filename = messageContent.body, url = messageContent.videoInfo?.thumbnailFile?.url - ?: messageContent.videoInfo?.thumbnailUrl, + ?: messageContent.videoInfo?.thumbnailUrl, elementToDecrypt = messageContent.videoInfo?.thumbnailFile?.toElementToDecrypt(), height = messageContent.videoInfo?.height, maxHeight = maxHeight, @@ -286,7 +266,7 @@ class MessageItemFactory @Inject constructor( .clickListener { view -> callback?.onVideoMessageClicked(messageContent, videoData, view) } .longClickListener { view -> return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view) - ?: false + ?: false } } @@ -326,7 +306,7 @@ class MessageItemFactory @Inject constructor( })) .longClickListener { view -> return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view) - ?: false + ?: false } } @@ -356,9 +336,9 @@ class MessageItemFactory @Inject constructor( //nop } }, - editStart, - editEnd, - Spanned.SPAN_INCLUSIVE_EXCLUSIVE) + editStart, + editEnd, + Spanned.SPAN_INCLUSIVE_EXCLUSIVE) return spannable } @@ -396,7 +376,7 @@ class MessageItemFactory @Inject constructor( })) .longClickListener { view -> return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view) - ?: false + ?: false } } @@ -433,7 +413,7 @@ class MessageItemFactory @Inject constructor( })) .longClickListener { view -> return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view) - ?: false + ?: false } } @@ -453,7 +433,7 @@ class MessageItemFactory @Inject constructor( })) .longClickListener { view -> return@longClickListener callback?.onEventLongClicked(informationData, null, view) - ?: false + ?: false } } From eec2abf164f0b1f79ef5a7c58754e0e7e15bc5fe Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 2 Sep 2019 14:33:53 +0200 Subject: [PATCH 24/34] Reduce release build log level --- CHANGES.md | 2 +- .../java/im/vector/riotx/VectorApplication.kt | 9 ++- .../vector/riotx/core/di/VectorComponent.kt | 3 + .../riotx/features/rageshake/BugReporter.kt | 5 +- .../features/rageshake/VectorFileLogger.kt | 81 +++++++++++-------- .../features/settings/VectorPreferences.kt | 6 ++ vector/src/main/res/values/strings_riotX.xml | 1 + .../src/main/res/xml/vector_settings_labs.xml | 6 ++ 8 files changed, 73 insertions(+), 40 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index aa494b723b..02c14b849f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features: - Improvements: - - + - Reduce default release build log level, and lab option to enable more logs. Other changes: - diff --git a/vector/src/main/java/im/vector/riotx/VectorApplication.kt b/vector/src/main/java/im/vector/riotx/VectorApplication.kt index b62c44f58c..cd4a97327e 100644 --- a/vector/src/main/java/im/vector/riotx/VectorApplication.kt +++ b/vector/src/main/java/im/vector/riotx/VectorApplication.kt @@ -86,9 +86,12 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration. vectorComponent = DaggerVectorComponent.factory().create(this) vectorComponent.inject(this) vectorUncaughtExceptionHandler.activate(this) - // Log - VectorFileLogger.init(this) - Timber.plant(Timber.DebugTree(), VectorFileLogger) + + if (BuildConfig.DEBUG) { + Timber.plant(Timber.DebugTree()) + } + Timber.plant(vectorComponent.vectorFileLogger()) + if (BuildConfig.DEBUG) { Stetho.initializeWithDefaults(this) } diff --git a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt index 7cbbc30673..0549222428 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt @@ -41,6 +41,7 @@ import im.vector.riotx.features.notifications.NotificationBroadcastReceiver import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.notifications.PushRuleTriggerListener import im.vector.riotx.features.rageshake.BugReporter +import im.vector.riotx.features.rageshake.VectorFileLogger import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler import im.vector.riotx.features.settings.VectorPreferences import javax.inject.Singleton @@ -101,6 +102,8 @@ interface VectorComponent { fun vectorPreferences(): VectorPreferences + fun vectorFileLogger(): VectorFileLogger + @Component.Factory interface Factory { fun create(@BindsInstance context: Context): VectorComponent diff --git a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt index d21ad021d8..c678f47d99 100755 --- a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt @@ -52,7 +52,8 @@ import javax.inject.Singleton */ @Singleton class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSessionHolder, - private val versionProvider: VersionProvider) { + private val versionProvider: VersionProvider, + private val vectorFileLogger : VectorFileLogger) { var inMultiWindowMode = false companion object { @@ -162,7 +163,7 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes val gzippedFiles = ArrayList() if (withDevicesLogs) { - val files = VectorFileLogger.getLogFiles() + val files = vectorFileLogger.getLogFiles() for (f in files) { if (!mIsCancelled) { diff --git a/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt b/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt index cdea1f0d30..3ef5e19830 100644 --- a/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt +++ b/vector/src/main/java/im/vector/riotx/features/rageshake/VectorFileLogger.kt @@ -17,43 +17,74 @@ package im.vector.riotx.features.rageshake import android.content.Context -import android.text.TextUtils +import android.util.Log +import im.vector.riotx.features.settings.VectorPreferences import timber.log.Timber import java.io.File -import java.io.IOException import java.io.PrintWriter import java.io.StringWriter import java.text.SimpleDateFormat import java.util.* import java.util.logging.* import java.util.logging.Formatter +import javax.inject.Inject +import javax.inject.Singleton import kotlin.collections.ArrayList -object VectorFileLogger : Timber.DebugTree() { +private const val LOG_SIZE_BYTES = 20 * 1024 * 1024 // 20MB - private const val LOG_SIZE_BYTES = 50 * 1024 * 1024 // 50MB +private const val LOG_ROTATION_COUNT = 3 + + +@Singleton +class VectorFileLogger @Inject constructor(val context: Context, private val vectorPreferences: VectorPreferences) : Timber.DebugTree() { - // relatively large rotation count because closing > opening the app rotates the log (!) - private const val LOG_ROTATION_COUNT = 15 private val sLogger = Logger.getLogger("im.vector.riotx") - private lateinit var sFileHandler: FileHandler - private lateinit var sCacheDirectory: File - private var sFileName = "riotx" + private var sFileHandler: FileHandler? = null + private var sCacheDirectory: File? = null + private var sFileName = "riotxlogs" - fun init(context: Context) { + private val prioPrefixes = mapOf( + Log.VERBOSE to "V/ ", + Log.DEBUG to "D/ ", + Log.INFO to "I/ ", + Log.WARN to "W/ ", + Log.ERROR to "E/ ", + Log.ASSERT to "WTF/ " + ) + + init { val logsDirectoryFile = context.cacheDir.absolutePath + "/logs" - setLogDirectory(File(logsDirectoryFile)) - init("RiotXLog") + try { + if (sCacheDirectory != null) { + sFileHandler = FileHandler(sCacheDirectory!!.absolutePath + "/" + sFileName + ".%g.txt", LOG_SIZE_BYTES, LOG_ROTATION_COUNT) + sFileHandler?.formatter = LogFormatter() + sLogger.useParentHandlers = false + sLogger.level = Level.ALL + sLogger.addHandler(sFileHandler) + } + } catch (e: Throwable) { + Timber.e(e, "Failed to initialize FileLogger") + } } override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { + if (sFileHandler == null) return + if (skipLog(priority)) return if (t != null) { logToFile(t) } + logToFile(prioPrefixes[priority] ?: "$priority ", tag ?: "Tag", message) + } - logToFile("$priority ", tag ?: "Tag", message) + private fun skipLog(priority: Int): Boolean { + return if (vectorPreferences.labAllowedExtendedLogging()) { + false + } else { + priority < Log.ERROR + } } /** @@ -68,24 +99,6 @@ object VectorFileLogger : Timber.DebugTree() { sCacheDirectory = cacheDir } - /** - * Initialises the logger. Should be called AFTER [Log.setLogDirectory]. - * - * @param fileName the base file name - */ - private fun init(fileName: String) { - try { - if (!TextUtils.isEmpty(fileName)) { - sFileName = fileName - } - sFileHandler = FileHandler(sCacheDirectory.absolutePath + "/" + sFileName + ".%g.txt", LOG_SIZE_BYTES, LOG_ROTATION_COUNT) - sFileHandler.formatter = LogFormatter() - sLogger.useParentHandlers = false - sLogger.level = Level.ALL - sLogger.addHandler(sFileHandler) - } catch (e: IOException) { - } - } /** * Adds our own log files to the provided list of files. @@ -99,8 +112,8 @@ object VectorFileLogger : Timber.DebugTree() { try { // reported by GA if (null != sFileHandler) { - sFileHandler.flush() - val absPath = sCacheDirectory.absolutePath + sFileHandler!!.flush() + val absPath = sCacheDirectory?.absolutePath ?: return emptyList() for (i in 0..LOG_ROTATION_COUNT) { val filepath = "$absPath/$sFileName.$i.txt" @@ -111,7 +124,7 @@ object VectorFileLogger : Timber.DebugTree() { } } } catch (e: Exception) { - Timber.e(e, "## addLogFiles() failed : " + e.message) + Timber.e(e, "## addLogFiles() failed : %s", e.message) } return files diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt index 8ba6c7ed12..7116f33a70 100755 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt @@ -149,6 +149,8 @@ class VectorPreferences @Inject constructor(private val context: Context) { private const val SETTINGS_USE_NATIVE_CAMERA_PREFERENCE_KEY = "SETTINGS_USE_NATIVE_CAMERA_PREFERENCE_KEY" private const val SETTINGS_ENABLE_SEND_VOICE_FEATURE_PREFERENCE_KEY = "SETTINGS_ENABLE_SEND_VOICE_FEATURE_PREFERENCE_KEY" + const val SETTINGS_LABS_ALLOW_EXTENDED_LOGS = "SETTINGS_LABS_ALLOW_EXTENDED_LOGS" + private const val SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY = "SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY" private const val SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY = "SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY" @@ -257,6 +259,10 @@ class VectorPreferences @Inject constructor(private val context: Context) { return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY, true) } + fun labAllowedExtendedLogging(): Boolean { + return defaultPrefs.getBoolean(SETTINGS_LABS_ALLOW_EXTENDED_LOGS, false) + } + /** * Tells if we have already asked the user to disable battery optimisations on android >= M devices. * diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 118fde8442..877512d713 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -2,5 +2,6 @@ + Help developers by allowing extended logging. \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_labs.xml b/vector/src/main/res/xml/vector_settings_labs.xml index 5620517216..cb0cba3351 100644 --- a/vector/src/main/res/xml/vector_settings_labs.xml +++ b/vector/src/main/res/xml/vector_settings_labs.xml @@ -45,6 +45,12 @@ android:key="SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY" android:title="@string/labs_swipe_to_reply_in_timeline" /> + + + \ No newline at end of file From e89ba7b87bc242a3a272e5163f9b34243e887039 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Sep 2019 15:23:38 +0200 Subject: [PATCH 25/34] Update wording --- vector/src/main/res/values/strings_riotX.xml | 3 ++- vector/src/main/res/xml/vector_settings_labs.xml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml index 877512d713..3dd8c6b36a 100644 --- a/vector/src/main/res/values/strings_riotX.xml +++ b/vector/src/main/res/values/strings_riotX.xml @@ -2,6 +2,7 @@ - Help developers by allowing extended logging. + Enable verbose logs. + Verbose logs will help developers by providing more logs when you send a RageShake. Even when enabled, the application does not log message contents or any other private data. \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_labs.xml b/vector/src/main/res/xml/vector_settings_labs.xml index cb0cba3351..e9e5e27198 100644 --- a/vector/src/main/res/xml/vector_settings_labs.xml +++ b/vector/src/main/res/xml/vector_settings_labs.xml @@ -49,6 +49,7 @@ From ed39b02924748201bc92ad92de61985a5c151b00 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Sep 2019 15:36:20 +0200 Subject: [PATCH 26/34] Avoid using keyword for variable names --- .../api/pushrules/RoomMemberCountCondition.kt | 6 +++--- .../vector/riotx/features/rageshake/BugReporter.kt | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/RoomMemberCountCondition.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/RoomMemberCountCondition.kt index 1c02d63d76..d0b76fbab7 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/RoomMemberCountCondition.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/pushrules/RoomMemberCountCondition.kt @@ -21,14 +21,14 @@ import timber.log.Timber private val regex = Regex("^(==|<=|>=|<|>)?(\\d*)$") -class RoomMemberCountCondition(val `is`: String) : Condition(Kind.room_member_count) { +class RoomMemberCountCondition(val iz: String) : Condition(Kind.room_member_count) { override fun isSatisfied(conditionResolver: ConditionResolver): Boolean { return conditionResolver.resolveRoomMemberCountCondition(this) } override fun technicalDescription(): String { - return "Room member count is $`is`" + return "Room member count is $iz" } fun isSatisfied(event: Event, session: RoomService?): Boolean { @@ -55,7 +55,7 @@ class RoomMemberCountCondition(val `is`: String) : Condition(Kind.room_member_co */ private fun parseIsField(): Pair? { try { - val match = regex.find(`is`) ?: return null + val match = regex.find(iz) ?: return null val (prefix, count) = match.destructured return prefix to count.toInt() } catch (t: Throwable) { diff --git a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt index c678f47d99..39a57b8785 100755 --- a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt @@ -349,20 +349,20 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes } else if (null == response || null == response.body()) { serverError = "Failed with error $responseCode" } else { - var `is`: InputStream? = null + var inputStream: InputStream? = null try { - `is` = response.body()!!.byteStream() + inputStream = response.body()!!.byteStream() - if (null != `is`) { - var ch = `is`.read() + if (null != inputStream) { + var ch = inputStream.read() val b = StringBuilder() while (ch != -1) { b.append(ch.toChar()) - ch = `is`.read() + ch = inputStream.read() } serverError = b.toString() - `is`.close() + inputStream.close() // check if the error message try { @@ -381,7 +381,7 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes Timber.e(e, "## sendBugReport() : failed to parse error " + e.message) } finally { try { - `is`?.close() + inputStream?.close() } catch (e: Exception) { Timber.e(e, "## sendBugReport() : failed to close the error stream " + e.message) } From a23be05cbf2f9fea52470f843f1ab4e0d57bceeb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Sep 2019 15:38:14 +0200 Subject: [PATCH 27/34] Better type --- .../android/internal/crypto/keysbackup/KeysBackup.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt index edd2e19027..786923dad5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackup.kt @@ -67,7 +67,6 @@ import org.matrix.olm.OlmPkMessage import timber.log.Timber import java.security.InvalidParameterException import javax.inject.Inject -import kotlin.collections.HashMap import kotlin.random.Random /** @@ -846,7 +845,7 @@ internal class KeysBackup @Inject constructor( // Wait between 0 and 10 seconds, to avoid backup requests from // different clients hitting the server all at the same time when a // new key is sent - val delayInMs = Random.nextInt(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS).toLong() + val delayInMs = Random.nextLong(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS) uiHandler.postDelayed({ backupKeys() }, delayInMs) } @@ -1305,7 +1304,7 @@ internal class KeysBackup @Inject constructor( // Make the request storeSessionDataTask - .configureWith(StoreSessionsDataTask.Params(keysBackupVersion!!.version!!, keysBackupData)){ + .configureWith(StoreSessionsDataTask.Params(keysBackupVersion!!.version!!, keysBackupData)) { this.callback = sendingRequestCallback } .executeBy(taskExecutor) @@ -1403,7 +1402,7 @@ internal class KeysBackup @Inject constructor( companion object { // Maximum delay in ms in {@link maybeBackupKeys} - private const val KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS = 10000 + private const val KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS = 10_000L // Maximum number of keys to send at a time to the homeserver. private const val KEY_BACKUP_SEND_KEYS_MAX_COUNT = 100 From 242e60fcaaf0b1c9343987090369da5bfb6e1eb4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Sep 2019 16:14:34 +0200 Subject: [PATCH 28/34] Rename CryptoManager to DefaultCryptoService --- .../matrix/android/internal/crypto/CryptoModule.kt | 2 +- .../{CryptoManager.kt => DefaultCryptoService.kt} | 4 ++-- .../android/internal/session/DefaultSession.kt | 4 ++-- .../internal/session/sync/CryptoSyncHandler.kt | 10 +++++----- .../android/internal/session/sync/RoomSyncHandler.kt | 8 ++++---- .../internal/session/sync/SyncResponseHandler.kt | 12 ++++++------ 6 files changed, 20 insertions(+), 20 deletions(-) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/{CryptoManager.kt => DefaultCryptoService.kt} (99%) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt index 5ed0c0e29f..4272dbd340 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt @@ -105,7 +105,7 @@ internal abstract class CryptoModule { } @Binds - abstract fun bindCryptoService(cryptoManager: CryptoManager): CryptoService + abstract fun bindCryptoService(cryptoService: DefaultCryptoService): CryptoService @Binds abstract fun bindDeleteDeviceTask(deleteDeviceTask: DefaultDeleteDeviceTask): DeleteDeviceTask diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt similarity index 99% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt index 96d337bd2d..a3786d481d 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt @@ -93,7 +93,7 @@ import kotlin.math.max * Specially, it tracks all room membership changes events in order to do keys updates. */ @SessionScope -internal class CryptoManager @Inject constructor( +internal class DefaultCryptoService @Inject constructor( // Olm Manager private val olmManager: OlmManager, // The credentials, @@ -1067,6 +1067,6 @@ internal class CryptoManager @Inject constructor( * ========================================================================================== */ override fun toString(): String { - return "CryptoManager of " + credentials.userId + " (" + credentials.deviceId + ")" + return "DefaultCryptoService of " + credentials.userId + " (" + credentials.deviceId + ")" } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt index 2922b7d6de..a18c339b47 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt @@ -40,7 +40,7 @@ import im.vector.matrix.android.api.session.sync.FilterService import im.vector.matrix.android.api.session.sync.SyncState import im.vector.matrix.android.api.session.user.UserService import im.vector.matrix.android.api.util.MatrixCallbackDelegate -import im.vector.matrix.android.internal.crypto.CryptoManager +import im.vector.matrix.android.internal.crypto.DefaultCryptoService import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.session.sync.job.SyncThread import im.vector.matrix.android.internal.session.sync.job.SyncWorker @@ -63,7 +63,7 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se private val signOutService: Lazy, private val pushRuleService: Lazy, private val pushersService: Lazy, - private val cryptoService: Lazy, + private val cryptoService: Lazy, private val fileService: Lazy, private val syncThreadProvider: Provider, private val contentUrlResolver: ContentUrlResolver, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt index 013fc3ca52..945f344036 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt @@ -22,7 +22,7 @@ import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.message.MessageContent -import im.vector.matrix.android.internal.crypto.CryptoManager +import im.vector.matrix.android.internal.crypto.DefaultCryptoService import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService @@ -33,7 +33,7 @@ import timber.log.Timber import javax.inject.Inject -internal class CryptoSyncHandler @Inject constructor(private val cryptoManager: CryptoManager, +internal class CryptoSyncHandler @Inject constructor(private val cryptoService: DefaultCryptoService, private val sasVerificationService: DefaultSasVerificationService) { fun handleToDevice(toDevice: ToDeviceSyncResponse, initialSyncProgressService: DefaultInitialSyncProgressService? = null) { @@ -47,13 +47,13 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoManager: Timber.e("## handleToDeviceEvent() : Warning: Unable to decrypt to-device event : " + event.content) } else { sasVerificationService.onToDeviceEvent(event) - cryptoManager.onToDeviceEvent(event) + cryptoService.onToDeviceEvent(event) } } } fun onSyncCompleted(syncResponse: SyncResponse) { - cryptoManager.onSyncCompleted(syncResponse) + cryptoService.onSyncCompleted(syncResponse) } @@ -68,7 +68,7 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoManager: if (event.getClearType() == EventType.ENCRYPTED) { var result: MXEventDecryptionResult? = null try { - result = cryptoManager.decryptEvent(event, timelineId ?: "") + result = cryptoService.decryptEvent(event, timelineId ?: "") } catch (exception: MXCryptoError) { event.mCryptoError = (exception as? MXCryptoError.Base)?.errorType //setCryptoError(exception.cryptoError) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index 74b56e774c..0ebca5e130 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -23,7 +23,7 @@ import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.tag.RoomTagContent -import im.vector.matrix.android.internal.crypto.CryptoManager +import im.vector.matrix.android.internal.crypto.DefaultCryptoService import im.vector.matrix.android.internal.database.helper.* import im.vector.matrix.android.internal.database.model.ChunkEntity import im.vector.matrix.android.internal.database.model.EventEntityFields @@ -50,7 +50,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch private val readReceiptHandler: ReadReceiptHandler, private val roomSummaryUpdater: RoomSummaryUpdater, private val roomTagHandler: RoomTagHandler, - private val cryptoManager: CryptoManager, + private val cryptoService: DefaultCryptoService, private val tokenStore: SyncTokenStore, private val pushRuleService: DefaultPushRuleService, private val processForPushTask: ProcessEventForPushTask, @@ -141,7 +141,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch roomSync.state.events.forEach { event -> roomEntity.addStateEvent(event, filterDuplicates = true, stateIndex = untimelinedStateIndex) // Give info to crypto module - cryptoManager.onStateEvent(roomId, event) + cryptoService.onStateEvent(roomId, event) UserEntityFactory.createOrNull(event)?.also { realm.insertOrUpdate(it) } @@ -214,7 +214,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch event.eventId?.also { eventIds.add(it) } chunkEntity.add(roomEntity.roomId, event, PaginationDirection.FORWARDS, stateIndexOffset) // Give info to crypto module - cryptoManager.onLiveEvent(roomEntity.roomId, event) + cryptoService.onLiveEvent(roomEntity.roomId, event) // Try to remove local echo event.unsignedData?.transactionId?.also { val sendingEventEntity = roomEntity.sendingTimelineEvents.find(it) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt index 991e5a9a1a..584e84c2ae 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt @@ -18,7 +18,7 @@ package im.vector.matrix.android.internal.session.sync import arrow.core.Try import im.vector.matrix.android.R -import im.vector.matrix.android.internal.crypto.CryptoManager +import im.vector.matrix.android.internal.crypto.DefaultCryptoService import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService import im.vector.matrix.android.internal.session.reportSubtask import im.vector.matrix.android.internal.session.sync.model.SyncResponse @@ -30,7 +30,7 @@ internal class SyncResponseHandler @Inject constructor(private val roomSyncHandl private val userAccountDataSyncHandler: UserAccountDataSyncHandler, private val groupSyncHandler: GroupSyncHandler, private val cryptoSyncHandler: CryptoSyncHandler, - private val cryptoManager: CryptoManager, + private val cryptoService: DefaultCryptoService, private val initialSyncProgressService: DefaultInitialSyncProgressService) { fun handleResponse(syncResponse: SyncResponse, fromToken: String?, isCatchingUp: Boolean): Try { @@ -40,12 +40,12 @@ internal class SyncResponseHandler @Inject constructor(private val roomSyncHandl val reporter = initialSyncProgressService.takeIf { isInitialSync } measureTimeMillis { - if (!cryptoManager.isStarted()) { - Timber.v("Should start cryptoManager") - cryptoManager.start(isInitialSync) + if (!cryptoService.isStarted()) { + Timber.v("Should start cryptoService") + cryptoService.start(isInitialSync) } }.also { - Timber.v("Finish handling start cryptoManager in $it ms") + Timber.v("Finish handling start cryptoService in $it ms") } val measure = measureTimeMillis { // Handle the to device events before the room ones From 38da4b9ee502ff070e2dd00e3debdc9b6f19b9b7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Sep 2019 17:02:03 +0200 Subject: [PATCH 29/34] Cleanup and document DefaultInitialSyncProgressService --- .../DefaultInitialSyncProgressService.kt | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt index f1f8a6e37d..69f608d0d5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt @@ -15,6 +15,7 @@ */ package im.vector.matrix.android.internal.session +import androidx.annotation.StringRes import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import im.vector.matrix.android.api.session.InitialSyncProgressService @@ -25,31 +26,33 @@ import javax.inject.Inject @SessionScope class DefaultInitialSyncProgressService @Inject constructor() : InitialSyncProgressService { - var status = MutableLiveData() + private var status = MutableLiveData() - var rootTask: TaskInfo? = null + private var rootTask: TaskInfo? = null override fun getLiveStatus(): LiveData { return status } - - fun startTask(nameRes: Int, totalProgress: Int, parentWeight: Float = 1f) { + fun startTask(@StringRes nameRes: Int, totalProgress: Int, parentWeight: Float = 1f) { + // Create a rootTask, or add a child to the leaf if (rootTask == null) { rootTask = TaskInfo(nameRes, totalProgress) } else { val currentLeaf = rootTask!!.leaf() - val newTask = TaskInfo(nameRes, totalProgress) - newTask.parent = currentLeaf - newTask.offset = currentLeaf.currentProgress + + val newTask = TaskInfo(nameRes, + totalProgress, + currentLeaf, + parentWeight) + currentLeaf.child = newTask - newTask.parentWeight = parentWeight } reportProgress(0) } fun reportProgress(progress: Int) { - rootTask?.leaf()?.incrementProgress(progress) + rootTask?.leaf()?.setProgress(progress) } fun endTask(nameRes: Int) { @@ -58,7 +61,7 @@ class DefaultInitialSyncProgressService @Inject constructor() : InitialSyncProgr //close it val parent = endedTask.parent parent?.child = null - parent?.incrementProgress(endedTask.offset + (endedTask.totalProgress * endedTask.parentWeight).toInt()) + parent?.setProgress(endedTask.offset + (endedTask.totalProgress * endedTask.parentWeight).toInt()) } if (endedTask?.parent == null) { status.postValue(null) @@ -71,14 +74,17 @@ class DefaultInitialSyncProgressService @Inject constructor() : InitialSyncProgr } - inner class TaskInfo(var nameRes: Int, - var totalProgress: Int) { - var parent: TaskInfo? = null + private inner class TaskInfo(@StringRes var nameRes: Int, + var totalProgress: Int, + var parent: TaskInfo? = null, + var parentWeight: Float = 1f, + var offset: Int = parent?.currentProgress ?: 0) { var child: TaskInfo? = null - var parentWeight: Float = 1f var currentProgress: Int = 0 - var offset: Int = 0 + /** + * Get the further child + */ fun leaf(): TaskInfo { var last = this while (last.child != null) { @@ -87,26 +93,27 @@ class DefaultInitialSyncProgressService @Inject constructor() : InitialSyncProgr return last } - fun incrementProgress(progress: Int) { + /** + * Set progress of the parent if any (which will post value), or post the value + */ + fun setProgress(progress: Int) { currentProgress = progress // val newProgress = Math.min(currentProgress + progress, totalProgress) parent?.let { val parentProgress = (currentProgress * parentWeight).toInt() - it.incrementProgress(offset + parentProgress) - } - if (parent == null) { - Timber.e("--- ${leaf().nameRes}: ${currentProgress}") + it.setProgress(offset + parentProgress) + } ?: run { + Timber.e("--- ${leaf().nameRes}: $currentProgress") status.postValue( InitialSyncProgressService.Status(leaf().nameRes, currentProgress) ) } } } - } inline fun reportSubtask(reporter: DefaultInitialSyncProgressService?, - nameRes: Int, + @StringRes nameRes: Int, totalProgress: Int, parentWeight: Float = 1f, block: () -> T): T { From a5975a099efe833f0050e49d3986224fefc08f1c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Sep 2019 17:23:09 +0200 Subject: [PATCH 30/34] Cleanup and document DefaultInitialSyncProgressService --- .../api/session/InitialSyncProgressService.kt | 4 ++-- .../session/DefaultInitialSyncProgressService.kt | 2 +- .../im/vector/riotx/features/home/HomeActivity.kt | 15 +++++---------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/InitialSyncProgressService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/InitialSyncProgressService.kt index 3bb567ae00..a4c9d81beb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/InitialSyncProgressService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/InitialSyncProgressService.kt @@ -20,10 +20,10 @@ import androidx.lifecycle.LiveData interface InitialSyncProgressService { - fun getLiveStatus() : LiveData + fun getInitialSyncProgressStatus() : LiveData data class Status( - @StringRes val statusText: Int?, + @StringRes val statusText: Int, val percentProgress: Int = 0 ) } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt index 69f608d0d5..1d3ce23302 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt @@ -30,7 +30,7 @@ class DefaultInitialSyncProgressService @Inject constructor() : InitialSyncProgr private var rootTask: TaskInfo? = null - override fun getLiveStatus(): LiveData { + override fun getInitialSyncProgressStatus(): LiveData { return status } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt index 64a86b9040..247c0c1981 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeActivity.kt @@ -26,7 +26,6 @@ import androidx.appcompat.widget.Toolbar import androidx.core.view.GravityCompat import androidx.core.view.isVisible import androidx.drawerlayout.widget.DrawerLayout -import androidx.fragment.app.FragmentManager import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.airbnb.mvrx.viewModel @@ -36,12 +35,10 @@ import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.hideKeyboard import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.extensions.replaceFragment -import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.core.pushers.PushersManager import im.vector.riotx.features.disclaimer.showDisclaimerDialog -import im.vector.riotx.features.navigation.Navigator import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler import im.vector.riotx.features.workers.signout.SignOutViewModel @@ -119,22 +116,22 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { intent.removeExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION) } - activeSessionHolder.getSafeActiveSession()?.getLiveStatus()?.observe(this, Observer { sprogress -> - Timber.e("${sprogress?.statusText?.let { getString(it) }} ${sprogress?.percentProgress}") - if (sprogress == null) { + activeSessionHolder.getSafeActiveSession()?.getInitialSyncProgressStatus()?.observe(this, Observer { status -> + if (status == null) { waiting_view.isVisible = false } else { + Timber.e("${getString(status.statusText)} ${status.percentProgress}") waiting_view.setOnClickListener { //block interactions } waiting_view_status_horizontal_progress.apply { isIndeterminate = false max = 100 - progress = sprogress.percentProgress + progress = status.percentProgress isVisible = true } waiting_view_status_text.apply { - text = sprogress.statusText?.let { getString(it) } + text = getString(status.statusText) isVisible = true } waiting_view.isVisible = true @@ -213,8 +210,6 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable { } - - companion object { private const val EXTRA_CLEAR_EXISTING_NOTIFICATION = "EXTRA_CLEAR_EXISTING_NOTIFICATION" From 012840abbae87b92b424534dd2f45c3ea48b9ce2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Sep 2019 18:14:05 +0200 Subject: [PATCH 31/34] Progress in initial sync dialog is decreasing for a step and should not (#532) --- CHANGES.md | 1 + .../session/DefaultInitialSyncProgressService.kt | 6 +++--- .../internal/session/sync/RoomSyncHandler.kt | 16 ++++++---------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index df1379d4e2..7655c08dc5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Other changes: Bugfix: - Fix crash due to missing informationData (#535) + - Progress in initial sync dialog is decreasing for a step and should not (#532) Translations: - diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt index 1d3ce23302..6eb1ec35c1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultInitialSyncProgressService.kt @@ -128,11 +128,11 @@ inline fun Map.mapWithProgress(reporter: DefaultInitialSyncP taskId: Int, weight: Float, transform: (Map.Entry) -> R): List { - val total = count() + val total = count().toFloat() var current = 0 reporter?.startTask(taskId, 100, weight) - return this.map { - reporter?.reportProgress((current / total.toFloat() * 100).toInt()) + return map { + reporter?.reportProgress((current / total * 100).toInt()) current++ transform.invoke(it) }.also { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index 0ebca5e130..fccaa9b9b2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -97,12 +97,12 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch handleJoinedRoom(realm, it.key, it.value, isInitialSync) } is HandlingStrategy.INVITED -> - handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_invited_rooms, 0.4f) { + handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_invited_rooms, 0.1f) { handleInvitedRoom(realm, it.key, it.value) } is HandlingStrategy.LEFT -> { - handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_left_rooms, 0.2f) { + handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_left_rooms, 0.3f) { handleLeftRoom(realm, it.key, it.value) } } @@ -125,8 +125,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch handleRoomAccountDataEvents(realm, roomId, roomSync.accountData) } - val roomEntity = RoomEntity.where(realm, roomId).findFirst() - ?: realm.createObject(roomId) + val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) if (roomEntity.membership == Membership.INVITE) { roomEntity.chunks.deleteAllFromRealm() @@ -135,8 +134,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch // State event if (roomSync.state != null && roomSync.state.events.isNotEmpty()) { - val minStateIndex = roomEntity.untimelinedStateEvents.where().min(EventEntityFields.STATE_INDEX)?.toInt() - ?: Int.MIN_VALUE + val minStateIndex = roomEntity.untimelinedStateEvents.where().min(EventEntityFields.STATE_INDEX)?.toInt() ?: Int.MIN_VALUE val untimelinedStateIndex = minStateIndex + 1 roomSync.state.events.forEach { event -> roomEntity.addStateEvent(event, filterDuplicates = true, stateIndex = untimelinedStateIndex) @@ -167,8 +165,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch roomSync: InvitedRoomSync): RoomEntity { Timber.v("Handle invited sync for room $roomId") - val roomEntity = RoomEntity.where(realm, roomId).findFirst() - ?: realm.createObject(roomId) + val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) roomEntity.membership = Membership.INVITE if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) { val chunkEntity = handleTimelineEvents(realm, roomEntity, roomSync.inviteState.events) @@ -181,8 +178,7 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch private fun handleLeftRoom(realm: Realm, roomId: String, roomSync: RoomSync): RoomEntity { - val roomEntity = RoomEntity.where(realm, roomId).findFirst() - ?: realm.createObject(roomId) + val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) roomEntity.membership = Membership.LEAVE roomEntity.chunks.deleteAllFromRealm() From 2a92a3dc80f66333b7731eaac85ad02ea2322e78 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 6 Sep 2019 14:34:52 +0200 Subject: [PATCH 32/34] Fix rendering issue of accepted third party invitation event --- CHANGES.md | 1 + .../detail/timeline/format/NoticeEventFormatter.kt | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index df1379d4e2..6de63c93f3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,6 +18,7 @@ Translations: Build: - Fix issue with version name (#533) + - Fix rendering issue of accepted third party invitation event Changes in RiotX 0.4.0 (2019-XX-XX) =================================================== diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index 05ce7a9c19..9a939a722f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -95,8 +95,7 @@ class NoticeEventFormatter @Inject constructor(private val stringProvider: Strin } private fun formatRoomHistoryVisibilityEvent(event: Event, senderName: String?): CharSequence? { - val historyVisibility = event.getClearContent().toModel()?.historyVisibility - ?: return null + val historyVisibility = event.getClearContent().toModel()?.historyVisibility ?: return null val formattedVisibility = when (historyVisibility) { RoomHistoryVisibility.SHARED -> stringProvider.getString(R.string.notice_room_visibility_shared) @@ -146,7 +145,7 @@ class NoticeEventFormatter @Inject constructor(private val stringProvider: Strin stringProvider.getString(R.string.notice_display_name_removed, event.senderId, prevEventContent?.displayName) else -> stringProvider.getString(R.string.notice_display_name_changed_from, - event.senderId, prevEventContent?.displayName, eventContent?.displayName) + event.senderId, prevEventContent?.displayName, eventContent?.displayName) } displayText.append(displayNameText) } @@ -171,9 +170,11 @@ class NoticeEventFormatter @Inject constructor(private val stringProvider: Strin // TODO get userId val selfUserId = "" when { - eventContent.thirdPartyInvite != null -> + eventContent.thirdPartyInvite != null -> { + val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey stringProvider.getString(R.string.notice_room_third_party_registered_invite, - targetDisplayName, eventContent.thirdPartyInvite?.displayName) + userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName) + } TextUtils.equals(event.stateKey, selfUserId) -> stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName) event.stateKey.isNullOrEmpty() -> From cf0b331c3b342d4ea85716a62238241b90141399 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 6 Sep 2019 15:48:42 +0200 Subject: [PATCH 33/34] Handle invite to the current user rendering --- .../room/detail/timeline/format/NoticeEventFormatter.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index 9a939a722f..33306dcb72 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -24,12 +24,14 @@ import im.vector.matrix.android.api.session.room.model.* import im.vector.matrix.android.api.session.room.model.call.CallInviteContent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.riotx.R +import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.room.detail.timeline.helper.senderName import timber.log.Timber import javax.inject.Inject -class NoticeEventFormatter @Inject constructor(private val stringProvider: StringProvider) { +class NoticeEventFormatter @Inject constructor(private val sessionHolder: ActiveSessionHolder, + private val stringProvider: StringProvider) { fun format(timelineEvent: TimelineEvent): CharSequence? { return when (val type = timelineEvent.root.getClearType()) { @@ -167,8 +169,7 @@ class NoticeEventFormatter @Inject constructor(private val stringProvider: Strin val targetDisplayName = eventContent?.displayName ?: prevEventContent?.displayName ?: "" return when { Membership.INVITE == eventContent?.membership -> { - // TODO get userId - val selfUserId = "" + val selfUserId = sessionHolder.getSafeActiveSession()?.myUserId when { eventContent.thirdPartyInvite != null -> { val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey From 1b82a1a24d277a1c2cbd2446b9d4e637a636d7a3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 6 Sep 2019 15:52:29 +0200 Subject: [PATCH 34/34] Cleanup --- .../timeline/format/NoticeEventFormatter.kt | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index 33306dcb72..da5a3d4183 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -16,7 +16,6 @@ package im.vector.riotx.features.home.room.detail.timeline.format -import android.text.TextUtils import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel @@ -76,10 +75,10 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active private fun formatRoomNameEvent(event: Event, senderName: String?): CharSequence? { val content = event.getClearContent().toModel() ?: return null - return if (!TextUtils.isEmpty(content.name)) { - stringProvider.getString(R.string.notice_room_name_changed, senderName, content.name) - } else { + return if (content.name.isNullOrBlank()) { stringProvider.getString(R.string.notice_room_name_removed, senderName) + } else { + stringProvider.getString(R.string.notice_room_name_changed, senderName, content.name) } } @@ -139,7 +138,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active private fun buildProfileNotice(event: Event, senderName: String?, eventContent: RoomMember?, prevEventContent: RoomMember?): String? { val displayText = StringBuilder() // Check display name has been changed - if (!TextUtils.equals(eventContent?.displayName, prevEventContent?.displayName)) { + if (eventContent?.displayName != prevEventContent?.displayName) { val displayNameText = when { prevEventContent?.displayName.isNullOrEmpty() -> stringProvider.getString(R.string.notice_display_name_set, event.senderId, eventContent?.displayName) @@ -152,7 +151,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active displayText.append(displayNameText) } // Check whether the avatar has been changed - if (!TextUtils.equals(eventContent?.avatarUrl, prevEventContent?.avatarUrl)) { + if (eventContent?.avatarUrl != prevEventContent?.avatarUrl) { val displayAvatarText = if (displayText.isNotEmpty()) { displayText.append(" ") stringProvider.getString(R.string.notice_avatar_changed_too) @@ -171,16 +170,16 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active Membership.INVITE == eventContent?.membership -> { val selfUserId = sessionHolder.getSafeActiveSession()?.myUserId when { - eventContent.thirdPartyInvite != null -> { + eventContent.thirdPartyInvite != null -> { val userWhoHasAccepted = eventContent.thirdPartyInvite?.signed?.mxid ?: event.stateKey stringProvider.getString(R.string.notice_room_third_party_registered_invite, userWhoHasAccepted, eventContent.thirdPartyInvite?.displayName) } - TextUtils.equals(event.stateKey, selfUserId) -> + event.stateKey == selfUserId -> stringProvider.getString(R.string.notice_room_invite_you, senderDisplayName) - event.stateKey.isNullOrEmpty() -> + event.stateKey.isNullOrEmpty() -> stringProvider.getString(R.string.notice_room_invite_no_invitee, senderDisplayName) - else -> + else -> stringProvider.getString(R.string.notice_room_invite, senderDisplayName, targetDisplayName) } } @@ -188,7 +187,7 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active stringProvider.getString(R.string.notice_room_join, senderDisplayName) Membership.LEAVE == eventContent?.membership -> // 2 cases here: this member may have left voluntarily or they may have been "left" by someone else ie. kicked - return if (TextUtils.equals(event.senderId, event.stateKey)) { + return if (event.senderId == event.stateKey) { if (prevEventContent?.membership == Membership.INVITE) { stringProvider.getString(R.string.notice_room_reject, senderDisplayName) } else {