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