mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
81dc625c70
commit
e701ad6aee
12 changed files with 68 additions and 14 deletions
|
|
@ -2321,9 +2321,12 @@ class MeshService : Service() {
|
|||
)
|
||||
}
|
||||
|
||||
override fun requestNodedbReset(requestId: Int, destNum: Int) = toRemoteExceptions {
|
||||
packetHandler.sendToRadio(newMeshPacketTo(destNum).buildAdminPacket(id = requestId) { nodedbReset = 1 })
|
||||
}
|
||||
override fun requestNodedbReset(requestId: Int, destNum: Int, preserveFavorites: Boolean) =
|
||||
toRemoteExceptions {
|
||||
packetHandler.sendToRadio(
|
||||
newMeshPacketTo(destNum).buildAdminPacket(id = requestId) { nodedbReset = preserveFavorites },
|
||||
)
|
||||
}
|
||||
|
||||
override fun getDeviceConnectionStatus(requestId: Int, destNum: Int) = toRemoteExceptions {
|
||||
packetHandler.sendToRadio(
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ interface NodeInfoWriteDataSource {
|
|||
|
||||
suspend fun installConfig(mi: MyNodeEntity, nodes: List<NodeEntity>)
|
||||
|
||||
suspend fun clearNodeDB()
|
||||
suspend fun clearNodeDB(preserveFavorites: Boolean)
|
||||
|
||||
suspend fun deleteNode(num: Int)
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ constructor(
|
|||
override suspend fun installConfig(mi: MyNodeEntity, nodes: List<NodeEntity>) =
|
||||
withContext(dispatchers.io) { dbManager.withDb { it.nodeInfoDao().installConfig(mi, nodes) } }
|
||||
|
||||
override suspend fun clearNodeDB() =
|
||||
withContext(dispatchers.io) { dbManager.withDb { it.nodeInfoDao().clearNodeInfo() } }
|
||||
override suspend fun clearNodeDB(preserveFavorites: Boolean) =
|
||||
withContext(dispatchers.io) { dbManager.withDb { it.nodeInfoDao().clearNodeInfo(preserveFavorites) } }
|
||||
|
||||
override suspend fun deleteNode(num: Int) =
|
||||
withContext(dispatchers.io) { dbManager.withDb { it.nodeInfoDao().deleteNode(num) } }
|
||||
|
|
|
|||
|
|
@ -136,7 +136,8 @@ constructor(
|
|||
suspend fun installConfig(mi: MyNodeEntity, nodes: List<NodeEntity>) =
|
||||
withContext(dispatchers.io) { nodeInfoWriteDataSource.installConfig(mi, nodes) }
|
||||
|
||||
suspend fun clearNodeDB() = withContext(dispatchers.io) { nodeInfoWriteDataSource.clearNodeDB() }
|
||||
suspend fun clearNodeDB(preserveFavorites: Boolean = false) =
|
||||
withContext(dispatchers.io) { nodeInfoWriteDataSource.clearNodeDB(preserveFavorites) }
|
||||
|
||||
suspend fun deleteNode(num: Int) = withContext(dispatchers.io) {
|
||||
nodeInfoWriteDataSource.deleteNode(num)
|
||||
|
|
|
|||
|
|
@ -182,8 +182,20 @@ interface NodeInfoDao {
|
|||
lastHeardMin: Int,
|
||||
): Flow<List<NodeWithRelations>>
|
||||
|
||||
@Transaction
|
||||
fun clearNodeInfo(preserveFavorites: Boolean) {
|
||||
if (preserveFavorites) {
|
||||
deleteNonFavoriteNodes()
|
||||
} else {
|
||||
deleteAllNodes()
|
||||
}
|
||||
}
|
||||
|
||||
@Query("DELETE FROM nodes WHERE is_favorite = 0")
|
||||
fun deleteNonFavoriteNodes()
|
||||
|
||||
@Query("DELETE FROM nodes")
|
||||
fun clearNodeInfo()
|
||||
fun deleteAllNodes()
|
||||
|
||||
@Query("DELETE FROM nodes WHERE num=:num")
|
||||
fun deleteNode(num: Int)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit fbe1538c21f87e6717e6617ac21bc0799e594ec7
|
||||
Subproject commit 7654db2e2d1834aebde40090a9b74162ad1048ae
|
||||
|
|
@ -136,7 +136,7 @@ interface IMeshService {
|
|||
void requestFactoryReset(in int requestId, in int destNum);
|
||||
|
||||
/// Send NodedbReset admin packet to nodeNum
|
||||
void requestNodedbReset(in int requestId, in int destNum);
|
||||
void requestNodedbReset(in int requestId, in int destNum, in boolean preserveFavorites);
|
||||
|
||||
/// Returns a ChannelSet protobuf
|
||||
byte []getChannelSet();
|
||||
|
|
|
|||
|
|
@ -950,4 +950,5 @@
|
|||
<string name="privacy_url" translatable="false">" https://meshtastic.org/docs/legal/privacy/"</string>
|
||||
<string name="unset">Unset - 0</string>
|
||||
<string name="relayed_by">Relayed by: %s</string>
|
||||
<string name="preserve_favorites">Preserve Favorites?</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -237,6 +237,7 @@ fun SettingsScreen(
|
|||
state = state,
|
||||
isManaged = localConfig.security.isManaged,
|
||||
excludedModulesUnlocked = excludedModulesUnlocked,
|
||||
onPreserveFavoritesToggle = { viewModel.setPreserveFavorites(it) },
|
||||
onRouteClick = { route ->
|
||||
isWaiting = true
|
||||
viewModel.setResponseStateLoading(route)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@
|
|||
|
||||
package org.meshtastic.feature.settings.radio
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Download
|
||||
|
|
@ -28,7 +31,9 @@ import androidx.compose.material.icons.rounded.PowerSettingsNew
|
|||
import androidx.compose.material.icons.rounded.RestartAlt
|
||||
import androidx.compose.material.icons.rounded.Restore
|
||||
import androidx.compose.material.icons.rounded.Storage
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
|
|
@ -36,6 +41,7 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -57,6 +63,7 @@ import org.meshtastic.core.strings.import_configuration
|
|||
import org.meshtastic.core.strings.message_device_managed
|
||||
import org.meshtastic.core.strings.module_settings
|
||||
import org.meshtastic.core.strings.nodedb_reset
|
||||
import org.meshtastic.core.strings.preserve_favorites
|
||||
import org.meshtastic.core.strings.radio_configuration
|
||||
import org.meshtastic.core.strings.reboot
|
||||
import org.meshtastic.core.strings.shutdown
|
||||
|
|
@ -68,12 +75,14 @@ import org.meshtastic.feature.settings.navigation.ConfigRoute
|
|||
import org.meshtastic.feature.settings.navigation.ModuleRoute
|
||||
import org.meshtastic.feature.settings.radio.component.WarningDialog
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
@Composable
|
||||
fun RadioConfigItemList(
|
||||
state: RadioConfigState,
|
||||
isManaged: Boolean,
|
||||
excludedModulesUnlocked: Boolean = false,
|
||||
onPreserveFavoritesToggle: (Boolean) -> Unit = {},
|
||||
onRouteClick: (Enum<*>) -> Unit = {},
|
||||
onImport: () -> Unit = {},
|
||||
onExport: () -> Unit = {},
|
||||
|
|
@ -147,6 +156,23 @@ fun RadioConfigItemList(
|
|||
if (showDialog) {
|
||||
WarningDialog(
|
||||
title = "${stringResource(route.title)}?",
|
||||
text = {
|
||||
if (route == AdminRoute.NODEDB_RESET) {
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp).fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Text(text = stringResource(Res.string.preserve_favorites))
|
||||
Switch(
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
enabled = enabled,
|
||||
checked = state.nodeDbResetPreserveFavorites,
|
||||
onCheckedChange = onPreserveFavoritesToggle,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
onDismiss = { showDialog = false },
|
||||
onConfirm = { onRouteClick(route) },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ data class RadioConfigState(
|
|||
val responseState: ResponseState<Boolean> = ResponseState.Empty,
|
||||
val analyticsAvailable: Boolean = true,
|
||||
val analyticsEnabled: Boolean = false,
|
||||
val nodeDbResetPreserveFavorites: Boolean = false,
|
||||
)
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -135,6 +136,10 @@ constructor(
|
|||
private val _radioConfigState = MutableStateFlow(RadioConfigState())
|
||||
val radioConfigState: StateFlow<RadioConfigState> = _radioConfigState
|
||||
|
||||
fun setPreserveFavorites(preserveFavorites: Boolean) {
|
||||
viewModelScope.launch { _radioConfigState.update { it.copy(nodeDbResetPreserveFavorites = preserveFavorites) } }
|
||||
}
|
||||
|
||||
private val _currentDeviceProfile = MutableStateFlow(deviceProfile {})
|
||||
val currentDeviceProfile
|
||||
get() = _currentDeviceProfile.value
|
||||
|
|
@ -365,14 +370,14 @@ constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun requestNodedbReset(destNum: Int) {
|
||||
private fun requestNodedbReset(destNum: Int, preserveFavorites: Boolean) {
|
||||
request(
|
||||
destNum,
|
||||
{ service, packetId, dest -> service.requestNodedbReset(packetId, dest) },
|
||||
{ service, packetId, dest -> service.requestNodedbReset(packetId, dest, preserveFavorites) },
|
||||
"Request NodeDB reset error",
|
||||
)
|
||||
if (destNum == myNodeNum) {
|
||||
viewModelScope.launch { nodeRepository.clearNodeDB() }
|
||||
viewModelScope.launch { nodeRepository.clearNodeDB(preserveFavorites) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -380,6 +385,8 @@ constructor(
|
|||
val route = radioConfigState.value.route
|
||||
_radioConfigState.update { it.copy(route = "") } // setter (response is PortNum.ROUTING_APP)
|
||||
|
||||
val preserveFavorites = radioConfigState.value.nodeDbResetPreserveFavorites
|
||||
|
||||
when (route) {
|
||||
AdminRoute.REBOOT.name -> requestReboot(destNum)
|
||||
AdminRoute.SHUTDOWN.name ->
|
||||
|
|
@ -392,7 +399,7 @@ constructor(
|
|||
}
|
||||
|
||||
AdminRoute.FACTORY_RESET.name -> requestFactoryReset(destNum)
|
||||
AdminRoute.NODEDB_RESET.name -> requestNodedbReset(destNum)
|
||||
AdminRoute.NODEDB_RESET.name -> requestNodedbReset(destNum, preserveFavorites)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -535,6 +542,7 @@ constructor(
|
|||
connected = it.connected,
|
||||
route = route.name,
|
||||
metadata = it.metadata,
|
||||
nodeDbResetPreserveFavorites = it.nodeDbResetPreserveFavorites,
|
||||
responseState = ResponseState.Loading(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import org.meshtastic.core.ui.theme.AppTheme
|
|||
fun WarningDialog(
|
||||
icon: ImageVector? = Icons.Rounded.Warning,
|
||||
title: String,
|
||||
text: @Composable () -> Unit = {},
|
||||
onDismiss: () -> Unit,
|
||||
onConfirm: () -> Unit,
|
||||
) {
|
||||
|
|
@ -44,6 +45,7 @@ fun WarningDialog(
|
|||
onDismissRequest = {},
|
||||
icon = { icon?.let { Icon(imageVector = it, contentDescription = null) } },
|
||||
title = { Text(text = title) },
|
||||
text = text,
|
||||
dismissButton = { TextButton(onClick = { onDismiss() }) { Text(stringResource(Res.string.cancel)) } },
|
||||
confirmButton = {
|
||||
Button(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue