mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 18:35:40 +03:00
Verification: migrate to Epoxy - Choose Fragment
This commit is contained in:
parent
a8e81d95cf
commit
878bae1c45
9 changed files with 187 additions and 222 deletions
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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.riotx.features.crypto.verification.choose
|
||||
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.bottomsheet.bottomSheetSeparatorItem
|
||||
import im.vector.riotx.core.resources.ColorProvider
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationActionItem
|
||||
import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationBigImageItem
|
||||
import im.vector.riotx.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationChooseMethodController @Inject constructor(
|
||||
private val stringProvider: StringProvider,
|
||||
private val colorProvider: ColorProvider
|
||||
) : EpoxyController() {
|
||||
|
||||
var listener: Listener? = null
|
||||
|
||||
private var viewState: VerificationChooseMethodViewState? = null
|
||||
|
||||
init {
|
||||
// We are requesting a model build directly as the first build of epoxy is on the main thread.
|
||||
// It avoids to build the whole list on the main thread.
|
||||
requestModelBuild()
|
||||
}
|
||||
|
||||
fun update(viewState: VerificationChooseMethodViewState) {
|
||||
this.viewState = viewState
|
||||
requestModelBuild()
|
||||
}
|
||||
|
||||
override fun buildModels() {
|
||||
val state = viewState ?: return
|
||||
|
||||
if (state.QRModeAvailable) {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(stringProvider.getString(R.string.verification_scan_notice))
|
||||
}
|
||||
|
||||
// TODO Generate the QR code
|
||||
bottomSheetVerificationBigImageItem {
|
||||
id("qr")
|
||||
imageRes(R.drawable.riotx_logo)
|
||||
}
|
||||
|
||||
bottomSheetSeparatorItem {
|
||||
id("sep0")
|
||||
}
|
||||
|
||||
bottomSheetVerificationActionItem {
|
||||
id("openCamera")
|
||||
title(stringProvider.getString(R.string.verification_scan_their_code))
|
||||
titleColor(colorProvider.getColor(R.color.riotx_accent))
|
||||
iconRes(R.drawable.ic_camera)
|
||||
iconColor(colorProvider.getColor(R.color.riotx_accent))
|
||||
listener { listener?.openCamera() }
|
||||
}
|
||||
|
||||
bottomSheetSeparatorItem {
|
||||
id("sep1")
|
||||
}
|
||||
|
||||
bottomSheetVerificationActionItem {
|
||||
id("openEmoji")
|
||||
title(stringProvider.getString(R.string.verification_scan_emoji_title))
|
||||
titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
|
||||
subTitle(stringProvider.getString(R.string.verification_scan_emoji_subtitle))
|
||||
iconRes(R.drawable.ic_arrow_right)
|
||||
iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
|
||||
listener { listener?.doVerifyBySas() }
|
||||
}
|
||||
} else if (state.SASModeAvailable) {
|
||||
bottomSheetVerificationActionItem {
|
||||
id("openEmoji")
|
||||
title(stringProvider.getString(R.string.verification_no_scan_emoji_title))
|
||||
titleColor(colorProvider.getColor(R.color.riotx_accent))
|
||||
iconRes(R.drawable.ic_arrow_right)
|
||||
iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
|
||||
listener { listener?.doVerifyBySas() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun openCamera()
|
||||
fun doVerifyBySas()
|
||||
}
|
||||
}
|
|
@ -15,56 +15,59 @@
|
|||
*/
|
||||
package im.vector.riotx.features.crypto.verification.choose
|
||||
|
||||
import android.text.style.ClickableSpan
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.text.toSpannable
|
||||
import androidx.core.view.isVisible
|
||||
import butterknife.OnClick
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.cleanup
|
||||
import im.vector.riotx.core.extensions.configureWith
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.utils.tappableMatchingText
|
||||
import im.vector.riotx.features.crypto.verification.VerificationAction
|
||||
import im.vector.riotx.features.crypto.verification.VerificationBottomSheetViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_verification_choose_method.*
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationChooseMethodFragment @Inject constructor(
|
||||
val verificationChooseMethodViewModelFactory: VerificationChooseMethodViewModel.Factory
|
||||
) : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_verification_choose_method
|
||||
|
||||
private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
|
||||
val verificationChooseMethodViewModelFactory: VerificationChooseMethodViewModel.Factory,
|
||||
val controller: VerificationChooseMethodController
|
||||
) : VectorBaseFragment(), VerificationChooseMethodController.Listener {
|
||||
|
||||
private val viewModel by fragmentViewModel(VerificationChooseMethodViewModel::class)
|
||||
|
||||
private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
setupRecyclerView()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetVerificationRecyclerView.cleanup()
|
||||
controller.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
controller.listener = this
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
if (state.QRModeAvailable) {
|
||||
val cSpan = object : ClickableSpan() {
|
||||
override fun onClick(widget: View) {
|
||||
}
|
||||
}
|
||||
val openLink = getString(R.string.verify_open_camera_link)
|
||||
val descCharSequence =
|
||||
getString(R.string.verify_by_scanning_description, openLink)
|
||||
.toSpannable()
|
||||
.tappableMatchingText(openLink, cSpan)
|
||||
verifyQRDescription.text = descCharSequence
|
||||
verifyQRGroup.isVisible = true
|
||||
} else {
|
||||
verifyQRGroup.isVisible = false
|
||||
controller.update(state)
|
||||
}
|
||||
|
||||
verifyEmojiGroup.isVisible = state.SASMOdeAvailable
|
||||
}
|
||||
|
||||
@OnClick(R.id.verificationByEmojiButton)
|
||||
fun doVerifyBySas() = withState(sharedViewModel) {
|
||||
override fun doVerifyBySas() = withState(sharedViewModel) {
|
||||
sharedViewModel.handle(VerificationAction.StartSASVerification(
|
||||
it.otherUserMxItem?.id ?: "",
|
||||
it.pendingRequest?.transactionId ?: ""))
|
||||
}
|
||||
|
||||
override fun openCamera() {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ data class VerificationChooseMethodViewState(
|
|||
val otherUserId: String = "",
|
||||
val transactionId: String = "",
|
||||
val QRModeAvailable: Boolean = false,
|
||||
val SASMOdeAvailable: Boolean = false
|
||||
val SASModeAvailable: Boolean = false
|
||||
) : MvRxState
|
||||
|
||||
class VerificationChooseMethodViewModel @AssistedInject constructor(
|
||||
|
@ -57,7 +57,7 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
|
|||
setState {
|
||||
copy(
|
||||
QRModeAvailable = qrAvailable,
|
||||
SASMOdeAvailable = emojiAvailable
|
||||
SASModeAvailable = emojiAvailable
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
|
|||
return VerificationChooseMethodViewState(otherUserId = args.otherUserId,
|
||||
transactionId = args.verificationId ?: "",
|
||||
QRModeAvailable = qrAvailable,
|
||||
SASMOdeAvailable = emojiAvailable
|
||||
SASModeAvailable = emojiAvailable
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ abstract class BottomSheetVerificationActionItem : VectorEpoxyModel<BottomSheetV
|
|||
@EpoxyAttribute
|
||||
var titleColor: Int = 0
|
||||
@EpoxyAttribute
|
||||
var iconColor: Int = 0
|
||||
var iconColor: Int = -1
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var listener: () -> Unit
|
||||
|
@ -63,7 +63,9 @@ abstract class BottomSheetVerificationActionItem : VectorEpoxyModel<BottomSheetV
|
|||
if (iconRes != -1) {
|
||||
holder.icon.isVisible = true
|
||||
holder.icon.setImageResource(iconRes)
|
||||
if (iconColor != -1) {
|
||||
ImageViewCompat.setImageTintList(holder.icon, ColorStateList.valueOf(iconColor))
|
||||
}
|
||||
} else {
|
||||
holder.icon.isVisible = false
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package im.vector.riotx.features.crypto.verification.epoxy
|
||||
|
||||
import android.widget.ImageView
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotx.R
|
||||
|
@ -32,8 +33,18 @@ abstract class BottomSheetVerificationBigImageItem : VectorEpoxyModel<BottomShee
|
|||
@EpoxyAttribute
|
||||
var imageRes: Int = 0
|
||||
|
||||
@EpoxyAttribute
|
||||
var contentDescription: String? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
holder.image.setImageResource(imageRes)
|
||||
|
||||
if (contentDescription == null) {
|
||||
ViewCompat.setImportantForAccessibility(holder.image, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO)
|
||||
} else {
|
||||
ViewCompat.setImportantForAccessibility(holder.image, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES)
|
||||
holder.image.contentDescription = contentDescription
|
||||
}
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
|
22
vector/src/main/res/drawable/ic_camera.xml
Normal file
22
vector/src/main/res/drawable/ic_camera.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M23,19C23,20.1046 22.1046,21 21,21H3C1.8954,21 1,20.1046 1,19V8C1,6.8954 1.8954,6 3,6H7L9,3H15L17,6H21C22.1046,6 23,6.8954 23,8V19Z"
|
||||
android:strokeWidth="2"
|
||||
android:strokeColor="#03B381"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M12,17C14.2091,17 16,15.2091 16,13C16,10.7909 14.2091,9 12,9C9.7909,9 8,10.7909 8,13C8,15.2091 9.7909,17 12,17Z"
|
||||
android:strokeWidth="2"
|
||||
android:strokeColor="#03B381"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</vector>
|
|
@ -1,117 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="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/verificationQRTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/verify_by_scanning_title"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/verifyQRDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/verify_by_scanning_description"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
app:layout_constraintTop_toBottomOf="@id/verificationQRTitle"
|
||||
tools:text="@string/verify_by_scanning_description" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/verifyQRImageView"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="180dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="?riotx_header_panel_background"
|
||||
android:contentDescription="@string/aria_qr_code_description"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/verifyQRDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/verificationEmojiTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="40dp"
|
||||
android:text="@string/verify_by_emoji_title"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/verifyQRImageView"
|
||||
app:layout_goneMarginTop="0dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/verifyEmojiDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/verify_by_emoji_description"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
app:layout_constraintTop_toBottomOf="@id/verificationEmojiTitle" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/verificationByEmojiButton"
|
||||
style="@style/VectorButtonStylePositive"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/verify_by_emoji_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/verifyEmojiDescription" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/verifyQRGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
app:constraint_referenced_ids="verifyQRDescription,verificationQRTitle,verifyQRImageView" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/verifyEmojiGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="visible"
|
||||
app:constraint_referenced_ids="verifyEmojiDescription,verificationEmojiTitle,verificationByEmojiButton" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,63 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/verificationConclusionTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/sas_verified"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
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"
|
||||
android:text="@string/sas_verified_successful_description"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
app:layout_constraintTop_toBottomOf="@id/verificationConclusionTitle"
|
||||
tools:text="@string/sas_verified_successful_description" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/verifyConclusionImageView"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="180dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
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"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
app:layout_constraintTop_toBottomOf="@id/verifyConclusionImageView"
|
||||
tools:text="@string/verification_green_shield" />
|
||||
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/verificationConclusionButton"
|
||||
style="@style/VectorButtonStylePositive"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/sas_got_it"
|
||||
app:layout_constraintTop_toBottomOf="@id/verifyConclusionBottomDescription" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -35,16 +35,17 @@
|
|||
<!-- 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="verification_scan_notice">Scan the code with the other user\'s device to securely verify each other</string>
|
||||
<string name="verification_scan_their_code">Scan their code</string>
|
||||
<string name="verification_scan_emoji_title">Can\'t scan</string>
|
||||
<string name="verification_scan_emoji_subtitle">If you\'re not in person, compare emoji instead</string>
|
||||
|
||||
<string name="verification_no_scan_emoji_title">Continue</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="a13n_qr_code_description">QR code image</string>
|
||||
|
||||
<string name="verification_verify_user">Verify %s</string>
|
||||
<string name="verification_verified_user">Verified %s</string>
|
||||
|
|
Loading…
Reference in a new issue