restore: restored older version

This commit is contained in:
2026-06-21 12:27:54 +03:00
parent 123af530ed
commit 1272e87ccd
9 changed files with 148 additions and 177 deletions
+2 -1
View File
@@ -23,7 +23,7 @@ android {
minSdk = 30 minSdk = 30
targetSdk = 36 targetSdk = 36
versionCode = generateVersionCode() versionCode = generateVersionCode()
versionName = "2.5.1" versionName = "4.0.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -77,4 +77,5 @@ dependencies {
implementation("com.google.android.gms:play-services-wearable:18.1.0") implementation("com.google.android.gms:play-services-wearable:18.1.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
implementation(libs.compose.colorpicker) implementation(libs.compose.colorpicker)
implementation("org.burnoutcrew.composereorderable:reorderable:0.9.6")
} }
Binary file not shown.
Binary file not shown.
@@ -14,5 +14,5 @@ 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?
) {} ) {}
@@ -6,9 +6,9 @@ import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper import android.database.sqlite.SQLiteOpenHelper
import com.google.zxing.BarcodeFormat import com.google.zxing.BarcodeFormat
class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?) : SQLiteOpenHelper(context, "omni_cards", factory, 2) { 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, position INTEGER DEFAULT 0)")
} }
override fun onUpgrade( override fun onUpgrade(
@@ -19,9 +19,27 @@ class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?)
if (oldVersion < 2) { if (oldVersion < 2) {
db!!.execSQL("ALTER TABLE cards ADD COLUMN color TEXT") db!!.execSQL("ALTER TABLE cards ADD COLUMN color TEXT")
} }
if (oldVersion < 3) {
db!!.execSQL("ALTER TABLE cards ADD COLUMN position INTEGER DEFAULT 0")
db.execSQL("ALTER TABLE cards ADD COLUMN iconPath TEXT")
db.execSQL("UPDATE cards SET position = id")
}
if (oldVersion < 4) {
db!!.execSQL("ALTER TABLE cards ADD COLUMN monochrome INTEGER DEFAULT 0")
}
if (oldVersion < 5) {
db!!.execSQL("ALTER TABLE cards DROP COLUMN iconPath")
db.execSQL("ALTER TABLE cards DROP COLUMN monochrome")
db.execSQL("ALTER TABLE cards DROP COLUMN position")
}
} }
fun addCard(name: String, codeValue: String, codeType: BarcodeFormat, color: String?) { fun addCard(name: String, codeValue: String, codeType: BarcodeFormat, color: String?) {
val db = this.writableDatabase
val values = ContentValues() val values = ContentValues()
values.put("name", name) values.put("name", name)
@@ -29,8 +47,6 @@ class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?)
values.put("codeType", codeType.name) values.put("codeType", codeType.name)
values.put("color", color) values.put("color", color)
val db = this.writableDatabase
db.insert("cards", null, values) db.insert("cards", null, values)
db.close() db.close()
@@ -54,7 +70,7 @@ class DbHelper(val context: Context, val factory: SQLiteDatabase.CursorFactory?)
fun getCards(): List<CardInfo> { fun getCards(): List<CardInfo> {
val db = this.readableDatabase val db = this.readableDatabase
val cursor = db.rawQuery("SELECT * FROM cards", null) val cursor = db.rawQuery("SELECT * FROM cards ORDER BY id ASC", null)
val cards = mutableListOf<CardInfo>() val cards = mutableListOf<CardInfo>()
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
@@ -1,7 +1,10 @@
package ru.omni_devel.cards package ru.omni_devel.cards
import android.content.Intent import android.content.Intent
import androidx.activity.compose.BackHandler
import androidx.activity.compose.LocalActivity
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@@ -15,19 +18,28 @@ 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.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
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
@@ -36,36 +48,103 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.core.graphics.toColorInt import androidx.core.graphics.toColorInt
import kotlinx.coroutines.launch
@Composable @Composable
fun Page(name: String, innerPadding: PaddingValues, content: @Composable () -> Unit) { fun Page(name: String, innerPadding: PaddingValues, pages: List<NavigationPageData>? = null, content: @Composable () -> Unit) {
Column() { val activityContext = LocalActivity.current
TopBar(name, innerPadding)
Column( val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
modifier = Modifier val scope = rememberCoroutineScope()
.fillMaxSize()
.padding(horizontal = 16.dp) BackHandler(
.background(MaterialTheme.colorScheme.background) enabled = pages != null && drawerState.isOpen
) { ) {
scope.launch {
drawerState.close()
}
}
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
if (pages != null) {
ModalDrawerSheet(
modifier = Modifier.background(MaterialTheme.colorScheme.background).padding(8.dp)
) {
for (page in pages) {
NavigationDrawerItem(
label = { Text(page.name) },
selected = false,
onClick = {
scope.launch { drawerState.close() }
if (page.pageClass != null) {
val intent = Intent(activityContext, page.pageClass)
activityContext!!.startActivity(intent)
} else if (page.onClick != null) {
page.onClick()
}
}
)
}
}
}
}
) {
Scaffold(
topBar = {
TopBar(name, innerPadding, if (pages != null) {
{
Text(
"",
fontSize = 24.sp,
color = MaterialTheme.colorScheme.onPrimaryContainer,
modifier = Modifier.clickable() {
scope.launch {
drawerState.open()
}
}
)
}
} else null)
}
) { padding ->
Box(
modifier = Modifier
.padding(padding)
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.padding(horizontal = 16.dp)
.padding(top = 16.dp)
) {
Column() {
content() content()
} }
} }
} }
}
}
@Composable @Composable
fun TopBar(text: String, innerPadding: PaddingValues) { fun TopBar(text: String, innerPadding: PaddingValues, openMenuButton: (@Composable () -> Unit)? = null) {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background(MaterialTheme.colorScheme.primaryContainer) .background(MaterialTheme.colorScheme.primaryContainer)
.padding(top = innerPadding.calculateTopPadding()) .padding(top = innerPadding.calculateTopPadding())
.padding(horizontal = 8.dp) .padding(vertical = 12.dp, horizontal = 12.dp),
.padding(bottom = 8.dp) verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
if (openMenuButton != null) {
openMenuButton()
}
Text( Text(
text, text,
modifier = Modifier.padding(vertical = 4.dp, horizontal = 12.dp), modifier = Modifier,
fontSize = 24.sp, fontSize = 24.sp,
color = MaterialTheme.colorScheme.onPrimaryContainer color = MaterialTheme.colorScheme.onPrimaryContainer
) )
@@ -93,7 +172,7 @@ fun CardButton(cardInfo: CardInfo, onDeleteCard: (Int) -> Unit) {
} }
) )
}, },
shape = ButtonDefaults.shape, shape = RoundedCornerShape(12.dp),
color = MaterialTheme.colorScheme.primaryContainer, color = MaterialTheme.colorScheme.primaryContainer,
tonalElevation = 2.dp tonalElevation = 2.dp
) { ) {
@@ -1,52 +1,29 @@
package ru.omni_devel.cards package ru.omni_devel.cards
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import ru.omni_devel.cards.ui.theme.OmniCardsTheme import ru.omni_devel.cards.ui.theme.OmniCardsTheme
@@ -96,25 +73,34 @@ fun MainPage(
) { ) {
val context = LocalContext.current val context = LocalContext.current
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
val scope = rememberCoroutineScope()
var isActionBarShowed by remember { mutableStateOf(false) }
Box( Box(
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()
) { ) {
BackHandler(
enabled = isActionBarShowed,
) {
isActionBarShowed = false
}
Page( Page(
stringResource(R.string.app_name), stringResource(R.string.app_name),
innerPadding innerPadding,
pages = listOf(
NavigationPageData(stringResource(R.string.do_add_card), EditCardActivity::class.java),
NavigationPageData(stringResource(R.string.do_sync)) {
Toast.makeText(context, context.getString(R.string.sync_in_progress), Toast.LENGTH_SHORT).show()
sendToWatch(context, "/updateCards", Json.encodeToString(getDbFun().getCards())) { isSuccess ->
if (isSuccess) {
Toast.makeText(context, context.getString(R.string.sync_is_successful), Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, context.getString(R.string.sync_is_fail), Toast.LENGTH_LONG).show()
}
}
},
NavigationPageData(stringResource(R.string.open_backup_menu), BackupActivity::class.java),
NavigationPageData(stringResource(R.string.source_code)) {
uriHandler.openUri("https://github.com/omni-devel/OmniCards")
},
)
) { ) {
Column( Column(
modifier = Modifier.verticalScroll(rememberScrollState()).padding(bottom = 64.dp).background(Color.Transparent).padding(top = 16.dp), modifier = Modifier.verticalScroll(rememberScrollState()).padding(bottom = 64.dp).background(Color.Transparent),
verticalArrangement = Arrangement.spacedBy(8.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
if (cards.isEmpty()) { if (cards.isEmpty()) {
@@ -128,125 +114,5 @@ fun MainPage(
} }
} }
} }
if (isActionBarShowed) {
Box(
modifier = Modifier
.fillMaxSize()
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null
) {
isActionBarShowed = false
}
) { }
}
AnimatedVisibility(
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(innerPadding)
.padding(16.dp),
visible = isActionBarShowed,
enter = slideInVertically(initialOffsetY = { it }) + fadeIn(),
exit = slideOutVertically(targetOffsetY = { it }) + fadeOut()
) {
Column(
modifier = Modifier
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null
) {}
.background(
MaterialTheme.colorScheme.inversePrimary,
RoundedCornerShape(24.dp)
)
.padding(16.dp)
.fillMaxWidth()
) {
FullWidthButton(
onClick = {
isActionBarShowed = false
scope.launch {
delay(ANIMATION_DELAY)
val intent = Intent(context, EditCardActivity::class.java)
context.startActivity(intent)
}
}
) {
Text(stringResource(R.string.do_add_card))
}
FullWidthButton(
onClick = {
Toast.makeText(context, context.getString(R.string.sync_in_progress), Toast.LENGTH_SHORT).show()
sendToWatch(context, "/updateCards", Json.encodeToString(getDbFun().getCards())) { isSuccess ->
if (isSuccess) {
Toast.makeText(context, context.getString(R.string.sync_is_successful), Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, context.getString(R.string.sync_is_fail), Toast.LENGTH_LONG).show()
}
}
isActionBarShowed = false
}
) {
Text(stringResource(R.string.do_sync))
}
FullWidthButton(
onClick = {
isActionBarShowed = false
scope.launch {
delay(ANIMATION_DELAY)
val intent = Intent(context, BackupActivity::class.java)
context.startActivity(intent)
}
}
) {
Text(stringResource(R.string.open_backup_menu))
}
FullWidthButton(
onClick = {
uriHandler.openUri("https://github.com/omni-devel/OmniCards")
isActionBarShowed = false
}
) {
Text(stringResource(R.string.source_code))
}
FullWidthButton(
onClick = {
isActionBarShowed = false
}
) {
Text(">")
}
}
}
AnimatedVisibility(
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(innerPadding)
.padding(32.dp),
visible = !isActionBarShowed,
enter = fadeIn() + scaleIn(),
exit = fadeOut() + scaleOut()
){
Button(
modifier = Modifier,
onClick = {
isActionBarShowed = true
}
) {
Text("<")
}
}
} }
} }
@@ -0,0 +1,9 @@
package ru.omni_devel.cards
import android.app.Activity
data class NavigationPageData(
val name: String,
val pageClass: Class<out Activity>? = null,
val onClick: (() -> Unit)? = null
)
+1 -1
View File
@@ -23,7 +23,7 @@ android {
minSdk = 30 minSdk = 30
targetSdk = 36 targetSdk = 36
versionCode = generateVersionCode() versionCode = generateVersionCode()
versionName = "1.4.0" versionName = "3.0.0"
} }
buildTypes { buildTypes {