From a6f7c05458c7a0777e6c8c695f719188babc952c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 May 2026 09:24:21 +0200 Subject: [PATCH] [Link new device] Automatically rotate the QR Code - limit number of rotation to 10. --- .../impl/LinkNewMobileHandler.kt | 8 ++++++++ .../screens/qrcode/ShowQrCodePresenter.kt | 19 ++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewMobileHandler.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewMobileHandler.kt index 12cf3af3b9..18d67f577a 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewMobileHandler.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/LinkNewMobileHandler.kt @@ -12,6 +12,7 @@ import dev.zacsweers.metro.SingleIn import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.linknewdevice.ErrorType import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileStep import io.element.android.libraries.matrix.api.logs.LoggerTags @@ -69,4 +70,11 @@ class LinkNewMobileHandler( fun rotateQrCode() { createAndStartNewHandler() } + + fun onTooManyRotation() { + reset() + sessionScope.launch { + linkMobileStepFlow.emit(LinkMobileStep.Error(ErrorType.Expired("Too many QR code rotations"))) + } + } } diff --git a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenter.kt b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenter.kt index 1688a6469d..3deff8c603 100644 --- a/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenter.kt +++ b/features/linknewdevice/impl/src/main/kotlin/io/element/android/features/linknewdevice/impl/screens/qrcode/ShowQrCodePresenter.kt @@ -9,7 +9,10 @@ package io.element.android.features.linknewdevice.impl.screens.qrcode import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.produceState +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject @@ -35,6 +38,7 @@ class ShowQrCodePresenter( @Composable override fun present(): ShowQrCodeState { + var qrCodeRotationCounter by remember { mutableIntStateOf(MAX_QR_CODE_ROTATION) } val data by produceState>(AsyncData.Success(initialData)) { linkNewMobileHandler.stepFlow.collect { step -> when (step) { @@ -42,9 +46,14 @@ class ShowQrCodePresenter( value = AsyncData.Success(step.data) } is LinkMobileStep.QrRotating -> { - Timber.tag(tag.value).d("Rotating QrCode") - linkNewMobileHandler.rotateQrCode() - value = AsyncData.Loading() + if (qrCodeRotationCounter-- > 0) { + Timber.tag(tag.value).d("Rotating QrCode") + linkNewMobileHandler.rotateQrCode() + value = AsyncData.Loading() + } else { + Timber.tag(tag.value).w("Max QR code rotation reached, not rotating anymore") + linkNewMobileHandler.onTooManyRotation() + } } else -> Unit } @@ -55,4 +64,8 @@ class ShowQrCodePresenter( data = data, ) } + + companion object { + const val MAX_QR_CODE_ROTATION = 10 + } }