Make :core:strings a Compose Multiplatform library (#3617)

This commit is contained in:
Phil Oliver 2025-11-10 19:58:38 -05:00 committed by GitHub
parent d7fff4add2
commit 28590bfcdf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
206 changed files with 1722 additions and 470 deletions

View file

@ -29,7 +29,6 @@ import org.junit.Assert
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.meshtastic.core.strings.R as Res
@RunWith(AndroidJUnit4::class)
class MapReportingPreferenceTest {

View file

@ -54,18 +54,44 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import com.meshtastic.core.strings.getString
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.common.gpsDisabled
import org.meshtastic.core.database.DatabaseConstants
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.analytics_okay
import org.meshtastic.core.strings.app_settings
import org.meshtastic.core.strings.app_version
import org.meshtastic.core.strings.bottom_nav_settings
import org.meshtastic.core.strings.choose_theme
import org.meshtastic.core.strings.device_db_cache_limit
import org.meshtastic.core.strings.device_db_cache_limit_summary
import org.meshtastic.core.strings.dynamic
import org.meshtastic.core.strings.export_configuration
import org.meshtastic.core.strings.export_data_csv
import org.meshtastic.core.strings.import_configuration
import org.meshtastic.core.strings.intro_show
import org.meshtastic.core.strings.location_disabled
import org.meshtastic.core.strings.modules_already_unlocked
import org.meshtastic.core.strings.modules_unlocked
import org.meshtastic.core.strings.preferences_language
import org.meshtastic.core.strings.provide_location_to_mesh
import org.meshtastic.core.strings.remotely_administrating
import org.meshtastic.core.strings.save_rangetest
import org.meshtastic.core.strings.system_settings
import org.meshtastic.core.strings.theme
import org.meshtastic.core.strings.theme_dark
import org.meshtastic.core.strings.theme_light
import org.meshtastic.core.strings.theme_system
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.MainAppBar
@ -86,7 +112,6 @@ import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlin.time.Duration.Companion.seconds
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalPermissionsApi::class)
@Suppress("LongMethod", "CyclomaticComplexMethod")

View file

@ -63,7 +63,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
@ -80,6 +79,16 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.debug_clear
import org.meshtastic.core.strings.debug_clear_logs_confirm
import org.meshtastic.core.strings.debug_decoded_payload
import org.meshtastic.core.strings.debug_export_failed
import org.meshtastic.core.strings.debug_export_success
import org.meshtastic.core.strings.debug_filters
import org.meshtastic.core.strings.debug_logs_export
import org.meshtastic.core.strings.debug_panel
import org.meshtastic.core.ui.component.CopyIconButton
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.SimpleAlertDialog
@ -94,7 +103,6 @@ import java.nio.charset.StandardCharsets
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import org.meshtastic.core.strings.R as Res
private val REGEX_ANNOTATED_NODE_ID = Regex("\\(![0-9a-fA-F]{8}\\)$", RegexOption.MULTILINE)

View file

@ -50,14 +50,21 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.debug_active_filters
import org.meshtastic.core.strings.debug_filter_add
import org.meshtastic.core.strings.debug_filter_clear
import org.meshtastic.core.strings.debug_filter_included
import org.meshtastic.core.strings.debug_filters
import org.meshtastic.core.strings.match_all
import org.meshtastic.core.strings.match_any
import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog
import org.meshtastic.core.strings.R as Res
@Composable
fun DebugCustomFilterInput(

View file

@ -46,18 +46,23 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.debug_default_search
import org.meshtastic.core.strings.debug_logs_export
import org.meshtastic.core.strings.debug_search_clear
import org.meshtastic.core.strings.debug_search_next
import org.meshtastic.core.strings.debug_search_prev
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog
import org.meshtastic.feature.settings.debugging.LogSearchManager.SearchMatch
import org.meshtastic.feature.settings.debugging.LogSearchManager.SearchState
import org.meshtastic.core.strings.R as Res
@Composable
internal fun DebugSearchNavigation(

View file

@ -17,7 +17,6 @@
package org.meshtastic.feature.settings.navigation
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.List
import androidx.compose.material.icons.filled.Bluetooth
@ -30,13 +29,24 @@ import androidx.compose.material.icons.filled.Router
import androidx.compose.material.icons.filled.Security
import androidx.compose.material.icons.filled.Wifi
import androidx.compose.ui.graphics.vector.ImageVector
import org.jetbrains.compose.resources.StringResource
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.bluetooth
import org.meshtastic.core.strings.channels
import org.meshtastic.core.strings.device
import org.meshtastic.core.strings.display
import org.meshtastic.core.strings.lora
import org.meshtastic.core.strings.network
import org.meshtastic.core.strings.position
import org.meshtastic.core.strings.power
import org.meshtastic.core.strings.security
import org.meshtastic.core.strings.user
import org.meshtastic.proto.AdminProtos
import org.meshtastic.proto.MeshProtos.DeviceMetadata
import org.meshtastic.core.strings.R as Res
enum class ConfigRoute(@StringRes val title: Int, val route: Route, val icon: ImageVector?, val type: Int = 0) {
enum class ConfigRoute(val title: StringResource, val route: Route, val icon: ImageVector?, val type: Int = 0) {
USER(Res.string.user, SettingsRoutes.User, Icons.Default.Person, 0),
CHANNELS(Res.string.channels, SettingsRoutes.ChannelConfig, Icons.AutoMirrored.Default.List, 0),
DEVICE(

View file

@ -17,7 +17,6 @@
package org.meshtastic.feature.settings.navigation
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Forward
import androidx.compose.material.icons.automirrored.filled.Message
@ -33,13 +32,27 @@ import androidx.compose.material.icons.filled.SettingsRemote
import androidx.compose.material.icons.filled.Speed
import androidx.compose.material.icons.filled.Usb
import androidx.compose.ui.graphics.vector.ImageVector
import org.jetbrains.compose.resources.StringResource
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.ambient_lighting
import org.meshtastic.core.strings.audio
import org.meshtastic.core.strings.canned_message
import org.meshtastic.core.strings.detection_sensor
import org.meshtastic.core.strings.external_notification
import org.meshtastic.core.strings.mqtt
import org.meshtastic.core.strings.neighbor_info
import org.meshtastic.core.strings.paxcounter
import org.meshtastic.core.strings.range_test
import org.meshtastic.core.strings.remote_hardware
import org.meshtastic.core.strings.serial
import org.meshtastic.core.strings.store_forward
import org.meshtastic.core.strings.telemetry
import org.meshtastic.proto.AdminProtos
import org.meshtastic.proto.MeshProtos.DeviceMetadata
import org.meshtastic.core.strings.R as Res
enum class ModuleRoute(@StringRes val title: Int, val route: Route, val icon: ImageVector?, val type: Int = 0) {
enum class ModuleRoute(val title: StringResource, val route: Route, val icon: ImageVector?, val type: Int = 0) {
MQTT(
Res.string.mqtt,
SettingsRoutes.MQTT,

View file

@ -43,12 +43,21 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.entity.NodeEntity
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.are_you_sure
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.clean_node_database_confirmation
import org.meshtastic.core.strings.clean_node_database_description
import org.meshtastic.core.strings.clean_node_database_title
import org.meshtastic.core.strings.clean_nodes_older_than
import org.meshtastic.core.strings.clean_now
import org.meshtastic.core.strings.clean_unknown_nodes
import org.meshtastic.core.strings.nodes_queued_for_deletion
import org.meshtastic.core.ui.component.NodeChip
import org.meshtastic.core.strings.R as Res
/**
* Composable screen for cleaning the node database. Allows users to specify criteria for deleting nodes. The list of

View file

@ -17,7 +17,6 @@
package org.meshtastic.feature.settings.radio
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
@ -39,11 +38,28 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.administration
import org.meshtastic.core.strings.advanced_title
import org.meshtastic.core.strings.backup_restore
import org.meshtastic.core.strings.clean_node_database_title
import org.meshtastic.core.strings.debug_panel
import org.meshtastic.core.strings.device_configuration
import org.meshtastic.core.strings.export_configuration
import org.meshtastic.core.strings.factory_reset
import org.meshtastic.core.strings.import_configuration
import org.meshtastic.core.strings.message_device_managed
import org.meshtastic.core.strings.module_settings
import org.meshtastic.core.strings.nodedb_reset
import org.meshtastic.core.strings.radio_configuration
import org.meshtastic.core.strings.reboot
import org.meshtastic.core.strings.shutdown
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.AppTheme
@ -51,7 +67,6 @@ import org.meshtastic.core.ui.theme.StatusColors.StatusRed
import org.meshtastic.feature.settings.navigation.ConfigRoute
import org.meshtastic.feature.settings.navigation.ModuleRoute
import org.meshtastic.feature.settings.radio.component.WarningDialog
import org.meshtastic.core.strings.R as Res
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable
@ -169,7 +184,7 @@ fun RadioConfigItemList(
}
}
enum class AdminRoute(val icon: ImageVector, @StringRes val title: Int) {
enum class AdminRoute(val icon: ImageVector, val title: StringResource) {
REBOOT(Icons.Rounded.RestartAlt, Res.string.reboot),
SHUTDOWN(Icons.Rounded.PowerSettingsNew, Res.string.shutdown),
FACTORY_RESET(Icons.Rounded.Restore, Res.string.factory_reset),

View file

@ -25,7 +25,6 @@ import android.net.Uri
import android.os.RemoteException
import android.util.Base64
import androidx.annotation.RequiresPermission
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.lifecycle.SavedStateHandle
@ -46,6 +45,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jetbrains.compose.resources.StringResource
import org.json.JSONObject
import org.meshtastic.core.data.repository.LocationRepository
import org.meshtastic.core.data.repository.NodeRepository
@ -62,6 +62,8 @@ import org.meshtastic.core.prefs.map.MapConsentPrefs
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.service.IMeshService
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.cant_shutdown
import org.meshtastic.core.ui.util.getChannelList
import org.meshtastic.feature.settings.navigation.ConfigRoute
import org.meshtastic.feature.settings.navigation.ModuleRoute
@ -81,7 +83,6 @@ import org.meshtastic.proto.moduleConfig
import timber.log.Timber
import java.io.FileOutputStream
import javax.inject.Inject
import org.meshtastic.core.strings.R as Res
/** Data class that represents the current RadioConfig state. */
data class RadioConfigState(
@ -606,7 +607,7 @@ constructor(
private fun sendError(error: String) = setResponseStateError(UiText.DynamicString(error))
private fun sendError(@StringRes id: Int) = setResponseStateError(UiText.StringResource(id))
private fun sendError(id: StringResource) = setResponseStateError(UiText.StringResource(id))
private fun setResponseStateError(error: UiText) {
_radioConfigState.update { it.copy(responseState = ResponseState.Error(error)) }

View file

@ -48,13 +48,20 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.Channel
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.add
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.channel_name
import org.meshtastic.core.strings.channels
import org.meshtastic.core.strings.press_and_drag
import org.meshtastic.core.strings.send
import org.meshtastic.core.ui.component.PreferenceFooter
import org.meshtastic.core.ui.component.dragContainer
import org.meshtastic.core.ui.component.dragDropItemsIndexed
@ -70,7 +77,6 @@ import org.meshtastic.feature.settings.radio.component.PacketResponseStateDialog
import org.meshtastic.proto.ChannelProtos.ChannelSettings
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig
import org.meshtastic.proto.channelSettings
import org.meshtastic.core.strings.R as Res
@Composable
fun ChannelConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {

View file

@ -27,9 +27,11 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.delete
import org.meshtastic.core.ui.component.ChannelItem
import org.meshtastic.core.ui.component.SecurityIcon
import org.meshtastic.core.ui.theme.AppTheme
@ -37,7 +39,6 @@ import org.meshtastic.proto.ChannelProtos.ChannelSettings
import org.meshtastic.proto.ConfigKt.loRaConfig
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig
import org.meshtastic.proto.channelSettings
import org.meshtastic.core.strings.R as Res
@Composable
internal fun ChannelCard(

View file

@ -25,12 +25,15 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.channels
import org.meshtastic.core.strings.freq
import org.meshtastic.core.strings.slot
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
@Composable
internal fun ChannelConfigHeader(frequency: Float, slot: Int) {

View file

@ -17,7 +17,6 @@
package org.meshtastic.feature.settings.radio.channel.component
import androidx.annotation.StringRes
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@ -42,11 +41,28 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.R as Res
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.channel_features
import org.meshtastic.core.strings.downlink_enabled
import org.meshtastic.core.strings.downlink_feature_description
import org.meshtastic.core.strings.icon_meanings
import org.meshtastic.core.strings.info
import org.meshtastic.core.strings.location_sharing
import org.meshtastic.core.strings.manual_position_request
import org.meshtastic.core.strings.periodic_position_broadcast
import org.meshtastic.core.strings.primary
import org.meshtastic.core.strings.primary_channel_feature
import org.meshtastic.core.strings.secondary
import org.meshtastic.core.strings.secondary_channel_position_feature
import org.meshtastic.core.strings.secondary_no_telemetry
import org.meshtastic.core.strings.security_icon_help_dismiss
import org.meshtastic.core.strings.uplink_enabled
import org.meshtastic.core.strings.uplink_feature_description
/**
* At this firmware version periodic position sharing on a secondary channel was implemented. To enable this feature the
@ -57,8 +73,8 @@ internal const val SECONDARY_CHANNEL_EPOCH = "2.6.10"
internal enum class ChannelIcons(
val icon: ImageVector,
@StringRes val descriptionResId: Int,
@StringRes val additionalInfoResId: Int,
val descriptionResId: StringResource,
val additionalInfoResId: StringResource,
) {
LOCATION(
icon = Icons.Filled.LocationOn,

View file

@ -37,12 +37,19 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.Channel
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.channel_name
import org.meshtastic.core.strings.default_
import org.meshtastic.core.strings.downlink_enabled
import org.meshtastic.core.strings.save
import org.meshtastic.core.strings.uplink_enabled
import org.meshtastic.core.ui.component.EditBase64Preference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PositionPrecisionPreference
@ -50,7 +57,6 @@ import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.proto.ChannelProtos
import org.meshtastic.proto.channelSettings
import org.meshtastic.proto.copy
import org.meshtastic.core.strings.R as Res
@Suppress("LongMethod")
@Composable

View file

@ -23,16 +23,23 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.ambient_lighting
import org.meshtastic.core.strings.ambient_lighting_config
import org.meshtastic.core.strings.blue
import org.meshtastic.core.strings.current
import org.meshtastic.core.strings.green
import org.meshtastic.core.strings.led_state
import org.meshtastic.core.strings.red
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun AmbientLightingConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -23,9 +23,19 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.audio
import org.meshtastic.core.strings.audio_config
import org.meshtastic.core.strings.codec2_sample_rate
import org.meshtastic.core.strings.codec_2_enabled
import org.meshtastic.core.strings.i2s_clock
import org.meshtastic.core.strings.i2s_data_in
import org.meshtastic.core.strings.i2s_data_out
import org.meshtastic.core.strings.i2s_word_select
import org.meshtastic.core.strings.ptt_pin
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -34,7 +44,6 @@ import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.ModuleConfigProtos.ModuleConfig.AudioConfig
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun AudioConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -23,9 +23,15 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.bluetooth
import org.meshtastic.core.strings.bluetooth_config
import org.meshtastic.core.strings.bluetooth_enabled
import org.meshtastic.core.strings.fixed_pin
import org.meshtastic.core.strings.pairing_mode
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -34,7 +40,6 @@ import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.ConfigProtos.Config.BluetoothConfig
import org.meshtastic.proto.config
import org.meshtastic.proto.copy
import org.meshtastic.core.strings.R as Res
@Composable
fun BluetoothConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -27,11 +27,26 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.allow_input_source
import org.meshtastic.core.strings.canned_message
import org.meshtastic.core.strings.canned_message_config
import org.meshtastic.core.strings.canned_message_enabled
import org.meshtastic.core.strings.generate_input_event_on_ccw
import org.meshtastic.core.strings.generate_input_event_on_cw
import org.meshtastic.core.strings.generate_input_event_on_press
import org.meshtastic.core.strings.gpio_pin_for_rotary_encoder_a_port
import org.meshtastic.core.strings.gpio_pin_for_rotary_encoder_b_port
import org.meshtastic.core.strings.gpio_pin_for_rotary_encoder_press_port
import org.meshtastic.core.strings.messages
import org.meshtastic.core.strings.rotary_encoder_1_enabled
import org.meshtastic.core.strings.send_bell
import org.meshtastic.core.strings.up_down_select_input_enabled
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -40,7 +55,6 @@ import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.ModuleConfigProtos.ModuleConfig.CannedMessageConfig
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -25,11 +25,22 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.detection_sensor
import org.meshtastic.core.strings.detection_sensor_config
import org.meshtastic.core.strings.detection_sensor_enabled
import org.meshtastic.core.strings.detection_trigger_type
import org.meshtastic.core.strings.friendly_name
import org.meshtastic.core.strings.gpio_pin_to_monitor
import org.meshtastic.core.strings.minimum_broadcast_seconds
import org.meshtastic.core.strings.send_bell_with_alert_message
import org.meshtastic.core.strings.state_broadcast_seconds
import org.meshtastic.core.strings.use_input_pullup_mode
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -41,7 +52,6 @@ import org.meshtastic.feature.settings.util.toDisplayString
import org.meshtastic.proto.ModuleConfigProtos.ModuleConfig
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -56,7 +56,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
@ -66,6 +65,51 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.accept
import org.meshtastic.core.strings.are_you_sure
import org.meshtastic.core.strings.button_gpio
import org.meshtastic.core.strings.buzzer_gpio
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.config_device_doubleTapAsButtonPress_summary
import org.meshtastic.core.strings.config_device_ledHeartbeatEnabled_summary
import org.meshtastic.core.strings.config_device_tripleClickAsAdHocPing_summary
import org.meshtastic.core.strings.config_device_tzdef_summary
import org.meshtastic.core.strings.config_device_use_phone_tz
import org.meshtastic.core.strings.device
import org.meshtastic.core.strings.double_tap_as_button_press
import org.meshtastic.core.strings.gpio
import org.meshtastic.core.strings.hardware
import org.meshtastic.core.strings.i_know_what_i_m_doing
import org.meshtastic.core.strings.led_heartbeat
import org.meshtastic.core.strings.nodeinfo_broadcast_interval
import org.meshtastic.core.strings.options
import org.meshtastic.core.strings.rebroadcast_mode
import org.meshtastic.core.strings.rebroadcast_mode_all_desc
import org.meshtastic.core.strings.rebroadcast_mode_all_skip_decoding_desc
import org.meshtastic.core.strings.rebroadcast_mode_core_portnums_only_desc
import org.meshtastic.core.strings.rebroadcast_mode_known_only_desc
import org.meshtastic.core.strings.rebroadcast_mode_local_only_desc
import org.meshtastic.core.strings.rebroadcast_mode_none_desc
import org.meshtastic.core.strings.role
import org.meshtastic.core.strings.role_client_desc
import org.meshtastic.core.strings.role_client_hidden_desc
import org.meshtastic.core.strings.role_client_mute_desc
import org.meshtastic.core.strings.role_lost_and_found_desc
import org.meshtastic.core.strings.role_repeater_desc
import org.meshtastic.core.strings.role_router_client_desc
import org.meshtastic.core.strings.role_router_desc
import org.meshtastic.core.strings.role_router_late_desc
import org.meshtastic.core.strings.role_sensor_desc
import org.meshtastic.core.strings.role_tak_desc
import org.meshtastic.core.strings.role_tak_tracker_desc
import org.meshtastic.core.strings.role_tracker_desc
import org.meshtastic.core.strings.router_role_confirmation_text
import org.meshtastic.core.strings.time_zone
import org.meshtastic.core.strings.triple_click_adhoc_ping
import org.meshtastic.core.strings.unrecognized
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.InsetDivider
@ -79,9 +123,8 @@ import org.meshtastic.proto.ConfigProtos.Config.DeviceConfig
import org.meshtastic.proto.config
import org.meshtastic.proto.copy
import java.time.ZoneId
import org.meshtastic.core.strings.R as Res
private val DeviceConfig.Role.description: Int
private val DeviceConfig.Role.description: StringResource
get() =
when (this) {
DeviceConfig.Role.CLIENT -> Res.string.role_client_desc
@ -99,7 +142,7 @@ private val DeviceConfig.Role.description: Int
else -> Res.string.unrecognized
}
private val DeviceConfig.RebroadcastMode.description: Int
private val DeviceConfig.RebroadcastMode.description: StringResource
get() =
when (this) {
DeviceConfig.RebroadcastMode.ALL -> Res.string.rebroadcast_mode_all_desc

View file

@ -22,9 +22,34 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.advanced
import org.meshtastic.core.strings.always_point_north
import org.meshtastic.core.strings.bold_heading
import org.meshtastic.core.strings.carousel_interval
import org.meshtastic.core.strings.compass_orientation
import org.meshtastic.core.strings.config_display_auto_screen_carousel_secs_summary
import org.meshtastic.core.strings.config_display_compass_north_top_summary
import org.meshtastic.core.strings.config_display_displaymode_summary
import org.meshtastic.core.strings.config_display_flip_screen_summary
import org.meshtastic.core.strings.config_display_heading_bold_summary
import org.meshtastic.core.strings.config_display_oled_summary
import org.meshtastic.core.strings.config_display_screen_on_secs_summary
import org.meshtastic.core.strings.config_display_units_summary
import org.meshtastic.core.strings.config_display_wake_on_tap_or_motion_summary
import org.meshtastic.core.strings.display
import org.meshtastic.core.strings.display_config
import org.meshtastic.core.strings.display_mode
import org.meshtastic.core.strings.display_time_in_12h_format
import org.meshtastic.core.strings.display_units
import org.meshtastic.core.strings.flip_screen
import org.meshtastic.core.strings.oled_type
import org.meshtastic.core.strings.screen_on_for
import org.meshtastic.core.strings.use_12h_format
import org.meshtastic.core.strings.wake_on_tap_or_motion
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
@ -34,7 +59,6 @@ import org.meshtastic.feature.settings.util.toDisplayString
import org.meshtastic.proto.ConfigProtos.Config.DisplayConfig
import org.meshtastic.proto.config
import org.meshtastic.proto.copy
import org.meshtastic.core.strings.R as Res
@Composable
fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -35,15 +35,17 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.protobuf.Descriptors
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.save
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.proto.ClientOnlyProtos.DeviceProfile
import org.meshtastic.core.strings.R as Res
private const val SUPPORTED_FIELDS = 7

View file

@ -28,11 +28,33 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.advanced
import org.meshtastic.core.strings.alert_bell_buzzer
import org.meshtastic.core.strings.alert_bell_led
import org.meshtastic.core.strings.alert_bell_vibra
import org.meshtastic.core.strings.alert_message_buzzer
import org.meshtastic.core.strings.alert_message_led
import org.meshtastic.core.strings.alert_message_vibra
import org.meshtastic.core.strings.external_notification
import org.meshtastic.core.strings.external_notification_config
import org.meshtastic.core.strings.external_notification_enabled
import org.meshtastic.core.strings.nag_timeout_seconds
import org.meshtastic.core.strings.notifications_on_alert_bell_receipt
import org.meshtastic.core.strings.notifications_on_message_receipt
import org.meshtastic.core.strings.output_buzzer_gpio
import org.meshtastic.core.strings.output_duration_milliseconds
import org.meshtastic.core.strings.output_led_active_high
import org.meshtastic.core.strings.output_led_gpio
import org.meshtastic.core.strings.output_vibra_gpio
import org.meshtastic.core.strings.ringtone
import org.meshtastic.core.strings.use_i2s_as_buzzer
import org.meshtastic.core.strings.use_pwm_buzzer
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -43,7 +65,6 @@ import org.meshtastic.feature.settings.util.gpioPins
import org.meshtastic.feature.settings.util.toDisplayString
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -26,12 +26,35 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.Channel
import org.meshtastic.core.model.ChannelOption
import org.meshtastic.core.model.RegionInfo
import org.meshtastic.core.model.numChannels
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.advanced
import org.meshtastic.core.strings.bandwidth
import org.meshtastic.core.strings.coding_rate
import org.meshtastic.core.strings.config_lora_frequency_slot_summary
import org.meshtastic.core.strings.config_lora_hop_limit_summary
import org.meshtastic.core.strings.config_lora_modem_preset_summary
import org.meshtastic.core.strings.config_lora_region_summary
import org.meshtastic.core.strings.frequency_slot
import org.meshtastic.core.strings.hop_limit
import org.meshtastic.core.strings.ignore_mqtt
import org.meshtastic.core.strings.lora
import org.meshtastic.core.strings.modem_preset
import org.meshtastic.core.strings.ok_to_mqtt
import org.meshtastic.core.strings.options
import org.meshtastic.core.strings.override_frequency_mhz
import org.meshtastic.core.strings.pa_fan_disabled
import org.meshtastic.core.strings.region_frequency_plan
import org.meshtastic.core.strings.spread_factor
import org.meshtastic.core.strings.sx126x_rx_boosted_gain
import org.meshtastic.core.strings.tx_enabled
import org.meshtastic.core.strings.tx_power_dbm
import org.meshtastic.core.strings.use_modem_preset
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SignedIntegerEditTextPreference
@ -41,7 +64,6 @@ import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.feature.settings.util.hopLimits
import org.meshtastic.proto.config
import org.meshtastic.proto.copy
import org.meshtastic.core.strings.R as Res
@Composable
fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {

View file

@ -26,11 +26,25 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.address
import org.meshtastic.core.strings.default_mqtt_address
import org.meshtastic.core.strings.encryption_enabled
import org.meshtastic.core.strings.json_output_enabled
import org.meshtastic.core.strings.map_reporting
import org.meshtastic.core.strings.mqtt
import org.meshtastic.core.strings.mqtt_config
import org.meshtastic.core.strings.mqtt_enabled
import org.meshtastic.core.strings.password
import org.meshtastic.core.strings.proxy_to_client_enabled
import org.meshtastic.core.strings.root_topic
import org.meshtastic.core.strings.tls_enabled
import org.meshtastic.core.strings.username
import org.meshtastic.core.ui.component.EditPasswordPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -38,7 +52,6 @@ import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -34,19 +34,26 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.util.DistanceUnit
import org.meshtastic.core.model.util.toDistanceString
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.i_agree
import org.meshtastic.core.strings.i_agree_to_share_my_location
import org.meshtastic.core.strings.map_reporting
import org.meshtastic.core.strings.map_reporting_consent_header
import org.meshtastic.core.strings.map_reporting_consent_text
import org.meshtastic.core.strings.map_reporting_interval_seconds
import org.meshtastic.core.strings.map_reporting_summary
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.precisionBitsToMeters
import org.meshtastic.feature.settings.util.IntervalConfiguration
import org.meshtastic.feature.settings.util.toDisplayString
import kotlin.math.roundToInt
import org.meshtastic.core.strings.R as Res
private const val POSITION_PRECISION_MIN = 12
private const val POSITION_PRECISION_MAX = 15

View file

@ -23,16 +23,22 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.config_device_transmitOverLora_summary
import org.meshtastic.core.strings.neighbor_info
import org.meshtastic.core.strings.neighbor_info_config
import org.meshtastic.core.strings.neighbor_info_enabled
import org.meshtastic.core.strings.transmit_over_lora
import org.meshtastic.core.strings.update_interval_seconds
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun NeighborInfoConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -34,7 +34,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
@ -42,6 +41,33 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanOptions
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.advanced
import org.meshtastic.core.strings.config_network_eth_enabled_summary
import org.meshtastic.core.strings.config_network_udp_enabled_summary
import org.meshtastic.core.strings.config_network_wifi_enabled_summary
import org.meshtastic.core.strings.connection_status
import org.meshtastic.core.strings.error
import org.meshtastic.core.strings.ethernet_config
import org.meshtastic.core.strings.ethernet_enabled
import org.meshtastic.core.strings.ethernet_ip
import org.meshtastic.core.strings.gateway
import org.meshtastic.core.strings.ip
import org.meshtastic.core.strings.ipv4_mode
import org.meshtastic.core.strings.network
import org.meshtastic.core.strings.ntp_server
import org.meshtastic.core.strings.password
import org.meshtastic.core.strings.rsyslog_server
import org.meshtastic.core.strings.ssid
import org.meshtastic.core.strings.subnet
import org.meshtastic.core.strings.udp_config
import org.meshtastic.core.strings.udp_enabled
import org.meshtastic.core.strings.wifi_config
import org.meshtastic.core.strings.wifi_enabled
import org.meshtastic.core.strings.wifi_ip
import org.meshtastic.core.strings.wifi_qr_code_error
import org.meshtastic.core.strings.wifi_qr_code_scan
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditIPv4Preference
import org.meshtastic.core.ui.component.EditPasswordPreference
@ -54,7 +80,6 @@ import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.ConfigProtos.Config.NetworkConfig
import org.meshtastic.proto.config
import org.meshtastic.proto.copy
import org.meshtastic.core.strings.R as Res
@Composable
private fun ScanErrorDialog(onDismiss: () -> Unit = {}) =

View file

@ -33,11 +33,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.close
import org.meshtastic.core.strings.delivery_confirmed
import org.meshtastic.core.strings.error
import org.meshtastic.feature.settings.radio.ResponseState
import org.meshtastic.core.strings.R as Res
@Composable
fun <T> PacketResponseStateDialog(state: ResponseState<T>, onDismiss: () -> Unit = {}, onComplete: () -> Unit = {}) {

View file

@ -24,9 +24,16 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.ble_rssi_threshold_defaults_to_80
import org.meshtastic.core.strings.paxcounter
import org.meshtastic.core.strings.paxcounter_config
import org.meshtastic.core.strings.paxcounter_enabled
import org.meshtastic.core.strings.update_interval_seconds
import org.meshtastic.core.strings.wifi_rssi_threshold_defaults_to_80
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.SignedIntegerEditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -36,7 +43,6 @@ import org.meshtastic.feature.settings.util.IntervalConfiguration
import org.meshtastic.feature.settings.util.toDisplayString
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun PaxcounterConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -35,14 +35,39 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.core.location.LocationCompat
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberPermissionState
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.Position
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.advanced_device_gps
import org.meshtastic.core.strings.altitude
import org.meshtastic.core.strings.broadcast_interval
import org.meshtastic.core.strings.config_position_broadcast_secs_summary
import org.meshtastic.core.strings.config_position_broadcast_smart_minimum_distance_summary
import org.meshtastic.core.strings.config_position_broadcast_smart_minimum_interval_secs_summary
import org.meshtastic.core.strings.config_position_flags_summary
import org.meshtastic.core.strings.config_position_gps_update_interval_summary
import org.meshtastic.core.strings.device_gps
import org.meshtastic.core.strings.fixed_position
import org.meshtastic.core.strings.gps_en_gpio
import org.meshtastic.core.strings.gps_mode
import org.meshtastic.core.strings.gps_receive_gpio
import org.meshtastic.core.strings.gps_transmit_gpio
import org.meshtastic.core.strings.latitude
import org.meshtastic.core.strings.longitude
import org.meshtastic.core.strings.minimum_distance
import org.meshtastic.core.strings.minimum_interval
import org.meshtastic.core.strings.position
import org.meshtastic.core.strings.position_config_set_fixed_from_phone
import org.meshtastic.core.strings.position_flags
import org.meshtastic.core.strings.position_packet
import org.meshtastic.core.strings.smart_position
import org.meshtastic.core.strings.update_interval
import org.meshtastic.core.ui.component.BitwisePreference
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
@ -56,7 +81,6 @@ import org.meshtastic.feature.settings.util.toDisplayString
import org.meshtastic.proto.ConfigProtos.Config.PositionConfig
import org.meshtastic.proto.config
import org.meshtastic.proto.copy
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalPermissionsApi::class)
@Composable

View file

@ -24,9 +24,21 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.adc_multiplier_override
import org.meshtastic.core.strings.adc_multiplier_override_ratio
import org.meshtastic.core.strings.battery_ina_2xx_i2c_address
import org.meshtastic.core.strings.config_power_is_power_saving_summary
import org.meshtastic.core.strings.enable_power_saving_mode
import org.meshtastic.core.strings.minimum_wake_time_seconds
import org.meshtastic.core.strings.power
import org.meshtastic.core.strings.power_config
import org.meshtastic.core.strings.shutdown_on_power_loss
import org.meshtastic.core.strings.super_deep_sleep_duration_seconds
import org.meshtastic.core.strings.wait_for_bluetooth_duration_seconds
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -36,7 +48,6 @@ import org.meshtastic.feature.settings.util.IntervalConfiguration
import org.meshtastic.feature.settings.util.toDisplayString
import org.meshtastic.proto.config
import org.meshtastic.proto.copy
import org.meshtastic.core.strings.R as Res
@Composable
fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -38,13 +38,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.google.protobuf.MessageLite
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.discard_changes
import org.meshtastic.core.strings.save_changes
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.PreferenceFooter
import org.meshtastic.feature.settings.radio.ResponseState
import org.meshtastic.core.strings.R as Res
@Composable
fun <T : MessageLite> RadioConfigScreenList(

View file

@ -22,9 +22,15 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.range_test
import org.meshtastic.core.strings.range_test_config
import org.meshtastic.core.strings.range_test_enabled
import org.meshtastic.core.strings.save_csv_in_storage_esp32_only
import org.meshtastic.core.strings.sender_message_interval_seconds
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
@ -33,7 +39,6 @@ import org.meshtastic.feature.settings.util.IntervalConfiguration
import org.meshtastic.feature.settings.util.toDisplayString
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun RangeTestConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -23,16 +23,21 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.allow_undefined_pin_access
import org.meshtastic.core.strings.available_pins
import org.meshtastic.core.strings.remote_hardware
import org.meshtastic.core.strings.remote_hardware_config
import org.meshtastic.core.strings.remote_hardware_enabled
import org.meshtastic.core.ui.component.EditListPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun RemoteHardwareConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -39,13 +39,38 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.protobuf.ByteString
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.util.encodeToString
import org.meshtastic.core.model.util.toByteString
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.admin_key
import org.meshtastic.core.strings.admin_keys
import org.meshtastic.core.strings.administration
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.config_security_admin_key
import org.meshtastic.core.strings.config_security_debug_log_api_enabled
import org.meshtastic.core.strings.config_security_is_managed
import org.meshtastic.core.strings.config_security_private_key
import org.meshtastic.core.strings.config_security_public_key
import org.meshtastic.core.strings.config_security_serial_enabled
import org.meshtastic.core.strings.debug_log_api_enabled
import org.meshtastic.core.strings.direct_message_key
import org.meshtastic.core.strings.export_keys
import org.meshtastic.core.strings.export_keys_confirmation
import org.meshtastic.core.strings.legacy_admin_channel
import org.meshtastic.core.strings.logs
import org.meshtastic.core.strings.managed_mode
import org.meshtastic.core.strings.okay
import org.meshtastic.core.strings.private_key
import org.meshtastic.core.strings.public_key
import org.meshtastic.core.strings.regenerate_keys_confirmation
import org.meshtastic.core.strings.regenerate_private_key
import org.meshtastic.core.strings.security
import org.meshtastic.core.strings.serial_console
import org.meshtastic.core.ui.component.CopyIconButton
import org.meshtastic.core.ui.component.EditBase64Preference
import org.meshtastic.core.ui.component.EditListPreference
@ -56,7 +81,6 @@ import org.meshtastic.proto.ConfigProtos.Config.SecurityConfig
import org.meshtastic.proto.config
import org.meshtastic.proto.copy
import java.security.SecureRandom
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable

View file

@ -23,9 +23,18 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.echo_enabled
import org.meshtastic.core.strings.override_console_serial_port
import org.meshtastic.core.strings.serial
import org.meshtastic.core.strings.serial_baud_rate
import org.meshtastic.core.strings.serial_config
import org.meshtastic.core.strings.serial_enabled
import org.meshtastic.core.strings.serial_mode
import org.meshtastic.core.strings.timeout
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -34,7 +43,6 @@ import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.ModuleConfigProtos.ModuleConfig.SerialConfig
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun SerialConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -23,16 +23,24 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.heartbeat
import org.meshtastic.core.strings.history_return_max
import org.meshtastic.core.strings.history_return_window
import org.meshtastic.core.strings.number_of_records
import org.meshtastic.core.strings.server
import org.meshtastic.core.strings.store_forward
import org.meshtastic.core.strings.store_forward_config
import org.meshtastic.core.strings.store_forward_enabled
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
@Composable
fun StoreForwardConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -22,10 +22,25 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.air_quality_metrics_module_enabled
import org.meshtastic.core.strings.air_quality_metrics_update_interval_seconds
import org.meshtastic.core.strings.device_metrics_update_interval_seconds
import org.meshtastic.core.strings.device_telemetry_enabled
import org.meshtastic.core.strings.device_telemetry_enabled_summary
import org.meshtastic.core.strings.environment_metrics_module_enabled
import org.meshtastic.core.strings.environment_metrics_on_screen_enabled
import org.meshtastic.core.strings.environment_metrics_update_interval_seconds
import org.meshtastic.core.strings.environment_metrics_use_fahrenheit
import org.meshtastic.core.strings.power_metrics_module_enabled
import org.meshtastic.core.strings.power_metrics_on_screen_enabled
import org.meshtastic.core.strings.power_metrics_update_interval_seconds
import org.meshtastic.core.strings.telemetry
import org.meshtastic.core.strings.telemetry_config
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
@ -34,7 +49,6 @@ import org.meshtastic.feature.settings.util.IntervalConfiguration
import org.meshtastic.feature.settings.util.toDisplayString
import org.meshtastic.proto.copy
import org.meshtastic.proto.moduleConfig
import org.meshtastic.core.strings.R as Res
private const val MIN_FW_FOR_TELEMETRY_TOGGLE = "2.7.12"

View file

@ -24,20 +24,30 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.isUnmessageableRole
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.hardware_model
import org.meshtastic.core.strings.licensed_amateur_radio
import org.meshtastic.core.strings.licensed_amateur_radio_text
import org.meshtastic.core.strings.long_name
import org.meshtastic.core.strings.node_id
import org.meshtastic.core.strings.short_name
import org.meshtastic.core.strings.unmessageable
import org.meshtastic.core.strings.unmonitored_or_infrastructure
import org.meshtastic.core.strings.user
import org.meshtastic.core.strings.user_config
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.RegularPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import org.meshtastic.proto.copy
import org.meshtastic.core.strings.R as Res
@Composable
fun UserConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {

View file

@ -26,10 +26,12 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.send
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
@Composable
fun WarningDialog(

View file

@ -18,8 +18,9 @@
package org.meshtastic.feature.settings.util
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import org.meshtastic.core.strings.R as Res
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.unset
@Composable
fun FixedUpdateIntervals.toDisplayString(): String = if (this == FixedUpdateIntervals.UNSET) {

View file

@ -20,10 +20,16 @@ package org.meshtastic.feature.settings.util
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import com.meshtastic.core.strings.getString
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.fr_HT
import org.meshtastic.core.strings.preferences_system_default
import org.meshtastic.core.strings.pt_BR
import org.meshtastic.core.strings.zh_CN
import org.meshtastic.core.strings.zh_TW
import org.xmlpull.v1.XmlPullParser
import timber.log.Timber
import java.util.Locale
import org.meshtastic.core.strings.R as Res
object LanguageUtils {

View file

@ -17,15 +17,14 @@
package org.meshtastic.feature.settings.util
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import org.jetbrains.compose.resources.stringResource
@Suppress("SpreadOperator")
sealed class UiText {
data class DynamicString(val value: String) : UiText()
class StringResource(@StringRes val resId: Int, vararg val args: Any) : UiText()
class StringResource(val resId: org.jetbrains.compose.resources.StringResource, vararg val args: Any) : UiText()
@Composable
fun asString(): String = when (this) {

View file

@ -18,42 +18,42 @@
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en"/>
<locale android:name="ar-SA"/>
<locale android:name="sr-Latn"/>
<locale android:name="bg-BG"/>
<locale android:name="ca-ES"/>
<locale android:name="cs-CZ"/>
<locale android:name="de-DE"/>
<locale android:name="el-GR"/>
<locale android:name="es-ES"/>
<locale android:name="et-EE"/>
<locale android:name="fi-FI"/>
<locale android:name="fr-FR"/>
<locale android:name="ga-IE"/>
<locale android:name="gl-ES"/>
<locale android:name="hr-HR"/>
<locale android:name="ht-HT"/>
<locale android:name="hu-HU"/>
<locale android:name="is-IS"/>
<locale android:name="it-IT"/>
<locale android:name="iw-IL"/>
<locale android:name="ja-JP"/>
<locale android:name="ko-KR"/>
<locale android:name="lt-LT"/>
<locale android:name="nl-NL"/>
<locale android:name="nb-NO"/>
<locale android:name="pl-PL"/>
<locale android:name="ar"/>
<locale android:name="bg"/>
<locale android:name="ca"/>
<locale android:name="cs"/>
<locale android:name="de"/>
<locale android:name="el"/>
<locale android:name="es"/>
<locale android:name="et"/>
<locale android:name="fi"/>
<locale android:name="fr"/>
<locale android:name="ga"/>
<locale android:name="gl"/>
<locale android:name="hr"/>
<locale android:name="ht"/>
<locale android:name="hu"/>
<locale android:name="is"/>
<locale android:name="it"/>
<locale android:name="iw"/>
<locale android:name="ja"/>
<locale android:name="ko"/>
<locale android:name="lt"/>
<locale android:name="nl"/>
<locale android:name="nb"/>
<locale android:name="pl"/>
<locale android:name="pt"/>
<locale android:name="pt-BR"/>
<locale android:name="pt-PT"/>
<locale android:name="ro-RO"/>
<locale android:name="ru-RU"/>
<locale android:name="sk-SK"/>
<locale android:name="sl-SI"/>
<locale android:name="sq-AL"/>
<locale android:name="ro"/>
<locale android:name="ru"/>
<locale android:name="sk"/>
<locale android:name="sl"/>
<locale android:name="sq"/>
<locale android:name="sr"/>
<locale android:name="sv-SE"/>
<locale android:name="tr-TR"/>
<locale android:name="uk-UA"/>
<locale android:name="srp"/>
<locale android:name="sv"/>
<locale android:name="tr"/>
<locale android:name="uk"/>
<locale android:name="zh-CN"/>
<locale android:name="zh-TW"/>
</locale-config>