forked from omni/OmniCards
feat: added QrScript support for templates
This commit is contained in:
@@ -47,6 +47,7 @@ android {
|
||||
buildFeatures {
|
||||
compose = true
|
||||
viewBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user