feat: added icons support for WearOS

This commit is contained in:
2026-06-23 11:09:55 +03:00
parent bb57ab007c
commit 3cf6b876f9
6 changed files with 88 additions and 20 deletions
+1
View File
@@ -71,4 +71,5 @@ dependencies {
implementation(libs.zxing.android)
implementation(libs.material)
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
implementation("androidx.compose.material:material-icons-extended")
}
@@ -9,5 +9,6 @@ class CardInfo (
val name: String,
val codeType: BarcodeFormat,
val codeValue: String,
val color: String?
val color: String?,
val icon: String?
)
@@ -4,11 +4,14 @@ import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import androidx.core.database.getStringOrNull
import com.google.zxing.BarcodeFormat
class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?) : SQLiteOpenHelper(context, "omni_cards", factory, 4) {
class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?) : SQLiteOpenHelper(context, "omni_cards", factory, 5) {
override fun onCreate(db: SQLiteDatabase?) {
db!!.execSQL("CREATE TABLE IF NOT EXISTS cards (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, codeType TEXT, codeValue TEXT, color TEXT)")
db!!.execSQL(
"CREATE TABLE IF NOT EXISTS cards (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, codeType TEXT, codeValue TEXT, color TEXT, icon TEXT)"
)
}
override fun onUpgrade(
@@ -30,6 +33,10 @@ class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?)
db!!.execSQL("ALTER TABLE cards DROP COLUMN position")
db.execSQL("ALTER TABLE cards DROP COLUMN iconPath")
}
if (oldVersion < 5) {
db!!.execSQL("ALTER TABLE cards ADD COLUMN icon TEXT")
}
}
fun clearDatabase() {
@@ -51,6 +58,7 @@ class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?)
values.put("codeValue", card.codeValue)
values.put("codeType", card.codeType.name)
values.put("color", card.color)
values.put("icon", card.icon)
db.insert("cards", null, values)
}
@@ -70,7 +78,8 @@ class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?)
name = cursor.getString(cursor.getColumnIndexOrThrow("name")),
codeType = BarcodeFormat.valueOf(cursor.getString(cursor.getColumnIndexOrThrow("codeType"))),
codeValue = cursor.getString(cursor.getColumnIndexOrThrow("codeValue")),
color = cursor.getString(cursor.getColumnIndexOrThrow("color"))
color = cursor.getString(cursor.getColumnIndexOrThrow("color")),
icon = cursor.getStringOrNull(cursor.getColumnIndexOrThrow("icon"))
))
}
@@ -97,7 +106,8 @@ class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?)
name = cursor.getString(cursor.getColumnIndexOrThrow("name")),
codeType = BarcodeFormat.valueOf(cursor.getString(cursor.getColumnIndexOrThrow("codeType"))),
codeValue = cursor.getString(cursor.getColumnIndexOrThrow("codeValue")),
color = cursor.getString(cursor.getColumnIndexOrThrow("color"))
color = cursor.getString(cursor.getColumnIndexOrThrow("color")),
icon = cursor.getStringOrNull(cursor.getColumnIndexOrThrow("icon"))
)
cursor.close()
@@ -1,20 +1,25 @@
package ru.omni_devel.cards.presentation
import android.content.Intent
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.QrCode
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@@ -22,6 +27,7 @@ import androidx.compose.ui.unit.sp
import androidx.core.graphics.toColorInt
import androidx.wear.compose.material3.Button
import androidx.wear.compose.material3.ButtonDefaults
import androidx.wear.compose.material3.Icon
import androidx.wear.compose.material3.MaterialTheme
import androidx.wear.compose.material3.Text
@@ -29,12 +35,18 @@ import androidx.wear.compose.material3.Text
fun CardButton(cardInfo: CardInfo) {
val context = LocalContext.current
val cardColor = if (cardInfo.color == null)
MaterialTheme.colorScheme.primaryContainer
else
Color(cardInfo.color.toColorInt())
Box(modifier = Modifier.fillMaxWidth()) {
Button(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier.fillMaxWidth().height(64.dp),
colors = ButtonDefaults.buttonColors(
containerColor = (if (cardInfo.color == null) MaterialTheme.colorScheme.primaryContainer else Color(cardInfo.color.toColorInt())).copy(0.425f)
containerColor = cardColor.copy(0.425f)
),
shape = RoundedCornerShape(12.dp),
contentPadding = PaddingValues(0.dp),
onClick = {
val intent = Intent(context, ShowCardActivity::class.java)
@@ -46,21 +58,55 @@ fun CardButton(cardInfo: CardInfo) {
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(IntrinsicSize.Min)
.clip(ButtonDefaults.shape)
.fillMaxSize()
.background(Color.Transparent)
.padding(horizontal = 8.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
CardIcon(
if (cardInfo.icon == null) null else base64ToImageBitmap(cardInfo.icon),
cardColor = cardColor
)
Text(
cardInfo.name,
fontSize = 16.sp,
color = MaterialTheme.colorScheme.onPrimaryContainer,
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
.weight(1f),
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Start
)
}
}
}
}
}
@Composable
fun CardIcon(icon: ImageBitmap?, cardColor: Color) {
Row(
modifier = Modifier
.background(
cardColor.copy(0.525f),
RoundedCornerShape(12.dp)
)
.padding(8.dp)
.size(32.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
if (icon == null) {
Icon(
modifier = Modifier.size(24.dp),
imageVector = Icons.Outlined.QrCode,
tint = MaterialTheme.colorScheme.onPrimaryContainer,
contentDescription = null
)
} else {
Image(
bitmap = icon,
contentDescription = null,
modifier = Modifier.size(32.dp)
)
}
}
}
@@ -1,6 +1,10 @@
package ru.omni_devel.cards.presentation
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Base64
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import com.google.zxing.BarcodeFormat
import com.google.zxing.MultiFormatWriter
import com.journeyapps.barcodescanner.BarcodeEncoder
@@ -11,3 +15,10 @@ fun generateCode(value: String, format: BarcodeFormat, width: Int, height: Int):
return BarcodeEncoder().createBitmap(matrix)
}
fun base64ToImageBitmap(base64String: String): ImageBitmap {
val decodedBytes = Base64.decode(base64String, Base64.DEFAULT)
val bitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size)
return bitmap.asImageBitmap()
}