diff options
Diffstat (limited to 'wallet/src/main/java/net/taler/wallet/compose/QrCodeUriComposable.kt')
-rw-r--r-- | wallet/src/main/java/net/taler/wallet/compose/QrCodeUriComposable.kt | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/compose/QrCodeUriComposable.kt b/wallet/src/main/java/net/taler/wallet/compose/QrCodeUriComposable.kt new file mode 100644 index 0000000..4991094 --- /dev/null +++ b/wallet/src/main/java/net/taler/wallet/compose/QrCodeUriComposable.kt @@ -0,0 +1,153 @@ +/* + * This file is part of GNU Taler + * (C) 2022 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +package net.taler.wallet.compose + +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context +import androidx.compose.foundation.Image +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ContentCopy +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonColors +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.produceState +import androidx.compose.ui.Alignment.Companion.CenterHorizontally +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.min +import androidx.core.content.getSystemService +import net.taler.common.QrCodeManager +import net.taler.wallet.R + +@Composable +fun ColumnScope.QrCodeUriComposable( + talerUri: String, + clipBoardLabel: String, + buttonText: String = stringResource(R.string.copy), + inBetween: (@Composable ColumnScope.() -> Unit)? = null, +) { + val qrCodeSize = getQrCodeSize() + val qrPlaceHolder = if (LocalInspectionMode.current) { + QrCodeManager.makeQrCode(talerUri, qrCodeSize.value.toInt()).asImageBitmap() + } else null + val qrState = produceState(qrPlaceHolder) { + value = QrCodeManager.makeQrCode(talerUri, qrCodeSize.value.toInt()).asImageBitmap() + } + qrState.value?.let { qrCode -> + Image( + modifier = Modifier + .size(qrCodeSize) + .align(CenterHorizontally) + .padding(vertical = 8.dp), + bitmap = qrCode, + contentDescription = stringResource(id = R.string.button_scan_qr_code), + ) + } + if (inBetween != null) inBetween() + val scrollState = rememberScrollState() + Box(modifier = Modifier.padding(16.dp)) { + Text( + modifier = Modifier.horizontalScroll(scrollState), + fontFamily = FontFamily.Monospace, + style = MaterialTheme.typography.bodyLarge, + text = talerUri, + ) + } + Row( + modifier = Modifier + .padding(horizontal = 16.dp) + .fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly, + ) { + CopyToClipboardButton( + label = clipBoardLabel, + content = talerUri, + buttonText = buttonText, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.primaryContainer, + contentColor = MaterialTheme.colorScheme.onPrimaryContainer + ) + ) + ShareButton( + content = talerUri, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.primaryContainer, + contentColor = MaterialTheme.colorScheme.onPrimaryContainer + ) + ) + } +} + +@Composable +fun getQrCodeSize(): Dp { + val configuration = LocalConfiguration.current + val screenHeight = configuration.screenHeightDp.dp + val screenWidth = configuration.screenWidthDp.dp + return min(screenHeight, screenWidth) +} + +@Composable +fun CopyToClipboardButton( + label: String, + content: String, + modifier: Modifier = Modifier, + buttonText: String = stringResource(R.string.copy), + colors: ButtonColors = ButtonDefaults.buttonColors(), +) { + val context = LocalContext.current + Button( + modifier = modifier, + colors = colors, + onClick = { copyToClipBoard(context, label, content) }, + ) { + Icon( + Icons.Default.ContentCopy, + buttonText, + modifier = Modifier.size(ButtonDefaults.IconSize), + ) + Spacer(Modifier.size(ButtonDefaults.IconSpacing)) + Text(buttonText) + } +} + +fun copyToClipBoard(context: Context, label: String, str: String) { + val clipboard = context.getSystemService<ClipboardManager>() + val clip = ClipData.newPlainText(label, str) + clipboard?.setPrimaryClip(clip) +} |