diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/usernamelinks/main/UsernameQrScanScreen.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/usernamelinks/main/UsernameQrScanScreen.kt index 8861a9e62c..363e8a6cc3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/usernamelinks/main/UsernameQrScanScreen.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/usernamelinks/main/UsernameQrScanScreen.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.components.settings.app.usernamelinks.main -import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -8,37 +7,21 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.Path -import androidx.compose.ui.graphics.PathEffect -import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.LifecycleOwner import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign -import org.signal.core.ui.Buttons import org.signal.core.ui.Dialogs -import org.signal.core.ui.theme.SignalTheme import org.signal.qr.QrScannerView import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.mediasend.camerax.CameraXModelBlocklist +import org.thoughtcrime.securesms.qr.QrScanScreens import org.thoughtcrime.securesms.recipients.Recipient import java.util.concurrent.TimeUnit @@ -58,8 +41,6 @@ fun UsernameQrScanScreen( hasCameraPermission: Boolean, modifier: Modifier = Modifier ) { - val path = remember { Path() } - when (qrScanResult) { QrScanResult.InvalidData -> { QrScanResultDialog(message = stringResource(R.string.UsernameLinkSettings_qr_result_invalid), onDismiss = onQrResultHandled) @@ -102,7 +83,7 @@ fun UsernameQrScanScreen( .fillMaxWidth() .weight(1f, true) ) { - AndroidView( + QrScanScreens.QrScanScreen( factory = { context -> val view = QrScannerView(context) disposables += view.qrData.throttleFirst(3000, TimeUnit.MILLISECONDS).subscribe { data -> @@ -113,54 +94,11 @@ fun UsernameQrScanScreen( update = { view -> view.start(lifecycleOwner = lifecycleOwner, forceLegacy = CameraXModelBlocklist.isBlocklisted()) }, - modifier = Modifier - .fillMaxWidth() - .fillMaxHeight() - .drawWithContent { - drawContent() - if (hasCameraPermission) { - drawQrCrosshair(path) - } - } + hasPermission = hasCameraPermission, + onRequestPermissions = onOpenCameraClicked, + qrHeaderLabelString = "", + onGalleryOpened = onOpenGalleryClicked ) - if (!hasCameraPermission) { - Column( - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .align(Alignment.Center) - .padding(50.dp) - ) { - Text( - text = stringResource(R.string.CameraXFragment_to_scan_qr_code_allow_camera), - textAlign = TextAlign.Center, - style = MaterialTheme.typography.bodyLarge, - color = Color.White, - modifier = Modifier.padding(10.dp) - ) - Buttons.MediumTonal( - colors = ButtonDefaults.filledTonalButtonColors(), - onClick = onOpenCameraClicked - ) { - Text(stringResource(R.string.CameraXFragment_allow_access)) - } - } - } - - FloatingActionButton( - shape = CircleShape, - containerColor = SignalTheme.colors.colorSurface1, - modifier = Modifier - .align(Alignment.BottomCenter) - .padding(bottom = 24.dp), - onClick = onOpenGalleryClicked - ) { - Image( - painter = painterResource(id = R.drawable.symbol_album_24), - contentDescription = null, - colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface) - ) - } } Row( @@ -188,40 +126,3 @@ private fun QrScanResultDialog(title: String? = null, message: String, onDismiss onDismiss = onDismiss ) } - -private fun DrawScope.drawQrCrosshair(path: Path) { - val crosshairWidth: Float = size.minDimension * 0.6f - val crosshairLineLength = crosshairWidth * 0.125f - - val topLeft = center - Offset(crosshairWidth / 2, crosshairWidth / 2) - val topRight = center + Offset(crosshairWidth / 2, -crosshairWidth / 2) - val bottomRight = center + Offset(crosshairWidth / 2, crosshairWidth / 2) - val bottomLeft = center + Offset(-crosshairWidth / 2, crosshairWidth / 2) - - path.reset() - - drawPath( - path = path.apply { - moveTo(topLeft.x, topLeft.y + crosshairLineLength) - lineTo(topLeft.x, topLeft.y) - lineTo(topLeft.x + crosshairLineLength, topLeft.y) - - moveTo(topRight.x - crosshairLineLength, topRight.y) - lineTo(topRight.x, topRight.y) - lineTo(topRight.x, topRight.y + crosshairLineLength) - - moveTo(bottomRight.x, bottomRight.y - crosshairLineLength) - lineTo(bottomRight.x, bottomRight.y) - lineTo(bottomRight.x - crosshairLineLength, bottomRight.y) - - moveTo(bottomLeft.x + crosshairLineLength, bottomLeft.y) - lineTo(bottomLeft.x, bottomLeft.y) - lineTo(bottomLeft.x, bottomLeft.y - crosshairLineLength) - }, - color = Color.White, - style = Stroke( - width = 3.dp.toPx(), - pathEffect = PathEffect.cornerPathEffect(10.dp.toPx()) - ) - ) -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceQrScanScreen.kt b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceQrScanScreen.kt index 9708739780..57c4a73b9b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceQrScanScreen.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceQrScanScreen.kt @@ -107,7 +107,7 @@ fun LinkDeviceQrScanScreen( }, hasPermission = hasPermission, onRequestPermissions = onRequestPermissions, - qrString = stringResource(R.string.AddLinkDeviceFragment__scan_the_qr_code), + qrHeaderLabelString = stringResource(R.string.AddLinkDeviceFragment__scan_the_qr_code), onGalleryOpened = onGalleryOpened ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/qr/QrScanScreens.kt b/app/src/main/java/org/thoughtcrime/securesms/qr/QrScanScreens.kt index bc907983db..bf84546831 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/qr/QrScanScreens.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/qr/QrScanScreens.kt @@ -46,7 +46,7 @@ object QrScanScreens { update: (QrScannerView) -> Unit = NoOpUpdate, hasPermission: Boolean, onRequestPermissions: () -> Unit = {}, - qrString: String, + qrHeaderLabelString: String, onGalleryOpened: () -> Unit = {} ) { val path = remember { Path() } @@ -97,7 +97,7 @@ object QrScanScreens { } } else { Text( - text = qrString, + text = qrHeaderLabelString, style = MaterialTheme.typography.bodyMedium, color = Color.White, textAlign = TextAlign.Center,