Compare commits

...
3 Commits
Author SHA1 Message Date
omni 36abc10972 feat: added russian translations 2026-06-15 17:18:36 +03:00
omni 5cf7e2b7b2 feat: added automatic generation for versionCode 2026-06-15 15:18:31 +03:00
omni 6f9490ea1c fix: fixed top bar paddings 2026-06-15 15:14:12 +03:00
15 changed files with 159 additions and 98 deletions
+12 -2
View File
@@ -4,6 +4,16 @@ plugins {
alias(libs.plugins.kotlin.serialization) alias(libs.plugins.kotlin.serialization)
} }
fun generateVersionCode(): Int {
return try {
val process = ProcessBuilder("git", "rev-list", "--count", "HEAD").start()
"${process.inputStream.bufferedReader().readText().trim()}0".toInt() // 0 at end for mobile
} catch (e: Exception) {
1
}
}
android { android {
namespace = "ru.omni_devel.cards" namespace = "ru.omni_devel.cards"
compileSdk = 36 compileSdk = 36
@@ -12,8 +22,8 @@ android {
applicationId = "ru.omni_devel.cards" applicationId = "ru.omni_devel.cards"
minSdk = 30 minSdk = 30
targetSdk = 36 targetSdk = 36
versionCode = 70 // 0 at end for mobile versionCode = generateVersionCode()
versionName = "2.3.0" versionName = "2.3.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
Binary file not shown.
Binary file not shown.
-9
View File
@@ -11,27 +11,18 @@
<activity <activity
android:name=".BackupActivity" android:name=".BackupActivity"
android:exported="false" android:exported="false"
android:label="@string/title_activity_backup"
android:theme="@style/Theme.OmniCards" /> android:theme="@style/Theme.OmniCards" />
<activity <activity
android:name=".EditCardActivity" android:name=".EditCardActivity"
android:exported="false" android:exported="false"
android:label="@string/title_activity_edit_card"
android:theme="@style/Theme.OmniCards" />
<activity
android:name=".AddCardActivity"
android:exported="false"
android:label="@string/title_activity_add_card"
android:theme="@style/Theme.OmniCards" /> android:theme="@style/Theme.OmniCards" />
<activity <activity
android:name=".ShowCardActivity" android:name=".ShowCardActivity"
android:exported="false" android:exported="false"
android:label="@string/title_activity_show_card"
android:theme="@style/Theme.OmniCards" /> android:theme="@style/Theme.OmniCards" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.OmniCards"> android:theme="@style/Theme.OmniCards">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -24,7 +24,7 @@ import kotlinx.serialization.json.Json
import ru.omni_devel.cards.ui.theme.OmniCardsTheme import ru.omni_devel.cards.ui.theme.OmniCardsTheme
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import kotlinx.serialization.decodeFromString import androidx.compose.ui.res.stringResource
class BackupActivity : ComponentActivity() { class BackupActivity : ComponentActivity() {
private lateinit var db: DbHelper private lateinit var db: DbHelper
@@ -65,12 +65,12 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) {
context.contentResolver.openOutputStream(it)?.use { outputStream -> context.contentResolver.openOutputStream(it)?.use { outputStream ->
outputStream.write(jsonData.toByteArray()) outputStream.write(jsonData.toByteArray())
Toast.makeText(context, "Backup successfully saved", Toast.LENGTH_SHORT).show() Toast.makeText(context, context.getString(R.string.backup_successfully_saved), Toast.LENGTH_SHORT).show()
activityContext!!.finish() activityContext!!.finish()
} }
} catch (e: Exception) { } catch (e: Exception) {
Toast.makeText(context, "Failed to save backup: $e", Toast.LENGTH_LONG).show() Toast.makeText(context, context.getString(R.string.failed_to_save_backup, e), Toast.LENGTH_LONG).show()
} }
} }
} }
@@ -86,8 +86,8 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) {
if (showImportDialog.value) { if (showImportDialog.value) {
AlertDialog( AlertDialog(
title = { Text("Restore backup") }, title = { Text(stringResource(R.string.ask_do_restore)) },
text = { Text("This will replace existing cards by data from backup file. Continue?") }, text = { Text(stringResource(R.string.restore_caution)) },
confirmButton = { confirmButton = {
TextButton( TextButton(
onClick = { onClick = {
@@ -105,17 +105,17 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) {
db.clearDatabase() db.clearDatabase()
db.addCards(cards) db.addCards(cards)
Toast.makeText(context, "Data successfully restored from backup", Toast.LENGTH_SHORT).show() Toast.makeText(context, context.getString(R.string.backup_successfully_restored), Toast.LENGTH_SHORT).show()
activityContext!!.finish() activityContext!!.finish()
} }
} catch (e: Exception) { } catch (e: Exception) {
Toast.makeText(context, "Failed to restore data from backup: $e", Toast.LENGTH_LONG).show() Toast.makeText(context, context.getString(R.string.failed_to_restore_backup, e), Toast.LENGTH_LONG).show()
} }
} }
} }
) { ) {
Text("Yes") Text(stringResource(R.string.yes))
} }
}, },
dismissButton = { dismissButton = {
@@ -124,7 +124,7 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) {
showImportDialog.value = false showImportDialog.value = false
} }
) { ) {
Text("No") Text(stringResource(R.string.no))
} }
}, },
onDismissRequest = { showImportDialog.value = false }, onDismissRequest = { showImportDialog.value = false },
@@ -137,14 +137,14 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) {
createBackupLauncher.launch("omnicards-backup.json") createBackupLauncher.launch("omnicards-backup.json")
} }
) { ) {
Text("Backup to file") Text(stringResource(R.string.do_backup))
} }
FullWidthButton( FullWidthButton(
onClick = { onClick = {
restoreFromBackupLauncher.launch("application/json") restoreFromBackupLauncher.launch("application/json")
} }
) { ) {
Text("Restore from file") Text(stringResource(R.string.do_restore))
} }
} }
} }
@@ -34,6 +34,8 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.graphics.toColorInt import androidx.core.graphics.toColorInt
import com.github.skydoves.colorpicker.compose.ColorEnvelope import com.github.skydoves.colorpicker.compose.ColorEnvelope
@@ -79,6 +81,8 @@ fun CardEditable(
color: String?, color: String?,
onColorChange: (String?) -> Unit onColorChange: (String?) -> Unit
) { ) {
val context = LocalContext.current
var isCodeTypeDropdownExpanded by rememberSaveable { mutableStateOf(false) } var isCodeTypeDropdownExpanded by rememberSaveable { mutableStateOf(false) }
var isColorPickerExpanded by rememberSaveable { mutableStateOf(false) } var isColorPickerExpanded by rememberSaveable { mutableStateOf(false) }
var isColorEnabled by rememberSaveable { mutableStateOf(color != null) } var isColorEnabled by rememberSaveable { mutableStateOf(color != null) }
@@ -105,7 +109,7 @@ fun CardEditable(
value = cardName, value = cardName,
onValueChange = onCardNameChange, onValueChange = onCardNameChange,
modifier = fieldModifier, modifier = fieldModifier,
label = { Text("Name") } label = { Text(stringResource(R.string.card_name)) }
) )
Row( Row(
horizontalArrangement = Arrangement.spacedBy(8.dp) horizontalArrangement = Arrangement.spacedBy(8.dp)
@@ -114,21 +118,21 @@ fun CardEditable(
value = codeValue, value = codeValue,
onValueChange = onCodeValueChange, onValueChange = onCodeValueChange,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
label = { Text("Value") } label = { Text(stringResource(R.string.card_value)) }
) )
Button( Button(
modifier = Modifier.align(Alignment.CenterVertically), modifier = Modifier.align(Alignment.CenterVertically),
onClick = { onClick = {
scanLauncher.launch( scanLauncher.launch(
ScanOptions().apply { ScanOptions().apply {
setPrompt("Scan your card") setPrompt(context.getString(R.string.scan_your_card))
setBeepEnabled(true) setBeepEnabled(true)
setOrientationLocked(false) setOrientationLocked(false)
} }
) )
} }
) { ) {
Text("Scan") Text(stringResource(R.string.do_scan_card))
} }
} }
@@ -139,7 +143,7 @@ fun CardEditable(
value = codeType.name, value = codeType.name,
onValueChange = {}, onValueChange = {},
modifier = fieldModifier, modifier = fieldModifier,
label = { Text("Code type") }, label = { Text(stringResource(R.string.card_code_type)) },
readOnly = true, readOnly = true,
) )
Box( Box(
@@ -176,7 +180,7 @@ fun CardEditable(
isColorPickerExpanded = !isColorPickerExpanded isColorPickerExpanded = !isColorPickerExpanded
} }
) { ) {
Text("Choose color") Text(stringResource(R.string.do_choose_color))
} }
Switch( Switch(
checked = isColorEnabled, checked = isColorEnabled,
@@ -215,7 +219,7 @@ fun AddCard(innerPadding: PaddingValues, getDbFun: () -> DbHelper) {
val context = LocalActivity.current val context = LocalActivity.current
Page( Page(
"New card", stringResource(R.string.new_card_title),
innerPadding innerPadding
) { ) {
Column( Column(
@@ -244,11 +248,11 @@ fun AddCard(innerPadding: PaddingValues, getDbFun: () -> DbHelper) {
getDbFun().addCard(cardName, codeValue, codeType, color) getDbFun().addCard(cardName, codeValue, codeType, color)
context!!.finish() context!!.finish()
} else { } else {
Toast.makeText(context, err, Toast.LENGTH_SHORT).show() Toast.makeText(context, context!!.getString(err), Toast.LENGTH_SHORT).show()
} }
} }
) { ) {
Text("Save") Text(stringResource(R.string.do_save))
} }
} }
} }
@@ -264,7 +268,7 @@ fun EditCard(cardInfo: CardInfo, innerPadding: PaddingValues, getDbFun: () -> Db
val context = LocalActivity.current val context = LocalActivity.current
Page( Page(
"Editing card id${cardInfo.id}", stringResource(R.string.editing_card_title, cardInfo.id),
innerPadding innerPadding
) { ) {
Column( Column(
@@ -293,11 +297,11 @@ fun EditCard(cardInfo: CardInfo, innerPadding: PaddingValues, getDbFun: () -> Db
getDbFun().editCard(cardInfo.id, cardName, codeValue, codeType, color) getDbFun().editCard(cardInfo.id, cardName, codeValue, codeType, color)
context!!.finish() context!!.finish()
} else { } else {
Toast.makeText(context, err, Toast.LENGTH_SHORT).show() Toast.makeText(context, context!!.getString(err), Toast.LENGTH_SHORT).show()
} }
} }
) { ) {
Text("Save") Text(stringResource(R.string.do_save))
} }
} }
} }
@@ -31,6 +31,7 @@ import androidx.compose.runtime.setValue
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
import androidx.compose.ui.res.stringResource
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
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@@ -58,7 +59,9 @@ fun TopBar(text: String, innerPadding: PaddingValues) {
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background(MaterialTheme.colorScheme.primaryContainer) .background(MaterialTheme.colorScheme.primaryContainer)
.padding(innerPadding) .padding(top = innerPadding.calculateTopPadding())
.padding(horizontal = 8.dp)
.padding(bottom = 8.dp)
) { ) {
Text( Text(
text, text,
@@ -126,7 +129,7 @@ fun CardButton(cardInfo: CardInfo, onDeleteCard: (Int) -> Unit) {
onDismissRequest = { menuExpanded = false } onDismissRequest = { menuExpanded = false }
) { ) {
DropdownMenuItem( DropdownMenuItem(
text = { Text("Edit") }, text = { Text(stringResource(R.string.do_edit_card)) },
onClick = { onClick = {
menuExpanded = false menuExpanded = false
@@ -138,7 +141,7 @@ fun CardButton(cardInfo: CardInfo, onDeleteCard: (Int) -> Unit) {
} }
) )
DropdownMenuItem( DropdownMenuItem(
text = { Text("Delete") }, text = { Text(stringResource(R.string.do_delete_card)) },
onClick = { onClick = {
menuExpanded = false menuExpanded = false
@@ -33,6 +33,7 @@ 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 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
@@ -87,7 +88,7 @@ fun MainPage(
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()
) { ) {
Page( Page(
"OmniCards", stringResource(R.string.app_name),
innerPadding innerPadding
) { ) {
Column( Column(
@@ -95,7 +96,9 @@ fun MainPage(
verticalArrangement = Arrangement.spacedBy(8.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
if (cards.isEmpty()) { if (cards.isEmpty()) {
Text("Add new card to get started") Text(
stringResource(R.string.add_card_to_get_started)
)
} else { } else {
for (card in cards) { for (card in cards) {
CardButton(card, onDeleteCard) CardButton(card, onDeleteCard)
@@ -126,24 +129,24 @@ fun MainPage(
context.startActivity(intent) context.startActivity(intent)
} }
) { ) {
Text("Add card") Text(stringResource(R.string.do_add_card))
} }
FullWidthButton( FullWidthButton(
onClick = { onClick = {
Toast.makeText(context, "Sync in progress...", Toast.LENGTH_SHORT).show() Toast.makeText(context, context.getString(R.string.sync_in_progress), Toast.LENGTH_SHORT).show()
sendToWatch(context, "/updateCards", Json.encodeToString(getDbFun().getCards())) { isSuccess -> sendToWatch(context, "/updateCards", Json.encodeToString(getDbFun().getCards())) { isSuccess ->
if (isSuccess) { if (isSuccess) {
Toast.makeText(context, "Successfully synced!", Toast.LENGTH_SHORT).show() Toast.makeText(context, context.getString(R.string.sync_is_successful), Toast.LENGTH_SHORT).show()
} else { } else {
Toast.makeText(context, "Sync failed! Please, check your connection", Toast.LENGTH_LONG).show() Toast.makeText(context, context.getString(R.string.sync_is_fail), Toast.LENGTH_LONG).show()
} }
} }
isActionBarShowed = false isActionBarShowed = false
} }
) { ) {
Text("Sync with WearOS") Text(stringResource(R.string.do_sync))
} }
FullWidthButton( FullWidthButton(
onClick = { onClick = {
@@ -154,7 +157,7 @@ fun MainPage(
isActionBarShowed = false isActionBarShowed = false
} }
) { ) {
Text("Backup") Text(stringResource(R.string.open_backup_menu))
} }
FullWidthButton( FullWidthButton(
onClick = { onClick = {
@@ -163,7 +166,7 @@ fun MainPage(
isActionBarShowed = false isActionBarShowed = false
} }
) { ) {
Text("Source code") Text(stringResource(R.string.source_code))
} }
FullWidthButton( FullWidthButton(
onClick = { onClick = {
@@ -22,6 +22,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
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
import ru.omni_devel.cards.ui.theme.OmniCardsTheme import ru.omni_devel.cards.ui.theme.OmniCardsTheme
@@ -105,7 +106,7 @@ fun ShowCardPage(innerPadding: PaddingValues, cardInfo: CardInfo) {
) )
} else { } else {
Text( Text(
"Failed to generate code. Check card data", stringResource(R.string.failed_to_generate_card_code),
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.error color = MaterialTheme.colorScheme.error
@@ -2,6 +2,7 @@ package ru.omni_devel.cards
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import androidx.compose.ui.platform.LocalContext
import com.google.android.gms.wearable.Wearable import com.google.android.gms.wearable.Wearable
import com.google.zxing.BarcodeFormat import com.google.zxing.BarcodeFormat
import com.google.zxing.MultiFormatWriter import com.google.zxing.MultiFormatWriter
@@ -49,13 +50,13 @@ fun sendToWatch(context: Context, path: String, message: String, onResult: (Bool
} }
} }
fun checkCardData(name: String, value: String): String? { fun checkCardData(name: String, value: String): Int? {
if (name.isEmpty()) { if (name.isEmpty()) {
return "Name should not be empty" return R.string.card_name_should_not_be_empty
} else if (value.isEmpty()) { } else if (value.isEmpty()) {
return "Code value should not be empty" return R.string.card_value_should_not_be_empty
} else if (name.length > 32) { } else if (name.length > 32) {
return "Name must be shorter than 32 symbols" return R.string.name_must_be_shorter_than_32_symbols
} }
return null return null
+41
View File
@@ -0,0 +1,41 @@
<resources>
<string name="add_card_to_get_started">Добавьте новую карту для того, чтобы начать работу</string>
<string name="do_add_card">Добавить карту</string>
<string name="do_edit_card">Редактировать карту</string>
<string name="do_delete_card">Удалить карту</string>
<string name="source_code">Исходный код</string>
<string name="do_sync">Синхронизировать с WearOS</string>
<string name="sync_in_progress">Синхронизация в процессе...</string>
<string name="sync_is_successful">Успешная синхронизация!</string>
<string name="sync_is_fail">Ошибка синхронизации. Проверьте подключение к часам</string>
<string name="open_backup_menu">Бэкап/восстановление</string>
<string name="do_backup">Сохранить данные</string>
<string name="do_restore">Восстановить данные</string>
<string name="ask_do_restore">Восстановить данные?</string>
<string name="backup_successfully_saved">Данные успешно сохранены</string>
<string name="failed_to_save_backup">Не удалось сохранить данные: %s</string>
<string name="backup_successfully_restored">Данные успешно восстановлены</string>
<string name="failed_to_restore_backup">Не удалось восстановить данные: %s</string>
<string name="restore_caution">Это заменит существующие карты данными из файла резервной копии. Продолжить?</string>
<string name="yes">Да</string>
<string name="no">Нет</string>
<string name="do_save">Сохранить</string>
<string name="new_card_title">Добавление карты</string>
<string name="editing_card_title">Редактирование карты #%d</string>
<string name="card_name">Название карты</string>
<string name="card_value">Значение карты</string>
<string name="do_scan_card">Сканировать карту</string>
<string name="scan_your_card">Отсканируйте вашу карту</string>
<string name="card_code_type">Тип кода карты</string>
<string name="do_choose_color">Выбрать цвет</string>
<string name="card_name_should_not_be_empty">Имя карты не должно быть пустым</string>
<string name="card_value_should_not_be_empty">Значение карты не должно быть пустым</string>
<string name="name_must_be_shorter_than_32_symbols">Имя карты должно быть короче 32 символов</string>
<string name="failed_to_generate_card_code">Не удалось сгенерировать код карты. Проверьте данные</string>
</resources>
+43 -46
View File
@@ -1,49 +1,46 @@
<resources> <resources>
<string name="app_name">OmniCards</string> <string name="first_fragment_label" translatable="false">First Fragment</string>
<!-- Strings used for fragments for navigation --> <string name="second_fragment_label" translatable="false">Second Fragment</string>
<string name="first_fragment_label">First Fragment</string>
<string name="second_fragment_label">Second Fragment</string>
<string name="next">Next</string>
<string name="previous">Previous</string>
<string name="lorem_ipsum"> <string name="app_name" translatable="false">OmniCards</string>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris
volutpat, dolor id interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus <string name="add_card_to_get_started">Add a new card to get started</string>
dui nec risus. Maecenas non sodales nisi, vel dictum dolor. Class aptent taciti sociosqu ad
litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse blandit eleifend <string name="do_add_card">Add card</string>
diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet, imperdiet nisl a, <string name="do_edit_card">Edit card</string>
ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n <string name="do_delete_card">Delete card</string>
Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus <string name="source_code">Source code</string>
egestas, est a condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed
neque. Morbi tellus erat, dapibus ut sem a, iaculis tincidunt dui. Interdum et malesuada <string name="do_sync">Sync with WearOS</string>
fames ac ante ipsum primis in faucibus. Curabitur et eros porttitor, ultricies urna vitae, <string name="sync_in_progress">Sync in progress...</string>
molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl nec dolor <string name="sync_is_successful">Sync successful!</string>
bibendum, vel congue leo egestas.\n\n <string name="sync_is_fail">Sync failed. Check your watch connection</string>
Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit
amet auctor at, mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel, <string name="open_backup_menu">Backup / Restore</string>
molestie quam. Fusce blandit tincidunt nulla, quis sollicitudin libero facilisis et. Integer <string name="do_backup">Save data</string>
interdum nunc ligula, et fermentum metus hendrerit id. Vestibulum lectus felis, dictum at <string name="do_restore">Restore data</string>
lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse sodales nunc ligula, <string name="ask_do_restore">Restore data?</string>
in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque <string name="backup_successfully_saved">Data saved successfully</string>
est.\n\n <string name="failed_to_save_backup">Failed to save data: %s</string>
Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh. <string name="backup_successfully_restored">Data restored successfully</string>
Morbi laoreet, tortor sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui <string name="failed_to_restore_backup">Failed to restore data: %s</string>
non lorem. Nam mollis ipsum quis auctor varius. Quisque elementum eu libero sed commodo. In <string name="restore_caution">This will replace your existing cards with data from the backup file. Continue?</string>
eros nisl, imperdiet vel imperdiet et, scelerisque a mauris. Pellentesque varius ex nunc,
quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non viverra <string name="yes">Yes</string>
ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a <string name="no">No</string>
placerat diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus <string name="do_save">Save</string>
convallis.\n\n
Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et <string name="new_card_title">Add card</string>
malesuada fames ac turpis egestas. In volutpat arcu ut felis sagittis, in finibus massa <string name="editing_card_title">Editing card #%d</string>
gravida. Pellentesque id tellus orci. Integer dictum, lorem sed efficitur ullamcorper, <string name="card_name">Card name</string>
libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec maximus ullamcorper <string name="card_value">Card value</string>
sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus <string name="do_scan_card">Scan card</string>
libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus <string name="scan_your_card">Scan your card</string>
vestibulum. Fusce dictum libero quis erat maximus, vitae volutpat diam dignissim. <string name="card_code_type">Card code type</string>
</string> <string name="do_choose_color">Choose color</string>
<string name="title_activity_show_card">ShowCardActivity</string> <string name="card_name_should_not_be_empty">Card name must not be empty</string>
<string name="title_activity_add_card">AddCardActivity</string> <string name="card_value_should_not_be_empty">Card value must not be empty</string>
<string name="title_activity_edit_card">EditCardActivity</string> <string name="name_must_be_shorter_than_32_symbols">Card name must be shorter than 32 characters</string>
<string name="title_activity_backup">BackupActivity</string>
<string name="failed_to_generate_card_code">Failed to generate card code. Check the card data</string>
</resources> </resources>
+11 -1
View File
@@ -4,6 +4,16 @@ plugins {
alias(libs.plugins.kotlin.serialization) alias(libs.plugins.kotlin.serialization)
} }
fun generateVersionCode(): Int {
return try {
val process = ProcessBuilder("git", "rev-list", "--count", "HEAD").start()
"${process.inputStream.bufferedReader().readText().trim()}1".toInt() // 0 at end for WearOS
} catch (e: Exception) {
1
}
}
android { android {
namespace = "ru.omni_devel.cards" namespace = "ru.omni_devel.cards"
compileSdk = 36 compileSdk = 36
@@ -12,7 +22,7 @@ android {
applicationId = "ru.omni_devel.cards" applicationId = "ru.omni_devel.cards"
minSdk = 30 minSdk = 30
targetSdk = 36 targetSdk = 36
versionCode = 71 // 1 at end for WearOS versionCode = generateVersionCode()
versionName = "1.3.0" versionName = "1.3.0"
} }
Binary file not shown.
Binary file not shown.