diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 97587507d..cce84c5d2 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -200,6 +200,7 @@ dependencies {
implementation(projects.feature.intro)
implementation(projects.feature.map)
implementation(projects.feature.node)
+ implementation(projects.feature.settings)
// Bundles
implementation(libs.bundles.markdown)
diff --git a/app/detekt-baseline.xml b/app/detekt-baseline.xml
index 8ea03a869..8e02cdb26 100644
--- a/app/detekt-baseline.xml
+++ b/app/detekt-baseline.xml
@@ -8,10 +8,6 @@
CommentWrapping:SignalMetrics.kt$Metric.SNR$/* Selected 12 as the max to get 4 equal vertical sections. */
ComposableNaming:NodeDetailScreen.kt$notesSection
ComposableParamOrder:Channel.kt$ChannelScreen
- ComposableParamOrder:ChannelSettingsItemList.kt$ChannelSettingsItemList
- ComposableParamOrder:Debug.kt$DecodedPayloadBlock
- ComposableParamOrder:DebugSearch.kt$DebugSearchState
- ComposableParamOrder:DebugSearch.kt$DebugSearchStateviewModelDefaults
ComposableParamOrder:DeviceMetrics.kt$DeviceMetricsChart
ComposableParamOrder:EmptyStateContent.kt$EmptyStateContent
ComposableParamOrder:EnvironmentCharts.kt$ChartContent
@@ -19,7 +15,6 @@
ComposableParamOrder:EnvironmentCharts.kt$MetricPlottingCanvas
ComposableParamOrder:HostMetricsLog.kt$HostMetricsItem
ComposableParamOrder:HostMetricsLog.kt$LogLine
- ComposableParamOrder:MapReportingPreference.kt$MapReportingPreference
ComposableParamOrder:Message.kt$MessageScreen
ComposableParamOrder:Message.kt$QuickChatRow
ComposableParamOrder:MessageActions.kt$MessageActions
@@ -29,7 +24,6 @@
ComposableParamOrder:MessageList.kt$MessageList
ComposableParamOrder:NodeDetailScreen.kt$DeviceActions
ComposableParamOrder:NodeDetailScreen.kt$EnvironmentMetrics
- ComposableParamOrder:NodeDetailScreen.kt$NodeActionButton
ComposableParamOrder:NodeDetailScreen.kt$NodeDetailList
ComposableParamOrder:PaxMetrics.kt$PaxMetricsChart
ComposableParamOrder:PowerMetrics.kt$PowerMetricsChart
@@ -37,11 +31,7 @@
ComposableParamOrder:Share.kt$ShareScreen
ComposableParamOrder:SignalMetrics.kt$SignalMetricsChart
ComposableParamOrder:TopLevelNavIcon.kt$ConnectionsNavIcon
- ComposableParamOrder:WarningDialog.kt$WarningDialog
CyclomaticComplexMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket)
- CyclomaticComplexMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- CyclomaticComplexMethod:PositionConfigItemList.kt$@OptIn(ExperimentalPermissionsApi::class) @Composable fun PositionConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- CyclomaticComplexMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)
EmptyClassBlock:DebugLogFile.kt$BinaryLogFile${ }
EmptyFunctionBlock:NopInterface.kt$NopInterface${ }
EmptyFunctionBlock:NsdManager.kt$<no name provided>${ }
@@ -71,44 +61,20 @@
LambdaParameterEventTrailing:Message.kt$onClick
LambdaParameterEventTrailing:Message.kt$onSendMessage
LambdaParameterEventTrailing:MessageList.kt$onReply
- LambdaParameterEventTrailing:NodeDetailScreen.kt$onClick
LambdaParameterEventTrailing:NodeDetailScreen.kt$onSaveNotes
LambdaParameterEventTrailing:QuickChat.kt$onNavigateUp
LambdaParameterEventTrailing:TracerouteLog.kt$onNavigateUp
LambdaParameterInRestartableEffect:Channel.kt$onConfirm
LambdaParameterInRestartableEffect:MessageList.kt$onUnreadChanged
LargeClass:MeshService.kt$MeshService : Service
- LongMethod:AmbientLightingConfigItemList.kt$@Composable fun AmbientLightingConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:AudioConfigItemList.kt$@Composable fun AudioConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:CannedMessageConfigItemList.kt$@Composable fun CannedMessageConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:DetectionSensorConfigItemList.kt$@Composable fun DetectionSensorConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:DeviceConfigItemList.kt$@Composable fun DeviceConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:DisplayConfigItemList.kt$@Composable fun DisplayConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
LongMethod:EnvironmentMetrics.kt$@Composable fun EnvironmentMetricsScreen(viewModel: MetricsViewModel = hiltViewModel(), onNavigateUp: () -> Unit)
- LongMethod:ExternalNotificationConfigItemList.kt$@Composable fun ExternalNotificationConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:LoRaConfigItemList.kt$@Composable fun LoRaConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
LongMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket)
- LongMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:PositionConfigItemList.kt$@OptIn(ExperimentalPermissionsApi::class) @Composable fun PositionConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:PowerConfigItemList.kt$@Composable fun PowerConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)
- LongMethod:SecurityConfigItemList.kt$@OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable fun SecurityConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:SerialConfigItemList.kt$@Composable fun SerialConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:StoreForwardConfigItemList.kt$@Composable fun StoreForwardConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:TelemetryConfigItemList.kt$@Composable fun TelemetryConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
- LongMethod:UserConfigItemList.kt$@Composable fun UserConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
LongParameterList:MessageViewModel.kt$MessageViewModel$( private val nodeRepository: NodeRepository, radioConfigRepository: RadioConfigRepository, quickChatActionRepository: QuickChatActionRepository, private val serviceRepository: ServiceRepository, private val packetRepository: PacketRepository, private val uiPrefs: UiPrefs, private val meshServiceNotifications: MeshServiceNotifications, )
MagicNumber:BluetoothInterface.kt$BluetoothInterface$1000
MagicNumber:BluetoothInterface.kt$BluetoothInterface$500
MagicNumber:BluetoothInterface.kt$BluetoothInterface$512
MagicNumber:Contacts.kt$7
MagicNumber:Contacts.kt$8
- MagicNumber:Debug.kt$3
- MagicNumber:EditChannelDialog.kt$16
- MagicNumber:EditChannelDialog.kt$32
- MagicNumber:LocationRepository.kt$LocationRepository$1000L
- MagicNumber:LocationRepository.kt$LocationRepository$30
- MagicNumber:LocationRepository.kt$LocationRepository$31
MagicNumber:MQTTRepository.kt$MQTTRepository$512
MagicNumber:MeshService.kt$MeshService$0xffffffff
MagicNumber:MeshService.kt$MeshService$1000
@@ -122,8 +88,6 @@
MagicNumber:MetricsViewModel.kt$MetricsViewModel$1000L
MagicNumber:MetricsViewModel.kt$MetricsViewModel$1e-5
MagicNumber:MetricsViewModel.kt$MetricsViewModel$1e-7
- MagicNumber:PacketResponseStateDialog.kt$100
- MagicNumber:PowerConfigItemList.kt$3600
MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$21972
MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$32809
MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$6790
@@ -149,8 +113,6 @@
ModifierClickableOrder:Channel.kt$clickable(onClick = onClick)
ModifierMissing:BLEDevices.kt$BLEDevices
ModifierMissing:Channel.kt$ChannelScreen
- ModifierMissing:ChannelSettingsItemList.kt$ChannelSelection
- ModifierMissing:CleanNodeDatabaseScreen.kt$CleanNodeDatabaseScreen
ModifierMissing:CommonCharts.kt$ChartHeader
ModifierMissing:CommonCharts.kt$Legend
ModifierMissing:CommonCharts.kt$TimeLabels
@@ -162,26 +124,18 @@
ModifierMissing:EmptyStateContent.kt$EmptyStateContent
ModifierMissing:EnvironmentMetrics.kt$EnvironmentMetricsScreen
ModifierMissing:HostMetricsLog.kt$HostMetricsLogScreen
- ModifierMissing:LoRaConfigItemList.kt$LoRaConfigScreen
ModifierMissing:Main.kt$MainScreen
- ModifierMissing:MapReportingPreference.kt$MapReportingPreference
ModifierMissing:MessageActions.kt$MessageStatusButton
ModifierMissing:MessageActions.kt$ReactionButton
ModifierMissing:MessageActions.kt$ReplyButton
- ModifierMissing:NetworkConfigItemList.kt$NetworkConfigScreen
ModifierMissing:NetworkDevices.kt$NetworkDevices
ModifierMissing:NodeListScreen.kt$NodeListScreen
ModifierMissing:PaxMetrics.kt$PaxMetricsItem
ModifierMissing:PaxMetrics.kt$PaxMetricsScreen
- ModifierMissing:PositionConfigItemList.kt$PositionConfigScreen
ModifierMissing:PositionLog.kt$PositionItem
ModifierMissing:PositionLog.kt$PositionLogScreen
ModifierMissing:PowerMetrics.kt$PowerMetricsScreen
- ModifierMissing:RadioConfig.kt$RadioConfigItemList
- ModifierMissing:RadioConfigScreenList.kt$RadioConfigScreenList
ModifierMissing:Reaction.kt$ReactionDialog
- ModifierMissing:SecurityConfigItemList.kt$SecurityConfigScreen
- ModifierMissing:SettingsScreen.kt$SettingsScreen
ModifierMissing:Share.kt$ShareScreen
ModifierMissing:SharedContactDialog.kt$SharedContactDialog
ModifierMissing:SignalMetrics.kt$SignalMetricsScreen
@@ -189,8 +143,6 @@
ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier = modifier.weight(weight = Y_AXIS_WEIGHT)
ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier = modifier.width(dp)
ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier.width(dp)
- ModifierNotUsedAtRoot:EditChannelDialog.kt$modifier = modifier.weight(1f)
- ModifierNotUsedAtRoot:EditDeviceProfileDialog.kt$modifier = modifier.weight(1f)
ModifierNotUsedAtRoot:EnvironmentCharts.kt$modifier = modifier.width(dp)
ModifierNotUsedAtRoot:EnvironmentCharts.kt$modifier.width(dp)
ModifierNotUsedAtRoot:PaxMetrics.kt$modifier.width(dp)
@@ -224,7 +176,6 @@
ModifierReused:SignalMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), Metric.SNR.color, minValue = Metric.SNR.min, maxValue = Metric.SNR.max, )
ModifierWithoutDefault:CommonCharts.kt$modifier
ModifierWithoutDefault:EnvironmentCharts.kt$modifier
- MultipleEmitters:CleanNodeDatabaseScreen.kt$NodesDeletionPreview
MultipleEmitters:CommonCharts.kt$LegendLabel
MultipleEmitters:DeviceMetrics.kt$DeviceMetricsChart
MultipleEmitters:EnvironmentCharts.kt$EnvironmentMetricsChart
@@ -232,13 +183,11 @@
MultipleEmitters:NodeDetailScreen.kt$MetricsSection
MultipleEmitters:PaxMetrics.kt$PaxMetricsChart
MultipleEmitters:PowerMetrics.kt$PowerMetricsChart
- MultipleEmitters:RadioConfig.kt$RadioConfigItemList
MultipleEmitters:SignalMetrics.kt$SignalMetricsChart
MutableStateAutoboxing:Contacts.kt$mutableStateOf(2)
MutableStateParam:MessageList.kt$selectedIds
NestedBlockDepth:MeshService.kt$MeshService$private fun handleReceivedAdmin(fromNodeNum: Int, a: AdminProtos.AdminMessage)
NestedBlockDepth:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket)
- NestedBlockDepth:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)
NewLineAtEndOfFile:BLEException.kt$com.geeksville.mesh.service.BLEException.kt
NewLineAtEndOfFile:BluetoothInterfaceFactory.kt$com.geeksville.mesh.repository.radio.BluetoothInterfaceFactory.kt
NewLineAtEndOfFile:BluetoothRepositoryModule.kt$com.geeksville.mesh.repository.bluetooth.BluetoothRepositoryModule.kt
@@ -266,27 +215,17 @@
NoEmptyClassBody:DebugLogFile.kt$BinaryLogFile${ }
NoSemicolons:DateUtils.kt$DateUtils$;
OptionalAbstractKeyword:SyncContinuation.kt$Continuation$abstract
- ParameterNaming:ChannelSettingsItemList.kt$onPositiveClicked
- ParameterNaming:ChannelSettingsItemList.kt$onSelected
- ParameterNaming:CleanNodeDatabaseScreen.kt$onCheckedChanged
- ParameterNaming:CleanNodeDatabaseScreen.kt$onDaysChanged
ParameterNaming:ContactSharing.kt$onSharedContactRequested
ParameterNaming:Contacts.kt$onDeleteSelected
ParameterNaming:Contacts.kt$onMuteSelected
- ParameterNaming:MapReportingPreference.kt$onMapReportingEnabledChanged
- ParameterNaming:MapReportingPreference.kt$onPositionPrecisionChanged
- ParameterNaming:MapReportingPreference.kt$onPublishIntervalSecsChanged
- ParameterNaming:MapReportingPreference.kt$onShouldReportLocationChanged
ParameterNaming:MessageList.kt$onUnreadChanged
ParameterNaming:NodeDetailScreen.kt$onFirmwareSelected
ParameterNaming:UsbDevices.kt$onDeviceSelected
PreviewPublic:Channel.kt$ModemPresetInfoPreview
PreviewPublic:EmptyStateContent.kt$EmptyStateContentPreview
- PreviewPublic:MapReportingPreference.kt$MapReportingPreview
PreviewPublic:Reaction.kt$ReactionItemPreview
PreviewPublic:Reaction.kt$ReactionRowPreview
RethrowCaughtException:SyncContinuation.kt$Continuation$throw ex
- ReturnCount:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)
SwallowedException:BluetoothInterface.kt$BluetoothInterface$ex: CancellationException
SwallowedException:Exceptions.kt$ex: Throwable
SwallowedException:MeshService.kt$MeshService$ex: BLEException
@@ -299,13 +238,10 @@
TooGenericExceptionCaught:BTScanModel.kt$BTScanModel$ex: Throwable
TooGenericExceptionCaught:BluetoothInterface.kt$BluetoothInterface$ex: Exception
TooGenericExceptionCaught:Exceptions.kt$ex: Throwable
- TooGenericExceptionCaught:LanguageUtils.kt$LanguageUtils$e: Exception
- TooGenericExceptionCaught:LocationRepository.kt$LocationRepository$e: Exception
TooGenericExceptionCaught:MQTTRepository.kt$MQTTRepository$ex: Exception
TooGenericExceptionCaught:MeshService.kt$MeshService$ex: Exception
TooGenericExceptionCaught:MeshService.kt$MeshService.<no name provided>$ex: Exception
TooGenericExceptionCaught:MeshServiceStarter.kt$ServiceStarter$ex: Exception
- TooGenericExceptionCaught:RadioConfigViewModel.kt$RadioConfigViewModel$ex: Exception
TooGenericExceptionCaught:SafeBluetooth.kt$SafeBluetooth$ex: Exception
TooGenericExceptionCaught:SafeBluetooth.kt$SafeBluetooth$ex: NullPointerException
TooGenericExceptionCaught:SyncContinuation.kt$Continuation$ex: Throwable
@@ -321,16 +257,12 @@
TooManyFunctions:MeshService.kt$MeshService$<no name provided> : Stub
TooManyFunctions:MessageViewModel.kt$MessageViewModel : ViewModel
TooManyFunctions:NodeDetailScreen.kt$com.geeksville.mesh.ui.node.NodeDetailScreen.kt
- TooManyFunctions:RadioConfigViewModel.kt$RadioConfigViewModel : ViewModel
TooManyFunctions:RadioInterfaceService.kt$RadioInterfaceService
TooManyFunctions:SafeBluetooth.kt$SafeBluetooth : Closeable
TooManyFunctions:UIState.kt$UIViewModel : ViewModel
TopLevelPropertyNaming:Constants.kt$const val prefix = "com.geeksville.mesh"
- UnusedParameter:ChannelSettingsItemList.kt$onBack: () -> Unit
- UnusedParameter:ChannelSettingsItemList.kt$title: String
UtilityClassWithPublicConstructor:NetworkRepositoryModule.kt$NetworkRepositoryModule
ViewModelForwarding:Main.kt$VersionChecks(uIViewModel)
- ViewModelInjection:DebugSearch.kt$viewModel
Wrapping:Message.kt${ event -> when (event) { is MessageScreenEvent.SendMessage -> { viewModel.sendMessage(event.text, contactKey, event.replyingToPacketId) if (event.replyingToPacketId != null) replyingToPacketId = null messageInputState.clearText() } is MessageScreenEvent.SendReaction -> viewModel.sendReaction(event.emoji, event.messageId, contactKey) is MessageScreenEvent.DeleteMessages -> { viewModel.deleteMessages(event.ids) selectedMessageIds.value = emptySet() showDeleteDialog = false } is MessageScreenEvent.ClearUnreadCount -> viewModel.clearUnreadCount(contactKey, event.lastReadMessageId) is MessageScreenEvent.NodeDetails -> navigateToNodeDetails(event.node.num) is MessageScreenEvent.SetTitle -> viewModel.setTitle(event.title) is MessageScreenEvent.NavigateToMessages -> navigateToMessages(event.contactKey) is MessageScreenEvent.NavigateToNodeDetails -> navigateToNodeDetails(event.nodeNum) MessageScreenEvent.NavigateBack -> onNavigateBack() is MessageScreenEvent.CopyToClipboard -> { clipboardManager.nativeClipboard.setPrimaryClip(ClipData.newPlainText(event.text, event.text)) selectedMessageIds.value = emptySet() } } }
diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt
index 85751f9ff..8acdfd751 100644
--- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt
+++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt
@@ -29,15 +29,11 @@ import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.AdminProtos
import com.geeksville.mesh.AppOnlyProtos
-import com.geeksville.mesh.ChannelProtos
-import com.geeksville.mesh.ChannelProtos.ChannelSettings
import com.geeksville.mesh.ConfigProtos.Config
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
import com.geeksville.mesh.MeshProtos
-import com.geeksville.mesh.channel
import com.geeksville.mesh.channelSet
-import com.geeksville.mesh.channelSettings
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
import com.geeksville.mesh.repository.radio.MeshActivity
@@ -106,34 +102,6 @@ fun getInitials(fullName: String): String {
private fun String.withoutEmojis(): String = filterNot { char -> char.isSurrogate() }
-/**
- * Builds a [Channel] list from the difference between two [ChannelSettings] lists. Only changes are included in the
- * resulting list.
- *
- * @param new The updated [ChannelSettings] list.
- * @param old The current [ChannelSettings] list (required when disabling unused channels).
- * @return A [Channel] list containing only the modified channels.
- */
-internal fun getChannelList(new: List, old: List): List =
- buildList {
- for (i in 0..maxOf(old.lastIndex, new.lastIndex)) {
- if (old.getOrNull(i) != new.getOrNull(i)) {
- add(
- channel {
- role =
- when (i) {
- 0 -> ChannelProtos.Channel.Role.PRIMARY
- in 1..new.lastIndex -> ChannelProtos.Channel.Role.SECONDARY
- else -> ChannelProtos.Channel.Role.DISABLED
- }
- index = i
- settings = new.getOrNull(i) ?: channelSettings {}
- },
- )
- }
- }
- }
-
data class Contact(
val contactKey: String,
val shortName: String,
diff --git a/app/src/main/java/com/geeksville/mesh/navigation/ChannelsNavigation.kt b/app/src/main/java/com/geeksville/mesh/navigation/ChannelsNavigation.kt
index e84cf926b..83974f67a 100644
--- a/app/src/main/java/com/geeksville/mesh/navigation/ChannelsNavigation.kt
+++ b/app/src/main/java/com/geeksville/mesh/navigation/ChannelsNavigation.kt
@@ -24,11 +24,12 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import androidx.navigation.navDeepLink
import androidx.navigation.navigation
-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
+import org.meshtastic.feature.settings.navigation.ConfigRoute
+import org.meshtastic.feature.settings.radio.component.ChannelConfigScreen
+import org.meshtastic.feature.settings.radio.component.LoRaConfigScreen
/** Navigation graph for for the top level ChannelScreen - [ChannelsRoutes.Channels]. */
fun NavGraphBuilder.channelsGraph(navController: NavHostController) {
diff --git a/app/src/main/java/com/geeksville/mesh/navigation/ConnectionsNavigation.kt b/app/src/main/java/com/geeksville/mesh/navigation/ConnectionsNavigation.kt
index 6663ead2a..976fda5dc 100644
--- a/app/src/main/java/com/geeksville/mesh/navigation/ConnectionsNavigation.kt
+++ b/app/src/main/java/com/geeksville/mesh/navigation/ConnectionsNavigation.kt
@@ -25,12 +25,12 @@ import androidx.navigation.compose.composable
import androidx.navigation.navDeepLink
import androidx.navigation.navigation
import com.geeksville.mesh.ui.connections.ConnectionsScreen
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
-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
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
+import org.meshtastic.feature.settings.radio.component.LoRaConfigScreen
/** Navigation graph for for the top level ConnectionsScreen - [ConnectionsRoutes.Connections]. */
fun NavGraphBuilder.connectionsGraph(navController: NavHostController) {
diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt
index feb2e9c1b..1ed6fb51c 100644
--- a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt
+++ b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt
@@ -37,6 +37,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
+import org.meshtastic.core.analytics.platform.PlatformAnalytics
import org.meshtastic.core.model.util.anonymize
import timber.log.Timber
import java.lang.reflect.Method
@@ -104,6 +105,7 @@ constructor(
context: Application,
bluetoothRepository: BluetoothRepository,
private val service: RadioInterfaceService,
+ analytics: PlatformAnalytics,
@Assisted val address: String,
) : IRadioInterface {
@@ -195,7 +197,7 @@ constructor(
Timber.i("Creating radio interface service. device=${address.anonymize}")
// Note this constructor also does no comm
- val s = SafeBluetooth(context, device)
+ val s = SafeBluetooth(context, device, analytics)
safe = s
startConnect()
diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt
index 17997c93e..4a56d43d5 100644
--- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt
+++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt
@@ -40,8 +40,6 @@ import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.MeshProtos.FromRadio.PayloadVariantCase
import com.geeksville.mesh.MeshProtos.MeshPacket
import com.geeksville.mesh.MeshProtos.ToRadio
-import com.geeksville.mesh.MeshUtilApplication
-import com.geeksville.mesh.MeshUtilApplication.Companion.analytics
import com.geeksville.mesh.ModuleConfigProtos
import com.geeksville.mesh.PaxcountProtos
import com.geeksville.mesh.Portnums
@@ -54,7 +52,6 @@ import com.geeksville.mesh.copy
import com.geeksville.mesh.fromRadio
import com.geeksville.mesh.model.NO_DEVICE_SELECTED
import com.geeksville.mesh.position
-import com.geeksville.mesh.repository.location.LocationRepository
import com.geeksville.mesh.repository.network.MQTTRepository
import com.geeksville.mesh.repository.radio.RadioInterfaceService
import com.geeksville.mesh.telemetry
@@ -77,7 +74,9 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.meshtastic.core.analytics.DataPair
+import org.meshtastic.core.analytics.platform.PlatformAnalytics
import org.meshtastic.core.common.hasLocationPermission
+import org.meshtastic.core.data.repository.LocationRepository
import org.meshtastic.core.data.repository.MeshLogRepository
import org.meshtastic.core.data.repository.NodeRepository
import org.meshtastic.core.data.repository.PacketRepository
@@ -152,6 +151,8 @@ class MeshService : Service() {
@Inject lateinit var serviceBroadcasts: MeshServiceBroadcasts
+ @Inject lateinit var analytics: PlatformAnalytics
+
private val tracerouteStartTimes = ConcurrentHashMap()
companion object {
@@ -869,13 +870,9 @@ class MeshService : Service() {
serviceBroadcasts.broadcastReceivedData(dataPacket)
}
- MeshUtilApplication.analytics.track("num_data_receive", DataPair("num_data_receive", 1))
+ analytics.track("num_data_receive", DataPair("num_data_receive", 1))
- MeshUtilApplication.analytics.track(
- "data_receive",
- DataPair("num_bytes", bytes.size),
- DataPair("type", data.portnumValue),
- )
+ analytics.track("data_receive", DataPair("num_bytes", bytes.size), DataPair("type", data.portnumValue))
}
}
}
@@ -1122,7 +1119,7 @@ class MeshService : Service() {
sendNow(p)
sentPackets.add(p)
} catch (ex: Exception) {
- Timber.e("Error sending queued message:", ex)
+ Timber.e(ex, "Error sending queued message:")
}
}
offlineSentPackets.removeAll(sentPackets)
@@ -1239,7 +1236,7 @@ class MeshService : Service() {
/** Send in analytics about mesh connection */
private fun reportConnection() {
val radioModel = DataPair("radio_model", myNodeInfo?.model ?: "unknown")
- MeshUtilApplication.analytics.track(
+ analytics.track(
"mesh_connect",
DataPair("num_nodes", numNodes),
DataPair("num_online", numOnlineNodes),
@@ -1266,10 +1263,7 @@ class MeshService : Service() {
val now = System.currentTimeMillis()
connectTimeMsec = 0L
- MeshUtilApplication.analytics.track(
- "connected_seconds",
- DataPair("connected_seconds", (now - connectTimeMsec) / 1000.0),
- )
+ analytics.track("connected_seconds", DataPair("connected_seconds", (now - connectTimeMsec) / 1000.0))
}
// Have our timeout fire in the appropriate number of seconds
@@ -1298,12 +1292,8 @@ class MeshService : Service() {
stopLocationRequests()
stopMqttClientProxy()
- MeshUtilApplication.analytics.track(
- "mesh_disconnect",
- DataPair("num_nodes", numNodes),
- DataPair("num_online", numOnlineNodes),
- )
- MeshUtilApplication.analytics.track("num_nodes", DataPair("num_nodes", numNodes))
+ analytics.track("mesh_disconnect", DataPair("num_nodes", numNodes), DataPair("num_online", numOnlineNodes))
+ analytics.track("num_nodes", DataPair("num_nodes", numNodes))
// broadcast an intent with our new connection state
serviceBroadcasts.broadcastConnection()
@@ -1315,7 +1305,7 @@ class MeshService : Service() {
connectTimeMsec = System.currentTimeMillis()
startConfig()
} catch (ex: InvalidProtocolBufferException) {
- Timber.e("Invalid protocol buffer sent by device - update device software and try again", ex)
+ Timber.e(ex, "Invalid protocol buffer sent by device - update device software and try again")
} catch (ex: RadioNotConnectedException) {
// note: no need to call startDeviceSleep(), because this exception could only have
// reached us if it was
@@ -2104,7 +2094,7 @@ class MeshService : Service() {
try {
sendNow(p)
} catch (ex: Exception) {
- Timber.e("Error sending message, so enqueueing", ex)
+ Timber.e(ex, "Error sending message, so enqueueing")
enqueueForSending(p)
}
} else {
@@ -2115,11 +2105,7 @@ class MeshService : Service() {
// Keep a record of DataPackets, so GUIs can show proper chat history
rememberDataPacket(p, false)
- MeshUtilApplication.analytics.track(
- "data_send",
- DataPair("num_bytes", bytes.size),
- DataPair("type", p.dataType),
- )
+ analytics.track("data_send", DataPair("num_bytes", bytes.size), DataPair("type", p.dataType))
}
}
diff --git a/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt b/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt
index 5bf6cd962..afe855e21 100644
--- a/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt
+++ b/app/src/main/java/com/geeksville/mesh/service/SafeBluetooth.kt
@@ -31,7 +31,6 @@ import android.os.Build
import android.os.DeadObjectException
import android.os.Handler
import android.os.Looper
-import com.geeksville.mesh.MeshUtilApplication.Companion.analytics
import com.geeksville.mesh.concurrent.CallbackContinuation
import com.geeksville.mesh.concurrent.Continuation
import com.geeksville.mesh.concurrent.SyncContinuation
@@ -43,6 +42,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
+import org.meshtastic.core.analytics.platform.PlatformAnalytics
import timber.log.Timber
import java.io.Closeable
import java.util.Random
@@ -63,7 +63,11 @@ fun longBLEUUID(hexFour: String): UUID = UUID.fromString("0000$hexFour-0000-1000
*
* This class fixes the API by using coroutines to let you safely do a series of BTLE operations.
*/
-class SafeBluetooth(private val context: Context, private val device: BluetoothDevice) : Closeable {
+class SafeBluetooth(
+ private val context: Context,
+ private val device: BluetoothDevice,
+ private val analytics: PlatformAnalytics,
+) : Closeable {
// / Timeout before we declare a bluetooth operation failed (used for synchronous API operations only)
var timeoutMsec = 20 * 1000L
@@ -430,7 +434,7 @@ class SafeBluetooth(private val context: Context, private val device: BluetoothD
try {
it.completion.resumeWithException(ex)
} catch (ex: Exception) {
- Timber.e("Mystery exception, why were we informed about our own exceptions?", ex)
+ Timber.e(ex, "Mystery exception, why were we informed about our own exceptions?")
}
}
workQueue.clear()
diff --git a/app/src/main/java/com/geeksville/mesh/ui/Main.kt b/app/src/main/java/com/geeksville/mesh/ui/Main.kt
index 7d66a0ae3..578689587 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/Main.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/Main.kt
@@ -75,7 +75,7 @@ import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.geeksville.mesh.BuildConfig
import com.geeksville.mesh.MeshProtos
-import com.geeksville.mesh.MeshUtilApplication.Companion.analytics
+import com.geeksville.mesh.MeshUtilApplication
import com.geeksville.mesh.model.BTScanModel
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.navigation.channelsGraph
@@ -83,7 +83,6 @@ import com.geeksville.mesh.navigation.connectionsGraph
import com.geeksville.mesh.navigation.contactsGraph
import com.geeksville.mesh.navigation.mapGraph
import com.geeksville.mesh.navigation.nodesGraph
-import com.geeksville.mesh.navigation.settingsGraph
import com.geeksville.mesh.repository.radio.MeshActivity
import com.geeksville.mesh.service.MeshService
import com.geeksville.mesh.ui.common.components.ScannedQrCodeDialog
@@ -114,6 +113,7 @@ import org.meshtastic.core.ui.icon.Nodes
import org.meshtastic.core.ui.icon.Settings
import org.meshtastic.core.ui.theme.StatusColors.StatusBlue
import org.meshtastic.core.ui.theme.StatusColors.StatusGreen
+import org.meshtastic.feature.settings.navigation.settingsGraph
import timber.log.Timber
enum class TopLevelDestination(@StringRes val label: Int, val icon: ImageVector, val route: Route) {
@@ -158,7 +158,7 @@ fun MainScreen(uIViewModel: UIViewModel = hiltViewModel(), scanModel: BTScanMode
}
}
- analytics.addNavigationTrackingEffect(navController = navController)
+ MeshUtilApplication.analytics.addNavigationTrackingEffect(navController = navController)
VersionChecks(uIViewModel)
val alertDialogState by uIViewModel.currentAlert.collectAsStateWithLifecycle()
diff --git a/app/src/main/java/com/geeksville/mesh/ui/common/components/ScannedQrCodeDialog.kt b/app/src/main/java/com/geeksville/mesh/ui/common/components/ScannedQrCodeDialog.kt
index 591d42435..89059ae01 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/common/components/ScannedQrCodeDialog.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/common/components/ScannedQrCodeDialog.kt
@@ -55,9 +55,9 @@ import com.geeksville.mesh.AppOnlyProtos.ChannelSet
import com.geeksville.mesh.ConfigProtos.Config.LoRaConfig.ModemPreset
import com.geeksville.mesh.channelSet
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.settings.radio.components.ChannelSelection
import org.meshtastic.core.model.Channel
import org.meshtastic.core.strings.R
+import org.meshtastic.feature.settings.radio.component.ChannelSelection
@Composable
fun ScannedQrCodeDialog(
diff --git a/app/src/main/java/com/geeksville/mesh/ui/common/components/ScannedQrCodeViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/common/components/ScannedQrCodeViewModel.kt
index 38b54cb8f..34d6f16df 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/common/components/ScannedQrCodeViewModel.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/common/components/ScannedQrCodeViewModel.kt
@@ -26,12 +26,12 @@ import com.geeksville.mesh.ConfigProtos.Config
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.channelSet
import com.geeksville.mesh.config
-import com.geeksville.mesh.model.getChannelList
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.meshtastic.core.data.repository.RadioConfigRepository
+import org.meshtastic.core.proto.getChannelList
import org.meshtastic.core.service.ServiceRepository
import timber.log.Timber
import javax.inject.Inject
diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt
index a601a1443..0a6c746e0 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt
@@ -55,15 +55,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.ConfigProtos
import com.geeksville.mesh.model.BTScanModel
import com.geeksville.mesh.model.DeviceListEntry
-import com.geeksville.mesh.navigation.ConfigRoute
-import com.geeksville.mesh.navigation.getNavRouteFrom
import com.geeksville.mesh.ui.connections.components.BLEDevices
import com.geeksville.mesh.ui.connections.components.ConnectionsSegmentedBar
import com.geeksville.mesh.ui.connections.components.CurrentlyConnectedInfo
import com.geeksville.mesh.ui.connections.components.NetworkDevices
import com.geeksville.mesh.ui.connections.components.UsbDevices
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
-import com.geeksville.mesh.ui.settings.radio.components.PacketResponseStateDialog
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import kotlinx.coroutines.delay
import org.meshtastic.core.navigation.Route
@@ -73,6 +69,10 @@ import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.SettingsItem
import org.meshtastic.core.ui.component.TitledCard
+import org.meshtastic.feature.settings.navigation.ConfigRoute
+import org.meshtastic.feature.settings.navigation.getNavRouteFrom
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
+import org.meshtastic.feature.settings.radio.component.PacketResponseStateDialog
fun String?.isIPAddress(): Boolean = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
@Suppress("DEPRECATION")
diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailScreen.kt
index c77152a42..83e0a1f04 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailScreen.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetailScreen.kt
@@ -1121,31 +1121,6 @@ private fun PowerMetrics(node: Node) {
}
}
-@Composable
-fun NodeActionButton(
- modifier: Modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp).height(48.dp),
- title: String,
- enabled: Boolean,
- icon: ImageVector? = null,
- iconTint: Color? = null,
- onClick: () -> Unit,
-) {
- Button(onClick = { onClick() }, enabled = enabled, modifier = modifier) {
- Row(verticalAlignment = Alignment.CenterVertically) {
- if (icon != null) {
- Icon(
- imageVector = icon,
- contentDescription = title,
- modifier = Modifier.size(24.dp),
- tint = iconTint ?: LocalContentColor.current,
- )
- Spacer(modifier = Modifier.width(8.dp))
- }
- Text(text = title, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.weight(1f))
- }
- }
-}
-
@Preview(showBackground = true)
@Composable
private fun NodeDetailsPreview(@PreviewParameter(NodePreviewParameterProvider::class) node: Node) {
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 cce17689e..97b5d4779 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
@@ -95,12 +95,7 @@ import com.geeksville.mesh.ConfigProtos
import com.geeksville.mesh.MeshUtilApplication.Companion.analytics
import com.geeksville.mesh.channelSet
import com.geeksville.mesh.copy
-import com.geeksville.mesh.navigation.ConfigRoute
-import com.geeksville.mesh.navigation.getNavRouteFrom
import com.geeksville.mesh.ui.common.components.ScannedQrCodeDialog
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
-import com.geeksville.mesh.ui.settings.radio.components.ChannelSelection
-import com.geeksville.mesh.ui.settings.radio.components.PacketResponseStateDialog
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
@@ -118,6 +113,11 @@ import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.AdaptiveTwoPane
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.PreferenceFooter
+import org.meshtastic.feature.settings.navigation.ConfigRoute
+import org.meshtastic.feature.settings.navigation.getNavRouteFrom
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
+import org.meshtastic.feature.settings.radio.component.ChannelSelection
+import org.meshtastic.feature.settings.radio.component.PacketResponseStateDialog
import timber.log.Timber
/**
diff --git a/app/src/main/java/com/geeksville/mesh/ui/sharing/ChannelViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/sharing/ChannelViewModel.kt
index 4b05764f1..20ec42095 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/sharing/ChannelViewModel.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/sharing/ChannelViewModel.kt
@@ -28,7 +28,6 @@ import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.channelSet
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
-import com.geeksville.mesh.model.getChannelList
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -37,6 +36,7 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.meshtastic.core.data.repository.RadioConfigRepository
import org.meshtastic.core.model.util.toChannelSet
+import org.meshtastic.core.proto.getChannelList
import org.meshtastic.core.service.ServiceRepository
import timber.log.Timber
import javax.inject.Inject
diff --git a/build.gradle.kts b/build.gradle.kts
index 8a8c59fb4..70b1c5d66 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -78,4 +78,5 @@ dependencies {
kover(projects.feature.intro)
kover(projects.feature.map)
kover(projects.feature.node)
+ kover(projects.feature.settings)
}
\ No newline at end of file
diff --git a/core/data/build.gradle.kts b/core/data/build.gradle.kts
index 37da5a7ef..0db09ac50 100644
--- a/core/data/build.gradle.kts
+++ b/core/data/build.gradle.kts
@@ -25,6 +25,7 @@ plugins {
android { namespace = "org.meshtastic.core.data" }
dependencies {
+ implementation(projects.core.analytics)
implementation(projects.core.database)
implementation(projects.core.datastore)
implementation(projects.core.di)
@@ -33,6 +34,7 @@ dependencies {
implementation(projects.core.prefs)
implementation(projects.core.proto)
+ implementation(libs.core.location.altitude)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlinx.serialization.json)
implementation(libs.timber)
diff --git a/core/data/detekt-baseline.xml b/core/data/detekt-baseline.xml
index 6f500e50a..b15fbf373 100644
--- a/core/data/detekt-baseline.xml
+++ b/core/data/detekt-baseline.xml
@@ -2,7 +2,11 @@
+ MagicNumber:LocationRepository.kt$LocationRepository$1000L
+ MagicNumber:LocationRepository.kt$LocationRepository$30
+ MagicNumber:LocationRepository.kt$LocationRepository$31
MagicNumber:PacketRepository.kt$PacketRepository$500
+ TooGenericExceptionCaught:LocationRepository.kt$LocationRepository$e: Exception
TooManyFunctions:PacketRepository.kt$PacketRepository
diff --git a/app/src/main/java/com/geeksville/mesh/repository/location/LocationRepositoryModule.kt b/core/data/src/main/kotlin/org/meshtastic/core/data/di/DataModule.kt
similarity index 93%
rename from app/src/main/java/com/geeksville/mesh/repository/location/LocationRepositoryModule.kt
rename to core/data/src/main/kotlin/org/meshtastic/core/data/di/DataModule.kt
index 3728d58f3..241f70218 100644
--- a/app/src/main/java/com/geeksville/mesh/repository/location/LocationRepositoryModule.kt
+++ b/core/data/src/main/kotlin/org/meshtastic/core/data/di/DataModule.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.repository.location
+package org.meshtastic.core.data.di
import android.content.Context
import android.location.LocationManager
@@ -28,7 +28,7 @@ import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
-object LocationRepositoryModule {
+object DataModule {
@Provides
@Singleton
diff --git a/app/src/main/java/com/geeksville/mesh/repository/location/LocationRepository.kt b/core/data/src/main/kotlin/org/meshtastic/core/data/repository/LocationRepository.kt
similarity index 93%
rename from app/src/main/java/com/geeksville/mesh/repository/location/LocationRepository.kt
rename to core/data/src/main/kotlin/org/meshtastic/core/data/repository/LocationRepository.kt
index 18359f8e6..7849ea1df 100644
--- a/app/src/main/java/com/geeksville/mesh/repository/location/LocationRepository.kt
+++ b/core/data/src/main/kotlin/org/meshtastic/core/data/repository/LocationRepository.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.repository.location
+package org.meshtastic.core.data.repository
import android.Manifest.permission.ACCESS_COARSE_LOCATION
import android.Manifest.permission.ACCESS_FINE_LOCATION
@@ -27,13 +27,13 @@ import androidx.core.location.LocationListenerCompat
import androidx.core.location.LocationManagerCompat
import androidx.core.location.LocationRequestCompat
import androidx.core.location.altitude.AltitudeConverterCompat
-import com.geeksville.mesh.MeshUtilApplication
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
+import org.meshtastic.core.analytics.platform.PlatformAnalytics
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
@@ -44,6 +44,7 @@ class LocationRepository
constructor(
private val context: Application,
private val locationManager: dagger.Lazy,
+ private val analytics: PlatformAnalytics,
) {
/** Status of whether the app is actively subscribed to location changes. */
@@ -88,7 +89,7 @@ constructor(
"Starting location updates with $providerList intervalMs=${intervalMs}ms and minDistanceM=${minDistanceM}m",
)
_receivingLocationUpdates.value = true
- MeshUtilApplication.analytics.track("location_start") // Figure out how many users needed to use the phone GPS
+ analytics.track("location_start") // Figure out how many users needed to use the phone GPS
try {
providerList.forEach { provider ->
@@ -107,7 +108,7 @@ constructor(
awaitClose {
Timber.i("Stopping location requests")
_receivingLocationUpdates.value = false
- MeshUtilApplication.analytics.track("location_stop")
+ analytics.track("location_stop")
LocationManagerCompat.removeUpdates(this@requestLocationUpdates, locationListener)
}
diff --git a/core/proto/src/main/kotlin/org/meshtastic/core/proto/ProtoExtensions.kt b/core/proto/src/main/kotlin/org/meshtastic/core/proto/ProtoExtensions.kt
index b62e31f95..037187240 100644
--- a/core/proto/src/main/kotlin/org/meshtastic/core/proto/ProtoExtensions.kt
+++ b/core/proto/src/main/kotlin/org/meshtastic/core/proto/ProtoExtensions.kt
@@ -19,9 +19,13 @@ package org.meshtastic.core.proto
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
+import com.geeksville.mesh.ChannelProtos
+import com.geeksville.mesh.ChannelProtos.ChannelSettings
import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.MeshProtos.MeshPacket
import com.geeksville.mesh.MeshProtos.Position
+import com.geeksville.mesh.channel
+import com.geeksville.mesh.channelSettings
import java.text.DateFormat
import kotlin.time.Duration.Companion.days
@@ -46,3 +50,30 @@ fun MeshPacket.toPosition(): Position? = if (!decoded.wantResponse) {
} else {
null
}
+
+/**
+ * Builds a [Channel] list from the difference between two [ChannelSettings] lists. Only changes are included in the
+ * resulting list.
+ *
+ * @param new The updated [ChannelSettings] list.
+ * @param old The current [ChannelSettings] list (required when disabling unused channels).
+ * @return A [Channel] list containing only the modified channels.
+ */
+fun getChannelList(new: List, old: List): List = buildList {
+ for (i in 0..maxOf(old.lastIndex, new.lastIndex)) {
+ if (old.getOrNull(i) != new.getOrNull(i)) {
+ add(
+ channel {
+ role =
+ when (i) {
+ 0 -> ChannelProtos.Channel.Role.PRIMARY
+ in 1..new.lastIndex -> ChannelProtos.Channel.Role.SECONDARY
+ else -> ChannelProtos.Channel.Role.DISABLED
+ }
+ index = i
+ settings = new.getOrNull(i) ?: channelSettings {}
+ },
+ )
+ }
+ }
+}
diff --git a/feature/settings/build.gradle.kts b/feature/settings/build.gradle.kts
new file mode 100644
index 000000000..58c9fe287
--- /dev/null
+++ b/feature/settings/build.gradle.kts
@@ -0,0 +1,44 @@
+/*
+ * 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 .
+ */
+
+plugins {
+ alias(libs.plugins.kover)
+ alias(libs.plugins.meshtastic.android.library)
+ alias(libs.plugins.meshtastic.android.library.compose)
+ alias(libs.plugins.meshtastic.hilt)
+}
+
+android { namespace = "org.meshtastic.feature.settings" }
+
+dependencies {
+ implementation(projects.core.common)
+ implementation(projects.core.data)
+ implementation(projects.core.database)
+ implementation(projects.core.datastore)
+ implementation(projects.core.model)
+ implementation(projects.core.navigation)
+ implementation(projects.core.prefs)
+ implementation(projects.core.proto)
+ implementation(projects.core.service)
+ implementation(projects.core.strings)
+ implementation(projects.core.ui)
+
+ implementation(libs.accompanist.permissions)
+ implementation(libs.kotlinx.collections.immutable)
+ implementation(libs.timber)
+ implementation(libs.zxing.android.embedded)
+}
diff --git a/feature/settings/detekt-baseline.xml b/feature/settings/detekt-baseline.xml
new file mode 100644
index 000000000..6b33612e1
--- /dev/null
+++ b/feature/settings/detekt-baseline.xml
@@ -0,0 +1,70 @@
+
+
+
+
+ ComposableParamOrder:ChannelSettingsItemList.kt$ChannelSettingsItemList
+ ComposableParamOrder:Debug.kt$DecodedPayloadBlock
+ ComposableParamOrder:DebugSearch.kt$DebugSearchState
+ ComposableParamOrder:DebugSearch.kt$DebugSearchStateviewModelDefaults
+ ComposableParamOrder:MapReportingPreference.kt$MapReportingPreference
+ ComposableParamOrder:NodeActionButton.kt$NodeActionButton
+ ComposableParamOrder:WarningDialog.kt$WarningDialog
+ CyclomaticComplexMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ CyclomaticComplexMethod:PositionConfigItemList.kt$@OptIn(ExperimentalPermissionsApi::class) @Composable fun PositionConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ CyclomaticComplexMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)
+ LambdaParameterEventTrailing:NodeActionButton.kt$onClick
+ LongMethod:AmbientLightingConfigItemList.kt$@Composable fun AmbientLightingConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:AudioConfigItemList.kt$@Composable fun AudioConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:CannedMessageConfigItemList.kt$@Composable fun CannedMessageConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:DetectionSensorConfigItemList.kt$@Composable fun DetectionSensorConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:DeviceConfigItemList.kt$@Composable fun DeviceConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:DisplayConfigItemList.kt$@Composable fun DisplayConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:ExternalNotificationConfigItemList.kt$@Composable fun ExternalNotificationConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:LoRaConfigItemList.kt$@Composable fun LoRaConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:PositionConfigItemList.kt$@OptIn(ExperimentalPermissionsApi::class) @Composable fun PositionConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:PowerConfigItemList.kt$@Composable fun PowerConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)
+ LongMethod:SecurityConfigItemList.kt$@OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable fun SecurityConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:SerialConfigItemList.kt$@Composable fun SerialConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:StoreForwardConfigItemList.kt$@Composable fun StoreForwardConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:TelemetryConfigItemList.kt$@Composable fun TelemetryConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ LongMethod:UserConfigItemList.kt$@Composable fun UserConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())
+ MagicNumber:Debug.kt$3
+ MagicNumber:EditChannelDialog.kt$16
+ MagicNumber:EditChannelDialog.kt$32
+ MagicNumber:PacketResponseStateDialog.kt$100
+ MagicNumber:PowerConfigItemList.kt$3600
+ ModifierMissing:ChannelSettingsItemList.kt$ChannelSelection
+ ModifierMissing:CleanNodeDatabaseScreen.kt$CleanNodeDatabaseScreen
+ ModifierMissing:LoRaConfigItemList.kt$LoRaConfigScreen
+ ModifierMissing:MapReportingPreference.kt$MapReportingPreference
+ ModifierMissing:NetworkConfigItemList.kt$NetworkConfigScreen
+ ModifierMissing:PositionConfigItemList.kt$PositionConfigScreen
+ ModifierMissing:RadioConfig.kt$RadioConfigItemList
+ ModifierMissing:RadioConfigScreenList.kt$RadioConfigScreenList
+ ModifierMissing:SecurityConfigItemList.kt$SecurityConfigScreen
+ ModifierMissing:SettingsScreen.kt$SettingsScreen
+ ModifierNotUsedAtRoot:EditChannelDialog.kt$modifier = modifier.weight(1f)
+ ModifierNotUsedAtRoot:EditDeviceProfileDialog.kt$modifier = modifier.weight(1f)
+ MultipleEmitters:CleanNodeDatabaseScreen.kt$NodesDeletionPreview
+ MultipleEmitters:RadioConfig.kt$RadioConfigItemList
+ NestedBlockDepth:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)
+ ParameterNaming:ChannelSettingsItemList.kt$onPositiveClicked
+ ParameterNaming:ChannelSettingsItemList.kt$onSelected
+ ParameterNaming:CleanNodeDatabaseScreen.kt$onCheckedChanged
+ ParameterNaming:CleanNodeDatabaseScreen.kt$onDaysChanged
+ ParameterNaming:MapReportingPreference.kt$onMapReportingEnabledChanged
+ ParameterNaming:MapReportingPreference.kt$onPositionPrecisionChanged
+ ParameterNaming:MapReportingPreference.kt$onPublishIntervalSecsChanged
+ ParameterNaming:MapReportingPreference.kt$onShouldReportLocationChanged
+ PreviewPublic:MapReportingPreference.kt$MapReportingPreview
+ ReturnCount:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)
+ TooGenericExceptionCaught:LanguageUtils.kt$LanguageUtils$e: Exception
+ TooGenericExceptionCaught:RadioConfigViewModel.kt$RadioConfigViewModel$ex: Exception
+ TooManyFunctions:RadioConfigViewModel.kt$RadioConfigViewModel : ViewModel
+ UnusedParameter:ChannelSettingsItemList.kt$onBack: () -> Unit
+ UnusedParameter:ChannelSettingsItemList.kt$title: String
+ ViewModelInjection:DebugSearch.kt$viewModel
+
+
diff --git a/app/src/androidTest/java/com/geeksville/mesh/compose/DebugFiltersTest.kt b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugFiltersTest.kt
similarity index 82%
rename from app/src/androidTest/java/com/geeksville/mesh/compose/DebugFiltersTest.kt
rename to feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugFiltersTest.kt
index a894e69e8..82d19e45c 100644
--- a/app/src/androidTest/java/com/geeksville/mesh/compose/DebugFiltersTest.kt
+++ b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugFiltersTest.kt
@@ -15,11 +15,13 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.compose
+package org.meshtastic.feature.settings.debugging
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.assertIsDisplayed
@@ -31,11 +33,11 @@ import androidx.compose.ui.test.performTextInput
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
-import com.geeksville.mesh.ui.debug.FilterMode
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.meshtastic.core.strings.R
+import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog
@RunWith(AndroidJUnit4::class)
class DebugFiltersTest {
@@ -47,20 +49,19 @@ class DebugFiltersTest {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val filterLabel = context.getString(R.string.debug_filters)
composeTestRule.setContent {
- var filterTexts by
- androidx.compose.runtime.remember { androidx.compose.runtime.mutableStateOf(listOf()) }
- var customFilterText by androidx.compose.runtime.remember { androidx.compose.runtime.mutableStateOf("") }
+ var filterTexts by remember { mutableStateOf(listOf()) }
+ var customFilterText by remember { mutableStateOf("") }
val presetFilters = listOf("Error", "Warning", "Info")
val logs =
listOf(
- com.geeksville.mesh.model.DebugViewModel.UiMeshLog(
+ UiMeshLog(
uuid = "1",
messageType = "Info",
formattedReceivedDate = "2024-01-01 12:00:00",
logMessage = "Sample log message",
),
)
- com.geeksville.mesh.ui.debug.DebugFilterBar(
+ DebugFilterBar(
filterTexts = filterTexts,
onFilterTextsChange = { filterTexts = it },
customFilterText = customFilterText,
@@ -78,17 +79,16 @@ class DebugFiltersTest {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val activeFiltersLabel = context.getString(R.string.debug_active_filters)
composeTestRule.setContent {
- var filterTexts by
- androidx.compose.runtime.remember { androidx.compose.runtime.mutableStateOf(listOf()) }
- var customFilterText by androidx.compose.runtime.remember { androidx.compose.runtime.mutableStateOf("") }
+ var filterTexts by remember { mutableStateOf(listOf()) }
+ var customFilterText by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(16.dp)) {
- com.geeksville.mesh.ui.debug.DebugActiveFilters(
+ DebugActiveFilters(
filterTexts = filterTexts,
onFilterTextsChange = { filterTexts = it },
filterMode = FilterMode.OR,
onFilterModeChange = {},
)
- com.geeksville.mesh.ui.debug.DebugCustomFilterInput(
+ DebugCustomFilterInput(
customFilterText = customFilterText,
onCustomFilterTextChange = { customFilterText = it },
filterTexts = filterTexts,
@@ -111,9 +111,8 @@ class DebugFiltersTest {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val activeFiltersLabel = context.getString(R.string.debug_active_filters)
composeTestRule.setContent {
- var filterTexts by
- androidx.compose.runtime.remember { androidx.compose.runtime.mutableStateOf(listOf("A", "B")) }
- com.geeksville.mesh.ui.debug.DebugActiveFilters(
+ var filterTexts by remember { mutableStateOf(listOf("A", "B")) }
+ DebugActiveFilters(
filterTexts = filterTexts,
onFilterTextsChange = { filterTexts = it },
filterMode = FilterMode.OR,
diff --git a/app/src/androidTest/java/com/geeksville/mesh/compose/DebugSearchTest.kt b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugSearchTest.kt
similarity index 85%
rename from app/src/androidTest/java/com/geeksville/mesh/compose/DebugSearchTest.kt
rename to feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugSearchTest.kt
index 3024648cd..0ba49ad64 100644
--- a/app/src/androidTest/java/com/geeksville/mesh/compose/DebugSearchTest.kt
+++ b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugSearchTest.kt
@@ -15,12 +15,13 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.compose
+package org.meshtastic.feature.settings.debugging
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.assertIsDisplayed
@@ -32,13 +33,13 @@ import androidx.compose.ui.test.performTextInput
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
-import com.geeksville.mesh.model.LogSearchManager.SearchState
-import com.geeksville.mesh.ui.debug.DebugSearchBar
-import com.geeksville.mesh.ui.debug.FilterMode
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.meshtastic.core.strings.R
+import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog
+import org.meshtastic.feature.settings.debugging.LogSearchManager.SearchMatch
+import org.meshtastic.feature.settings.debugging.LogSearchManager.SearchState
@RunWith(AndroidJUnit4::class)
class DebugSearchTest {
@@ -66,7 +67,7 @@ class DebugSearchTest {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val placeholder = context.getString(R.string.debug_default_search)
composeTestRule.setContent {
- var searchText by androidx.compose.runtime.remember { mutableStateOf("test") }
+ var searchText by remember { mutableStateOf("test") }
DebugSearchBar(
searchState = SearchState(searchText = searchText),
onSearchTextChange = { searchText = it },
@@ -91,10 +92,7 @@ class DebugSearchTest {
SearchState(
searchText = searchText,
currentMatchIndex = currentMatchIndex,
- allMatches =
- List(matchCount) {
- com.geeksville.mesh.model.LogSearchManager.SearchMatch(it, 0, 6, "Packet")
- },
+ allMatches = List(matchCount) { SearchMatch(it, 0, 6, "Packet") },
hasMatches = true,
),
onSearchTextChange = {},
@@ -117,19 +115,19 @@ class DebugSearchTest {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val filterLabel = context.getString(R.string.debug_filters)
composeTestRule.setContent {
- var filterTexts by androidx.compose.runtime.remember { mutableStateOf(listOf()) }
- var customFilterText by androidx.compose.runtime.remember { mutableStateOf("") }
+ var filterTexts by remember { mutableStateOf(listOf()) }
+ var customFilterText by remember { mutableStateOf("") }
val presetFilters = listOf("Error", "Warning", "Info")
val logs =
listOf(
- com.geeksville.mesh.model.DebugViewModel.UiMeshLog(
+ UiMeshLog(
uuid = "1",
messageType = "Info",
formattedReceivedDate = "2024-01-01 12:00:00",
logMessage = "Sample log message",
),
)
- com.geeksville.mesh.ui.debug.DebugFilterBar(
+ DebugFilterBar(
filterTexts = filterTexts,
onFilterTextsChange = { filterTexts = it },
customFilterText = customFilterText,
@@ -147,16 +145,16 @@ class DebugSearchTest {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val activeFiltersLabel = context.getString(R.string.debug_active_filters)
composeTestRule.setContent {
- var filterTexts by androidx.compose.runtime.remember { mutableStateOf(listOf()) }
- var customFilterText by androidx.compose.runtime.remember { mutableStateOf("") }
+ var filterTexts by remember { mutableStateOf(listOf()) }
+ var customFilterText by remember { mutableStateOf("") }
Column(modifier = Modifier.padding(16.dp)) {
- com.geeksville.mesh.ui.debug.DebugActiveFilters(
+ DebugActiveFilters(
filterTexts = filterTexts,
onFilterTextsChange = { filterTexts = it },
filterMode = FilterMode.OR,
onFilterModeChange = {},
)
- com.geeksville.mesh.ui.debug.DebugCustomFilterInput(
+ DebugCustomFilterInput(
customFilterText = customFilterText,
onCustomFilterTextChange = { customFilterText = it },
filterTexts = filterTexts,
@@ -177,8 +175,8 @@ class DebugSearchTest {
val context = InstrumentationRegistry.getInstrumentation().targetContext
val activeFiltersLabel = context.getString(R.string.debug_active_filters)
composeTestRule.setContent {
- var filterTexts by androidx.compose.runtime.remember { mutableStateOf(listOf("A", "B")) }
- com.geeksville.mesh.ui.debug.DebugActiveFilters(
+ var filterTexts by remember { mutableStateOf(listOf("A", "B")) }
+ DebugActiveFilters(
filterTexts = filterTexts,
onFilterTextsChange = { filterTexts = it },
filterMode = FilterMode.OR,
diff --git a/app/src/androidTest/java/com/geeksville/mesh/compose/EditDeviceProfileDialogTest.kt b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialogTest.kt
similarity index 97%
rename from app/src/androidTest/java/com/geeksville/mesh/compose/EditDeviceProfileDialogTest.kt
rename to feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialogTest.kt
index a11fadc51..1f1495083 100644
--- a/app/src/androidTest/java/com/geeksville/mesh/compose/EditDeviceProfileDialogTest.kt
+++ b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialogTest.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.compose
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
@@ -26,7 +26,6 @@ import androidx.test.platform.app.InstrumentationRegistry
import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile
import com.geeksville.mesh.deviceProfile
import com.geeksville.mesh.position
-import com.geeksville.mesh.ui.settings.radio.components.EditDeviceProfileDialog
import org.junit.Assert
import org.junit.Rule
import org.junit.Test
diff --git a/app/src/androidTest/java/com/geeksville/mesh/compose/MapReportingPreferenceTest.kt b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreferenceTest.kt
similarity index 97%
rename from app/src/androidTest/java/com/geeksville/mesh/compose/MapReportingPreferenceTest.kt
rename to feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreferenceTest.kt
index 56ff5c707..e6ce58fae 100644
--- a/app/src/androidTest/java/com/geeksville/mesh/compose/MapReportingPreferenceTest.kt
+++ b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreferenceTest.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.compose
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.layout.Column
import androidx.compose.ui.platform.LocalFocusManager
@@ -26,7 +26,6 @@ import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
-import com.geeksville.mesh.ui.settings.radio.components.MapReportingPreference
import org.junit.Assert
import org.junit.Rule
import org.junit.Test
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsScreen.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt
similarity index 95%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/SettingsScreen.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt
index 3950ecb74..75d30c5a9 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsScreen.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings
+package org.meshtastic.feature.settings
import android.Manifest
import android.app.Activity
@@ -58,15 +58,7 @@ import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.geeksville.mesh.BuildConfig
import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile
-import com.geeksville.mesh.navigation.getNavRouteFrom
-import com.geeksville.mesh.ui.settings.radio.RadioConfigItemList
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
-import com.geeksville.mesh.ui.settings.radio.components.EditDeviceProfileDialog
-import com.geeksville.mesh.ui.settings.radio.components.PacketResponseStateDialog
-import com.geeksville.mesh.util.LanguageUtils
-import com.geeksville.mesh.util.LanguageUtils.getLanguageMap
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import kotlinx.coroutines.delay
@@ -80,6 +72,13 @@ import org.meshtastic.core.ui.component.SettingsItemDetail
import org.meshtastic.core.ui.component.SettingsItemSwitch
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.MODE_DYNAMIC
+import org.meshtastic.feature.settings.navigation.getNavRouteFrom
+import org.meshtastic.feature.settings.radio.RadioConfigItemList
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
+import org.meshtastic.feature.settings.radio.component.EditDeviceProfileDialog
+import org.meshtastic.feature.settings.radio.component.PacketResponseStateDialog
+import org.meshtastic.feature.settings.util.LanguageUtils
+import org.meshtastic.feature.settings.util.LanguageUtils.getLanguageMap
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@@ -371,7 +370,12 @@ fun SettingsScreen(
settingsLauncher.launch(intent)
}
- AppVersionButton(excludedModulesUnlocked) { settingsViewModel.unlockExcludedModules() }
+ AppVersionButton(
+ excludedModulesUnlocked = excludedModulesUnlocked,
+ appVersionName = settingsViewModel.appVersionName,
+ ) {
+ settingsViewModel.unlockExcludedModules()
+ }
}
}
}
@@ -383,7 +387,11 @@ private const val UNLOCK_TIMEOUT_SECONDS = 1 // Timeout in seconds to reset the
/** A button to display the app version. Clicking it 5 times will unlock the excluded modules. */
@Composable
-private fun AppVersionButton(excludedModulesUnlocked: Boolean, onUnlockExcludedModules: () -> Unit) {
+private fun AppVersionButton(
+ excludedModulesUnlocked: Boolean,
+ appVersionName: String,
+ onUnlockExcludedModules: () -> Unit,
+) {
val context = LocalContext.current
var clickCount by remember { mutableIntStateOf(0) }
@@ -397,7 +405,7 @@ private fun AppVersionButton(excludedModulesUnlocked: Boolean, onUnlockExcludedM
SettingsItemDetail(
text = stringResource(R.string.app_version),
icon = Icons.Rounded.Memory,
- trailingText = BuildConfig.VERSION_NAME,
+ trailingText = appVersionName,
) {
clickCount = clickCount.inc().coerceIn(0, UNLOCK_CLICK_COUNT)
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsViewModel.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsViewModel.kt
index 78f3791d6..e09bb1de8 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsViewModel.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings
+package org.meshtastic.feature.settings
import android.app.Application
import android.net.Uri
@@ -38,6 +38,7 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
+import org.meshtastic.core.common.BuildConfigProvider
import org.meshtastic.core.data.repository.MeshLogRepository
import org.meshtastic.core.data.repository.NodeRepository
import org.meshtastic.core.data.repository.RadioConfigRepository
@@ -70,6 +71,7 @@ constructor(
private val meshLogRepository: MeshLogRepository,
private val uiPrefs: UiPrefs,
private val uiPreferencesDataSource: UiPreferencesDataSource,
+ private val buildConfigProvider: BuildConfigProvider,
) : ViewModel() {
val myNodeInfo: StateFlow = nodeRepository.myNodeInfo
@@ -108,6 +110,9 @@ constructor(
private val _excludedModulesUnlocked = MutableStateFlow(false)
val excludedModulesUnlocked: StateFlow = _excludedModulesUnlocked.asStateFlow()
+ val appVersionName
+ get() = buildConfigProvider.versionName
+
fun setProvideLocation(value: Boolean) {
myNodeNum?.let { uiPrefs.setShouldProvideNodeLocation(it, value) }
}
diff --git a/app/src/main/java/com/geeksville/mesh/ui/debug/Debug.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/ui/debug/Debug.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt
index aad95916e..f2b7cd9ec 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/debug/Debug.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.debug
+package org.meshtastic.feature.settings.debugging
import android.content.Context
import android.net.Uri
@@ -75,11 +75,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import androidx.datastore.core.IOException
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.geeksville.mesh.model.DebugViewModel
-import com.geeksville.mesh.model.DebugViewModel.UiMeshLog
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -90,7 +87,9 @@ 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.feature.settings.debugging.DebugViewModel.UiMeshLog
import timber.log.Timber
+import java.io.IOException
import java.io.OutputStreamWriter
import java.nio.charset.StandardCharsets
import java.text.SimpleDateFormat
diff --git a/app/src/main/java/com/geeksville/mesh/ui/debug/DebugFilters.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugFilters.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/debug/DebugFilters.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugFilters.kt
index 5aa6a5e0a..2da02d439 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/debug/DebugFilters.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugFilters.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.debug
+package org.meshtastic.feature.settings.debugging
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -56,8 +56,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
-import com.geeksville.mesh.model.DebugViewModel.UiMeshLog
import org.meshtastic.core.strings.R
+import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog
@Composable
fun DebugCustomFilterInput(
diff --git a/app/src/main/java/com/geeksville/mesh/ui/debug/DebugSearch.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugSearch.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/debug/DebugSearch.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugSearch.kt
index 700f9cf9a..31283ce5e 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/debug/DebugSearch.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugSearch.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.debug
+package org.meshtastic.feature.settings.debugging
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -53,12 +53,11 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
-import com.geeksville.mesh.model.DebugViewModel
-import com.geeksville.mesh.model.DebugViewModel.UiMeshLog
-import com.geeksville.mesh.model.LogSearchManager.SearchMatch
-import com.geeksville.mesh.model.LogSearchManager.SearchState
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.theme.AppTheme
+import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog
+import org.meshtastic.feature.settings.debugging.LogSearchManager.SearchMatch
+import org.meshtastic.feature.settings.debugging.LogSearchManager.SearchState
@Composable
internal fun DebugSearchNavigation(
diff --git a/app/src/main/java/com/geeksville/mesh/model/DebugViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModel.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/model/DebugViewModel.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModel.kt
index a26588d90..f3e582348 100644
--- a/app/src/main/java/com/geeksville/mesh/model/DebugViewModel.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModel.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.model
+package org.meshtastic.feature.settings.debugging
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
@@ -26,7 +26,6 @@ import com.geeksville.mesh.PaxcountProtos
import com.geeksville.mesh.Portnums.PortNum
import com.geeksville.mesh.StoreAndForwardProtos
import com.geeksville.mesh.TelemetryProtos
-import com.geeksville.mesh.ui.debug.FilterMode
import com.google.protobuf.InvalidProtocolBufferException
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.ImmutableList
diff --git a/app/src/main/java/com/geeksville/mesh/navigation/SettingsNavigation.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt
similarity index 90%
rename from app/src/main/java/com/geeksville/mesh/navigation/SettingsNavigation.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt
index 26eb67200..a5233615c 100644
--- a/app/src/main/java/com/geeksville/mesh/navigation/SettingsNavigation.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.navigation
+package org.meshtastic.feature.settings.navigation
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
@@ -57,38 +57,38 @@ import androidx.navigation.navDeepLink
import androidx.navigation.navigation
import com.geeksville.mesh.AdminProtos
import com.geeksville.mesh.MeshProtos.DeviceMetadata
-import com.geeksville.mesh.ui.debug.DebugScreen
-import com.geeksville.mesh.ui.settings.SettingsScreen
-import com.geeksville.mesh.ui.settings.radio.CleanNodeDatabaseScreen
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
-import com.geeksville.mesh.ui.settings.radio.components.AmbientLightingConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.AudioConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.BluetoothConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.CannedMessageConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.ChannelConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.DetectionSensorConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.DeviceConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.DisplayConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.ExternalNotificationConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.LoRaConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.MQTTConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.NeighborInfoConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.NetworkConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.PaxcounterConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.PositionConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.PowerConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.RangeTestConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.RemoteHardwareConfigScreen
-import com.geeksville.mesh.ui.settings.radio.components.SecurityConfigScreen
-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
import org.meshtastic.core.strings.R
+import org.meshtastic.feature.settings.SettingsScreen
+import org.meshtastic.feature.settings.debugging.DebugScreen
+import org.meshtastic.feature.settings.radio.CleanNodeDatabaseScreen
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
+import org.meshtastic.feature.settings.radio.component.AmbientLightingConfigScreen
+import org.meshtastic.feature.settings.radio.component.AudioConfigScreen
+import org.meshtastic.feature.settings.radio.component.BluetoothConfigScreen
+import org.meshtastic.feature.settings.radio.component.CannedMessageConfigScreen
+import org.meshtastic.feature.settings.radio.component.ChannelConfigScreen
+import org.meshtastic.feature.settings.radio.component.DetectionSensorConfigScreen
+import org.meshtastic.feature.settings.radio.component.DeviceConfigScreen
+import org.meshtastic.feature.settings.radio.component.DisplayConfigScreen
+import org.meshtastic.feature.settings.radio.component.ExternalNotificationConfigScreen
+import org.meshtastic.feature.settings.radio.component.LoRaConfigScreen
+import org.meshtastic.feature.settings.radio.component.MQTTConfigScreen
+import org.meshtastic.feature.settings.radio.component.NeighborInfoConfigScreen
+import org.meshtastic.feature.settings.radio.component.NetworkConfigScreen
+import org.meshtastic.feature.settings.radio.component.PaxcounterConfigScreen
+import org.meshtastic.feature.settings.radio.component.PositionConfigScreen
+import org.meshtastic.feature.settings.radio.component.PowerConfigScreen
+import org.meshtastic.feature.settings.radio.component.RangeTestConfigScreen
+import org.meshtastic.feature.settings.radio.component.RemoteHardwareConfigScreen
+import org.meshtastic.feature.settings.radio.component.SecurityConfigScreen
+import org.meshtastic.feature.settings.radio.component.SerialConfigScreen
+import org.meshtastic.feature.settings.radio.component.StoreForwardConfigScreen
+import org.meshtastic.feature.settings.radio.component.TelemetryConfigScreen
+import org.meshtastic.feature.settings.radio.component.UserConfigScreen
fun getNavRouteFrom(routeName: String): Route? =
ConfigRoute.entries.find { it.name == routeName }?.route ?: ModuleRoute.entries.find { it.name == routeName }?.route
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseScreen.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseScreen.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseScreen.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseScreen.kt
index a6423c681..a7d4f9c38 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseScreen.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseScreen.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio
+package org.meshtastic.feature.settings.radio
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseViewModel.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt
index 54adbef68..1b616102b 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseViewModel.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio
+package org.meshtastic.feature.settings.radio
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfig.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt
similarity index 96%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfig.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt
index 1a63250c2..b5b6361cc 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfig.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio
+package org.meshtastic.feature.settings.radio
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column
@@ -42,9 +42,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import com.geeksville.mesh.navigation.ConfigRoute
-import com.geeksville.mesh.navigation.ModuleRoute
-import com.geeksville.mesh.ui.settings.radio.components.WarningDialog
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.strings.R
@@ -52,6 +49,9 @@ import org.meshtastic.core.ui.component.SettingsItem
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.theme.AppTheme
import org.meshtastic.core.ui.theme.StatusColors.StatusRed
+import org.meshtastic.feature.settings.navigation.ConfigRoute
+import org.meshtastic.feature.settings.navigation.ModuleRoute
+import org.meshtastic.feature.settings.radio.component.WarningDialog
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt
index f17653293..e2e3cd694 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio
+package org.meshtastic.feature.settings.radio
import android.Manifest
import android.app.Application
@@ -42,12 +42,7 @@ import com.geeksville.mesh.ModuleConfigProtos
import com.geeksville.mesh.Portnums
import com.geeksville.mesh.config
import com.geeksville.mesh.deviceProfile
-import com.geeksville.mesh.model.getChannelList
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.navigation.ConfigRoute
-import com.geeksville.mesh.navigation.ModuleRoute
-import com.geeksville.mesh.repository.location.LocationRepository
-import com.geeksville.mesh.util.UiText
import com.google.protobuf.MessageLite
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
@@ -63,6 +58,7 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
+import org.meshtastic.core.data.repository.LocationRepository
import org.meshtastic.core.data.repository.NodeRepository
import org.meshtastic.core.data.repository.RadioConfigRepository
import org.meshtastic.core.database.entity.MyNodeEntity
@@ -73,10 +69,14 @@ import org.meshtastic.core.model.util.toChannelSet
import org.meshtastic.core.navigation.SettingsRoutes
import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
import org.meshtastic.core.prefs.map.MapConsentPrefs
+import org.meshtastic.core.proto.getChannelList
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.service.IMeshService
import org.meshtastic.core.service.ServiceRepository
import org.meshtastic.core.strings.R
+import org.meshtastic.feature.settings.navigation.ConfigRoute
+import org.meshtastic.feature.settings.navigation.ModuleRoute
+import org.meshtastic.feature.settings.util.UiText
import timber.log.Timber
import java.io.FileOutputStream
import javax.inject.Inject
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/ResponseState.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/ResponseState.kt
similarity index 92%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/ResponseState.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/ResponseState.kt
index d9e59dce1..8c6df952a 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/ResponseState.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/ResponseState.kt
@@ -15,9 +15,9 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio
+package org.meshtastic.feature.settings.radio
-import com.geeksville.mesh.util.UiText
+import org.meshtastic.feature.settings.util.UiText
/** Generic sealed class defines each possible state of a response. */
sealed class ResponseState {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AmbientLightingConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AmbientLightingConfigItemList.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AmbientLightingConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AmbientLightingConfigItemList.kt
index e0f49b71f..34beef468 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AmbientLightingConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AmbientLightingConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -28,11 +28,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun AmbientLightingConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AudioConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AudioConfigItemList.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AudioConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AudioConfigItemList.kt
index fed6e3562..8f5c0e4fc 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AudioConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AudioConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -29,12 +29,12 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.AudioConfig
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun AudioConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/BluetoothConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/BluetoothConfigItemList.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/BluetoothConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/BluetoothConfigItemList.kt
index e535bed80..2631b445b 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/BluetoothConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/BluetoothConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -29,12 +29,12 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ConfigProtos.Config.BluetoothConfig
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun BluetoothConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/CannedMessageConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/CannedMessageConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/CannedMessageConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/CannedMessageConfigItemList.kt
index 6c4b09e70..bea528626 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/CannedMessageConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/CannedMessageConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
@@ -35,12 +35,12 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.CannedMessageConfig
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun CannedMessageConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelLegend.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ChannelLegend.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelLegend.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ChannelLegend.kt
index 2e19d3644..8c8751d86 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelLegend.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ChannelLegend.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.annotation.StringRes
import androidx.compose.foundation.clickable
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelSettingsItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ChannelSettingsItemList.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelSettingsItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ChannelSettingsItemList.kt
index 6520898fe..f028afca2 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelSettingsItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ChannelSettingsItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.FastOutSlowInEasing
@@ -73,7 +73,6 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ChannelProtos.ChannelSettings
import com.geeksville.mesh.ConfigProtos.Config.LoRaConfig
import com.geeksville.mesh.channelSettings
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.model.Channel
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.R
@@ -83,6 +82,7 @@ import org.meshtastic.core.ui.component.SecurityIcon
import org.meshtastic.core.ui.component.dragContainer
import org.meshtastic.core.ui.component.dragDropItemsIndexed
import org.meshtastic.core.ui.component.rememberDragDropState
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
private fun ChannelItem(
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ConfigState.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ConfigState.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ConfigState.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ConfigState.kt
index 62a0498d5..94da1a977 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ConfigState.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ConfigState.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/DetectionSensorConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/DetectionSensorConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt
index 4da4725d5..a7a208d18 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/DetectionSensorConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
@@ -32,12 +32,12 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun DetectionSensorConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/DeviceConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/DeviceConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt
index 2e7263314..3563fea39 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/DeviceConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
@@ -50,12 +50,12 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ConfigProtos.Config.DeviceConfig
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
private val DeviceConfig.Role.description: Int
get() =
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/DisplayConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/DisplayConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt
index f567834f9..a6bdddbc6 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/DisplayConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -29,12 +29,12 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ConfigProtos.Config.DisplayConfig
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun DisplayConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/EditChannelDialog.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditChannelDialog.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/EditChannelDialog.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditChannelDialog.kt
index 04257bb9e..abd6f413a 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/EditChannelDialog.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditChannelDialog.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/EditDeviceProfileDialog.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialog.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/EditDeviceProfileDialog.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialog.kt
index b9601e168..7278ef9d4 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/EditDeviceProfileDialog.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialog.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ExternalNotificationConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ExternalNotificationConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt
index c35c3a4c7..3f93d259c 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ExternalNotificationConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
@@ -34,12 +34,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TextDividerPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun ExternalNotificationConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/LoRaConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/LoRaConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/LoRaConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/LoRaConfigItemList.kt
index a6deea4a9..c77746549 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/LoRaConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/LoRaConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
@@ -35,7 +35,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.model.Channel
import org.meshtastic.core.model.ChannelOption
import org.meshtastic.core.model.RegionInfo
@@ -47,6 +46,7 @@ import org.meshtastic.core.ui.component.PreferenceDivider
import org.meshtastic.core.ui.component.SignedIntegerEditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
import org.meshtastic.core.ui.component.TitledCard
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun LoRaConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/MQTTConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/MQTTConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.kt
index 01cadf8e8..7539822be 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/MQTTConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.kt
@@ -17,7 +17,7 @@
@file:Suppress("LongMethod")
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
@@ -33,12 +33,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditPasswordPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun MQTTConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/MapReportingPreference.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/MapReportingPreference.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt
index 8d5d1b610..2007e848f 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/MapReportingPreference.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/NeighborInfoConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NeighborInfoConfigItemList.kt
similarity index 96%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/NeighborInfoConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NeighborInfoConfigItemList.kt
index d09d870a7..fc4da425b 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/NeighborInfoConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NeighborInfoConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -28,11 +28,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun NeighborInfoConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/NetworkConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NetworkConfigItemList.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/NetworkConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NetworkConfigItemList.kt
index 3619ae91b..e90b8ed49 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/NetworkConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NetworkConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.compose.foundation.layout.fillMaxWidth
@@ -43,7 +43,6 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ConfigProtos.Config.NetworkConfig
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanOptions
import org.meshtastic.core.strings.R
@@ -54,6 +53,7 @@ import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SimpleAlertDialog
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
private fun ScanErrorDialog(onDismiss: () -> Unit = {}) =
diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NodeActionButton.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NodeActionButton.kt
new file mode 100644
index 000000000..804ae8f4a
--- /dev/null
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NodeActionButton.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.feature.settings.radio.component
+
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.Button
+import androidx.compose.material3.Icon
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.dp
+
+@Composable
+fun NodeActionButton(
+ modifier: Modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp).height(48.dp),
+ title: String,
+ enabled: Boolean,
+ icon: ImageVector? = null,
+ iconTint: Color? = null,
+ onClick: () -> Unit,
+) {
+ Button(onClick = { onClick() }, enabled = enabled, modifier = modifier) {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ if (icon != null) {
+ Icon(
+ imageVector = icon,
+ contentDescription = title,
+ modifier = Modifier.size(24.dp),
+ tint = iconTint ?: LocalContentColor.current,
+ )
+ Spacer(modifier = Modifier.width(8.dp))
+ }
+ Text(text = title, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.weight(1f))
+ }
+ }
+}
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PacketResponseStateDialog.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PacketResponseStateDialog.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PacketResponseStateDialog.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PacketResponseStateDialog.kt
index e3ad7e26e..d10287b03 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PacketResponseStateDialog.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PacketResponseStateDialog.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.compose.animation.core.animateFloatAsState
@@ -36,8 +36,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import com.geeksville.mesh.ui.settings.radio.ResponseState
import org.meshtastic.core.strings.R
+import org.meshtastic.feature.settings.radio.ResponseState
@Composable
fun PacketResponseStateDialog(state: ResponseState, onDismiss: () -> Unit = {}, onComplete: () -> Unit = {}) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PaxcounterConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PaxcounterConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt
index d5d635b2f..dbce6cc57 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PaxcounterConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -28,12 +28,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SignedIntegerEditTextPreference
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun PaxcounterConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt
similarity index 99%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt
index b53ed04e2..c4d963f2f 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import android.Manifest
import android.annotation.SuppressLint
@@ -43,7 +43,6 @@ import com.geeksville.mesh.ConfigProtos
import com.geeksville.mesh.ConfigProtos.Config.PositionConfig
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberPermissionState
import kotlinx.coroutines.launch
@@ -54,6 +53,7 @@ import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@OptIn(ExperimentalPermissionsApi::class)
@Composable
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PowerConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PowerConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt
index 5e18b4a6d..2d2bb3ec2 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PowerConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -28,11 +28,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun PowerConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/RadioConfigScreenList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RadioConfigScreenList.kt
similarity index 96%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/RadioConfigScreenList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RadioConfigScreenList.kt
index 7398032c5..a037c1462 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/RadioConfigScreenList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RadioConfigScreenList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
@@ -29,11 +29,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
-import com.geeksville.mesh.ui.settings.radio.ResponseState
import com.google.protobuf.MessageLite
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.core.ui.component.PreferenceFooter
+import org.meshtastic.feature.settings.radio.ResponseState
@Composable
fun RadioConfigScreenList(
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/RangeTestConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt
similarity index 96%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/RangeTestConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt
index 11d54dd81..abda41b83 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/RangeTestConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -28,11 +28,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun RangeTestConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/RemoteHardwareConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RemoteHardwareConfigItemList.kt
similarity index 96%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/RemoteHardwareConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RemoteHardwareConfigItemList.kt
index bf0d7ce3d..8d72dc097 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/RemoteHardwareConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RemoteHardwareConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -28,11 +28,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditListPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun RemoteHardwareConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/SecurityConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SecurityConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/SecurityConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SecurityConfigItemList.kt
index 289c30535..b4757f863 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/SecurityConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SecurityConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import android.app.Activity
import android.content.Intent
@@ -46,8 +46,6 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ConfigProtos.Config.SecurityConfig
import com.geeksville.mesh.config
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.node.NodeActionButton
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import com.google.protobuf.ByteString
import org.meshtastic.core.model.util.encodeToString
import org.meshtastic.core.model.util.toByteString
@@ -57,6 +55,7 @@ import org.meshtastic.core.ui.component.EditBase64Preference
import org.meshtastic.core.ui.component.EditListPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
import java.security.SecureRandom
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/SerialConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SerialConfigItemList.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/SerialConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SerialConfigItemList.kt
index 370da2c49..b56c7e737 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/SerialConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SerialConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -29,12 +29,12 @@ import androidx.navigation.NavController
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.SerialConfig
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.DropDownPreference
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun SerialConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/StoreForwardConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StoreForwardConfigItemList.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/StoreForwardConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StoreForwardConfigItemList.kt
index ad88360a1..ef1b187d5 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/StoreForwardConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StoreForwardConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -28,11 +28,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun StoreForwardConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt
similarity index 98%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt
index 777714ece..54a760b26 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.HorizontalDivider
@@ -28,11 +28,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
import com.geeksville.mesh.moduleConfig
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.strings.R
import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun TelemetryConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/UserConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/UserConfigItemList.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/UserConfigItemList.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/UserConfigItemList.kt
index 9be4f52a8..96da4ddb5 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/UserConfigItemList.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/UserConfigItemList.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
@@ -30,7 +30,6 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.geeksville.mesh.copy
-import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel
import org.meshtastic.core.database.model.isUnmessageableRole
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.strings.R
@@ -38,6 +37,7 @@ import org.meshtastic.core.ui.component.EditTextPreference
import org.meshtastic.core.ui.component.PreferenceCategory
import org.meshtastic.core.ui.component.RegularPreference
import org.meshtastic.core.ui.component.SwitchPreference
+import org.meshtastic.feature.settings.radio.RadioConfigViewModel
@Composable
fun UserConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel()) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/WarningDialog.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/WarningDialog.kt
similarity index 97%
rename from app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/WarningDialog.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/WarningDialog.kt
index 71cc9e527..d701440dc 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/WarningDialog.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/WarningDialog.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.ui.settings.radio.components
+package org.meshtastic.feature.settings.radio.component
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Warning
diff --git a/app/src/main/java/com/geeksville/mesh/util/LanguageUtils.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/LanguageUtils.kt
similarity index 95%
rename from app/src/main/java/com/geeksville/mesh/util/LanguageUtils.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/LanguageUtils.kt
index 98919d104..3e310ced5 100644
--- a/app/src/main/java/com/geeksville/mesh/util/LanguageUtils.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/LanguageUtils.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.util
+package org.meshtastic.feature.settings.util
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
@@ -46,7 +46,7 @@ object LanguageUtils {
add(SYSTEM_DEFAULT)
try {
- resources.getXml(com.geeksville.mesh.R.xml.locales_config).use { parser ->
+ resources.getXml(org.meshtastic.feature.settings.R.xml.locales_config).use { parser ->
while (parser.eventType != XmlPullParser.END_DOCUMENT) {
if (parser.eventType == XmlPullParser.START_TAG && parser.name == "locale") {
val languageTag =
diff --git a/app/src/main/java/com/geeksville/mesh/util/UiText.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/UiText.kt
similarity index 73%
rename from app/src/main/java/com/geeksville/mesh/util/UiText.kt
rename to feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/UiText.kt
index 47912b64f..b92ff1546 100644
--- a/app/src/main/java/com/geeksville/mesh/util/UiText.kt
+++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/UiText.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.util
+package org.meshtastic.feature.settings.util
import android.content.Context
import androidx.annotation.StringRes
@@ -25,20 +25,17 @@ import androidx.compose.ui.res.stringResource
@Suppress("SpreadOperator")
sealed class UiText {
data class DynamicString(val value: String) : UiText()
+
class StringResource(@StringRes val resId: Int, vararg val args: Any) : UiText()
@Composable
- fun asString(): String {
- return when (this) {
- is DynamicString -> value
- is StringResource -> stringResource(resId, *args)
- }
+ fun asString(): String = when (this) {
+ is DynamicString -> value
+ is StringResource -> stringResource(resId, *args)
}
- fun asString(context: Context): String {
- return when (this) {
- is DynamicString -> value
- is StringResource -> context.getString(resId, *args)
- }
+ fun asString(context: Context): String = when (this) {
+ is DynamicString -> value
+ is StringResource -> context.getString(resId, *args)
}
}
diff --git a/app/src/main/res/xml/locales_config.xml b/feature/settings/src/main/res/xml/locales_config.xml
similarity index 100%
rename from app/src/main/res/xml/locales_config.xml
rename to feature/settings/src/main/res/xml/locales_config.xml
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 7de9fcdea..46ac9f060 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -34,6 +34,7 @@ include(
":feature:intro",
":feature:map",
":feature:node",
+ ":feature:settings",
":mesh_service_example",
)
rootProject.name = "MeshtasticAndroid"