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

@ -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),