ui: smaller QR code for short links (#5946)

* ui: smaller QR code for short links

* more small

* size

* translations
This commit is contained in:
Evgeny
2025-05-25 11:56:00 +01:00
committed by GitHub
parent ee2ea152dc
commit b848f735ce
9 changed files with 46 additions and 31 deletions
@@ -101,13 +101,13 @@ actual fun GrayU8.toImageBitmap(): ImageBitmap = ConvertBitmap.grayToBitmap(this
actual fun ImageBitmap.hasAlpha(): Boolean = hasAlpha
actual fun ImageBitmap.addLogo(): ImageBitmap = asAndroidBitmap().applyCanvas {
val radius = (width * 0.16f) / 2
actual fun ImageBitmap.addLogo(size: Float): ImageBitmap = asAndroidBitmap().applyCanvas {
val radius = (width * size) / 2
val paint = android.graphics.Paint()
paint.color = android.graphics.Color.WHITE
drawCircle(width / 2f, height / 2f, radius, paint)
val logo = androidAppContext.resources.getDrawable(R.drawable.icon_foreground_android_common, null).toBitmap()
val logoSize = (width * 0.24).toInt()
val logoSize = (width * size * 1.5).toInt()
translate((width - logoSize) / 2f, (height - logoSize) / 2f)
drawBitmap(logo, null, android.graphics.Rect(0, 0, logoSize, logoSize), null)
}.asImageBitmap()
@@ -16,7 +16,7 @@ expect fun compressImageData(bitmap: ImageBitmap, usePng: Boolean): ByteArrayOut
expect fun GrayU8.toImageBitmap(): ImageBitmap
expect fun ImageBitmap.hasAlpha(): Boolean
expect fun ImageBitmap.addLogo(): ImageBitmap
expect fun ImageBitmap.addLogo(size: Float): ImageBitmap
expect fun ImageBitmap.scale(width: Int, height: Int): ImageBitmap
expect fun isImage(uri: URI): Boolean
@@ -31,6 +31,7 @@ fun SimpleXCreatedLinkQRCode(
) {
QRCode(
connLink.simplexChatUri(short),
small = short && connLink.connShortLink != null,
modifier,
padding,
tintColor,
@@ -50,6 +51,7 @@ fun SimpleXLinkQRCode(
) {
QRCode(
simplexChatLink(connReq),
small = connReq.count() < 200,
modifier,
padding,
tintColor,
@@ -61,6 +63,7 @@ fun SimpleXLinkQRCode(
@Composable
fun QRCode(
connReq: String,
small: Boolean = false,
modifier: Modifier = Modifier,
padding: PaddingValues = PaddingValues(horizontal = DEFAULT_PADDING * 2f, vertical = DEFAULT_PADDING_HALF),
tintColor: Color = Color(0xff062d56),
@@ -68,9 +71,11 @@ fun QRCode(
onShare: (() -> Unit)? = null,
) {
val scope = rememberCoroutineScope()
val logoSize = if (small) 0.21f else 0.16f
val errorLevel = if (small) QrCode.ErrorLevel.M else QrCode.ErrorLevel.L
val qr = remember(connReq, tintColor, withLogo) {
qrCodeBitmap(connReq, 1024).replaceColor(Color.Black.toArgb(), tintColor.toArgb())
.let { if (withLogo) it.addLogo() else it }
qrCodeBitmap(connReq, 1024, errorLevel).replaceColor(Color.Black.toArgb(), tintColor.toArgb())
.let { if (withLogo) it.addLogo(logoSize) else it }
}
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
Image(
@@ -79,12 +84,13 @@ fun QRCode(
Modifier
.padding(padding)
.widthIn(max = 400.dp)
.fillMaxWidth(if (small) 0.67f else 1f)
.aspectRatio(1f)
.then(modifier)
.clickable {
scope.launch {
val image = qrCodeBitmap(connReq, 1024).replaceColor(Color.Black.toArgb(), tintColor.toArgb())
.let { if (withLogo) it.addLogo() else it }
val image = qrCodeBitmap(connReq, 1024, errorLevel).replaceColor(Color.Black.toArgb(), tintColor.toArgb())
.let { if (withLogo) it.addLogo(logoSize) else it }
val file = saveTempImageUncompressed(image, true)
if (file != null) {
shareFile("", CryptoFile.plain(file.absolutePath))
@@ -96,8 +102,8 @@ fun QRCode(
}
}
fun qrCodeBitmap(content: String, size: Int = 1024): ImageBitmap {
val qrCode = QrCodeEncoder().addAutomatic(content).setError(QrCode.ErrorLevel.L).fixate()
fun qrCodeBitmap(content: String, size: Int = 1024, errorLevel: QrCode.ErrorLevel): ImageBitmap {
val qrCode = QrCodeEncoder().addAutomatic(content).setError(errorLevel).fixate()
/** See [QrCodeGeneratorImage.initialize] and [FiducialImageEngine.configure] for size calculation */
val numModules = QrCode.totalModules(qrCode.version)
// Hide border on light themes to make it fit to the same place as camera in QRCodeScanner.
@@ -189,7 +189,7 @@ fun CustomServer(
if (valid.value) {
SectionDividerSpaced()
SectionView(stringResource(MR.strings.smp_servers_add_to_another_device).uppercase()) {
QRCode(serverAddress.value)
QRCode(serverAddress.value, small = true)
}
}
}
@@ -133,9 +133,9 @@ actual fun ImageBitmap.hasAlpha(): Boolean {
return false
}
actual fun ImageBitmap.addLogo(): ImageBitmap {
val radius = (width * 0.16f).toInt()
val logoSize = (width * 0.24).toInt()
actual fun ImageBitmap.addLogo(size: Float): ImageBitmap {
val radius = (width * size).toInt()
val logoSize = (width * size * 1.5).toInt()
val logo: BufferedImage = MR.images.icon_foreground_common.image
val original = toAwtImage()
val withLogo = BufferedImage(width, height, original.type)