feat: added icons support for WearOS
This commit is contained in:
@@ -50,7 +50,6 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import androidx.compose.ui.graphics.Shape
|
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
|||||||
@@ -71,4 +71,5 @@ dependencies {
|
|||||||
implementation(libs.zxing.android)
|
implementation(libs.zxing.android)
|
||||||
implementation(libs.material)
|
implementation(libs.material)
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
|
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 name: String,
|
||||||
val codeType: BarcodeFormat,
|
val codeType: BarcodeFormat,
|
||||||
val codeValue: String,
|
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.content.Context
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import android.database.sqlite.SQLiteDatabase
|
||||||
import android.database.sqlite.SQLiteOpenHelper
|
import android.database.sqlite.SQLiteOpenHelper
|
||||||
|
import androidx.core.database.getStringOrNull
|
||||||
import com.google.zxing.BarcodeFormat
|
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?) {
|
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(
|
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 position")
|
||||||
db.execSQL("ALTER TABLE cards DROP COLUMN iconPath")
|
db.execSQL("ALTER TABLE cards DROP COLUMN iconPath")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldVersion < 5) {
|
||||||
|
db!!.execSQL("ALTER TABLE cards ADD COLUMN icon TEXT")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearDatabase() {
|
fun clearDatabase() {
|
||||||
@@ -51,6 +58,7 @@ class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?)
|
|||||||
values.put("codeValue", card.codeValue)
|
values.put("codeValue", card.codeValue)
|
||||||
values.put("codeType", card.codeType.name)
|
values.put("codeType", card.codeType.name)
|
||||||
values.put("color", card.color)
|
values.put("color", card.color)
|
||||||
|
values.put("icon", card.icon)
|
||||||
|
|
||||||
db.insert("cards", null, values)
|
db.insert("cards", null, values)
|
||||||
}
|
}
|
||||||
@@ -70,7 +78,8 @@ class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?)
|
|||||||
name = cursor.getString(cursor.getColumnIndexOrThrow("name")),
|
name = cursor.getString(cursor.getColumnIndexOrThrow("name")),
|
||||||
codeType = BarcodeFormat.valueOf(cursor.getString(cursor.getColumnIndexOrThrow("codeType"))),
|
codeType = BarcodeFormat.valueOf(cursor.getString(cursor.getColumnIndexOrThrow("codeType"))),
|
||||||
codeValue = cursor.getString(cursor.getColumnIndexOrThrow("codeValue")),
|
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")),
|
name = cursor.getString(cursor.getColumnIndexOrThrow("name")),
|
||||||
codeType = BarcodeFormat.valueOf(cursor.getString(cursor.getColumnIndexOrThrow("codeType"))),
|
codeType = BarcodeFormat.valueOf(cursor.getString(cursor.getColumnIndexOrThrow("codeType"))),
|
||||||
codeValue = cursor.getString(cursor.getColumnIndexOrThrow("codeValue")),
|
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()
|
cursor.close()
|
||||||
|
|||||||
@@ -1,20 +1,25 @@
|
|||||||
package ru.omni_devel.cards.presentation
|
package ru.omni_devel.cards.presentation
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.IntrinsicSize
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
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.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
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.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -22,6 +27,7 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.core.graphics.toColorInt
|
import androidx.core.graphics.toColorInt
|
||||||
import androidx.wear.compose.material3.Button
|
import androidx.wear.compose.material3.Button
|
||||||
import androidx.wear.compose.material3.ButtonDefaults
|
import androidx.wear.compose.material3.ButtonDefaults
|
||||||
|
import androidx.wear.compose.material3.Icon
|
||||||
import androidx.wear.compose.material3.MaterialTheme
|
import androidx.wear.compose.material3.MaterialTheme
|
||||||
import androidx.wear.compose.material3.Text
|
import androidx.wear.compose.material3.Text
|
||||||
|
|
||||||
@@ -29,12 +35,18 @@ import androidx.wear.compose.material3.Text
|
|||||||
fun CardButton(cardInfo: CardInfo) {
|
fun CardButton(cardInfo: CardInfo) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
val cardColor = if (cardInfo.color == null)
|
||||||
|
MaterialTheme.colorScheme.primaryContainer
|
||||||
|
else
|
||||||
|
Color(cardInfo.color.toColorInt())
|
||||||
|
|
||||||
Box(modifier = Modifier.fillMaxWidth()) {
|
Box(modifier = Modifier.fillMaxWidth()) {
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth().height(64.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
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),
|
contentPadding = PaddingValues(0.dp),
|
||||||
onClick = {
|
onClick = {
|
||||||
val intent = Intent(context, ShowCardActivity::class.java)
|
val intent = Intent(context, ShowCardActivity::class.java)
|
||||||
@@ -46,21 +58,55 @@ fun CardButton(cardInfo: CardInfo) {
|
|||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxSize()
|
||||||
.height(IntrinsicSize.Min)
|
.background(Color.Transparent)
|
||||||
.clip(ButtonDefaults.shape)
|
.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(
|
Text(
|
||||||
cardInfo.name,
|
cardInfo.name,
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
color = MaterialTheme.colorScheme.onPrimaryContainer,
|
color = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||||
modifier = Modifier
|
modifier = Modifier.fillMaxWidth(),
|
||||||
.padding(16.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.weight(1f),
|
|
||||||
textAlign = TextAlign.Start
|
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
|
package ru.omni_devel.cards.presentation
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
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.BarcodeFormat
|
||||||
import com.google.zxing.MultiFormatWriter
|
import com.google.zxing.MultiFormatWriter
|
||||||
import com.journeyapps.barcodescanner.BarcodeEncoder
|
import com.journeyapps.barcodescanner.BarcodeEncoder
|
||||||
@@ -11,3 +15,10 @@ fun generateCode(value: String, format: BarcodeFormat, width: Int, height: Int):
|
|||||||
|
|
||||||
return BarcodeEncoder().createBitmap(matrix)
|
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()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user