feat: integrate sensor data fetching and pull-to-refresh on HomeScreen
This commit is contained in:
parent
82c8093d1e
commit
c2fbd6fa25
|
|
@ -1,13 +1,13 @@
|
|||
package com.syaroful.agrilinkvocpro.ui.screen.home
|
||||
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import androidx.activity.viewModels
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
|
|
@ -16,108 +16,160 @@ 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.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Person
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
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.Text
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.syaroful.agrilinkvocpro.R
|
||||
import com.syaroful.agrilinkvocpro.core.components.DefaultErrorComponent
|
||||
import com.syaroful.agrilinkvocpro.core.components.DownloadProgressDialog
|
||||
import com.syaroful.agrilinkvocpro.core.components.MenuItemButton
|
||||
import com.syaroful.agrilinkvocpro.core.components.textTheme
|
||||
import com.syaroful.agrilinkvocpro.core.route.Screen
|
||||
import com.syaroful.agrilinkvocpro.presentation.dynamicModule.DynamicModuleViewModel
|
||||
import com.syaroful.agrilinkvocpro.core.utils.ResultState
|
||||
import com.syaroful.agrilinkvocpro.data.model.SensorDataResponse
|
||||
import com.syaroful.agrilinkvocpro.ui.theme.AgrilinkVocproTheme
|
||||
import com.syaroful.agrilinkvocpro.ui.theme.LightGrey
|
||||
import com.syaroful.agrilinkvocpro.ui.theme.MainGreen
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
import kotlin.math.log
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun HomeScreen(
|
||||
navController: NavController,
|
||||
onFeatureClick: (String) -> Unit,
|
||||
dialogState: MutableState<String?>,
|
||||
homeViewModel: HomeViewModel = viewModel()
|
||||
dynamicModuleViewModel: DynamicModuleViewModel,
|
||||
homeViewModel: HomeViewModel = koinViewModel()
|
||||
) {
|
||||
val CONTROL_FEATURE_MODULE_NAME = "control_feature"
|
||||
// State untuk menampilkan dialog log/progress
|
||||
val showProgressDialog by dynamicModuleViewModel.showProgressDialog.collectAsState()
|
||||
val progressMessage by dynamicModuleViewModel.progressMessage.collectAsState()
|
||||
val progressPercent by dynamicModuleViewModel.progressPercent.collectAsState()
|
||||
|
||||
// State untuk menampilkan dialog log/progress
|
||||
val showProgressDialog: MutableState<Boolean> = mutableStateOf(false)
|
||||
val progressMessage = mutableStateOf("")
|
||||
val progressPercent = mutableFloatStateOf(0f)
|
||||
|
||||
val currentModuleToDownload = mutableStateOf<String?>(null)
|
||||
val homeState by homeViewModel.homeState.collectAsState()
|
||||
val isRefreshing = remember { mutableStateOf(false) }
|
||||
AgrilinkVocproTheme {
|
||||
Scaffold { padding ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(padding)
|
||||
.fillMaxWidth()
|
||||
PullToRefreshBox(
|
||||
isRefreshing = isRefreshing.value,
|
||||
onRefresh = {
|
||||
isRefreshing.value = true
|
||||
homeViewModel.printUserToken()
|
||||
homeViewModel.getGreenHouseData()
|
||||
},
|
||||
) {
|
||||
GreenHouseInformationSection(navController = navController)
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
DynamicFeatureSection(
|
||||
onFeatureClick = onFeatureClick
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Text(
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 20.dp)
|
||||
.fillMaxWidth(),
|
||||
text = "Data Sensor Green House",
|
||||
textAlign = TextAlign.Center,
|
||||
style = textTheme.bodyMedium
|
||||
)
|
||||
BetDataComponent(
|
||||
onClick = { },
|
||||
betNUmber = 1,
|
||||
commodity = "Labu Kabocha",
|
||||
nitrogenValue = "120",
|
||||
phosphorValue = "34",
|
||||
potassiumValue = "65",
|
||||
commodityImage = painterResource(id = R.drawable.kabocha)
|
||||
)
|
||||
BetDataComponent(
|
||||
onClick = { },
|
||||
betNUmber = 2,
|
||||
commodity = "Melon",
|
||||
nitrogenValue = "154",
|
||||
phosphorValue = "45",
|
||||
potassiumValue = "32",
|
||||
commodityImage = painterResource(id = R.drawable.melon)
|
||||
)
|
||||
BetDataComponent(
|
||||
onClick = { },
|
||||
betNUmber = 3,
|
||||
commodity = "Kale",
|
||||
nitrogenValue = "230",
|
||||
phosphorValue = "50",
|
||||
potassiumValue = "40",
|
||||
commodityImage = painterResource(id = R.drawable.kale)
|
||||
)
|
||||
.padding(padding)
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
GreenHouseInformationSection(navController = navController)
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
DynamicFeatureSection(
|
||||
onFeatureClick = onFeatureClick
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 20.dp)
|
||||
.fillMaxWidth(),
|
||||
text = "Data Sensor Green House",
|
||||
textAlign = TextAlign.Center,
|
||||
style = textTheme.bodyMedium
|
||||
)
|
||||
when (homeState) {
|
||||
is ResultState.Loading -> {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
}
|
||||
|
||||
is ResultState.Success -> {
|
||||
isRefreshing.value = false
|
||||
val data = (homeState as ResultState.Success).data
|
||||
data?.data?.let { sensorData ->
|
||||
BetDataComponent(
|
||||
onClick = {
|
||||
navController.navigate("detail-screen")
|
||||
},
|
||||
betNUmber = 1,
|
||||
commodity = "Kabocha",
|
||||
nitrogenValue = sensorData.npk1?.soilnitrogen.toString(),
|
||||
phosphorValue = sensorData.npk1?.soilphosphorus.toString(),
|
||||
potassiumValue = sensorData.npk1?.soilpotassium.toString(),
|
||||
commodityImage = painterResource(id = R.drawable.kabocha)
|
||||
)
|
||||
BetDataComponent(
|
||||
onClick = {
|
||||
navController.navigate("detail-screen")
|
||||
},
|
||||
betNUmber = 2,
|
||||
commodity = "Melon",
|
||||
nitrogenValue = sensorData.npk2?.soilnitrogen.toString(),
|
||||
phosphorValue = sensorData.npk2?.soilphosphorus.toString(),
|
||||
potassiumValue = sensorData.npk2?.soilpotassium.toString(),
|
||||
commodityImage = painterResource(id = R.drawable.melon)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is ResultState.Error -> {
|
||||
isRefreshing.value = false
|
||||
DefaultErrorComponent(
|
||||
modifier = Modifier.padding(vertical = 20.dp),
|
||||
label = "Oops!",
|
||||
message = (homeState as ResultState.Error).message
|
||||
)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DownloadProgressDialog(
|
||||
showDialog = showProgressDialog,
|
||||
message = progressMessage,
|
||||
progress = progressPercent,
|
||||
onDismiss = { dynamicModuleViewModel.setDialogVisibility(false) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun BetDataComponent(
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -148,7 +200,7 @@ private fun BetDataComponent(
|
|||
.clip(shape = RoundedCornerShape(16.dp))
|
||||
.fillMaxWidth()
|
||||
.background(
|
||||
color = if (isSystemInDarkTheme()) Color.Black else Color.White,
|
||||
color = MaterialTheme.colorScheme.surfaceContainer,
|
||||
)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
|
|
@ -217,17 +269,17 @@ fun DynamicFeatureSection(
|
|||
MenuItemButton(
|
||||
label = "Resep\nPertumbuhan",
|
||||
icon = painterResource(id = R.drawable.growth_recipe_icon),
|
||||
onClick = { onFeatureClick("recipe_feature") },
|
||||
onClick = { onFeatureClick("growth_recipe_feature") },
|
||||
)
|
||||
MenuItemButton(
|
||||
label = "Harga\nKomoditas",
|
||||
icon = painterResource(id = R.drawable.commodity_price_prediction_icon),
|
||||
onClick = { onFeatureClick("commodity_price_feature") },
|
||||
onClick = { onFeatureClick("commodity_price_prediction_feature") },
|
||||
)
|
||||
MenuItemButton(
|
||||
label = "Deteksi\nPenyakit",
|
||||
icon = painterResource(id = R.drawable.plant_disease_detection_icon),
|
||||
onClick = { onFeatureClick("diseasedetection_feature") },
|
||||
onClick = { onFeatureClick("plant_disease_detection_feature") },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -237,8 +289,8 @@ fun GreenHouseInformationSection(navController: NavController) {
|
|||
Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth()) {
|
||||
IconButton(
|
||||
onClick = {
|
||||
navController.navigate(Screen.Profile.route) {
|
||||
popUpTo(Screen.Profile.route) {
|
||||
navController.navigate("profile") {
|
||||
popUpTo("profile") {
|
||||
inclusive = true
|
||||
}
|
||||
}
|
||||
|
|
@ -285,15 +337,13 @@ fun GreenHouseInformationSection(navController: NavController) {
|
|||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, name = "Light Mode")
|
||||
@Preview(showBackground = true, name = "Dark Mode", uiMode = UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
fun HomePreview() {
|
||||
val navController = rememberNavController()
|
||||
val state = remember { mutableStateOf<String?>(null) }
|
||||
HomeScreen(
|
||||
navController = navController,
|
||||
onFeatureClick = {},
|
||||
dialogState = state
|
||||
)
|
||||
}
|
||||
//@Preview(showBackground = true, name = "Light Mode")
|
||||
//@Preview(showBackground = true, name = "Dark Mode", uiMode = UI_MODE_NIGHT_YES)
|
||||
//@Composable
|
||||
//fun HomePreview() {
|
||||
// val navController = rememberNavController()
|
||||
// HomeScreen(
|
||||
// navController = navController,
|
||||
// onFeatureClick = {},
|
||||
// )
|
||||
//}
|
||||
Loading…
Reference in New Issue
Block a user