kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
feat: add `NodeDetail` request metadata
rodzic
60e7e18116
commit
1d6a3f44e4
|
@ -40,6 +40,7 @@ import com.geeksville.mesh.database.MeshLogRepository
|
|||
import com.geeksville.mesh.database.entity.MeshLog
|
||||
import com.geeksville.mesh.model.map.CustomTileSource
|
||||
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
|
||||
import com.geeksville.mesh.service.ServiceAction
|
||||
import com.geeksville.mesh.ui.Route
|
||||
import com.geeksville.mesh.ui.map.MAP_STYLE_ID
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
|
@ -67,6 +68,7 @@ import java.util.concurrent.TimeUnit
|
|||
import javax.inject.Inject
|
||||
|
||||
data class MetricsState(
|
||||
val isLocal: Boolean = false,
|
||||
val isManaged: Boolean = true,
|
||||
val isFahrenheit: Boolean = false,
|
||||
val displayUnits: DisplayUnits = DisplayUnits.METRIC,
|
||||
|
@ -208,6 +210,10 @@ class MetricsViewModel @Inject constructor(
|
|||
meshLogRepository.deleteLogs(destNum, PortNum.POSITION_APP_VALUE)
|
||||
}
|
||||
|
||||
fun onServiceAction(action: ServiceAction) = viewModelScope.launch {
|
||||
radioConfigRepository.onServiceAction(action)
|
||||
}
|
||||
|
||||
private val _state = MutableStateFlow(MetricsState.Empty)
|
||||
val state: StateFlow<MetricsState> = _state
|
||||
|
||||
|
@ -219,10 +225,10 @@ class MetricsViewModel @Inject constructor(
|
|||
init {
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
radioConfigRepository.nodeDBbyNum
|
||||
.mapLatest { nodes -> nodes[destNum] }
|
||||
.mapLatest { nodes -> nodes[destNum] to nodes.keys.firstOrNull() }
|
||||
.distinctUntilChanged()
|
||||
.onEach { node ->
|
||||
_state.update { state -> state.copy(node = node) }
|
||||
.onEach { (node, ourNode) ->
|
||||
_state.update { state -> state.copy(node = node, isLocal = destNum == ourNode) }
|
||||
node?.user?.hwModel?.let { hwModel ->
|
||||
_state.update { state ->
|
||||
state.copy(deviceHardware = getDeviceHardwareFromHardwareModel(hwModel))
|
||||
|
|
|
@ -54,6 +54,7 @@ import androidx.compose.material.icons.filled.ChargingStation
|
|||
import androidx.compose.material.icons.filled.CheckCircle
|
||||
import androidx.compose.material.icons.filled.Height
|
||||
import androidx.compose.material.icons.filled.History
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material.icons.filled.KeyOff
|
||||
import androidx.compose.material.icons.filled.LightMode
|
||||
import androidx.compose.material.icons.filled.LocationOn
|
||||
|
@ -95,6 +96,7 @@ import com.geeksville.mesh.R
|
|||
import com.geeksville.mesh.model.MetricsState
|
||||
import com.geeksville.mesh.model.MetricsViewModel
|
||||
import com.geeksville.mesh.model.Node
|
||||
import com.geeksville.mesh.service.ServiceAction
|
||||
import com.geeksville.mesh.ui.components.PreferenceCategory
|
||||
import com.geeksville.mesh.ui.preview.NodePreviewParameterProvider
|
||||
import com.geeksville.mesh.ui.theme.AppTheme
|
||||
|
@ -117,7 +119,12 @@ fun NodeDetailScreen(
|
|||
NodeDetailList(
|
||||
node = node,
|
||||
metricsState = state,
|
||||
onNavigate = onNavigate,
|
||||
onAction = { action ->
|
||||
when (action) {
|
||||
is Route -> onNavigate(action)
|
||||
is ServiceAction -> viewModel.onServiceAction(action)
|
||||
}
|
||||
},
|
||||
modifier = modifier,
|
||||
)
|
||||
} else {
|
||||
|
@ -135,7 +142,7 @@ private fun NodeDetailList(
|
|||
modifier: Modifier = Modifier,
|
||||
node: Node,
|
||||
metricsState: MetricsState,
|
||||
onNavigate: (Any) -> Unit = {},
|
||||
onAction: (Any) -> Unit = {},
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
|
@ -172,10 +179,17 @@ private fun NodeDetailList(
|
|||
|
||||
item {
|
||||
PreferenceCategory(stringResource(id = R.string.logs))
|
||||
LogNavigationList(metricsState, onNavigate)
|
||||
LogNavigationList(metricsState, onAction)
|
||||
}
|
||||
|
||||
if (!metricsState.isManaged) {
|
||||
if (!metricsState.isLocal) {
|
||||
item {
|
||||
PreferenceCategory("Actions")
|
||||
NodeActionList(node, onAction)
|
||||
}
|
||||
}
|
||||
|
||||
if (node.metadata != null && !metricsState.isManaged) {
|
||||
item {
|
||||
PreferenceCategory(stringResource(id = R.string.administration))
|
||||
NavCard(
|
||||
|
@ -183,7 +197,7 @@ private fun NodeDetailList(
|
|||
icon = Icons.Default.Settings,
|
||||
enabled = true
|
||||
) {
|
||||
onNavigate(Route.RadioConfig(node.num))
|
||||
onAction(Route.RadioConfig(node.num))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +334,7 @@ private fun NodeDetailsContent(
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun LogNavigationList(state: MetricsState, onNavigate: (Any) -> Unit) {
|
||||
fun LogNavigationList(state: MetricsState, onNavigate: (Route) -> Unit) {
|
||||
NavCard(
|
||||
title = stringResource(R.string.device_metrics_log),
|
||||
icon = Icons.Default.ChargingStation,
|
||||
|
@ -370,6 +384,17 @@ fun LogNavigationList(state: MetricsState, onNavigate: (Any) -> Unit) {
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NodeActionList(node: Node, onAction: (ServiceAction) -> Unit) {
|
||||
NavCard(
|
||||
title = "Request Metadata",
|
||||
icon = Icons.Default.Info,
|
||||
enabled = true
|
||||
) {
|
||||
onAction(ServiceAction.GetDeviceMetadata(node.num))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InfoCard(
|
||||
icon: ImageVector,
|
||||
|
@ -604,7 +629,7 @@ private fun PowerMetrics(node: Node) = with(node.powerMetrics) {
|
|||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun NodeDetailsPreview(
|
||||
private fun NodeDetailPreview(
|
||||
@PreviewParameter(NodePreviewParameterProvider::class)
|
||||
node: Node
|
||||
) {
|
||||
|
|
Ładowanie…
Reference in New Issue