mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-10-06 18:41:21 -04:00
Make :core:strings a Compose Multiplatform library (#3617)
This commit is contained in:
1 parent
d7fff4add2
commit
28590bfcdf
206 files changed
+1722
-470
No files matched your search
+34
-34
@@ -87,42 +87,42 @@ android {
|
||||
androidResources.localeFilters.addAll(
|
||||
listOf(
|
||||
"en",
|
||||
"ar-rSA",
|
||||
"b+sr+Latn",
|
||||
"bg-rBG",
|
||||
"ca-rES",
|
||||
"cs-rCZ",
|
||||
"de-rDE",
|
||||
"el-rGR",
|
||||
"es-rES",
|
||||
"et-rEE",
|
||||
"fi-rFI",
|
||||
"fr-rFR",
|
||||
"ga-rIE",
|
||||
"gl-rES",
|
||||
"hr-rHR",
|
||||
"ht-rHT",
|
||||
"hu-rHU",
|
||||
"is-rIS",
|
||||
"it-rIT",
|
||||
"iw-rIL",
|
||||
"ja-rJP",
|
||||
"ko-rKR",
|
||||
"lt-rLT",
|
||||
"nl-rNL",
|
||||
"no-rNO",
|
||||
"pl-rPL",
|
||||
"ar",
|
||||
"bg",
|
||||
"ca",
|
||||
"cs",
|
||||
"de",
|
||||
"el",
|
||||
"es",
|
||||
"et",
|
||||
"fi",
|
||||
"fr",
|
||||
"ga",
|
||||
"gl",
|
||||
"hr",
|
||||
"ht",
|
||||
"hu",
|
||||
"is",
|
||||
"it",
|
||||
"iw",
|
||||
"ja",
|
||||
"ko",
|
||||
"lt",
|
||||
"nl",
|
||||
"no",
|
||||
"pl",
|
||||
"pt",
|
||||
"pt-rBR",
|
||||
"pt-rPT",
|
||||
"ro-rRO",
|
||||
"ru-rRU",
|
||||
"sk-rSK",
|
||||
"sl-rSI",
|
||||
"sq-rAL",
|
||||
"ro",
|
||||
"ru",
|
||||
"sk",
|
||||
"sl",
|
||||
"sq",
|
||||
"sr",
|
||||
"srp",
|
||||
"sv-rSE",
|
||||
"tr-rTR",
|
||||
"uk-rUA",
|
||||
"sv",
|
||||
"tr",
|
||||
"uk",
|
||||
"zh-rCN",
|
||||
"zh-rTW",
|
||||
),
|
||||
|
||||
@@ -46,13 +46,15 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.datastore.UiPreferencesDataSource
|
||||
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.channel_invalid
|
||||
import org.meshtastic.core.strings.contact_invalid
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.ui.theme.MODE_DYNAMIC
|
||||
import org.meshtastic.core.ui.util.showToast
|
||||
import org.meshtastic.feature.intro.AppIntroductionScreen
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
@@ -47,14 +47,18 @@ import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import org.meshtastic.core.datastore.RecentAddressesDataSource
|
||||
import org.meshtastic.core.datastore.model.RecentAddress
|
||||
import org.meshtastic.core.model.util.anonymize
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.meshtastic
|
||||
import org.meshtastic.core.strings.pairing_completed
|
||||
import org.meshtastic.core.strings.pairing_failed_try_again
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
/**
|
||||
* A sealed class is used here to represent the different types of devices that can be displayed in the list. This is
|
||||
@@ -135,8 +139,7 @@ constructor(
|
||||
val idBytes = txtRecords["id"]
|
||||
|
||||
val shortName =
|
||||
shortNameBytes?.let { String(it, Charsets.UTF_8) }
|
||||
?: context.getString(Res.string.meshtastic)
|
||||
shortNameBytes?.let { String(it, Charsets.UTF_8) } ?: getString(Res.string.meshtastic)
|
||||
val deviceId = idBytes?.let { String(it, Charsets.UTF_8) }?.replace("!", "")
|
||||
var displayName = recentMap[address] ?: shortName
|
||||
if (deviceId != null && !displayName.split("_").none { it == deviceId }) {
|
||||
@@ -283,10 +286,10 @@ constructor(
|
||||
if (state != BluetoothDevice.BOND_BONDING) {
|
||||
Timber.d("Bonding completed, state=$state")
|
||||
if (state == BluetoothDevice.BOND_BONDED) {
|
||||
setErrorText(context.getString(Res.string.pairing_completed))
|
||||
setErrorText(getString(Res.string.pairing_completed))
|
||||
changeDeviceAddress("x${device.address}")
|
||||
} else {
|
||||
setErrorText(context.getString(Res.string.pairing_failed_try_again))
|
||||
setErrorText(getString(Res.string.pairing_failed_try_again))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.shareIn
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import org.meshtastic.core.analytics.platform.PlatformAnalytics
|
||||
import org.meshtastic.core.data.repository.FirmwareReleaseRepository
|
||||
import org.meshtastic.core.data.repository.MeshLogRepository
|
||||
@@ -51,6 +52,8 @@ import org.meshtastic.core.model.util.toChannelSet
|
||||
import org.meshtastic.core.service.IMeshService
|
||||
import org.meshtastic.core.service.MeshServiceNotifications
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.client_notification
|
||||
import org.meshtastic.core.ui.component.toSharedContact
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import org.meshtastic.proto.AdminProtos
|
||||
@@ -58,7 +61,6 @@ import org.meshtastic.proto.AppOnlyProtos
|
||||
import org.meshtastic.proto.MeshProtos
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
// Given a human name, strip out the first letter of the first three words and return that as the
|
||||
// initials for
|
||||
@@ -178,7 +180,7 @@ constructor(
|
||||
.filterNotNull()
|
||||
.onEach {
|
||||
showAlert(
|
||||
title = app.getString(Res.string.client_notification),
|
||||
title = getString(Res.string.client_notification),
|
||||
message = it,
|
||||
onConfirm = { serviceRepository.clearErrorMessage() },
|
||||
dismissable = false,
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
package com.geeksville.mesh.navigation
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.CellTower
|
||||
import androidx.compose.material.icons.filled.LightMode
|
||||
@@ -39,11 +38,22 @@ import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.navigation
|
||||
import androidx.navigation.navDeepLink
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.navigation.ContactsRoutes
|
||||
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
|
||||
import org.meshtastic.core.navigation.NodeDetailRoutes
|
||||
import org.meshtastic.core.navigation.NodesRoutes
|
||||
import org.meshtastic.core.navigation.Route
|
||||
import org.meshtastic.core.strings.R
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.device
|
||||
import org.meshtastic.core.strings.environment
|
||||
import org.meshtastic.core.strings.host
|
||||
import org.meshtastic.core.strings.pax
|
||||
import org.meshtastic.core.strings.position_log
|
||||
import org.meshtastic.core.strings.power
|
||||
import org.meshtastic.core.strings.signal
|
||||
import org.meshtastic.core.strings.traceroute
|
||||
import org.meshtastic.feature.map.node.NodeMapScreen
|
||||
import org.meshtastic.feature.map.node.NodeMapViewModel
|
||||
import org.meshtastic.feature.node.detail.NodeDetailScreen
|
||||
@@ -57,7 +67,6 @@ import org.meshtastic.feature.node.metrics.PositionLogScreen
|
||||
import org.meshtastic.feature.node.metrics.PowerMetricsScreen
|
||||
import org.meshtastic.feature.node.metrics.SignalMetricsScreen
|
||||
import org.meshtastic.feature.node.metrics.TracerouteLogScreen
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
fun NavGraphBuilder.nodesGraph(navController: NavHostController) {
|
||||
navigation<NodesRoutes.NodesGraph>(startDestination = NodesRoutes.Nodes) {
|
||||
@@ -198,7 +207,7 @@ private inline fun <reified R : Route> NavGraphBuilder.addNodeDetailScreenCompos
|
||||
}
|
||||
|
||||
enum class NodeDetailRoute(
|
||||
@StringRes val title: Int,
|
||||
val title: StringResource,
|
||||
val route: Route,
|
||||
val icon: ImageVector?,
|
||||
val screenComposable: @Composable (metricsViewModel: MetricsViewModel, onNavigateUp: () -> Unit) -> Unit,
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.geeksville.mesh.util.ignoreException
|
||||
import com.geeksville.mesh.util.toRemoteExceptions
|
||||
import com.google.protobuf.ByteString
|
||||
import com.google.protobuf.InvalidProtocolBufferException
|
||||
import com.meshtastic.core.strings.getString
|
||||
import dagger.Lazy
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CancellationException
|
||||
@@ -86,6 +87,14 @@ import org.meshtastic.core.service.MeshServiceNotifications
|
||||
import org.meshtastic.core.service.SERVICE_NOTIFY_ID
|
||||
import org.meshtastic.core.service.ServiceAction
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.connected_count
|
||||
import org.meshtastic.core.strings.critical_alert
|
||||
import org.meshtastic.core.strings.device_sleeping
|
||||
import org.meshtastic.core.strings.disconnected
|
||||
import org.meshtastic.core.strings.error_duty_cycle
|
||||
import org.meshtastic.core.strings.unknown_username
|
||||
import org.meshtastic.core.strings.waypoint_received
|
||||
import org.meshtastic.proto.AdminProtos
|
||||
import org.meshtastic.proto.AppOnlyProtos
|
||||
import org.meshtastic.proto.ChannelProtos
|
||||
@@ -113,7 +122,6 @@ import java.util.UUID
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.absoluteValue
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
/**
|
||||
* Handles all the communication with android apps. Also keeps an internal model of the network state.
|
||||
|
||||
@@ -28,7 +28,6 @@ import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.media.AudioAttributes
|
||||
import android.media.RingtoneManager
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.Person
|
||||
import androidx.core.app.RemoteInput
|
||||
@@ -37,17 +36,32 @@ import androidx.core.net.toUri
|
||||
import com.geeksville.mesh.MainActivity
|
||||
import com.geeksville.mesh.R.raw
|
||||
import com.geeksville.mesh.service.ReplyReceiver.Companion.KEY_TEXT_REPLY
|
||||
import com.meshtastic.core.strings.getString
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.database.entity.NodeEntity
|
||||
import org.meshtastic.core.model.util.formatUptime
|
||||
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
|
||||
import org.meshtastic.core.service.MeshServiceNotifications
|
||||
import org.meshtastic.core.service.SERVICE_NOTIFY_ID
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.client_notification
|
||||
import org.meshtastic.core.strings.low_battery_message
|
||||
import org.meshtastic.core.strings.low_battery_title
|
||||
import org.meshtastic.core.strings.meshtastic_alerts_notifications
|
||||
import org.meshtastic.core.strings.meshtastic_broadcast_notifications
|
||||
import org.meshtastic.core.strings.meshtastic_low_battery_notifications
|
||||
import org.meshtastic.core.strings.meshtastic_low_battery_temporary_remote_notifications
|
||||
import org.meshtastic.core.strings.meshtastic_messages_notifications
|
||||
import org.meshtastic.core.strings.meshtastic_new_nodes_notifications
|
||||
import org.meshtastic.core.strings.meshtastic_service_notifications
|
||||
import org.meshtastic.core.strings.new_node_seen
|
||||
import org.meshtastic.core.strings.no_local_stats
|
||||
import org.meshtastic.core.strings.reply
|
||||
import org.meshtastic.proto.MeshProtos
|
||||
import org.meshtastic.proto.TelemetryProtos
|
||||
import org.meshtastic.proto.TelemetryProtos.LocalStats
|
||||
import javax.inject.Inject
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
/**
|
||||
* Manages the creation and display of all app notifications.
|
||||
@@ -73,7 +87,7 @@ class MeshServiceNotificationsImpl @Inject constructor(@ApplicationContext priva
|
||||
*/
|
||||
private sealed class NotificationType(
|
||||
val channelId: String,
|
||||
@StringRes val channelNameRes: Int,
|
||||
val channelNameRes: StringResource,
|
||||
val importance: Int,
|
||||
) {
|
||||
object ServiceState :
|
||||
|
||||
@@ -21,7 +21,6 @@ package com.geeksville.mesh.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.os.Build
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
@@ -71,8 +70,6 @@ import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalResources
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.NavDestination
|
||||
@@ -100,6 +97,9 @@ import com.google.accompanist.permissions.isGranted
|
||||
import com.google.accompanist.permissions.rememberPermissionState
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.DeviceVersion
|
||||
import org.meshtastic.core.navigation.ConnectionsRoutes
|
||||
import org.meshtastic.core.navigation.ContactsRoutes
|
||||
@@ -108,6 +108,25 @@ import org.meshtastic.core.navigation.NodesRoutes
|
||||
import org.meshtastic.core.navigation.Route
|
||||
import org.meshtastic.core.navigation.SettingsRoutes
|
||||
import org.meshtastic.core.service.ConnectionState
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.app_too_old
|
||||
import org.meshtastic.core.strings.bottom_nav_settings
|
||||
import org.meshtastic.core.strings.client_notification
|
||||
import org.meshtastic.core.strings.compromised_keys
|
||||
import org.meshtastic.core.strings.connected
|
||||
import org.meshtastic.core.strings.connections
|
||||
import org.meshtastic.core.strings.conversations
|
||||
import org.meshtastic.core.strings.device_sleeping
|
||||
import org.meshtastic.core.strings.disconnected
|
||||
import org.meshtastic.core.strings.firmware_old
|
||||
import org.meshtastic.core.strings.firmware_too_old
|
||||
import org.meshtastic.core.strings.map
|
||||
import org.meshtastic.core.strings.must_update
|
||||
import org.meshtastic.core.strings.nodes
|
||||
import org.meshtastic.core.strings.okay
|
||||
import org.meshtastic.core.strings.should_update
|
||||
import org.meshtastic.core.strings.should_update_firmware
|
||||
import org.meshtastic.core.strings.traceroute
|
||||
import org.meshtastic.core.ui.component.MultipleChoiceAlertDialog
|
||||
import org.meshtastic.core.ui.component.SimpleAlertDialog
|
||||
import org.meshtastic.core.ui.icon.Conversations
|
||||
@@ -122,9 +141,8 @@ import org.meshtastic.core.ui.theme.StatusColors.StatusGreen
|
||||
import org.meshtastic.feature.node.metrics.annotateTraceroute
|
||||
import org.meshtastic.proto.MeshProtos
|
||||
import timber.log.Timber
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
enum class TopLevelDestination(@StringRes val label: Int, val icon: ImageVector, val route: Route) {
|
||||
enum class TopLevelDestination(val label: StringResource, val icon: ImageVector, val route: Route) {
|
||||
Conversations(Res.string.conversations, MeshtasticIcons.Conversations, ContactsRoutes.ContactsGraph),
|
||||
Nodes(Res.string.nodes, MeshtasticIcons.Nodes, NodesRoutes.NodesGraph),
|
||||
Map(Res.string.map, MeshtasticIcons.Map, MapRoutes.Map),
|
||||
@@ -392,7 +410,6 @@ private fun VersionChecks(viewModel: UIViewModel) {
|
||||
val connectionState by viewModel.connectionState.collectAsStateWithLifecycle()
|
||||
val myNodeInfo by viewModel.myNodeInfo.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
val resources = LocalResources.current
|
||||
|
||||
val myFirmwareVersion = myNodeInfo?.firmwareVersion
|
||||
|
||||
@@ -424,8 +441,8 @@ private fun VersionChecks(viewModel: UIViewModel) {
|
||||
val isOld = info.minAppVersion > BuildConfig.VERSION_CODE && BuildConfig.DEBUG.not()
|
||||
if (isOld) {
|
||||
viewModel.showAlert(
|
||||
resources.getString(Res.string.app_too_old),
|
||||
resources.getString(Res.string.must_update),
|
||||
getString(Res.string.app_too_old),
|
||||
getString(Res.string.must_update),
|
||||
dismissable = false,
|
||||
onConfirm = {
|
||||
val service = viewModel.meshService ?: return@showAlert
|
||||
@@ -436,8 +453,8 @@ private fun VersionChecks(viewModel: UIViewModel) {
|
||||
myFirmwareVersion?.let {
|
||||
val curVer = DeviceVersion(it)
|
||||
if (curVer < MeshService.absoluteMinDeviceVersion) {
|
||||
val title = resources.getString(Res.string.firmware_too_old)
|
||||
val message = resources.getString(Res.string.firmware_old)
|
||||
val title = getString(Res.string.firmware_too_old)
|
||||
val message = getString(Res.string.firmware_old)
|
||||
viewModel.showAlert(
|
||||
title = title,
|
||||
html = message,
|
||||
@@ -448,9 +465,8 @@ private fun VersionChecks(viewModel: UIViewModel) {
|
||||
},
|
||||
)
|
||||
} else if (curVer < MeshService.minDeviceVersion) {
|
||||
val title = resources.getString(Res.string.should_update_firmware)
|
||||
val message =
|
||||
resources.getString(Res.string.should_update, latestStableFirmwareRelease.asString)
|
||||
val title = getString(Res.string.should_update_firmware)
|
||||
val message = getString(Res.string.should_update, latestStableFirmwareRelease.asString)
|
||||
viewModel.showAlert(title = title, message = message, dismissable = false, onConfirm = {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,6 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
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.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -62,9 +60,20 @@ import com.geeksville.mesh.ui.connections.components.NetworkDevices
|
||||
import com.geeksville.mesh.ui.connections.components.UsbDevices
|
||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import kotlinx.coroutines.delay
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.navigation.Route
|
||||
import org.meshtastic.core.navigation.SettingsRoutes
|
||||
import org.meshtastic.core.service.ConnectionState
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.connected
|
||||
import org.meshtastic.core.strings.connected_device
|
||||
import org.meshtastic.core.strings.connected_sleeping
|
||||
import org.meshtastic.core.strings.connections
|
||||
import org.meshtastic.core.strings.must_set_region
|
||||
import org.meshtastic.core.strings.not_connected
|
||||
import org.meshtastic.core.strings.set_your_region
|
||||
import org.meshtastic.core.strings.warning_not_paired
|
||||
import org.meshtastic.core.ui.component.ListItem
|
||||
import org.meshtastic.core.ui.component.MainAppBar
|
||||
import org.meshtastic.core.ui.component.TitledCard
|
||||
@@ -73,7 +82,6 @@ import org.meshtastic.feature.settings.navigation.getNavRouteFrom
|
||||
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
|
||||
import org.meshtastic.feature.settings.radio.component.PacketResponseStateDialog
|
||||
import org.meshtastic.proto.ConfigProtos
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
fun String?.isIPAddress(): Boolean = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
@Suppress("DEPRECATION")
|
||||
@@ -104,7 +112,6 @@ fun ConnectionsScreen(
|
||||
val connectionState by
|
||||
connectionsViewModel.connectionState.collectAsStateWithLifecycle(ConnectionState.DISCONNECTED)
|
||||
val scanning by scanModel.spinner.collectAsStateWithLifecycle(false)
|
||||
val context = LocalContext.current
|
||||
val ourNode by connectionsViewModel.ourNodeInfo.collectAsStateWithLifecycle()
|
||||
val selectedDevice by scanModel.selectedNotNullFlow.collectAsStateWithLifecycle()
|
||||
val bluetoothState by connectionsViewModel.bluetoothState.collectAsStateWithLifecycle()
|
||||
@@ -158,7 +165,7 @@ fun ConnectionsScreen(
|
||||
|
||||
ConnectionState.DISCONNECTED -> Res.string.not_connected
|
||||
ConnectionState.DEVICE_SLEEP -> Res.string.connected_sleeping
|
||||
}.let { scanModel.setErrorText(context.getString(it)) }
|
||||
}.let { scanModel.setErrorText(getString(it)) }
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
|
||||
@@ -43,7 +43,6 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.model.BTScanModel
|
||||
@@ -51,9 +50,20 @@ import com.geeksville.mesh.model.DeviceListEntry
|
||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.MultiplePermissionsState
|
||||
import com.google.accompanist.permissions.rememberMultiplePermissionsState
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.service.ConnectionState
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.bluetooth_available_devices
|
||||
import org.meshtastic.core.strings.bluetooth_disabled
|
||||
import org.meshtastic.core.strings.bluetooth_paired_devices
|
||||
import org.meshtastic.core.strings.grant_permissions
|
||||
import org.meshtastic.core.strings.no_ble_devices
|
||||
import org.meshtastic.core.strings.open_settings
|
||||
import org.meshtastic.core.strings.permission_missing
|
||||
import org.meshtastic.core.strings.permission_missing_31
|
||||
import org.meshtastic.core.strings.scan
|
||||
import org.meshtastic.core.strings.scanning_bluetooth
|
||||
import org.meshtastic.core.ui.component.TitledCard
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
/**
|
||||
* Composable that displays a list of Bluetooth Low Energy (BLE) devices and allows scanning. It handles Bluetooth
|
||||
|
||||
+7
-4
@@ -17,7 +17,6 @@
|
||||
|
||||
package com.geeksville.mesh.ui.connections.components
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Bluetooth
|
||||
import androidx.compose.material.icons.rounded.Usb
|
||||
@@ -30,12 +29,16 @@ import androidx.compose.material3.Text
|
||||
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.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.geeksville.mesh.ui.connections.DeviceType
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.bluetooth
|
||||
import org.meshtastic.core.strings.network
|
||||
import org.meshtastic.core.strings.serial
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Suppress("LambdaParameterEventTrailing")
|
||||
@Composable
|
||||
@@ -58,7 +61,7 @@ fun ConnectionsSegmentedBar(
|
||||
}
|
||||
}
|
||||
|
||||
private enum class Item(val imageVector: ImageVector, @StringRes val textRes: Int, val deviceType: DeviceType) {
|
||||
private enum class Item(val imageVector: ImageVector, val textRes: StringResource, val deviceType: DeviceType) {
|
||||
BLUETOOTH(imageVector = Icons.Rounded.Bluetooth, textRes = Res.string.bluetooth, deviceType = DeviceType.BLE),
|
||||
NETWORK(imageVector = Icons.Rounded.Wifi, textRes = Res.string.network, deviceType = DeviceType.TCP),
|
||||
SERIAL(imageVector = Icons.Rounded.Usb, textRes = Res.string.serial, deviceType = DeviceType.USB),
|
||||
|
||||
+4
-2
@@ -32,11 +32,14 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.res.stringResource
|
||||
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.model.Node
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.disconnect
|
||||
import org.meshtastic.core.strings.firmware_version
|
||||
import org.meshtastic.core.ui.component.MaterialBatteryInfo
|
||||
import org.meshtastic.core.ui.component.NodeChip
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
@@ -44,7 +47,6 @@ import org.meshtastic.core.ui.theme.StatusColors.StatusRed
|
||||
import org.meshtastic.proto.MeshProtos
|
||||
import org.meshtastic.proto.PaxcountProtos
|
||||
import org.meshtastic.proto.TelemetryProtos
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
/** Converts Bluetooth RSSI to a 0-4 bar signal strength level. */
|
||||
@Composable
|
||||
|
||||
@@ -33,9 +33,13 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.geeksville.mesh.model.DeviceListEntry
|
||||
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.add
|
||||
import org.meshtastic.core.strings.bluetooth
|
||||
import org.meshtastic.core.strings.network
|
||||
import org.meshtastic.core.strings.serial
|
||||
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
@Composable
|
||||
|
||||
@@ -46,7 +46,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
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.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
@@ -56,10 +55,20 @@ import com.geeksville.mesh.model.DeviceListEntry
|
||||
import com.geeksville.mesh.repository.network.NetworkRepository
|
||||
import com.geeksville.mesh.ui.connections.isIPAddress
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.service.ConnectionState
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.add_network_device
|
||||
import org.meshtastic.core.strings.cancel
|
||||
import org.meshtastic.core.strings.confirm_delete_node
|
||||
import org.meshtastic.core.strings.delete
|
||||
import org.meshtastic.core.strings.discovered_network_devices
|
||||
import org.meshtastic.core.strings.ip_address
|
||||
import org.meshtastic.core.strings.ip_port
|
||||
import org.meshtastic.core.strings.no_network_devices
|
||||
import org.meshtastic.core.strings.recent_network_devices
|
||||
import org.meshtastic.core.ui.component.TitledCard
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Suppress("MagicNumber", "LongMethod")
|
||||
|
||||
@@ -21,14 +21,15 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.UsbOff
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import com.geeksville.mesh.model.BTScanModel
|
||||
import com.geeksville.mesh.model.DeviceListEntry
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.service.ConnectionState
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.no_usb_devices
|
||||
import org.meshtastic.core.ui.component.TitledCard
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Composable
|
||||
fun UsbDevices(
|
||||
|
||||
@@ -44,7 +44,6 @@ 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.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@@ -53,10 +52,14 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.geeksville.mesh.model.Contact
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.sample_message
|
||||
import org.meshtastic.core.strings.some_username
|
||||
import org.meshtastic.core.strings.unknown_username
|
||||
import org.meshtastic.core.ui.component.SecurityIcon
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.proto.AppOnlyProtos
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
|
||||
@@ -55,19 +55,37 @@ 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.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.model.Contact
|
||||
import org.jetbrains.compose.resources.pluralStringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.database.entity.ContactSettings
|
||||
import org.meshtastic.core.model.util.formatMuteRemainingTime
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.cancel
|
||||
import org.meshtastic.core.strings.close_selection
|
||||
import org.meshtastic.core.strings.conversations
|
||||
import org.meshtastic.core.strings.currently
|
||||
import org.meshtastic.core.strings.delete
|
||||
import org.meshtastic.core.strings.delete_messages
|
||||
import org.meshtastic.core.strings.delete_selection
|
||||
import org.meshtastic.core.strings.mute_1_week
|
||||
import org.meshtastic.core.strings.mute_8_hours
|
||||
import org.meshtastic.core.strings.mute_always
|
||||
import org.meshtastic.core.strings.mute_notifications
|
||||
import org.meshtastic.core.strings.mute_status_always
|
||||
import org.meshtastic.core.strings.mute_status_muted_for_days
|
||||
import org.meshtastic.core.strings.mute_status_muted_for_hours
|
||||
import org.meshtastic.core.strings.mute_status_unmuted
|
||||
import org.meshtastic.core.strings.okay
|
||||
import org.meshtastic.core.strings.select_all
|
||||
import org.meshtastic.core.strings.unmute
|
||||
import org.meshtastic.core.ui.component.MainAppBar
|
||||
import org.meshtastic.proto.AppOnlyProtos
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Suppress("LongMethod")
|
||||
|
||||
@@ -17,15 +17,14 @@
|
||||
|
||||
package com.geeksville.mesh.ui.contact
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.geeksville.mesh.model.Contact
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.PacketRepository
|
||||
import org.meshtastic.core.data.repository.RadioConfigRepository
|
||||
@@ -34,17 +33,17 @@ import org.meshtastic.core.model.DataPacket
|
||||
import org.meshtastic.core.model.util.getChannel
|
||||
import org.meshtastic.core.model.util.getShortDate
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.channel_name
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import org.meshtastic.proto.channelSet
|
||||
import javax.inject.Inject
|
||||
import kotlin.collections.map
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@HiltViewModel
|
||||
class ContactsViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
private val nodeRepository: NodeRepository,
|
||||
private val packetRepository: PacketRepository,
|
||||
radioConfigRepository: RadioConfigRepository,
|
||||
@@ -87,7 +86,7 @@ constructor(
|
||||
val shortName = user.shortName
|
||||
val longName =
|
||||
if (toBroadcast) {
|
||||
channelSet.getChannel(data.channel)?.name ?: context.getString(Res.string.channel_name)
|
||||
channelSet.getChannel(data.channel)?.name ?: getString(Res.string.channel_name)
|
||||
} else {
|
||||
user.longName
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.painterResource
|
||||
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
|
||||
@@ -94,12 +93,31 @@ import com.google.accompanist.permissions.rememberPermissionState
|
||||
import com.journeyapps.barcodescanner.ScanContract
|
||||
import com.journeyapps.barcodescanner.ScanOptions
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.Channel
|
||||
import org.meshtastic.core.model.util.getChannelUrl
|
||||
import org.meshtastic.core.model.util.qrCode
|
||||
import org.meshtastic.core.model.util.toChannelSet
|
||||
import org.meshtastic.core.navigation.Route
|
||||
import org.meshtastic.core.service.ConnectionState
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.add
|
||||
import org.meshtastic.core.strings.apply
|
||||
import org.meshtastic.core.strings.are_you_sure_change_default
|
||||
import org.meshtastic.core.strings.cancel
|
||||
import org.meshtastic.core.strings.cant_change_no_radio
|
||||
import org.meshtastic.core.strings.channel_invalid
|
||||
import org.meshtastic.core.strings.copy
|
||||
import org.meshtastic.core.strings.edit
|
||||
import org.meshtastic.core.strings.modem_preset
|
||||
import org.meshtastic.core.strings.navigate_into_label
|
||||
import org.meshtastic.core.strings.qr_code
|
||||
import org.meshtastic.core.strings.replace
|
||||
import org.meshtastic.core.strings.reset
|
||||
import org.meshtastic.core.strings.reset_to_defaults
|
||||
import org.meshtastic.core.strings.scan
|
||||
import org.meshtastic.core.strings.send
|
||||
import org.meshtastic.core.strings.url
|
||||
import org.meshtastic.core.ui.component.AdaptiveTwoPane
|
||||
import org.meshtastic.core.ui.component.ChannelSelection
|
||||
import org.meshtastic.core.ui.component.MainAppBar
|
||||
@@ -116,7 +134,6 @@ import org.meshtastic.proto.ConfigProtos
|
||||
import org.meshtastic.proto.channelSet
|
||||
import org.meshtastic.proto.copy
|
||||
import timber.log.Timber
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
/**
|
||||
* Composable screen for managing and sharing Meshtastic channels. Allows users to view, edit, and share channel
|
||||
|
||||
@@ -35,7 +35,6 @@ 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.tooling.preview.PreviewScreenSizes
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
@@ -43,9 +42,15 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.model.Contact
|
||||
import com.geeksville.mesh.ui.contact.ContactItem
|
||||
import com.geeksville.mesh.ui.contact.ContactsViewModel
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.sample_message
|
||||
import org.meshtastic.core.strings.share
|
||||
import org.meshtastic.core.strings.share_to
|
||||
import org.meshtastic.core.strings.some_username
|
||||
import org.meshtastic.core.strings.unknown_username
|
||||
import org.meshtastic.core.ui.component.MainAppBar
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Composable
|
||||
fun ShareScreen(viewModel: ContactsViewModel = hiltViewModel(), onConfirm: (String) -> Unit, onNavigateUp: () -> Unit) {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright (c) 2025 Meshtastic LLC
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<resources>
|
||||
<string name="app_name" translatable="false">Meshtastic</string>
|
||||
</resources>
|
||||
@@ -112,5 +112,10 @@ gradlePlugin {
|
||||
implementationClass = "SpotlessConventionPlugin"
|
||||
}
|
||||
|
||||
register("kmpLibrary") {
|
||||
id = libs.plugins.meshtastic.kmp.library.get().pluginId
|
||||
implementationClass = "KmpLibraryConventionPlugin"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import com.android.build.api.dsl.androidLibrary
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import java.io.FileInputStream
|
||||
import java.util.Properties
|
||||
|
||||
class KmpLibraryConventionPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
with(target) {
|
||||
apply(plugin = "org.jetbrains.kotlin.multiplatform")
|
||||
apply(plugin = "org.jetbrains.kotlin.plugin.compose")
|
||||
apply(plugin = "com.android.kotlin.multiplatform.library")
|
||||
apply(plugin = "meshtastic.detekt")
|
||||
apply(plugin = "meshtastic.spotless")
|
||||
apply(plugin = "com.autonomousapps.dependency-analysis")
|
||||
|
||||
val configPropertiesFile = rootProject.file("config.properties")
|
||||
val configProperties = Properties()
|
||||
|
||||
if (configPropertiesFile.exists()) {
|
||||
FileInputStream(configPropertiesFile).use { configProperties.load(it) }
|
||||
}
|
||||
|
||||
extensions.configure<KotlinMultiplatformExtension> {
|
||||
@Suppress("UnstableApiUsage")
|
||||
androidLibrary {
|
||||
compileSdk = configProperties.getProperty("COMPILE_SDK").toInt()
|
||||
minSdk = configProperties.getProperty("MIN_SDK").toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -19,8 +19,10 @@
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.android.kotlin.multiplatform.library) apply false
|
||||
alias(libs.plugins.android.library) apply false
|
||||
alias(libs.plugins.compose) apply false
|
||||
alias(libs.plugins.compose.compiler) apply false
|
||||
alias(libs.plugins.compose.multiplatform) apply false
|
||||
alias(libs.plugins.datadog) apply false
|
||||
alias(libs.plugins.devtools.ksp) apply false
|
||||
alias(libs.plugins.firebase.crashlytics) apply false
|
||||
@@ -30,6 +32,7 @@ plugins {
|
||||
alias(libs.plugins.room) apply false
|
||||
alias(libs.plugins.kotlin.android) apply false
|
||||
alias(libs.plugins.kotlin.jvm) apply false
|
||||
alias(libs.plugins.kotlin.multiplatform) apply false
|
||||
alias(libs.plugins.kotlin.parcelize) apply false
|
||||
alias(libs.plugins.kotlin.serialization) apply false
|
||||
alias(libs.plugins.ktorfit) apply false
|
||||
|
||||
@@ -17,15 +17,37 @@
|
||||
|
||||
package org.meshtastic.core.database.model
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.database.entity.Reaction
|
||||
import org.meshtastic.core.model.MessageStatus
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.delivery_confirmed
|
||||
import org.meshtastic.core.strings.error
|
||||
import org.meshtastic.core.strings.message_delivery_status
|
||||
import org.meshtastic.core.strings.message_status_enroute
|
||||
import org.meshtastic.core.strings.message_status_queued
|
||||
import org.meshtastic.core.strings.routing_error_admin_bad_session_key
|
||||
import org.meshtastic.core.strings.routing_error_admin_public_key_unauthorized
|
||||
import org.meshtastic.core.strings.routing_error_bad_request
|
||||
import org.meshtastic.core.strings.routing_error_duty_cycle_limit
|
||||
import org.meshtastic.core.strings.routing_error_got_nak
|
||||
import org.meshtastic.core.strings.routing_error_max_retransmit
|
||||
import org.meshtastic.core.strings.routing_error_no_channel
|
||||
import org.meshtastic.core.strings.routing_error_no_interface
|
||||
import org.meshtastic.core.strings.routing_error_no_response
|
||||
import org.meshtastic.core.strings.routing_error_no_route
|
||||
import org.meshtastic.core.strings.routing_error_none
|
||||
import org.meshtastic.core.strings.routing_error_not_authorized
|
||||
import org.meshtastic.core.strings.routing_error_pki_failed
|
||||
import org.meshtastic.core.strings.routing_error_pki_unknown_pubkey
|
||||
import org.meshtastic.core.strings.routing_error_rate_limit_exceeded
|
||||
import org.meshtastic.core.strings.routing_error_timeout
|
||||
import org.meshtastic.core.strings.routing_error_too_large
|
||||
import org.meshtastic.core.strings.unrecognized
|
||||
import org.meshtastic.proto.MeshProtos.Routing
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Suppress("CyclomaticComplexMethod")
|
||||
@StringRes
|
||||
fun getStringResFrom(routingError: Int): Int = when (routingError) {
|
||||
fun getStringResFrom(routingError: Int): StringResource = when (routingError) {
|
||||
Routing.Error.NONE_VALUE -> Res.string.routing_error_none
|
||||
Routing.Error.NO_ROUTE_VALUE -> Res.string.routing_error_no_route
|
||||
Routing.Error.GOT_NAK_VALUE -> Res.string.routing_error_got_nak
|
||||
@@ -66,7 +88,7 @@ data class Message(
|
||||
val viaMqtt: Boolean = false,
|
||||
val relayNode: Int? = null,
|
||||
) {
|
||||
fun getStatusStringRes(): Pair<Int, Int> {
|
||||
fun getStatusStringRes(): Pair<StringResource, StringResource> {
|
||||
val title = if (routingError > 0) Res.string.error else Res.string.message_delivery_status
|
||||
val text =
|
||||
when (status) {
|
||||
|
||||
@@ -17,10 +17,17 @@
|
||||
|
||||
package org.meshtastic.core.database.model
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
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.node_sort_alpha
|
||||
import org.meshtastic.core.strings.node_sort_channel
|
||||
import org.meshtastic.core.strings.node_sort_distance
|
||||
import org.meshtastic.core.strings.node_sort_hops_away
|
||||
import org.meshtastic.core.strings.node_sort_last_heard
|
||||
import org.meshtastic.core.strings.node_sort_via_favorite
|
||||
import org.meshtastic.core.strings.node_sort_via_mqtt
|
||||
|
||||
enum class NodeSortOption(val sqlValue: String, @StringRes val stringRes: Int) {
|
||||
enum class NodeSortOption(val sqlValue: String, val stringRes: StringResource) {
|
||||
LAST_HEARD("last_heard", Res.string.node_sort_last_heard),
|
||||
ALPHABETICAL("alpha", Res.string.node_sort_alpha),
|
||||
DISTANCE("distance", Res.string.node_sort_distance),
|
||||
|
||||
@@ -17,12 +17,21 @@
|
||||
|
||||
package org.meshtastic.core.model
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.label_long_fast
|
||||
import org.meshtastic.core.strings.label_long_moderate
|
||||
import org.meshtastic.core.strings.label_long_slow
|
||||
import org.meshtastic.core.strings.label_medium_fast
|
||||
import org.meshtastic.core.strings.label_medium_slow
|
||||
import org.meshtastic.core.strings.label_short_fast
|
||||
import org.meshtastic.core.strings.label_short_slow
|
||||
import org.meshtastic.core.strings.label_short_turbo
|
||||
import org.meshtastic.core.strings.label_very_long_slow
|
||||
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig
|
||||
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig.ModemPreset
|
||||
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig.RegionCode
|
||||
import kotlin.math.floor
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
/** hash a string into an integer using the djb2 algorithm by Dan Bernstein http://www.cse.yorku.ca/~oz/hash.html */
|
||||
private fun hash(name: String): UInt { // using UInt instead of Long to match RadioInterface.cpp results
|
||||
@@ -296,7 +305,7 @@ enum class RegionInfo(
|
||||
}
|
||||
}
|
||||
|
||||
enum class ChannelOption(val modemPreset: ModemPreset, @StringRes val labelRes: Int, val bandwidth: Float) {
|
||||
enum class ChannelOption(val modemPreset: ModemPreset, val labelRes: StringResource, val bandwidth: Float) {
|
||||
VERY_LONG_SLOW(ModemPreset.VERY_LONG_SLOW, Res.string.label_very_long_slow, .0625f),
|
||||
LONG_FAST(ModemPreset.LONG_FAST, Res.string.label_long_fast, .250f),
|
||||
LONG_MODERATE(ModemPreset.LONG_MODERATE, Res.string.label_long_moderate, .125f),
|
||||
|
||||
@@ -14,7 +14,30 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import com.android.build.api.dsl.androidLibrary
|
||||
|
||||
plugins { alias(libs.plugins.meshtastic.android.library) }
|
||||
plugins {
|
||||
alias(libs.plugins.meshtastic.kmp.library)
|
||||
alias(libs.plugins.compose.multiplatform)
|
||||
}
|
||||
|
||||
android { namespace = "org.meshtastic.core.strings" }
|
||||
kotlin {
|
||||
@Suppress("UnstableApiUsage")
|
||||
androidLibrary {
|
||||
namespace = "org.meshtastic.core.strings"
|
||||
androidResources.enable = true
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
implementation(compose.runtime)
|
||||
// API because consuming modules will always need this dependency
|
||||
api(compose.components.resources)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compose.resources {
|
||||
publicResClass = true
|
||||
packageOfResClass = "org.meshtastic.core.strings"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.meshtastic.core.strings
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
|
||||
fun Context.getString(stringResource: StringResource): String = runBlocking {
|
||||
org.jetbrains.compose.resources.getString(stringResource)
|
||||
}
|
||||
|
||||
fun Context.getString(stringResource: StringResource, vararg formatArgs: Any): String = runBlocking {
|
||||
org.jetbrains.compose.resources.getString(stringResource, *formatArgs)
|
||||
}
|
||||
|
||||
fun Resources.getString(stringResource: StringResource): String = runBlocking {
|
||||
org.jetbrains.compose.resources.getString(stringResource)
|
||||
}
|
||||
|
||||
fun Resources.getString(stringResource: StringResource, vararg formatArgs: Any): String = runBlocking {
|
||||
org.jetbrains.compose.resources.getString(stringResource, *formatArgs)
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-1
@@ -22,7 +22,6 @@
|
||||
<string name="zh_CN" translatable="false">简体中文</string>
|
||||
<string name="zh_TW" translatable="false">繁體中文</string>
|
||||
|
||||
<string name="app_name" translatable="false">Meshtastic</string>
|
||||
<string name="some_username" translatable="false">SKH</string>
|
||||
<string name="sample_message" translatable="false">hey I found the cache, it is over here next to the big tiger. I\'m kinda scared.</string>
|
||||
|
||||
@@ -29,7 +29,6 @@ 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.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.TextLinkStyles
|
||||
@@ -37,7 +36,9 @@ import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.fromHtml
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
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.okay
|
||||
|
||||
@Composable
|
||||
fun SimpleAlertDialog(
|
||||
|
||||
@@ -38,7 +38,9 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.clear
|
||||
import org.meshtastic.core.strings.close
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
package org.meshtastic.core.ui.component
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -28,11 +27,12 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
@Composable
|
||||
fun ClickableTextField(
|
||||
@StringRes label: Int,
|
||||
label: StringResource,
|
||||
enabled: Boolean,
|
||||
trailingIcon: ImageVector,
|
||||
value: String,
|
||||
|
||||
@@ -40,7 +40,6 @@ import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.net.toUri
|
||||
@@ -55,15 +54,19 @@ import com.google.zxing.WriterException
|
||||
import com.journeyapps.barcodescanner.BarcodeEncoder
|
||||
import com.journeyapps.barcodescanner.ScanContract
|
||||
import com.journeyapps.barcodescanner.ScanOptions
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.DeviceVersion
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.qr_code
|
||||
import org.meshtastic.core.strings.scan_qr_code
|
||||
import org.meshtastic.core.strings.share_contact
|
||||
import org.meshtastic.core.ui.R
|
||||
import org.meshtastic.core.ui.share.SharedContactDialog
|
||||
import org.meshtastic.proto.AdminProtos
|
||||
import org.meshtastic.proto.MeshProtos
|
||||
import timber.log.Timber
|
||||
import java.net.MalformedURLException
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
/**
|
||||
* Composable FloatingActionButton to initiate scanning a QR code for adding a contact. Handles camera permission
|
||||
|
||||
@@ -27,9 +27,10 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import kotlinx.coroutines.launch
|
||||
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.copy
|
||||
|
||||
@Composable
|
||||
fun CopyIconButton(
|
||||
|
||||
@@ -39,16 +39,18 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
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 com.google.protobuf.ByteString
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.Channel
|
||||
import org.meshtastic.core.model.util.encodeToString
|
||||
import org.meshtastic.core.model.util.toByteString
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.error
|
||||
import org.meshtastic.core.strings.reset
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
|
||||
@@ -35,17 +35,23 @@ import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.remember
|
||||
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 com.google.protobuf.ByteString
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.add
|
||||
import org.meshtastic.core.strings.delete
|
||||
import org.meshtastic.core.strings.gpio_pin
|
||||
import org.meshtastic.core.strings.ignore_incoming
|
||||
import org.meshtastic.core.strings.name
|
||||
import org.meshtastic.core.strings.type
|
||||
import org.meshtastic.proto.ModuleConfigProtos.RemoteHardwarePin
|
||||
import org.meshtastic.proto.ModuleConfigProtos.RemoteHardwarePinType
|
||||
import org.meshtastic.proto.copy
|
||||
import org.meshtastic.proto.remoteHardwarePin
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
|
||||
@@ -29,13 +29,15 @@ 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 androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
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.hide_password
|
||||
import org.meshtastic.core.strings.show_password
|
||||
|
||||
@Composable
|
||||
fun EditPasswordPreference(
|
||||
|
||||
@@ -38,13 +38,14 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusState
|
||||
import androidx.compose.ui.focus.onFocusEvent
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
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.error
|
||||
|
||||
@Composable
|
||||
fun SignedIntegerEditTextPreference(
|
||||
|
||||
@@ -51,12 +51,16 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
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.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.air_quality_icon
|
||||
import org.meshtastic.core.strings.close
|
||||
import org.meshtastic.core.strings.indoor_air_quality_iaq
|
||||
import org.meshtastic.core.ui.theme.IAQColors.IAQDangerouslyPolluted
|
||||
import org.meshtastic.core.ui.theme.IAQColors.IAQExcellent
|
||||
import org.meshtastic.core.ui.theme.IAQColors.IAQExtremelyPolluted
|
||||
@@ -65,7 +69,6 @@ import org.meshtastic.core.ui.theme.IAQColors.IAQHeavilyPolluted
|
||||
import org.meshtastic.core.ui.theme.IAQColors.IAQLightlyPolluted
|
||||
import org.meshtastic.core.ui.theme.IAQColors.IAQModeratelyPolluted
|
||||
import org.meshtastic.core.ui.theme.IAQColors.IAQSeverelyPolluted
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
enum class Iaq(val color: Color, val description: String, val range: IntRange) {
|
||||
|
||||
@@ -43,13 +43,22 @@ import androidx.compose.ui.Alignment
|
||||
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.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.bad
|
||||
import org.meshtastic.core.strings.fair
|
||||
import org.meshtastic.core.strings.good
|
||||
import org.meshtastic.core.strings.none_quality
|
||||
import org.meshtastic.core.strings.rssi
|
||||
import org.meshtastic.core.strings.signal
|
||||
import org.meshtastic.core.strings.signal_quality
|
||||
import org.meshtastic.core.strings.snr
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusGreen
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusOrange
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusRed
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusYellow
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
const val SNR_GOOD_THRESHOLD = -7f
|
||||
const val SNR_FAIR_THRESHOLD = -15f
|
||||
@@ -59,7 +68,7 @@ const val RSSI_FAIR_THRESHOLD = -126
|
||||
|
||||
@Stable
|
||||
enum class Quality(
|
||||
@Stable val nameRes: Int,
|
||||
@Stable val nameRes: StringResource,
|
||||
@Stable val imageVector: ImageVector,
|
||||
@Stable val color: @Composable () -> Color,
|
||||
) {
|
||||
|
||||
@@ -33,17 +33,20 @@ import androidx.compose.material3.TopAppBar
|
||||
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.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
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.strings.R
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.application_icon
|
||||
import org.meshtastic.core.strings.navigate_back
|
||||
import org.meshtastic.core.ui.component.preview.BooleanProvider
|
||||
import org.meshtastic.core.ui.component.preview.previewNode
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
||||
@@ -33,11 +33,13 @@ import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.unknown
|
||||
import org.meshtastic.core.ui.icon.BatteryEmpty
|
||||
import org.meshtastic.core.ui.icon.BatteryUnknown
|
||||
import org.meshtastic.core.ui.icon.MeshtasticIcons
|
||||
@@ -45,7 +47,6 @@ import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusGreen
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusOrange
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusRed
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
private const val FORMAT = "%d%%"
|
||||
private const val SIZE_ICON = 20
|
||||
|
||||
+3
-2
@@ -35,11 +35,13 @@ import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.dbm_value
|
||||
import org.meshtastic.core.ui.icon.MeshtasticIcons
|
||||
import org.meshtastic.core.ui.icon.SignalCellular0Bar
|
||||
import org.meshtastic.core.ui.icon.SignalCellular1Bar
|
||||
@@ -51,7 +53,6 @@ import org.meshtastic.core.ui.theme.StatusColors.StatusGreen
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusOrange
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusRed
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusYellow
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
private const val SIZE_ICON = 20
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package org.meshtastic.core.ui.component
|
||||
|
||||
import android.util.Base64
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -53,19 +52,32 @@ import androidx.compose.ui.Alignment
|
||||
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.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.google.protobuf.ByteString
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.Channel
|
||||
import org.meshtastic.core.strings.R
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.config_security_public_key
|
||||
import org.meshtastic.core.strings.encryption_error
|
||||
import org.meshtastic.core.strings.encryption_error_text
|
||||
import org.meshtastic.core.strings.encryption_pkc
|
||||
import org.meshtastic.core.strings.encryption_pkc_text
|
||||
import org.meshtastic.core.strings.encryption_psk
|
||||
import org.meshtastic.core.strings.encryption_psk_text
|
||||
import org.meshtastic.core.strings.security_icon_help_dismiss
|
||||
import org.meshtastic.core.strings.security_icon_help_show_all
|
||||
import org.meshtastic.core.strings.security_icon_help_show_less
|
||||
import org.meshtastic.core.strings.show_all_key_title
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
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
|
||||
|
||||
/**
|
||||
* function to display information about the current node's encryption key.
|
||||
@@ -131,9 +143,9 @@ fun NodeKeyStatusIcon(
|
||||
enum class NodeKeySecurityState(
|
||||
@Stable val icon: ImageVector,
|
||||
@Stable val color: @Composable () -> Color,
|
||||
@StringRes val descriptionResId: Int,
|
||||
@StringRes val helpTextResId: Int,
|
||||
@Stable val title: Int,
|
||||
val descriptionResId: StringResource,
|
||||
val helpTextResId: StringResource,
|
||||
@Stable val title: StringResource,
|
||||
) {
|
||||
// State for public key mismatch
|
||||
PKM(
|
||||
@@ -164,7 +176,7 @@ enum class NodeKeySecurityState(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun KeyStatusDialog(@StringRes title: Int, @StringRes text: Int, key: ByteString?, onDismiss: () -> Unit = {}) {
|
||||
private fun KeyStatusDialog(title: StringResource, text: StringResource, key: ByteString?, onDismiss: () -> Unit = {}) {
|
||||
var showAll by rememberSaveable { mutableStateOf(false) }
|
||||
AlertDialog(
|
||||
modifier = Modifier,
|
||||
|
||||
+4
-2
@@ -27,15 +27,17 @@ 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.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.position_enabled
|
||||
import org.meshtastic.core.strings.precise_location
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
private const val POSITION_ENABLED = 32
|
||||
private const val POSITION_DISABLED = 0
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
package org.meshtastic.core.ui.component
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@@ -29,17 +28,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.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
@Deprecated(message = "Use overload that accepts Strings for button text.")
|
||||
@Composable
|
||||
fun PreferenceFooter(
|
||||
enabled: Boolean,
|
||||
@StringRes negativeText: Int,
|
||||
negativeText: StringResource,
|
||||
onNegativeClicked: () -> Unit,
|
||||
@StringRes positiveText: Int,
|
||||
positiveText: StringResource,
|
||||
onPositiveClicked: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
package org.meshtastic.core.ui.component
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -57,18 +56,34 @@ import androidx.compose.ui.Alignment
|
||||
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.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.Channel
|
||||
import org.meshtastic.core.model.util.getChannel
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.security_icon_badge_warning_description
|
||||
import org.meshtastic.core.strings.security_icon_description
|
||||
import org.meshtastic.core.strings.security_icon_help_dismiss
|
||||
import org.meshtastic.core.strings.security_icon_help_green_lock
|
||||
import org.meshtastic.core.strings.security_icon_help_red_open_lock
|
||||
import org.meshtastic.core.strings.security_icon_help_show_all
|
||||
import org.meshtastic.core.strings.security_icon_help_show_less
|
||||
import org.meshtastic.core.strings.security_icon_help_title
|
||||
import org.meshtastic.core.strings.security_icon_help_title_all
|
||||
import org.meshtastic.core.strings.security_icon_help_warning_precise_mqtt
|
||||
import org.meshtastic.core.strings.security_icon_help_yellow_open_lock
|
||||
import org.meshtastic.core.strings.security_icon_insecure_no_precise
|
||||
import org.meshtastic.core.strings.security_icon_insecure_precise_only
|
||||
import org.meshtastic.core.strings.security_icon_secure
|
||||
import org.meshtastic.core.strings.security_icon_warning_precise_mqtt
|
||||
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.proto.AppOnlyProtos
|
||||
import org.meshtastic.proto.ChannelProtos.ChannelSettings
|
||||
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
private const val PRECISE_POSITION_BITS = 32
|
||||
|
||||
@@ -87,8 +102,8 @@ private const val PRECISE_POSITION_BITS = 32
|
||||
enum class SecurityState(
|
||||
@Stable val icon: ImageVector,
|
||||
@Stable val color: @Composable () -> Color,
|
||||
@StringRes val descriptionResId: Int,
|
||||
@StringRes val helpTextResId: Int,
|
||||
val descriptionResId: StringResource,
|
||||
val helpTextResId: StringResource,
|
||||
@Stable val badgeIcon: ImageVector? = null,
|
||||
@Stable val badgeIconColor: @Composable () -> Color? = { null },
|
||||
) {
|
||||
|
||||
@@ -28,15 +28,19 @@ 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.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
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.strings.Res
|
||||
import org.meshtastic.core.strings.channel_air_util
|
||||
import org.meshtastic.core.strings.hops_away
|
||||
import org.meshtastic.core.strings.signal
|
||||
import org.meshtastic.core.strings.signal_quality
|
||||
import org.meshtastic.core.ui.component.preview.NodePreviewParameterProvider
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
const val MAX_VALID_SNR = 100F
|
||||
const val MAX_VALID_RSSI = 0
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
package org.meshtastic.core.ui.component
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
@@ -28,16 +27,21 @@ 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.text.style.TextAlign
|
||||
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.cancel
|
||||
import org.meshtastic.core.strings.message
|
||||
import org.meshtastic.core.strings.okay
|
||||
import org.meshtastic.core.strings.sample_message
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Composable
|
||||
fun SimpleAlertDialog(
|
||||
@StringRes title: Int,
|
||||
title: StringResource,
|
||||
text: @Composable (() -> Unit)? = null,
|
||||
confirmText: String? = null,
|
||||
onConfirm: (() -> Unit)? = null,
|
||||
@@ -74,8 +78,8 @@ fun SimpleAlertDialog(
|
||||
|
||||
@Composable
|
||||
fun SimpleAlertDialog(
|
||||
@StringRes title: Int,
|
||||
@StringRes text: Int,
|
||||
title: StringResource,
|
||||
text: StringResource,
|
||||
onConfirm: (() -> Unit)? = null,
|
||||
onDismiss: () -> Unit = {},
|
||||
) = SimpleAlertDialog(
|
||||
@@ -87,7 +91,7 @@ fun SimpleAlertDialog(
|
||||
|
||||
@Composable
|
||||
fun SimpleAlertDialog(
|
||||
@StringRes title: Int,
|
||||
title: StringResource,
|
||||
text: String,
|
||||
onConfirm: (() -> Unit)? = null,
|
||||
onDismiss: () -> Unit = {},
|
||||
|
||||
@@ -43,7 +43,6 @@ 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.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.PreviewScreenSizes
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -51,13 +50,19 @@ import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.Channel
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.accept
|
||||
import org.meshtastic.core.strings.add
|
||||
import org.meshtastic.core.strings.cancel
|
||||
import org.meshtastic.core.strings.new_channel_rcvd
|
||||
import org.meshtastic.core.strings.replace
|
||||
import org.meshtastic.core.ui.component.ChannelSelection
|
||||
import org.meshtastic.proto.AppOnlyProtos.ChannelSet
|
||||
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig.ModemPreset
|
||||
import org.meshtastic.proto.channelSet
|
||||
import org.meshtastic.proto.copy
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Composable
|
||||
fun ScannedQrCodeDialog(
|
||||
|
||||
@@ -23,14 +23,19 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
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.cancel
|
||||
import org.meshtastic.core.strings.import_known_shared_contact_text
|
||||
import org.meshtastic.core.strings.import_label
|
||||
import org.meshtastic.core.strings.import_shared_contact
|
||||
import org.meshtastic.core.strings.public_key_changed
|
||||
import org.meshtastic.core.ui.component.SimpleAlertDialog
|
||||
import org.meshtastic.core.ui.component.compareUsers
|
||||
import org.meshtastic.core.ui.component.userFieldsToString
|
||||
import org.meshtastic.proto.AdminProtos
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
/** A dialog for importing a shared contact that was scanned from a QR code. */
|
||||
@Composable
|
||||
|
||||
@@ -19,16 +19,17 @@ package org.meshtastic.core.ui.util
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.StringRes
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.getString
|
||||
|
||||
suspend fun Context.showToast(@StringRes resId: Int) {
|
||||
showToast(getString(resId))
|
||||
suspend fun Context.showToast(stringResource: StringResource) {
|
||||
showToast(getString(stringResource))
|
||||
}
|
||||
|
||||
suspend fun Context.showToast(text: CharSequence) {
|
||||
suspend fun Context.showToast(stringResource: StringResource, vararg formatArgs: Any) {
|
||||
Toast.makeText(this, getString(stringResource, formatArgs), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
suspend fun Context.showToast(text: String) {
|
||||
Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
suspend fun Context.showToast(@StringRes resId: Int, vararg formatArgs: Any) {
|
||||
Toast.makeText(this, getString(resId, formatArgs), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
@@ -18,7 +18,9 @@
|
||||
package org.meshtastic.core.ui.util
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.unknown_age
|
||||
import org.meshtastic.proto.ChannelProtos
|
||||
import org.meshtastic.proto.ChannelProtos.ChannelSettings
|
||||
import org.meshtastic.proto.MeshProtos
|
||||
@@ -28,7 +30,6 @@ import org.meshtastic.proto.channel
|
||||
import org.meshtastic.proto.channelSettings
|
||||
import java.text.DateFormat
|
||||
import kotlin.time.Duration.Companion.days
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
private const val SECONDS_TO_MILLIS = 1000L
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ pull_request_labels:
|
||||
- automation
|
||||
- l10n
|
||||
files:
|
||||
- source: /**/src/main/res/values/strings.xml
|
||||
- source: /**/src/commonMain/composeResources/values/strings.xml
|
||||
translation: /%original_path%-%android_code%/strings.xml
|
||||
translate_attributes: 0
|
||||
content_segmentation: 0
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Loaded 100 of 206 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user