mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
Make :core:strings a Compose Multiplatform library (#3617)
This commit is contained in:
parent
d7fff4add2
commit
28590bfcdf
206 changed files with 1722 additions and 470 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue