diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml index 1f57f40..83ff95f 100644 --- a/mobile/src/main/AndroidManifest.xml +++ b/mobile/src/main/AndroidManifest.xml @@ -11,27 +11,18 @@ - diff --git a/mobile/src/main/java/ru/omni_devel/cards/BackupActivity.kt b/mobile/src/main/java/ru/omni_devel/cards/BackupActivity.kt index ee944e9..75f7af5 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/BackupActivity.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/BackupActivity.kt @@ -24,7 +24,7 @@ import kotlinx.serialization.json.Json import ru.omni_devel.cards.ui.theme.OmniCardsTheme import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue -import kotlinx.serialization.decodeFromString +import androidx.compose.ui.res.stringResource class BackupActivity : ComponentActivity() { private lateinit var db: DbHelper @@ -65,12 +65,12 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) { context.contentResolver.openOutputStream(it)?.use { outputStream -> 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() } } 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) { AlertDialog( - title = { Text("Restore backup") }, - text = { Text("This will replace existing cards by data from backup file. Continue?") }, + title = { Text(stringResource(R.string.ask_do_restore)) }, + text = { Text(stringResource(R.string.restore_caution)) }, confirmButton = { TextButton( onClick = { @@ -105,17 +105,17 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) { db.clearDatabase() 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() } } 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 = { @@ -124,7 +124,7 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) { showImportDialog.value = false } ) { - Text("No") + Text(stringResource(R.string.no)) } }, onDismissRequest = { showImportDialog.value = false }, @@ -137,14 +137,14 @@ fun BackupPage(innerPadding: PaddingValues, getDbFun: () -> DbHelper) { createBackupLauncher.launch("omnicards-backup.json") } ) { - Text("Backup to file") + Text(stringResource(R.string.do_backup)) } FullWidthButton( onClick = { restoreFromBackupLauncher.launch("application/json") } ) { - Text("Restore from file") + Text(stringResource(R.string.do_restore)) } } } diff --git a/mobile/src/main/java/ru/omni_devel/cards/EditCardActivity.kt b/mobile/src/main/java/ru/omni_devel/cards/EditCardActivity.kt index b439fd3..0cf992b 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/EditCardActivity.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/EditCardActivity.kt @@ -34,6 +34,8 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier 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.core.graphics.toColorInt import com.github.skydoves.colorpicker.compose.ColorEnvelope @@ -79,6 +81,8 @@ fun CardEditable( color: String?, onColorChange: (String?) -> Unit ) { + val context = LocalContext.current + var isCodeTypeDropdownExpanded by rememberSaveable { mutableStateOf(false) } var isColorPickerExpanded by rememberSaveable { mutableStateOf(false) } var isColorEnabled by rememberSaveable { mutableStateOf(color != null) } @@ -105,7 +109,7 @@ fun CardEditable( value = cardName, onValueChange = onCardNameChange, modifier = fieldModifier, - label = { Text("Name") } + label = { Text(stringResource(R.string.card_name)) } ) Row( horizontalArrangement = Arrangement.spacedBy(8.dp) @@ -114,21 +118,21 @@ fun CardEditable( value = codeValue, onValueChange = onCodeValueChange, modifier = Modifier.weight(1f), - label = { Text("Value") } + label = { Text(stringResource(R.string.card_value)) } ) Button( modifier = Modifier.align(Alignment.CenterVertically), onClick = { scanLauncher.launch( ScanOptions().apply { - setPrompt("Scan your card") + setPrompt(context.getString(R.string.scan_your_card)) setBeepEnabled(true) setOrientationLocked(false) } ) } ) { - Text("Scan") + Text(stringResource(R.string.do_scan_card)) } } @@ -139,7 +143,7 @@ fun CardEditable( value = codeType.name, onValueChange = {}, modifier = fieldModifier, - label = { Text("Code type") }, + label = { Text(stringResource(R.string.card_code_type)) }, readOnly = true, ) Box( @@ -176,7 +180,7 @@ fun CardEditable( isColorPickerExpanded = !isColorPickerExpanded } ) { - Text("Choose color") + Text(stringResource(R.string.do_choose_color)) } Switch( checked = isColorEnabled, @@ -215,7 +219,7 @@ fun AddCard(innerPadding: PaddingValues, getDbFun: () -> DbHelper) { val context = LocalActivity.current Page( - "New card", + stringResource(R.string.new_card_title), innerPadding ) { Column( @@ -244,11 +248,11 @@ fun AddCard(innerPadding: PaddingValues, getDbFun: () -> DbHelper) { getDbFun().addCard(cardName, codeValue, codeType, color) context!!.finish() } 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 Page( - "Editing card id${cardInfo.id}", + stringResource(R.string.editing_card_title, cardInfo.id), innerPadding ) { Column( @@ -293,11 +297,11 @@ fun EditCard(cardInfo: CardInfo, innerPadding: PaddingValues, getDbFun: () -> Db getDbFun().editCard(cardInfo.id, cardName, codeValue, codeType, color) context!!.finish() } 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)) } } } 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 13ec775..b008911 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/Elements.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/Elements.kt @@ -31,6 +31,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -128,7 +129,7 @@ fun CardButton(cardInfo: CardInfo, onDeleteCard: (Int) -> Unit) { onDismissRequest = { menuExpanded = false } ) { DropdownMenuItem( - text = { Text("Edit") }, + text = { Text(stringResource(R.string.do_edit_card)) }, onClick = { menuExpanded = false @@ -140,7 +141,7 @@ fun CardButton(cardInfo: CardInfo, onDeleteCard: (Int) -> Unit) { } ) DropdownMenuItem( - text = { Text("Delete") }, + text = { Text(stringResource(R.string.do_delete_card)) }, onClick = { menuExpanded = false diff --git a/mobile/src/main/java/ru/omni_devel/cards/MainActivity.kt b/mobile/src/main/java/ru/omni_devel/cards/MainActivity.kt index 8f57706..ba7d222 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/MainActivity.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/MainActivity.kt @@ -33,6 +33,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalUriHandler +import androidx.compose.ui.res.stringResource import kotlinx.serialization.json.Json import ru.omni_devel.cards.ui.theme.OmniCardsTheme @@ -87,7 +88,7 @@ fun MainPage( modifier = Modifier.fillMaxSize() ) { Page( - "OmniCards", + stringResource(R.string.app_name), innerPadding ) { Column( @@ -95,7 +96,9 @@ fun MainPage( verticalArrangement = Arrangement.spacedBy(8.dp) ) { if (cards.isEmpty()) { - Text("Add new card to get started") + Text( + stringResource(R.string.add_card_to_get_started) + ) } else { for (card in cards) { CardButton(card, onDeleteCard) @@ -126,24 +129,24 @@ fun MainPage( context.startActivity(intent) } ) { - Text("Add card") + Text(stringResource(R.string.do_add_card)) } FullWidthButton( 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 -> 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 { - 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 } ) { - Text("Sync with WearOS") + Text(stringResource(R.string.do_sync)) } FullWidthButton( onClick = { @@ -154,7 +157,7 @@ fun MainPage( isActionBarShowed = false } ) { - Text("Backup") + Text(stringResource(R.string.open_backup_menu)) } FullWidthButton( onClick = { @@ -163,7 +166,7 @@ fun MainPage( isActionBarShowed = false } ) { - Text("Source code") + Text(stringResource(R.string.source_code)) } FullWidthButton( onClick = { diff --git a/mobile/src/main/java/ru/omni_devel/cards/ShowCardActivity.kt b/mobile/src/main/java/ru/omni_devel/cards/ShowCardActivity.kt index 3e01f06..f805a5a 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/ShowCardActivity.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/ShowCardActivity.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import ru.omni_devel.cards.ui.theme.OmniCardsTheme @@ -105,7 +106,7 @@ fun ShowCardPage(innerPadding: PaddingValues, cardInfo: CardInfo) { ) } else { Text( - "Failed to generate code. Check card data", + stringResource(R.string.failed_to_generate_card_code), modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colorScheme.error diff --git a/mobile/src/main/java/ru/omni_devel/cards/Utils.kt b/mobile/src/main/java/ru/omni_devel/cards/Utils.kt index ed76b3d..0947346 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/Utils.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/Utils.kt @@ -2,6 +2,7 @@ package ru.omni_devel.cards import android.content.Context import android.graphics.Bitmap +import androidx.compose.ui.platform.LocalContext import com.google.android.gms.wearable.Wearable import com.google.zxing.BarcodeFormat 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()) { - return "Name should not be empty" + return R.string.card_name_should_not_be_empty } 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) { - return "Name must be shorter than 32 symbols" + return R.string.name_must_be_shorter_than_32_symbols } return null diff --git a/mobile/src/main/res/values-ru/strings.xml b/mobile/src/main/res/values-ru/strings.xml new file mode 100644 index 0000000..9072d3a --- /dev/null +++ b/mobile/src/main/res/values-ru/strings.xml @@ -0,0 +1,41 @@ + + Добавьте новую карту для того, чтобы начать работу + + Добавить карту + Редактировать карту + Удалить карту + Исходный код + + Синхронизировать с WearOS + Синхронизация в процессе... + Успешная синхронизация! + Ошибка синхронизации. Проверьте подключение к часам + + Бэкап/восстановление + Сохранить данные + Восстановить данные + Восстановить данные? + Данные успешно сохранены + Не удалось сохранить данные: %s + Данные успешно восстановлены + Не удалось восстановить данные: %s + Это заменит существующие карты данными из файла резервной копии. Продолжить? + + Да + Нет + Сохранить + + Добавление карты + Редактирование карты #%d + Название карты + Значение карты + Сканировать карту + Отсканируйте вашу карту + Тип кода карты + Выбрать цвет + Имя карты не должно быть пустым + Значение карты не должно быть пустым + Имя карты должно быть короче 32 символов + + Не удалось сгенерировать код карты. Проверьте данные + \ No newline at end of file diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index e54dca9..c923782 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -1,49 +1,46 @@ - OmniCards - - First Fragment - Second Fragment - Next - Previous + First Fragment + Second Fragment - - 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 - 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 - diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet, imperdiet nisl a, - ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n - Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus - 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 - fames ac ante ipsum primis in faucibus. Curabitur et eros porttitor, ultricies urna vitae, - molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl nec dolor - bibendum, vel congue leo egestas.\n\n - 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, - molestie quam. Fusce blandit tincidunt nulla, quis sollicitudin libero facilisis et. Integer - interdum nunc ligula, et fermentum metus hendrerit id. Vestibulum lectus felis, dictum at - lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse sodales nunc ligula, - in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque - est.\n\n - Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh. - Morbi laoreet, tortor sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui - non lorem. Nam mollis ipsum quis auctor varius. Quisque elementum eu libero sed commodo. In - 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 - ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a - placerat diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus - convallis.\n\n - Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et - malesuada fames ac turpis egestas. In volutpat arcu ut felis sagittis, in finibus massa - gravida. Pellentesque id tellus orci. Integer dictum, lorem sed efficitur ullamcorper, - libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec maximus ullamcorper - sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus - libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus - vestibulum. Fusce dictum libero quis erat maximus, vitae volutpat diam dignissim. - - ShowCardActivity - AddCardActivity - EditCardActivity - BackupActivity + OmniCards + + Add a new card to get started + + Add card + Edit card + Delete card + Source code + + Sync with WearOS + Sync in progress... + Sync successful! + Sync failed. Check your watch connection + + Backup / Restore + Save data + Restore data + Restore data? + Data saved successfully + Failed to save data: %s + Data restored successfully + Failed to restore data: %s + This will replace your existing cards with data from the backup file. Continue? + + Yes + No + Save + + Add card + Editing card #%d + Card name + Card value + Scan card + Scan your card + Card code type + Choose color + Card name must not be empty + Card value must not be empty + Card name must be shorter than 32 characters + + Failed to generate card code. Check the card data \ No newline at end of file