feat: tidy up code

This commit is contained in:
Cutiful 2025-05-20 18:02:05 +07:00
parent ae6e0a31db
commit ce5ddf39e0
12 changed files with 380 additions and 161 deletions

View File

@ -49,6 +49,10 @@
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewParameterProviderOnFirstParameter" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />

View File

@ -6,134 +6,53 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.lifecycleScope
import com.syaroful.agrilinkvocpro.core.components.DownloadModuleConfirmationDialog
import com.syaroful.agrilinkvocpro.core.components.DownloadProgressDialog
import com.syaroful.agrilinkvocpro.core.utils.DownloadState
import com.syaroful.agrilinkvocpro.presentation.dynamicModule.DynamicModuleViewModel
import com.syaroful.agrilinkvocpro.ui.screen.home.HomeScreen
import com.syaroful.agrilinkvocpro.core.route.SetupNavigation
import com.syaroful.agrilinkvocpro.ui.screen.home.HomeViewModel
import com.syaroful.agrilinkvocpro.ui.theme.AgrilinkVocproTheme
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
@Suppress("DEPRECATION")
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
private val viewModel: DynamicModuleViewModel by viewModels()
private val CONTROL_FEATURE_MODULE_NAME = "control_feature"
// State untuk menampilkan dialog log/progress
private val showProgressDialog = mutableStateOf(false)
private val progressMessage = mutableStateOf("")
private val progressPercent = mutableFloatStateOf(0f)
private val currentModuleToDownload = mutableStateOf<String?>(null)
private val homeViewModel: HomeViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
AgrilinkVocproTheme {
HomeScreen(
onControlFeatureClick = { onFeatureClicked("control_feature") },
onRecipeFeatureClick = { onFeatureClicked("recipe_feature") },
onPricePredictionFeatureClick = { onFeatureClicked("price_prediction_feature") },
onPlantDiseaseDetectionFeatureClick = { onFeatureClicked("diseasedetection_feature") },
dialogState = currentModuleToDownload
SetupNavigation(
homeViewModel = homeViewModel,
onLaunchFeature = { className ->
val intent = Intent().apply {
setClassName(packageName, className)
}
startActivity(intent)
}
)
DownloadProgressDialog(
showDialog = showProgressDialog.value,
message = progressMessage.value,
progress = progressPercent.floatValue,
onDismiss = { showProgressDialog.value = false }
showDialog = homeViewModel.showProgressDialog.value,
message = homeViewModel.progressMessage.value,
progress = homeViewModel.progressPercent.floatValue,
onDismiss = {homeViewModel.showProgressDialog.value = false}
)
DownloadModuleConfirmationDialog(
moduleName = currentModuleToDownload.value,
onDismiss = { currentModuleToDownload.value = null },
onClickConfirm = {
currentModuleToDownload.value?.let { moduleName ->
downloadDynamicModule(moduleName)
}
currentModuleToDownload.value = null
}
moduleName = homeViewModel.currentModuleToDownload.value,
onDismiss = { homeViewModel.currentModuleToDownload.value = null },
onClickConfirm = { homeViewModel.confirmDownload { startFeature(it) } }
)
}
}
observeDownloadStatus()
}
private fun observeDownloadStatus() {
lifecycleScope.launchWhenStarted {
viewModel.downloadState.collect { status ->
when (status) {
is DownloadState.Idle -> {
showProgressDialog.value = false
progressMessage.value = ""
progressPercent.floatValue = 0f
private fun startFeature(className: String) {
val intent = Intent().apply {
setClassName(packageName, className)
}
is DownloadState.Starting -> {
showProgressDialog.value = true
progressMessage.value = "Starting download..."
progressPercent.floatValue = 0f
}
is DownloadState.Downloading -> {
showProgressDialog.value = true
progressMessage.value = "Downloading module..."
// Progress update akan di-handle via listener tambahan (lihat catatan di bawah)
}
is DownloadState.Downloaded -> {
progressMessage.value = "Download completed"
progressPercent.floatValue = 1f
}
is DownloadState.Installed -> {
progressMessage.value = "Install completed"
progressPercent.floatValue = 1f
// Tutup dialog setelah beberapa saat
delayAndDismissDialog()
}
is DownloadState.Failed -> {
progressMessage.value = "Failed: ${status.message}"
showProgressDialog.value = true
progressPercent.floatValue = 0f
}
is DownloadState.DownloadingWithProgress -> {
showProgressDialog.value = true
}
}
}
}
}
private fun onFeatureClicked(moduleName: String) {
if (viewModel.isModuleDownloaded(moduleName)) {
startFeatureActivity(moduleName)
} else {
currentModuleToDownload.value = moduleName
}
}
private fun delayAndDismissDialog() {
lifecycleScope.launch {
kotlinx.coroutines.delay(1500)
showProgressDialog.value = false
currentModuleToDownload.value?.let { startFeatureActivity(it) }
currentModuleToDownload.value = null
}
}
private fun downloadDynamicModule(moduleName: String) {
viewModel.downloadModule(moduleName)
startActivity(intent)
}
private fun startFeatureActivity(moduleName: String) {

View File

@ -6,4 +6,3 @@ import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class MyApplication : Application() {
}

View File

@ -30,9 +30,11 @@ fun MenuItemButton(
icon: Painter,
onClick: () -> Unit = {}
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
OutlinedButton(
onClick = onClick,
onClick = { onClick() },
modifier = Modifier.size(48.dp),
shape = CircleShape,
border = BorderStroke(0.dp, Color.Transparent),
@ -59,6 +61,9 @@ fun MenuItemButton(
@Preview
@Composable
fun MenuItemPreview(){
MenuItemButton(label = "Kontrol\nAktuator",icon = painterResource(id = R.drawable.control_actuator_icon))
fun MenuItemPreview() {
MenuItemButton(
label = "Kontrol\nAktuator",
icon = painterResource(id = R.drawable.control_actuator_icon)
)
}

View File

@ -0,0 +1,37 @@
package com.syaroful.agrilinkvocpro.core.route
import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.syaroful.agrilinkvocpro.ui.screen.home.HomeScreen
import com.syaroful.agrilinkvocpro.ui.screen.home.HomeViewModel
import com.syaroful.agrilinkvocpro.ui.screen.profile.ProfileScreen
sealed class Screen(val route: String) {
object Home : Screen("home")
object Profile : Screen("profile")
}
@Composable
fun SetupNavigation(
homeViewModel: HomeViewModel,
onLaunchFeature: (String) -> Unit
) {
val navController = rememberNavController()
NavHost(navController, startDestination = "home") {
composable("home") {
HomeScreen(
navController = navController,
onFeatureClick = { moduleName ->
homeViewModel.onFeatureClicked(moduleName, onLaunchFeature)
},
dialogState = homeViewModel.currentModuleToDownload,
homeViewModel = homeViewModel
)
}
composable("profile"){
ProfileScreen()
}
}
}

View File

@ -0,0 +1,6 @@
package com.syaroful.agrilinkvocpro.presentation.event
sealed class HomeUiEvent {
data class RequestModule(val moduleName: String) : HomeUiEvent()
data class ConfirmDownload(val moduleName: String) : HomeUiEvent()
}

View File

@ -1,8 +1,12 @@
package com.syaroful.agrilinkvocpro.ui.screen.home
import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.activity.viewModels
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.Column
import androidx.compose.foundation.layout.Row
@ -21,104 +25,160 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
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.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.ui.theme.AgrilinkVocproTheme
import com.syaroful.agrilinkvocpro.ui.theme.LightGrey
import com.syaroful.agrilinkvocpro.ui.theme.MainGreen
@Composable
fun HomeScreen(
onControlFeatureClick: () -> Unit,
onRecipeFeatureClick: () -> Unit,
onPricePredictionFeatureClick: () -> Unit,
onPlantDiseaseDetectionFeatureClick: () -> Unit,
dialogState: MutableState<String?>
navController: NavController,
onFeatureClick: (String) -> Unit,
dialogState: MutableState<String?>,
homeViewModel: HomeViewModel = viewModel()
) {
val CONTROL_FEATURE_MODULE_NAME = "control_feature"
// State untuk menampilkan dialog log/progress
val showProgressDialog: MutableState<Boolean> = mutableStateOf(false)
val progressMessage = mutableStateOf("")
val progressPercent = mutableFloatStateOf(0f)
val currentModuleToDownload = mutableStateOf<String?>(null)
AgrilinkVocproTheme {
Scaffold { padding ->
Column(
modifier = Modifier
.padding(padding)
.fillMaxWidth()
) {
GreenHouseInformationSection()
GreenHouseInformationSection(navController = navController)
Spacer(modifier = Modifier.height(20.dp))
DynamicFeatureSection(
onControlFeatureClick = onControlFeatureClick,
onRecipeFeatureClick = onRecipeFeatureClick,
onPricePredictionFeatureClick = onPricePredictionFeatureClick,
onPlantDiseaseDetectionFeatureClick = onPlantDiseaseDetectionFeatureClick
onFeatureClick = onFeatureClick
)
Spacer(modifier = Modifier.height(32.dp))
Text(
modifier = Modifier.padding(horizontal = 20.dp).fillMaxWidth(),
modifier = Modifier
.padding(horizontal = 20.dp)
.fillMaxWidth(),
text = "Data Sensor Green House",
textAlign = TextAlign.Center,
style = textTheme.bodyMedium
)
BetDataComponent()
BetDataComponent()
BetDataComponent()
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)
)
}
}
}
}
@Composable
private fun BetDataComponent() {
Column(Modifier.padding(horizontal = 20.dp, vertical = 8.dp)) {
private fun BetDataComponent(
modifier: Modifier = Modifier,
onClick: () -> Unit,
betNUmber: Int,
commodity: String,
nitrogenValue: String,
phosphorValue: String,
potassiumValue: String,
commodityImage: Painter
) {
Column(
modifier
.padding(horizontal = 20.dp, vertical = 8.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Absolute.SpaceBetween
) {
Text("Bet 1")
Text("Labu Kabocha", color = MainGreen)
Text("Bet $betNUmber")
Text(commodity, color = MainGreen)
}
Spacer(modifier = Modifier.height(4.dp))
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.clip(shape = RoundedCornerShape(16.dp))
.fillMaxWidth()
.background(
color = if (isSystemInDarkTheme()) Color.Black else Color.White,
)
.border(
width = 1.dp,
color = MainGreen.copy(alpha = 0.4f),
shape = RoundedCornerShape(16.dp)
)
.clickable { onClick() }
.padding(horizontal = 16.dp, vertical = 8.dp)
)
{
SensorDataItem(
icon = "N",
label = "Nitrogen",
value = 230.toString()
value = nitrogenValue
)
SensorDataItem(
icon = "P",
label = "Phosphor",
value = 50.toString()
value = phosphorValue
)
SensorDataItem(
icon = "K",
label = "Potassium",
value = 40.toString()
value = potassiumValue
)
Image(
modifier = Modifier.height(60.dp),
painter = painterResource(id = R.drawable.kabocha),
modifier = Modifier
.height(60.dp)
.width(60.dp),
painter = commodityImage,
contentDescription = "Commodity"
)
}
@ -134,16 +194,14 @@ private fun SensorDataItem(
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = icon, color = MainGreen, style = textTheme.headlineMedium)
Text(text = label, color = LightGrey, style = textTheme.bodySmall)
Spacer(modifier = Modifier.height(8.dp))
Text(text = value, style = textTheme.headlineSmall)
}
}
@Composable
fun DynamicFeatureSection(
onControlFeatureClick: () -> Unit,
onRecipeFeatureClick: () -> Unit,
onPricePredictionFeatureClick: () -> Unit,
onPlantDiseaseDetectionFeatureClick: () -> Unit
onFeatureClick: (String) -> Unit
) {
Row(
modifier = Modifier
@ -154,31 +212,37 @@ fun DynamicFeatureSection(
MenuItemButton(
label = "Kontrol\nAktuator",
icon = painterResource(id = R.drawable.control_actuator_icon),
onClick = onControlFeatureClick
onClick = { onFeatureClick("control_feature") },
)
MenuItemButton(
label = "Resep\nPertumbuhan",
icon = painterResource(id = R.drawable.growth_recipe_icon),
onClick = onRecipeFeatureClick
onClick = { onFeatureClick("recipe_feature") },
)
MenuItemButton(
label = "Harga\nKomoditas",
icon = painterResource(id = R.drawable.commodity_price_prediction_icon),
onClick = onPricePredictionFeatureClick
onClick = { onFeatureClick("commodity_price_feature") },
)
MenuItemButton(
label = "Deteksi\nPenyakit",
icon = painterResource(id = R.drawable.plant_disease_detection_icon),
onClick = onPlantDiseaseDetectionFeatureClick
onClick = { onFeatureClick("diseasedetection_feature") },
)
}
}
@Composable
fun GreenHouseInformationSection() {
fun GreenHouseInformationSection(navController: NavController) {
Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth()) {
IconButton(
onClick = {},
onClick = {
navController.navigate(Screen.Profile.route) {
popUpTo(Screen.Profile.route) {
inclusive = true
}
}
},
modifier = Modifier.align(Alignment.CenterVertically)
) {
Icon(
@ -225,12 +289,11 @@ fun GreenHouseInformationSection() {
@Preview(showBackground = true, name = "Dark Mode", uiMode = UI_MODE_NIGHT_YES)
@Composable
fun HomePreview() {
val state = remember { mutableStateOf<String?>("control_feature") }
val navController = rememberNavController()
val state = remember { mutableStateOf<String?>(null) }
HomeScreen(
onControlFeatureClick = {},
onRecipeFeatureClick = {},
onPricePredictionFeatureClick = {},
onPlantDiseaseDetectionFeatureClick = {},
navController = navController,
onFeatureClick = {},
dialogState = state
)
}

View File

@ -0,0 +1,184 @@
package com.syaroful.agrilinkvocpro.ui.screen.home
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.android.play.core.splitinstall.SplitInstallException
import com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener
import com.google.android.play.core.splitinstall.model.SplitInstallErrorCode
import com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus
import com.syaroful.agrilinkvocpro.core.utils.DownloadState
import com.syaroful.agrilinkvocpro.data.repository.DynamicModuleRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class HomeViewModel @Inject constructor(
private val dynamicModuleRepository: DynamicModuleRepository
) : ViewModel() {
var currentModuleToDownload = mutableStateOf<String?>(null)
private set
var showProgressDialog = mutableStateOf(false)
private set
var progressMessage = mutableStateOf("")
private set
var progressPercent = mutableFloatStateOf(0f)
private set
private val _downloadState = MutableStateFlow<DownloadState>(DownloadState.Idle)
private val downloadState: StateFlow<DownloadState> = _downloadState.asStateFlow()
private val listener = SplitInstallStateUpdatedListener { state ->
if (state.sessionId() == dynamicModuleRepository.getSessionId()) {
when (state.status()) {
SplitInstallSessionStatus.DOWNLOADING -> {
val progress = if (state.totalBytesToDownload() > 0)
state.bytesDownloaded().toFloat() / state.totalBytesToDownload()
else 0f
_downloadState.value = DownloadState.DownloadingWithProgress(progress)
}
SplitInstallSessionStatus.DOWNLOADED -> {
_downloadState.value = DownloadState.Downloaded
}
SplitInstallSessionStatus.INSTALLED -> {
_downloadState.value = DownloadState.Installed
}
SplitInstallSessionStatus.FAILED -> {
_downloadState.value = DownloadState.Failed("Installation Failed")
}
SplitInstallSessionStatus.CANCELED -> {
_downloadState.value = DownloadState.Failed("Installation Canceled")
}
else -> {}
}
}
}
fun onFeatureClicked(moduleName: String, onLaunch: (String) -> Unit) {
if (isModuleDownloaded(moduleName)) {
startFeatureActivity(moduleName, onLaunch)
} else {
currentModuleToDownload.value = moduleName
}
}
fun confirmDownload(onLaunch: (String) -> Unit) {
currentModuleToDownload.value?.let {
downloadDynamicModule(it, onLaunch)
}
currentModuleToDownload.value = null
}
private fun downloadDynamicModule(moduleName: String, onLaunch: (String) -> Unit) {
_downloadState.value = DownloadState.Starting
dynamicModuleRepository.startDownload(moduleName, listener)
.addOnFailureListener { exception ->
val errorCode = (exception as? SplitInstallException)?.errorCode ?: -1
val errorMessage = when (errorCode) {
SplitInstallErrorCode.NETWORK_ERROR -> "No Internet Connection"
SplitInstallErrorCode.MODULE_UNAVAILABLE -> "Module Unavailable"
SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED -> "Active Session Limit Exceeded"
SplitInstallErrorCode.INSUFFICIENT_STORAGE -> "Insufficient Storage"
SplitInstallErrorCode.PLAY_STORE_NOT_FOUND -> "Play Store Not Found"
else -> "Unknown Error: $errorCode"
}
_downloadState.value = DownloadState.Failed(errorMessage)
}
observeDownloadStatus(onLaunch)
}
private fun isModuleDownloaded(moduleName: String): Boolean {
return dynamicModuleRepository.isModuleDownloaded(moduleName)
}
private fun observeDownloadStatus(onLaunch: (String) -> Unit) {
viewModelScope.launch {
downloadState.collect { status ->
when (status) {
is DownloadState.Idle -> {
showProgressDialog.value = false
progressMessage.value = ""
progressPercent.floatValue = 0f
}
is DownloadState.Starting -> {
showProgressDialog.value = true
progressMessage.value = "Starting download..."
progressPercent.floatValue = 0f
}
is DownloadState.Downloading -> {
showProgressDialog.value = true
progressMessage.value = "Downloading module..."
}
is DownloadState.Downloaded -> {
progressMessage.value = "Download completed"
progressPercent.floatValue = 1f
}
is DownloadState.Installed -> {
progressMessage.value = "Install completed"
progressPercent.floatValue = 1f
delayAndDismissDialog(onLaunch)
}
is DownloadState.Failed -> {
progressMessage.value = "Failed: ${status.message}"
showProgressDialog.value = true
progressPercent.floatValue = 0f
}
is DownloadState.DownloadingWithProgress -> {
showProgressDialog.value = true
progressPercent.floatValue = status.progress
}
}
}
}
}
private fun delayAndDismissDialog(onLaunch: (String) -> Unit) {
viewModelScope.launch {
delay(1500)
showProgressDialog.value = false
currentModuleToDownload.value?.let {
startFeatureActivity(it, onLaunch)
}
currentModuleToDownload.value = null
}
}
private fun startFeatureActivity(moduleName: String, onLaunch: (String) -> Unit) {
val className = when (moduleName) {
"control_feature" -> "com.syaroful.agrilinkvocpro.control_feature.ControlActuatorActivity"
"recipe_feature" -> "com.syaroful.agrilinkvocpro.recipe_feature.RecipeActivity"
"price_prediction_feature" -> "com.syaroful.agrilinkvocpro.price_prediction_feature.PricePredictionActivity"
"plant_disease_detection_feature" -> "com.syaroful.agrilinkvocpro.diseasedetection_feature.PlantDiseaseDetectionActivity"
else -> null
}
className?.let { onLaunch(it) }
}
override fun onCleared() {
super.onCleared()
dynamicModuleRepository.unregisterListener(listener)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -2,6 +2,7 @@ package com.syaroful.agrilinkvocpro.control_feature.components
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -26,8 +27,8 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.syaroful.agrilinkvocpro.control_feature.ui.theme.DarkGreen
import com.syaroful.agrilinkvocpro.control_feature.ui.theme.DarkGrey
import com.syaroful.agrilinkvocpro.control_feature.ui.theme.DividerColor
import com.syaroful.agrilinkvocpro.control_feature.ui.theme.Grey10
import com.syaroful.agrilinkvocpro.control_feature.ui.theme.MainGreen
@ -38,14 +39,15 @@ fun ControlCard(
isOn: Boolean,
onToggle: (Boolean) -> Unit
) {
val backgroundColor = if (isOn) DarkGreen else Color.White
val backgroundColor = if (isOn) DarkGreen else if (isSystemInDarkTheme()) Color.Black else Color.White
val iconTint = if (isOn) Color(0xFFB2FF59) else Color(0xFF4CAF50)
val textColor = if (isOn) MainGreen else MainGreen
val textColor = if (isSystemInDarkTheme()) Color.White else Color.Black
val trackColor = if (isSystemInDarkTheme()) DarkGrey else DividerColor
Column(
modifier = Modifier
.clip(RoundedCornerShape(12.dp))
.border(1.dp, Grey10, RoundedCornerShape(12.dp))
.border(1.dp, MainGreen.copy(alpha = 0.4f), RoundedCornerShape(12.dp))
.background(backgroundColor)
.padding(16.dp)
.fillMaxWidth()
@ -77,20 +79,20 @@ fun ControlCard(
colors = SwitchDefaults.colors(
checkedThumbColor = DarkGreen,
uncheckedThumbColor = Color.White,
uncheckedBorderColor = DividerColor,
uncheckedBorderColor = trackColor,
checkedTrackColor = MainGreen,
uncheckedTrackColor = DividerColor
uncheckedTrackColor = trackColor
)
)
}
Spacer(modifier = Modifier.height(16.dp))
Text(label, color = if (isOn) Color.White else Color.Black)
Text(label, color = if (isOn) Color.White else textColor)
Text(
if (isOn) "On" else "Off",
color = textColor,
color = MainGreen,
fontWeight = FontWeight.Bold
)
}