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

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

View file

@ -24,12 +24,18 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.analytics_notice
import org.meshtastic.core.strings.analytics_platforms
import org.meshtastic.core.strings.datadog_link
import org.meshtastic.core.strings.firebase_link
import org.meshtastic.core.strings.for_more_information_see_our_privacy_policy
import org.meshtastic.core.strings.privacy_url
import org.meshtastic.core.ui.component.AutoLinkText
import org.meshtastic.core.strings.R as Res
@Composable
fun AnalyticsIntro(modifier: Modifier = Modifier) {

View file

@ -30,11 +30,15 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import org.meshtastic.core.strings.R as Res
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.configure_critical_alerts
import org.meshtastic.core.strings.critical_alerts
import org.meshtastic.core.strings.critical_alerts_dnd_request_text
import org.meshtastic.core.strings.skip
/**
* Screen for explaining and guiding the user to configure critical alert settings. This screen is part of the app

View file

@ -17,8 +17,8 @@
package org.meshtastic.feature.intro
import androidx.annotation.StringRes
import androidx.compose.ui.graphics.vector.ImageVector
import org.jetbrains.compose.resources.StringResource
/**
* Data class representing the UI elements for a feature row in the app introduction.
@ -29,6 +29,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
*/
internal data class FeatureUIData(
val icon: ImageVector,
@StringRes val titleRes: Int? = null,
@StringRes val subtitleRes: Int,
val titleRes: StringResource? = null,
val subtitleRes: StringResource,
)

View file

@ -18,7 +18,6 @@
package org.meshtastic.feature.intro
import android.content.Context
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
@ -29,13 +28,14 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
/** Tag used for identifying clickable annotations in text, specifically for linking to settings. */
internal const val SETTINGS_TAG = "settings_link_tag"
@ -80,8 +80,8 @@ internal fun FeatureRow(feature: FeatureUIData) {
*/
@Composable
internal fun Context.createClickableAnnotatedString(
@StringRes fullTextRes: Int,
@StringRes linkTextRes: Int,
fullTextRes: StringResource,
linkTextRes: StringResource,
tag: String,
): AnnotatedString {
val fullText = stringResource(fullTextRes)

View file

@ -26,7 +26,20 @@ import androidx.compose.material.icons.outlined.Router
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import org.meshtastic.core.strings.R as Res
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.configure_location_permissions
import org.meshtastic.core.strings.distance_filters
import org.meshtastic.core.strings.distance_filters_description
import org.meshtastic.core.strings.distance_measurements
import org.meshtastic.core.strings.distance_measurements_description
import org.meshtastic.core.strings.mesh_map_location
import org.meshtastic.core.strings.mesh_map_location_description
import org.meshtastic.core.strings.next
import org.meshtastic.core.strings.phone_location
import org.meshtastic.core.strings.phone_location_description
import org.meshtastic.core.strings.settings
import org.meshtastic.core.strings.share_location
import org.meshtastic.core.strings.share_location_description
/**
* Screen for configuring location permissions during the app introduction. It explains why location permissions are

View file

@ -33,11 +33,24 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import org.meshtastic.core.strings.R as Res
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.app_notifications
import org.meshtastic.core.strings.configure_notification_permissions
import org.meshtastic.core.strings.critical_alerts
import org.meshtastic.core.strings.critical_alerts_description
import org.meshtastic.core.strings.incoming_messages
import org.meshtastic.core.strings.low_battery
import org.meshtastic.core.strings.new_nodes
import org.meshtastic.core.strings.next
import org.meshtastic.core.strings.notification_permissions_description
import org.meshtastic.core.strings.notifications_for_channel_and_direct_messages
import org.meshtastic.core.strings.notifications_for_low_battery_alerts
import org.meshtastic.core.strings.notifications_for_newly_discovered_nodes
import org.meshtastic.core.strings.settings
/**
* Screen for configuring notification permissions during the app introduction. It explains why notification permissions

View file

@ -17,7 +17,6 @@
package org.meshtastic.feature.intro
import androidx.annotation.StringRes
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
@ -37,13 +36,15 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import org.meshtastic.core.strings.R as Res
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.skip
/**
* A generic layout for screens within the app introduction flow. It typically presents a headline, a descriptive text
@ -60,13 +61,13 @@ import org.meshtastic.core.strings.R as Res
*/
@Composable
internal fun PermissionScreenLayout(
@StringRes headlineRes: Int,
headlineRes: StringResource,
annotatedDescription: AnnotatedString,
features: List<FeatureUIData>,
additionalContent: (@Composable () -> Unit)? = null,
onSkip: () -> Unit,
onConfigure: () -> Unit,
@StringRes configureButtonTextRes: Int,
configureButtonTextRes: StringResource,
onAnnotationClick: (String) -> Unit,
) {
var textLayoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }

View file

@ -35,12 +35,21 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.meshtastic.core.strings.R as Res
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.communicate_off_the_grid
import org.meshtastic.core.strings.create_your_own_networks
import org.meshtastic.core.strings.easily_set_up_private_mesh_networks
import org.meshtastic.core.strings.get_started
import org.meshtastic.core.strings.intro_welcome
import org.meshtastic.core.strings.meshtastic
import org.meshtastic.core.strings.share_your_location_in_real_time
import org.meshtastic.core.strings.stay_connected_anywhere
import org.meshtastic.core.strings.track_and_share_locations
/**
* The initial welcome screen for the app introduction flow. It displays a brief overview of the app's key features.

View file

@ -58,7 +58,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
@ -66,13 +65,47 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.accompanist.permissions.ExperimentalPermissionsApi // Added for Accompanist
import com.google.accompanist.permissions.rememberMultiplePermissionsState // Added for Accompanist
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.meshtastic.core.strings.getString
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.getString
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.common.gpsDisabled
import org.meshtastic.core.common.hasGps
import org.meshtastic.core.database.entity.Packet
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.util.formatAgo
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.calculating
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.clear
import org.meshtastic.core.strings.close
import org.meshtastic.core.strings.delete_for_everyone
import org.meshtastic.core.strings.delete_for_me
import org.meshtastic.core.strings.expires
import org.meshtastic.core.strings.location_disabled
import org.meshtastic.core.strings.map_cache_info
import org.meshtastic.core.strings.map_cache_manager
import org.meshtastic.core.strings.map_cache_size
import org.meshtastic.core.strings.map_cache_tiles
import org.meshtastic.core.strings.map_clear_tiles
import org.meshtastic.core.strings.map_download_complete
import org.meshtastic.core.strings.map_download_errors
import org.meshtastic.core.strings.map_download_region
import org.meshtastic.core.strings.map_filter
import org.meshtastic.core.strings.map_node_popup_details
import org.meshtastic.core.strings.map_offline_manager
import org.meshtastic.core.strings.map_purge_fail
import org.meshtastic.core.strings.map_purge_success
import org.meshtastic.core.strings.map_style_selection
import org.meshtastic.core.strings.map_subDescription
import org.meshtastic.core.strings.map_tile_source
import org.meshtastic.core.strings.only_favorites
import org.meshtastic.core.strings.show_precision_circle
import org.meshtastic.core.strings.show_waypoints
import org.meshtastic.core.strings.toggle_my_position
import org.meshtastic.core.strings.waypoint_delete
import org.meshtastic.core.strings.you
import org.meshtastic.core.ui.util.showToast
import org.meshtastic.feature.map.cluster.RadiusMarkerClusterer
import org.meshtastic.feature.map.component.CacheLayout
@ -106,7 +139,6 @@ import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
import timber.log.Timber
import java.io.File
import java.text.DateFormat
import org.meshtastic.core.strings.R as Res
@Composable
private fun MapView.UpdateMarkers(
@ -186,7 +218,7 @@ private fun Context.purgeTileSource(onResult: (String) -> Unit) {
val b = cache.purgeCache(item.source)
onResult(
if (b) {
getString(Res.string.map_purge_success, item.source)
getString(Res.string.map_purge_success, item.source.toString())
} else {
getString(Res.string.map_purge_fail)
},
@ -336,7 +368,8 @@ fun MapView(mapViewModel: MapViewModel = hiltViewModel(), navigateToNodeDetails:
if (node.batteryStr != "") node.batteryStr else "?",
)
ourNode?.distanceStr(node, displayUnits)?.let { dist ->
subDescription = resources.getString(Res.string.map_subDescription, ourNode.bearing(node), dist)
subDescription =
resources.getString(Res.string.map_subDescription, ourNode.bearing(node).toString(), dist)
}
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
position = nodePosition
@ -460,7 +493,7 @@ fun MapView(mapViewModel: MapViewModel = hiltViewModel(), navigateToNodeDetails:
val currentCacheUsage = cacheManager.currentCacheUsage()
val mapCacheInfoText =
resources.getString(
getString(
Res.string.map_cache_info,
cacheCapacity / (1024.0 * 1024.0),
currentCacheUsage / (1024.0 * 1024.0),

View file

@ -32,11 +32,15 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.meshtastic.core.strings.R as Res
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.map_select_download_region
import org.meshtastic.core.strings.map_start_download
import org.meshtastic.core.strings.map_tile_download_estimate
@OptIn(ExperimentalLayoutApi::class)
@Composable

View file

@ -30,8 +30,9 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.res.stringResource
import org.meshtastic.core.strings.R as Res
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.map_download_region
@Composable
fun DownloadButton(enabled: Boolean, onClick: () -> Unit) {

View file

@ -56,7 +56,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
@ -64,6 +63,19 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.date
import org.meshtastic.core.strings.delete
import org.meshtastic.core.strings.description
import org.meshtastic.core.strings.expires
import org.meshtastic.core.strings.locked
import org.meshtastic.core.strings.name
import org.meshtastic.core.strings.send
import org.meshtastic.core.strings.time
import org.meshtastic.core.strings.waypoint_edit
import org.meshtastic.core.strings.waypoint_new
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.emoji.EmojiPickerDialog
import org.meshtastic.core.ui.theme.AppTheme
@ -73,7 +85,6 @@ import org.meshtastic.proto.waypoint
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import org.meshtastic.core.strings.R as Res
@Suppress("LongMethod")
@OptIn(ExperimentalLayoutApi::class)

View file

@ -17,7 +17,6 @@
package org.meshtastic.feature.map.component
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Layers
@ -26,16 +25,18 @@ import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.map_style_selection
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
@Composable
fun MapButton(
icon: ImageVector,
@StringRes contentDescription: Int,
contentDescription: StringResource,
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
) {

View file

@ -58,7 +58,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.graphics.createBitmap
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
@ -90,12 +89,23 @@ import com.google.maps.android.compose.rememberUpdatedMarkerState
import com.google.maps.android.compose.widgets.ScaleBar
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.util.formatAgo
import org.meshtastic.core.model.util.metersIn
import org.meshtastic.core.model.util.mpsToKmph
import org.meshtastic.core.model.util.mpsToMph
import org.meshtastic.core.model.util.toString
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.alt
import org.meshtastic.core.strings.heading
import org.meshtastic.core.strings.latitude
import org.meshtastic.core.strings.longitude
import org.meshtastic.core.strings.position
import org.meshtastic.core.strings.sats
import org.meshtastic.core.strings.speed
import org.meshtastic.core.strings.timestamp
import org.meshtastic.core.strings.track_point
import org.meshtastic.core.ui.component.NodeChip
import org.meshtastic.core.ui.util.formatPositionTime
import org.meshtastic.feature.map.component.ClusterItemsListDialog
@ -113,7 +123,6 @@ import org.meshtastic.proto.copy
import org.meshtastic.proto.waypoint
import timber.log.Timber
import java.text.DateFormat
import org.meshtastic.core.strings.R as Res
private const val MIN_TRACK_POINT_DISTANCE_METERS = 20f
private const val DEG_D = 1e-7

View file

@ -29,11 +29,13 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.nodes_at_this_location
import org.meshtastic.core.strings.okay
import org.meshtastic.core.ui.component.NodeChip
import org.meshtastic.feature.map.model.NodeClusterItem
import org.meshtastic.core.strings.R as Res
@Composable
fun ClusterItemsListDialog(

View file

@ -37,10 +37,17 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.add_layer
import org.meshtastic.core.strings.hide_layer
import org.meshtastic.core.strings.manage_map_layers
import org.meshtastic.core.strings.map_layer_formats
import org.meshtastic.core.strings.no_map_layers_loaded
import org.meshtastic.core.strings.remove_layer
import org.meshtastic.core.strings.show_layer
import org.meshtastic.feature.map.MapLayerItem
import org.meshtastic.core.strings.R as Res
@Suppress("LongMethod")
@Composable

View file

@ -47,14 +47,28 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.flow.collectLatest
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.data.model.CustomTileProviderConfig
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.add_custom_tile_source
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.delete_custom_tile_source
import org.meshtastic.core.strings.edit_custom_tile_source
import org.meshtastic.core.strings.manage_custom_tile_sources
import org.meshtastic.core.strings.name
import org.meshtastic.core.strings.name_cannot_be_empty
import org.meshtastic.core.strings.no_custom_tile_sources_found
import org.meshtastic.core.strings.provider_name_exists
import org.meshtastic.core.strings.save
import org.meshtastic.core.strings.url_cannot_be_empty
import org.meshtastic.core.strings.url_must_contain_placeholders
import org.meshtastic.core.strings.url_template
import org.meshtastic.core.strings.url_template_hint
import org.meshtastic.core.ui.util.showToast
import org.meshtastic.feature.map.MapViewModel
import org.meshtastic.core.strings.R as Res
@Suppress("LongMethod")
@Composable

View file

@ -55,13 +55,25 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.date
import org.meshtastic.core.strings.delete
import org.meshtastic.core.strings.description
import org.meshtastic.core.strings.expires
import org.meshtastic.core.strings.locked
import org.meshtastic.core.strings.name
import org.meshtastic.core.strings.send
import org.meshtastic.core.strings.time
import org.meshtastic.core.strings.waypoint_edit
import org.meshtastic.core.strings.waypoint_new
import org.meshtastic.core.ui.emoji.EmojiPickerDialog
import org.meshtastic.proto.MeshProtos.Waypoint
import org.meshtastic.proto.copy
@ -69,7 +81,6 @@ import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.TimeZone
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalMaterial3Api::class)
@Suppress("LongMethod", "CyclomaticComplexMethod", "MagicNumber")

View file

@ -32,10 +32,15 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.res.stringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.manage_map_layers
import org.meshtastic.core.strings.map_filter
import org.meshtastic.core.strings.map_tile_source
import org.meshtastic.core.strings.orient_north
import org.meshtastic.core.strings.toggle_my_position
import org.meshtastic.core.ui.theme.StatusColors.StatusRed
import org.meshtastic.feature.map.MapViewModel
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable

View file

@ -37,13 +37,17 @@ import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.last_heard_filter_label
import org.meshtastic.core.strings.only_favorites
import org.meshtastic.core.strings.show_precision_circle
import org.meshtastic.core.strings.show_waypoints
import org.meshtastic.feature.map.LastHeardFilter
import org.meshtastic.feature.map.MapViewModel
import kotlin.math.roundToInt
import org.meshtastic.core.strings.R as Res
@Composable
internal fun MapFilterDropdown(expanded: Boolean, onDismissRequest: () -> Unit, mapViewModel: MapViewModel) {

View file

@ -26,11 +26,17 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.maps.android.compose.MapType
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.manage_custom_tile_sources
import org.meshtastic.core.strings.map_type_hybrid
import org.meshtastic.core.strings.map_type_normal
import org.meshtastic.core.strings.map_type_satellite
import org.meshtastic.core.strings.map_type_terrain
import org.meshtastic.core.strings.selected_map_type
import org.meshtastic.feature.map.MapViewModel
import org.meshtastic.core.strings.R as Res
@Suppress("LongMethod")
@Composable

View file

@ -25,10 +25,11 @@ import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.compose.Marker
import com.google.maps.android.compose.rememberUpdatedMarkerState
import kotlinx.coroutines.launch
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.locked
import org.meshtastic.core.ui.util.showToast
import org.meshtastic.feature.map.BaseMapViewModel
import org.meshtastic.proto.MeshProtos
import org.meshtastic.core.strings.R as Res
private const val DEG_D = 1e-7

View file

@ -18,7 +18,6 @@
package org.meshtastic.feature.map
import android.os.RemoteException
import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
@ -28,6 +27,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.StringResource
import org.meshtastic.core.data.repository.NodeRepository
import org.meshtastic.core.data.repository.PacketRepository
import org.meshtastic.core.database.entity.Packet
@ -35,14 +35,19 @@ import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.prefs.map.MapPrefs
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.any
import org.meshtastic.core.strings.eight_hours
import org.meshtastic.core.strings.one_day
import org.meshtastic.core.strings.one_hour
import org.meshtastic.core.strings.two_days
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
import org.meshtastic.proto.MeshProtos
import timber.log.Timber
import java.util.concurrent.TimeUnit
import org.meshtastic.core.strings.R as Res
@Suppress("MagicNumber")
sealed class LastHeardFilter(val seconds: Long, @StringRes val label: Int) {
sealed class LastHeardFilter(val seconds: Long, val label: StringResource) {
data object Any : LastHeardFilter(0L, Res.string.any)
data object OneHour : LastHeardFilter(TimeUnit.HOURS.toSeconds(1), Res.string.one_hour)

View file

@ -23,11 +23,12 @@ import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.map
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.strings.R as Res
@Composable
fun MapScreen(

View file

@ -85,7 +85,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
@ -95,18 +94,42 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.pluralStringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.entity.QuickChatAction
import org.meshtastic.core.database.model.Message
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.util.getChannel
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.alert_bell_text
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.cancel_reply
import org.meshtastic.core.strings.clear_selection
import org.meshtastic.core.strings.copy
import org.meshtastic.core.strings.delete
import org.meshtastic.core.strings.delete_messages
import org.meshtastic.core.strings.delete_messages_title
import org.meshtastic.core.strings.message_input_label
import org.meshtastic.core.strings.navigate_back
import org.meshtastic.core.strings.overflow_menu
import org.meshtastic.core.strings.quick_chat
import org.meshtastic.core.strings.quick_chat_hide
import org.meshtastic.core.strings.quick_chat_show
import org.meshtastic.core.strings.reply
import org.meshtastic.core.strings.replying_to
import org.meshtastic.core.strings.scroll_to_bottom
import org.meshtastic.core.strings.select_all
import org.meshtastic.core.strings.send
import org.meshtastic.core.strings.type_a_message
import org.meshtastic.core.strings.unknown
import org.meshtastic.core.strings.unknown_channel
import org.meshtastic.core.ui.component.NodeKeyStatusIcon
import org.meshtastic.core.ui.component.SecurityIcon
import org.meshtastic.core.ui.component.SharedContactDialog
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.proto.AppOnlyProtos
import java.nio.charset.StandardCharsets
import org.meshtastic.core.strings.R as Res
private const val MESSAGE_CHARACTER_LIMIT_BYTES = 200
private const val SNIPPET_CHARACTER_LIMIT = 50

View file

@ -17,7 +17,6 @@
package org.meshtastic.feature.messaging
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@ -45,26 +44,30 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.entity.Packet
import org.meshtastic.core.database.entity.Reaction
import org.meshtastic.core.database.model.Message
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.MessageStatus
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.close
import org.meshtastic.core.strings.relayed_by
import org.meshtastic.core.strings.resend
import org.meshtastic.feature.messaging.component.MessageItem
import org.meshtastic.feature.messaging.component.ReactionDialog
import org.meshtastic.core.strings.R as Res
@Composable
fun DeliveryInfo(
@StringRes title: Int,
@StringRes text: Int? = null,
title: StringResource,
text: StringResource? = null,
relayNodeName: String? = null,
onConfirm: (() -> Unit) = {},
onDismiss: () -> Unit = {},

View file

@ -64,20 +64,31 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusEvent
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.entity.QuickChatAction
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.add
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.delete
import org.meshtastic.core.strings.message
import org.meshtastic.core.strings.name
import org.meshtastic.core.strings.quick_chat
import org.meshtastic.core.strings.quick_chat_append
import org.meshtastic.core.strings.quick_chat_edit
import org.meshtastic.core.strings.quick_chat_instant
import org.meshtastic.core.strings.quick_chat_new
import org.meshtastic.core.strings.save
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.dragContainer
import org.meshtastic.core.ui.component.dragDropItemsIndexed
import org.meshtastic.core.ui.component.rememberDragDropState
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
@Composable
fun QuickChatScreen(

View file

@ -38,10 +38,13 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.MessageStatus
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.message_delivery_status
import org.meshtastic.core.strings.react
import org.meshtastic.core.strings.reply
import org.meshtastic.core.ui.emoji.EmojiPickerDialog
import org.meshtastic.core.strings.R as Res
@Composable
internal fun ReactionButton(onSendReaction: (String) -> Unit = {}) {

View file

@ -44,15 +44,20 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.entity.Reaction
import org.meshtastic.core.database.model.Message
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.MessageStatus
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.hops_away_template
import org.meshtastic.core.strings.reply
import org.meshtastic.core.strings.sample_message
import org.meshtastic.core.strings.via_mqtt
import org.meshtastic.core.ui.component.AutoLinkText
import org.meshtastic.core.ui.component.NodeChip
import org.meshtastic.core.ui.component.Rssi
@ -60,7 +65,6 @@ import org.meshtastic.core.ui.component.Snr
import org.meshtastic.core.ui.component.preview.NodePreviewParameterProvider
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.ui.theme.MessageItemColors
import org.meshtastic.core.strings.R as Res
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable

View file

@ -26,13 +26,22 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.entity.FirmwareRelease
import org.meshtastic.core.database.entity.asDeviceVersion
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.service.ServiceAction
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.administration
import org.meshtastic.core.strings.firmware
import org.meshtastic.core.strings.firmware_edition
import org.meshtastic.core.strings.installed_firmware_version
import org.meshtastic.core.strings.latest_alpha_firmware
import org.meshtastic.core.strings.latest_stable_firmware
import org.meshtastic.core.strings.remote_admin
import org.meshtastic.core.strings.request_metadata
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
@ -43,7 +52,6 @@ import org.meshtastic.core.ui.theme.StatusColors.StatusYellow
import org.meshtastic.feature.node.model.MetricsState
import org.meshtastic.feature.node.model.NodeDetailAction
import org.meshtastic.proto.MeshProtos
import org.meshtastic.core.strings.R as Res
@Suppress("LongMethod")
@Composable

View file

@ -32,14 +32,19 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.actions
import org.meshtastic.core.strings.favorite
import org.meshtastic.core.strings.ignore
import org.meshtastic.core.strings.remove
import org.meshtastic.core.strings.share_contact
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.SwitchListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.node.model.NodeDetailAction
import org.meshtastic.core.strings.R as Res
@Composable
fun DeviceActions(

View file

@ -38,19 +38,24 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.DeviceHardware
import org.meshtastic.core.strings.R
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.device
import org.meshtastic.core.strings.hardware
import org.meshtastic.core.strings.supported
import org.meshtastic.core.strings.supported_by_community
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.StatusColors.StatusGreen
import org.meshtastic.core.ui.theme.StatusColors.StatusRed
import org.meshtastic.feature.node.model.MetricsState
import org.meshtastic.core.strings.R as Res
@Composable
fun DeviceDetailsSection(state: MetricsState, modifier: Modifier = Modifier) {

View file

@ -23,10 +23,11 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.distance
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
@Composable
fun DistanceInfo(

View file

@ -21,14 +21,16 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.util.metersIn
import org.meshtastic.core.model.util.toString
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.altitude
import org.meshtastic.core.strings.elevation_suffix
import org.meshtastic.core.ui.icon.Elevation
import org.meshtastic.core.ui.icon.MeshtasticIcons
import org.meshtastic.proto.ConfigProtos.Config.DisplayConfig.DisplayUnits
import org.meshtastic.core.strings.R as Res
@Composable
fun ElevationInfo(

View file

@ -35,16 +35,33 @@ import androidx.compose.material.icons.outlined.Navigation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.util.UnitConversions
import org.meshtastic.core.model.util.UnitConversions.toTempString
import org.meshtastic.core.model.util.toSmallDistanceString
import org.meshtastic.core.model.util.toSpeedString
import org.meshtastic.core.strings.R
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.current
import org.meshtastic.core.strings.dew_point
import org.meshtastic.core.strings.distance
import org.meshtastic.core.strings.gas_resistance
import org.meshtastic.core.strings.humidity
import org.meshtastic.core.strings.iaq
import org.meshtastic.core.strings.lux
import org.meshtastic.core.strings.pressure
import org.meshtastic.core.strings.radiation
import org.meshtastic.core.strings.soil_moisture
import org.meshtastic.core.strings.soil_temperature
import org.meshtastic.core.strings.temperature
import org.meshtastic.core.strings.uv_lux
import org.meshtastic.core.strings.voltage
import org.meshtastic.core.strings.weight
import org.meshtastic.core.strings.wind
import org.meshtastic.feature.node.model.DrawableMetricInfo
import org.meshtastic.feature.node.model.VectorMetricInfo
import org.meshtastic.proto.ConfigProtos
import org.meshtastic.core.strings.R as Res
@Suppress("CyclomaticComplexMethod", "LongMethod")
@Composable

View file

@ -39,15 +39,18 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import com.mikepenz.markdown.m3.Markdown
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.entity.FirmwareRelease
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.download
import org.meshtastic.core.strings.error_no_app_to_handle_link
import org.meshtastic.core.strings.view_release
import org.meshtastic.core.ui.util.showToast
import timber.log.Timber
import org.meshtastic.core.strings.R as Res
@Composable
fun FirmwareReleaseSheetContent(firmwareRelease: FirmwareRelease, modifier: Modifier = Modifier) {

View file

@ -22,13 +22,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.util.formatAgo
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.node_sort_last_heard
import org.meshtastic.core.ui.R
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
@Composable
fun LastHeardInfo(

View file

@ -30,20 +30,21 @@ import androidx.compose.ui.platform.ClipEntry
import androidx.compose.ui.platform.Clipboard
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.core.net.toUri
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.util.GPSFormat
import org.meshtastic.core.model.util.formatAgo
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.last_position_update
import org.meshtastic.core.ui.component.BasicListItem
import org.meshtastic.core.ui.component.icon
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.ui.util.showToast
import timber.log.Timber
import java.net.URLEncoder
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalFoundationApi::class)
@Composable

View file

@ -21,15 +21,18 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.environment
import org.meshtastic.core.strings.logs
import org.meshtastic.core.strings.power
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.node.model.LogsType
import org.meshtastic.feature.node.model.MetricsState
import org.meshtastic.feature.node.model.NodeDetailAction
import org.meshtastic.core.strings.R as Res
@Composable
@Suppress("MultipleEmitters")

View file

@ -38,17 +38,28 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.util.formatAgo
import org.meshtastic.core.model.util.formatUptime
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.details
import org.meshtastic.core.strings.encryption_error
import org.meshtastic.core.strings.encryption_error_text
import org.meshtastic.core.strings.long_name
import org.meshtastic.core.strings.node_number
import org.meshtastic.core.strings.node_sort_last_heard
import org.meshtastic.core.strings.role
import org.meshtastic.core.strings.short_name
import org.meshtastic.core.strings.unmonitored_or_infrastructure
import org.meshtastic.core.strings.uptime
import org.meshtastic.core.strings.user_id
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.node.model.isEffectivelyUnmessageable
import org.meshtastic.core.strings.R as Res
@Composable
fun NodeDetailsSection(node: Node, modifier: Modifier = Modifier) {

View file

@ -54,16 +54,26 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusEvent
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.NodeSortOption
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.desc_node_filter_clear
import org.meshtastic.core.strings.node_filter_ignored
import org.meshtastic.core.strings.node_filter_include_unknown
import org.meshtastic.core.strings.node_filter_only_direct
import org.meshtastic.core.strings.node_filter_only_online
import org.meshtastic.core.strings.node_filter_placeholder
import org.meshtastic.core.strings.node_filter_show_ignored
import org.meshtastic.core.strings.node_filter_title
import org.meshtastic.core.strings.node_sort_button
import org.meshtastic.core.strings.node_sort_title
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
@Suppress("LongParameterList")
@Composable

View file

@ -40,15 +40,18 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.database.model.isUnmessageableRole
import org.meshtastic.core.model.util.toDistanceString
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.elevation_suffix
import org.meshtastic.core.strings.unknown_username
import org.meshtastic.core.ui.component.MaterialBatteryInfo
import org.meshtastic.core.ui.component.NodeChip
import org.meshtastic.core.ui.component.NodeKeyStatusIcon
@ -56,7 +59,6 @@ import org.meshtastic.core.ui.component.SignalInfo
import org.meshtastic.core.ui.component.preview.NodePreviewParameterProvider
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.proto.ConfigProtos.Config.DisplayConfig
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Suppress("LongMethod", "CyclomaticComplexMethod")

View file

@ -18,10 +18,18 @@
package org.meshtastic.feature.node.component
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.favorite
import org.meshtastic.core.strings.favorite_add
import org.meshtastic.core.strings.favorite_remove
import org.meshtastic.core.strings.ignore
import org.meshtastic.core.strings.ignore_add
import org.meshtastic.core.strings.ignore_remove
import org.meshtastic.core.strings.remove
import org.meshtastic.core.strings.remove_node_text
import org.meshtastic.core.ui.component.SimpleAlertDialog
import org.meshtastic.core.strings.R as Res
@Composable
fun NodeActionDialogs(

View file

@ -37,13 +37,19 @@ import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.connected
import org.meshtastic.core.strings.disconnected
import org.meshtastic.core.strings.favorite
import org.meshtastic.core.strings.not_connected
import org.meshtastic.core.strings.unmessageable
import org.meshtastic.core.strings.unmonitored_or_infrastructure
import org.meshtastic.core.ui.theme.StatusColors.StatusGreen
import org.meshtastic.core.ui.theme.StatusColors.StatusRed
import org.meshtastic.core.ui.theme.StatusColors.StatusYellow
import org.meshtastic.core.strings.R as Res
@Suppress("LongMethod")
@OptIn(ExperimentalMaterial3Api::class)

View file

@ -34,12 +34,15 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.add_a_note
import org.meshtastic.core.strings.notes
import org.meshtastic.core.strings.save
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.strings.R as Res
@Composable
fun NotesSection(node: Node, onSaveNotes: (Int, String) -> Unit, modifier: Modifier = Modifier) {

View file

@ -24,17 +24,20 @@ import androidx.compose.material.icons.filled.LocationOn
import androidx.compose.material.icons.filled.SocialDistance
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.util.toDistanceString
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.exchange_position
import org.meshtastic.core.strings.node_sort_distance
import org.meshtastic.core.strings.position
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.feature.node.model.LogsType
import org.meshtastic.feature.node.model.MetricsState
import org.meshtastic.feature.node.model.NodeDetailAction
import org.meshtastic.core.strings.R as Res
/**
* Displays node position details, last update time, distance, and related actions like requesting position and

View file

@ -27,10 +27,13 @@ import androidx.compose.material.icons.filled.Power
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.channel_1
import org.meshtastic.core.strings.channel_2
import org.meshtastic.core.strings.channel_3
import org.meshtastic.feature.node.model.VectorMetricInfo
import org.meshtastic.core.strings.R as Res
/**
* Displays environmental metrics for a node, including temperature, humidity, pressure, and other sensor data.

View file

@ -21,13 +21,15 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.twotone.Message
import androidx.compose.material.icons.filled.Person
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.direct_message
import org.meshtastic.core.strings.exchange_userinfo
import org.meshtastic.core.ui.component.InsetDivider
import org.meshtastic.core.ui.component.ListItem
import org.meshtastic.feature.node.model.NodeDetailAction
import org.meshtastic.feature.node.model.isEffectivelyUnmessageable
import org.meshtastic.core.strings.R as Res
@Composable
internal fun RemoteDeviceActions(node: Node, lastTracerouteTime: Long?, onAction: (NodeDetailAction) -> Unit) {

View file

@ -23,10 +23,11 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.sats
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
@Composable
fun SatelliteCountInfo(

View file

@ -31,12 +31,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.traceroute
import org.meshtastic.core.ui.component.BasicListItem
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.strings.R as Res
private const val COOL_DOWN_TIME_MS = 30000L

View file

@ -53,13 +53,21 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.add_favorite
import org.meshtastic.core.strings.ignore
import org.meshtastic.core.strings.node_count_template
import org.meshtastic.core.strings.nodes
import org.meshtastic.core.strings.remove
import org.meshtastic.core.strings.remove_favorite
import org.meshtastic.core.strings.remove_ignored
import org.meshtastic.core.ui.component.AddContactFAB
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.rememberTimeTickWithLifecycle
@ -69,7 +77,6 @@ import org.meshtastic.feature.node.component.NodeActionDialogs
import org.meshtastic.feature.node.component.NodeFilterTextField
import org.meshtastic.feature.node.component.NodeItem
import org.meshtastic.proto.AdminProtos
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Suppress("LongMethod", "CyclomaticComplexMethod")

View file

@ -48,7 +48,6 @@ import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
@ -56,11 +55,18 @@ import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.close
import org.meshtastic.core.strings.info
import org.meshtastic.core.strings.logs
import org.meshtastic.core.strings.rssi
import org.meshtastic.core.strings.snr
import org.meshtastic.feature.node.metrics.CommonCharts.DATE_TIME_MINUTE_FORMAT
import org.meshtastic.feature.node.metrics.CommonCharts.MAX_PERCENT_VALUE
import org.meshtastic.feature.node.metrics.CommonCharts.MS_PER_SEC
import java.text.DateFormat
import org.meshtastic.core.strings.R as Res
object CommonCharts {
val DATE_TIME_FORMAT: DateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM)
@ -79,7 +85,7 @@ private const val LINE_LIMIT = 4
private const val TEXT_PAINT_ALPHA = 192
data class LegendData(
val nameRes: Int,
val nameRes: StringResource,
val color: Color,
val isLine: Boolean = false,
val environmentMetric: Environment? = null,
@ -269,7 +275,7 @@ fun Legend(legendData: List<LegendData>, displayInfoIcon: Boolean = true, prompt
* @param onDismiss Executes when the user presses the close button.
*/
@Composable
fun LegendInfoDialog(pairedRes: List<Pair<Int, Int>>, onDismiss: () -> Unit) {
fun LegendInfoDialog(pairedRes: List<Pair<StringResource, StringResource>>, onDismiss: () -> Unit) {
AlertDialog(
title = {
Text(

View file

@ -53,13 +53,20 @@ import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.air_util_definition
import org.meshtastic.core.strings.air_utilization
import org.meshtastic.core.strings.battery
import org.meshtastic.core.strings.ch_util_definition
import org.meshtastic.core.strings.channel_air_util
import org.meshtastic.core.strings.channel_utilization
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.MaterialBatteryInfo
import org.meshtastic.core.ui.component.OptionLabel
@ -76,7 +83,6 @@ import org.meshtastic.feature.node.metrics.GraphUtil.plotPoint
import org.meshtastic.feature.node.model.TimeFrame
import org.meshtastic.proto.TelemetryProtos
import org.meshtastic.proto.TelemetryProtos.Telemetry
import org.meshtastic.core.strings.R as Res
private const val CHART_WEIGHT = 1f
private const val Y_AXIS_WEIGHT = 0.1f

View file

@ -40,11 +40,19 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.baro_pressure
import org.meshtastic.core.strings.humidity
import org.meshtastic.core.strings.iaq
import org.meshtastic.core.strings.lux
import org.meshtastic.core.strings.soil_moisture
import org.meshtastic.core.strings.soil_temperature
import org.meshtastic.core.strings.temperature
import org.meshtastic.core.strings.uv_lux
import org.meshtastic.feature.node.metrics.GraphUtil.createPath
import org.meshtastic.feature.node.metrics.GraphUtil.drawPathWithGradient
import org.meshtastic.feature.node.model.TimeFrame
import org.meshtastic.proto.TelemetryProtos.Telemetry
import org.meshtastic.core.strings.R as Res
private const val CHART_WEIGHT = 1f
private const val Y_AXIS_WEIGHT = 0.1f

View file

@ -42,14 +42,27 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.util.UnitConversions.celsiusToFahrenheit
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.current
import org.meshtastic.core.strings.gas_resistance
import org.meshtastic.core.strings.humidity
import org.meshtastic.core.strings.iaq
import org.meshtastic.core.strings.iaq_definition
import org.meshtastic.core.strings.lux
import org.meshtastic.core.strings.radiation
import org.meshtastic.core.strings.soil_moisture
import org.meshtastic.core.strings.soil_temperature
import org.meshtastic.core.strings.temperature
import org.meshtastic.core.strings.uv_lux
import org.meshtastic.core.strings.voltage
import org.meshtastic.core.ui.component.IaqDisplayMode
import org.meshtastic.core.ui.component.IndoorAirQuality
import org.meshtastic.core.ui.component.MainAppBar
@ -61,7 +74,6 @@ import org.meshtastic.feature.node.model.TimeFrame
import org.meshtastic.proto.TelemetryProtos
import org.meshtastic.proto.TelemetryProtos.Telemetry
import org.meshtastic.proto.copy
import org.meshtastic.core.strings.R as Res
@Composable
fun EnvironmentMetricsScreen(viewModel: MetricsViewModel = hiltViewModel(), onNavigateUp: () -> Unit) {

View file

@ -45,7 +45,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
@ -54,13 +53,19 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.util.formatUptime
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.disk_free_indexed
import org.meshtastic.core.strings.free_memory
import org.meshtastic.core.strings.load_indexed
import org.meshtastic.core.strings.uptime
import org.meshtastic.core.strings.user_string
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.feature.node.metrics.CommonCharts.DATE_TIME_FORMAT
import org.meshtastic.proto.TelemetryProtos
import java.text.DecimalFormat
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalFoundationApi::class)
@Composable

View file

@ -38,6 +38,7 @@ import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jetbrains.compose.resources.getString
import org.meshtastic.core.data.repository.DeviceHardwareRepository
import org.meshtastic.core.data.repository.FirmwareReleaseRepository
import org.meshtastic.core.data.repository.MeshLogRepository
@ -50,6 +51,8 @@ import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.navigation.NodesRoutes
import org.meshtastic.core.service.ServiceAction
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.fallback_node_name
import org.meshtastic.core.ui.util.toPosition
import org.meshtastic.feature.node.model.MetricsState
import org.meshtastic.feature.node.model.TimeFrame
@ -64,7 +67,6 @@ import java.io.FileWriter
import java.text.SimpleDateFormat
import java.util.Locale
import javax.inject.Inject
import org.meshtastic.core.strings.R as Res
private const val DEFAULT_ID_SUFFIX_LENGTH = 4
@ -95,10 +97,10 @@ constructor(
* Creates a fallback node for hidden clients or nodes not yet in the database. This prevents the detail screen from
* freezing when viewing unknown nodes.
*/
private fun createFallbackNode(nodeNum: Int): Node {
private suspend fun createFallbackNode(nodeNum: Int): Node {
val userId = DataPacket.nodeNumToDefaultId(nodeNum)
val safeUserId = userId.padStart(DEFAULT_ID_SUFFIX_LENGTH, '0').takeLast(DEFAULT_ID_SUFFIX_LENGTH)
val longName = app.getString(Res.string.fallback_node_name) + " $safeUserId"
val longName = getString(Res.string.fallback_node_name) + " $safeUserId"
val defaultUser =
MeshProtos.User.newBuilder()
.setId(userId)

View file

@ -48,14 +48,21 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.entity.MeshLog
import org.meshtastic.core.model.util.formatUptime
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.ble_devices
import org.meshtastic.core.strings.no_pax_metrics_logs
import org.meshtastic.core.strings.pax
import org.meshtastic.core.strings.uptime
import org.meshtastic.core.strings.wifi_devices
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.OptionLabel
import org.meshtastic.core.ui.component.SlidingSelector
@ -64,13 +71,12 @@ import org.meshtastic.proto.PaxcountProtos
import org.meshtastic.proto.Portnums.PortNum
import java.text.DateFormat
import java.util.Date
import org.meshtastic.core.strings.R as Res
private const val CHART_WEIGHT = 1f
private const val Y_AXIS_WEIGHT = 0.1f
private const val CHART_WIDTH_RATIO = CHART_WEIGHT / (CHART_WEIGHT + Y_AXIS_WEIGHT + Y_AXIS_WEIGHT)
private enum class PaxSeries(val color: Color, val legendRes: Int) {
private enum class PaxSeries(val color: Color, val legendRes: StringResource) {
PAX(Color.Black, Res.string.pax),
BLE(Color.Cyan, Res.string.ble_devices),
WIFI(Color.Green, Res.string.wifi_devices),

View file

@ -54,7 +54,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
@ -62,15 +61,25 @@ import androidx.compose.ui.tooling.preview.PreviewScreenSizes
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.util.metersIn
import org.meshtastic.core.model.util.toString
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.alt
import org.meshtastic.core.strings.clear
import org.meshtastic.core.strings.heading
import org.meshtastic.core.strings.latitude
import org.meshtastic.core.strings.longitude
import org.meshtastic.core.strings.sats
import org.meshtastic.core.strings.save
import org.meshtastic.core.strings.speed
import org.meshtastic.core.strings.timestamp
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.ui.util.formatPositionTime
import org.meshtastic.proto.ConfigProtos.Config.DisplayConfig.DisplayUnits
import org.meshtastic.proto.MeshProtos
import java.text.DateFormat
import org.meshtastic.core.strings.R as Res
@Composable
private fun RowScope.PositionText(text: String, weight: Float) {

View file

@ -17,7 +17,6 @@
package org.meshtastic.feature.node.metrics
import androidx.annotation.StringRes
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
@ -54,12 +53,19 @@ import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.channel_1
import org.meshtastic.core.strings.channel_2
import org.meshtastic.core.strings.channel_3
import org.meshtastic.core.strings.current
import org.meshtastic.core.strings.voltage
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.OptionLabel
import org.meshtastic.core.ui.component.SlidingSelector
@ -72,7 +78,6 @@ import org.meshtastic.feature.node.model.TimeFrame
import org.meshtastic.proto.TelemetryProtos.Telemetry
import kotlin.math.ceil
import kotlin.math.floor
import org.meshtastic.core.strings.R as Res
@Suppress("MagicNumber")
private enum class Power(val color: Color, val min: Float, val max: Float) {
@ -83,7 +88,7 @@ private enum class Power(val color: Color, val min: Float, val max: Float) {
fun difference() = max - min
}
private enum class PowerChannel(@StringRes val strRes: Int) {
private enum class PowerChannel(val strRes: StringResource) {
ONE(Res.string.channel_1),
TWO(Res.string.channel_2),
THREE(Res.string.channel_3),
@ -349,7 +354,7 @@ private fun PowerMetricsCard(telemetry: Telemetry) {
}
@Composable
private fun PowerChannelColumn(@StringRes titleRes: Int, voltage: Float, current: Float) {
private fun PowerChannelColumn(titleRes: StringResource, voltage: Float, current: Float) {
Column {
Text(
text = stringResource(titleRes),

View file

@ -51,12 +51,17 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.rssi
import org.meshtastic.core.strings.rssi_definition
import org.meshtastic.core.strings.snr
import org.meshtastic.core.strings.snr_definition
import org.meshtastic.core.ui.component.LoraSignalIndicator
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.OptionLabel
@ -67,7 +72,6 @@ import org.meshtastic.feature.node.metrics.CommonCharts.MS_PER_SEC
import org.meshtastic.feature.node.metrics.GraphUtil.plotPoint
import org.meshtastic.feature.node.model.TimeFrame
import org.meshtastic.proto.MeshProtos.MeshPacket
import org.meshtastic.core.strings.R as Res
@Suppress("MagicNumber")
private enum class Metric(val color: Color, val min: Float, val max: Float) {

View file

@ -52,7 +52,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
@ -62,8 +61,17 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.resources.pluralStringResource
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.fullRouteDiscovery
import org.meshtastic.core.model.getTracerouteResponse
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.delete
import org.meshtastic.core.strings.routing_error_no_response
import org.meshtastic.core.strings.traceroute
import org.meshtastic.core.strings.traceroute_diff
import org.meshtastic.core.strings.traceroute_direct
import org.meshtastic.core.strings.traceroute_hops
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.SNR_FAIR_THRESHOLD
import org.meshtastic.core.ui.component.SNR_GOOD_THRESHOLD
@ -75,7 +83,6 @@ import org.meshtastic.core.ui.theme.StatusColors.StatusYellow
import org.meshtastic.feature.node.metrics.CommonCharts.MS_PER_SEC
import org.meshtastic.proto.MeshProtos
import java.text.DateFormat
import org.meshtastic.core.strings.R as Res
@OptIn(ExperimentalFoundationApi::class)
@Suppress("LongMethod")

View file

@ -17,7 +17,6 @@
package org.meshtastic.feature.node.model
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ChargingStation
import androidx.compose.material.icons.filled.LocationOn
@ -29,11 +28,21 @@ import androidx.compose.material.icons.filled.Route
import androidx.compose.material.icons.filled.SignalCellularAlt
import androidx.compose.material.icons.filled.Thermostat
import androidx.compose.ui.graphics.vector.ImageVector
import org.jetbrains.compose.resources.StringResource
import org.meshtastic.core.navigation.NodeDetailRoutes
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.strings.R as Res
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.device_metrics_log
import org.meshtastic.core.strings.env_metrics_log
import org.meshtastic.core.strings.host_metrics_log
import org.meshtastic.core.strings.node_map
import org.meshtastic.core.strings.pax_metrics_log
import org.meshtastic.core.strings.position_log
import org.meshtastic.core.strings.power_metrics_log
import org.meshtastic.core.strings.sig_metrics_log
import org.meshtastic.core.strings.traceroute_log
enum class LogsType(@StringRes val titleRes: Int, val icon: ImageVector, val route: Route) {
enum class LogsType(val titleRes: StringResource, val icon: ImageVector, val route: Route) {
DEVICE(Res.string.device_metrics_log, Icons.Default.ChargingStation, NodeDetailRoutes.DeviceMetrics),
NODE_MAP(Res.string.node_map, Icons.Default.Map, NodeDetailRoutes.NodeMap),
POSITIONS(Res.string.position_log, Icons.Default.LocationOn, NodeDetailRoutes.PositionLog),

View file

@ -18,18 +18,18 @@
package org.meshtastic.feature.node.model
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.ui.graphics.vector.ImageVector
import org.jetbrains.compose.resources.StringResource
internal data class VectorMetricInfo(
@StringRes val label: Int,
val label: StringResource,
val value: String,
val icon: ImageVector,
val rotateIcon: Float = 0f,
)
internal data class DrawableMetricInfo(
@StringRes val label: Int,
val label: StringResource,
val value: String,
@DrawableRes val icon: Int,
val rotateIcon: Float = 0f,

View file

@ -17,18 +17,24 @@
package org.meshtastic.feature.node.model
import androidx.annotation.StringRes
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.StringResource
import org.meshtastic.core.database.entity.FirmwareRelease
import org.meshtastic.core.database.entity.MeshLog
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.DeviceHardware
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.forty_eight_hours
import org.meshtastic.core.strings.four_weeks
import org.meshtastic.core.strings.max
import org.meshtastic.core.strings.one_week
import org.meshtastic.core.strings.twenty_four_hours
import org.meshtastic.core.strings.two_weeks
import org.meshtastic.proto.ConfigProtos
import org.meshtastic.proto.MeshProtos
import org.meshtastic.proto.TelemetryProtos
import java.util.concurrent.TimeUnit
import org.meshtastic.core.strings.R as Res
data class MetricsState(
val isLocal: Boolean = false,
@ -87,7 +93,7 @@ data class MetricsState(
/** Supported time frames used to display data. */
@Suppress("MagicNumber")
enum class TimeFrame(val seconds: Long, @StringRes val strRes: Int) {
enum class TimeFrame(val seconds: Long, val strRes: StringResource) {
TWENTY_FOUR_HOURS(TimeUnit.DAYS.toSeconds(1), Res.string.twenty_four_hours),
FORTY_EIGHT_HOURS(TimeUnit.DAYS.toSeconds(2), Res.string.forty_eight_hours),
ONE_WEEK(TimeUnit.DAYS.toSeconds(7), Res.string.one_week),

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

Some files were not shown because too many files have changed in this diff Show more