diff --git a/app/src/main/java/network/columba/app/ui/screens/WelcomeScreen.kt b/app/src/main/java/network/columba/app/ui/screens/WelcomeScreen.kt
index 1d0a20efb..771fd3900 100644
--- a/app/src/main/java/network/columba/app/ui/screens/WelcomeScreen.kt
+++ b/app/src/main/java/network/columba/app/ui/screens/WelcomeScreen.kt
@@ -41,6 +41,8 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import network.columba.app.viewmodel.OnboardingViewModel
+import androidx.compose.ui.res.stringResource
+import network.columba.app.R
/**
* Welcome screen shown on first launch for fresh installs.
@@ -208,7 +210,7 @@ fun WelcomeScreen(
enabled = !state.isSaving,
) {
Text(
- text = "Skip",
+ text = stringResource(R.string.skip),
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
diff --git a/app/src/main/java/network/columba/app/ui/screens/onboarding/OnboardingPagerScreen.kt b/app/src/main/java/network/columba/app/ui/screens/onboarding/OnboardingPagerScreen.kt
index 628f8dc21..9cd333163 100644
--- a/app/src/main/java/network/columba/app/ui/screens/onboarding/OnboardingPagerScreen.kt
+++ b/app/src/main/java/network/columba/app/ui/screens/onboarding/OnboardingPagerScreen.kt
@@ -46,7 +46,8 @@ import network.columba.app.util.BatteryOptimizationManager
import network.columba.app.viewmodel.DebugViewModel
import network.columba.app.viewmodel.OnboardingViewModel
import kotlinx.coroutines.launch
-
+import androidx.compose.ui.res.stringResource
+import network.columba.app.R
/**
* Main onboarding screen with horizontal pager for multi-step setup.
* Guides users through identity setup, connectivity options, and permissions.
@@ -293,7 +294,7 @@ private fun TopBar(
modifier = Modifier.align(Alignment.CenterEnd),
) {
Text(
- text = "Skip",
+ text = stringResource(R.string.skip),
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
diff --git a/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/ConnectivityPage.kt b/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/ConnectivityPage.kt
index 96a617944..09a7add4a 100644
--- a/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/ConnectivityPage.kt
+++ b/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/ConnectivityPage.kt
@@ -36,6 +36,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import network.columba.app.ui.screens.onboarding.OnboardingInterfaceType
+import androidx.compose.ui.res.stringResource
+import network.columba.app.R
+
/**
* Connectivity page - allows user to select which network interfaces to enable.
@@ -72,7 +75,7 @@ fun ConnectivityPage(
// Title
Text(
- text = "How will you connect?",
+ text = stringResource(R.string.connection_methods),
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onBackground,
@@ -83,7 +86,7 @@ fun ConnectivityPage(
// Subtitle
Text(
- text = "Select the networks you'd like to use:",
+ text = stringResource(R.string.connection_methods_description),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
@@ -108,8 +111,8 @@ fun ConnectivityPage(
icon = Icons.Default.Bluetooth,
statusText =
when {
- blePermissionsDenied -> "Permissions denied"
- blePermissionsGranted -> "Permissions granted"
+ blePermissionsDenied -> stringResource(R.string.permission_denied)
+ blePermissionsGranted -> stringResource(R.string.permission_granted)
else -> null
},
statusIsError = blePermissionsDenied,
@@ -137,7 +140,7 @@ fun ConnectivityPage(
// Helper text
Text(
- text = "You can configure these later in Settings",
+ text = stringResource(R.string.configure_in_settings),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
@@ -158,7 +161,7 @@ fun ConnectivityPage(
.height(56.dp),
shape = RoundedCornerShape(12.dp),
) {
- Text("Back")
+ Text(stringResource(R.string.back))
}
Button(
@@ -169,7 +172,7 @@ fun ConnectivityPage(
.height(56.dp),
shape = RoundedCornerShape(12.dp),
) {
- Text("Continue")
+ Text(stringResource(R.string.nextAction))
}
}
diff --git a/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/IdentityPage.kt b/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/IdentityPage.kt
index e4d7cf8ca..2a48c12f3 100644
--- a/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/IdentityPage.kt
+++ b/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/IdentityPage.kt
@@ -30,6 +30,10 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.res.stringResource
+import network.columba.app.R
+
+
/**
* Identity page - allows user to set their display name.
@@ -67,7 +71,7 @@ fun IdentityPage(
// Title
Text(
- text = "Your Identity",
+ text = stringResource(R.string.your_identity),
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onBackground,
@@ -78,7 +82,7 @@ fun IdentityPage(
// Subtitle
Text(
- text = "Choose a display name others will see:",
+ text = stringResource(R.string.choose_your_name),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
@@ -90,8 +94,8 @@ fun IdentityPage(
OutlinedTextField(
value = displayName,
onValueChange = onDisplayNameChange,
- label = { Text("Display Name") },
- placeholder = { Text("Anonymous Peer") },
+ label = { Text(stringResource(R.string.display_name)) },
+ placeholder = { Text(stringResource(R.string.name_example)) },
singleLine = true,
modifier = Modifier.fillMaxWidth(),
keyboardOptions =
@@ -112,7 +116,7 @@ fun IdentityPage(
// Helper text
Text(
- text = "You can change this anytime, or create multiple identities for different contexts.",
+ text = stringResource(R.string.name_change_description),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
@@ -133,7 +137,7 @@ fun IdentityPage(
.height(56.dp),
shape = RoundedCornerShape(12.dp),
) {
- Text("Back")
+ Text(stringResource(R.string.back))
}
Button(
@@ -147,7 +151,7 @@ fun IdentityPage(
.height(56.dp),
shape = RoundedCornerShape(12.dp),
) {
- Text("Continue")
+ Text(stringResource(R.string.nextAction))
}
}
diff --git a/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/PermissionsPage.kt b/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/PermissionsPage.kt
index ff554d2d8..14ee3a3de 100644
--- a/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/PermissionsPage.kt
+++ b/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/PermissionsPage.kt
@@ -33,6 +33,8 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.res.stringResource
+import network.columba.app.R
/**
* Permissions page - explains and requests notification and battery permissions.
@@ -69,7 +71,7 @@ fun PermissionsPage(
// Title
Text(
- text = "Stay Connected",
+ text = stringResource(R.string.stay_connected),
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onBackground,
@@ -80,7 +82,7 @@ fun PermissionsPage(
// Subtitle
Text(
- text = "Columba can notify you when:",
+ text = stringResource(R.string.can_notify_you, stringResource(R.string.app_name)),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
@@ -93,9 +95,9 @@ fun PermissionsPage(
modifier = Modifier.padding(horizontal = 32.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
- FeatureItem("New messages arrive")
- FeatureItem("Someone adds you as a contact")
- FeatureItem("Delivery confirmations are received")
+ FeatureItem(stringResource(R.string.item_new_messages))
+ FeatureItem(stringResource(R.string.item_some_add_contact))
+ FeatureItem(stringResource(R.string.item_delivery_confirmed))
}
Spacer(modifier = Modifier.height(24.dp))
@@ -103,8 +105,8 @@ fun PermissionsPage(
// Notification permission card
PermissionCard(
icon = Icons.Default.Notifications,
- title = "Notifications",
- description = "Get alerts for new messages",
+ title = stringResource(R.string.notifications),
+ description = stringResource(R.string.notifications_description),
isGranted = notificationsGranted,
onEnable = onEnableNotifications,
)
@@ -114,9 +116,9 @@ fun PermissionsPage(
// Battery optimization card
PermissionCard(
icon = Icons.Default.BatteryChargingFull,
- title = "Unrestricted Battery",
- description = "Receive messages even when phone is idle",
- secondaryDescription = "Prevents Android from pausing Columba",
+ title = stringResource(R.string.unrestricted_battery),
+ description = stringResource(R.string.unrestricted_battery_description),
+ secondaryDescription = stringResource(R.string.unrestricted_battery_secondDescription, stringResource(R.string.app_name)),
isGranted = batteryOptimizationExempt,
onEnable = onEnableBatteryOptimization,
)
@@ -136,7 +138,7 @@ fun PermissionsPage(
.height(56.dp),
shape = RoundedCornerShape(12.dp),
) {
- Text("Back")
+ Text(stringResource(R.string.back))
}
Button(
@@ -147,7 +149,7 @@ fun PermissionsPage(
.height(56.dp),
shape = RoundedCornerShape(12.dp),
) {
- Text("Continue")
+ Text(stringResource(R.string.nextAction))
}
}
@@ -274,7 +276,7 @@ private fun PermissionCard(
onClick = onEnable,
shape = RoundedCornerShape(8.dp),
) {
- Text("Enable")
+ Text(stringResource(R.string.enable))
}
}
}
diff --git a/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/WelcomePage.kt b/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/WelcomePage.kt
index a54e9cf25..6cda6e790 100644
--- a/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/WelcomePage.kt
+++ b/app/src/main/java/network/columba/app/ui/screens/onboarding/pages/WelcomePage.kt
@@ -29,6 +29,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import network.columba.app.R
+import androidx.compose.ui.res.stringResource
/**
* Welcome page - introduces privacy-first messaging.
@@ -82,7 +83,7 @@ fun WelcomePage(
// Title
Text(
- text = "Welcome to Columba",
+ text = stringResource(R.string.welcome_to, stringResource(R.string.app_name)),
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onBackground,
@@ -93,7 +94,7 @@ fun WelcomePage(
// Subtitle
Text(
- text = "A private messenger that requires:",
+ text = stringResource(R.string.messenger_requires),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
@@ -102,17 +103,17 @@ fun WelcomePage(
Spacer(modifier = Modifier.height(24.dp))
// Privacy features
- PrivacyFeature(text = "No phone number")
+ PrivacyFeature(text = stringResource(R.string.no_phone_number))
Spacer(modifier = Modifier.height(12.dp))
- PrivacyFeature(text = "No email address")
+ PrivacyFeature(text = stringResource(R.string.no_email_address))
Spacer(modifier = Modifier.height(12.dp))
- PrivacyFeature(text = "No sign-up or accounts")
+ PrivacyFeature(text = stringResource(R.string.no_accounts))
Spacer(modifier = Modifier.height(32.dp))
// Identity explanation
Text(
- text = "Your identity is generated and stored securely on your device. You control it completely.",
+ text = stringResource(R.string.welcome_security_description),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
@@ -131,7 +132,7 @@ fun WelcomePage(
shape = RoundedCornerShape(12.dp),
) {
Text(
- text = "Get Started",
+ text = stringResource(R.string.get_started),
style = MaterialTheme.typography.titleMedium,
)
}
@@ -143,7 +144,7 @@ fun WelcomePage(
onClick = onRestoreFromBackup,
) {
Text(
- text = "Restore from backup",
+ text = stringResource(R.string.restore_from_backup),
color = MaterialTheme.colorScheme.primary,
)
}
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
new file mode 100644
index 000000000..2fe07d9b4
--- /dev/null
+++ b/app/src/main/res/values-ru/strings.xml
@@ -0,0 +1,69 @@
+
+
+ Входящий аудиовызов
+ Ответить
+ Отклонить
+ Ответить на вызов
+ Отклонить вызов
+ На телефоне не найден файловый менеджер
+ Геолокация на карте
+ Перезапуск сервиса Reticulum \u2026
+ Columba сейчас оффлайн
+ Ошибка подключения
+ Переподключение\u2026
+ Переподключиться
+ Процесс переподключения
+ Удалить интерфейс
+ Детали
+ Действия
+ Редактировать
+ Приватный мессенджер, для которого:
+ Добро пожаловать в %1$s
+ Не нужен номер телефона
+ Не нужен Email
+ Не нужна авторизация или аккаунты
+ Ваш профиль создается и надежно хранится на вашем устройстве. Только вы контролируете его
+ Начать
+ Восстановить из бэкапа
+ Ваш профиль
+ Напишите ваш никнейм, который будет виден всем
+ Никнейм
+ Анонимная нода
+ Вы можете сменить его в любое время или создать другие профили
+ Назад
+ Далее
+ Как вы хотите подключиться?
+ Выберите типы сетей, которые вы будете использовать:
+ Разрешение отклонено
+ Разрешение предоставлено
+ Вы можете изменить это в настройках
+ Оставайтесь на связи
+ %1$s может оповестить вас когда:
+ Пришло новое сообщение
+ Кто-то добавил вас в контакты
+ Получено подтверждение о доставке сообщения
+ Уведомления
+ Пропустить
+ Получение уведомлений о новых сообщениях
+ Без ограничений батареи
+ Получение уведомлений в режиме ожидания
+ Защищает %1$s от остановки в фоне
+ Включить
+ Выключить
+ Вы всё настроили!
+ Итого
+ Никнейм
+ Сети
+ Ничего не выбрано
+ Включены
+ Выключены
+ Ограниченно
+ Нет ограничения
+ Батарея
+ Показать QR код
+ Поделитесь своим QR-кодом, чтобы другие могли добавить вас в контакты.
+ Настроить LoRa
+ Начать общение
+ Поделиться профилем
+ Добавьте меня через reticulum: \n\n%1$s\n%2$s
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c1ba74421..c957d1baf 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -30,4 +30,53 @@
View interface details
Interface actions
Edit interface
+ A private messenger that requires:
+ Welcome to %1$s
+ No phone number
+ No email address
+ No sign-up or accounts
+ Your identity is generated and stored securely on your device. You control it completely.
+ Get Started
+ Restore from backup
+ Your Identity
+ Choose a display name others will see:
+ Display Name
+ Anonymous Peer
+ You can change this anytime, or create multiple identities for different contexts.
+ Back
+ Continue
+ How will you connect?
+ Select the networks you\'d like to use:
+ Permission denied
+ Permission granted
+ You can configure these in Settings.
+ Stay connected
+ %1$s can notify you when:
+ New messages arrive
+ Someone adds you as a contact
+ Delivery confirmations are received
+ Notifications
+ Skip
+ Get alerts for new messages
+ Unrestricted Battery
+ Receive messages even when phone is idle
+ Prevents Android from pausing %1$s
+ Enable
+ Disable
+ You\'re all set!
+ Summary
+ Identity
+ Networks
+ None selected
+ Enabled
+ Disabled
+ Restricted
+ Unrestricted
+ Battery
+ Show QR code
+ Share your identity QR code to let others add you as a contact.
+ Configure LoRa
+ Start Messaging
+ Share identity
+ Add me on Reticulum: \n\n%1$s\n%2$s
diff --git a/build.gradle.kts b/build.gradle.kts
index eff049129..d060c9923 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
- id("com.android.application") version "9.1.0" apply false
- id("com.android.library") version "9.1.0" apply false
+ id("com.android.application") version "9.2.0" apply false
+ id("com.android.library") version "9.2.0" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.3.20" apply false
id("com.google.dagger.hilt.android") version "2.59.2" apply false
id("com.google.devtools.ksp") version "2.3.6" apply false