update qr code scanner screen

This commit is contained in:
2026-05-16 15:11:24 +07:00
parent 5b440112f1
commit 955da2fea6
5 changed files with 94 additions and 10 deletions

View File

@@ -26,6 +26,7 @@ kotlin {
implementation("io.coil-kt.coil3:coil-compose:3.4.0") implementation("io.coil-kt.coil3:coil-compose:3.4.0")
implementation("io.coil-kt.coil3:coil-network-okhttp:3.4.0") implementation("io.coil-kt.coil3:coil-network-okhttp:3.4.0")
implementation("su.reya:nostr-sdk-kmp:0.2.3") implementation("su.reya:nostr-sdk-kmp:0.2.3")
implementation("io.github.kalinjul.easyqrscan:scanner:0.7.0")
} }
commonMain.dependencies { commonMain.dependencies {
implementation(libs.compose.runtime) implementation(libs.compose.runtime)

View File

@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.hardware.camera" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@@ -9,11 +16,10 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@android:style/Theme.Material.Light.NoActionBar"> android:theme="@android:style/Theme.Material.Light.NoActionBar">
<activity <activity
android:exported="true" android:name=".MainActivity"
android:name=".MainActivity"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>

View File

@@ -52,7 +52,12 @@ fun ImportScreen(
snackbarHost = { SnackbarHost(snackbarHostState) }, snackbarHost = { SnackbarHost(snackbarHostState) },
topBar = { topBar = {
TopAppBar( TopAppBar(
title = { Text("Import") }, title = {
Text(
text = "Import",
style = MaterialTheme.typography.titleMediumEmphasized
)
},
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon( Icon(

View File

@@ -70,7 +70,12 @@ fun NewIdentityScreen(
snackbarHost = { SnackbarHost(snackbarHostState) }, snackbarHost = { SnackbarHost(snackbarHostState) },
topBar = { topBar = {
TopAppBar( TopAppBar(
title = { Text("Create a new identity") }, title = {
Text(
text = "Create a new identity",
style = MaterialTheme.typography.titleMediumEmphasized
)
},
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon( Icon(

View File

@@ -1,24 +1,45 @@
package su.reya.coop.screens package su.reya.coop.screens
import android.annotation.SuppressLint
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import coop.composeapp.generated.resources.Res import coop.composeapp.generated.resources.Res
import coop.composeapp.generated.resources.ic_arrow_back import coop.composeapp.generated.resources.ic_arrow_back
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import org.publicvalue.multiplatform.qrcode.CameraPosition
import org.publicvalue.multiplatform.qrcode.CodeType
import org.publicvalue.multiplatform.qrcode.ScannerWithPermissions
import su.reya.coop.LocalNavController import su.reya.coop.LocalNavController
import su.reya.coop.LocalSnackbarHostState
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable @Composable
fun ScanScreen( fun ScanScreen(
onBack: () -> Unit onBack: () -> Unit
) { ) {
val navController = LocalNavController.current val navController = LocalNavController.current
val snackbarHostState = LocalSnackbarHostState.current
val onResult: (String) -> Unit = { result -> val onResult: (String) -> Unit = { result ->
navController.previousBackStackEntry navController.previousBackStackEntry
@@ -28,9 +49,14 @@ fun ScanScreen(
} }
Scaffold( Scaffold(
snackbarHost = { SnackbarHost(snackbarHostState) },
topBar = { topBar = {
TopAppBar( TopAppBar(
title = { Text("Scan QR") }, title = {
Text(
text = "Scan QR", style = MaterialTheme.typography.titleMediumEmphasized
)
},
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon( Icon(
@@ -39,11 +65,52 @@ fun ScanScreen(
) )
} }
}, },
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.Transparent,
titleContentColor = Color.White,
navigationIconContentColor = Color.White,
)
) )
} },
) { innerPadding -> ) { innerPadding ->
Box(modifier = Modifier.padding(innerPadding)) { Box(modifier = Modifier.fillMaxSize()) {
Text("Scan QR") ScannerWithPermissions(
modifier = Modifier.fillMaxSize(),
onScanned = {
println("Scanned: $it");
onResult(it)
true
},
types = listOf(CodeType.QR),
cameraPosition = CameraPosition.BACK,
enableTorch = false
)
Canvas(modifier = Modifier.fillMaxSize()) {
val scannerSize = 250.dp.toPx()
val left = (size.width - scannerSize) / 2
val top = (size.height - scannerSize) / 2
drawRect(color = Color.Black.copy(alpha = 0.6f))
drawRect(
color = Color.Transparent,
topLeft = Offset(left, top),
size = Size(scannerSize, scannerSize),
blendMode = BlendMode.Clear
)
}
Box(
modifier = Modifier
.size(250.dp)
.align(Alignment.Center)
.border(2.dp, Color.White, RoundedCornerShape(12.dp))
)
Text(
text = "Scan a Nostr address",
style = MaterialTheme.typography.titleSmallEmphasized,
color = Color.White,
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 64.dp)
)
} }
} }
} }