mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 13:38:49 +03:00
Manage done states + cleaning
This commit is contained in:
parent
935b3d7f3f
commit
5b210df7c5
23 changed files with 115 additions and 54 deletions
|
@ -55,7 +55,7 @@ interface SasVerificationService {
|
|||
*/
|
||||
fun beginKeyVerification(method: String, userId: String, deviceID: String): String?
|
||||
|
||||
fun requestKeyVerificationInDMs(userId: String, roomId: String, callback: MatrixCallback<String>?) : PendingVerificationRequest
|
||||
fun requestKeyVerificationInDMs(userId: String, roomId: String, callback: MatrixCallback<String>?): PendingVerificationRequest
|
||||
|
||||
fun beginKeyVerificationInDMs(method: String,
|
||||
transactionId: String,
|
||||
|
@ -76,4 +76,17 @@ interface SasVerificationService {
|
|||
fun verificationRequestCreated(pr: PendingVerificationRequest) {}
|
||||
fun verificationRequestUpdated(pr: PendingVerificationRequest) {}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ package im.vector.matrix.android.api.session.room.model.message
|
|||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.events.model.toContent
|
||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||
import im.vector.matrix.android.internal.crypto.verification.VerificationInfo
|
||||
|
||||
|
@ -24,5 +26,11 @@ import im.vector.matrix.android.internal.crypto.verification.VerificationInfo
|
|||
internal data class MessageVerificationDoneContent(
|
||||
@Json(name = "m.relates_to") val relatesTo: RelationDefaultContent?
|
||||
) : VerificationInfo {
|
||||
override fun isValid() = true
|
||||
|
||||
override val transactionID: String?
|
||||
get() = relatesTo?.eventId
|
||||
|
||||
override fun isValid() = transactionID?.isNotEmpty() == true
|
||||
|
||||
override fun toEventContent(): Content? = this.toContent()
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ internal data class KeyVerificationRequest(
|
|||
val timestamp: Int,
|
||||
|
||||
@Json(name = "transaction_id")
|
||||
var transactionID: String? = null
|
||||
override var transactionID: String? = null
|
||||
|
||||
) : SendToDeviceObject, VerificationInfo {
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.crypto.tasks
|
|||
|
||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
||||
import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
||||
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationService
|
||||
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
|
||||
|
@ -52,27 +53,16 @@ internal class DefaultRoomVerificationUpdateTask @Inject constructor(
|
|||
override suspend fun execute(params: RoomVerificationUpdateTask.Params) {
|
||||
// TODO ignore initial sync or back pagination?
|
||||
|
||||
val now = System.currentTimeMillis()
|
||||
val tooInThePast = now - (10 * 60 * 1000)
|
||||
val fiveMinInMs = 5 * 60 * 1000
|
||||
val tooInTheFuture = System.currentTimeMillis() + fiveMinInMs
|
||||
|
||||
params.events.forEach { event ->
|
||||
Timber.d("## SAS Verification live observer: received msgId: ${event.eventId} msgtype: ${event.type} from ${event.senderId}")
|
||||
Timber.v("## SAS Verification live observer: received msgId: $event")
|
||||
|
||||
// If the request is in the future by more than 5 minutes or more than 10 minutes in the past,
|
||||
// the message should be ignored by the receiver.
|
||||
val ageLocalTs = event.ageLocalTs
|
||||
if (ageLocalTs != null && (now - ageLocalTs) > fiveMinInMs) {
|
||||
Timber.d("## SAS Verification live observer: msgId: ${event.eventId} is too old (age: ${(now - ageLocalTs)})")
|
||||
return@forEach
|
||||
} else {
|
||||
val eventOrigin = event.originServerTs ?: -1
|
||||
if (eventOrigin < tooInThePast || eventOrigin > tooInTheFuture) {
|
||||
Timber.d("## SAS Verification live observer: msgId: ${event.eventId} is too old (ts: $eventOrigin")
|
||||
return@forEach
|
||||
}
|
||||
|
||||
if (!SasVerificationService.isValidRequest(event.ageLocalTs
|
||||
?: event.originServerTs)) return@forEach Unit.also {
|
||||
Timber.d("## SAS Verification live observer: msgId: ${event.eventId} is outdated")
|
||||
}
|
||||
|
||||
// decrypt if needed?
|
||||
|
@ -149,7 +139,7 @@ internal class DefaultRoomVerificationUpdateTask @Inject constructor(
|
|||
EventType.KEY_VERIFICATION_DONE -> {
|
||||
params.sasVerificationService.onRoomEvent(event)
|
||||
}
|
||||
EventType.MESSAGE -> {
|
||||
EventType.MESSAGE -> {
|
||||
if (MessageType.MSGTYPE_VERIFICATION_REQUEST == event.getClearContent().toModel<MessageContent>()?.type) {
|
||||
params.sasVerificationService.onRoomRequestReceived(event)
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
|
||||
/**
|
||||
* Map [sender: [PendingVerificationRequest]]
|
||||
* For now we keep all requests (even terminated ones) during the lifetime of the app.
|
||||
*/
|
||||
private val pendingRequests = HashMap<String, ArrayList<PendingVerificationRequest>>()
|
||||
|
||||
|
@ -84,7 +85,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 -> {
|
||||
|
@ -93,13 +94,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
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +110,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 -> {
|
||||
|
@ -119,24 +120,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 -> {
|
||||
// TODO?
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -247,6 +248,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
}
|
||||
|
||||
val pendingVerificationRequest = PendingVerificationRequest(
|
||||
ageLocalTs = event.ageLocalTs ?: System.currentTimeMillis(),
|
||||
isIncoming = true,
|
||||
otherUserId = senderId, // requestInfo.toUserId,
|
||||
transactionId = event.eventId,
|
||||
|
@ -411,7 +413,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
return
|
||||
}
|
||||
getExistingVerificationRequest(event.senderId ?: "", cancelReq.transactionID)?.let {
|
||||
updateOutgoingPendingRequest(it.copy(cancelConclusion = safeValueOf(cancelReq.code)))
|
||||
updatePendingRequest(it.copy(cancelConclusion = safeValueOf(cancelReq.code)))
|
||||
// Should we remove it from the list?
|
||||
}
|
||||
handleOnCancel(event.senderId!!, cancelReq)
|
||||
|
@ -433,14 +435,20 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
|
||||
private fun handleOnCancel(otherUserId: String, cancelReq: VerificationInfoCancel) {
|
||||
Timber.v("## SAS onCancelReceived otherUser:$otherUserId reason:${cancelReq.reason}")
|
||||
val existing = getExistingTransaction(otherUserId, cancelReq.transactionID!!)
|
||||
if (existing == null) {
|
||||
Timber.e("## Received invalid cancel request")
|
||||
return
|
||||
|
||||
val existingTransaction = getExistingTransaction(otherUserId, cancelReq.transactionID!!)
|
||||
val existingRequest = getExistingVerificationRequest(otherUserId, cancelReq.transactionID!!)
|
||||
|
||||
if (existingRequest != null) {
|
||||
// Mark this request as cancelled
|
||||
updatePendingRequest(existingRequest.copy(
|
||||
cancelConclusion = safeValueOf(cancelReq.code)
|
||||
))
|
||||
}
|
||||
if (existing is SASVerificationTransaction) {
|
||||
existing.cancelledReason = safeValueOf(cancelReq.code)
|
||||
existing.state = SasVerificationTxState.OnCancelled
|
||||
|
||||
if (existingTransaction is SASVerificationTransaction) {
|
||||
existingTransaction.cancelledReason = safeValueOf(cancelReq.code)
|
||||
existingTransaction.state = SasVerificationTxState.OnCancelled
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,6 +566,23 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
handleReadyReceived(event.senderId, readyReq)
|
||||
}
|
||||
|
||||
private fun onRoomDoneReceived(event: Event) {
|
||||
val doneReq = event.getClearContent().toModel<MessageVerificationDoneContent>()
|
||||
?.copy(
|
||||
// relates_to is in clear in encrypted payload
|
||||
relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo
|
||||
)
|
||||
|
||||
if (doneReq == null || doneReq.isValid().not() || event.senderId == null) {
|
||||
// ignore
|
||||
Timber.e("## SAS Received invalid Done request")
|
||||
// TODO should we cancel?
|
||||
return
|
||||
}
|
||||
|
||||
handleDoneReceived(event.senderId, doneReq)
|
||||
}
|
||||
|
||||
private fun onMacReceived(event: Event) {
|
||||
val macReq = event.getClearContent().toModel<KeyVerificationMac>()!!
|
||||
|
||||
|
@ -589,7 +614,16 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
Timber.e("## SAS Received Ready for unknown request txId:${readyReq.transactionID} fromDevice ${readyReq.fromDevice}")
|
||||
return
|
||||
}
|
||||
updateOutgoingPendingRequest(existingRequest.copy(readyInfo = readyReq))
|
||||
updatePendingRequest(existingRequest.copy(readyInfo = readyReq))
|
||||
}
|
||||
|
||||
private fun handleDoneReceived(senderId: String, doneInfo: VerificationInfo) {
|
||||
val existingRequest = getExistingVerificationRequest(senderId)?.find { it.transactionId == doneInfo.transactionID }
|
||||
if (existingRequest == null) {
|
||||
Timber.e("## SAS Received Done for unknown request txId:${doneInfo.transactionID}")
|
||||
return
|
||||
}
|
||||
updatePendingRequest(existingRequest.copy(isSuccessful = true))
|
||||
}
|
||||
|
||||
override fun getExistingTransaction(otherUser: String, tid: String): VerificationTransaction? {
|
||||
|
@ -675,6 +709,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
cryptoService = cryptoService
|
||||
)
|
||||
val verificationRequest = PendingVerificationRequest(
|
||||
ageLocalTs = System.currentTimeMillis(),
|
||||
isIncoming = false,
|
||||
localID = params.event.eventId ?: "",
|
||||
otherUserId = userId
|
||||
|
@ -694,7 +729,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
this.callback = object : MatrixCallback<SendResponse> {
|
||||
override fun onSuccess(data: SendResponse) {
|
||||
params.event.getClearContent().toModel<MessageVerificationRequestContent>()?.let {
|
||||
updateOutgoingPendingRequest(verificationRequest.copy(
|
||||
updatePendingRequest(verificationRequest.copy(
|
||||
transactionId = data.eventId,
|
||||
requestInfo = it
|
||||
))
|
||||
|
@ -713,7 +748,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
return verificationRequest
|
||||
}
|
||||
|
||||
private fun updateOutgoingPendingRequest(updated: PendingVerificationRequest) {
|
||||
private fun updatePendingRequest(updated: PendingVerificationRequest) {
|
||||
val requestsForUser = pendingRequests[updated.otherUserId]
|
||||
?: ArrayList<PendingVerificationRequest>().also {
|
||||
pendingRequests[updated.otherUserId] = it
|
||||
|
@ -768,7 +803,7 @@ internal class DefaultSasVerificationService @Inject constructor(
|
|||
CancelCode.User,
|
||||
null // TODO handle error?
|
||||
)
|
||||
updateOutgoingPendingRequest(it.copy(readyInfo = readyMsg))
|
||||
updatePendingRequest(it.copy(readyInfo = readyMsg))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.*
|
|||
* Stores current pending verification requests
|
||||
*/
|
||||
data class PendingVerificationRequest(
|
||||
val ageLocalTs : Long,
|
||||
val isIncoming: Boolean = false,
|
||||
val localID: String = UUID.randomUUID().toString(),
|
||||
val otherUserId: String,
|
||||
|
|
|
@ -22,4 +22,5 @@ interface VerificationInfo {
|
|||
fun toEventContent(): Content? = null
|
||||
fun toSendToDeviceObject(): SendToDeviceObject? = null
|
||||
fun isValid() : Boolean
|
||||
val transactionID: String?
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ package im.vector.matrix.android.internal.crypto.verification
|
|||
|
||||
internal interface VerificationInfoAccept : VerificationInfo {
|
||||
|
||||
val transactionID: String?
|
||||
override val transactionID: String?
|
||||
|
||||
/**
|
||||
* The key agreement protocol that Bob’s device has selected to use, out of the list proposed by Alice’s device
|
||||
|
|
|
@ -17,7 +17,7 @@ package im.vector.matrix.android.internal.crypto.verification
|
|||
|
||||
internal interface VerificationInfoCancel : VerificationInfo {
|
||||
|
||||
val transactionID: String?
|
||||
override val transactionID: String?
|
||||
/**
|
||||
* machine-readable reason for cancelling, see [CancelCode]
|
||||
*/
|
||||
|
|
|
@ -20,7 +20,7 @@ package im.vector.matrix.android.internal.crypto.verification
|
|||
*/
|
||||
internal interface VerificationInfoKey : VerificationInfo {
|
||||
|
||||
val transactionID: String?
|
||||
override val transactionID: String?
|
||||
/**
|
||||
* The device’s ephemeral public key, as an unpadded base64 string
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ package im.vector.matrix.android.internal.crypto.verification
|
|||
|
||||
internal interface VerificationInfoMac : VerificationInfo {
|
||||
|
||||
val transactionID: String?
|
||||
override val transactionID: String?
|
||||
|
||||
/**
|
||||
* A map of key ID to the MAC of the key, as an unpadded base64 string, calculated using the MAC key
|
||||
|
|
|
@ -24,7 +24,7 @@ package im.vector.matrix.android.internal.crypto.verification
|
|||
*/
|
||||
interface VerificationInfoReady : VerificationInfo {
|
||||
|
||||
val transactionID: String?
|
||||
override val transactionID: String?
|
||||
|
||||
/**
|
||||
* The ID of the device that sent the m.key.verification.ready message
|
||||
|
|
|
@ -28,7 +28,7 @@ internal interface VerificationInfoStart : VerificationInfo {
|
|||
* This string must be unique for the pair of users performing verification for the duration that the transaction is valid.
|
||||
* Alice’s device should record this ID and use it in future messages in this transaction.
|
||||
*/
|
||||
val transactionID: String?
|
||||
override val transactionID: String?
|
||||
|
||||
/**
|
||||
* An array of key agreement protocols that Alice’s client understands.
|
||||
|
|
|
@ -31,6 +31,7 @@ import im.vector.riotx.core.extensions.observeEvent
|
|||
import im.vector.riotx.core.platform.SimpleFragmentActivity
|
||||
import im.vector.riotx.core.platform.WaitingViewData
|
||||
|
||||
// TODO Deprecated("replaced by bottomsheet UX")
|
||||
class SASVerificationActivity : SimpleFragmentActivity() {
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -29,6 +29,7 @@ import im.vector.riotx.core.platform.VectorBaseFragment
|
|||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO Deprecated("replaced by bottomsheet UX")
|
||||
class SASVerificationIncomingFragment @Inject constructor(
|
||||
private var avatarRenderer: AvatarRenderer
|
||||
) : VectorBaseFragment() {
|
||||
|
|
|
@ -29,6 +29,7 @@ import im.vector.riotx.R
|
|||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO Deprecated("replaced by bottomsheet UX")
|
||||
class SASVerificationShortCodeFragment @Inject constructor(): VectorBaseFragment() {
|
||||
|
||||
private lateinit var viewModel: SasVerificationViewModel
|
||||
|
|
|
@ -32,6 +32,7 @@ import im.vector.riotx.core.platform.VectorBaseActivity
|
|||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO Deprecated("replaced by bottomsheet UX")
|
||||
class SASVerificationStartFragment @Inject constructor(): VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_sas_verification_start
|
||||
|
|
|
@ -21,6 +21,7 @@ import im.vector.riotx.R
|
|||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO Deprecated("replaced by bottomsheet UX")
|
||||
class SASVerificationVerifiedFragment @Inject constructor() : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_sas_verification_verified
|
||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.matrix.android.api.session.user.model.User
|
|||
import im.vector.riotx.core.utils.LiveEvent
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO Deprecated("replaced by bottomsheet UX")
|
||||
class SasVerificationViewModel @Inject constructor() : ViewModel(),
|
||||
SasVerificationService.SasVerificationListener {
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ class EncryptionItemFactory @Inject constructor(private val stringProvider: Stri
|
|||
eventId = event.root.eventId ?: "?",
|
||||
senderId = event.root.senderId ?: "",
|
||||
sendState = event.root.sendState,
|
||||
ageLocalTS = event.root.ageLocalTs,
|
||||
avatarUrl = event.senderAvatar,
|
||||
memberName = event.getDisambiguatedDisplayName(),
|
||||
showInformation = false,
|
||||
|
|
|
@ -73,6 +73,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
|
|||
senderId = event.root.senderId ?: "",
|
||||
sendState = event.root.sendState,
|
||||
time = time,
|
||||
ageLocalTS = event.root.ageLocalTs,
|
||||
avatarUrl = avatarUrl,
|
||||
memberName = formattedMemberName,
|
||||
showInformation = showInformation,
|
||||
|
|
|
@ -28,6 +28,7 @@ data class MessageInformationData(
|
|||
val senderId: String,
|
||||
val sendState: SendState,
|
||||
val time: CharSequence? = null,
|
||||
val ageLocalTS : Long?,
|
||||
val avatarUrl: String?,
|
||||
val memberName: CharSequence? = null,
|
||||
val showInformation: Boolean = true,
|
||||
|
|
|
@ -28,6 +28,7 @@ import androidx.core.view.isVisible
|
|||
import androidx.core.view.updateLayoutParams
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationService
|
||||
import im.vector.matrix.android.internal.session.room.VerificationState
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.resources.ColorProvider
|
||||
|
@ -72,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
|
||||
|
@ -82,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)
|
||||
|
@ -101,13 +102,16 @@ abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestI
|
|||
}
|
||||
holder.statusTextView.isVisible = true
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
holder.buttonBar.isVisible = false
|
||||
holder.statusTextView.text = null
|
||||
holder.statusTextView.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
// Always hide buttons if request is too old
|
||||
holder.buttonBar.isVisible = holder.buttonBar.isVisible && SasVerificationService.isValidRequest(attributes.informationData.ageLocalTS)
|
||||
|
||||
holder.callback = callback
|
||||
holder.attributes = attributes
|
||||
|
||||
|
|
Loading…
Reference in a new issue