feat: implement snackbar for control actuator

This commit is contained in:
Cutiful 2025-07-05 11:23:49 +07:00
parent 18c5b81ccf
commit 5899b77556

View File

@ -3,19 +3,23 @@ package com.syaroful.agrilinkvocpro.control_feature.presentation.control
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
@ -27,18 +31,23 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.syaroful.agrilinkvocpro.control_feature.R
import com.syaroful.agrilinkvocpro.control_feature.core.components.ControlCard
import com.syaroful.agrilinkvocpro.control_feature.core.components.CustomSnackBar
import com.syaroful.agrilinkvocpro.control_feature.core.components.DisableControlCard
import com.syaroful.agrilinkvocpro.control_feature.core.state.ControlState
import com.syaroful.agrilinkvocpro.control_feature.data.model.ActuatorType
import com.syaroful.agrilinkvocpro.core.placeholder.shimmerEffect
import kotlinx.coroutines.flow.collectLatest
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ControlActuatorScreen(
viewModel: ControlViewModel
viewModel: ControlViewModel,
navController: NavController
) {
val allActuators by viewModel.allActuatorState.collectAsState()
val waterValveStatus by viewModel.waterValveStatus.collectAsState()
@ -48,11 +57,27 @@ fun ControlActuatorScreen(
val isRefreshing = remember { mutableStateOf(false) }
val snackBarHostState = remember { SnackbarHostState() }
LaunchedEffect(Unit) {
viewModel.getActuatorStatus()
viewModel.uiEvent.collectLatest { event ->
val (msg, color) = when (event) {
is ControlUiEvent.Success -> event.message to Color(0xFF4CAF50)
is ControlUiEvent.Error -> event.message to Color(0xFFF44336)
}
snackBarHostState.showSnackbar(message = msg)
}
}
Scaffold(
snackbarHost = {
SnackbarHost(hostState = snackBarHostState) { data ->
CustomSnackBar(
modifier = Modifier.padding(16.dp),
message = data.visuals.message,
icon = if (data.visuals.message.contains("Failed")) Icons.Default.Clear else Icons.Default.Check
)
}
},
topBar = {
TopAppBar(
title = {
@ -63,19 +88,18 @@ fun ControlActuatorScreen(
Text("Control Actuator", style = MaterialTheme.typography.titleMedium)
}
},
navigationIcon = {
IconButton(onClick = { }) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
}
},
actions = {
IconButton(onClick = { }) {
Icon(Icons.Filled.Info, contentDescription = "History")
IconButton(onClick = {
navController.navigate("control_history")
}) {
Icon(Icons.Filled.Refresh, contentDescription = "History")
}
}
)
}
) { innerPadding ->
PullToRefreshBox(
isRefreshing = isRefreshing.value,
onRefresh = {
@ -89,15 +113,11 @@ fun ControlActuatorScreen(
.padding(innerPadding)
.padding(16.dp)
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(16.dp)
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text("Daftar Actuator", style = MaterialTheme.typography.titleMedium)
Spacer(modifier = Modifier.height(1.dp))
// ControlGrid(
// iconRes = R.drawable.ic_valve,
// items = List(4) { index -> "Bet ${index + 1}" }
// )
when (allActuators) {
is ControlState.Loading -> {
isRefreshing.value = false
@ -128,14 +148,24 @@ fun ControlActuatorScreen(
label = "Water Valve",
isOn = waterValveStatus,
isLoading = isLoading,
onToggle = { viewModel.controlActuator(ActuatorType.WATER, !waterValveStatus) }
onToggle = {
viewModel.controlActuator(
ActuatorType.WATER,
!waterValveStatus
)
}
)
ControlCard(
iconRes = R.drawable.ic_leaf,
label = "Nutrient Valve",
isOn = nutritionValveStatus,
isLoading = isLoading,
onToggle = { viewModel.controlActuator(ActuatorType.NUTRIENT, !nutritionValveStatus) }
onToggle = {
viewModel.controlActuator(
ActuatorType.NUTRIENT,
!nutritionValveStatus
)
}
)
ControlCard(
iconRes = R.drawable.ic_valve,
@ -147,8 +177,6 @@ fun ControlActuatorScreen(
}
}
}
}
}