mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-17 19:58:57 +03:00
Code review
This commit is contained in:
parent
d1233e8470
commit
08ed8d4fa7
31 changed files with 356 additions and 360 deletions
|
@ -106,7 +106,6 @@ dependencies {
|
|||
|
||||
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
|
||||
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
|
||||
implementation("com.google.guava:guava:28.2-jre")
|
||||
|
||||
// Network
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
|
||||
|
|
|
@ -26,3 +26,8 @@ fun Throwable.is401() =
|
|||
fun Throwable.isTokenError() =
|
||||
this is Failure.ServerError
|
||||
&& (error.code == MatrixError.M_UNKNOWN_TOKEN || error.code == MatrixError.M_MISSING_TOKEN)
|
||||
|
||||
fun Throwable.shouldBeRetried(): Boolean {
|
||||
return this is Failure.NetworkConnection
|
||||
|| (this is Failure.ServerError && error.code == MatrixError.M_LIMIT_EXCEEDED)
|
||||
}
|
||||
|
|
|
@ -81,14 +81,15 @@ interface SasVerificationService {
|
|||
|
||||
companion object {
|
||||
|
||||
private const val TEN_MINTUTES_IN_MILLIS = 10 * 60 * 1000
|
||||
private const val FIVE_MINTUTES_IN_MILLIS = 5 * 60 * 1000
|
||||
|
||||
fun isValidRequest(age: Long?): Boolean {
|
||||
if (age == null) return false
|
||||
val now = System.currentTimeMillis()
|
||||
val tooInThePast = now - (10 * 60 * 1000)
|
||||
val fiveMinInMs = 5 * 60 * 1000
|
||||
val tooInTheFuture = System.currentTimeMillis() + fiveMinInMs
|
||||
|
||||
return !(age < tooInThePast || age > tooInTheFuture)
|
||||
val tooInThePast = now - TEN_MINTUTES_IN_MILLIS
|
||||
val tooInTheFuture = now + FIVE_MINTUTES_IN_MILLIS
|
||||
return age in tooInThePast..tooInTheFuture
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,5 +48,5 @@ interface SasVerificationTransaction {
|
|||
*/
|
||||
fun userHasVerifiedShortCode()
|
||||
|
||||
fun shortCodeDoNotMatch()
|
||||
fun shortCodeDoesNotMatch()
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ internal data class MessageVerificationAcceptContent(
|
|||
return true
|
||||
}
|
||||
|
||||
override fun toEventContent() = this.toContent()
|
||||
override fun toEventContent() = toContent()
|
||||
|
||||
companion object : VerificationInfoAcceptFactory {
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ data class MessageVerificationCancelContent(
|
|||
override val transactionID: String?
|
||||
get() = relatesTo?.eventId
|
||||
|
||||
override fun toEventContent() = this.toContent()
|
||||
override fun toEventContent() = toContent()
|
||||
|
||||
override fun isValid(): Boolean {
|
||||
if (transactionID.isNullOrBlank() || code.isNullOrBlank()) {
|
||||
|
|
|
@ -32,5 +32,5 @@ internal data class MessageVerificationDoneContent(
|
|||
|
||||
override fun isValid() = transactionID?.isNotEmpty() == true
|
||||
|
||||
override fun toEventContent(): Content? = this.toContent()
|
||||
override fun toEventContent(): Content? = toContent()
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ internal data class MessageVerificationKeyContent(
|
|||
return true
|
||||
}
|
||||
|
||||
override fun toEventContent() = this.toContent()
|
||||
override fun toEventContent() = toContent()
|
||||
|
||||
companion object : VerificationInfoKeyFactory {
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ internal data class MessageVerificationMacContent(
|
|||
override val transactionID: String?
|
||||
get() = relatesTo?.eventId
|
||||
|
||||
override fun toEventContent() = this.toContent()
|
||||
override fun toEventContent() = toContent()
|
||||
|
||||
override fun isValid(): Boolean {
|
||||
if (transactionID.isNullOrBlank() || keys.isNullOrBlank() || mac.isNullOrEmpty()) {
|
||||
|
|
|
@ -33,7 +33,7 @@ internal data class MessageVerificationReadyContent(
|
|||
override val transactionID: String?
|
||||
get() = relatesTo?.eventId
|
||||
|
||||
override fun toEventContent() = this.toContent()
|
||||
override fun toEventContent() = toContent()
|
||||
|
||||
override fun isValid(): Boolean {
|
||||
if (transactionID.isNullOrBlank() || methods.isNullOrEmpty() || fromDevice.isNullOrEmpty()) {
|
||||
|
|
|
@ -62,5 +62,5 @@ internal data class MessageVerificationStartContent(
|
|||
return true
|
||||
}
|
||||
|
||||
override fun toEventContent() = this.toContent()
|
||||
override fun toEventContent() = toContent()
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package im.vector.matrix.android.internal.crypto.verification
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import dagger.Lazy
|
||||
|
@ -52,7 +51,6 @@ import kotlin.collections.set
|
|||
|
||||
@SessionScope
|
||||
internal class DefaultSasVerificationService @Inject constructor(
|
||||
private val context: Context,
|
||||
private val credentials: Credentials,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
|
||||
|
@ -81,7 +79,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
fun onToDeviceEvent(event: Event) {
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
when (event.getClearType()) {
|
||||
EventType.KEY_VERIFICATION_START -> {
|
||||
EventType.KEY_VERIFICATION_START -> {
|
||||
onStartRequestReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_CANCEL -> {
|
||||
|
@ -90,13 +88,13 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
EventType.KEY_VERIFICATION_ACCEPT -> {
|
||||
onAcceptReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_KEY -> {
|
||||
EventType.KEY_VERIFICATION_KEY -> {
|
||||
onKeyReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_MAC -> {
|
||||
EventType.KEY_VERIFICATION_MAC -> {
|
||||
onMacReceived(event)
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +104,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
fun onRoomEvent(event: Event) {
|
||||
GlobalScope.launch(coroutineDispatchers.crypto) {
|
||||
when (event.getClearType()) {
|
||||
EventType.KEY_VERIFICATION_START -> {
|
||||
EventType.KEY_VERIFICATION_START -> {
|
||||
onRoomStartRequestReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_CANCEL -> {
|
||||
|
@ -116,24 +114,24 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
EventType.KEY_VERIFICATION_ACCEPT -> {
|
||||
onRoomAcceptReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_KEY -> {
|
||||
EventType.KEY_VERIFICATION_KEY -> {
|
||||
onRoomKeyRequestReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_MAC -> {
|
||||
EventType.KEY_VERIFICATION_MAC -> {
|
||||
onRoomMacReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_READY -> {
|
||||
EventType.KEY_VERIFICATION_READY -> {
|
||||
onRoomReadyReceived(event)
|
||||
}
|
||||
EventType.KEY_VERIFICATION_DONE -> {
|
||||
EventType.KEY_VERIFICATION_DONE -> {
|
||||
onRoomDoneReceived(event)
|
||||
}
|
||||
EventType.MESSAGE -> {
|
||||
EventType.MESSAGE -> {
|
||||
if (MessageType.MSGTYPE_VERIFICATION_REQUEST == event.getClearContent().toModel<MessageContent>()?.type) {
|
||||
onRoomRequestReceived(event)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
@ -275,7 +273,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
if (startReq?.isValid()?.not() == true) {
|
||||
Timber.e("## received invalid verification request")
|
||||
if (startReq.transactionID != null) {
|
||||
sasTransportRoomMessageFactory.createTransport(context, credentials.userId, credentials.deviceId
|
||||
sasTransportRoomMessageFactory.createTransport(credentials.userId, credentials.deviceId
|
||||
?: "", event.roomId
|
||||
?: "", null).cancelTransaction(
|
||||
startReq.transactionID ?: "",
|
||||
|
@ -288,11 +286,11 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
}
|
||||
|
||||
handleStart(otherUserId, startReq as VerificationInfoStart) {
|
||||
it.transport = sasTransportRoomMessageFactory.createTransport(context, credentials.userId, credentials.deviceId
|
||||
it.transport = sasTransportRoomMessageFactory.createTransport(credentials.userId, credentials.deviceId
|
||||
?: "", event.roomId
|
||||
?: "", it)
|
||||
}?.let {
|
||||
sasTransportRoomMessageFactory.createTransport(context, credentials.userId, credentials.deviceId
|
||||
sasTransportRoomMessageFactory.createTransport(credentials.userId, credentials.deviceId
|
||||
?: "", event.roomId
|
||||
?: "", null).cancelTransaction(
|
||||
startReq.transactionID ?: "",
|
||||
|
@ -701,7 +699,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
pendingRequests[userId] = it
|
||||
}
|
||||
|
||||
val transport = sasTransportRoomMessageFactory.createTransport(context, credentials.userId, credentials.deviceId
|
||||
val transport = sasTransportRoomMessageFactory.createTransport(credentials.userId, credentials.deviceId
|
||||
?: "", roomId, null)
|
||||
|
||||
// Cancel existing pending requests?
|
||||
|
@ -738,7 +736,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
}
|
||||
|
||||
override fun declineVerificationRequestInDMs(otherUserId: String, otherDeviceId: String, transactionId: String, roomId: String) {
|
||||
sasTransportRoomMessageFactory.createTransport(context, credentials.userId, credentials.deviceId
|
||||
sasTransportRoomMessageFactory.createTransport(credentials.userId, credentials.deviceId
|
||||
?: "", roomId, null).cancelTransaction(transactionId, otherUserId, otherDeviceId, CancelCode.User)
|
||||
|
||||
getExistingVerificationRequest(otherUserId, transactionId)?.let {
|
||||
|
@ -776,7 +774,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
transactionId,
|
||||
otherUserId,
|
||||
otherDeviceId)
|
||||
tx.transport = sasTransportRoomMessageFactory.createTransport(context, credentials.userId, credentials.deviceId
|
||||
tx.transport = sasTransportRoomMessageFactory.createTransport(credentials.userId, credentials.deviceId
|
||||
?: "", roomId, tx)
|
||||
addTransaction(tx)
|
||||
|
||||
|
@ -791,7 +789,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
// Let's find the related request
|
||||
getExistingVerificationRequest(otherUserId)?.find { it.transactionId == transactionId }?.let {
|
||||
// we need to send a ready event, with matching methods
|
||||
val transport = sasTransportRoomMessageFactory.createTransport(context, credentials.userId, credentials.deviceId
|
||||
val transport = sasTransportRoomMessageFactory.createTransport(credentials.userId, credentials.deviceId
|
||||
?: "", roomId, null)
|
||||
val methods = it.requestInfo?.methods?.intersect(listOf(KeyVerificationStart.VERIF_METHOD_SAS))?.toList()
|
||||
if (methods.isNullOrEmpty()) {
|
||||
|
|
|
@ -169,7 +169,7 @@ internal abstract class SASVerificationTransaction(
|
|||
} // if not wait for it
|
||||
}
|
||||
|
||||
override fun shortCodeDoNotMatch() {
|
||||
override fun shortCodeDoesNotMatch() {
|
||||
Timber.v("## SAS short code do not match for id:$transactionId")
|
||||
cancel(CancelCode.MismatchedSas)
|
||||
}
|
||||
|
|
|
@ -284,10 +284,11 @@ internal class SasTransportRoomMessage(
|
|||
}
|
||||
|
||||
internal class SasTransportRoomMessageFactory @Inject constructor(
|
||||
private val context: Context,
|
||||
private val monarchy: Monarchy,
|
||||
private val localEchoEventFactory: LocalEchoEventFactory) {
|
||||
|
||||
fun createTransport(context: Context, userId: String, userDevice: String, roomId: String, tx: SASVerificationTransaction?
|
||||
fun createTransport(userId: String, userDevice: String, roomId: String, tx: SASVerificationTransaction?
|
||||
): SasTransportRoomMessage {
|
||||
return SasTransportRoomMessage(context, userId, userDevice, roomId, monarchy, localEchoEventFactory, tx)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* Copyright 2020 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.matrix.android.internal.crypto.verification
|
||||
|
||||
import android.content.Context
|
||||
|
@ -5,8 +20,7 @@ import androidx.work.CoroutineWorker
|
|||
import androidx.work.Data
|
||||
import androidx.work.WorkerParameters
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.failure.Failure
|
||||
import im.vector.matrix.android.api.failure.MatrixError
|
||||
import im.vector.matrix.android.api.failure.shouldBeRetried
|
||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.internal.crypto.tasks.SendVerificationMessageTask
|
||||
|
@ -35,10 +49,11 @@ internal class SendVerificationMessageWorker constructor(context: Context, param
|
|||
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
||||
?: return Result.success(errorOutputData)
|
||||
|
||||
val sessionComponent = getSessionComponent(params.userId) ?: return Result.success(errorOutputData).also {
|
||||
// TODO, can this happen? should I update local echo?
|
||||
Timber.e("Unknown Session, cannot send message, userId:${params.userId}")
|
||||
}
|
||||
val sessionComponent = getSessionComponent(params.userId)
|
||||
?: return Result.success(errorOutputData).also {
|
||||
// TODO, can this happen? should I update local echo?
|
||||
Timber.e("Unknown Session, cannot send message, userId:${params.userId}")
|
||||
}
|
||||
sessionComponent.inject(this)
|
||||
val localId = params.event.eventId ?: ""
|
||||
return try {
|
||||
|
@ -58,9 +73,4 @@ internal class SendVerificationMessageWorker constructor(context: Context, param
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Throwable.shouldBeRetried(): Boolean {
|
||||
return this is Failure.NetworkConnection
|
||||
|| (this is Failure.ServerError && error.code == MatrixError.M_LIMIT_EXCEEDED)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,7 @@ import android.content.Context
|
|||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.failure.Failure
|
||||
import im.vector.matrix.android.api.failure.MatrixError
|
||||
import im.vector.matrix.android.api.failure.shouldBeRetried
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.room.send.SendState
|
||||
|
@ -77,11 +76,6 @@ internal class SendEventWorker constructor(context: Context, params: WorkerParam
|
|||
}
|
||||
}
|
||||
|
||||
private fun Throwable.shouldBeRetried(): Boolean {
|
||||
return this is Failure.NetworkConnection
|
||||
|| (this is Failure.ServerError && error.code == MatrixError.M_LIMIT_EXCEEDED)
|
||||
}
|
||||
|
||||
private suspend fun sendEvent(eventId: String, eventType: String, content: Content?, roomId: String) {
|
||||
localEchoUpdater.updateSendState(eventId, SendState.SENDING)
|
||||
executeRequest<SendResponse> {
|
||||
|
|
|
@ -21,21 +21,4 @@
|
|||
|
||||
<string name="key_verification_request_fallback_message">%s is requesting to verify your key, but your client does not support in-chat key verification. You will need to use legacy key verification to verify keys.</string>
|
||||
|
||||
<!-- Sender name of a message when it is send by you, e.g. You: Hello!-->
|
||||
<string name="you">You</string>
|
||||
|
||||
<string name="verify_by_scanning_title">Verify by scanning</string>
|
||||
<!-- the %s will be replaced by verify_open_camera_link that will be clickable -->
|
||||
<string name="verify_by_scanning_description">Ask the other user to scan this code, or %s to scan theirs</string>
|
||||
<!-- This part is inserted in verify_by_scanning_description-->
|
||||
<string name="verify_open_camera_link">open your camera</string>
|
||||
|
||||
<string name="verify_by_emoji_title">Verify by Emoji</string>
|
||||
<string name="verify_by_emoji_description">If you can’t scan the code above, verify by comparing a short, unique selection of emoji.</string>
|
||||
|
||||
<string name="aria_qr_code_description">QR code image</string>
|
||||
|
||||
<string name="verification_request_alert_title">Verify %s</string>
|
||||
<string name="verification_request_waiting_for">Waiting for %s…</string>
|
||||
<string name="verification_request_alert_description">For extra security, verify %s by checking a one-time code on both your devices.\n\nFor maximum security, do this in person.</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2018 New Vector Ltd
|
||||
* 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.
|
||||
|
|
|
@ -109,13 +109,13 @@ class SASVerificationCodeFragment @Inject constructor(
|
|||
sasCodeWaitingPartnerText.isVisible = false
|
||||
}
|
||||
}
|
||||
is Fail -> {
|
||||
is Fail -> {
|
||||
sasLoadingProgress.isVisible = false
|
||||
emojiGrid.isInvisible = true
|
||||
ButtonsVisibilityGroup.isInvisible = true
|
||||
// TODO?
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
sasLoadingProgress.isVisible = true
|
||||
emojiGrid.isInvisible = true
|
||||
ButtonsVisibilityGroup.isInvisible = true
|
||||
|
@ -142,17 +142,21 @@ class SASVerificationCodeFragment @Inject constructor(
|
|||
|
||||
@OnClick(R.id.sas_request_continue_button)
|
||||
fun onMatchButtonTapped() = withState(viewModel) { state ->
|
||||
val otherUserId = state.otherUser?.id ?: return@withState
|
||||
val txId = state.transactionId ?: return@withState
|
||||
// UX echo
|
||||
ButtonsVisibilityGroup.isInvisible = true
|
||||
sasCodeWaitingPartnerText.isVisible = true
|
||||
sharedViewModel.handle(VerificationAction.SASMatchAction(state.otherUserId, state.transactionId))
|
||||
sharedViewModel.handle(VerificationAction.SASMatchAction(otherUserId, txId))
|
||||
}
|
||||
|
||||
@OnClick(R.id.sas_request_cancel_button)
|
||||
fun onDoNotMatchButtonTapped() = withState(viewModel) { state ->
|
||||
val otherUserId = state.otherUser?.id ?: return@withState
|
||||
val txId = state.transactionId ?: return@withState
|
||||
// UX echo
|
||||
ButtonsVisibilityGroup.isInvisible = true
|
||||
sasCodeWaitingPartnerText.isVisible = true
|
||||
sharedViewModel.handle(VerificationAction.SASDoNotMatchAction(state.otherUserId, state.transactionId))
|
||||
sharedViewModel.handle(VerificationAction.SASDoNotMatchAction(otherUserId, txId))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@ import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTransactio
|
|||
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.core.di.HasScreenInjector
|
||||
import im.vector.riotx.core.platform.EmptyAction
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
|
||||
data class SASVerificationCodeViewState(
|
||||
val transactionId: String,
|
||||
val otherUserId: String,
|
||||
val transactionId: String?,
|
||||
val otherUser: MatrixItem? = null,
|
||||
val supportsEmoji: Boolean = true,
|
||||
val emojiDescription: Async<List<EmojiRepresentation>> = Uninitialized,
|
||||
|
@ -45,23 +45,9 @@ class SASVerificationCodeViewModel @AssistedInject constructor(
|
|||
|
||||
init {
|
||||
withState { state ->
|
||||
val matrixItem = session.getUser(state.otherUserId)?.toMatrixItem()
|
||||
setState {
|
||||
copy(otherUser = matrixItem)
|
||||
}
|
||||
val sasTx = session.getSasVerificationService()
|
||||
.getExistingTransaction(state.otherUserId, state.transactionId)
|
||||
if (sasTx == null) {
|
||||
setState {
|
||||
copy(
|
||||
isWaitingFromOther = false,
|
||||
emojiDescription = Fail(Throwable("Unknown Transaction")),
|
||||
decimalDescription = Fail(Throwable("Unknown Transaction"))
|
||||
)
|
||||
}
|
||||
} else {
|
||||
refreshStateFromTx(sasTx)
|
||||
}
|
||||
refreshStateFromTx(session.getSasVerificationService()
|
||||
.getExistingTransaction(state.otherUser?.id ?: "", state.transactionId
|
||||
?: ""))
|
||||
}
|
||||
|
||||
session.getSasVerificationService().addListener(this)
|
||||
|
@ -72,8 +58,8 @@ class SASVerificationCodeViewModel @AssistedInject constructor(
|
|||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun refreshStateFromTx(sasTx: SasVerificationTransaction) {
|
||||
when (sasTx.state) {
|
||||
private fun refreshStateFromTx(sasTx: SasVerificationTransaction?) {
|
||||
when (sasTx?.state) {
|
||||
SasVerificationTxState.None,
|
||||
SasVerificationTxState.SendingStart,
|
||||
SasVerificationTxState.Started,
|
||||
|
@ -131,6 +117,15 @@ class SASVerificationCodeViewModel @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
null -> {
|
||||
setState {
|
||||
copy(
|
||||
isWaitingFromOther = false,
|
||||
emojiDescription = Fail(Throwable("Unknown Transaction")),
|
||||
decimalDescription = Fail(Throwable("Unknown Transaction"))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,8 +133,10 @@ class SASVerificationCodeViewModel @AssistedInject constructor(
|
|||
transactionUpdated(tx)
|
||||
}
|
||||
|
||||
override fun transactionUpdated(tx: SasVerificationTransaction) {
|
||||
refreshStateFromTx(tx)
|
||||
override fun transactionUpdated(tx: SasVerificationTransaction) = withState { state ->
|
||||
if (tx.transactionId == state.transactionId) {
|
||||
refreshStateFromTx(tx)
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedInject.Factory
|
||||
|
@ -156,9 +153,12 @@ class SASVerificationCodeViewModel @AssistedInject constructor(
|
|||
|
||||
override fun initialState(viewModelContext: ViewModelContext): SASVerificationCodeViewState? {
|
||||
val args = viewModelContext.args<VerificationBottomSheet.VerificationArgs>()
|
||||
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
|
||||
val matrixItem = session.getUser(args.otherUserId)?.toMatrixItem()
|
||||
|
||||
return SASVerificationCodeViewState(
|
||||
transactionId = args.verificationId ?: "",
|
||||
otherUserId = args.otherUserId
|
||||
transactionId = args.verificationId,
|
||||
otherUser = matrixItem
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import androidx.transition.AutoTransition
|
|||
import androidx.transition.TransitionManager
|
||||
import butterknife.BindView
|
||||
import butterknife.ButterKnife
|
||||
import butterknife.Unbinder
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
|
@ -75,12 +76,20 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
@BindView(R.id.verificationRequestAvatar)
|
||||
lateinit var otherUserAvatarImageView: ImageView
|
||||
|
||||
private var unBinder: Unbinder? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val view = inflater.inflate(R.layout.bottom_sheet_verification, container, false)
|
||||
ButterKnife.bind(this, view)
|
||||
unBinder = ButterKnife.bind(this, view)
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
unBinder?.unbind()
|
||||
unBinder = null
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
@ -183,6 +192,20 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun withArgs(roomId: String, otherUserId: String, transactionId: String? = null): VerificationBottomSheet {
|
||||
return VerificationBottomSheet().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(MvRx.KEY_ARG, VerificationBottomSheet.VerificationArgs(
|
||||
otherUserId = otherUserId,
|
||||
roomId = roomId,
|
||||
verificationId = transactionId
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun View.getParentCoordinatorLayout(): CoordinatorLayout? {
|
||||
|
|
|
@ -112,8 +112,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
|||
}
|
||||
}
|
||||
is VerificationAction.StartSASVerification -> {
|
||||
val request = session.getSasVerificationService().getExistingVerificationRequest(otherUserId)
|
||||
?.firstOrNull { it.transactionId == action.pendingRequestTransactionId }
|
||||
val request = session.getSasVerificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
|
||||
?: return@withState
|
||||
|
||||
val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice
|
||||
|
@ -134,7 +133,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
|||
is VerificationAction.SASDoNotMatchAction -> {
|
||||
session.getSasVerificationService()
|
||||
.getExistingTransaction(action.userID, action.sasTransactionId)
|
||||
?.shortCodeDoNotMatch()
|
||||
?.shortCodeDoesNotMatch()
|
||||
}
|
||||
is VerificationAction.GotItConclusion -> {
|
||||
_requestLiveData.postValue(LiveEvent(Success(action)))
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.squareup.inject.assisted.Assisted
|
|||
import com.squareup.inject.assisted.AssistedInject
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationStart
|
||||
import im.vector.riotx.core.di.HasScreenInjector
|
||||
import im.vector.riotx.core.platform.EmptyAction
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
|
||||
|
@ -38,19 +39,6 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
|
|||
private val session: Session
|
||||
) : VectorViewModel<VerificationChooseMethodViewState, EmptyAction>(initialState) {
|
||||
|
||||
init {
|
||||
withState { state ->
|
||||
val pvr = session.getSasVerificationService().getExistingVerificationRequest(state.otherUserId)?.first {
|
||||
it.transactionId == state.transactionId
|
||||
}
|
||||
val qrAvailable = pvr?.readyInfo?.methods?.contains(KeyVerificationStart.VERIF_METHOD_SCAN) ?: false
|
||||
val emojiAvailable = pvr?.readyInfo?.methods?.contains(KeyVerificationStart.VERIF_METHOD_SAS) ?: false
|
||||
setState {
|
||||
copy(QRModeAvailable = qrAvailable, SASMOdeAvailable = emojiAvailable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
fun create(initialState: VerificationChooseMethodViewState): VerificationChooseMethodViewModel
|
||||
|
@ -64,7 +52,18 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
|
|||
|
||||
override fun initialState(viewModelContext: ViewModelContext): VerificationChooseMethodViewState? {
|
||||
val args: VerificationBottomSheet.VerificationArgs = viewModelContext.args()
|
||||
return VerificationChooseMethodViewState(otherUserId = args.otherUserId, transactionId = args.verificationId ?: "")
|
||||
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
|
||||
val pvr = session.getSasVerificationService().getExistingVerificationRequest(args.otherUserId, args.verificationId)
|
||||
val qrAvailable = pvr?.readyInfo?.methods?.contains(KeyVerificationStart.VERIF_METHOD_SCAN)
|
||||
?: false
|
||||
val emojiAvailable = pvr?.readyInfo?.methods?.contains(KeyVerificationStart.VERIF_METHOD_SAS)
|
||||
?: false
|
||||
|
||||
return VerificationChooseMethodViewState(otherUserId = args.otherUserId,
|
||||
transactionId = args.verificationId ?: "",
|
||||
QRModeAvailable = qrAvailable,
|
||||
SASMOdeAvailable = emojiAvailable
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ package im.vector.riotx.features.crypto.verification
|
|||
|
||||
import android.os.Parcelable
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import butterknife.OnClick
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
|
@ -53,7 +54,7 @@ class VerificationConclusionFragment @Inject constructor() : VectorBaseFragment(
|
|||
}
|
||||
ConclusionState.WARNING -> {
|
||||
verificationConclusionTitle.text = getString(R.string.verification_conclusion_not_secure)
|
||||
verifyConclusionDescription.setTextOrHide(null)
|
||||
verifyConclusionDescription.isVisible = false
|
||||
verifyConclusionImageView.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_shield_warning))
|
||||
|
||||
verifyConclusionBottomDescription.text = Markwon.builder(requireContext())
|
||||
|
|
|
@ -25,6 +25,7 @@ import im.vector.matrix.android.api.util.MatrixItem
|
|||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.matrix.android.internal.crypto.verification.PendingVerificationRequest
|
||||
import im.vector.riotx.core.di.HasScreenInjector
|
||||
import im.vector.riotx.core.platform.EmptyAction
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
|
||||
data class VerificationRequestViewState(
|
||||
|
@ -36,7 +37,7 @@ data class VerificationRequestViewState(
|
|||
class VerificationRequestViewModel @AssistedInject constructor(
|
||||
@Assisted initialState: VerificationRequestViewState,
|
||||
private val session: Session
|
||||
) : VectorViewModel<VerificationRequestViewState, VerificationAction>(initialState), SasVerificationService.SasVerificationListener {
|
||||
) : VectorViewModel<VerificationRequestViewState, EmptyAction>(initialState), SasVerificationService.SasVerificationListener {
|
||||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
|
@ -75,8 +76,7 @@ class VerificationRequestViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun handle(action: VerificationAction) {
|
||||
}
|
||||
override fun handle(action: EmptyAction) {}
|
||||
|
||||
override fun transactionCreated(tx: SasVerificationTransaction) {}
|
||||
|
||||
|
|
|
@ -432,7 +432,8 @@ class RoomDetailFragment @Inject constructor(
|
|||
composerLayout.sendButton.setContentDescription(getString(descriptionRes))
|
||||
|
||||
avatarRenderer.render(
|
||||
MatrixItem.UserItem(event.root.senderId ?: "", event.getDisambiguatedDisplayName(), event.senderAvatar),
|
||||
MatrixItem.UserItem(event.root.senderId
|
||||
?: "", event.getDisambiguatedDisplayName(), event.senderAvatar),
|
||||
composerLayout.composerRelatedMessageAvatar
|
||||
)
|
||||
composerLayout.expand {
|
||||
|
@ -962,20 +963,17 @@ class RoomDetailFragment @Inject constructor(
|
|||
}
|
||||
}
|
||||
is RoomDetailAction.RequestVerification -> {
|
||||
VerificationBottomSheet().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(MvRx.KEY_ARG, VerificationBottomSheet.VerificationArgs(data.userId, roomId = roomDetailArgs.roomId))
|
||||
}
|
||||
// setArguments()
|
||||
}.show(parentFragmentManager, "REQ")
|
||||
VerificationBottomSheet.withArgs(
|
||||
roomDetailArgs.roomId,
|
||||
data.userId
|
||||
).show(parentFragmentManager, "REQ")
|
||||
}
|
||||
is RoomDetailAction.AcceptVerificationRequest -> {
|
||||
VerificationBottomSheet().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(MvRx.KEY_ARG, VerificationBottomSheet.VerificationArgs(
|
||||
data.otherUserId, data.transactionId, roomId = roomDetailArgs.roomId))
|
||||
}
|
||||
}.show(parentFragmentManager, "REQ")
|
||||
VerificationBottomSheet.withArgs(
|
||||
roomDetailArgs.roomId,
|
||||
data.otherUserId,
|
||||
data.transactionId
|
||||
).show(parentFragmentManager, "REQ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
|
|||
|
||||
when (attributes.informationData.referencesInfoData?.verificationStatus) {
|
||||
VerificationState.REQUEST,
|
||||
null -> {
|
||||
null -> {
|
||||
holder.buttonBar.isVisible = !attributes.informationData.sentByMe
|
||||
holder.statusTextView.text = null
|
||||
holder.statusTextView.isVisible = false
|
||||
|
@ -83,17 +83,17 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
|
|||
holder.statusTextView.text = holder.view.context.getString(R.string.verification_request_other_cancelled, attributes.informationData.memberName)
|
||||
holder.statusTextView.isVisible = true
|
||||
}
|
||||
VerificationState.CANCELED_BY_ME -> {
|
||||
VerificationState.CANCELED_BY_ME -> {
|
||||
holder.buttonBar.isVisible = false
|
||||
holder.statusTextView.text = holder.view.context.getString(R.string.verification_request_you_cancelled)
|
||||
holder.statusTextView.isVisible = true
|
||||
}
|
||||
VerificationState.WAITING -> {
|
||||
VerificationState.WAITING -> {
|
||||
holder.buttonBar.isVisible = false
|
||||
holder.statusTextView.text = holder.view.context.getString(R.string.verification_request_waiting)
|
||||
holder.statusTextView.isVisible = true
|
||||
}
|
||||
VerificationState.DONE -> {
|
||||
VerificationState.DONE -> {
|
||||
holder.buttonBar.isVisible = false
|
||||
holder.statusTextView.text = if (attributes.informationData.sentByMe) {
|
||||
holder.view.context.getString(R.string.verification_request_other_accepted, attributes.otherUserName)
|
||||
|
@ -102,7 +102,7 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
|
|||
}
|
||||
holder.statusTextView.isVisible = true
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
holder.buttonBar.isVisible = false
|
||||
holder.statusTextView.text = null
|
||||
holder.statusTextView.isVisible = false
|
||||
|
@ -110,7 +110,9 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
|
|||
}
|
||||
|
||||
// Always hide buttons if request is too old
|
||||
holder.buttonBar.isVisible = holder.buttonBar.isVisible && SasVerificationService.isValidRequest(attributes.informationData.ageLocalTS)
|
||||
if (!SasVerificationService.isValidRequest(attributes.informationData.ageLocalTS)) {
|
||||
holder.buttonBar.isVisible = false
|
||||
}
|
||||
|
||||
holder.callback = callback
|
||||
holder.attributes = attributes
|
||||
|
|
|
@ -1,195 +1,188 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:colorBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sas_emoji_description"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||
android:text="@string/verify_by_emoji_title"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sas_emoji_description_2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:text="@string/verify_user_sas_emoji_help_text"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/sas_emoji_description" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sas_decimal_code"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/sas_emoji_grid"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/sas_emoji_grid"
|
||||
tools:text="1234-4320-3905"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/sasLoadingProgress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/sas_emoji_grid"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/sas_emoji_grid" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:id="@+id/sas_emoji_grid"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:visibility="invisible"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sas_emoji_description_2"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sas_emoji_description"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||
android:text="@string/verify_by_emoji_title"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<include
|
||||
android:id="@+id/emoji0"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sas_emoji_description_2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:text="@string/verify_user_sas_emoji_help_text"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/sas_emoji_description" />
|
||||
<include
|
||||
android:id="@+id/emoji1"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sas_decimal_code"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/sas_emoji_grid"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/sas_emoji_grid"
|
||||
tools:text="1234-4320-3905"
|
||||
tools:visibility="visible" />
|
||||
<include
|
||||
android:id="@+id/emoji2"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/sasLoadingProgress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/sas_emoji_grid"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/sas_emoji_grid"
|
||||
/>
|
||||
<include
|
||||
android:id="@+id/emoji3"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/sas_emoji_grid"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:visibility="invisible"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sas_emoji_description_2"
|
||||
tools:visibility="visible">
|
||||
<include
|
||||
android:id="@+id/emoji4"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<include
|
||||
android:id="@+id/emoji0"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
<include
|
||||
android:id="@+id/emoji5"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<include
|
||||
android:id="@+id/emoji1"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
<include
|
||||
android:id="@+id/emoji6"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<include
|
||||
android:id="@+id/emoji2"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<include
|
||||
android:id="@+id/emoji3"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<include
|
||||
android:id="@+id/emoji4"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<include
|
||||
android:id="@+id/emoji5"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<include
|
||||
android:id="@+id/emoji6"
|
||||
layout="@layout/item_emoji_verif" />
|
||||
|
||||
<androidx.constraintlayout.helper.widget.Flow
|
||||
android:id="@+id/sas_emoji_grid_flow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="emoji0,emoji1,emoji2,emoji3,emoji4,emoji5,emoji6"
|
||||
app:flow_horizontalBias="0.5"
|
||||
app:flow_horizontalGap="16dp"
|
||||
app:flow_horizontalStyle="packed"
|
||||
app:flow_verticalBias="0"
|
||||
app:flow_verticalGap="8dp"
|
||||
app:flow_wrapMode="chain"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/sas_request_continue_button"
|
||||
style="@style/VectorButtonStylePositive"
|
||||
android:layout_width="0dp"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:minWidth="160dp"
|
||||
android:text="@string/verification_sas_match"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/centerGuideLine"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sas_emoji_grid"
|
||||
tools:text="A very long translation thats too big" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/centerGuideLine"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/sas_request_cancel_button"
|
||||
style="@style/VectorButtonStyleDestructive"
|
||||
android:layout_width="0dp"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:text="@string/verification_sas_do_not_match"
|
||||
app:layout_constraintEnd_toStartOf="@+id/centerGuideLine"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sas_emoji_grid" />
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/bottomBarrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:barrierMargin="8dp"
|
||||
app:constraint_referenced_ids="sas_request_cancel_button,sas_request_continue_button" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sasCodeWaitingPartnerText"
|
||||
<androidx.constraintlayout.helper.widget.Flow
|
||||
android:id="@+id/sas_emoji_grid_flow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textColor="?attr/vctr_notice_secondary"
|
||||
android:textSize="15sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottomBarrier"
|
||||
app:layout_constraintTop_toBottomOf="@id/sas_emoji_grid"
|
||||
android:text="@string/sas_waiting_for_partner"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sasEmojiSecurityTip"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:gravity="center"
|
||||
android:text="@string/verify_user_sas_emoji_security_tip"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/bottomBarrier" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/ButtonsVisibilityGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="sas_request_continue_button,sas_request_cancel_button"
|
||||
tools:visibility="visible" />
|
||||
app:constraint_referenced_ids="emoji0,emoji1,emoji2,emoji3,emoji4,emoji5,emoji6"
|
||||
app:flow_horizontalBias="0.5"
|
||||
app:flow_horizontalGap="16dp"
|
||||
app:flow_horizontalStyle="packed"
|
||||
app:flow_verticalBias="0"
|
||||
app:flow_verticalGap="8dp"
|
||||
app:flow_wrapMode="chain"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/sas_request_continue_button"
|
||||
style="@style/VectorButtonStylePositive"
|
||||
android:layout_width="0dp"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:minWidth="160dp"
|
||||
android:text="@string/verification_sas_match"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/centerGuideLine"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sas_emoji_grid"
|
||||
tools:text="A very long translation thats too big" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/centerGuideLine"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/sas_request_cancel_button"
|
||||
style="@style/VectorButtonStyleDestructive"
|
||||
android:layout_width="0dp"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:text="@string/verification_sas_do_not_match"
|
||||
app:layout_constraintEnd_toStartOf="@+id/centerGuideLine"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sas_emoji_grid" />
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/bottomBarrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:barrierMargin="8dp"
|
||||
app:constraint_referenced_ids="sas_request_cancel_button,sas_request_continue_button" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sasCodeWaitingPartnerText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/sas_waiting_for_partner"
|
||||
android:textColor="?attr/vctr_notice_secondary"
|
||||
android:textSize="15sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottomBarrier"
|
||||
app:layout_constraintTop_toBottomOf="@id/sas_emoji_grid"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sasEmojiSecurityTip"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/layout_vertical_margin"
|
||||
android:gravity="center"
|
||||
android:text="@string/verify_user_sas_emoji_security_tip"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/bottomBarrier" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/ButtonsVisibilityGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="sas_request_continue_button,sas_request_cancel_button"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -14,21 +14,21 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/sas_verified"
|
||||
tools:text="@string/sas_verified"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@string/sas_verified" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/verifyConclusionDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
tools:text="@string/sas_verified_successful_description"
|
||||
android:text="@string/sas_verified_successful_description"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
app:layout_constraintTop_toBottomOf="@id/verificationConclusionTitle"/>
|
||||
app:layout_constraintTop_toBottomOf="@id/verificationConclusionTitle"
|
||||
tools:text="@string/sas_verified_successful_description" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/verifyConclusionImageView"
|
||||
|
@ -36,22 +36,20 @@
|
|||
android:layout_height="180dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
tools:background="@drawable/ic_shield_trusted"
|
||||
android:background="@drawable/ic_shield_trusted"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/verifyConclusionDescription" />
|
||||
app:layout_constraintTop_toBottomOf="@id/verifyConclusionDescription"
|
||||
tools:background="@drawable/ic_shield_trusted" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/verifyConclusionBottomDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
tools:text="@string/verification_green_shield"
|
||||
android:text="@string/verification_green_shield"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
app:layout_constraintTop_toBottomOf="@id/verifyConclusionImageView"/>
|
||||
app:layout_constraintTop_toBottomOf="@id/verifyConclusionImageView"
|
||||
tools:text="@string/verification_green_shield" />
|
||||
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
|
|
|
@ -4,38 +4,8 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<!-- <ImageView-->
|
||||
<!-- android:id="@+id/verificationRequestAvatar"-->
|
||||
<!-- android:layout_width="32dp"-->
|
||||
<!-- android:layout_height="32dp"-->
|
||||
<!-- android:adjustViewBounds="true"-->
|
||||
<!-- android:background="@drawable/circle"-->
|
||||
<!-- android:contentDescription="@string/avatar"-->
|
||||
<!-- android:scaleType="centerCrop"-->
|
||||
<!-- android:transitionName="bottomSheetAvatar"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="parent"-->
|
||||
<!-- app:layout_constraintVertical_bias="0"-->
|
||||
<!-- tools:src="@tools:sample/avatars" />-->
|
||||
|
||||
<!-- <TextView-->
|
||||
<!-- android:id="@+id/verificationRequestName"-->
|
||||
<!-- android:layout_width="0dp"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginStart="16dp"-->
|
||||
<!-- android:text="@string/verification_request_alert_title"-->
|
||||
<!-- android:textColor="?riotx_text_primary"-->
|
||||
<!-- android:textSize="20sp"-->
|
||||
<!-- android:textStyle="bold"-->
|
||||
<!-- android:transitionName="bottomSheetDisplayName"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="@id/verificationRequestAvatar"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||
<!-- app:layout_constraintStart_toEndOf="@id/verificationRequestAvatar"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="@id/verificationRequestAvatar" />-->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/verificationRequestText"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -53,8 +23,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/start_verification"
|
||||
app:layout_constraintTop_toBottomOf="@id/verificationRequestText"
|
||||
tools:visibility="visible" />
|
||||
app:layout_constraintTop_toBottomOf="@id/verificationRequestText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/verificationWaitingText"
|
||||
|
@ -65,6 +34,7 @@
|
|||
android:textSize="17sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="@id/verificationStartButton"
|
||||
app:layout_constraintTop_toTopOf="@id/verificationStartButton"
|
||||
tools:text="@string/verification_request_waiting_for" />
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<string name="verification_conclusion_warning">Untrusted sign in</string>
|
||||
<string name="verification_sas_match">They match</string>
|
||||
<string name="verification_sas_do_not_match">They don‘t match</string>
|
||||
<string name="verification_sas_do_not_match">They don\'t match</string>
|
||||
<string name="verify_user_sas_emoji_help_text">Verify this user by confirming the following unique emoji appear on their screen, in the same order."</string>
|
||||
<string name="verify_user_sas_emoji_security_tip">For ultimate security, use another trusted means of communication or do this in person.</string>
|
||||
<string name="verification_green_shield">Look for the green shield to ensure a user is trusted. Trust all users in a room to ensure the room is secure.</string>
|
||||
|
@ -31,4 +31,22 @@
|
|||
<string name="verification_request_you_accepted">You accepted</string>
|
||||
<string name="verification_sent">Verification Sent</string>
|
||||
<string name="verification_request">Verification Request</string>
|
||||
|
||||
<!-- Sender name of a message when it is send by you, e.g. You: Hello!-->
|
||||
<string name="you">You</string>
|
||||
|
||||
<string name="verify_by_scanning_title">Verify by scanning</string>
|
||||
<!-- the %s will be replaced by verify_open_camera_link that will be clickable -->
|
||||
<string name="verify_by_scanning_description">Ask the other user to scan this code, or %s to scan theirs</string>
|
||||
<!-- This part is inserted in verify_by_scanning_description-->
|
||||
<string name="verify_open_camera_link">open your camera</string>
|
||||
|
||||
<string name="verify_by_emoji_title">Verify by Emoji</string>
|
||||
<string name="verify_by_emoji_description">If you can’t scan the code above, verify by comparing a short, unique selection of emoji.</string>
|
||||
|
||||
<string name="aria_qr_code_description">QR code image</string>
|
||||
|
||||
<string name="verification_request_alert_title">Verify %s</string>
|
||||
<string name="verification_request_waiting_for">Waiting for %s…</string>
|
||||
<string name="verification_request_alert_description">For extra security, verify %s by checking a one-time code on both your devices.\n\nFor maximum security, do this in person.</string>
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Reference in a new issue