diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt
index 69f9285d2..ea3ccf816 100644
--- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt
+++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt
@@ -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")
diff --git a/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt b/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt
index 81d82b89a..3759f253e 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt
@@ -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) }
}
},
)
diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ContextExtensions.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ContextExtensions.kt
new file mode 100644
index 000000000..55318db91
--- /dev/null
+++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ContextExtensions.kt
@@ -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 .
+ */
+
+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()
+}
diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt
index a864d7cc5..ea9b60c4c 100644
--- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt
+++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt
@@ -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(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()
}
}
diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomTileProviderManagerSheet.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomTileProviderManagerSheet.kt
index ab556923f..da2850657 100644
--- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomTileProviderManagerSheet.kt
+++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomTileProviderManagerSheet.kt
@@ -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(
diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/WaypointMarkers.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/WaypointMarkers.kt
index abf807e80..92d4fcbe6 100644
--- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/WaypointMarkers.kt
+++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/WaypointMarkers.kt
@@ -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) }
}
},
)
diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/FirmwareReleaseSheetContent.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/FirmwareReleaseSheetContent.kt
index 48f05c8cd..157ea2d34 100644
--- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/FirmwareReleaseSheetContent.kt
+++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/FirmwareReleaseSheetContent.kt
@@ -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)
}
},
diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LinkedCoordinatesItem.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LinkedCoordinatesItem.kt
index 360f6d635..bb765dfb5 100644
--- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LinkedCoordinatesItem.kt
+++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LinkedCoordinatesItem.kt
@@ -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")
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt
index e45cf8421..891dcd778 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt
@@ -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) }
}
}
}
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt
index 82b9a648a..32fed894f 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt
@@ -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 ")
}
}
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt
index c5e809f04..99f64b605 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt
@@ -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()
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt
index c6311aebf..0348473bb 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt
@@ -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() } },
)
}
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt
index c522224d3..8eb7679d6 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt
@@ -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(),
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt
index 0ed4921d8..8fc985e28 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt
@@ -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() } },
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt
index fb8f8de3b..bc1d41d28 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt
@@ -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()) },
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt
index edfb223d4..ed66d2cbc 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt
@@ -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() }
},
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt
index 9c417b686..96970194d 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt
@@ -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 = {
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt
index 959071f2d..b3e82f555 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt
@@ -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()
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt
index 90f5b88b6..2723c76ca 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt
@@ -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()
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt
index e82853c28..6bc8e2e59 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt
@@ -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()
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/Formatting.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/Formatting.kt
index 5d9273095..34f7c804c 100644
--- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/Formatting.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/Formatting.kt
@@ -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() } }
}