mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
Modularize settings code (#3355)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
parent
4613a26c9d
commit
95ec4877df
75 changed files with 444 additions and 358 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -8,10 +8,6 @@
|
|||
<ID>CommentWrapping:SignalMetrics.kt$Metric.SNR$/* Selected 12 as the max to get 4 equal vertical sections. */</ID>
|
||||
<ID>ComposableNaming:NodeDetailScreen.kt$notesSection</ID>
|
||||
<ID>ComposableParamOrder:Channel.kt$ChannelScreen</ID>
|
||||
<ID>ComposableParamOrder:ChannelSettingsItemList.kt$ChannelSettingsItemList</ID>
|
||||
<ID>ComposableParamOrder:Debug.kt$DecodedPayloadBlock</ID>
|
||||
<ID>ComposableParamOrder:DebugSearch.kt$DebugSearchState</ID>
|
||||
<ID>ComposableParamOrder:DebugSearch.kt$DebugSearchStateviewModelDefaults</ID>
|
||||
<ID>ComposableParamOrder:DeviceMetrics.kt$DeviceMetricsChart</ID>
|
||||
<ID>ComposableParamOrder:EmptyStateContent.kt$EmptyStateContent</ID>
|
||||
<ID>ComposableParamOrder:EnvironmentCharts.kt$ChartContent</ID>
|
||||
|
|
@ -19,7 +15,6 @@
|
|||
<ID>ComposableParamOrder:EnvironmentCharts.kt$MetricPlottingCanvas</ID>
|
||||
<ID>ComposableParamOrder:HostMetricsLog.kt$HostMetricsItem</ID>
|
||||
<ID>ComposableParamOrder:HostMetricsLog.kt$LogLine</ID>
|
||||
<ID>ComposableParamOrder:MapReportingPreference.kt$MapReportingPreference</ID>
|
||||
<ID>ComposableParamOrder:Message.kt$MessageScreen</ID>
|
||||
<ID>ComposableParamOrder:Message.kt$QuickChatRow</ID>
|
||||
<ID>ComposableParamOrder:MessageActions.kt$MessageActions</ID>
|
||||
|
|
@ -29,7 +24,6 @@
|
|||
<ID>ComposableParamOrder:MessageList.kt$MessageList</ID>
|
||||
<ID>ComposableParamOrder:NodeDetailScreen.kt$DeviceActions</ID>
|
||||
<ID>ComposableParamOrder:NodeDetailScreen.kt$EnvironmentMetrics</ID>
|
||||
<ID>ComposableParamOrder:NodeDetailScreen.kt$NodeActionButton</ID>
|
||||
<ID>ComposableParamOrder:NodeDetailScreen.kt$NodeDetailList</ID>
|
||||
<ID>ComposableParamOrder:PaxMetrics.kt$PaxMetricsChart</ID>
|
||||
<ID>ComposableParamOrder:PowerMetrics.kt$PowerMetricsChart</ID>
|
||||
|
|
@ -37,11 +31,7 @@
|
|||
<ID>ComposableParamOrder:Share.kt$ShareScreen</ID>
|
||||
<ID>ComposableParamOrder:SignalMetrics.kt$SignalMetricsChart</ID>
|
||||
<ID>ComposableParamOrder:TopLevelNavIcon.kt$ConnectionsNavIcon</ID>
|
||||
<ID>ComposableParamOrder:WarningDialog.kt$WarningDialog</ID>
|
||||
<ID>CyclomaticComplexMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket)</ID>
|
||||
<ID>CyclomaticComplexMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>CyclomaticComplexMethod:PositionConfigItemList.kt$@OptIn(ExperimentalPermissionsApi::class) @Composable fun PositionConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>CyclomaticComplexMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)</ID>
|
||||
<ID>EmptyClassBlock:DebugLogFile.kt$BinaryLogFile${ }</ID>
|
||||
<ID>EmptyFunctionBlock:NopInterface.kt$NopInterface${ }</ID>
|
||||
<ID>EmptyFunctionBlock:NsdManager.kt$<no name provided>${ }</ID>
|
||||
|
|
@ -71,44 +61,20 @@
|
|||
<ID>LambdaParameterEventTrailing:Message.kt$onClick</ID>
|
||||
<ID>LambdaParameterEventTrailing:Message.kt$onSendMessage</ID>
|
||||
<ID>LambdaParameterEventTrailing:MessageList.kt$onReply</ID>
|
||||
<ID>LambdaParameterEventTrailing:NodeDetailScreen.kt$onClick</ID>
|
||||
<ID>LambdaParameterEventTrailing:NodeDetailScreen.kt$onSaveNotes</ID>
|
||||
<ID>LambdaParameterEventTrailing:QuickChat.kt$onNavigateUp</ID>
|
||||
<ID>LambdaParameterEventTrailing:TracerouteLog.kt$onNavigateUp</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:Channel.kt$onConfirm</ID>
|
||||
<ID>LambdaParameterInRestartableEffect:MessageList.kt$onUnreadChanged</ID>
|
||||
<ID>LargeClass:MeshService.kt$MeshService : Service</ID>
|
||||
<ID>LongMethod:AmbientLightingConfigItemList.kt$@Composable fun AmbientLightingConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:AudioConfigItemList.kt$@Composable fun AudioConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:CannedMessageConfigItemList.kt$@Composable fun CannedMessageConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:DetectionSensorConfigItemList.kt$@Composable fun DetectionSensorConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:DeviceConfigItemList.kt$@Composable fun DeviceConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:DisplayConfigItemList.kt$@Composable fun DisplayConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:EnvironmentMetrics.kt$@Composable fun EnvironmentMetricsScreen(viewModel: MetricsViewModel = hiltViewModel(), onNavigateUp: () -> Unit)</ID>
|
||||
<ID>LongMethod:ExternalNotificationConfigItemList.kt$@Composable fun ExternalNotificationConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:LoRaConfigItemList.kt$@Composable fun LoRaConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket)</ID>
|
||||
<ID>LongMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:PositionConfigItemList.kt$@OptIn(ExperimentalPermissionsApi::class) @Composable fun PositionConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:PowerConfigItemList.kt$@Composable fun PowerConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)</ID>
|
||||
<ID>LongMethod:SecurityConfigItemList.kt$@OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable fun SecurityConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:SerialConfigItemList.kt$@Composable fun SerialConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:StoreForwardConfigItemList.kt$@Composable fun StoreForwardConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:TelemetryConfigItemList.kt$@Composable fun TelemetryConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:UserConfigItemList.kt$@Composable fun UserConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>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, )</ID>
|
||||
<ID>MagicNumber:BluetoothInterface.kt$BluetoothInterface$1000</ID>
|
||||
<ID>MagicNumber:BluetoothInterface.kt$BluetoothInterface$500</ID>
|
||||
<ID>MagicNumber:BluetoothInterface.kt$BluetoothInterface$512</ID>
|
||||
<ID>MagicNumber:Contacts.kt$7</ID>
|
||||
<ID>MagicNumber:Contacts.kt$8</ID>
|
||||
<ID>MagicNumber:Debug.kt$3</ID>
|
||||
<ID>MagicNumber:EditChannelDialog.kt$16</ID>
|
||||
<ID>MagicNumber:EditChannelDialog.kt$32</ID>
|
||||
<ID>MagicNumber:LocationRepository.kt$LocationRepository$1000L</ID>
|
||||
<ID>MagicNumber:LocationRepository.kt$LocationRepository$30</ID>
|
||||
<ID>MagicNumber:LocationRepository.kt$LocationRepository$31</ID>
|
||||
<ID>MagicNumber:MQTTRepository.kt$MQTTRepository$512</ID>
|
||||
<ID>MagicNumber:MeshService.kt$MeshService$0xffffffff</ID>
|
||||
<ID>MagicNumber:MeshService.kt$MeshService$1000</ID>
|
||||
|
|
@ -122,8 +88,6 @@
|
|||
<ID>MagicNumber:MetricsViewModel.kt$MetricsViewModel$1000L</ID>
|
||||
<ID>MagicNumber:MetricsViewModel.kt$MetricsViewModel$1e-5</ID>
|
||||
<ID>MagicNumber:MetricsViewModel.kt$MetricsViewModel$1e-7</ID>
|
||||
<ID>MagicNumber:PacketResponseStateDialog.kt$100</ID>
|
||||
<ID>MagicNumber:PowerConfigItemList.kt$3600</ID>
|
||||
<ID>MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$21972</ID>
|
||||
<ID>MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$32809</ID>
|
||||
<ID>MagicNumber:ProbeTableProvider.kt$ProbeTableProvider$6790</ID>
|
||||
|
|
@ -149,8 +113,6 @@
|
|||
<ID>ModifierClickableOrder:Channel.kt$clickable(onClick = onClick)</ID>
|
||||
<ID>ModifierMissing:BLEDevices.kt$BLEDevices</ID>
|
||||
<ID>ModifierMissing:Channel.kt$ChannelScreen</ID>
|
||||
<ID>ModifierMissing:ChannelSettingsItemList.kt$ChannelSelection</ID>
|
||||
<ID>ModifierMissing:CleanNodeDatabaseScreen.kt$CleanNodeDatabaseScreen</ID>
|
||||
<ID>ModifierMissing:CommonCharts.kt$ChartHeader</ID>
|
||||
<ID>ModifierMissing:CommonCharts.kt$Legend</ID>
|
||||
<ID>ModifierMissing:CommonCharts.kt$TimeLabels</ID>
|
||||
|
|
@ -162,26 +124,18 @@
|
|||
<ID>ModifierMissing:EmptyStateContent.kt$EmptyStateContent</ID>
|
||||
<ID>ModifierMissing:EnvironmentMetrics.kt$EnvironmentMetricsScreen</ID>
|
||||
<ID>ModifierMissing:HostMetricsLog.kt$HostMetricsLogScreen</ID>
|
||||
<ID>ModifierMissing:LoRaConfigItemList.kt$LoRaConfigScreen</ID>
|
||||
<ID>ModifierMissing:Main.kt$MainScreen</ID>
|
||||
<ID>ModifierMissing:MapReportingPreference.kt$MapReportingPreference</ID>
|
||||
<ID>ModifierMissing:MessageActions.kt$MessageStatusButton</ID>
|
||||
<ID>ModifierMissing:MessageActions.kt$ReactionButton</ID>
|
||||
<ID>ModifierMissing:MessageActions.kt$ReplyButton</ID>
|
||||
<ID>ModifierMissing:NetworkConfigItemList.kt$NetworkConfigScreen</ID>
|
||||
<ID>ModifierMissing:NetworkDevices.kt$NetworkDevices</ID>
|
||||
<ID>ModifierMissing:NodeListScreen.kt$NodeListScreen</ID>
|
||||
<ID>ModifierMissing:PaxMetrics.kt$PaxMetricsItem</ID>
|
||||
<ID>ModifierMissing:PaxMetrics.kt$PaxMetricsScreen</ID>
|
||||
<ID>ModifierMissing:PositionConfigItemList.kt$PositionConfigScreen</ID>
|
||||
<ID>ModifierMissing:PositionLog.kt$PositionItem</ID>
|
||||
<ID>ModifierMissing:PositionLog.kt$PositionLogScreen</ID>
|
||||
<ID>ModifierMissing:PowerMetrics.kt$PowerMetricsScreen</ID>
|
||||
<ID>ModifierMissing:RadioConfig.kt$RadioConfigItemList</ID>
|
||||
<ID>ModifierMissing:RadioConfigScreenList.kt$RadioConfigScreenList</ID>
|
||||
<ID>ModifierMissing:Reaction.kt$ReactionDialog</ID>
|
||||
<ID>ModifierMissing:SecurityConfigItemList.kt$SecurityConfigScreen</ID>
|
||||
<ID>ModifierMissing:SettingsScreen.kt$SettingsScreen</ID>
|
||||
<ID>ModifierMissing:Share.kt$ShareScreen</ID>
|
||||
<ID>ModifierMissing:SharedContactDialog.kt$SharedContactDialog</ID>
|
||||
<ID>ModifierMissing:SignalMetrics.kt$SignalMetricsScreen</ID>
|
||||
|
|
@ -189,8 +143,6 @@
|
|||
<ID>ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier = modifier.weight(weight = Y_AXIS_WEIGHT)</ID>
|
||||
<ID>ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier = modifier.width(dp)</ID>
|
||||
<ID>ModifierNotUsedAtRoot:DeviceMetrics.kt$modifier.width(dp)</ID>
|
||||
<ID>ModifierNotUsedAtRoot:EditChannelDialog.kt$modifier = modifier.weight(1f)</ID>
|
||||
<ID>ModifierNotUsedAtRoot:EditDeviceProfileDialog.kt$modifier = modifier.weight(1f)</ID>
|
||||
<ID>ModifierNotUsedAtRoot:EnvironmentCharts.kt$modifier = modifier.width(dp)</ID>
|
||||
<ID>ModifierNotUsedAtRoot:EnvironmentCharts.kt$modifier.width(dp)</ID>
|
||||
<ID>ModifierNotUsedAtRoot:PaxMetrics.kt$modifier.width(dp)</ID>
|
||||
|
|
@ -224,7 +176,6 @@
|
|||
<ID>ModifierReused:SignalMetrics.kt$YAxisLabels( modifier = modifier.weight(weight = Y_AXIS_WEIGHT), Metric.SNR.color, minValue = Metric.SNR.min, maxValue = Metric.SNR.max, )</ID>
|
||||
<ID>ModifierWithoutDefault:CommonCharts.kt$modifier</ID>
|
||||
<ID>ModifierWithoutDefault:EnvironmentCharts.kt$modifier</ID>
|
||||
<ID>MultipleEmitters:CleanNodeDatabaseScreen.kt$NodesDeletionPreview</ID>
|
||||
<ID>MultipleEmitters:CommonCharts.kt$LegendLabel</ID>
|
||||
<ID>MultipleEmitters:DeviceMetrics.kt$DeviceMetricsChart</ID>
|
||||
<ID>MultipleEmitters:EnvironmentCharts.kt$EnvironmentMetricsChart</ID>
|
||||
|
|
@ -232,13 +183,11 @@
|
|||
<ID>MultipleEmitters:NodeDetailScreen.kt$MetricsSection</ID>
|
||||
<ID>MultipleEmitters:PaxMetrics.kt$PaxMetricsChart</ID>
|
||||
<ID>MultipleEmitters:PowerMetrics.kt$PowerMetricsChart</ID>
|
||||
<ID>MultipleEmitters:RadioConfig.kt$RadioConfigItemList</ID>
|
||||
<ID>MultipleEmitters:SignalMetrics.kt$SignalMetricsChart</ID>
|
||||
<ID>MutableStateAutoboxing:Contacts.kt$mutableStateOf(2)</ID>
|
||||
<ID>MutableStateParam:MessageList.kt$selectedIds</ID>
|
||||
<ID>NestedBlockDepth:MeshService.kt$MeshService$private fun handleReceivedAdmin(fromNodeNum: Int, a: AdminProtos.AdminMessage)</ID>
|
||||
<ID>NestedBlockDepth:MeshService.kt$MeshService$private fun handleReceivedData(packet: MeshPacket)</ID>
|
||||
<ID>NestedBlockDepth:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)</ID>
|
||||
<ID>NewLineAtEndOfFile:BLEException.kt$com.geeksville.mesh.service.BLEException.kt</ID>
|
||||
<ID>NewLineAtEndOfFile:BluetoothInterfaceFactory.kt$com.geeksville.mesh.repository.radio.BluetoothInterfaceFactory.kt</ID>
|
||||
<ID>NewLineAtEndOfFile:BluetoothRepositoryModule.kt$com.geeksville.mesh.repository.bluetooth.BluetoothRepositoryModule.kt</ID>
|
||||
|
|
@ -266,27 +215,17 @@
|
|||
<ID>NoEmptyClassBody:DebugLogFile.kt$BinaryLogFile${ }</ID>
|
||||
<ID>NoSemicolons:DateUtils.kt$DateUtils$;</ID>
|
||||
<ID>OptionalAbstractKeyword:SyncContinuation.kt$Continuation$abstract</ID>
|
||||
<ID>ParameterNaming:ChannelSettingsItemList.kt$onPositiveClicked</ID>
|
||||
<ID>ParameterNaming:ChannelSettingsItemList.kt$onSelected</ID>
|
||||
<ID>ParameterNaming:CleanNodeDatabaseScreen.kt$onCheckedChanged</ID>
|
||||
<ID>ParameterNaming:CleanNodeDatabaseScreen.kt$onDaysChanged</ID>
|
||||
<ID>ParameterNaming:ContactSharing.kt$onSharedContactRequested</ID>
|
||||
<ID>ParameterNaming:Contacts.kt$onDeleteSelected</ID>
|
||||
<ID>ParameterNaming:Contacts.kt$onMuteSelected</ID>
|
||||
<ID>ParameterNaming:MapReportingPreference.kt$onMapReportingEnabledChanged</ID>
|
||||
<ID>ParameterNaming:MapReportingPreference.kt$onPositionPrecisionChanged</ID>
|
||||
<ID>ParameterNaming:MapReportingPreference.kt$onPublishIntervalSecsChanged</ID>
|
||||
<ID>ParameterNaming:MapReportingPreference.kt$onShouldReportLocationChanged</ID>
|
||||
<ID>ParameterNaming:MessageList.kt$onUnreadChanged</ID>
|
||||
<ID>ParameterNaming:NodeDetailScreen.kt$onFirmwareSelected</ID>
|
||||
<ID>ParameterNaming:UsbDevices.kt$onDeviceSelected</ID>
|
||||
<ID>PreviewPublic:Channel.kt$ModemPresetInfoPreview</ID>
|
||||
<ID>PreviewPublic:EmptyStateContent.kt$EmptyStateContentPreview</ID>
|
||||
<ID>PreviewPublic:MapReportingPreference.kt$MapReportingPreview</ID>
|
||||
<ID>PreviewPublic:Reaction.kt$ReactionItemPreview</ID>
|
||||
<ID>PreviewPublic:Reaction.kt$ReactionRowPreview</ID>
|
||||
<ID>RethrowCaughtException:SyncContinuation.kt$Continuation$throw ex</ID>
|
||||
<ID>ReturnCount:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)</ID>
|
||||
<ID>SwallowedException:BluetoothInterface.kt$BluetoothInterface$ex: CancellationException</ID>
|
||||
<ID>SwallowedException:Exceptions.kt$ex: Throwable</ID>
|
||||
<ID>SwallowedException:MeshService.kt$MeshService$ex: BLEException</ID>
|
||||
|
|
@ -299,13 +238,10 @@
|
|||
<ID>TooGenericExceptionCaught:BTScanModel.kt$BTScanModel$ex: Throwable</ID>
|
||||
<ID>TooGenericExceptionCaught:BluetoothInterface.kt$BluetoothInterface$ex: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:Exceptions.kt$ex: Throwable</ID>
|
||||
<ID>TooGenericExceptionCaught:LanguageUtils.kt$LanguageUtils$e: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:LocationRepository.kt$LocationRepository$e: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:MQTTRepository.kt$MQTTRepository$ex: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:MeshService.kt$MeshService$ex: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:MeshService.kt$MeshService.<no name provided>$ex: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:MeshServiceStarter.kt$ServiceStarter$ex: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:RadioConfigViewModel.kt$RadioConfigViewModel$ex: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:SafeBluetooth.kt$SafeBluetooth$ex: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:SafeBluetooth.kt$SafeBluetooth$ex: NullPointerException</ID>
|
||||
<ID>TooGenericExceptionCaught:SyncContinuation.kt$Continuation$ex: Throwable</ID>
|
||||
|
|
@ -321,16 +257,12 @@
|
|||
<ID>TooManyFunctions:MeshService.kt$MeshService$<no name provided> : Stub</ID>
|
||||
<ID>TooManyFunctions:MessageViewModel.kt$MessageViewModel : ViewModel</ID>
|
||||
<ID>TooManyFunctions:NodeDetailScreen.kt$com.geeksville.mesh.ui.node.NodeDetailScreen.kt</ID>
|
||||
<ID>TooManyFunctions:RadioConfigViewModel.kt$RadioConfigViewModel : ViewModel</ID>
|
||||
<ID>TooManyFunctions:RadioInterfaceService.kt$RadioInterfaceService</ID>
|
||||
<ID>TooManyFunctions:SafeBluetooth.kt$SafeBluetooth : Closeable</ID>
|
||||
<ID>TooManyFunctions:UIState.kt$UIViewModel : ViewModel</ID>
|
||||
<ID>TopLevelPropertyNaming:Constants.kt$const val prefix = "com.geeksville.mesh"</ID>
|
||||
<ID>UnusedParameter:ChannelSettingsItemList.kt$onBack: () -> Unit</ID>
|
||||
<ID>UnusedParameter:ChannelSettingsItemList.kt$title: String</ID>
|
||||
<ID>UtilityClassWithPublicConstructor:NetworkRepositoryModule.kt$NetworkRepositoryModule</ID>
|
||||
<ID>ViewModelForwarding:Main.kt$VersionChecks(uIViewModel)</ID>
|
||||
<ID>ViewModelInjection:DebugSearch.kt$viewModel</ID>
|
||||
<ID>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() } } }</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
|
|||
|
|
@ -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<ChannelSettings>, old: List<ChannelSettings>): List<ChannelProtos.Channel> =
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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<Int, Long>()
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -78,4 +78,5 @@ dependencies {
|
|||
kover(projects.feature.intro)
|
||||
kover(projects.feature.map)
|
||||
kover(projects.feature.node)
|
||||
kover(projects.feature.settings)
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@
|
|||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>MagicNumber:LocationRepository.kt$LocationRepository$1000L</ID>
|
||||
<ID>MagicNumber:LocationRepository.kt$LocationRepository$30</ID>
|
||||
<ID>MagicNumber:LocationRepository.kt$LocationRepository$31</ID>
|
||||
<ID>MagicNumber:PacketRepository.kt$PacketRepository$500</ID>
|
||||
<ID>TooGenericExceptionCaught:LocationRepository.kt$LocationRepository$e: Exception</ID>
|
||||
<ID>TooManyFunctions:PacketRepository.kt$PacketRepository</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<LocationManager>,
|
||||
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)
|
||||
}
|
||||
|
|
@ -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<ChannelSettings>, old: List<ChannelSettings>): List<ChannelProtos.Channel> = 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 {}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
44
feature/settings/build.gradle.kts
Normal file
44
feature/settings/build.gradle.kts
Normal file
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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)
|
||||
}
|
||||
70
feature/settings/detekt-baseline.xml
Normal file
70
feature/settings/detekt-baseline.xml
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>ComposableParamOrder:ChannelSettingsItemList.kt$ChannelSettingsItemList</ID>
|
||||
<ID>ComposableParamOrder:Debug.kt$DecodedPayloadBlock</ID>
|
||||
<ID>ComposableParamOrder:DebugSearch.kt$DebugSearchState</ID>
|
||||
<ID>ComposableParamOrder:DebugSearch.kt$DebugSearchStateviewModelDefaults</ID>
|
||||
<ID>ComposableParamOrder:MapReportingPreference.kt$MapReportingPreference</ID>
|
||||
<ID>ComposableParamOrder:NodeActionButton.kt$NodeActionButton</ID>
|
||||
<ID>ComposableParamOrder:WarningDialog.kt$WarningDialog</ID>
|
||||
<ID>CyclomaticComplexMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>CyclomaticComplexMethod:PositionConfigItemList.kt$@OptIn(ExperimentalPermissionsApi::class) @Composable fun PositionConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>CyclomaticComplexMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)</ID>
|
||||
<ID>LambdaParameterEventTrailing:NodeActionButton.kt$onClick</ID>
|
||||
<ID>LongMethod:AmbientLightingConfigItemList.kt$@Composable fun AmbientLightingConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:AudioConfigItemList.kt$@Composable fun AudioConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:CannedMessageConfigItemList.kt$@Composable fun CannedMessageConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:DetectionSensorConfigItemList.kt$@Composable fun DetectionSensorConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:DeviceConfigItemList.kt$@Composable fun DeviceConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:DisplayConfigItemList.kt$@Composable fun DisplayConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:ExternalNotificationConfigItemList.kt$@Composable fun ExternalNotificationConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:LoRaConfigItemList.kt$@Composable fun LoRaConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:NetworkConfigItemList.kt$@Composable fun NetworkConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:PositionConfigItemList.kt$@OptIn(ExperimentalPermissionsApi::class) @Composable fun PositionConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:PowerConfigItemList.kt$@Composable fun PowerConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)</ID>
|
||||
<ID>LongMethod:SecurityConfigItemList.kt$@OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable fun SecurityConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:SerialConfigItemList.kt$@Composable fun SerialConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:StoreForwardConfigItemList.kt$@Composable fun StoreForwardConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:TelemetryConfigItemList.kt$@Composable fun TelemetryConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>LongMethod:UserConfigItemList.kt$@Composable fun UserConfigScreen(navController: NavController, viewModel: RadioConfigViewModel = hiltViewModel())</ID>
|
||||
<ID>MagicNumber:Debug.kt$3</ID>
|
||||
<ID>MagicNumber:EditChannelDialog.kt$16</ID>
|
||||
<ID>MagicNumber:EditChannelDialog.kt$32</ID>
|
||||
<ID>MagicNumber:PacketResponseStateDialog.kt$100</ID>
|
||||
<ID>MagicNumber:PowerConfigItemList.kt$3600</ID>
|
||||
<ID>ModifierMissing:ChannelSettingsItemList.kt$ChannelSelection</ID>
|
||||
<ID>ModifierMissing:CleanNodeDatabaseScreen.kt$CleanNodeDatabaseScreen</ID>
|
||||
<ID>ModifierMissing:LoRaConfigItemList.kt$LoRaConfigScreen</ID>
|
||||
<ID>ModifierMissing:MapReportingPreference.kt$MapReportingPreference</ID>
|
||||
<ID>ModifierMissing:NetworkConfigItemList.kt$NetworkConfigScreen</ID>
|
||||
<ID>ModifierMissing:PositionConfigItemList.kt$PositionConfigScreen</ID>
|
||||
<ID>ModifierMissing:RadioConfig.kt$RadioConfigItemList</ID>
|
||||
<ID>ModifierMissing:RadioConfigScreenList.kt$RadioConfigScreenList</ID>
|
||||
<ID>ModifierMissing:SecurityConfigItemList.kt$SecurityConfigScreen</ID>
|
||||
<ID>ModifierMissing:SettingsScreen.kt$SettingsScreen</ID>
|
||||
<ID>ModifierNotUsedAtRoot:EditChannelDialog.kt$modifier = modifier.weight(1f)</ID>
|
||||
<ID>ModifierNotUsedAtRoot:EditDeviceProfileDialog.kt$modifier = modifier.weight(1f)</ID>
|
||||
<ID>MultipleEmitters:CleanNodeDatabaseScreen.kt$NodesDeletionPreview</ID>
|
||||
<ID>MultipleEmitters:RadioConfig.kt$RadioConfigItemList</ID>
|
||||
<ID>NestedBlockDepth:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)</ID>
|
||||
<ID>ParameterNaming:ChannelSettingsItemList.kt$onPositiveClicked</ID>
|
||||
<ID>ParameterNaming:ChannelSettingsItemList.kt$onSelected</ID>
|
||||
<ID>ParameterNaming:CleanNodeDatabaseScreen.kt$onCheckedChanged</ID>
|
||||
<ID>ParameterNaming:CleanNodeDatabaseScreen.kt$onDaysChanged</ID>
|
||||
<ID>ParameterNaming:MapReportingPreference.kt$onMapReportingEnabledChanged</ID>
|
||||
<ID>ParameterNaming:MapReportingPreference.kt$onPositionPrecisionChanged</ID>
|
||||
<ID>ParameterNaming:MapReportingPreference.kt$onPublishIntervalSecsChanged</ID>
|
||||
<ID>ParameterNaming:MapReportingPreference.kt$onShouldReportLocationChanged</ID>
|
||||
<ID>PreviewPublic:MapReportingPreference.kt$MapReportingPreview</ID>
|
||||
<ID>ReturnCount:RadioConfigViewModel.kt$RadioConfigViewModel$private fun processPacketResponse(packet: MeshProtos.MeshPacket)</ID>
|
||||
<ID>TooGenericExceptionCaught:LanguageUtils.kt$LanguageUtils$e: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:RadioConfigViewModel.kt$RadioConfigViewModel$ex: Exception</ID>
|
||||
<ID>TooManyFunctions:RadioConfigViewModel.kt$RadioConfigViewModel : ViewModel</ID>
|
||||
<ID>UnusedParameter:ChannelSettingsItemList.kt$onBack: () -> Unit</ID>
|
||||
<ID>UnusedParameter:ChannelSettingsItemList.kt$title: String</ID>
|
||||
<ID>ViewModelInjection:DebugSearch.kt$viewModel</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -15,11 +15,13 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<String>()) }
|
||||
var customFilterText by androidx.compose.runtime.remember { androidx.compose.runtime.mutableStateOf("") }
|
||||
var filterTexts by remember { mutableStateOf(listOf<String>()) }
|
||||
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<String>()) }
|
||||
var customFilterText by androidx.compose.runtime.remember { androidx.compose.runtime.mutableStateOf("") }
|
||||
var filterTexts by remember { mutableStateOf(listOf<String>()) }
|
||||
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,
|
||||
|
|
@ -15,12 +15,13 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<String>()) }
|
||||
var customFilterText by androidx.compose.runtime.remember { mutableStateOf("") }
|
||||
var filterTexts by remember { mutableStateOf(listOf<String>()) }
|
||||
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<String>()) }
|
||||
var customFilterText by androidx.compose.runtime.remember { mutableStateOf("") }
|
||||
var filterTexts by remember { mutableStateOf(listOf<String>()) }
|
||||
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,
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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)
|
||||
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<MyNodeEntity?> = nodeRepository.myNodeInfo
|
||||
|
||||
|
|
@ -108,6 +110,9 @@ constructor(
|
|||
private val _excludedModulesUnlocked = MutableStateFlow(false)
|
||||
val excludedModulesUnlocked: StateFlow<Boolean> = _excludedModulesUnlocked.asStateFlow()
|
||||
|
||||
val appVersionName
|
||||
get() = buildConfigProvider.versionName
|
||||
|
||||
fun setProvideLocation(value: Boolean) {
|
||||
myNodeNum?.let { uiPrefs.setShouldProvideNodeLocation(it, value) }
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.geeksville.mesh.ui.settings.radio
|
||||
package org.meshtastic.feature.settings.radio
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,9 +15,9 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<out T> {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.geeksville.mesh.ui.settings.radio.components
|
||||
package org.meshtastic.feature.settings.radio.component
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.clickable
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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() =
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 = {}) =
|
||||
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <T> PacketResponseStateDialog(state: ResponseState<T>, onDismiss: () -> Unit = {}, onComplete: () -> Unit = {}) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <T : MessageLite> RadioConfigScreenList(
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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)
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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()) {
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 =
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ include(
|
|||
":feature:intro",
|
||||
":feature:map",
|
||||
":feature:node",
|
||||
":feature:settings",
|
||||
":mesh_service_example",
|
||||
)
|
||||
rootProject.name = "MeshtasticAndroid"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue