InfoScreen 체크박스 상태 저장

This commit is contained in:
areumwoo
2026-03-02 12:45:05 +09:00
parent 53cd5976bb
commit d6efa9bcaa
3 changed files with 86 additions and 5 deletions

View File

@@ -88,4 +88,7 @@ interface Preference {
suspend fun getPowerSupplySerialListFromPreference(): Flow<List<String>> suspend fun getPowerSupplySerialListFromPreference(): Flow<List<String>>
///// /////
suspend fun saveInfoChartLineStates(states: Map<String, Boolean>)
suspend fun getInfoChartLineStates(): Flow<Map<String, Boolean>>
} }

View File

@@ -68,6 +68,9 @@ class PreferenceRepository(private val context: Context) : Preference {
val PRODUCT_SERIAL = stringPreferencesKey("PRODUCT_SERIAL") val PRODUCT_SERIAL = stringPreferencesKey("PRODUCT_SERIAL")
val LASER_HAND_SERIAL = stringPreferencesKey("LASER_HAND_SERIAL") val LASER_HAND_SERIAL = stringPreferencesKey("LASER_HAND_SERIAL")
val POWER_SUPPLY_SERIAL = stringPreferencesKey("POWER_SUPPLY_SERIAL") val POWER_SUPPLY_SERIAL = stringPreferencesKey("POWER_SUPPLY_SERIAL")
// InfoScreen Chart Checkboxes
val INFO_CHART_LINE_STATES = stringPreferencesKey("INFO_CHART_LINE_STATES")
} }
override suspend fun clearAllPreferences() { override suspend fun clearAllPreferences() {
@@ -559,4 +562,31 @@ class PreferenceRepository(private val context: Context) : Preference {
emit(listOf("B", "U", "O", "C", "L", "D")) emit(listOf("B", "U", "O", "C", "L", "D"))
} }
} }
override suspend fun saveInfoChartLineStates(states: Map<String, Boolean>) {
try {
val stateJson = gson.toJson(states)
context.datastore.edit { preferences ->
preferences[INFO_CHART_LINE_STATES] = stateJson
}
} catch (e: Exception) {
Timber.e(e, "Failed to serialize INFO_CHART_LINE_STATES to JSON.")
}
}
override suspend fun getInfoChartLineStates(): Flow<Map<String, Boolean>> {
return context.datastore.data.map { preferences ->
preferences[INFO_CHART_LINE_STATES]
}.distinctUntilChanged().map { jsonString ->
if (!jsonString.isNullOrBlank()) {
val type = object : TypeToken<Map<String, Boolean>>() {}.type
gson.fromJson<Map<String, Boolean>>(jsonString, type) ?: emptyMap()
} else {
emptyMap()
}
}.catch { e ->
Timber.e(e, "Failed to get or parse INFO_CHART_LINE_STATES. Emitting default.")
emit(emptyMap())
}
}
} }

View File

@@ -1,10 +1,14 @@
package com.laseroptek.raman.ui.screens.info package com.laseroptek.raman.ui.screens.info
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import com.laseroptek.raman.repository.PreferenceRepository
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@@ -25,10 +29,13 @@ data class ChartUiState(
val chamber2State: Boolean = true, val chamber2State: Boolean = true,
val basePlateState: Boolean = true, val basePlateState: Boolean = true,
val waterState: Boolean = true, val waterState: Boolean = true,
) ) {
companion object
}
@HiltViewModel @HiltViewModel
class InfoViewModel @Inject constructor( class InfoViewModel @Inject constructor(
private val preferenceRepository: PreferenceRepository,
) : ViewModel() { ) : ViewModel() {
// This is the single source of truth for the checkbox states. // This is the single source of truth for the checkbox states.
@@ -39,7 +46,7 @@ class InfoViewModel @Inject constructor(
fun toggleLine(line: ChartLine) { fun toggleLine(line: ChartLine) {
// .update is a thread-safe way to update the state. // .update is a thread-safe way to update the state.
_chartUiState.update { currentState -> _chartUiState.update { currentState ->
when (line) { val updatedState = when (line) {
ChartLine.INT_TEMP -> currentState.copy(intTempState = !currentState.intTempState) ChartLine.INT_TEMP -> currentState.copy(intTempState = !currentState.intTempState)
ChartLine.EXT_TEMP -> currentState.copy(extTempState = !currentState.extTempState) ChartLine.EXT_TEMP -> currentState.copy(extTempState = !currentState.extTempState)
ChartLine.INT_HUMIDITY -> currentState.copy(intHumidityState = !currentState.intHumidityState) ChartLine.INT_HUMIDITY -> currentState.copy(intHumidityState = !currentState.intHumidityState)
@@ -50,10 +57,51 @@ class InfoViewModel @Inject constructor(
ChartLine.BASE_PLATE -> currentState.copy(basePlateState = !currentState.basePlateState) ChartLine.BASE_PLATE -> currentState.copy(basePlateState = !currentState.basePlateState)
ChartLine.WATER -> currentState.copy(waterState = !currentState.waterState) ChartLine.WATER -> currentState.copy(waterState = !currentState.waterState)
} }
persistChartUiState(updatedState)
updatedState
} }
} }
init { init {
Timber.d("InfoViewModel init") Timber.d("InfoViewModel init")
viewModelScope.launch {
preferenceRepository.getInfoChartLineStates().collectLatest { savedStates ->
if (savedStates.isEmpty()) return@collectLatest
_chartUiState.update { ChartUiState.fromPreference(savedStates) }
} }
} }
}
private fun persistChartUiState(state: ChartUiState) {
viewModelScope.launch {
preferenceRepository.saveInfoChartLineStates(state.toPreferenceMap())
}
}
}
private fun ChartUiState.toPreferenceMap(): Map<String, Boolean> = mapOf(
ChartLine.INT_TEMP.name to intTempState,
ChartLine.EXT_TEMP.name to extTempState,
ChartLine.INT_HUMIDITY.name to intHumidityState,
ChartLine.EXT_HUMIDITY.name to extHumidityState,
ChartLine.KTP.name to ktpState,
ChartLine.CHAMBER1.name to chamber1State,
ChartLine.CHAMBER2.name to chamber2State,
ChartLine.BASE_PLATE.name to basePlateState,
ChartLine.WATER.name to waterState,
)
private fun ChartUiState.Companion.fromPreference(savedStates: Map<String, Boolean>): ChartUiState {
val defaults = ChartUiState()
return ChartUiState(
intTempState = savedStates[ChartLine.INT_TEMP.name] ?: defaults.intTempState,
extTempState = savedStates[ChartLine.EXT_TEMP.name] ?: defaults.extTempState,
intHumidityState = savedStates[ChartLine.INT_HUMIDITY.name] ?: defaults.intHumidityState,
extHumidityState = savedStates[ChartLine.EXT_HUMIDITY.name] ?: defaults.extHumidityState,
ktpState = savedStates[ChartLine.KTP.name] ?: defaults.ktpState,
chamber1State = savedStates[ChartLine.CHAMBER1.name] ?: defaults.chamber1State,
chamber2State = savedStates[ChartLine.CHAMBER2.name] ?: defaults.chamber2State,
basePlateState = savedStates[ChartLine.BASE_PLATE.name] ?: defaults.basePlateState,
waterState = savedStates[ChartLine.WATER.name] ?: defaults.waterState,
)
}