mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-03-12 10:57:43 -04:00
Decouple ScannedQrCodeDialog from UiViewModel (#3300)
This commit is contained in:
@@ -347,23 +347,6 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun setChannel(channel: ChannelProtos.Channel) {
|
||||
try {
|
||||
meshService?.setChannel(channel.toByteArray())
|
||||
} catch (ex: RemoteException) {
|
||||
Timber.e(ex, "Set channel error")
|
||||
}
|
||||
}
|
||||
|
||||
/** Set the radio config (also updates our saved copy in preferences). */
|
||||
fun setChannels(channelSet: AppOnlyProtos.ChannelSet) = viewModelScope.launch {
|
||||
getChannelList(channelSet.settingsList, channels.value.settingsList).forEach(::setChannel)
|
||||
radioConfigRepository.replaceAllSettings(channelSet.settingsList)
|
||||
|
||||
val newConfig = config { lora = channelSet.loraConfig }
|
||||
if (config.lora != newConfig.lora) setConfig(newConfig)
|
||||
}
|
||||
|
||||
fun addQuickChatAction(action: QuickChatAction) =
|
||||
viewModelScope.launch(Dispatchers.IO) { quickChatActionRepository.upsert(action) }
|
||||
|
||||
|
||||
@@ -150,7 +150,9 @@ fun MainScreen(uIViewModel: UIViewModel = hiltViewModel(), scanModel: BTScanMode
|
||||
}
|
||||
|
||||
if (connectionState == ConnectionState.CONNECTED) {
|
||||
requestChannelSet?.let { newChannelSet -> ScannedQrCodeDialog(uIViewModel, newChannelSet) }
|
||||
requestChannelSet?.let { newChannelSet ->
|
||||
ScannedQrCodeDialog(newChannelSet, onDismiss = { uIViewModel.clearRequestChannelUrl() })
|
||||
}
|
||||
}
|
||||
|
||||
analytics.addNavigationTrackingEffect(navController = navController)
|
||||
|
||||
@@ -49,24 +49,28 @@ import androidx.compose.ui.tooling.preview.PreviewScreenSizes
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
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.model.UIViewModel
|
||||
import com.geeksville.mesh.ui.settings.radio.components.ChannelSelection
|
||||
import org.meshtastic.core.model.Channel
|
||||
import org.meshtastic.core.strings.R
|
||||
|
||||
@Composable
|
||||
fun ScannedQrCodeDialog(viewModel: UIViewModel, incoming: ChannelSet) {
|
||||
fun ScannedQrCodeDialog(
|
||||
incoming: ChannelSet,
|
||||
onDismiss: () -> Unit,
|
||||
viewModel: ScannedQrCodeViewModel = hiltViewModel(),
|
||||
) {
|
||||
val channels by viewModel.channels.collectAsStateWithLifecycle()
|
||||
|
||||
ScannedQrCodeDialog(
|
||||
channels = channels,
|
||||
incoming = incoming,
|
||||
onDismiss = viewModel::clearRequestChannelUrl,
|
||||
onDismiss = onDismiss,
|
||||
onConfirm = viewModel::setChannels,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 com.geeksville.mesh.ui.common.components
|
||||
|
||||
import android.os.RemoteException
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.geeksville.mesh.AppOnlyProtos
|
||||
import com.geeksville.mesh.ChannelProtos
|
||||
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.service.ServiceRepository
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ScannedQrCodeViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val radioConfigRepository: RadioConfigRepository,
|
||||
private val serviceRepository: ServiceRepository,
|
||||
) : ViewModel() {
|
||||
|
||||
val channels =
|
||||
radioConfigRepository.channelSetFlow.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.WhileSubscribed(5_000L),
|
||||
channelSet {},
|
||||
)
|
||||
|
||||
private val localConfig =
|
||||
radioConfigRepository.localConfigFlow.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.WhileSubscribed(5_000L),
|
||||
LocalConfig.getDefaultInstance(),
|
||||
)
|
||||
|
||||
/** Set the radio config (also updates our saved copy in preferences). */
|
||||
fun setChannels(channelSet: AppOnlyProtos.ChannelSet) = viewModelScope.launch {
|
||||
getChannelList(channelSet.settingsList, channels.value.settingsList).forEach(::setChannel)
|
||||
radioConfigRepository.replaceAllSettings(channelSet.settingsList)
|
||||
|
||||
val newConfig = config { lora = channelSet.loraConfig }
|
||||
if (localConfig.value.lora != newConfig.lora) setConfig(newConfig)
|
||||
}
|
||||
|
||||
private fun setChannel(channel: ChannelProtos.Channel) {
|
||||
try {
|
||||
serviceRepository.meshService?.setChannel(channel.toByteArray())
|
||||
} catch (ex: RemoteException) {
|
||||
Timber.e(ex, "Set channel error")
|
||||
}
|
||||
}
|
||||
|
||||
// Set the radio config (also updates our saved copy in preferences)
|
||||
private fun setConfig(config: Config) {
|
||||
try {
|
||||
serviceRepository.meshService?.setConfig(config.toByteArray())
|
||||
} catch (ex: RemoteException) {
|
||||
Timber.e(ex, "Set config error")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,6 +96,7 @@ 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
|
||||
@@ -144,6 +145,8 @@ fun ChannelScreen(
|
||||
|
||||
var shouldAddChannelsState by remember { mutableStateOf(true) }
|
||||
|
||||
val requestChannelSet by viewModel.requestChannelSet.collectAsStateWithLifecycle()
|
||||
|
||||
/* Animate waiting for the configurations */
|
||||
var isWaiting by remember { mutableStateOf(false) }
|
||||
if (isWaiting) {
|
||||
@@ -269,6 +272,8 @@ fun ChannelScreen(
|
||||
)
|
||||
}
|
||||
|
||||
requestChannelSet?.let { ScannedQrCodeDialog(it, onDismiss = { viewModel.clearRequestChannelUrl() }) }
|
||||
|
||||
val listState = rememberLazyListState()
|
||||
LazyColumn(state = listState, contentPadding = PaddingValues(horizontal = 24.dp, vertical = 16.dp)) {
|
||||
item {
|
||||
|
||||
@@ -91,6 +91,10 @@ constructor(
|
||||
onError()
|
||||
}
|
||||
|
||||
fun clearRequestChannelUrl() {
|
||||
_requestChannelSet.value = null
|
||||
}
|
||||
|
||||
/** Set the radio config (also updates our saved copy in preferences). */
|
||||
fun setChannels(channelSet: AppOnlyProtos.ChannelSet) = viewModelScope.launch {
|
||||
getChannelList(channelSet.settingsList, channels.value.settingsList).forEach(::setChannel)
|
||||
|
||||
Reference in New Issue
Block a user