package ru.omni_devel.cards import android.app.Activity import android.os.Bundle import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Button import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.IconButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import com.google.zxing.BarcodeFormat import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanOptions import ru.omni_devel.cards.ui.theme.OmniCardsTheme class EditCardActivity : ComponentActivity() { private lateinit var db: DbHelper override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() db = DbHelper(this, null) val cardId = intent.getIntExtra("cardId", -1) val cardInfo = db.getCard(cardId) setContent { OmniCardsTheme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> EditCardPage(cardInfo, innerPadding, getDbFun = { return@EditCardPage db }) } } } } } @Composable fun CardEditable( cardName: String, onCardNameChange: (String) -> Unit, codeValue: String, oncodeValueChange: (String) -> Unit, codeType: BarcodeFormat, onCodeTypeChange: (BarcodeFormat) -> Unit ) { var isCodeTypeDropdownExpanded by remember { mutableStateOf(false) } val fieldModifier = Modifier.fillMaxWidth() val scanLauncher = rememberLauncherForActivityResult( contract = ScanContract() ) { result -> if (result.contents != null) { oncodeValueChange(result.contents) result.formatName?.let { formatName -> try { onCodeTypeChange(BarcodeFormat.valueOf(formatName)) } catch (e: IllegalArgumentException) {} } } } OutlinedTextField( value = cardName, onValueChange = onCardNameChange, modifier = fieldModifier, label = { Text("Name") } ) Row( horizontalArrangement = Arrangement.spacedBy(8.dp) ) { OutlinedTextField( value = codeValue, onValueChange = oncodeValueChange, modifier = Modifier.weight(1f), label = { Text("Value") } ) Button( modifier = Modifier.align(Alignment.CenterVertically), onClick = { scanLauncher.launch( ScanOptions().apply { setPrompt("Scan your card") setBeepEnabled(true) setOrientationLocked(false) } ) } ) { Text("Scan") } } Box( modifier = fieldModifier, ) { OutlinedTextField( value = codeType.name, onValueChange = {}, modifier = fieldModifier, label = { Text("Code type") }, readOnly = true, ) Box( modifier = fieldModifier .matchParentSize() .clickable { isCodeTypeDropdownExpanded = !isCodeTypeDropdownExpanded } ) DropdownMenu( expanded = isCodeTypeDropdownExpanded, onDismissRequest = { isCodeTypeDropdownExpanded = false }, modifier = fieldModifier ) { BarcodeFormat.entries.forEach { format -> DropdownMenuItem( text = { Text(format.name) }, onClick = { onCodeTypeChange(format) isCodeTypeDropdownExpanded = false } ) } } } } @Composable fun AddCard(innerPadding: PaddingValues, getDbFun: () -> DbHelper) { var cardName by remember { mutableStateOf("") } var codeValue by remember { mutableStateOf("") } var codeType by remember { mutableStateOf(BarcodeFormat.QR_CODE) } val context = LocalContext.current as Activity Page( "New card", innerPadding ) { Column( verticalArrangement = Arrangement.spacedBy(8.dp) ) { CardEditable( cardName = cardName, onCardNameChange = { cardName = it }, codeValue = codeValue, oncodeValueChange = { codeValue = it }, codeType = codeType, onCodeTypeChange = { codeType = it } ) Button( modifier = Modifier.fillMaxWidth(), onClick = { val err = checkCardData(cardName, codeValue) if (err == null) { getDbFun().addCard(cardName, codeValue, codeType) context.finish() } else { Toast.makeText(context, err, Toast.LENGTH_SHORT).show()git } } ) { Text("Save") } } } } @Composable fun EditCard(cardInfo: CardInfo, innerPadding: PaddingValues, getDbFun: () -> DbHelper) { var cardName by remember { mutableStateOf(cardInfo.name) } var codeValue by remember { mutableStateOf(cardInfo.codeValue) } var codeType by remember { mutableStateOf(cardInfo.codeType) } val context = LocalContext.current as Activity Page( "Editing card id${cardInfo.id}", innerPadding ) { Column( verticalArrangement = Arrangement.spacedBy(8.dp) ) { CardEditable( cardName = cardName, onCardNameChange = { cardName = it }, codeValue = codeValue, oncodeValueChange = { codeValue = it }, codeType = codeType, onCodeTypeChange = { codeType = it } ) Button( modifier = Modifier.fillMaxWidth(), onClick = { val err = checkCardData(cardName, codeValue) if (err == null) { getDbFun().editCard(cardInfo.id, cardName, codeValue, codeType) context.finish() } else { Toast.makeText(context, err, Toast.LENGTH_SHORT).show() } } ) { Text("Save") } } } } @Composable fun EditCardPage(cardInfo: CardInfo?, innerPadding: PaddingValues, getDbFun: () -> DbHelper) { if (cardInfo == null) { AddCard(innerPadding, getDbFun) } else { EditCard(cardInfo, innerPadding, getDbFun) } }