mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
Clean up string access (#3629)
This commit is contained in:
parent
4e033d422d
commit
a2da943ed7
21 changed files with 106 additions and 127 deletions
|
|
@ -25,7 +25,6 @@ import android.hardware.usb.UsbManager
|
|||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.activity.SystemBarStyle
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
|
|
@ -40,13 +39,16 @@ import androidx.compose.ui.platform.LocalView
|
|||
import androidx.core.net.toUri
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.ui.MainScreen
|
||||
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.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
|
||||
|
|
@ -119,17 +121,13 @@ class MainActivity : AppCompatActivity() {
|
|||
Timber.d("App link data is a channel set")
|
||||
model.requestChannelUrl(
|
||||
url = it,
|
||||
onFailure = {
|
||||
Toast.makeText(this, getString(Res.string.channel_invalid), Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
onFailure = { lifecycleScope.launch { showToast(Res.string.channel_invalid) } },
|
||||
)
|
||||
} else if (it.path?.startsWith("/v/") == true || it.path?.startsWith("/V/") == true) {
|
||||
Timber.d("App link data is a shared contact")
|
||||
model.setSharedContactRequested(
|
||||
url = it,
|
||||
onFailure = {
|
||||
Toast.makeText(this, getString(Res.string.contact_invalid), Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
onFailure = { lifecycleScope.launch { showToast(Res.string.contact_invalid) } },
|
||||
)
|
||||
} else {
|
||||
Timber.d("App link data is not a channel set")
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import android.Manifest
|
|||
import android.content.ClipData
|
||||
import android.net.Uri
|
||||
import android.os.RemoteException
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.border
|
||||
|
|
@ -78,7 +77,6 @@ import androidx.compose.ui.platform.ClipEntry
|
|||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalResources
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
|
|
@ -107,6 +105,7 @@ import org.meshtastic.core.ui.component.ChannelSelection
|
|||
import org.meshtastic.core.ui.component.MainAppBar
|
||||
import org.meshtastic.core.ui.component.PreferenceFooter
|
||||
import org.meshtastic.core.ui.qr.ScannedQrCodeDialog
|
||||
import org.meshtastic.core.ui.util.showToast
|
||||
import org.meshtastic.feature.settings.navigation.ConfigRoute
|
||||
import org.meshtastic.feature.settings.navigation.getNavRouteFrom
|
||||
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
|
||||
|
|
@ -181,13 +180,13 @@ fun ChannelScreen(
|
|||
settings.addAll(result)
|
||||
}
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val resources = LocalResources.current
|
||||
val barcodeLauncher =
|
||||
rememberLauncherForActivityResult(ScanContract()) { result ->
|
||||
if (result.contents != null) {
|
||||
viewModel.requestChannelUrl(result.contents.toUri()) {
|
||||
Toast.makeText(context, resources.getString(Res.string.channel_invalid), Toast.LENGTH_SHORT).show()
|
||||
scope.launch { context.showToast(Res.string.channel_invalid) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +224,7 @@ fun ChannelScreen(
|
|||
channelSet = channels // Throw away user edits
|
||||
|
||||
// Tell the user to try again
|
||||
Toast.makeText(context, resources.getString(Res.string.cant_change_no_radio), Toast.LENGTH_SHORT).show()
|
||||
scope.launch { context.showToast(Res.string.cant_change_no_radio) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -314,8 +313,7 @@ fun ChannelScreen(
|
|||
onTrackShare = viewModel::trackShare,
|
||||
onConfirm = {
|
||||
viewModel.requestChannelUrl(it) {
|
||||
Toast.makeText(context, resources.getString(Res.string.channel_invalid), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
scope.launch { context.showToast(Res.string.channel_invalid) }
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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 org.meshtastic.core.ui.util
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.StringRes
|
||||
|
||||
suspend fun Context.showToast(@StringRes resId: Int) {
|
||||
showToast(getString(resId))
|
||||
}
|
||||
|
||||
suspend fun Context.showToast(text: CharSequence) {
|
||||
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()
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@ package org.meshtastic.feature.map
|
|||
|
||||
import android.Manifest // Added for Accompanist
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
|
|
@ -50,6 +49,7 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableDoubleStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -66,12 +66,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.google.accompanist.permissions.ExperimentalPermissionsApi // Added for Accompanist
|
||||
import com.google.accompanist.permissions.rememberMultiplePermissionsState // Added for Accompanist
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.common.gpsDisabled
|
||||
import org.meshtastic.core.common.hasGps
|
||||
import org.meshtastic.core.database.entity.Packet
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.DataPacket
|
||||
import org.meshtastic.core.model.util.formatAgo
|
||||
import org.meshtastic.core.ui.util.showToast
|
||||
import org.meshtastic.feature.map.cluster.RadiusMarkerClusterer
|
||||
import org.meshtastic.feature.map.component.CacheLayout
|
||||
import org.meshtastic.feature.map.component.DownloadButton
|
||||
|
|
@ -223,6 +225,7 @@ fun MapView(mapViewModel: MapViewModel = hiltViewModel(), navigateToNodeDetails:
|
|||
var showEditWaypointDialog by remember { mutableStateOf<Waypoint?>(null) }
|
||||
var showCurrentCacheInfo by remember { mutableStateOf(false) }
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val resources = LocalResources.current
|
||||
val density = LocalDensity.current
|
||||
|
|
@ -264,7 +267,7 @@ fun MapView(mapViewModel: MapViewModel = hiltViewModel(), navigateToNodeDetails:
|
|||
fun MapView.toggleMyLocation() {
|
||||
if (context.gpsDisabled()) {
|
||||
Timber.d("Telling user we need location turned on for MyLocationNewOverlay")
|
||||
Toast.makeText(context, resources.getString(Res.string.location_disabled), Toast.LENGTH_SHORT).show()
|
||||
scope.launch { context.showToast(Res.string.location_disabled) }
|
||||
return
|
||||
}
|
||||
Timber.d("user clicked MyLocationNewOverlay ${myLocationOverlay == null}")
|
||||
|
|
@ -451,7 +454,7 @@ fun MapView(mapViewModel: MapViewModel = hiltViewModel(), navigateToNodeDetails:
|
|||
|
||||
LaunchedEffect(showCurrentCacheInfo) {
|
||||
if (!showCurrentCacheInfo) return@LaunchedEffect
|
||||
Toast.makeText(context, resources.getString(Res.string.calculating), Toast.LENGTH_SHORT).show()
|
||||
context.showToast(Res.string.calculating)
|
||||
val cacheManager = CacheManager(map)
|
||||
val cacheCapacity = cacheManager.cacheCapacity()
|
||||
val currentCacheUsage = cacheManager.currentCacheUsage()
|
||||
|
|
@ -560,21 +563,11 @@ fun MapView(mapViewModel: MapViewModel = hiltViewModel(), navigateToNodeDetails:
|
|||
zoomLevelMax.toInt(),
|
||||
cacheManagerCallback(
|
||||
onTaskComplete = {
|
||||
Toast.makeText(
|
||||
context,
|
||||
resources.getString(Res.string.map_download_complete),
|
||||
Toast.LENGTH_SHORT,
|
||||
)
|
||||
.show()
|
||||
scope.launch { context.showToast(Res.string.map_download_complete) }
|
||||
writer.onDetach()
|
||||
},
|
||||
onTaskFailed = { errors ->
|
||||
Toast.makeText(
|
||||
context,
|
||||
resources.getString(Res.string.map_download_errors, errors),
|
||||
Toast.LENGTH_SHORT,
|
||||
)
|
||||
.show()
|
||||
scope.launch { context.showToast(Res.string.map_download_errors, errors) }
|
||||
writer.onDetach()
|
||||
},
|
||||
),
|
||||
|
|
@ -619,7 +612,7 @@ fun MapView(mapViewModel: MapViewModel = hiltViewModel(), navigateToNodeDetails:
|
|||
dialog.dismiss()
|
||||
}
|
||||
|
||||
2 -> purgeTileSource { Toast.makeText(this, it, Toast.LENGTH_SHORT).show() }
|
||||
2 -> purgeTileSource { scope.launch { context.showToast(it) } }
|
||||
else -> dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.meshtastic.feature.map.component
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
|
|
@ -53,6 +52,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import org.meshtastic.core.data.model.CustomTileProviderConfig
|
||||
import org.meshtastic.core.ui.util.showToast
|
||||
import org.meshtastic.feature.map.MapViewModel
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
|
|
@ -64,11 +64,7 @@ fun CustomTileProviderManagerSheet(mapViewModel: MapViewModel) {
|
|||
var showEditDialog by remember { mutableStateOf(false) }
|
||||
val context = LocalContext.current
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
mapViewModel.errorFlow.collectLatest { errorMessage ->
|
||||
Toast.makeText(context, errorMessage, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) { mapViewModel.errorFlow.collectLatest { errorMessage -> context.showToast(errorMessage) } }
|
||||
|
||||
if (showEditDialog) {
|
||||
AddEditCustomTileProviderDialog(
|
||||
|
|
|
|||
|
|
@ -17,13 +17,15 @@
|
|||
|
||||
package org.meshtastic.feature.map.component
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.google.android.gms.maps.model.BitmapDescriptor
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.maps.android.compose.Marker
|
||||
import com.google.maps.android.compose.rememberUpdatedMarkerState
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.ui.util.showToast
|
||||
import org.meshtastic.feature.map.BaseMapViewModel
|
||||
import org.meshtastic.proto.MeshProtos
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
|
@ -39,6 +41,7 @@ fun WaypointMarkers(
|
|||
unicodeEmojiToBitmapProvider: (Int) -> BitmapDescriptor,
|
||||
onEditWaypointRequest: (MeshProtos.Waypoint) -> Unit,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
if (mapFilterState.showWaypoints) {
|
||||
displayableWaypoints.forEach { waypoint ->
|
||||
|
|
@ -60,7 +63,7 @@ fun WaypointMarkers(
|
|||
if (waypoint.lockedTo == 0 || waypoint.lockedTo == myNodeNum || !isConnected) {
|
||||
onEditWaypointRequest(waypoint)
|
||||
} else {
|
||||
Toast.makeText(context, context.getString(Res.string.locked), Toast.LENGTH_SHORT).show()
|
||||
scope.launch { context.showToast(Res.string.locked) }
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package org.meshtastic.feature.node.component
|
|||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
|
@ -37,21 +36,24 @@ import androidx.compose.material3.Icon
|
|||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalResources
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.net.toUri
|
||||
import com.mikepenz.markdown.m3.Markdown
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.database.entity.FirmwareRelease
|
||||
import org.meshtastic.core.ui.util.showToast
|
||||
import timber.log.Timber
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
@Composable
|
||||
fun FirmwareReleaseSheetContent(firmwareRelease: FirmwareRelease, modifier: Modifier = Modifier) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val resources = LocalResources.current
|
||||
|
||||
Column(
|
||||
modifier = modifier.verticalScroll(rememberScrollState()).padding(16.dp).fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
|
|
@ -66,12 +68,7 @@ fun FirmwareReleaseSheetContent(firmwareRelease: FirmwareRelease, modifier: Modi
|
|||
val intent = Intent(Intent.ACTION_VIEW, firmwareRelease.pageUrl.toUri())
|
||||
context.startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
resources.getString(Res.string.error_no_app_to_handle_link),
|
||||
Toast.LENGTH_LONG,
|
||||
)
|
||||
.show()
|
||||
scope.launch { context.showToast(Res.string.error_no_app_to_handle_link) }
|
||||
Timber.e(e)
|
||||
}
|
||||
},
|
||||
|
|
@ -87,12 +84,7 @@ fun FirmwareReleaseSheetContent(firmwareRelease: FirmwareRelease, modifier: Modi
|
|||
val intent = Intent(Intent.ACTION_VIEW, firmwareRelease.zipUrl.toUri())
|
||||
context.startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
resources.getString(Res.string.error_no_app_to_handle_link),
|
||||
Toast.LENGTH_LONG,
|
||||
)
|
||||
.show()
|
||||
scope.launch { context.showToast(Res.string.error_no_app_to_handle_link) }
|
||||
Timber.e(e)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ package org.meshtastic.feature.node.component
|
|||
import android.content.ActivityNotFoundException
|
||||
import android.content.ClipData
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.rounded.KeyboardArrowRight
|
||||
|
|
@ -41,6 +40,7 @@ import org.meshtastic.core.model.util.formatAgo
|
|||
import org.meshtastic.core.ui.component.BasicListItem
|
||||
import org.meshtastic.core.ui.component.icon
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.ui.util.showToast
|
||||
import timber.log.Timber
|
||||
import java.net.URLEncoder
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
|
@ -69,7 +69,7 @@ fun LinkedCoordinatesItem(node: Node) {
|
|||
if (intent.resolveActivity(context.packageManager) != null) {
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
Toast.makeText(context, "No application available to open this location!", Toast.LENGTH_LONG).show()
|
||||
coroutineScope.launch { context.showToast("No application available to open this location!") }
|
||||
}
|
||||
} catch (ex: ActivityNotFoundException) {
|
||||
Timber.d("Failed to open geo intent: $ex")
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import android.net.Uri
|
|||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.provider.Settings.ACTION_APP_LOCALE_SETTINGS
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity.RESULT_OK
|
||||
|
|
@ -50,6 +49,7 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
|
|
@ -62,6 +62,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.rememberMultiplePermissionsState
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.common.gpsDisabled
|
||||
import org.meshtastic.core.navigation.Route
|
||||
import org.meshtastic.core.ui.component.ListItem
|
||||
|
|
@ -70,6 +71,7 @@ import org.meshtastic.core.ui.component.MultipleChoiceAlertDialog
|
|||
import org.meshtastic.core.ui.component.SwitchListItem
|
||||
import org.meshtastic.core.ui.component.TitledCard
|
||||
import org.meshtastic.core.ui.theme.MODE_DYNAMIC
|
||||
import org.meshtastic.core.ui.util.showToast
|
||||
import org.meshtastic.feature.settings.navigation.getNavRouteFrom
|
||||
import org.meshtastic.feature.settings.radio.RadioConfigItemList
|
||||
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
|
||||
|
|
@ -230,8 +232,8 @@ fun SettingsScreen(
|
|||
onNavigate = onNavigate,
|
||||
)
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val resources = LocalResources.current
|
||||
|
||||
TitledCard(title = stringResource(Res.string.app_settings), modifier = Modifier.padding(top = 16.dp)) {
|
||||
if (state.analyticsAvailable) {
|
||||
|
|
@ -255,12 +257,7 @@ fun SettingsScreen(
|
|||
if (!isGpsDisabled) {
|
||||
settingsViewModel.meshService?.startProvideLocation()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
resources.getString(Res.string.location_disabled),
|
||||
Toast.LENGTH_LONG,
|
||||
)
|
||||
.show()
|
||||
context.showToast(Res.string.location_disabled)
|
||||
}
|
||||
} else {
|
||||
// Request permissions if not granted and user wants to provide location
|
||||
|
|
@ -393,8 +390,8 @@ private fun AppVersionButton(
|
|||
appVersionName: String,
|
||||
onUnlockExcludedModules: () -> Unit,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val resources = LocalResources.current
|
||||
var clickCount by remember { mutableIntStateOf(0) }
|
||||
|
||||
LaunchedEffect(clickCount) {
|
||||
|
|
@ -415,14 +412,13 @@ private fun AppVersionButton(
|
|||
when {
|
||||
clickCount == UNLOCKED_CLICK_COUNT && excludedModulesUnlocked -> {
|
||||
clickCount = 0
|
||||
Toast.makeText(context, resources.getString(Res.string.modules_already_unlocked), Toast.LENGTH_LONG)
|
||||
.show()
|
||||
scope.launch { context.showToast(Res.string.modules_already_unlocked) }
|
||||
}
|
||||
|
||||
clickCount == UNLOCK_CLICK_COUNT -> {
|
||||
clickCount = 0
|
||||
onUnlockExcludedModules()
|
||||
Toast.makeText(context, resources.getString(Res.string.modules_unlocked), Toast.LENGTH_LONG).show()
|
||||
scope.launch { context.showToast(Res.string.modules_unlocked) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package org.meshtastic.feature.settings.debugging
|
|||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
|
|
@ -86,6 +85,7 @@ import org.meshtastic.core.ui.component.MainAppBar
|
|||
import org.meshtastic.core.ui.component.SimpleAlertDialog
|
||||
import org.meshtastic.core.ui.theme.AnnotationColor
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
import org.meshtastic.core.ui.util.showToast
|
||||
import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
|
|
@ -396,23 +396,9 @@ private suspend fun exportAllLogsToUri(context: Context, targetUri: Uri, logs: L
|
|||
}
|
||||
} ?: run { throw IOException("Unable to open output stream for URI: $targetUri") }
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(Res.string.debug_export_success, logs.size),
|
||||
Toast.LENGTH_LONG,
|
||||
)
|
||||
.show()
|
||||
}
|
||||
withContext(Dispatchers.Main) { context.showToast(Res.string.debug_export_success, logs.size) }
|
||||
} catch (e: IOException) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(Res.string.debug_export_failed, e.message ?: ""),
|
||||
Toast.LENGTH_LONG,
|
||||
)
|
||||
.show()
|
||||
}
|
||||
withContext(Dispatchers.Main) { context.showToast(Res.string.debug_export_failed, e.message ?: "") }
|
||||
Timber.w(e, "Error:IOException ")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import androidx.compose.material3.HorizontalDivider
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
|
|
@ -50,7 +49,6 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
|
|||
val detectionSensorConfig = state.moduleConfig.detectionSensor
|
||||
val formState = rememberConfigState(initialValue = detectionSensorConfig)
|
||||
val focusManager = LocalFocusManager.current
|
||||
val context = LocalContext.current
|
||||
|
||||
RadioConfigScreenList(
|
||||
title = stringResource(Res.string.detection_sensor),
|
||||
|
|
@ -81,7 +79,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
|
|||
title = stringResource(Res.string.minimum_broadcast_seconds),
|
||||
selectedItem = formState.value.minimumBroadcastSecs.toLong(),
|
||||
enabled = state.connected,
|
||||
items = minimumBroadcastIntervals.map { it.value to it.toDisplayString(context = context) },
|
||||
items = minimumBroadcastIntervals.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = { formState.value = formState.value.copy { minimumBroadcastSecs = it.toInt() } },
|
||||
)
|
||||
|
||||
|
|
@ -90,7 +88,7 @@ fun DetectionSensorConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(
|
|||
title = stringResource(Res.string.state_broadcast_seconds),
|
||||
selectedItem = formState.value.stateBroadcastSecs.toLong(),
|
||||
enabled = state.connected,
|
||||
items = stateBroadcastIntervals.map { it.value to it.toDisplayString(context = context) },
|
||||
items = stateBroadcastIntervals.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = { formState.value = formState.value.copy { stateBroadcastSecs = it.toInt() } },
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
|
|||
}
|
||||
}
|
||||
val focusManager = LocalFocusManager.current
|
||||
val context = LocalContext.current
|
||||
RadioConfigScreenList(
|
||||
title = stringResource(Res.string.device),
|
||||
onBack = onBack,
|
||||
|
|
@ -170,7 +169,7 @@ fun DeviceConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack
|
|||
title = stringResource(Res.string.nodeinfo_broadcast_interval),
|
||||
selectedItem = formState.value.nodeInfoBroadcastSecs.toLong(),
|
||||
enabled = state.connected,
|
||||
items = nodeInfoBroadcastIntervals.map { it.value to it.toDisplayString(context = context) },
|
||||
items = nodeInfoBroadcastIntervals.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = { formState.value = formState.value.copy { nodeInfoBroadcastSecs = it.toInt() } },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import androidx.compose.material3.HorizontalDivider
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
|
|
@ -42,7 +41,6 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
|
|||
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
|
||||
val displayConfig = state.radioConfig.display
|
||||
val formState = rememberConfigState(initialValue = displayConfig)
|
||||
val context = LocalContext.current
|
||||
|
||||
RadioConfigScreenList(
|
||||
title = stringResource(Res.string.display),
|
||||
|
|
@ -106,7 +104,7 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
|
|||
title = stringResource(Res.string.screen_on_for),
|
||||
summary = stringResource(Res.string.config_display_screen_on_secs_summary),
|
||||
enabled = state.connected,
|
||||
items = screenOnIntervals.map { it to it.toDisplayString(context = context) },
|
||||
items = screenOnIntervals.map { it to it.toDisplayString() },
|
||||
selectedItem =
|
||||
screenOnIntervals.find { it.value == formState.value.screenOnSecs.toLong() }
|
||||
?: screenOnIntervals.first(),
|
||||
|
|
@ -117,7 +115,7 @@ fun DisplayConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBac
|
|||
title = stringResource(Res.string.carousel_interval),
|
||||
summary = stringResource(Res.string.config_display_auto_screen_carousel_secs_summary),
|
||||
enabled = state.connected,
|
||||
items = carouselIntervals.map { it to it.toDisplayString(context = context) },
|
||||
items = carouselIntervals.map { it to it.toDisplayString() },
|
||||
selectedItem =
|
||||
carouselIntervals.find { it.value == formState.value.autoScreenCarouselSecs.toLong() }
|
||||
?: carouselIntervals.first(),
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
|
|
@ -54,7 +53,6 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
|
|||
val formState = rememberConfigState(initialValue = extNotificationConfig)
|
||||
var ringtoneInput by rememberSaveable(ringtone) { mutableStateOf(ringtone) }
|
||||
val focusManager = LocalFocusManager.current
|
||||
val context = LocalContext.current
|
||||
|
||||
RadioConfigScreenList(
|
||||
title = stringResource(Res.string.external_notification),
|
||||
|
|
@ -191,7 +189,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
|
|||
val outputItems = remember { IntervalConfiguration.OUTPUT.allowedIntervals }
|
||||
DropDownPreference(
|
||||
title = stringResource(Res.string.output_duration_milliseconds),
|
||||
items = outputItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = outputItems.map { it.value to it.toDisplayString() },
|
||||
selectedItem = formState.value.outputMs,
|
||||
enabled = state.connected,
|
||||
onItemSelected = { formState.value = formState.value.copy { outputMs = it.toInt() } },
|
||||
|
|
@ -200,7 +198,7 @@ fun ExternalNotificationConfigScreen(viewModel: RadioConfigViewModel = hiltViewM
|
|||
val nagItems = remember { IntervalConfiguration.NAG_TIMEOUT.allowedIntervals }
|
||||
DropDownPreference(
|
||||
title = stringResource(Res.string.nag_timeout_seconds),
|
||||
items = nagItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = nagItems.map { it.value to it.toDisplayString() },
|
||||
selectedItem = formState.value.nagTimeout,
|
||||
enabled = state.connected,
|
||||
onItemSelected = { formState.value = formState.value.copy { nagTimeout = it.toInt() } },
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -65,7 +64,6 @@ fun MapReportingPreference(
|
|||
onPublishIntervalSecsChanged: (Int) -> Unit = {},
|
||||
enabled: Boolean,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
Column {
|
||||
var showMapReportingWarning by rememberSaveable { mutableStateOf(mapReportingEnabled) }
|
||||
LaunchedEffect(mapReportingEnabled) { showMapReportingWarning = mapReportingEnabled }
|
||||
|
|
@ -126,7 +124,7 @@ fun MapReportingPreference(
|
|||
DropDownPreference(
|
||||
modifier = Modifier.padding(bottom = 16.dp),
|
||||
title = stringResource(Res.string.map_reporting_interval_seconds),
|
||||
items = publishItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = publishItems.map { it.value to it.toDisplayString() },
|
||||
selectedItem = publishIntervalSecs,
|
||||
enabled = enabled,
|
||||
onItemSelected = { onPublishIntervalSecsChanged(it.toInt()) },
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import androidx.compose.material3.HorizontalDivider
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
|
|
@ -45,7 +44,6 @@ fun PaxcounterConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), on
|
|||
val paxcounterConfig = state.moduleConfig.paxcounter
|
||||
val formState = rememberConfigState(initialValue = paxcounterConfig)
|
||||
val focusManager = LocalFocusManager.current
|
||||
val context = LocalContext.current
|
||||
|
||||
RadioConfigScreenList(
|
||||
title = stringResource(Res.string.paxcounter),
|
||||
|
|
@ -74,7 +72,7 @@ fun PaxcounterConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), on
|
|||
title = stringResource(Res.string.update_interval_seconds),
|
||||
selectedItem = formState.value.paxcounterUpdateInterval.toLong(),
|
||||
enabled = state.connected,
|
||||
items = items.map { it.value to it.toDisplayString(context = context) },
|
||||
items = items.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = {
|
||||
formState.value = formState.value.copy { paxcounterUpdateInterval = it.toInt() }
|
||||
},
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.core.location.LocationCompat
|
||||
|
|
@ -119,7 +118,6 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
|
|||
}
|
||||
}
|
||||
val focusManager = LocalFocusManager.current
|
||||
val context = LocalContext.current
|
||||
RadioConfigScreenList(
|
||||
title = stringResource(Res.string.position),
|
||||
onBack = onBack,
|
||||
|
|
@ -149,7 +147,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
|
|||
title = stringResource(Res.string.broadcast_interval),
|
||||
summary = stringResource(Res.string.config_position_broadcast_secs_summary),
|
||||
enabled = state.connected,
|
||||
items = items.map { it to it.toDisplayString(context = context) },
|
||||
items = items.map { it to it.toDisplayString() },
|
||||
selectedItem =
|
||||
FixedUpdateIntervals.fromValue(formState.value.positionBroadcastSecs.toLong()) ?: items.first(),
|
||||
onItemSelected = {
|
||||
|
|
@ -172,7 +170,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
|
|||
summary =
|
||||
stringResource(Res.string.config_position_broadcast_smart_minimum_interval_secs_summary),
|
||||
enabled = state.connected,
|
||||
items = smartItems.map { it to it.toDisplayString(context = context) },
|
||||
items = smartItems.map { it to it.toDisplayString() },
|
||||
selectedItem =
|
||||
FixedUpdateIntervals.fromValue(formState.value.broadcastSmartMinimumIntervalSecs.toLong())
|
||||
?: smartItems.first(),
|
||||
|
|
@ -262,7 +260,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBa
|
|||
title = stringResource(Res.string.update_interval),
|
||||
summary = stringResource(Res.string.config_position_gps_update_interval_summary),
|
||||
enabled = state.connected,
|
||||
items = items.map { it to it.toDisplayString(context = context) },
|
||||
items = items.map { it to it.toDisplayString() },
|
||||
selectedItem =
|
||||
FixedUpdateIntervals.fromValue(formState.value.gpsUpdateInterval.toLong()) ?: items.first(),
|
||||
onItemSelected = {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import androidx.compose.material3.HorizontalDivider
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
|
|
@ -45,7 +44,6 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
|
|||
val powerConfig = state.radioConfig.power
|
||||
val formState = rememberConfigState(initialValue = powerConfig)
|
||||
val focusManager = LocalFocusManager.current
|
||||
val context = LocalContext.current
|
||||
|
||||
RadioConfigScreenList(
|
||||
title = stringResource(Res.string.power),
|
||||
|
|
@ -75,7 +73,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
|
|||
title = stringResource(Res.string.shutdown_on_power_loss),
|
||||
selectedItem = formState.value.onBatteryShutdownAfterSecs.toLong(),
|
||||
enabled = state.connected,
|
||||
items = items.map { it.value to it.toDisplayString(context = context) },
|
||||
items = items.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = {
|
||||
formState.value = formState.value.copy { onBatteryShutdownAfterSecs = it.toInt() }
|
||||
},
|
||||
|
|
@ -106,7 +104,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
|
|||
title = stringResource(Res.string.wait_for_bluetooth_duration_seconds),
|
||||
selectedItem = formState.value.waitBluetoothSecs.toLong(),
|
||||
enabled = state.connected,
|
||||
items = waitBluetoothItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = waitBluetoothItems.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = { formState.value = formState.value.copy { waitBluetoothSecs = it.toInt() } },
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
|
@ -116,7 +114,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
|
|||
selectedItem = formState.value.sdsSecs.toLong(),
|
||||
onItemSelected = { formState.value = formState.value.copy { sdsSecs = it.toInt() } },
|
||||
enabled = state.connected,
|
||||
items = sdsSecsItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = sdsSecsItems.map { it.value to it.toDisplayString() },
|
||||
)
|
||||
HorizontalDivider()
|
||||
val minWakeItems = remember { IntervalConfiguration.NAG_TIMEOUT.allowedIntervals }
|
||||
|
|
@ -124,7 +122,7 @@ fun PowerConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onBack:
|
|||
title = stringResource(Res.string.minimum_wake_time_seconds),
|
||||
selectedItem = formState.value.minWakeSecs.toLong(),
|
||||
enabled = state.connected,
|
||||
items = minWakeItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = minWakeItems.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = { formState.value = formState.value.copy { minWakeSecs = it.toInt() } },
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import androidx.compose.material3.HorizontalDivider
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
|
|
@ -41,7 +40,6 @@ fun RangeTestConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
|
|||
val state by viewModel.radioConfigState.collectAsStateWithLifecycle()
|
||||
val rangeTestConfig = state.moduleConfig.rangeTest
|
||||
val formState = rememberConfigState(initialValue = rangeTestConfig)
|
||||
val context = LocalContext.current
|
||||
|
||||
RadioConfigScreenList(
|
||||
title = stringResource(Res.string.range_test),
|
||||
|
|
@ -70,7 +68,7 @@ fun RangeTestConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
|
|||
title = stringResource(Res.string.sender_message_interval_seconds),
|
||||
selectedItem = formState.value.sender.toLong(),
|
||||
enabled = state.connected,
|
||||
items = rangeItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = rangeItems.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = { formState.value = formState.value.copy { sender = it.toInt() } },
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import androidx.compose.material3.HorizontalDivider
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
|
|
@ -46,7 +45,6 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
|
|||
val formState = rememberConfigState(initialValue = telemetryConfig)
|
||||
|
||||
val firmwareVersion = state.metadata?.firmwareVersion ?: "1"
|
||||
val context = LocalContext.current
|
||||
|
||||
RadioConfigScreenList(
|
||||
title = stringResource(Res.string.telemetry),
|
||||
|
|
@ -78,7 +76,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
|
|||
title = stringResource(Res.string.device_metrics_update_interval_seconds),
|
||||
selectedItem = formState.value.deviceUpdateInterval.toLong(),
|
||||
enabled = state.connected,
|
||||
items = items.map { it.value to it.toDisplayString(context = context) },
|
||||
items = items.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = { formState.value = formState.value.copy { deviceUpdateInterval = it.toInt() } },
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
|
@ -95,7 +93,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
|
|||
title = stringResource(Res.string.environment_metrics_update_interval_seconds),
|
||||
selectedItem = formState.value.environmentUpdateInterval.toLong(),
|
||||
enabled = state.connected,
|
||||
items = envItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = envItems.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = {
|
||||
formState.value = formState.value.copy { environmentUpdateInterval = it.toInt() }
|
||||
},
|
||||
|
|
@ -130,7 +128,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
|
|||
title = stringResource(Res.string.air_quality_metrics_update_interval_seconds),
|
||||
selectedItem = formState.value.airQualityInterval.toLong(),
|
||||
enabled = state.connected,
|
||||
items = airItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = airItems.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = { formState.value = formState.value.copy { airQualityInterval = it.toInt() } },
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
|
@ -147,7 +145,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel(), onB
|
|||
title = stringResource(Res.string.power_metrics_update_interval_seconds),
|
||||
selectedItem = formState.value.powerUpdateInterval.toLong(),
|
||||
enabled = state.connected,
|
||||
items = powerItems.map { it.value to it.toDisplayString(context = context) },
|
||||
items = powerItems.map { it.value to it.toDisplayString() },
|
||||
onItemSelected = { formState.value = formState.value.copy { powerUpdateInterval = it.toInt() } },
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
|
|
|||
|
|
@ -17,11 +17,13 @@
|
|||
|
||||
package org.meshtastic.feature.settings.util
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import org.meshtastic.core.strings.R as Res
|
||||
|
||||
fun FixedUpdateIntervals.toDisplayString(context: Context): String = if (this == FixedUpdateIntervals.UNSET) {
|
||||
context.getString(Res.string.unset)
|
||||
@Composable
|
||||
fun FixedUpdateIntervals.toDisplayString(): String = if (this == FixedUpdateIntervals.UNSET) {
|
||||
stringResource(Res.string.unset)
|
||||
} else {
|
||||
name.split('_').joinToString(" ") { word -> word.lowercase().replaceFirstChar { it.uppercase() } }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue