Alias strings R to Res (#3619)

This commit is contained in:
Phil Oliver 2025-11-04 22:32:42 -05:00 committed by GitHub
parent a687328f08
commit 0833a6767e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
153 changed files with 1403 additions and 1350 deletions

View file

@ -36,8 +36,8 @@ import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.meshtastic.core.strings.R
import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog
import org.meshtastic.core.strings.R as Res
@RunWith(AndroidJUnit4::class)
class DebugFiltersTest {
@ -47,7 +47,7 @@ class DebugFiltersTest {
@Test
fun debugFilterBar_showsFilterButtonAndMenu() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val filterLabel = context.getString(R.string.debug_filters)
val filterLabel = context.getString(Res.string.debug_filters)
composeTestRule.setContent {
var filterTexts by remember { mutableStateOf(listOf<String>()) }
var customFilterText by remember { mutableStateOf("") }
@ -77,7 +77,7 @@ class DebugFiltersTest {
@Test
fun debugFilterBar_addCustomFilter_displaysActiveFilter() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val activeFiltersLabel = context.getString(R.string.debug_active_filters)
val activeFiltersLabel = context.getString(Res.string.debug_active_filters)
composeTestRule.setContent {
var filterTexts by remember { mutableStateOf(listOf<String>()) }
var customFilterText by remember { mutableStateOf("") }
@ -109,7 +109,7 @@ class DebugFiltersTest {
@Test
fun debugActiveFilters_clearAllFilters_removesFilters() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val activeFiltersLabel = context.getString(R.string.debug_active_filters)
val activeFiltersLabel = context.getString(Res.string.debug_active_filters)
composeTestRule.setContent {
var filterTexts by remember { mutableStateOf(listOf("A", "B")) }
DebugActiveFilters(

View file

@ -36,10 +36,10 @@ import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.meshtastic.core.strings.R
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
@RunWith(AndroidJUnit4::class)
class DebugSearchTest {
@ -49,7 +49,7 @@ class DebugSearchTest {
@Test
fun debugSearchBar_showsPlaceholder() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val placeholder = context.getString(R.string.debug_default_search)
val placeholder = context.getString(Res.string.debug_default_search)
composeTestRule.setContent {
DebugSearchBar(
searchState = SearchState(),
@ -65,7 +65,7 @@ class DebugSearchTest {
@Test
fun debugSearchBar_showsClearButtonWhenTextEntered() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val placeholder = context.getString(R.string.debug_default_search)
val placeholder = context.getString(Res.string.debug_default_search)
composeTestRule.setContent {
var searchText by remember { mutableStateOf("test") }
DebugSearchBar(
@ -113,7 +113,7 @@ class DebugSearchTest {
@Test
fun debugFilterBar_showsFilterButtonAndMenu() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val filterLabel = context.getString(R.string.debug_filters)
val filterLabel = context.getString(Res.string.debug_filters)
composeTestRule.setContent {
var filterTexts by remember { mutableStateOf(listOf<String>()) }
var customFilterText by remember { mutableStateOf("") }
@ -143,7 +143,7 @@ class DebugSearchTest {
@Test
fun debugFilterBar_addCustomFilter_displaysActiveFilter() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val activeFiltersLabel = context.getString(R.string.debug_active_filters)
val activeFiltersLabel = context.getString(Res.string.debug_active_filters)
composeTestRule.setContent {
var filterTexts by remember { mutableStateOf(listOf<String>()) }
var customFilterText by remember { mutableStateOf("") }
@ -173,7 +173,7 @@ class DebugSearchTest {
@Test
fun debugActiveFilters_clearAllFilters_removesFilters() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val activeFiltersLabel = context.getString(R.string.debug_active_filters)
val activeFiltersLabel = context.getString(Res.string.debug_active_filters)
composeTestRule.setContent {
var filterTexts by remember { mutableStateOf(listOf("A", "B")) }
DebugActiveFilters(

View file

@ -27,10 +27,10 @@ import org.junit.Assert
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.meshtastic.core.strings.R
import org.meshtastic.proto.ClientOnlyProtos.DeviceProfile
import org.meshtastic.proto.deviceProfile
import org.meshtastic.proto.position
import org.meshtastic.core.strings.R as Res
@RunWith(AndroidJUnit4::class)
class EditDeviceProfileDialogTest {
@ -77,8 +77,8 @@ class EditDeviceProfileDialogTest {
testEditDeviceProfileDialog()
// Verify the "Cancel" and "Save" buttons are displayed
onNodeWithText(getString(R.string.cancel)).assertIsDisplayed()
onNodeWithText(getString(R.string.save)).assertIsDisplayed()
onNodeWithText(getString(Res.string.cancel)).assertIsDisplayed()
onNodeWithText(getString(Res.string.save)).assertIsDisplayed()
}
}
@ -89,7 +89,7 @@ class EditDeviceProfileDialogTest {
testEditDeviceProfileDialog(onDismiss = { onDismissClicked = true })
// Click the "Cancel" button
onNodeWithText(getString(R.string.cancel)).performClick()
onNodeWithText(getString(Res.string.cancel)).performClick()
}
// Verify onDismiss is called
@ -102,7 +102,7 @@ class EditDeviceProfileDialogTest {
composeTestRule.apply {
testEditDeviceProfileDialog(onConfirm = { actualDeviceProfile = it })
onNodeWithText(getString(R.string.save)).performClick()
onNodeWithText(getString(Res.string.save)).performClick()
}
// Verify onConfirm is called with the correct DeviceProfile

View file

@ -29,7 +29,7 @@ import org.junit.Assert
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.meshtastic.core.strings.R
import org.meshtastic.core.strings.R as Res
@RunWith(AndroidJUnit4::class)
class MapReportingPreferenceTest {
@ -69,8 +69,8 @@ class MapReportingPreferenceTest {
composeTestRule.apply {
testMapReportingPreference()
// Verify that the dialog title is displayed
onNodeWithText(getString(R.string.map_reporting)).assertIsDisplayed()
onNodeWithText(getString(R.string.map_reporting_summary)).assertIsDisplayed()
onNodeWithText(getString(Res.string.map_reporting)).assertIsDisplayed()
onNodeWithText(getString(Res.string.map_reporting_summary)).assertIsDisplayed()
}
}
@ -78,16 +78,16 @@ class MapReportingPreferenceTest {
fun testMapReportingPreference_toggleMapReporting() {
composeTestRule.apply {
testMapReportingPreference()
onNodeWithText(getString(R.string.i_agree)).assertIsNotDisplayed()
onNodeWithText(getString(R.string.map_reporting)).performClick()
onNodeWithText(getString(Res.string.i_agree)).assertIsNotDisplayed()
onNodeWithText(getString(Res.string.map_reporting)).performClick()
Assert.assertFalse(mapReportingEnabled)
Assert.assertFalse(shouldReportLocation)
onNodeWithText(getString(R.string.i_agree)).assertIsDisplayed()
onNodeWithText(getString(R.string.i_agree)).performClick()
onNodeWithText(getString(Res.string.i_agree)).assertIsDisplayed()
onNodeWithText(getString(Res.string.i_agree)).performClick()
Assert.assertTrue(shouldReportLocation)
Assert.assertTrue(mapReportingEnabled)
onNodeWithText(getString(R.string.map_reporting)).performClick()
onNodeWithText(getString(R.string.i_agree)).assertIsNotDisplayed()
onNodeWithText(getString(Res.string.map_reporting)).performClick()
onNodeWithText(getString(Res.string.i_agree)).assertIsNotDisplayed()
Assert.assertTrue(shouldReportLocation)
Assert.assertFalse(mapReportingEnabled)
}

View file

@ -64,7 +64,6 @@ import com.google.accompanist.permissions.rememberMultiplePermissionsState
import kotlinx.coroutines.delay
import org.meshtastic.core.common.gpsDisabled
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.MultipleChoiceAlertDialog
@ -83,6 +82,7 @@ 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")
@ -139,9 +139,9 @@ fun SettingsScreen(
EditDeviceProfileDialog(
title =
if (deviceProfile != null) {
stringResource(R.string.import_configuration)
stringResource(Res.string.import_configuration)
} else {
stringResource(R.string.export_configuration)
stringResource(Res.string.export_configuration)
},
deviceProfile = deviceProfile ?: viewModel.currentDeviceProfile,
onConfirm = {
@ -186,13 +186,13 @@ fun SettingsScreen(
Scaffold(
topBar = {
MainAppBar(
title = stringResource(R.string.bottom_nav_settings),
title = stringResource(Res.string.bottom_nav_settings),
subtitle =
if (state.isLocal) {
ourNode?.user?.longName
} else {
val remoteName = viewModel.destNode.value?.user?.longName ?: ""
stringResource(R.string.remotely_administrating, remoteName)
stringResource(Res.string.remotely_administrating, remoteName)
},
ourNode = ourNode,
showNodeChip = ourNode != null && isConnected && state.isLocal,
@ -233,11 +233,11 @@ fun SettingsScreen(
val context = LocalContext.current
val resources = LocalResources.current
TitledCard(title = stringResource(R.string.app_settings), modifier = Modifier.padding(top = 16.dp)) {
TitledCard(title = stringResource(Res.string.app_settings), modifier = Modifier.padding(top = 16.dp)) {
if (state.analyticsAvailable) {
val allowed by viewModel.analyticsAllowedFlow.collectAsStateWithLifecycle(false)
SwitchListItem(
text = stringResource(R.string.analytics_okay),
text = stringResource(Res.string.analytics_okay),
checked = allowed,
leadingIcon = Icons.Default.BugReport,
onClick = { viewModel.toggleAnalyticsAllowed() },
@ -257,7 +257,7 @@ fun SettingsScreen(
} else {
Toast.makeText(
context,
resources.getString(R.string.location_disabled),
resources.getString(Res.string.location_disabled),
Toast.LENGTH_LONG,
)
.show()
@ -272,7 +272,7 @@ fun SettingsScreen(
}
SwitchListItem(
text = stringResource(R.string.provide_location_to_mesh),
text = stringResource(Res.string.provide_location_to_mesh),
leadingIcon = Icons.Rounded.LocationOn,
enabled = !isGpsDisabled,
checked = provideLocation,
@ -286,7 +286,7 @@ fun SettingsScreen(
// picker for these devices.
val useInAppLangPicker = Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU
ListItem(
text = stringResource(R.string.preferences_language),
text = stringResource(Res.string.preferences_language),
leadingIcon = Icons.Rounded.Language,
trailingIcon = if (useInAppLangPicker) null else Icons.AutoMirrored.Rounded.KeyboardArrowRight,
) {
@ -304,7 +304,7 @@ fun SettingsScreen(
}
ListItem(
text = stringResource(R.string.theme),
text = stringResource(Res.string.theme),
leadingIcon = Icons.Rounded.FormatPaint,
trailingIcon = null,
) {
@ -320,7 +320,7 @@ fun SettingsScreen(
}
}
ListItem(
text = stringResource(R.string.save_rangetest),
text = stringResource(Res.string.save_rangetest),
leadingIcon = Icons.Rounded.Output,
trailingIcon = null,
) {
@ -340,7 +340,7 @@ fun SettingsScreen(
}
}
ListItem(
text = stringResource(R.string.export_data_csv),
text = stringResource(Res.string.export_data_csv),
leadingIcon = Icons.Rounded.Output,
trailingIcon = null,
) {
@ -354,7 +354,7 @@ fun SettingsScreen(
}
ListItem(
text = stringResource(R.string.intro_show),
text = stringResource(Res.string.intro_show),
leadingIcon = Icons.Rounded.WavingHand,
trailingIcon = null,
) {
@ -362,7 +362,7 @@ fun SettingsScreen(
}
ListItem(
text = stringResource(R.string.system_settings),
text = stringResource(Res.string.system_settings),
leadingIcon = Icons.Rounded.AppSettingsAlt,
trailingIcon = null,
) {
@ -405,7 +405,7 @@ private fun AppVersionButton(
}
ListItem(
text = stringResource(R.string.app_version),
text = stringResource(Res.string.app_version),
leadingIcon = Icons.Rounded.Memory,
supportingText = appVersionName,
trailingIcon = null,
@ -415,14 +415,14 @@ private fun AppVersionButton(
when {
clickCount == UNLOCKED_CLICK_COUNT && excludedModulesUnlocked -> {
clickCount = 0
Toast.makeText(context, resources.getString(R.string.modules_already_unlocked), Toast.LENGTH_LONG)
Toast.makeText(context, resources.getString(Res.string.modules_already_unlocked), Toast.LENGTH_LONG)
.show()
}
clickCount == UNLOCK_CLICK_COUNT -> {
clickCount = 0
onUnlockExcludedModules()
Toast.makeText(context, resources.getString(R.string.modules_unlocked), Toast.LENGTH_LONG).show()
Toast.makeText(context, resources.getString(Res.string.modules_unlocked), Toast.LENGTH_LONG).show()
}
}
}
@ -439,7 +439,7 @@ private fun LanguagePickerDialog(onDismiss: () -> Unit) {
}
MultipleChoiceAlertDialog(
title = stringResource(R.string.preferences_language),
title = stringResource(Res.string.preferences_language),
message = "",
choices = choices,
onDismissRequest = onDismiss,
@ -451,16 +451,16 @@ private fun ThemePickerDialog(onClickTheme: (Int) -> Unit, onDismiss: () -> Unit
val resources = LocalResources.current
val themeMap = remember {
mapOf(
resources.getString(R.string.dynamic) to MODE_DYNAMIC,
resources.getString(R.string.theme_light) to AppCompatDelegate.MODE_NIGHT_NO,
resources.getString(R.string.theme_dark) to AppCompatDelegate.MODE_NIGHT_YES,
resources.getString(R.string.theme_system) to AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
resources.getString(Res.string.dynamic) to MODE_DYNAMIC,
resources.getString(Res.string.theme_light) to AppCompatDelegate.MODE_NIGHT_NO,
resources.getString(Res.string.theme_dark) to AppCompatDelegate.MODE_NIGHT_YES,
resources.getString(Res.string.theme_system) to AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
)
.mapValues { (_, value) -> { onClickTheme(value) } }
}
MultipleChoiceAlertDialog(
title = stringResource(R.string.choose_theme),
title = stringResource(Res.string.choose_theme),
message = "",
choices = themeMap,
onDismissRequest = onDismiss,

View file

@ -81,7 +81,6 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.CopyIconButton
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.SimpleAlertDialog
@ -95,6 +94,7 @@ 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)
@ -147,7 +147,7 @@ fun DebugScreen(onNavigateUp: () -> Unit, viewModel: DebugViewModel = hiltViewMo
Scaffold(
topBar = {
MainAppBar(
title = stringResource(R.string.debug_panel),
title = stringResource(Res.string.debug_panel),
ourNode = null,
showNodeChip = false,
canNavigateUp = true,
@ -349,12 +349,12 @@ fun DebugMenuActions(deleteLogs: () -> Unit, modifier: Modifier = Modifier) {
var showDeleteLogsDialog by remember { mutableStateOf(false) }
IconButton(onClick = { showDeleteLogsDialog = true }, modifier = modifier.padding(4.dp)) {
Icon(imageVector = Icons.Default.Delete, contentDescription = stringResource(R.string.debug_clear))
Icon(imageVector = Icons.Default.Delete, contentDescription = stringResource(Res.string.debug_clear))
}
if (showDeleteLogsDialog) {
SimpleAlertDialog(
title = R.string.debug_clear,
text = R.string.debug_clear_logs_confirm,
title = Res.string.debug_clear,
text = Res.string.debug_clear_logs_confirm,
onConfirm = {
showDeleteLogsDialog = false
deleteLogs()
@ -397,14 +397,18 @@ private suspend fun exportAllLogsToUri(context: Context, targetUri: Uri, logs: L
} ?: run { throw IOException("Unable to open output stream for URI: $targetUri") }
withContext(Dispatchers.Main) {
Toast.makeText(context, context.getString(R.string.debug_export_success, logs.size), Toast.LENGTH_LONG)
Toast.makeText(
context,
context.getString(Res.string.debug_export_success, logs.size),
Toast.LENGTH_LONG,
)
.show()
}
} catch (e: IOException) {
withContext(Dispatchers.Main) {
Toast.makeText(
context,
context.getString(R.string.debug_export_failed, e.message ?: ""),
context.getString(Res.string.debug_export_failed, e.message ?: ""),
Toast.LENGTH_LONG,
)
.show()
@ -426,7 +430,7 @@ private fun DecodedPayloadBlock(
Column(modifier = modifier) {
Text(
text = stringResource(R.string.debug_decoded_payload),
text = stringResource(Res.string.debug_decoded_payload),
style = commonTextStyle,
modifier = Modifier.padding(top = 8.dp, bottom = 4.dp),
)
@ -595,11 +599,11 @@ private fun DebugMenuActionsPreview() {
IconButton(onClick = { /* Preview only */ }, modifier = Modifier.padding(4.dp)) {
Icon(
imageVector = Icons.Outlined.FileDownload,
contentDescription = stringResource(R.string.debug_logs_export),
contentDescription = stringResource(Res.string.debug_logs_export),
)
}
IconButton(onClick = { /* Preview only */ }, modifier = Modifier.padding(4.dp)) {
Icon(imageVector = Icons.Default.Delete, contentDescription = stringResource(R.string.debug_clear))
Icon(imageVector = Icons.Default.Delete, contentDescription = stringResource(Res.string.debug_clear))
}
}
}
@ -637,7 +641,7 @@ private fun DebugScreenEmptyPreview() {
Text(text = "Filters", style = TextStyle(fontWeight = FontWeight.Bold))
Icon(
imageVector = Icons.TwoTone.FilterAltOff,
contentDescription = stringResource(R.string.debug_filters),
contentDescription = stringResource(Res.string.debug_filters),
)
}
}

View file

@ -56,8 +56,8 @@ 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.meshtastic.core.strings.R
import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog
import org.meshtastic.core.strings.R as Res
@Composable
fun DebugCustomFilterInput(
@ -95,7 +95,7 @@ fun DebugCustomFilterInput(
},
enabled = customFilterText.isNotBlank(),
) {
Icon(imageVector = Icons.Default.Add, contentDescription = stringResource(R.string.debug_filter_add))
Icon(imageVector = Icons.Default.Add, contentDescription = stringResource(Res.string.debug_filter_add))
}
}
}
@ -144,7 +144,7 @@ internal fun DebugPresetFilters(
if (filter in filterTexts) {
Icon(
imageVector = Icons.Filled.Done,
contentDescription = stringResource(R.string.debug_filter_included),
contentDescription = stringResource(Res.string.debug_filter_included),
)
}
},
@ -173,7 +173,10 @@ internal fun DebugFilterBar(
Box {
TextButton(onClick = { showFilterMenu = !showFilterMenu }) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(text = stringResource(R.string.debug_filters), style = TextStyle(fontWeight = FontWeight.Bold))
Text(
text = stringResource(Res.string.debug_filters),
style = TextStyle(fontWeight = FontWeight.Bold),
)
Icon(
imageVector =
if (filterTexts.isNotEmpty()) {
@ -181,7 +184,7 @@ internal fun DebugFilterBar(
} else {
Icons.TwoTone.FilterAltOff
},
contentDescription = stringResource(R.string.debug_filters),
contentDescription = stringResource(Res.string.debug_filters),
)
}
}
@ -231,7 +234,7 @@ internal fun DebugActiveFilters(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = stringResource(R.string.debug_active_filters),
text = stringResource(Res.string.debug_active_filters),
style = TextStyle(fontWeight = FontWeight.Bold),
)
TextButton(
@ -247,16 +250,16 @@ internal fun DebugActiveFilters(
) {
Text(
if (filterMode == FilterMode.OR) {
stringResource(R.string.match_any)
stringResource(Res.string.match_any)
} else {
stringResource(R.string.match_all)
stringResource(Res.string.match_all)
},
)
}
IconButton(onClick = { onFilterTextsChange(emptyList()) }) {
Icon(
imageVector = Icons.Default.Clear,
contentDescription = stringResource(R.string.debug_filter_clear),
contentDescription = stringResource(Res.string.debug_filter_clear),
)
}
}

View file

@ -53,11 +53,11 @@ 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.meshtastic.core.strings.R
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(
@ -79,14 +79,14 @@ internal fun DebugSearchNavigation(
IconButton(onClick = onPreviousMatch, enabled = searchState.hasMatches, modifier = Modifier.size(32.dp)) {
Icon(
imageVector = Icons.Default.KeyboardArrowUp,
contentDescription = stringResource(R.string.debug_search_prev),
contentDescription = stringResource(Res.string.debug_search_prev),
modifier = Modifier.size(16.dp),
)
}
IconButton(onClick = onNextMatch, enabled = searchState.hasMatches, modifier = Modifier.size(32.dp)) {
Icon(
imageVector = Icons.Default.KeyboardArrowDown,
contentDescription = stringResource(R.string.debug_search_next),
contentDescription = stringResource(Res.string.debug_search_next),
modifier = Modifier.size(16.dp),
)
}
@ -106,7 +106,7 @@ internal fun DebugSearchBar(
value = searchState.searchText,
onValueChange = onSearchTextChange,
modifier = modifier.then(Modifier.padding(end = 8.dp)),
placeholder = { Text(stringResource(R.string.debug_default_search)) },
placeholder = { Text(stringResource(Res.string.debug_default_search)) },
singleLine = true,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
keyboardActions =
@ -132,7 +132,7 @@ internal fun DebugSearchBar(
IconButton(onClick = onClearSearch, modifier = Modifier.size(32.dp)) {
Icon(
imageVector = Icons.Default.Clear,
contentDescription = stringResource(R.string.debug_search_clear),
contentDescription = stringResource(Res.string.debug_search_clear),
modifier = Modifier.size(16.dp),
)
}
@ -188,7 +188,7 @@ internal fun DebugSearchState(
IconButton(onClick = onExport, modifier = Modifier) {
Icon(
imageVector = Icons.Outlined.FileDownload,
contentDescription = stringResource(R.string.debug_logs_export),
contentDescription = stringResource(Res.string.debug_logs_export),
modifier = Modifier.size(24.dp),
)
}

View file

@ -32,57 +32,57 @@ import androidx.compose.material.icons.filled.Wifi
import androidx.compose.ui.graphics.vector.ImageVector
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.strings.R
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) {
USER(R.string.user, SettingsRoutes.User, Icons.Default.Person, 0),
CHANNELS(R.string.channels, SettingsRoutes.ChannelConfig, Icons.AutoMirrored.Default.List, 0),
USER(Res.string.user, SettingsRoutes.User, Icons.Default.Person, 0),
CHANNELS(Res.string.channels, SettingsRoutes.ChannelConfig, Icons.AutoMirrored.Default.List, 0),
DEVICE(
R.string.device,
Res.string.device,
SettingsRoutes.Device,
Icons.Default.Router,
AdminProtos.AdminMessage.ConfigType.DEVICE_CONFIG_VALUE,
),
POSITION(
R.string.position,
Res.string.position,
SettingsRoutes.Position,
Icons.Default.LocationOn,
AdminProtos.AdminMessage.ConfigType.POSITION_CONFIG_VALUE,
),
POWER(
R.string.power,
Res.string.power,
SettingsRoutes.Power,
Icons.Default.Power,
AdminProtos.AdminMessage.ConfigType.POWER_CONFIG_VALUE,
),
NETWORK(
R.string.network,
Res.string.network,
SettingsRoutes.Network,
Icons.Default.Wifi,
AdminProtos.AdminMessage.ConfigType.NETWORK_CONFIG_VALUE,
),
DISPLAY(
R.string.display,
Res.string.display,
SettingsRoutes.Display,
Icons.Default.DisplaySettings,
AdminProtos.AdminMessage.ConfigType.DISPLAY_CONFIG_VALUE,
),
LORA(
R.string.lora,
Res.string.lora,
SettingsRoutes.LoRa,
Icons.Default.CellTower,
AdminProtos.AdminMessage.ConfigType.LORA_CONFIG_VALUE,
),
BLUETOOTH(
R.string.bluetooth,
Res.string.bluetooth,
SettingsRoutes.Bluetooth,
Icons.Default.Bluetooth,
AdminProtos.AdminMessage.ConfigType.BLUETOOTH_CONFIG_VALUE,
),
SECURITY(
R.string.security,
Res.string.security,
SettingsRoutes.Security,
Icons.Default.Security,
AdminProtos.AdminMessage.ConfigType.SECURITY_CONFIG_VALUE,

View file

@ -35,85 +35,85 @@ import androidx.compose.material.icons.filled.Usb
import androidx.compose.ui.graphics.vector.ImageVector
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.strings.R
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) {
MQTT(
R.string.mqtt,
Res.string.mqtt,
SettingsRoutes.MQTT,
Icons.Default.Cloud,
AdminProtos.AdminMessage.ModuleConfigType.MQTT_CONFIG_VALUE,
),
SERIAL(
R.string.serial,
Res.string.serial,
SettingsRoutes.Serial,
Icons.Default.Usb,
AdminProtos.AdminMessage.ModuleConfigType.SERIAL_CONFIG_VALUE,
),
EXT_NOTIFICATION(
R.string.external_notification,
Res.string.external_notification,
SettingsRoutes.ExtNotification,
Icons.Default.Notifications,
AdminProtos.AdminMessage.ModuleConfigType.EXTNOTIF_CONFIG_VALUE,
),
STORE_FORWARD(
R.string.store_forward,
Res.string.store_forward,
SettingsRoutes.StoreForward,
Icons.AutoMirrored.Default.Forward,
AdminProtos.AdminMessage.ModuleConfigType.STOREFORWARD_CONFIG_VALUE,
),
RANGE_TEST(
R.string.range_test,
Res.string.range_test,
SettingsRoutes.RangeTest,
Icons.Default.Speed,
AdminProtos.AdminMessage.ModuleConfigType.RANGETEST_CONFIG_VALUE,
),
TELEMETRY(
R.string.telemetry,
Res.string.telemetry,
SettingsRoutes.Telemetry,
Icons.Default.DataUsage,
AdminProtos.AdminMessage.ModuleConfigType.TELEMETRY_CONFIG_VALUE,
),
CANNED_MESSAGE(
R.string.canned_message,
Res.string.canned_message,
SettingsRoutes.CannedMessage,
Icons.AutoMirrored.Default.Message,
AdminProtos.AdminMessage.ModuleConfigType.CANNEDMSG_CONFIG_VALUE,
),
AUDIO(
R.string.audio,
Res.string.audio,
SettingsRoutes.Audio,
Icons.AutoMirrored.Default.VolumeUp,
AdminProtos.AdminMessage.ModuleConfigType.AUDIO_CONFIG_VALUE,
),
REMOTE_HARDWARE(
R.string.remote_hardware,
Res.string.remote_hardware,
SettingsRoutes.RemoteHardware,
Icons.Default.SettingsRemote,
AdminProtos.AdminMessage.ModuleConfigType.REMOTEHARDWARE_CONFIG_VALUE,
),
NEIGHBOR_INFO(
R.string.neighbor_info,
Res.string.neighbor_info,
SettingsRoutes.NeighborInfo,
Icons.Default.People,
AdminProtos.AdminMessage.ModuleConfigType.NEIGHBORINFO_CONFIG_VALUE,
),
AMBIENT_LIGHTING(
R.string.ambient_lighting,
Res.string.ambient_lighting,
SettingsRoutes.AmbientLighting,
Icons.Default.LightMode,
AdminProtos.AdminMessage.ModuleConfigType.AMBIENTLIGHTING_CONFIG_VALUE,
),
DETECTION_SENSOR(
R.string.detection_sensor,
Res.string.detection_sensor,
SettingsRoutes.DetectionSensor,
Icons.Default.Sensors,
AdminProtos.AdminMessage.ModuleConfigType.DETECTIONSENSOR_CONFIG_VALUE,
),
PAXCOUNTER(
R.string.paxcounter,
Res.string.paxcounter,
SettingsRoutes.Paxcounter,
Icons.Default.PermScanWifi,
AdminProtos.AdminMessage.ModuleConfigType.PAXCOUNTER_CONFIG_VALUE,

View file

@ -47,8 +47,8 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import org.meshtastic.core.database.entity.NodeEntity
import org.meshtastic.core.strings.R
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
@ -75,8 +75,8 @@ fun CleanNodeDatabaseScreen(viewModel: CleanNodeDatabaseViewModel = hiltViewMode
}
Column(modifier = Modifier.padding(16.dp).verticalScroll(rememberScrollState())) {
Text(stringResource(R.string.clean_node_database_title))
Text(stringResource(R.string.clean_node_database_description), style = MaterialTheme.typography.bodySmall)
Text(stringResource(Res.string.clean_node_database_title))
Text(stringResource(Res.string.clean_node_database_description), style = MaterialTheme.typography.bodySmall)
Spacer(modifier = Modifier.height(16.dp))
DaysThresholdFilter(
@ -100,7 +100,7 @@ fun CleanNodeDatabaseScreen(viewModel: CleanNodeDatabaseViewModel = hiltViewMode
modifier = Modifier.fillMaxWidth(),
enabled = nodesToDelete.isNotEmpty(),
) {
Text(stringResource(R.string.clean_now))
Text(stringResource(Res.string.clean_now))
}
}
}
@ -129,7 +129,7 @@ private fun DaysThresholdFilter(olderThanDays: Float, onlyUnknownNodes: Boolean,
Column(modifier = Modifier.fillMaxWidth()) {
Text(
modifier = Modifier.padding(bottom = 8.dp),
text = stringResource(R.string.clean_nodes_older_than, olderThanDays.toInt()),
text = stringResource(Res.string.clean_nodes_older_than, olderThanDays.toInt()),
)
Slider(
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
@ -150,7 +150,7 @@ private fun DaysThresholdFilter(olderThanDays: Float, onlyUnknownNodes: Boolean,
@Composable
private fun UnknownNodesFilter(onlyUnknownNodes: Boolean, onCheckedChanged: (Boolean) -> Unit) {
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
Text(stringResource(R.string.clean_unknown_nodes))
Text(stringResource(Res.string.clean_unknown_nodes))
Spacer(Modifier.weight(1f))
Switch(checked = onlyUnknownNodes, onCheckedChange = onCheckedChanged)
}
@ -164,7 +164,7 @@ private fun UnknownNodesFilter(onlyUnknownNodes: Boolean, onCheckedChanged: (Boo
@Composable
private fun NodesDeletionPreview(nodesToDelete: List<NodeEntity>) {
Text(
stringResource(R.string.nodes_queued_for_deletion, nodesToDelete.size),
stringResource(Res.string.nodes_queued_for_deletion, nodesToDelete.size),
modifier = Modifier.padding(bottom = 16.dp),
)
FlowRow(
@ -189,9 +189,9 @@ private fun NodesDeletionPreview(nodesToDelete: List<NodeEntity>) {
private fun ConfirmationDialog(nodesToDeleteCount: Int, onConfirm: () -> Unit, onDismiss: () -> Unit) {
AlertDialog(
onDismissRequest = onDismiss,
title = { Text(stringResource(R.string.are_you_sure)) },
text = { Text(stringResource(R.string.clean_node_database_confirmation, nodesToDeleteCount)) },
confirmButton = { Button(onClick = onConfirm) { Text(stringResource(R.string.clean_now)) } },
dismissButton = { TextButton(onClick = onDismiss) { Text(stringResource(R.string.cancel)) } },
title = { Text(stringResource(Res.string.are_you_sure)) },
text = { Text(stringResource(Res.string.clean_node_database_confirmation, nodesToDeleteCount)) },
confirmButton = { Button(onClick = onConfirm) { Text(stringResource(Res.string.clean_now)) } },
dismissButton = { TextButton(onClick = onDismiss) { Text(stringResource(Res.string.cancel)) } },
)
}

View file

@ -44,7 +44,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.AppTheme
@ -52,6 +51,7 @@ 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
@ -76,7 +76,7 @@ fun RadioConfigItemList(
}
Column {
TitledCard(title = stringResource(R.string.radio_configuration)) {
TitledCard(title = stringResource(Res.string.radio_configuration)) {
if (isManaged) {
ManagedMessage()
}
@ -85,7 +85,7 @@ fun RadioConfigItemList(
}
}
TitledCard(title = stringResource(R.string.device_configuration), modifier = Modifier.padding(top = 16.dp)) {
TitledCard(title = stringResource(Res.string.device_configuration), modifier = Modifier.padding(top = 16.dp)) {
if (isManaged) {
ManagedMessage()
}
@ -94,7 +94,7 @@ fun RadioConfigItemList(
}
}
TitledCard(title = stringResource(R.string.module_settings), modifier = Modifier.padding(top = 16.dp)) {
TitledCard(title = stringResource(Res.string.module_settings), modifier = Modifier.padding(top = 16.dp)) {
if (isManaged) {
ManagedMessage()
}
@ -106,19 +106,19 @@ fun RadioConfigItemList(
}
if (state.isLocal) {
TitledCard(title = stringResource(R.string.backup_restore), modifier = Modifier.padding(top = 16.dp)) {
TitledCard(title = stringResource(Res.string.backup_restore), modifier = Modifier.padding(top = 16.dp)) {
if (isManaged) {
ManagedMessage()
}
ListItem(
text = stringResource(R.string.import_configuration),
text = stringResource(Res.string.import_configuration),
leadingIcon = Icons.Default.Download,
enabled = enabled,
onClick = onImport,
)
ListItem(
text = stringResource(R.string.export_configuration),
text = stringResource(Res.string.export_configuration),
leadingIcon = Icons.Default.Upload,
enabled = enabled,
onClick = onExport,
@ -126,7 +126,7 @@ fun RadioConfigItemList(
}
}
TitledCard(title = stringResource(R.string.administration), modifier = Modifier.padding(top = 16.dp)) {
TitledCard(title = stringResource(Res.string.administration), modifier = Modifier.padding(top = 16.dp)) {
AdminRoute.entries.forEach { route ->
var showDialog by remember { mutableStateOf(false) }
if (showDialog) {
@ -148,20 +148,20 @@ fun RadioConfigItemList(
}
}
TitledCard(title = stringResource(R.string.advanced_title), modifier = Modifier.padding(top = 16.dp)) {
TitledCard(title = stringResource(Res.string.advanced_title), modifier = Modifier.padding(top = 16.dp)) {
if (isManaged) {
ManagedMessage()
}
ListItem(
text = stringResource(R.string.clean_node_database_title),
text = stringResource(Res.string.clean_node_database_title),
leadingIcon = Icons.Rounded.CleaningServices,
enabled = enabled,
onClick = { onNavigate(SettingsRoutes.CleanNodeDb) },
)
ListItem(
text = stringResource(R.string.debug_panel),
text = stringResource(Res.string.debug_panel),
leadingIcon = Icons.Rounded.BugReport,
enabled = enabled,
onClick = { onNavigate(SettingsRoutes.DebugPanel) },
@ -170,10 +170,10 @@ fun RadioConfigItemList(
}
enum class AdminRoute(val icon: ImageVector, @StringRes val title: Int) {
REBOOT(Icons.Rounded.RestartAlt, R.string.reboot),
SHUTDOWN(Icons.Rounded.PowerSettingsNew, R.string.shutdown),
FACTORY_RESET(Icons.Rounded.Restore, R.string.factory_reset),
NODEDB_RESET(Icons.Rounded.Storage, R.string.nodedb_reset),
REBOOT(Icons.Rounded.RestartAlt, Res.string.reboot),
SHUTDOWN(Icons.Rounded.PowerSettingsNew, Res.string.shutdown),
FACTORY_RESET(Icons.Rounded.Restore, Res.string.factory_reset),
NODEDB_RESET(Icons.Rounded.Storage, Res.string.nodedb_reset),
}
@Preview(showBackground = true)
@ -189,7 +189,7 @@ private fun RadioSettingsScreenPreview() = AppTheme {
@Composable
private fun ManagedMessage() {
Text(
text = stringResource(R.string.message_device_managed),
text = stringResource(Res.string.message_device_managed),
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
color = MaterialTheme.colorScheme.StatusRed,
)

View file

@ -63,7 +63,6 @@ import org.meshtastic.core.proto.getChannelList
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.service.IMeshService
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.R
import org.meshtastic.feature.settings.navigation.ConfigRoute
import org.meshtastic.feature.settings.navigation.ModuleRoute
import org.meshtastic.feature.settings.util.UiText
@ -82,6 +81,7 @@ 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(
@ -384,7 +384,7 @@ constructor(
AdminRoute.SHUTDOWN.name ->
with(radioConfigState.value) {
if (metadata != null && !metadata.canShutdown) {
sendError(R.string.cant_shutdown)
sendError(Res.string.cant_shutdown)
} else {
requestShutdown(destNum)
}

View file

@ -55,7 +55,6 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.meshtastic.core.model.Channel
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.PreferenceFooter
import org.meshtastic.core.ui.component.dragContainer
import org.meshtastic.core.ui.component.dragDropItemsIndexed
@ -71,6 +70,7 @@ 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) {
@ -81,7 +81,7 @@ fun ChannelConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
}
ChannelConfigScreen(
title = stringResource(R.string.channels),
title = stringResource(Res.string.channels),
onBack = onBack,
settingsList = state.channelList,
loraConfig = state.radioConfig.lora,
@ -164,7 +164,7 @@ private fun ChannelConfigScreen(
},
modifier = Modifier.padding(16.dp),
) {
Icon(Icons.TwoTone.Add, stringResource(R.string.add))
Icon(Icons.TwoTone.Add, stringResource(Res.string.add))
}
}
},
@ -186,7 +186,7 @@ private fun ChannelConfigScreen(
},
)
Text(
text = stringResource(R.string.press_and_drag),
text = stringResource(Res.string.press_and_drag),
fontSize = 11.sp,
modifier = Modifier.padding(start = 16.dp),
)
@ -221,13 +221,13 @@ private fun ChannelConfigScreen(
item {
PreferenceFooter(
enabled = enabled && isEditing,
negativeText = stringResource(R.string.cancel),
negativeText = stringResource(Res.string.cancel),
onNegativeClicked = {
focusManager.clearFocus()
settingsListInput.clear()
settingsListInput.addAll(settingsList)
},
positiveText = stringResource(R.string.send),
positiveText = stringResource(Res.string.send),
onPositiveClicked = {
focusManager.clearFocus()
onPositiveClicked(settingsListInput)
@ -294,7 +294,7 @@ private fun ChannelConfigScreenPreview() {
psk = Channel.default.settings.psk
name = Channel.default.name
},
channelSettings { name = stringResource(R.string.channel_name) },
channelSettings { name = stringResource(Res.string.channel_name) },
),
loraConfig = Channel.default.loraConfig,
firmwareVersion = "1.3.2",

View file

@ -30,7 +30,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.ChannelItem
import org.meshtastic.core.ui.component.SecurityIcon
import org.meshtastic.core.ui.theme.AppTheme
@ -38,6 +37,7 @@ 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(
@ -76,7 +76,7 @@ internal fun ChannelCard(
IconButton(onClick = { onDeleteClick() }) {
Icon(
imageVector = Icons.TwoTone.Close,
contentDescription = stringResource(R.string.delete),
contentDescription = stringResource(Res.string.delete),
modifier = Modifier.wrapContentSize(),
)
}

View file

@ -28,9 +28,9 @@ 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.meshtastic.core.strings.R
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) {
@ -39,10 +39,10 @@ internal fun ChannelConfigHeader(frequency: Float, slot: Int) {
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
PreferenceCategory(text = stringResource(R.string.channels))
PreferenceCategory(text = stringResource(Res.string.channels))
Column {
Text(text = "${stringResource(R.string.freq)}: ${frequency}MHz", fontSize = 11.sp)
Text(text = "${stringResource(R.string.slot)}: $slot", fontSize = 11.sp)
Text(text = "${stringResource(Res.string.freq)}: ${frequency}MHz", fontSize = 11.sp)
Text(text = "${stringResource(Res.string.slot)}: $slot", fontSize = 11.sp)
}
}
}

View file

@ -46,7 +46,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.R
import org.meshtastic.core.strings.R as Res
/**
* At this firmware version periodic position sharing on a secondary channel was implemented. To enable this feature the
@ -62,18 +62,18 @@ internal enum class ChannelIcons(
) {
LOCATION(
icon = Icons.Filled.LocationOn,
descriptionResId = R.string.location_sharing,
additionalInfoResId = R.string.periodic_position_broadcast,
descriptionResId = Res.string.location_sharing,
additionalInfoResId = Res.string.periodic_position_broadcast,
),
UPLINK(
icon = Icons.Filled.CloudUpload,
descriptionResId = R.string.uplink_enabled,
additionalInfoResId = R.string.uplink_feature_description,
descriptionResId = Res.string.uplink_enabled,
additionalInfoResId = Res.string.uplink_feature_description,
),
DOWNLINK(
icon = Icons.Filled.CloudDownload,
descriptionResId = R.string.downlink_enabled,
additionalInfoResId = R.string.downlink_feature_description,
descriptionResId = Res.string.downlink_enabled,
additionalInfoResId = Res.string.downlink_feature_description,
),
}
@ -84,15 +84,15 @@ internal fun ChannelLegend(onClick: () -> Unit) {
horizontalArrangement = Arrangement.SpaceEvenly,
) {
Row {
Icon(imageVector = Icons.Filled.Info, contentDescription = stringResource(R.string.info))
Icon(imageVector = Icons.Filled.Info, contentDescription = stringResource(Res.string.info))
Text(
text = stringResource(R.string.primary),
text = stringResource(Res.string.primary),
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.padding(start = 16.dp),
)
}
Text(
text = stringResource(R.string.secondary),
text = stringResource(Res.string.secondary),
color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.padding(start = 16.dp),
)
@ -104,29 +104,29 @@ internal fun ChannelLegendDialog(firmwareVersion: DeviceVersion, onDismiss: () -
AlertDialog(
modifier = Modifier.fillMaxSize(),
onDismissRequest = onDismiss,
title = { Text(stringResource(R.string.channel_features)) },
title = { Text(stringResource(Res.string.channel_features)) },
text = {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.verticalScroll(rememberScrollState()),
) {
Text(
text = stringResource(R.string.primary),
text = stringResource(Res.string.primary),
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.titleMedium,
)
Text(
text = "- ${stringResource(R.string.primary_channel_feature)}",
text = "- ${stringResource(Res.string.primary_channel_feature)}",
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.bodyMedium,
)
Text(
text = stringResource(R.string.secondary),
text = stringResource(Res.string.secondary),
color = MaterialTheme.colorScheme.onBackground,
style = MaterialTheme.typography.titleMedium,
)
Text(
text = "- ${stringResource(R.string.secondary_no_telemetry)}",
text = "- ${stringResource(Res.string.secondary_no_telemetry)}",
color = MaterialTheme.colorScheme.onBackground,
style = MaterialTheme.typography.bodyMedium,
)
@ -134,9 +134,9 @@ internal fun ChannelLegendDialog(firmwareVersion: DeviceVersion, onDismiss: () -
text =
if (firmwareVersion >= DeviceVersion(asString = SECONDARY_CHANNEL_EPOCH)) {
/* 2.6.10+ */
"- ${stringResource(R.string.secondary_channel_position_feature)}"
"- ${stringResource(Res.string.secondary_channel_position_feature)}"
} else {
"- ${stringResource(R.string.manual_position_request)}"
"- ${stringResource(Res.string.manual_position_request)}"
},
color = MaterialTheme.colorScheme.onBackground,
style = MaterialTheme.typography.bodyMedium,
@ -150,7 +150,7 @@ internal fun ChannelLegendDialog(firmwareVersion: DeviceVersion, onDismiss: () -
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
TextButton(onClick = onDismiss) { Text(stringResource(R.string.security_icon_help_dismiss)) }
TextButton(onClick = onDismiss) { Text(stringResource(Res.string.security_icon_help_dismiss)) }
}
},
)
@ -158,7 +158,7 @@ internal fun ChannelLegendDialog(firmwareVersion: DeviceVersion, onDismiss: () -
@Composable
private fun IconDefinitions() {
Text(text = stringResource(R.string.icon_meanings), style = MaterialTheme.typography.titleLarge)
Text(text = stringResource(Res.string.icon_meanings), style = MaterialTheme.typography.titleLarge)
ChannelIcons.entries.forEach { icon ->
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(imageVector = icon.icon, contentDescription = stringResource(icon.descriptionResId))

View file

@ -43,7 +43,6 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.meshtastic.core.model.Channel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditBase64Preference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PositionPrecisionPreference
@ -51,6 +50,7 @@ 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
@ -59,7 +59,7 @@ fun EditChannelDialog(
onAddClick: (ChannelProtos.ChannelSettings) -> Unit,
onDismissRequest: () -> Unit,
modifier: Modifier = Modifier,
modemPresetName: String = stringResource(R.string.default_),
modemPresetName: String = stringResource(Res.string.default_),
) {
val focusManager = LocalFocusManager.current
var isFocused by remember { mutableStateOf(false) }
@ -72,7 +72,7 @@ fun EditChannelDialog(
text = {
Column(modifier.fillMaxWidth()) {
EditTextPreference(
title = stringResource(R.string.channel_name),
title = stringResource(Res.string.channel_name),
value = if (isFocused) channelInput.name else channelInput.name.ifEmpty { modemPresetName },
maxSize = 11, // name max_size:12
enabled = true,
@ -105,7 +105,7 @@ fun EditChannelDialog(
)
SwitchPreference(
title = stringResource(R.string.uplink_enabled),
title = stringResource(Res.string.uplink_enabled),
checked = channelInput.uplinkEnabled,
enabled = true,
onCheckedChange = { channelInput = channelInput.copy { uplinkEnabled = it } },
@ -113,7 +113,7 @@ fun EditChannelDialog(
)
SwitchPreference(
title = stringResource(R.string.downlink_enabled),
title = stringResource(Res.string.downlink_enabled),
checked = channelInput.downlinkEnabled,
enabled = true,
onCheckedChange = { channelInput = channelInput.copy { downlinkEnabled = it } },
@ -136,10 +136,10 @@ fun EditChannelDialog(
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
TextButton(modifier = modifier.weight(1f), onClick = onDismissRequest) {
Text(stringResource(R.string.cancel))
Text(stringResource(Res.string.cancel))
}
Button(modifier = modifier.weight(1f), onClick = { onAddClick(channelInput) }, enabled = true) {
Text(stringResource(R.string.save))
Text(stringResource(Res.string.save))
}
}
},

View file

@ -26,13 +26,13 @@ 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.meshtastic.core.strings.R
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) {
@ -42,7 +42,7 @@ fun AmbientLightingConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.ambient_lighting),
title = stringResource(Res.string.ambient_lighting),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -54,9 +54,9 @@ fun AmbientLightingConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
},
) {
item {
TitledCard(title = stringResource(R.string.ambient_lighting_config)) {
TitledCard(title = stringResource(Res.string.ambient_lighting_config)) {
SwitchPreference(
title = stringResource(R.string.led_state),
title = stringResource(Res.string.led_state),
checked = formState.value.ledState,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { ledState = it } },
@ -64,21 +64,21 @@ fun AmbientLightingConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.current),
title = stringResource(Res.string.current),
value = formState.value.current,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { formState.value = formState.value.copy { current = it } },
)
EditTextPreference(
title = stringResource(R.string.red),
title = stringResource(Res.string.red),
value = formState.value.red,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { formState.value = formState.value.copy { red = it } },
)
EditTextPreference(
title = stringResource(R.string.green),
title = stringResource(Res.string.green),
value = formState.value.green,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -86,7 +86,7 @@ fun AmbientLightingConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
)
EditTextPreference(
title = stringResource(R.string.blue),
title = stringResource(Res.string.blue),
value = formState.value.blue,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),

View file

@ -26,7 +26,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -35,6 +34,7 @@ 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) {
@ -44,7 +44,7 @@ fun AudioConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.audio),
title = stringResource(Res.string.audio),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -56,9 +56,9 @@ fun AudioConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
},
) {
item {
TitledCard(title = stringResource(R.string.audio_config)) {
TitledCard(title = stringResource(Res.string.audio_config)) {
SwitchPreference(
title = stringResource(R.string.codec_2_enabled),
title = stringResource(Res.string.codec_2_enabled),
checked = formState.value.codec2Enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { codec2Enabled = it } },
@ -66,14 +66,14 @@ fun AudioConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.ptt_pin),
title = stringResource(Res.string.ptt_pin),
value = formState.value.pttPin,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { formState.value = formState.value.copy { pttPin = it } },
)
DropDownPreference(
title = stringResource(R.string.codec2_sample_rate),
title = stringResource(Res.string.codec2_sample_rate),
enabled = state.connected,
items =
AudioConfig.Audio_Baud.entries
@ -84,28 +84,28 @@ fun AudioConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.i2s_word_select),
title = stringResource(Res.string.i2s_word_select),
value = formState.value.i2SWs,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { formState.value = formState.value.copy { i2SWs = it } },
)
EditTextPreference(
title = stringResource(R.string.i2s_data_in),
title = stringResource(Res.string.i2s_data_in),
value = formState.value.i2SSd,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { formState.value = formState.value.copy { i2SSd = it } },
)
EditTextPreference(
title = stringResource(R.string.i2s_data_out),
title = stringResource(Res.string.i2s_data_out),
value = formState.value.i2SDin,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { formState.value = formState.value.copy { i2SDin = it } },
)
EditTextPreference(
title = stringResource(R.string.i2s_clock),
title = stringResource(Res.string.i2s_clock),
value = formState.value.i2SSck,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),

View file

@ -26,7 +26,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -35,6 +34,7 @@ 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) {
@ -44,7 +44,7 @@ fun BluetoothConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.bluetooth),
title = stringResource(Res.string.bluetooth),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -56,9 +56,9 @@ fun BluetoothConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
},
) {
item {
TitledCard(title = stringResource(R.string.bluetooth_config)) {
TitledCard(title = stringResource(Res.string.bluetooth_config)) {
SwitchPreference(
title = stringResource(R.string.bluetooth_enabled),
title = stringResource(Res.string.bluetooth_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -66,7 +66,7 @@ fun BluetoothConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.pairing_mode),
title = stringResource(Res.string.pairing_mode),
enabled = state.connected,
items =
BluetoothConfig.PairingMode.entries
@ -77,7 +77,7 @@ fun BluetoothConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.fixed_pin),
title = stringResource(Res.string.fixed_pin),
value = formState.value.fixedPin,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),

View file

@ -32,7 +32,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -41,6 +40,7 @@ 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) {
@ -52,7 +52,7 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.canned_message),
title = stringResource(Res.string.canned_message),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -69,9 +69,9 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
},
) {
item {
TitledCard(title = stringResource(R.string.canned_message_config)) {
TitledCard(title = stringResource(Res.string.canned_message_config)) {
SwitchPreference(
title = stringResource(R.string.canned_message_enabled),
title = stringResource(Res.string.canned_message_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -79,7 +79,7 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.rotary_encoder_1_enabled),
title = stringResource(Res.string.rotary_encoder_1_enabled),
checked = formState.value.rotary1Enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { rotary1Enabled = it } },
@ -87,28 +87,28 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.gpio_pin_for_rotary_encoder_a_port),
title = stringResource(Res.string.gpio_pin_for_rotary_encoder_a_port),
value = formState.value.inputbrokerPinA,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { formState.value = formState.value.copy { inputbrokerPinA = it } },
)
EditTextPreference(
title = stringResource(R.string.gpio_pin_for_rotary_encoder_b_port),
title = stringResource(Res.string.gpio_pin_for_rotary_encoder_b_port),
value = formState.value.inputbrokerPinB,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { formState.value = formState.value.copy { inputbrokerPinB = it } },
)
EditTextPreference(
title = stringResource(R.string.gpio_pin_for_rotary_encoder_press_port),
title = stringResource(Res.string.gpio_pin_for_rotary_encoder_press_port),
value = formState.value.inputbrokerPinPress,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { formState.value = formState.value.copy { inputbrokerPinPress = it } },
)
DropDownPreference(
title = stringResource(R.string.generate_input_event_on_press),
title = stringResource(Res.string.generate_input_event_on_press),
enabled = state.connected,
items =
CannedMessageConfig.InputEventChar.entries
@ -119,7 +119,7 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.generate_input_event_on_cw),
title = stringResource(Res.string.generate_input_event_on_cw),
enabled = state.connected,
items =
CannedMessageConfig.InputEventChar.entries
@ -130,7 +130,7 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.generate_input_event_on_ccw),
title = stringResource(Res.string.generate_input_event_on_ccw),
enabled = state.connected,
items =
CannedMessageConfig.InputEventChar.entries
@ -141,7 +141,7 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.up_down_select_input_enabled),
title = stringResource(Res.string.up_down_select_input_enabled),
checked = formState.value.updown1Enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { updown1Enabled = it } },
@ -149,7 +149,7 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.allow_input_source),
title = stringResource(Res.string.allow_input_source),
value = formState.value.allowInputSource,
maxSize = 63, // allow_input_source max_size:16
enabled = state.connected,
@ -160,7 +160,7 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
onValueChanged = { formState.value = formState.value.copy { allowInputSource = it } },
)
SwitchPreference(
title = stringResource(R.string.send_bell),
title = stringResource(Res.string.send_bell),
checked = formState.value.sendBell,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { sendBell = it } },
@ -168,7 +168,7 @@ fun CannedMessageConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.messages),
title = stringResource(Res.string.messages),
value = messagesInput,
maxSize = 200, // messages max_size:201
enabled = state.connected,

View file

@ -31,7 +31,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -43,6 +42,7 @@ 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) {
@ -53,7 +53,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
val context = LocalContext.current
RadioConfigScreenList(
title = stringResource(R.string.detection_sensor),
title = stringResource(Res.string.detection_sensor),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -65,9 +65,9 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
},
) {
item {
TitledCard(title = stringResource(R.string.detection_sensor_config)) {
TitledCard(title = stringResource(Res.string.detection_sensor_config)) {
SwitchPreference(
title = stringResource(R.string.detection_sensor_enabled),
title = stringResource(Res.string.detection_sensor_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -78,7 +78,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
IntervalConfiguration.DETECTION_SENSOR_MINIMUM.allowedIntervals
}
DropDownPreference(
title = stringResource(R.string.minimum_broadcast_seconds),
title = stringResource(Res.string.minimum_broadcast_seconds),
selectedItem = formState.value.minimumBroadcastSecs.toLong(),
enabled = state.connected,
items = minimumBroadcastIntervals.map { it.value to it.toDisplayString(context = context) },
@ -87,7 +87,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
val stateBroadcastIntervals = remember { IntervalConfiguration.DETECTION_SENSOR_STATE.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.state_broadcast_seconds),
title = stringResource(Res.string.state_broadcast_seconds),
selectedItem = formState.value.stateBroadcastSecs.toLong(),
enabled = state.connected,
items = stateBroadcastIntervals.map { it.value to it.toDisplayString(context = context) },
@ -95,7 +95,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.send_bell_with_alert_message),
title = stringResource(Res.string.send_bell_with_alert_message),
checked = formState.value.sendBell,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { sendBell = it } },
@ -103,7 +103,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.friendly_name),
title = stringResource(Res.string.friendly_name),
value = formState.value.name,
maxSize = 19, // name max_size:20
enabled = state.connected,
@ -116,7 +116,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
HorizontalDivider()
val pins = remember { gpioPins }
DropDownPreference(
title = stringResource(R.string.gpio_pin_to_monitor),
title = stringResource(Res.string.gpio_pin_to_monitor),
items = pins,
selectedItem = formState.value.monitorPin,
enabled = state.connected,
@ -124,7 +124,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.detection_trigger_type),
title = stringResource(Res.string.detection_trigger_type),
enabled = state.connected,
items =
ModuleConfig.DetectionSensorConfig.TriggerType.entries
@ -135,7 +135,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.use_input_pullup_mode),
title = stringResource(Res.string.use_input_pullup_mode),
checked = formState.value.usePullup,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { usePullup = it } },

View file

@ -66,7 +66,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.InsetDivider
@ -80,35 +79,36 @@ 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
get() =
when (this) {
DeviceConfig.Role.CLIENT -> R.string.role_client_desc
DeviceConfig.Role.CLIENT_MUTE -> R.string.role_client_mute_desc
DeviceConfig.Role.ROUTER -> R.string.role_router_desc
DeviceConfig.Role.ROUTER_CLIENT -> R.string.role_router_client_desc
DeviceConfig.Role.REPEATER -> R.string.role_repeater_desc
DeviceConfig.Role.TRACKER -> R.string.role_tracker_desc
DeviceConfig.Role.SENSOR -> R.string.role_sensor_desc
DeviceConfig.Role.TAK -> R.string.role_tak_desc
DeviceConfig.Role.CLIENT_HIDDEN -> R.string.role_client_hidden_desc
DeviceConfig.Role.LOST_AND_FOUND -> R.string.role_lost_and_found_desc
DeviceConfig.Role.TAK_TRACKER -> R.string.role_tak_tracker_desc
DeviceConfig.Role.ROUTER_LATE -> R.string.role_router_late_desc
else -> R.string.unrecognized
DeviceConfig.Role.CLIENT -> Res.string.role_client_desc
DeviceConfig.Role.CLIENT_MUTE -> Res.string.role_client_mute_desc
DeviceConfig.Role.ROUTER -> Res.string.role_router_desc
DeviceConfig.Role.ROUTER_CLIENT -> Res.string.role_router_client_desc
DeviceConfig.Role.REPEATER -> Res.string.role_repeater_desc
DeviceConfig.Role.TRACKER -> Res.string.role_tracker_desc
DeviceConfig.Role.SENSOR -> Res.string.role_sensor_desc
DeviceConfig.Role.TAK -> Res.string.role_tak_desc
DeviceConfig.Role.CLIENT_HIDDEN -> Res.string.role_client_hidden_desc
DeviceConfig.Role.LOST_AND_FOUND -> Res.string.role_lost_and_found_desc
DeviceConfig.Role.TAK_TRACKER -> Res.string.role_tak_tracker_desc
DeviceConfig.Role.ROUTER_LATE -> Res.string.role_router_late_desc
else -> Res.string.unrecognized
}
private val DeviceConfig.RebroadcastMode.description: Int
get() =
when (this) {
DeviceConfig.RebroadcastMode.ALL -> R.string.rebroadcast_mode_all_desc
DeviceConfig.RebroadcastMode.ALL_SKIP_DECODING -> R.string.rebroadcast_mode_all_skip_decoding_desc
DeviceConfig.RebroadcastMode.LOCAL_ONLY -> R.string.rebroadcast_mode_local_only_desc
DeviceConfig.RebroadcastMode.KNOWN_ONLY -> R.string.rebroadcast_mode_known_only_desc
DeviceConfig.RebroadcastMode.NONE -> R.string.rebroadcast_mode_none_desc
DeviceConfig.RebroadcastMode.CORE_PORTNUMS_ONLY -> R.string.rebroadcast_mode_core_portnums_only_desc
else -> R.string.unrecognized
DeviceConfig.RebroadcastMode.ALL -> Res.string.rebroadcast_mode_all_desc
DeviceConfig.RebroadcastMode.ALL_SKIP_DECODING -> Res.string.rebroadcast_mode_all_skip_decoding_desc
DeviceConfig.RebroadcastMode.LOCAL_ONLY -> Res.string.rebroadcast_mode_local_only_desc
DeviceConfig.RebroadcastMode.KNOWN_ONLY -> Res.string.rebroadcast_mode_known_only_desc
DeviceConfig.RebroadcastMode.NONE -> Res.string.rebroadcast_mode_none_desc
DeviceConfig.RebroadcastMode.CORE_PORTNUMS_ONLY -> Res.string.rebroadcast_mode_core_portnums_only_desc
else -> Res.string.unrecognized
}
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@ -132,7 +132,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
val focusManager = LocalFocusManager.current
val context = LocalContext.current
RadioConfigScreenList(
title = stringResource(R.string.device),
title = stringResource(Res.string.device),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -144,9 +144,9 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
},
) {
item {
TitledCard(title = stringResource(R.string.options)) {
TitledCard(title = stringResource(Res.string.options)) {
DropDownPreference(
title = stringResource(R.string.role),
title = stringResource(Res.string.role),
enabled = state.connected,
selectedItem = formState.value.role,
onItemSelected = { selectedRole = it },
@ -156,7 +156,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.rebroadcast_mode),
title = stringResource(Res.string.rebroadcast_mode),
enabled = state.connected,
selectedItem = formState.value.rebroadcastMode,
onItemSelected = { formState.value = formState.value.copy { rebroadcastMode = it } },
@ -167,7 +167,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
val nodeInfoBroadcastIntervals = remember { IntervalConfiguration.NODE_INFO_BROADCAST.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.nodeinfo_broadcast_interval),
title = stringResource(Res.string.nodeinfo_broadcast_interval),
selectedItem = formState.value.nodeInfoBroadcastSecs.toLong(),
enabled = state.connected,
items = nodeInfoBroadcastIntervals.map { it.value to it.toDisplayString(context = context) },
@ -177,10 +177,10 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
}
item {
TitledCard(title = stringResource(R.string.hardware)) {
TitledCard(title = stringResource(Res.string.hardware)) {
SwitchPreference(
title = stringResource(R.string.double_tap_as_button_press),
summary = stringResource(R.string.config_device_doubleTapAsButtonPress_summary),
title = stringResource(Res.string.double_tap_as_button_press),
summary = stringResource(Res.string.config_device_doubleTapAsButtonPress_summary),
checked = formState.value.doubleTapAsButtonPress,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { doubleTapAsButtonPress = it } },
@ -190,8 +190,8 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
InsetDivider()
SwitchPreference(
title = stringResource(R.string.triple_click_adhoc_ping),
summary = stringResource(R.string.config_device_tripleClickAsAdHocPing_summary),
title = stringResource(Res.string.triple_click_adhoc_ping),
summary = stringResource(Res.string.config_device_tripleClickAsAdHocPing_summary),
checked = !formState.value.disableTripleClick,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { disableTripleClick = !it } },
@ -201,8 +201,8 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
InsetDivider()
SwitchPreference(
title = stringResource(R.string.led_heartbeat),
summary = stringResource(R.string.config_device_ledHeartbeatEnabled_summary),
title = stringResource(Res.string.led_heartbeat),
summary = stringResource(Res.string.config_device_ledHeartbeatEnabled_summary),
checked = !formState.value.ledHeartbeatDisabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { ledHeartbeatDisabled = !it } },
@ -211,7 +211,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
}
}
item {
TitledCard(title = stringResource(R.string.time_zone)) {
TitledCard(title = stringResource(Res.string.time_zone)) {
val context = LocalContext.current
val appTzPosixString by
produceState(initialValue = ZoneId.systemDefault().toPosixString()) {
@ -230,7 +230,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
EditTextPreference(
title = "",
value = formState.value.tzdef,
summary = stringResource(R.string.config_device_tzdef_summary),
summary = stringResource(Res.string.config_device_tzdef_summary),
maxSize = 64, // tzdef max_size:65
enabled = state.connected,
isError = false,
@ -257,15 +257,15 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
Spacer(modifier = Modifier.width(8.dp))
Text(text = stringResource(R.string.config_device_use_phone_tz))
Text(text = stringResource(Res.string.config_device_use_phone_tz))
}
}
}
item {
TitledCard(title = stringResource(R.string.gpio)) {
TitledCard(title = stringResource(Res.string.gpio)) {
EditTextPreference(
title = stringResource(R.string.button_gpio),
title = stringResource(Res.string.button_gpio),
value = formState.value.buttonGpio,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -275,7 +275,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.buzzer_gpio),
title = stringResource(Res.string.buzzer_gpio),
value = formState.value.buzzerGpio,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -288,10 +288,10 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
@Composable
fun RouterRoleConfirmationDialog(onDismiss: () -> Unit, onConfirm: () -> Unit) {
val dialogTitle = stringResource(R.string.are_you_sure)
val dialogTitle = stringResource(Res.string.are_you_sure)
val annotatedDialogText =
AnnotatedString.fromHtml(
htmlString = stringResource(R.string.router_role_confirmation_text),
htmlString = stringResource(Res.string.router_role_confirmation_text),
linkStyles = TextLinkStyles(style = SpanStyle(color = Color.Blue)),
)
@ -307,14 +307,14 @@ fun RouterRoleConfirmationDialog(onDismiss: () -> Unit, onConfirm: () -> Unit) {
verticalAlignment = Alignment.CenterVertically,
) {
Checkbox(checked = confirmed, onCheckedChange = { confirmed = it })
Text(stringResource(R.string.i_know_what_i_m_doing))
Text(stringResource(Res.string.i_know_what_i_m_doing))
}
}
},
onDismissRequest = onDismiss,
confirmButton = {
TextButton(onClick = onConfirm, enabled = confirmed) { Text(stringResource(R.string.accept)) }
TextButton(onClick = onConfirm, enabled = confirmed) { Text(stringResource(Res.string.accept)) }
},
dismissButton = { TextButton(onClick = onDismiss) { Text(stringResource(R.string.cancel)) } },
dismissButton = { TextButton(onClick = onDismiss) { Text(stringResource(Res.string.cancel)) } },
)
}

View file

@ -26,7 +26,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
@ -36,6 +35,7 @@ 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) {
@ -45,7 +45,7 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
val context = LocalContext.current
RadioConfigScreenList(
title = stringResource(R.string.display),
title = stringResource(Res.string.display),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -57,10 +57,10 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
},
) {
item {
TitledCard(title = stringResource(R.string.display_config)) {
TitledCard(title = stringResource(Res.string.display_config)) {
SwitchPreference(
title = stringResource(R.string.always_point_north),
summary = stringResource(R.string.config_display_compass_north_top_summary),
title = stringResource(Res.string.always_point_north),
summary = stringResource(Res.string.config_display_compass_north_top_summary),
checked = formState.value.compassNorthTop,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { compassNorthTop = it } },
@ -68,8 +68,8 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.use_12h_format),
summary = stringResource(R.string.display_time_in_12h_format),
title = stringResource(Res.string.use_12h_format),
summary = stringResource(Res.string.display_time_in_12h_format),
enabled = state.connected,
checked = formState.value.use12HClock,
onCheckedChange = { formState.value = formState.value.copy { use12HClock = it } },
@ -77,8 +77,8 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.bold_heading),
summary = stringResource(R.string.config_display_heading_bold_summary),
title = stringResource(Res.string.bold_heading),
summary = stringResource(Res.string.config_display_heading_bold_summary),
checked = formState.value.headingBold,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { headingBold = it } },
@ -86,8 +86,8 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.display_units),
summary = stringResource(R.string.config_display_units_summary),
title = stringResource(Res.string.display_units),
summary = stringResource(Res.string.config_display_units_summary),
enabled = state.connected,
items =
DisplayConfig.DisplayUnits.entries
@ -99,12 +99,12 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
}
}
item {
TitledCard(title = stringResource(R.string.advanced)) {
TitledCard(title = stringResource(Res.string.advanced)) {
val screenOnIntervals = remember { IntervalConfiguration.DISPLAY_SCREEN_ON.allowedIntervals }
val carouselIntervals = remember { IntervalConfiguration.DISPLAY_CAROUSEL.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.screen_on_for),
summary = stringResource(R.string.config_display_screen_on_secs_summary),
title = stringResource(Res.string.screen_on_for),
summary = stringResource(Res.string.config_display_screen_on_secs_summary),
enabled = state.connected,
items = screenOnIntervals.map { it to it.toDisplayString(context = context) },
selectedItem =
@ -114,8 +114,8 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.carousel_interval),
summary = stringResource(R.string.config_display_auto_screen_carousel_secs_summary),
title = stringResource(Res.string.carousel_interval),
summary = stringResource(Res.string.config_display_auto_screen_carousel_secs_summary),
enabled = state.connected,
items = carouselIntervals.map { it to it.toDisplayString(context = context) },
selectedItem =
@ -127,8 +127,8 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.wake_on_tap_or_motion),
summary = stringResource(R.string.config_display_wake_on_tap_or_motion_summary),
title = stringResource(Res.string.wake_on_tap_or_motion),
summary = stringResource(Res.string.config_display_wake_on_tap_or_motion_summary),
checked = formState.value.wakeOnTapOrMotion,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { wakeOnTapOrMotion = it } },
@ -136,8 +136,8 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.flip_screen),
summary = stringResource(R.string.config_display_flip_screen_summary),
title = stringResource(Res.string.flip_screen),
summary = stringResource(Res.string.config_display_flip_screen_summary),
checked = formState.value.flipScreen,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { flipScreen = it } },
@ -145,8 +145,8 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.display_mode),
summary = stringResource(R.string.config_display_displaymode_summary),
title = stringResource(Res.string.display_mode),
summary = stringResource(Res.string.config_display_displaymode_summary),
enabled = state.connected,
items =
DisplayConfig.DisplayMode.entries
@ -157,8 +157,8 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.oled_type),
summary = stringResource(R.string.config_display_oled_summary),
title = stringResource(Res.string.oled_type),
summary = stringResource(Res.string.config_display_oled_summary),
enabled = state.connected,
items =
DisplayConfig.OledType.entries
@ -169,7 +169,7 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.compass_orientation),
title = stringResource(Res.string.compass_orientation),
enabled = state.connected,
items =
DisplayConfig.CompassOrientation.entries

View file

@ -41,9 +41,9 @@ 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.meshtastic.core.strings.R
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
@ -102,7 +102,7 @@ fun EditDeviceProfileDialog(
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
TextButton(modifier = modifier.weight(1f), onClick = onDismiss) {
Text(stringResource(R.string.cancel))
Text(stringResource(Res.string.cancel))
}
Button(
modifier = modifier.weight(1f),
@ -117,7 +117,7 @@ fun EditDeviceProfileDialog(
},
enabled = state.values.any { it },
) {
Text(stringResource(R.string.save))
Text(stringResource(Res.string.save))
}
}
},

View file

@ -34,7 +34,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -45,6 +44,7 @@ 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) {
@ -57,7 +57,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
val context = LocalContext.current
RadioConfigScreenList(
title = stringResource(R.string.external_notification),
title = stringResource(Res.string.external_notification),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -74,9 +74,9 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
},
) {
item {
TitledCard(title = stringResource(R.string.external_notification_config)) {
TitledCard(title = stringResource(Res.string.external_notification_config)) {
SwitchPreference(
title = stringResource(R.string.external_notification_enabled),
title = stringResource(Res.string.external_notification_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -86,9 +86,9 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
}
item {
TitledCard(title = stringResource(R.string.notifications_on_message_receipt)) {
TitledCard(title = stringResource(Res.string.notifications_on_message_receipt)) {
SwitchPreference(
title = stringResource(R.string.alert_message_led),
title = stringResource(Res.string.alert_message_led),
checked = formState.value.alertMessage,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { alertMessage = it } },
@ -96,7 +96,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.alert_message_buzzer),
title = stringResource(Res.string.alert_message_buzzer),
checked = formState.value.alertMessageBuzzer,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { alertMessageBuzzer = it } },
@ -104,7 +104,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.alert_message_vibra),
title = stringResource(Res.string.alert_message_vibra),
checked = formState.value.alertMessageVibra,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { alertMessageVibra = it } },
@ -114,9 +114,9 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
}
item {
TitledCard(title = stringResource(R.string.notifications_on_alert_bell_receipt)) {
TitledCard(title = stringResource(Res.string.notifications_on_alert_bell_receipt)) {
SwitchPreference(
title = stringResource(R.string.alert_bell_led),
title = stringResource(Res.string.alert_bell_led),
checked = formState.value.alertBell,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { alertBell = it } },
@ -124,7 +124,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.alert_bell_buzzer),
title = stringResource(Res.string.alert_bell_buzzer),
checked = formState.value.alertBellBuzzer,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { alertBellBuzzer = it } },
@ -132,7 +132,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.alert_bell_vibra),
title = stringResource(Res.string.alert_bell_vibra),
checked = formState.value.alertBellVibra,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { alertBellVibra = it } },
@ -142,10 +142,10 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
}
item {
TitledCard(title = stringResource(R.string.advanced)) {
TitledCard(title = stringResource(Res.string.advanced)) {
val gpio = remember { gpioPins }
DropDownPreference(
title = stringResource(R.string.output_led_gpio),
title = stringResource(Res.string.output_led_gpio),
items = gpio,
selectedItem = formState.value.output,
enabled = state.connected,
@ -154,7 +154,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
if (formState.value.output != 0) {
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.output_led_active_high),
title = stringResource(Res.string.output_led_active_high),
checked = formState.value.active,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { active = it } },
@ -163,7 +163,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
}
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.output_buzzer_gpio),
title = stringResource(Res.string.output_buzzer_gpio),
items = gpio,
selectedItem = formState.value.outputBuzzer,
enabled = state.connected,
@ -172,7 +172,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
if (formState.value.outputBuzzer != 0) {
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.use_pwm_buzzer),
title = stringResource(Res.string.use_pwm_buzzer),
checked = formState.value.usePwm,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { usePwm = it } },
@ -181,7 +181,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
}
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.output_vibra_gpio),
title = stringResource(Res.string.output_vibra_gpio),
items = gpio,
selectedItem = formState.value.outputVibra,
enabled = state.connected,
@ -190,7 +190,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
HorizontalDivider()
val outputItems = remember { IntervalConfiguration.OUTPUT.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.output_duration_milliseconds),
title = stringResource(Res.string.output_duration_milliseconds),
items = outputItems.map { it.value to it.toDisplayString(context = context) },
selectedItem = formState.value.outputMs,
enabled = state.connected,
@ -199,7 +199,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
HorizontalDivider()
val nagItems = remember { IntervalConfiguration.NAG_TIMEOUT.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.nag_timeout_seconds),
title = stringResource(Res.string.nag_timeout_seconds),
items = nagItems.map { it.value to it.toDisplayString(context = context) },
selectedItem = formState.value.nagTimeout,
enabled = state.connected,
@ -207,7 +207,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.ringtone),
title = stringResource(Res.string.ringtone),
value = ringtoneInput,
maxSize = 230, // ringtone max_size:231
enabled = state.connected,
@ -219,7 +219,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.use_i2s_as_buzzer),
title = stringResource(Res.string.use_i2s_as_buzzer),
checked = formState.value.useI2SAsBuzzer,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { useI2SAsBuzzer = it } },

View file

@ -32,7 +32,6 @@ 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.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SignedIntegerEditTextPreference
@ -42,6 +41,7 @@ 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) {
@ -54,7 +54,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.lora),
title = stringResource(Res.string.lora),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -66,10 +66,10 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
},
) {
item {
TitledCard(title = stringResource(R.string.options)) {
TitledCard(title = stringResource(Res.string.options)) {
DropDownPreference(
title = stringResource(R.string.region_frequency_plan),
summary = stringResource(R.string.config_lora_region_summary),
title = stringResource(Res.string.region_frequency_plan),
summary = stringResource(Res.string.config_lora_region_summary),
enabled = state.connected,
items = RegionInfo.entries.map { it.regionCode to it.description },
selectedItem = formState.value.region,
@ -77,7 +77,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.use_modem_preset),
title = stringResource(Res.string.use_modem_preset),
checked = formState.value.usePreset,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { usePreset = it } },
@ -86,8 +86,8 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
HorizontalDivider()
if (formState.value.usePreset) {
DropDownPreference(
title = stringResource(R.string.modem_preset),
summary = stringResource(R.string.config_lora_modem_preset_summary),
title = stringResource(Res.string.modem_preset),
summary = stringResource(Res.string.config_lora_modem_preset_summary),
enabled = state.connected && formState.value.usePreset,
items = ChannelOption.entries.map { it.modemPreset to stringResource(it.labelRes) },
selectedItem = formState.value.modemPreset,
@ -95,7 +95,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
)
} else {
EditTextPreference(
title = stringResource(R.string.bandwidth),
title = stringResource(Res.string.bandwidth),
value = formState.value.bandwidth,
enabled = state.connected && !formState.value.usePreset,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -103,7 +103,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.spread_factor),
title = stringResource(Res.string.spread_factor),
value = formState.value.spreadFactor,
enabled = state.connected && !formState.value.usePreset,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -111,7 +111,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.coding_rate),
title = stringResource(Res.string.coding_rate),
value = formState.value.codingRate,
enabled = state.connected && !formState.value.usePreset,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -122,9 +122,9 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
}
item {
TitledCard(title = stringResource(R.string.advanced)) {
TitledCard(title = stringResource(Res.string.advanced)) {
SwitchPreference(
title = stringResource(R.string.ignore_mqtt),
title = stringResource(Res.string.ignore_mqtt),
checked = formState.value.ignoreMqtt,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { ignoreMqtt = it } },
@ -132,7 +132,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.ok_to_mqtt),
title = stringResource(Res.string.ok_to_mqtt),
checked = formState.value.configOkToMqtt,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { configOkToMqtt = it } },
@ -140,7 +140,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.tx_enabled),
title = stringResource(Res.string.tx_enabled),
checked = formState.value.txEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { txEnabled = it } },
@ -149,8 +149,8 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
HorizontalDivider()
val hopLimitItems = remember { hopLimits }
DropDownPreference(
title = stringResource(R.string.hop_limit),
summary = stringResource(R.string.config_lora_hop_limit_summary),
title = stringResource(Res.string.hop_limit),
summary = stringResource(Res.string.config_lora_hop_limit_summary),
items = hopLimitItems,
selectedItem = formState.value.hopLimit,
onItemSelected = { formState.value = formState.value.copy { hopLimit = it } },
@ -159,8 +159,8 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
HorizontalDivider()
var isFocusedSlot by remember { mutableStateOf(false) }
EditTextPreference(
title = stringResource(R.string.frequency_slot),
summary = stringResource(R.string.config_lora_frequency_slot_summary),
title = stringResource(Res.string.frequency_slot),
summary = stringResource(Res.string.config_lora_frequency_slot_summary),
value =
if (isFocusedSlot || formState.value.channelNum != 0) {
formState.value.channelNum
@ -178,7 +178,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.sx126x_rx_boosted_gain),
title = stringResource(Res.string.sx126x_rx_boosted_gain),
checked = formState.value.sx126XRxBoostedGain,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { sx126XRxBoostedGain = it } },
@ -187,7 +187,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
HorizontalDivider()
var isFocusedOverride by remember { mutableStateOf(false) }
EditTextPreference(
title = stringResource(R.string.override_frequency_mhz),
title = stringResource(Res.string.override_frequency_mhz),
value =
if (isFocusedOverride || formState.value.overrideFrequency != 0f) {
formState.value.overrideFrequency
@ -201,7 +201,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
)
HorizontalDivider()
SignedIntegerEditTextPreference(
title = stringResource(R.string.tx_power_dbm),
title = stringResource(Res.string.tx_power_dbm),
value = formState.value.txPower,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -210,7 +210,7 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
if (viewModel.hasPaFan) {
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.pa_fan_disabled),
title = stringResource(Res.string.pa_fan_disabled),
checked = formState.value.paFanDisabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { paFanDisabled = it } },

View file

@ -31,7 +31,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditPasswordPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -39,6 +38,7 @@ 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) {
@ -66,7 +66,7 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.mqtt),
title = stringResource(Res.string.mqtt),
onBack = onBack,
configState = formState,
enabled = state.connected && consentValid,
@ -78,9 +78,9 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
},
) {
item {
TitledCard(title = stringResource(R.string.mqtt_config)) {
TitledCard(title = stringResource(Res.string.mqtt_config)) {
SwitchPreference(
title = stringResource(R.string.mqtt_enabled),
title = stringResource(Res.string.mqtt_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -88,7 +88,7 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.address),
title = stringResource(Res.string.address),
value = formState.value.address,
maxSize = 63, // address max_size:64
enabled = state.connected,
@ -100,7 +100,7 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.username),
title = stringResource(Res.string.username),
value = formState.value.username,
maxSize = 63, // username max_size:64
enabled = state.connected,
@ -112,7 +112,7 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
EditPasswordPreference(
title = stringResource(R.string.password),
title = stringResource(Res.string.password),
value = formState.value.password,
maxSize = 63, // password max_size:64
enabled = state.connected,
@ -121,7 +121,7 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.encryption_enabled),
title = stringResource(Res.string.encryption_enabled),
checked = formState.value.encryptionEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { encryptionEnabled = it } },
@ -129,18 +129,18 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.json_output_enabled),
title = stringResource(Res.string.json_output_enabled),
checked = formState.value.jsonEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { jsonEnabled = it } },
containerColor = CardDefaults.cardColors().containerColor,
)
HorizontalDivider()
val defaultAddress = stringResource(R.string.default_mqtt_address)
val defaultAddress = stringResource(Res.string.default_mqtt_address)
val isDefault = formState.value.address.isEmpty() || formState.value.address.contains(defaultAddress)
val enforceTls = isDefault && formState.value.proxyToClientEnabled
SwitchPreference(
title = stringResource(R.string.tls_enabled),
title = stringResource(Res.string.tls_enabled),
checked = formState.value.tlsEnabled || enforceTls,
enabled = state.connected && !enforceTls,
onCheckedChange = { formState.value = formState.value.copy { tlsEnabled = it } },
@ -148,7 +148,7 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.root_topic),
title = stringResource(Res.string.root_topic),
value = formState.value.root,
maxSize = 31, // root max_size:32
enabled = state.connected,
@ -160,7 +160,7 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.proxy_to_client_enabled),
title = stringResource(Res.string.proxy_to_client_enabled),
checked = formState.value.proxyToClientEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { proxyToClientEnabled = it } },
@ -170,7 +170,7 @@ fun MQTTConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
}
item {
TitledCard(title = stringResource(R.string.map_reporting)) {
TitledCard(title = stringResource(Res.string.map_reporting)) {
MapReportingPreference(
mapReportingEnabled = formState.value.mapReportingEnabled,
onMapReportingEnabledChanged = {

View file

@ -41,13 +41,13 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.meshtastic.core.model.util.DistanceUnit
import org.meshtastic.core.model.util.toDistanceString
import org.meshtastic.core.strings.R
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
@ -70,8 +70,8 @@ fun MapReportingPreference(
var showMapReportingWarning by rememberSaveable { mutableStateOf(mapReportingEnabled) }
LaunchedEffect(mapReportingEnabled) { showMapReportingWarning = mapReportingEnabled }
SwitchPreference(
title = stringResource(R.string.map_reporting),
summary = stringResource(R.string.map_reporting_summary),
title = stringResource(Res.string.map_reporting),
summary = stringResource(Res.string.map_reporting_summary),
checked = showMapReportingWarning,
enabled = enabled,
onCheckedChange = { checked ->
@ -85,13 +85,13 @@ fun MapReportingPreference(
)
AnimatedVisibility(showMapReportingWarning) {
Card(modifier = Modifier.padding(16.dp)) {
Text(text = stringResource(R.string.map_reporting_consent_header), modifier = Modifier.padding(16.dp))
Text(text = stringResource(Res.string.map_reporting_consent_header), modifier = Modifier.padding(16.dp))
HorizontalDivider()
Text(stringResource(R.string.map_reporting_consent_text), modifier = Modifier.padding(16.dp))
Text(stringResource(Res.string.map_reporting_consent_text), modifier = Modifier.padding(16.dp))
SwitchPreference(
title = stringResource(R.string.i_agree),
summary = stringResource(R.string.i_agree_to_share_my_location),
title = stringResource(Res.string.i_agree),
summary = stringResource(Res.string.i_agree_to_share_my_location),
checked = shouldReportLocation,
enabled = enabled,
onCheckedChange = { checked ->
@ -125,7 +125,7 @@ fun MapReportingPreference(
val publishItems = remember { IntervalConfiguration.BROADCAST_MEDIUM.allowedIntervals }
DropDownPreference(
modifier = Modifier.padding(bottom = 16.dp),
title = stringResource(R.string.map_reporting_interval_seconds),
title = stringResource(Res.string.map_reporting_interval_seconds),
items = publishItems.map { it.value to it.toDisplayString(context = context) },
selectedItem = publishIntervalSecs,
enabled = enabled,

View file

@ -26,13 +26,13 @@ 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.meshtastic.core.strings.R
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) {
@ -42,7 +42,7 @@ fun NeighborInfoConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.neighbor_info),
title = stringResource(Res.string.neighbor_info),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -54,9 +54,9 @@ fun NeighborInfoConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
},
) {
item {
TitledCard(title = stringResource(R.string.neighbor_info_config)) {
TitledCard(title = stringResource(Res.string.neighbor_info_config)) {
SwitchPreference(
title = stringResource(R.string.neighbor_info_enabled),
title = stringResource(Res.string.neighbor_info_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -64,7 +64,7 @@ fun NeighborInfoConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.update_interval_seconds),
title = stringResource(Res.string.update_interval_seconds),
value = formState.value.updateInterval,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -72,8 +72,8 @@ fun NeighborInfoConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.transmit_over_lora),
summary = stringResource(R.string.config_device_transmitOverLora_summary),
title = stringResource(Res.string.transmit_over_lora),
summary = stringResource(Res.string.config_device_transmitOverLora_summary),
checked = formState.value.transmitOverLora,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { transmitOverLora = it } },

View file

@ -42,7 +42,6 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanOptions
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditIPv4Preference
import org.meshtastic.core.ui.component.EditPasswordPreference
@ -55,10 +54,11 @@ 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 = {}) =
SimpleAlertDialog(title = R.string.error, text = R.string.wifi_qr_code_error, onDismiss = onDismiss)
SimpleAlertDialog(title = Res.string.error, text = Res.string.wifi_qr_code_error, onDismiss = onDismiss)
@Composable
fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack: () -> Unit) {
@ -100,7 +100,7 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.network),
title = stringResource(Res.string.network),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -118,11 +118,11 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
connectionStatus.ethernet?.status?.isConnected == true
) {
item {
TitledCard(title = stringResource(R.string.connection_status)) {
TitledCard(title = stringResource(Res.string.connection_status)) {
connectionStatus.wifi?.let { wifiStatus ->
if (wifiStatus.status.isConnected) {
ListItem(
text = stringResource(R.string.wifi_ip),
text = stringResource(Res.string.wifi_ip),
supportingText = formatIpAddress(wifiStatus.status.ipAddress),
trailingIcon = null,
)
@ -131,7 +131,7 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
connectionStatus.ethernet?.let { ethernetStatus ->
if (ethernetStatus.status.isConnected) {
ListItem(
text = stringResource(R.string.ethernet_ip),
text = stringResource(Res.string.ethernet_ip),
supportingText = formatIpAddress(ethernetStatus.status.ipAddress),
trailingIcon = null,
)
@ -143,10 +143,10 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
}
if (state.metadata?.hasWifi == true) {
item {
TitledCard(title = stringResource(R.string.wifi_config)) {
TitledCard(title = stringResource(Res.string.wifi_config)) {
SwitchPreference(
title = stringResource(R.string.wifi_enabled),
summary = stringResource(R.string.config_network_wifi_enabled_summary),
title = stringResource(Res.string.wifi_enabled),
summary = stringResource(Res.string.config_network_wifi_enabled_summary),
checked = formState.value.wifiEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { wifiEnabled = it } },
@ -154,7 +154,7 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.ssid),
title = stringResource(Res.string.ssid),
value = formState.value.wifiSsid,
maxSize = 32, // wifi_ssid max_size:33
enabled = state.connected,
@ -166,7 +166,7 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
EditPasswordPreference(
title = stringResource(R.string.password),
title = stringResource(Res.string.password),
value = formState.value.wifiPsk,
maxSize = 64, // wifi_psk max_size:65
enabled = state.connected,
@ -179,17 +179,17 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp).height(48.dp),
enabled = state.connected,
) {
Text(text = stringResource(R.string.wifi_qr_code_scan))
Text(text = stringResource(Res.string.wifi_qr_code_scan))
}
}
}
}
if (state.metadata?.hasEthernet == true) {
item {
TitledCard(title = stringResource(R.string.ethernet_config)) {
TitledCard(title = stringResource(Res.string.ethernet_config)) {
SwitchPreference(
title = stringResource(R.string.ethernet_enabled),
summary = stringResource(R.string.config_network_eth_enabled_summary),
title = stringResource(Res.string.ethernet_enabled),
summary = stringResource(Res.string.config_network_eth_enabled_summary),
checked = formState.value.ethEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { ethEnabled = it } },
@ -201,10 +201,10 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
if (state.metadata?.hasEthernet == true || state.metadata?.hasWifi == true) {
item {
TitledCard(title = stringResource(R.string.udp_config)) {
TitledCard(title = stringResource(Res.string.udp_config)) {
SwitchPreference(
title = stringResource(R.string.udp_enabled),
summary = stringResource(R.string.config_network_udp_enabled_summary),
title = stringResource(Res.string.udp_enabled),
summary = stringResource(Res.string.config_network_udp_enabled_summary),
checked = formState.value.enabledProtocols == 1,
enabled = state.connected,
onCheckedChange = {
@ -218,9 +218,9 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
}
item {
TitledCard(title = stringResource(R.string.advanced)) {
TitledCard(title = stringResource(Res.string.advanced)) {
EditTextPreference(
title = stringResource(R.string.ntp_server),
title = stringResource(Res.string.ntp_server),
value = formState.value.ntpServer,
maxSize = 32, // ntp_server max_size:33
enabled = state.connected,
@ -232,7 +232,7 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.rsyslog_server),
title = stringResource(Res.string.rsyslog_server),
value = formState.value.rsyslogServer,
maxSize = 32, // rsyslog_server max_size:33
enabled = state.connected,
@ -244,7 +244,7 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.ipv4_mode),
title = stringResource(Res.string.ipv4_mode),
enabled = state.connected,
items =
NetworkConfig.AddressMode.entries
@ -255,7 +255,7 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
EditIPv4Preference(
title = stringResource(R.string.ip),
title = stringResource(Res.string.ip),
value = formState.value.ipv4Config.ip,
enabled = state.connected && formState.value.addressMode == NetworkConfig.AddressMode.STATIC,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -266,7 +266,7 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
EditIPv4Preference(
title = stringResource(R.string.gateway),
title = stringResource(Res.string.gateway),
value = formState.value.ipv4Config.gateway,
enabled = state.connected && formState.value.addressMode == NetworkConfig.AddressMode.STATIC,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -277,7 +277,7 @@ fun NetworkConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
)
HorizontalDivider()
EditIPv4Preference(
title = stringResource(R.string.subnet),
title = stringResource(Res.string.subnet),
value = formState.value.ipv4Config.subnet,
enabled = state.connected && formState.value.addressMode == NetworkConfig.AddressMode.STATIC,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),

View file

@ -36,8 +36,8 @@ 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.meshtastic.core.strings.R
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 = {}) {
@ -58,10 +58,10 @@ fun <T> PacketResponseStateDialog(state: ResponseState<T>, onDismiss: () -> Unit
if (state.total == state.completed) onComplete()
}
if (state is ResponseState.Success) {
Text(text = stringResource(R.string.delivery_confirmed))
Text(text = stringResource(Res.string.delivery_confirmed))
}
if (state is ResponseState.Error) {
Text(text = stringResource(R.string.error), minLines = 2)
Text(text = stringResource(Res.string.error), minLines = 2)
Text(text = state.error.asString())
}
}
@ -80,7 +80,7 @@ fun <T> PacketResponseStateDialog(state: ResponseState<T>, onDismiss: () -> Unit
},
modifier = Modifier.padding(top = 16.dp),
) {
Text(stringResource(R.string.close))
Text(stringResource(Res.string.close))
}
}
},

View file

@ -28,7 +28,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.SignedIntegerEditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -38,6 +37,7 @@ 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) {
@ -48,7 +48,7 @@ fun PaxcounterConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), on
val context = LocalContext.current
RadioConfigScreenList(
title = stringResource(R.string.paxcounter),
title = stringResource(Res.string.paxcounter),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -60,9 +60,9 @@ fun PaxcounterConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), on
},
) {
item {
TitledCard(title = stringResource(R.string.paxcounter_config)) {
TitledCard(title = stringResource(Res.string.paxcounter_config)) {
SwitchPreference(
title = stringResource(R.string.paxcounter_enabled),
title = stringResource(Res.string.paxcounter_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -71,7 +71,7 @@ fun PaxcounterConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), on
HorizontalDivider()
val items = remember { IntervalConfiguration.PAX_COUNTER.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.update_interval_seconds),
title = stringResource(Res.string.update_interval_seconds),
selectedItem = formState.value.paxcounterUpdateInterval.toLong(),
enabled = state.connected,
items = items.map { it.value to it.toDisplayString(context = context) },
@ -81,7 +81,7 @@ fun PaxcounterConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), on
)
HorizontalDivider()
SignedIntegerEditTextPreference(
title = stringResource(R.string.wifi_rssi_threshold_defaults_to_80),
title = stringResource(Res.string.wifi_rssi_threshold_defaults_to_80),
value = formState.value.wifiThreshold,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -89,7 +89,7 @@ fun PaxcounterConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), on
)
HorizontalDivider()
SignedIntegerEditTextPreference(
title = stringResource(R.string.ble_rssi_threshold_defaults_to_80),
title = stringResource(Res.string.ble_rssi_threshold_defaults_to_80),
value = formState.value.bleThreshold,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),

View file

@ -44,7 +44,6 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberPermissionState
import kotlinx.coroutines.launch
import org.meshtastic.core.model.Position
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.BitwisePreference
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
@ -58,6 +57,7 @@ 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
@ -121,7 +121,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
val focusManager = LocalFocusManager.current
val context = LocalContext.current
RadioConfigScreenList(
title = stringResource(R.string.position),
title = stringResource(Res.string.position),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -143,11 +143,11 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
},
) {
item {
TitledCard(title = stringResource(R.string.position_packet)) {
TitledCard(title = stringResource(Res.string.position_packet)) {
val items = remember { IntervalConfiguration.POSITION_BROADCAST.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.broadcast_interval),
summary = stringResource(R.string.config_position_broadcast_secs_summary),
title = stringResource(Res.string.broadcast_interval),
summary = stringResource(Res.string.config_position_broadcast_secs_summary),
enabled = state.connected,
items = items.map { it to it.toDisplayString(context = context) },
selectedItem =
@ -158,7 +158,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.smart_position),
title = stringResource(Res.string.smart_position),
checked = formState.value.positionBroadcastSmartEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { positionBroadcastSmartEnabled = it } },
@ -168,9 +168,9 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
HorizontalDivider()
val smartItems = remember { IntervalConfiguration.SMART_BROADCAST_MINIMUM.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.minimum_interval),
title = stringResource(Res.string.minimum_interval),
summary =
stringResource(R.string.config_position_broadcast_smart_minimum_interval_secs_summary),
stringResource(Res.string.config_position_broadcast_smart_minimum_interval_secs_summary),
enabled = state.connected,
items = smartItems.map { it to it.toDisplayString(context = context) },
selectedItem =
@ -183,8 +183,8 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.minimum_distance),
summary = stringResource(R.string.config_position_broadcast_smart_minimum_distance_summary),
title = stringResource(Res.string.minimum_distance),
summary = stringResource(Res.string.config_position_broadcast_smart_minimum_distance_summary),
value = formState.value.broadcastSmartMinimumDistance,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -196,9 +196,9 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
}
}
item {
TitledCard(title = stringResource(R.string.device_gps)) {
TitledCard(title = stringResource(Res.string.device_gps)) {
SwitchPreference(
title = stringResource(R.string.fixed_position),
title = stringResource(Res.string.fixed_position),
checked = formState.value.fixedPosition,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { fixedPosition = it } },
@ -207,7 +207,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
if (formState.value.fixedPosition) {
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.latitude),
title = stringResource(Res.string.latitude),
value = locationInput.latitude,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -219,7 +219,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.longitude),
title = stringResource(Res.string.longitude),
value = locationInput.longitude,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -231,7 +231,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.altitude),
title = stringResource(Res.string.altitude),
value = locationInput.altitude,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -242,12 +242,12 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
enabled = state.connected,
onClick = { coroutineScope.launch { locationPermissionState.launchPermissionRequest() } },
) {
Text(text = stringResource(R.string.position_config_set_fixed_from_phone))
Text(text = stringResource(Res.string.position_config_set_fixed_from_phone))
}
} else {
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.gps_mode),
title = stringResource(Res.string.gps_mode),
enabled = state.connected,
items =
PositionConfig.GpsMode.entries
@ -259,8 +259,8 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
HorizontalDivider()
val items = remember { IntervalConfiguration.GPS_UPDATE.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.update_interval),
summary = stringResource(R.string.config_position_gps_update_interval_summary),
title = stringResource(Res.string.update_interval),
summary = stringResource(Res.string.config_position_gps_update_interval_summary),
enabled = state.connected,
items = items.map { it to it.toDisplayString(context = context) },
selectedItem =
@ -273,10 +273,10 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
}
}
item {
TitledCard(title = stringResource(R.string.position_flags)) {
TitledCard(title = stringResource(Res.string.position_flags)) {
BitwisePreference(
title = stringResource(R.string.position_flags),
summary = stringResource(R.string.config_position_flags_summary),
title = stringResource(Res.string.position_flags),
summary = stringResource(Res.string.config_position_flags_summary),
value = formState.value.positionFlags,
enabled = state.connected,
items =
@ -291,10 +291,10 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
}
}
item {
TitledCard(title = stringResource(R.string.advanced_device_gps)) {
TitledCard(title = stringResource(Res.string.advanced_device_gps)) {
val pins = remember { gpioPins }
DropDownPreference(
title = stringResource(R.string.gps_receive_gpio),
title = stringResource(Res.string.gps_receive_gpio),
enabled = state.connected,
items = pins,
selectedItem = formState.value.rxGpio,
@ -302,7 +302,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.gps_transmit_gpio),
title = stringResource(Res.string.gps_transmit_gpio),
enabled = state.connected,
items = pins,
selectedItem = formState.value.txGpio,
@ -310,7 +310,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.gps_en_gpio),
title = stringResource(Res.string.gps_en_gpio),
enabled = state.connected,
items = pins,
selectedItem = formState.value.gpsEnGpio,

View file

@ -28,7 +28,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -38,6 +37,7 @@ 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) {
@ -48,7 +48,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
val context = LocalContext.current
RadioConfigScreenList(
title = stringResource(R.string.power),
title = stringResource(Res.string.power),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -60,10 +60,10 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
},
) {
item {
TitledCard(title = stringResource(R.string.power_config)) {
TitledCard(title = stringResource(Res.string.power_config)) {
SwitchPreference(
title = stringResource(R.string.enable_power_saving_mode),
summary = stringResource(R.string.config_power_is_power_saving_summary),
title = stringResource(Res.string.enable_power_saving_mode),
summary = stringResource(Res.string.config_power_is_power_saving_summary),
checked = formState.value.isPowerSaving,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { isPowerSaving = it } },
@ -72,7 +72,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
HorizontalDivider()
val items = remember { IntervalConfiguration.ALL.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.shutdown_on_power_loss),
title = stringResource(Res.string.shutdown_on_power_loss),
selectedItem = formState.value.onBatteryShutdownAfterSecs.toLong(),
enabled = state.connected,
items = items.map { it.value to it.toDisplayString(context = context) },
@ -82,7 +82,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.adc_multiplier_override),
title = stringResource(Res.string.adc_multiplier_override),
checked = formState.value.adcMultiplierOverride > 0f,
enabled = state.connected,
onCheckedChange = {
@ -93,7 +93,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
if (formState.value.adcMultiplierOverride > 0f) {
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.adc_multiplier_override_ratio),
title = stringResource(Res.string.adc_multiplier_override_ratio),
value = formState.value.adcMultiplierOverride,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -103,7 +103,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
HorizontalDivider()
val waitBluetoothItems = remember { IntervalConfiguration.NAG_TIMEOUT.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.wait_for_bluetooth_duration_seconds),
title = stringResource(Res.string.wait_for_bluetooth_duration_seconds),
selectedItem = formState.value.waitBluetoothSecs.toLong(),
enabled = state.connected,
items = waitBluetoothItems.map { it.value to it.toDisplayString(context = context) },
@ -112,7 +112,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
HorizontalDivider()
val sdsSecsItems = remember { IntervalConfiguration.ALL.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.super_deep_sleep_duration_seconds),
title = stringResource(Res.string.super_deep_sleep_duration_seconds),
selectedItem = formState.value.sdsSecs.toLong(),
onItemSelected = { formState.value = formState.value.copy { sdsSecs = it.toInt() } },
enabled = state.connected,
@ -121,7 +121,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
HorizontalDivider()
val minWakeItems = remember { IntervalConfiguration.NAG_TIMEOUT.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.minimum_wake_time_seconds),
title = stringResource(Res.string.minimum_wake_time_seconds),
selectedItem = formState.value.minWakeSecs.toLong(),
enabled = state.connected,
items = minWakeItems.map { it.value to it.toDisplayString(context = context) },
@ -129,7 +129,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.battery_ina_2xx_i2c_address),
title = stringResource(Res.string.battery_ina_2xx_i2c_address),
value = formState.value.deviceBatteryInaAddress,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),

View file

@ -41,10 +41,10 @@ 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.meshtastic.core.strings.R
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(
@ -106,12 +106,12 @@ fun <T : MessageLite> RadioConfigScreenList(
) {
PreferenceFooter(
enabled = enabled && configState.isDirty,
negativeText = stringResource(R.string.discard_changes),
negativeText = stringResource(Res.string.discard_changes),
onNegativeClicked = {
focusManager.clearFocus()
configState.reset()
},
positiveText = stringResource(R.string.save_changes),
positiveText = stringResource(Res.string.save_changes),
onPositiveClicked = {
focusManager.clearFocus()
onSave(configState.value)

View file

@ -26,7 +26,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
@ -35,6 +34,7 @@ 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) {
@ -44,7 +44,7 @@ fun RangeTestConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
val context = LocalContext.current
RadioConfigScreenList(
title = stringResource(R.string.range_test),
title = stringResource(Res.string.range_test),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -56,9 +56,9 @@ fun RangeTestConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
},
) {
item {
TitledCard(title = stringResource(R.string.range_test_config)) {
TitledCard(title = stringResource(Res.string.range_test_config)) {
SwitchPreference(
title = stringResource(R.string.range_test_enabled),
title = stringResource(Res.string.range_test_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -67,7 +67,7 @@ fun RangeTestConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
HorizontalDivider()
val rangeItems = remember { IntervalConfiguration.RANGE_TEST_SENDER.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.sender_message_interval_seconds),
title = stringResource(Res.string.sender_message_interval_seconds),
selectedItem = formState.value.sender.toLong(),
enabled = state.connected,
items = rangeItems.map { it.value to it.toDisplayString(context = context) },
@ -75,7 +75,7 @@ fun RangeTestConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.save_csv_in_storage_esp32_only),
title = stringResource(Res.string.save_csv_in_storage_esp32_only),
checked = formState.value.save,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { save = it } },

View file

@ -26,13 +26,13 @@ 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.meshtastic.core.strings.R
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) {
@ -42,7 +42,7 @@ fun RemoteHardwareConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel()
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.remote_hardware),
title = stringResource(Res.string.remote_hardware),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -54,9 +54,9 @@ fun RemoteHardwareConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel()
},
) {
item {
TitledCard(title = stringResource(R.string.remote_hardware_config)) {
TitledCard(title = stringResource(Res.string.remote_hardware_config)) {
SwitchPreference(
title = stringResource(R.string.remote_hardware_enabled),
title = stringResource(Res.string.remote_hardware_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -64,7 +64,7 @@ fun RemoteHardwareConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel()
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.allow_undefined_pin_access),
title = stringResource(Res.string.allow_undefined_pin_access),
checked = formState.value.allowUndefinedPinAccess,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { allowUndefinedPinAccess = it } },
@ -72,7 +72,7 @@ fun RemoteHardwareConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel()
)
HorizontalDivider()
EditListPreference(
title = stringResource(R.string.available_pins),
title = stringResource(Res.string.available_pins),
list = formState.value.availablePinsList,
maxCount = 4, // available_pins max_count:4
enabled = state.connected,

View file

@ -46,7 +46,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.protobuf.ByteString
import org.meshtastic.core.model.util.encodeToString
import org.meshtastic.core.model.util.toByteString
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.CopyIconButton
import org.meshtastic.core.ui.component.EditBase64Preference
import org.meshtastic.core.ui.component.EditListPreference
@ -57,6 +56,7 @@ 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
@ -96,8 +96,8 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
var showEditSecurityConfigDialog by rememberSaveable { mutableStateOf(false) }
if (showEditSecurityConfigDialog) {
AlertDialog(
title = { Text(text = stringResource(R.string.export_keys)) },
text = { Text(text = stringResource(R.string.export_keys_confirmation)) },
title = { Text(text = stringResource(Res.string.export_keys)) },
text = { Text(text = stringResource(Res.string.export_keys_confirmation)) },
onDismissRequest = { showEditSecurityConfigDialog = false },
confirmButton = {
TextButton(
@ -115,7 +115,7 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
exportConfigLauncher.launch(intent)
},
) {
Text(stringResource(R.string.okay))
Text(stringResource(Res.string.okay))
}
},
)
@ -123,7 +123,7 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.security),
title = stringResource(Res.string.security),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -135,10 +135,10 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
},
) {
item {
TitledCard(title = stringResource(R.string.direct_message_key)) {
TitledCard(title = stringResource(Res.string.direct_message_key)) {
EditBase64Preference(
title = stringResource(R.string.public_key),
summary = stringResource(R.string.config_security_public_key),
title = stringResource(Res.string.public_key),
summary = stringResource(Res.string.config_security_public_key),
value = publicKey,
enabled = state.connected,
readOnly = true,
@ -152,8 +152,8 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
)
HorizontalDivider()
EditBase64Preference(
title = stringResource(R.string.private_key),
summary = stringResource(R.string.config_security_private_key),
title = stringResource(Res.string.private_key),
summary = stringResource(Res.string.config_security_private_key),
value = formState.value.privateKey,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -167,7 +167,7 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
HorizontalDivider()
NodeActionButton(
modifier = Modifier.padding(horizontal = 8.dp),
title = stringResource(R.string.regenerate_private_key),
title = stringResource(Res.string.regenerate_private_key),
enabled = state.connected,
icon = Icons.TwoTone.Warning,
onClick = { showKeyGenerationDialog = true },
@ -175,7 +175,7 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
HorizontalDivider()
NodeActionButton(
modifier = Modifier.padding(horizontal = 8.dp),
title = stringResource(R.string.export_keys),
title = stringResource(Res.string.export_keys),
enabled = state.connected,
icon = Icons.TwoTone.Warning,
onClick = { showEditSecurityConfigDialog = true },
@ -183,10 +183,10 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
}
}
item {
TitledCard(title = stringResource(R.string.admin_keys)) {
TitledCard(title = stringResource(Res.string.admin_keys)) {
EditListPreference(
title = stringResource(R.string.admin_key),
summary = stringResource(R.string.config_security_admin_key),
title = stringResource(Res.string.admin_key),
summary = stringResource(Res.string.config_security_admin_key),
list = formState.value.adminKeyList,
maxCount = 3,
enabled = state.connected,
@ -202,10 +202,10 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
}
}
item {
TitledCard(title = stringResource(R.string.logs)) {
TitledCard(title = stringResource(Res.string.logs)) {
SwitchPreference(
title = stringResource(R.string.serial_console),
summary = stringResource(R.string.config_security_serial_enabled),
title = stringResource(Res.string.serial_console),
summary = stringResource(Res.string.config_security_serial_enabled),
checked = formState.value.serialEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { serialEnabled = it } },
@ -213,8 +213,8 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.debug_log_api_enabled),
summary = stringResource(R.string.config_security_debug_log_api_enabled),
title = stringResource(Res.string.debug_log_api_enabled),
summary = stringResource(Res.string.config_security_debug_log_api_enabled),
checked = formState.value.debugLogApiEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { debugLogApiEnabled = it } },
@ -223,10 +223,10 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
}
}
item {
TitledCard(title = stringResource(R.string.administration)) {
TitledCard(title = stringResource(Res.string.administration)) {
SwitchPreference(
title = stringResource(R.string.managed_mode),
summary = stringResource(R.string.config_security_is_managed),
title = stringResource(Res.string.managed_mode),
summary = stringResource(Res.string.config_security_is_managed),
checked = formState.value.isManaged,
enabled = state.connected && formState.value.adminKeyCount > 0,
onCheckedChange = { formState.value = formState.value.copy { isManaged = it } },
@ -234,7 +234,7 @@ fun SecurityConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.legacy_admin_channel),
title = stringResource(Res.string.legacy_admin_channel),
checked = formState.value.adminChannelEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { adminChannelEnabled = it } },
@ -255,8 +255,8 @@ fun PrivateKeyRegenerateDialog(
if (showKeyGenerationDialog) {
AlertDialog(
onDismissRequest = onDismiss,
title = { Text(text = stringResource(R.string.regenerate_private_key)) },
text = { Text(text = stringResource(R.string.regenerate_keys_confirmation)) },
title = { Text(text = stringResource(Res.string.regenerate_private_key)) },
text = { Text(text = stringResource(Res.string.regenerate_keys_confirmation)) },
confirmButton = {
TextButton(
onClick = {
@ -279,10 +279,10 @@ fun PrivateKeyRegenerateDialog(
onConfirm(securityInput)
},
) {
Text(stringResource(R.string.okay))
Text(stringResource(Res.string.okay))
}
},
dismissButton = { TextButton(onClick = onDismiss) { Text(stringResource(R.string.cancel)) } },
dismissButton = { TextButton(onClick = onDismiss) { Text(stringResource(Res.string.cancel)) } },
)
}
}

View file

@ -26,7 +26,6 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
@ -35,6 +34,7 @@ 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) {
@ -44,7 +44,7 @@ fun SerialConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.serial),
title = stringResource(Res.string.serial),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -56,9 +56,9 @@ fun SerialConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
},
) {
item {
TitledCard(title = stringResource(R.string.serial_config)) {
TitledCard(title = stringResource(Res.string.serial_config)) {
SwitchPreference(
title = stringResource(R.string.serial_enabled),
title = stringResource(Res.string.serial_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -66,7 +66,7 @@ fun SerialConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.echo_enabled),
title = stringResource(Res.string.echo_enabled),
checked = formState.value.echo,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { echo = it } },
@ -90,7 +90,7 @@ fun SerialConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.serial_baud_rate),
title = stringResource(Res.string.serial_baud_rate),
enabled = state.connected,
items =
SerialConfig.Serial_Baud.entries
@ -101,7 +101,7 @@ fun SerialConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.timeout),
title = stringResource(Res.string.timeout),
value = formState.value.timeout,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -109,7 +109,7 @@ fun SerialConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
)
HorizontalDivider()
DropDownPreference(
title = stringResource(R.string.serial_mode),
title = stringResource(Res.string.serial_mode),
enabled = state.connected,
items =
SerialConfig.Serial_Mode.entries
@ -120,7 +120,7 @@ fun SerialConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.override_console_serial_port),
title = stringResource(Res.string.override_console_serial_port),
checked = formState.value.overrideConsoleSerialPort,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { overrideConsoleSerialPort = it } },

View file

@ -26,13 +26,13 @@ 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.meshtastic.core.strings.R
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) {
@ -42,7 +42,7 @@ fun StoreForwardConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.store_forward),
title = stringResource(Res.string.store_forward),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -54,9 +54,9 @@ fun StoreForwardConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
},
) {
item {
TitledCard(title = stringResource(R.string.store_forward_config)) {
TitledCard(title = stringResource(Res.string.store_forward_config)) {
SwitchPreference(
title = stringResource(R.string.store_forward_enabled),
title = stringResource(Res.string.store_forward_enabled),
checked = formState.value.enabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { this.enabled = it } },
@ -64,7 +64,7 @@ fun StoreForwardConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.heartbeat),
title = stringResource(Res.string.heartbeat),
checked = formState.value.heartbeat,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { heartbeat = it } },
@ -72,7 +72,7 @@ fun StoreForwardConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.number_of_records),
title = stringResource(Res.string.number_of_records),
value = formState.value.records,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -80,7 +80,7 @@ fun StoreForwardConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.history_return_max),
title = stringResource(Res.string.history_return_max),
value = formState.value.historyReturnMax,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -88,7 +88,7 @@ fun StoreForwardConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.history_return_window),
title = stringResource(Res.string.history_return_window),
value = formState.value.historyReturnWindow,
enabled = state.connected,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
@ -96,7 +96,7 @@ fun StoreForwardConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(),
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.server),
title = stringResource(Res.string.server),
checked = formState.value.isServer,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { isServer = it } },

View file

@ -27,7 +27,6 @@ import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
@ -36,6 +35,7 @@ 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"
@ -49,7 +49,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
val context = LocalContext.current
RadioConfigScreenList(
title = stringResource(R.string.telemetry),
title = stringResource(Res.string.telemetry),
onBack = onBack,
configState = formState,
enabled = state.connected,
@ -61,11 +61,11 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
},
) {
item {
TitledCard(title = stringResource(R.string.telemetry_config)) {
TitledCard(title = stringResource(Res.string.telemetry_config)) {
if (DeviceVersion(firmwareVersion) >= DeviceVersion(MIN_FW_FOR_TELEMETRY_TOGGLE)) {
SwitchPreference(
title = stringResource(R.string.device_telemetry_enabled),
summary = stringResource(R.string.device_telemetry_enabled_summary),
title = stringResource(Res.string.device_telemetry_enabled),
summary = stringResource(Res.string.device_telemetry_enabled_summary),
checked = formState.value.deviceTelemetryEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { deviceTelemetryEnabled = it } },
@ -75,7 +75,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
}
val items = remember { IntervalConfiguration.BROADCAST_SHORT.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.device_metrics_update_interval_seconds),
title = stringResource(Res.string.device_metrics_update_interval_seconds),
selectedItem = formState.value.deviceUpdateInterval.toLong(),
enabled = state.connected,
items = items.map { it.value to it.toDisplayString(context = context) },
@ -83,7 +83,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.environment_metrics_module_enabled),
title = stringResource(Res.string.environment_metrics_module_enabled),
checked = formState.value.environmentMeasurementEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { environmentMeasurementEnabled = it } },
@ -92,7 +92,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
HorizontalDivider()
val envItems = remember { IntervalConfiguration.BROADCAST_SHORT.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.environment_metrics_update_interval_seconds),
title = stringResource(Res.string.environment_metrics_update_interval_seconds),
selectedItem = formState.value.environmentUpdateInterval.toLong(),
enabled = state.connected,
items = envItems.map { it.value to it.toDisplayString(context = context) },
@ -102,7 +102,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.environment_metrics_on_screen_enabled),
title = stringResource(Res.string.environment_metrics_on_screen_enabled),
checked = formState.value.environmentScreenEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { environmentScreenEnabled = it } },
@ -110,7 +110,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.environment_metrics_use_fahrenheit),
title = stringResource(Res.string.environment_metrics_use_fahrenheit),
checked = formState.value.environmentDisplayFahrenheit,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { environmentDisplayFahrenheit = it } },
@ -118,7 +118,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.air_quality_metrics_module_enabled),
title = stringResource(Res.string.air_quality_metrics_module_enabled),
checked = formState.value.airQualityEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { airQualityEnabled = it } },
@ -127,7 +127,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
HorizontalDivider()
val airItems = remember { IntervalConfiguration.BROADCAST_SHORT.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.air_quality_metrics_update_interval_seconds),
title = stringResource(Res.string.air_quality_metrics_update_interval_seconds),
selectedItem = formState.value.airQualityInterval.toLong(),
enabled = state.connected,
items = airItems.map { it.value to it.toDisplayString(context = context) },
@ -135,7 +135,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.power_metrics_module_enabled),
title = stringResource(Res.string.power_metrics_module_enabled),
checked = formState.value.powerMeasurementEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { powerMeasurementEnabled = it } },
@ -144,7 +144,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
HorizontalDivider()
val powerItems = remember { IntervalConfiguration.BROADCAST_SHORT.allowedIntervals }
DropDownPreference(
title = stringResource(R.string.power_metrics_update_interval_seconds),
title = stringResource(Res.string.power_metrics_update_interval_seconds),
selectedItem = formState.value.powerUpdateInterval.toLong(),
enabled = state.connected,
items = powerItems.map { it.value to it.toDisplayString(context = context) },
@ -152,7 +152,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.power_metrics_on_screen_enabled),
title = stringResource(Res.string.power_metrics_on_screen_enabled),
checked = formState.value.powerScreenEnabled,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { powerScreenEnabled = it } },

View file

@ -31,13 +31,13 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.meshtastic.core.database.model.isUnmessageableRole
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.R
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) {
@ -52,7 +52,7 @@ fun UserConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
val focusManager = LocalFocusManager.current
RadioConfigScreenList(
title = stringResource(R.string.user),
title = stringResource(Res.string.user),
onBack = onBack,
configState = formState,
enabled = state.connected && validNames,
@ -61,11 +61,15 @@ fun UserConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
onSave = viewModel::setOwner,
) {
item {
TitledCard(title = stringResource(R.string.user_config)) {
RegularPreference(title = stringResource(R.string.node_id), subtitle = formState.value.id, onClick = {})
TitledCard(title = stringResource(Res.string.user_config)) {
RegularPreference(
title = stringResource(Res.string.node_id),
subtitle = formState.value.id,
onClick = {},
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.long_name),
title = stringResource(Res.string.long_name),
value = formState.value.longName,
maxSize = 39, // long_name max_size:40
enabled = state.connected,
@ -77,7 +81,7 @@ fun UserConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
EditTextPreference(
title = stringResource(R.string.short_name),
title = stringResource(Res.string.short_name),
value = formState.value.shortName,
maxSize = 4, // short_name max_size:5
enabled = state.connected,
@ -89,14 +93,14 @@ fun UserConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
RegularPreference(
title = stringResource(R.string.hardware_model),
title = stringResource(Res.string.hardware_model),
subtitle = formState.value.hwModel.name,
onClick = {},
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.unmessageable),
summary = stringResource(R.string.unmonitored_or_infrastructure),
title = stringResource(Res.string.unmessageable),
summary = stringResource(Res.string.unmonitored_or_infrastructure),
checked =
formState.value.isUnmessagable ||
(firmwareVersion < DeviceVersion("2.6.9") && formState.value.role.isUnmessageableRole()),
@ -106,8 +110,8 @@ fun UserConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
)
HorizontalDivider()
SwitchPreference(
title = stringResource(R.string.licensed_amateur_radio),
summary = stringResource(R.string.licensed_amateur_radio_text),
title = stringResource(Res.string.licensed_amateur_radio),
summary = stringResource(Res.string.licensed_amateur_radio_text),
checked = formState.value.isLicensed,
enabled = state.connected,
onCheckedChange = { formState.value = formState.value.copy { isLicensed = it } },

View file

@ -28,8 +28,8 @@ 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.meshtastic.core.strings.R
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
@Composable
fun WarningDialog(
@ -42,7 +42,7 @@ fun WarningDialog(
onDismissRequest = {},
icon = { icon?.let { Icon(imageVector = it, contentDescription = null) } },
title = { Text(text = title) },
dismissButton = { TextButton(onClick = { onDismiss() }) { Text(stringResource(R.string.cancel)) } },
dismissButton = { TextButton(onClick = { onDismiss() }) { Text(stringResource(Res.string.cancel)) } },
confirmButton = {
Button(
onClick = {
@ -50,7 +50,7 @@ fun WarningDialog(
onConfirm()
},
) {
Text(stringResource(R.string.send))
Text(stringResource(Res.string.send))
}
},
)

View file

@ -18,9 +18,10 @@
package org.meshtastic.feature.settings.util
import android.content.Context
import org.meshtastic.core.strings.R as Res
fun FixedUpdateIntervals.toDisplayString(context: Context): String = if (this == FixedUpdateIntervals.UNSET) {
context.getString(org.meshtastic.core.strings.R.string.unset)
context.getString(Res.string.unset)
} else {
name.split('_').joinToString(" ") { word -> word.lowercase().replaceFirstChar { it.uppercase() } }
}

View file

@ -20,10 +20,10 @@ package org.meshtastic.feature.settings.util
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import org.meshtastic.core.strings.R
import org.xmlpull.v1.XmlPullParser
import timber.log.Timber
import java.util.Locale
import org.meshtastic.core.strings.R as Res
object LanguageUtils {
@ -63,11 +63,11 @@ object LanguageUtils {
return languageTags.associateWith { languageTag ->
when (languageTag) {
SYSTEM_DEFAULT -> getString(R.string.preferences_system_default)
"fr-HT" -> getString(R.string.fr_HT)
"pt-BR" -> getString(R.string.pt_BR)
"zh-CN" -> getString(R.string.zh_CN)
"zh-TW" -> getString(R.string.zh_TW)
SYSTEM_DEFAULT -> getString(Res.string.preferences_system_default)
"fr-HT" -> getString(Res.string.fr_HT)
"pt-BR" -> getString(Res.string.pt_BR)
"zh-CN" -> getString(Res.string.zh_CN)
"zh-TW" -> getString(Res.string.zh_TW)
else -> {
Locale.forLanguageTag(languageTag).let { locale ->
locale.getDisplayLanguage(locale).replaceFirstChar { char ->