feat: added QrScript support for templates

This commit is contained in:
2026-06-23 20:54:58 +03:00
parent d702928c28
commit e8b572bf9a
8 changed files with 70 additions and 8 deletions
@@ -2,7 +2,10 @@ package ru.omni_devel.cards
const val REPO_BASE_URL = "https://gitea.omni-devel.ru/omni/OmniCardsRepo/raw/branch/main"
const val TEMPLATES_REPO_FILE = "templates.json"
val TEMPLATES_REPO_FILE = if (BuildConfig.DEBUG)
"templates.debug.json"
else
"templates.json"
const val ICONS_REPO_FILE = "icons.json"
const val ICONS_REPO_FOLDER = "icons"
@@ -125,9 +125,11 @@ fun CardEditable(
contract = ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val codeValue = result.data?.getStringExtra("codeValue") ?: ""
val codeValue = result.data?.getStringExtra("codeValue")!!
val codeType = BarcodeFormat.valueOf(result.data?.getStringExtra("codeType")!!)
onCodeValueChange(codeValue)
onCodeTypeChange(codeType)
}
}
@@ -87,15 +87,18 @@ fun FillTemplatePage(template: Template, innerPadding: PaddingValues) {
return@AdaptiveButton
}
var result = template.template
val result = try {
processQrScript(template.template, filledFields)
} catch (e: Exception) {
Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show()
for ((id, value) in filledFields) {
result = result.replace("$$id$", value)
return@AdaptiveButton
}
val resultIntent = Intent()
resultIntent.putExtra("codeValue", result)
resultIntent.putExtra("codeType", template.codeType.name)
activityContext!!.setResult(Activity.RESULT_OK, resultIntent)
activityContext.finish()
@@ -84,10 +84,12 @@ fun SelectTemplatePage(innerPadding: PaddingValues) {
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val codeValue = result.data?.getStringExtra("codeValue")
val codeTypeString = result.data?.getStringExtra("codeType")
val resultIntent = Intent()
resultIntent.putExtra("codeValue", codeValue)
resultIntent.putExtra("codeType", codeTypeString)
activityContext!!.setResult(Activity.RESULT_OK, resultIntent)
activityContext.finish()
@@ -1,5 +1,6 @@
package ru.omni_devel.cards
import com.google.zxing.BarcodeFormat
import kotlinx.serialization.Serializable
import org.json.JSONArray
import org.json.JSONObject
@@ -16,7 +17,8 @@ class Field(
class Template(
val names: LinkedHashMap<String, String>,
val fields: List<Field>,
val template: String
val template: String,
val codeType: BarcodeFormat = BarcodeFormat.QR_CODE
) {
companion object {
fun parseTemplateFromJson(json: String): Template {
@@ -39,7 +41,8 @@ class Template(
return Template(
names = jsonObjectToMap(obj.getJSONObject("names")),
fields = fields,
template = obj.getString("template")
template = obj.getString("template"),
codeType = parseCodeType(obj)
)
}
@@ -67,11 +70,21 @@ class Template(
templates.add(Template(
names = jsonObjectToMap(obj.getJSONObject("names")),
fields = fields,
template = obj.getString("template")
template = obj.getString("template"),
codeType = parseCodeType(obj)
))
}
return templates
}
private fun parseCodeType(obj: JSONObject): BarcodeFormat {
val raw = obj.optString("codeType", "")
return if (raw.isBlank()) {
BarcodeFormat.QR_CODE
} else {
BarcodeFormat.valueOf(raw)
}
}
}
}
@@ -121,3 +121,41 @@ fun base64ToImageBitmap(base64String: String): ImageBitmap {
return bitmap.asImageBitmap()
}
fun processQrScript(input: String, fills: Map<String, String>): String {
val outerRegex = Regex("""\$(\w+)((?:\([^)]*\))*)\$""")
val innerRegex = Regex("""\(([^)]*)\)""")
var result = input
outerRegex.findAll(input).forEach { match ->
val fullBlock = match.value
val name = match.groupValues[1]
val contents = innerRegex.findAll(match.groupValues[2]).map { it.groupValues[1] }.toList()
var blockResult = fills[name] ?: return@forEach
contents.forEach { content ->
val args = content.split(" ")
val action = args[0]
when (action) {
"first" -> {
val count = args[1].toInt()
blockResult = blockResult.take(count)
}
"last" -> {
val count = args[1].toInt()
blockResult = blockResult.takeLast(count)
}
}
}
result = result.replace(fullBlock, blockResult)
}
return result
}