New core modules for :model, :navigation, :network, :prefs (#3147)

This commit is contained in:
Phil Oliver 2025-09-19 08:16:36 -04:00 committed by GitHub
parent bb707526f9
commit 0d2c1f1516
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
49 changed files with 228 additions and 212 deletions

View file

@ -43,7 +43,6 @@ import com.geeksville.mesh.android.GeeksvilleApplication
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.android.prefs.UiPrefs
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.navigation.DEEP_LINK_BASE_URI
import com.geeksville.mesh.ui.MainScreen
import com.geeksville.mesh.ui.common.theme.AppTheme
import com.geeksville.mesh.ui.common.theme.MODE_DYNAMIC
@ -51,6 +50,7 @@ import com.geeksville.mesh.ui.intro.AppIntroductionScreen
import com.geeksville.mesh.ui.sharing.toSharedContact
import com.geeksville.mesh.util.LanguageUtils
import dagger.hilt.android.AndroidEntryPoint
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
import javax.inject.Inject
@AndroidEntryPoint

View file

@ -21,8 +21,8 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.geeksville.mesh.model.DeviceHardware
import com.geeksville.mesh.network.model.NetworkDeviceHardware
import kotlinx.serialization.Serializable
import org.meshtastic.core.network.model.NetworkDeviceHardware
@Serializable
@Entity(tableName = "device_hardware")

View file

@ -21,27 +21,19 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.geeksville.mesh.model.DeviceVersion
import com.geeksville.mesh.network.model.NetworkFirmwareRelease
import kotlinx.serialization.Serializable
import org.meshtastic.core.network.model.NetworkFirmwareRelease
@Serializable
@Entity(tableName = "firmware_release")
data class FirmwareReleaseEntity(
@PrimaryKey
@ColumnInfo(name = "id")
val id: String = "",
@ColumnInfo(name = "page_url")
val pageUrl: String = "",
@ColumnInfo(name = "release_notes")
val releaseNotes: String = "",
@ColumnInfo(name = "title")
val title: String = "",
@ColumnInfo(name = "zip_url")
val zipUrl: String = "",
@ColumnInfo(name = "last_updated")
val lastUpdated: Long = System.currentTimeMillis(),
@ColumnInfo(name = "release_type")
val releaseType: FirmwareReleaseType = FirmwareReleaseType.STABLE,
@PrimaryKey @ColumnInfo(name = "id") val id: String = "",
@ColumnInfo(name = "page_url") val pageUrl: String = "",
@ColumnInfo(name = "release_notes") val releaseNotes: String = "",
@ColumnInfo(name = "title") val title: String = "",
@ColumnInfo(name = "zip_url") val zipUrl: String = "",
@ColumnInfo(name = "last_updated") val lastUpdated: Long = System.currentTimeMillis(),
@ColumnInfo(name = "release_type") val releaseType: FirmwareReleaseType = FirmwareReleaseType.STABLE,
)
fun NetworkFirmwareRelease.asEntity(releaseType: FirmwareReleaseType) = FirmwareReleaseEntity(
@ -74,19 +66,11 @@ data class FirmwareRelease(
val releaseType: FirmwareReleaseType = FirmwareReleaseType.STABLE,
)
fun FirmwareReleaseEntity.asDeviceVersion(): DeviceVersion {
return DeviceVersion(
id.substringBeforeLast(".").replace("v", "")
)
}
fun FirmwareReleaseEntity.asDeviceVersion(): DeviceVersion = DeviceVersion(id.substringBeforeLast(".").replace("v", ""))
fun FirmwareRelease.asDeviceVersion(): DeviceVersion {
return DeviceVersion(
id.substringBeforeLast(".").replace("v", "")
)
}
fun FirmwareRelease.asDeviceVersion(): DeviceVersion = DeviceVersion(id.substringBeforeLast(".").replace("v", ""))
enum class FirmwareReleaseType {
STABLE,
ALPHA
ALPHA,
}

View file

@ -42,7 +42,6 @@ import com.geeksville.mesh.database.MeshLogRepository
import com.geeksville.mesh.database.entity.FirmwareRelease
import com.geeksville.mesh.database.entity.MeshLog
import com.geeksville.mesh.model.map.CustomTileSource
import com.geeksville.mesh.navigation.NodesRoutes
import com.geeksville.mesh.repository.api.DeviceHardwareRepository
import com.geeksville.mesh.repository.api.FirmwareReleaseRepository
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
@ -63,6 +62,7 @@ import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.meshtastic.core.navigation.NodesRoutes
import java.io.BufferedWriter
import java.io.FileNotFoundException
import java.io.FileWriter

View file

@ -28,6 +28,8 @@ import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.ui.settings.radio.components.ChannelConfigScreen
import com.geeksville.mesh.ui.settings.radio.components.LoRaConfigScreen
import com.geeksville.mesh.ui.sharing.ChannelScreen
import org.meshtastic.core.navigation.ChannelsRoutes
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
/** Navigation graph for for the top level ChannelScreen - [ChannelsRoutes.Channels]. */
fun NavGraphBuilder.channelsGraph(navController: NavHostController, uiViewModel: UIViewModel) {

View file

@ -26,6 +26,10 @@ import androidx.navigation.navDeepLink
import androidx.navigation.navigation
import com.geeksville.mesh.ui.connections.ConnectionsScreen
import com.geeksville.mesh.ui.settings.radio.components.LoRaConfigScreen
import org.meshtastic.core.navigation.ConnectionsRoutes
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
import org.meshtastic.core.navigation.NodesRoutes
import org.meshtastic.core.navigation.SettingsRoutes
/** Navigation graph for for the top level ConnectionsScreen - [ConnectionsRoutes.Connections]. */
fun NavGraphBuilder.connectionsGraph(navController: NavHostController) {

View file

@ -28,6 +28,10 @@ import com.geeksville.mesh.ui.contact.ContactsScreen
import com.geeksville.mesh.ui.message.MessageScreen
import com.geeksville.mesh.ui.message.QuickChatScreen
import com.geeksville.mesh.ui.sharing.ShareScreen
import org.meshtastic.core.navigation.ChannelsRoutes
import org.meshtastic.core.navigation.ContactsRoutes
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
import org.meshtastic.core.navigation.NodesRoutes
@Suppress("LongMethod")
fun NavGraphBuilder.contactsGraph(navController: NavHostController, uiViewModel: UIViewModel) {

View file

@ -23,6 +23,9 @@ import androidx.navigation.compose.composable
import androidx.navigation.navDeepLink
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.ui.map.MapScreen
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
import org.meshtastic.core.navigation.MapRoutes
import org.meshtastic.core.navigation.NodesRoutes
fun NavGraphBuilder.mapGraph(navController: NavHostController, uiViewModel: UIViewModel) {
composable<MapRoutes.Map>(deepLinks = listOf(navDeepLink<MapRoutes.Map>(basePath = "$DEEP_LINK_BASE_URI/map"))) {

View file

@ -53,6 +53,11 @@ import com.geeksville.mesh.ui.metrics.TracerouteLogScreen
import com.geeksville.mesh.ui.node.NodeDetailScreen
import com.geeksville.mesh.ui.node.NodeMapScreen
import com.geeksville.mesh.ui.node.NodeScreen
import org.meshtastic.core.navigation.ContactsRoutes
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
import org.meshtastic.core.navigation.NodeDetailRoutes
import org.meshtastic.core.navigation.NodesRoutes
import org.meshtastic.core.navigation.Route
fun NavGraphBuilder.nodesGraph(navController: NavHostController, uiViewModel: UIViewModel) {
navigation<NodesRoutes.NodesGraph>(startDestination = NodesRoutes.Nodes) {

View file

@ -84,6 +84,10 @@ import com.geeksville.mesh.ui.settings.radio.components.SerialConfigScreen
import com.geeksville.mesh.ui.settings.radio.components.StoreForwardConfigScreen
import com.geeksville.mesh.ui.settings.radio.components.TelemetryConfigScreen
import com.geeksville.mesh.ui.settings.radio.components.UserConfigScreen
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
import org.meshtastic.core.navigation.NodesRoutes
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
fun getNavRouteFrom(routeName: String): Route? =
ConfigRoute.entries.find { it.name == routeName }?.route ?: ModuleRoute.entries.find { it.name == routeName }?.route

View file

@ -18,15 +18,13 @@
package com.geeksville.mesh.repository.api
import android.app.Application
import com.geeksville.mesh.network.model.NetworkDeviceHardware
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import org.meshtastic.core.network.model.NetworkDeviceHardware
import javax.inject.Inject
class DeviceHardwareJsonDataSource @Inject constructor(
private val application: Application,
) {
class DeviceHardwareJsonDataSource @Inject constructor(private val application: Application) {
@OptIn(ExperimentalSerializationApi::class)
fun loadDeviceHardwareFromJsonAsset(): List<NetworkDeviceHardware> {
val inputStream = application.assets.open("device_hardware.json")

View file

@ -20,30 +20,24 @@ package com.geeksville.mesh.repository.api
import com.geeksville.mesh.database.dao.DeviceHardwareDao
import com.geeksville.mesh.database.entity.DeviceHardwareEntity
import com.geeksville.mesh.database.entity.asEntity
import com.geeksville.mesh.network.model.NetworkDeviceHardware
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.meshtastic.core.network.model.NetworkDeviceHardware
import javax.inject.Inject
class DeviceHardwareLocalDataSource @Inject constructor(
private val deviceHardwareDaoLazy: dagger.Lazy<DeviceHardwareDao>
class DeviceHardwareLocalDataSource
@Inject
constructor(
private val deviceHardwareDaoLazy: dagger.Lazy<DeviceHardwareDao>,
) {
private val deviceHardwareDao by lazy {
deviceHardwareDaoLazy.get()
private val deviceHardwareDao by lazy { deviceHardwareDaoLazy.get() }
suspend fun insertAllDeviceHardware(deviceHardware: List<NetworkDeviceHardware>) = withContext(Dispatchers.IO) {
deviceHardware.forEach { deviceHardware -> deviceHardwareDao.insert(deviceHardware.asEntity()) }
}
suspend fun insertAllDeviceHardware(deviceHardware: List<NetworkDeviceHardware>) =
withContext(Dispatchers.IO) {
deviceHardware.forEach { deviceHardware ->
deviceHardwareDao.insert(deviceHardware.asEntity())
}
}
suspend fun deleteAllDeviceHardware() = withContext(Dispatchers.IO) { deviceHardwareDao.deleteAll() }
suspend fun deleteAllDeviceHardware() = withContext(Dispatchers.IO) {
deviceHardwareDao.deleteAll()
}
suspend fun getByHwModel(hwModel: Int): DeviceHardwareEntity? = withContext(Dispatchers.IO) {
deviceHardwareDao.getByHwModel(hwModel)
}
suspend fun getByHwModel(hwModel: Int): DeviceHardwareEntity? =
withContext(Dispatchers.IO) { deviceHardwareDao.getByHwModel(hwModel) }
}

View file

@ -22,9 +22,9 @@ import com.geeksville.mesh.android.BuildUtils.warn
import com.geeksville.mesh.database.entity.DeviceHardwareEntity
import com.geeksville.mesh.database.entity.asExternalModel
import com.geeksville.mesh.model.DeviceHardware
import com.geeksville.mesh.network.DeviceHardwareRemoteDataSource
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.meshtastic.core.network.DeviceHardwareRemoteDataSource
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton

View file

@ -18,21 +18,17 @@
package com.geeksville.mesh.repository.api
import android.app.Application
import com.geeksville.mesh.network.model.NetworkFirmwareReleases
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import org.meshtastic.core.network.model.NetworkFirmwareReleases
import javax.inject.Inject
class FirmwareReleaseJsonDataSource @Inject constructor(
private val application: Application,
) {
class FirmwareReleaseJsonDataSource @Inject constructor(private val application: Application) {
@OptIn(ExperimentalSerializationApi::class)
fun loadFirmwareReleaseFromJsonAsset(): NetworkFirmwareReleases {
val inputStream = application.assets.open("firmware_releases.json")
val result = inputStream.use {
Json.decodeFromStream<NetworkFirmwareReleases>(inputStream)
}
val result = inputStream.use { Json.decodeFromStream<NetworkFirmwareReleases>(inputStream) }
return result
}
}

View file

@ -22,44 +22,36 @@ import com.geeksville.mesh.database.entity.FirmwareReleaseEntity
import com.geeksville.mesh.database.entity.FirmwareReleaseType
import com.geeksville.mesh.database.entity.asDeviceVersion
import com.geeksville.mesh.database.entity.asEntity
import com.geeksville.mesh.network.model.NetworkFirmwareRelease
import dagger.Lazy
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.meshtastic.core.network.model.NetworkFirmwareRelease
import javax.inject.Inject
class FirmwareReleaseLocalDataSource @Inject constructor(
private val firmwareReleaseDaoLazy: Lazy<FirmwareReleaseDao>
) {
private val firmwareReleaseDao by lazy {
firmwareReleaseDaoLazy.get()
}
class FirmwareReleaseLocalDataSource @Inject constructor(private val firmwareReleaseDaoLazy: Lazy<FirmwareReleaseDao>) {
private val firmwareReleaseDao by lazy { firmwareReleaseDaoLazy.get() }
suspend fun insertFirmwareReleases(
firmwareReleases: List<NetworkFirmwareRelease>,
releaseType: FirmwareReleaseType
) =
withContext(Dispatchers.IO) {
if (firmwareReleases.isNotEmpty()) {
firmwareReleaseDao.deleteAll()
firmwareReleases.forEach { firmwareRelease ->
firmwareReleaseDao.insert(firmwareRelease.asEntity(releaseType))
}
releaseType: FirmwareReleaseType,
) = withContext(Dispatchers.IO) {
if (firmwareReleases.isNotEmpty()) {
firmwareReleaseDao.deleteAll()
firmwareReleases.forEach { firmwareRelease ->
firmwareReleaseDao.insert(firmwareRelease.asEntity(releaseType))
}
}
suspend fun deleteAllFirmwareReleases() = withContext(Dispatchers.IO) {
firmwareReleaseDao.deleteAll()
}
suspend fun deleteAllFirmwareReleases() = withContext(Dispatchers.IO) { firmwareReleaseDao.deleteAll() }
suspend fun getLatestRelease(releaseType: FirmwareReleaseType): FirmwareReleaseEntity? =
withContext(Dispatchers.IO) {
val releases = firmwareReleaseDao.getReleasesByType(releaseType)
if (releases.isEmpty()) {
return@withContext null
} else {
val latestRelease =
releases.maxBy { it.asDeviceVersion() }
val latestRelease = releases.maxBy { it.asDeviceVersion() }
return@withContext latestRelease
}
}

View file

@ -23,9 +23,9 @@ import com.geeksville.mesh.database.entity.FirmwareRelease
import com.geeksville.mesh.database.entity.FirmwareReleaseEntity
import com.geeksville.mesh.database.entity.FirmwareReleaseType
import com.geeksville.mesh.database.entity.asExternalModel
import com.geeksville.mesh.network.FirmwareReleaseRemoteDataSource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import org.meshtastic.core.network.FirmwareReleaseRemoteDataSource
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton

View file

@ -39,9 +39,9 @@ import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.R
import com.geeksville.mesh.TelemetryProtos.LocalStats
import com.geeksville.mesh.database.entity.NodeEntity
import com.geeksville.mesh.navigation.DEEP_LINK_BASE_URI
import com.geeksville.mesh.service.ReplyReceiver.Companion.KEY_TEXT_REPLY
import com.geeksville.mesh.util.formatUptime
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
/**
* Manages the creation and display of all app notifications.

View file

@ -84,13 +84,6 @@ import com.geeksville.mesh.model.BTScanModel
import com.geeksville.mesh.model.DeviceVersion
import com.geeksville.mesh.model.Node
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.navigation.ConnectionsRoutes
import com.geeksville.mesh.navigation.ContactsRoutes
import com.geeksville.mesh.navigation.MapRoutes
import com.geeksville.mesh.navigation.NodeDetailRoutes
import com.geeksville.mesh.navigation.NodesRoutes
import com.geeksville.mesh.navigation.Route
import com.geeksville.mesh.navigation.SettingsRoutes
import com.geeksville.mesh.navigation.channelsGraph
import com.geeksville.mesh.navigation.connectionsGraph
import com.geeksville.mesh.navigation.contactsGraph
@ -120,6 +113,13 @@ import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.meshtastic.core.navigation.ConnectionsRoutes
import org.meshtastic.core.navigation.ContactsRoutes
import org.meshtastic.core.navigation.MapRoutes
import org.meshtastic.core.navigation.NodeDetailRoutes
import org.meshtastic.core.navigation.NodesRoutes
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import kotlin.reflect.KClass
enum class TopLevelDestination(@StringRes val label: Int, val icon: ImageVector, val route: Route) {

View file

@ -49,9 +49,6 @@ import androidx.navigation.compose.currentBackStackEntryAsState
import com.geeksville.mesh.R
import com.geeksville.mesh.model.Node
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.navigation.ContactsRoutes
import com.geeksville.mesh.navigation.NodesRoutes
import com.geeksville.mesh.navigation.SettingsRoutes
import com.geeksville.mesh.navigation.isConfigRoute
import com.geeksville.mesh.navigation.isNodeDetailRoute
import com.geeksville.mesh.ui.TopLevelDestination.Companion.isTopLevel
@ -59,6 +56,9 @@ import com.geeksville.mesh.ui.common.theme.AppTheme
import com.geeksville.mesh.ui.debug.DebugMenuActions
import com.geeksville.mesh.ui.node.components.NodeChip
import com.geeksville.mesh.ui.node.components.NodeMenuAction
import org.meshtastic.core.navigation.ContactsRoutes
import org.meshtastic.core.navigation.NodesRoutes
import org.meshtastic.core.navigation.SettingsRoutes
@Suppress("CyclomaticComplexMethod")
@Composable

View file

@ -65,8 +65,6 @@ import com.geeksville.mesh.model.BTScanModel
import com.geeksville.mesh.model.DeviceListEntry
import com.geeksville.mesh.model.Node
import com.geeksville.mesh.navigation.ConfigRoute
import com.geeksville.mesh.navigation.Route
import com.geeksville.mesh.navigation.SettingsRoutes
import com.geeksville.mesh.navigation.getNavRouteFrom
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.ui.common.components.MainAppBar
@ -83,6 +81,8 @@ import com.geeksville.mesh.ui.settings.radio.components.PacketResponseStateDialo
import com.geeksville.mesh.ui.sharing.SharedContactDialog
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import kotlinx.coroutines.delay
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
fun String?.isIPAddress(): Boolean = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
@Suppress("DEPRECATION")

View file

@ -46,7 +46,6 @@ import androidx.compose.material.icons.filled.BlurOn
import androidx.compose.material.icons.filled.Bolt
import androidx.compose.material.icons.filled.ChargingStation
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Download
import androidx.compose.material.icons.filled.ForkLeft
import androidx.compose.material.icons.filled.Height
@ -135,9 +134,6 @@ import com.geeksville.mesh.model.MetricsViewModel
import com.geeksville.mesh.model.Node
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.model.isUnmessageableRole
import com.geeksville.mesh.navigation.NodeDetailRoutes
import com.geeksville.mesh.navigation.Route
import com.geeksville.mesh.navigation.SettingsRoutes
import com.geeksville.mesh.service.ServiceAction
import com.geeksville.mesh.ui.common.components.MainAppBar
import com.geeksville.mesh.ui.common.components.TitledCard
@ -163,6 +159,9 @@ import com.geeksville.mesh.util.toDistanceString
import com.geeksville.mesh.util.toSmallDistanceString
import com.geeksville.mesh.util.toSpeedString
import com.mikepenz.markdown.m3.Markdown
import org.meshtastic.core.navigation.NodeDetailRoutes
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
private data class VectorMetricInfo(
@StringRes val label: Int,

View file

@ -55,7 +55,6 @@ import com.geeksville.mesh.BuildConfig
import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile
import com.geeksville.mesh.R
import com.geeksville.mesh.android.gpsDisabled
import com.geeksville.mesh.navigation.Route
import com.geeksville.mesh.navigation.getNavRouteFrom
import com.geeksville.mesh.ui.common.components.MainAppBar
import com.geeksville.mesh.ui.common.components.MultipleChoiceAlertDialog
@ -73,6 +72,7 @@ import com.geeksville.mesh.util.LanguageUtils
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import kotlinx.coroutines.delay
import org.meshtastic.core.navigation.Route
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

View file

@ -45,13 +45,13 @@ import androidx.compose.ui.unit.dp
import com.geeksville.mesh.R
import com.geeksville.mesh.navigation.ConfigRoute
import com.geeksville.mesh.navigation.ModuleRoute
import com.geeksville.mesh.navigation.Route
import com.geeksville.mesh.navigation.SettingsRoutes
import com.geeksville.mesh.ui.common.components.TitledCard
import com.geeksville.mesh.ui.common.theme.AppTheme
import com.geeksville.mesh.ui.common.theme.StatusColors.StatusRed
import com.geeksville.mesh.ui.settings.components.SettingsItem
import com.geeksville.mesh.ui.settings.radio.components.WarningDialog
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable

View file

@ -58,7 +58,6 @@ import com.geeksville.mesh.model.toChannelSet
import com.geeksville.mesh.moduleConfig
import com.geeksville.mesh.navigation.ConfigRoute
import com.geeksville.mesh.navigation.ModuleRoute
import com.geeksville.mesh.navigation.SettingsRoutes
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
import com.geeksville.mesh.repository.location.LocationRepository
import com.geeksville.mesh.service.ConnectionState
@ -78,6 +77,7 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
import org.meshtastic.core.navigation.SettingsRoutes
import java.io.FileOutputStream
import javax.inject.Inject

View file

@ -102,7 +102,6 @@ import com.geeksville.mesh.model.getChannelUrl
import com.geeksville.mesh.model.qrCode
import com.geeksville.mesh.model.toChannelSet
import com.geeksville.mesh.navigation.ConfigRoute
import com.geeksville.mesh.navigation.Route
import com.geeksville.mesh.navigation.getNavRouteFrom
import com.geeksville.mesh.service.ConnectionState
import com.geeksville.mesh.ui.common.components.AdaptiveTwoPane
@ -116,6 +115,7 @@ import com.google.accompanist.permissions.rememberPermissionState
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanOptions
import kotlinx.coroutines.launch
import org.meshtastic.core.navigation.Route
/**
* Composable screen for managing and sharing Meshtastic channels. Allows users to view, edit, and share channel