From d6efa9bcaa4f4fb59bcb683a61339d4f5b5b068d Mon Sep 17 00:00:00 2001 From: areumwoo Date: Mon, 2 Mar 2026 12:45:05 +0900 Subject: [PATCH] =?UTF-8?q?InfoScreen=20=EC=B2=B4=ED=81=AC=EB=B0=95?= =?UTF-8?q?=EC=8A=A4=20=EC=83=81=ED=83=9C=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/source/preference/Preference.kt | 5 +- .../raman/repository/PreferenceRepository.kt | 32 ++++++++++- .../raman/ui/screens/info/InfoViewModel.kt | 54 +++++++++++++++++-- 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/laseroptek/raman/data/source/preference/Preference.kt b/app/src/main/java/com/laseroptek/raman/data/source/preference/Preference.kt index b5ec628..a3e70ec 100644 --- a/app/src/main/java/com/laseroptek/raman/data/source/preference/Preference.kt +++ b/app/src/main/java/com/laseroptek/raman/data/source/preference/Preference.kt @@ -88,4 +88,7 @@ interface Preference { suspend fun getPowerSupplySerialListFromPreference(): Flow> ///// -} \ No newline at end of file + suspend fun saveInfoChartLineStates(states: Map) + suspend fun getInfoChartLineStates(): Flow> + +} diff --git a/app/src/main/java/com/laseroptek/raman/repository/PreferenceRepository.kt b/app/src/main/java/com/laseroptek/raman/repository/PreferenceRepository.kt index f3538a7..ee671d6 100644 --- a/app/src/main/java/com/laseroptek/raman/repository/PreferenceRepository.kt +++ b/app/src/main/java/com/laseroptek/raman/repository/PreferenceRepository.kt @@ -68,6 +68,9 @@ class PreferenceRepository(private val context: Context) : Preference { val PRODUCT_SERIAL = stringPreferencesKey("PRODUCT_SERIAL") val LASER_HAND_SERIAL = stringPreferencesKey("LASER_HAND_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() { @@ -559,4 +562,31 @@ class PreferenceRepository(private val context: Context) : Preference { emit(listOf("B", "U", "O", "C", "L", "D")) } } -} \ No newline at end of file + + override suspend fun saveInfoChartLineStates(states: Map) { + 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> { + return context.datastore.data.map { preferences -> + preferences[INFO_CHART_LINE_STATES] + }.distinctUntilChanged().map { jsonString -> + if (!jsonString.isNullOrBlank()) { + val type = object : TypeToken>() {}.type + gson.fromJson>(jsonString, type) ?: emptyMap() + } else { + emptyMap() + } + }.catch { e -> + Timber.e(e, "Failed to get or parse INFO_CHART_LINE_STATES. Emitting default.") + emit(emptyMap()) + } + } +} diff --git a/app/src/main/java/com/laseroptek/raman/ui/screens/info/InfoViewModel.kt b/app/src/main/java/com/laseroptek/raman/ui/screens/info/InfoViewModel.kt index fc035de..72717b8 100644 --- a/app/src/main/java/com/laseroptek/raman/ui/screens/info/InfoViewModel.kt +++ b/app/src/main/java/com/laseroptek/raman/ui/screens/info/InfoViewModel.kt @@ -1,10 +1,14 @@ package com.laseroptek.raman.ui.screens.info import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import com.laseroptek.raman.repository.PreferenceRepository import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject @@ -25,10 +29,13 @@ data class ChartUiState( val chamber2State: Boolean = true, val basePlateState: Boolean = true, val waterState: Boolean = true, -) +) { + companion object +} @HiltViewModel class InfoViewModel @Inject constructor( + private val preferenceRepository: PreferenceRepository, ) : ViewModel() { // This is the single source of truth for the checkbox states. @@ -39,7 +46,7 @@ class InfoViewModel @Inject constructor( fun toggleLine(line: ChartLine) { // .update is a thread-safe way to update the state. _chartUiState.update { currentState -> - when (line) { + val updatedState = when (line) { ChartLine.INT_TEMP -> currentState.copy(intTempState = !currentState.intTempState) ChartLine.EXT_TEMP -> currentState.copy(extTempState = !currentState.extTempState) 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.WATER -> currentState.copy(waterState = !currentState.waterState) } + persistChartUiState(updatedState) + updatedState } } init { Timber.d("InfoViewModel init") + viewModelScope.launch { + preferenceRepository.getInfoChartLineStates().collectLatest { savedStates -> + if (savedStates.isEmpty()) return@collectLatest + _chartUiState.update { ChartUiState.fromPreference(savedStates) } + } + } } -} \ No newline at end of file + + private fun persistChartUiState(state: ChartUiState) { + viewModelScope.launch { + preferenceRepository.saveInfoChartLineStates(state.toPreferenceMap()) + } + } +} + +private fun ChartUiState.toPreferenceMap(): Map = 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): 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, + ) +}