diff --git a/mobile/src/main/java/ru/omni_devel/cards/Elements.kt b/mobile/src/main/java/ru/omni_devel/cards/Elements.kt index e2baa2e..483aaa2 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/Elements.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/Elements.kt @@ -50,7 +50,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap -import androidx.compose.ui.graphics.Shape import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource diff --git a/wear/build.gradle.kts b/wear/build.gradle.kts index 9ef4211..c555e0b 100644 --- a/wear/build.gradle.kts +++ b/wear/build.gradle.kts @@ -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") } \ No newline at end of file diff --git a/wear/src/main/java/ru/omni_devel/cards/presentation/CardInfo.kt b/wear/src/main/java/ru/omni_devel/cards/presentation/CardInfo.kt index f60bd50..29ea05a 100644 --- a/wear/src/main/java/ru/omni_devel/cards/presentation/CardInfo.kt +++ b/wear/src/main/java/ru/omni_devel/cards/presentation/CardInfo.kt @@ -9,5 +9,6 @@ class CardInfo ( val name: String, val codeType: BarcodeFormat, val codeValue: String, - val color: String? + val color: String?, + val icon: String? ) \ No newline at end of file diff --git a/wear/src/main/java/ru/omni_devel/cards/presentation/DbHelper.kt b/wear/src/main/java/ru/omni_devel/cards/presentation/DbHelper.kt index 6aa41c5..d68b06e 100644 --- a/wear/src/main/java/ru/omni_devel/cards/presentation/DbHelper.kt +++ b/wear/src/main/java/ru/omni_devel/cards/presentation/DbHelper.kt @@ -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() diff --git a/wear/src/main/java/ru/omni_devel/cards/presentation/Elements.kt b/wear/src/main/java/ru/omni_devel/cards/presentation/Elements.kt index aa80edc..68c5094 100644 --- a/wear/src/main/java/ru/omni_devel/cards/presentation/Elements.kt +++ b/wear/src/main/java/ru/omni_devel/cards/presentation/Elements.kt @@ -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 ) } } } -} \ No newline at end of file +} + +@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) + ) + } + } +} diff --git a/wear/src/main/java/ru/omni_devel/cards/presentation/Utils.kt b/wear/src/main/java/ru/omni_devel/cards/presentation/Utils.kt index 3eace92..c4246df 100644 --- a/wear/src/main/java/ru/omni_devel/cards/presentation/Utils.kt +++ b/wear/src/main/java/ru/omni_devel/cards/presentation/Utils.kt @@ -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() +}