refactor: remove Jsoup dependency + replace runBlocking with Flow

Step 7: Remove Jsoup
- Delete implementation(libs.jsoup) from build.gradle.kts
- Delete jsoup version + library from libs.versions.toml
- 0 imports of Jsoup in codebase, pure dead dependency

Step 8: ChartSettingsStore Flow
- Replace runBlocking getUseUtc8() with StateFlow useUtc8State
- UsageChartViewModel: setWorkspace() reads useUtc8Flow.first() async
- ChartUiState: add useUtc8Initialized flag to prevent double-load
- Remove runBlocking import from ChartSettingsStore
This commit is contained in:
WaterRain 2026-07-07 00:05:33 +00:00
parent 220a74492a
commit 6e629d8eb2
No known key found for this signature in database
4 changed files with 27 additions and 16 deletions

View File

@ -96,7 +96,6 @@ dependencies {
implementation(libs.okhttp.logging.interceptor)
implementation(libs.kotlinx.serialization.json)
implementation(libs.retrofit.kotlinx.serialization.converter)
implementation(libs.jsoup)
// DataStore
implementation(libs.androidx.datastore.preferences)

View File

@ -7,14 +7,19 @@ import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.Dispatchers
private val Context.chartSettingsDataStore: DataStore<Preferences> by preferencesDataStore(
name = "chart_settings"
)
private val chartSettingsScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
/** 图表页偏好设置持久化 */
class ChartSettingsStore(private val dataStore: DataStore<Preferences>) {
@ -27,10 +32,9 @@ class ChartSettingsStore(private val dataStore: DataStore<Preferences>) {
prefs[KEY_USE_UTC8] ?: false
}
/** 同步读取(用于 ViewModel 初始化) */
fun getUseUtc8(): Boolean = runBlocking {
dataStore.data.map { it[KEY_USE_UTC8] ?: false }.first()
}
/** StateFlow 版本,UI 层 collectAsState 直接使用 */
val useUtc8State: StateFlow<Boolean> = useUtc8Flow
.stateIn(chartSettingsScope, kotlinx.coroutines.flow.SharingStarted.Eagerly, false)
/** 写入偏好 */
suspend fun setUseUtc8(value: Boolean) {

View File

@ -15,6 +15,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import java.time.Instant
import java.time.LocalDate
@ -29,9 +30,7 @@ class UsageChartViewModel @Inject constructor(
private val chartSettingsStore: ChartSettingsStore
) : ViewModel() {
private val _state = MutableStateFlow(
ChartUiState(useUtc8 = chartSettingsStore.getUseUtc8())
)
private val _state = MutableStateFlow(ChartUiState(useUtc8 = false))
val state: StateFlow<ChartUiState> = _state.asStateFlow()
private var workspaceIdOverride: String? = null
@ -43,11 +42,21 @@ class UsageChartViewModel @Inject constructor(
fun setWorkspace(wid: String) {
workspaceIdOverride = wid
loadGeneration++
allowFallback = true // CCGO 首次加载也允许降级
// 先清空数据防止 init 自动加载的 OCGO 数据闪一下,但保留持久化偏好
allowFallback = true
_state.value = ChartUiState(useUtc8 = _state.value.useUtc8)
viewModelScope.launch {
// 首次加载时同步读取 UTC 偏好,避免用默认值 false 加载后再切换
if (!_state.value.useUtc8Initialized) {
val saved = chartSettingsStore.useUtc8Flow.first()
if (saved != _state.value.useUtc8) {
_state.update { it.copy(useUtc8 = saved, useUtc8Initialized = true) }
} else {
_state.update { it.copy(useUtc8Initialized = true) }
}
}
load()
}
}
private suspend fun workspaceId(): String? {
workspaceIdOverride?.let { return it }
@ -259,5 +268,6 @@ data class ChartUiState(
val allModels: List<String> = emptyList(),
val selectedModels: Set<String> = emptySet(), // empty = all
val buckets: List<ChartBucket> = emptyList(),
val useUtc8: Boolean = false
val useUtc8: Boolean = false,
val useUtc8Initialized: Boolean = false
)

View File

@ -18,7 +18,6 @@ retrofit = "2.11.0"
okhttp = "4.12.0"
kotlinxSerializationJson = "1.7.3"
retrofitKotlinxSerializationConverter = "1.0.0"
jsoup = "1.18.3"
# DataStore
datastorePreferences = "1.1.1"
@ -69,7 +68,6 @@ okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhtt
okhttp-logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
retrofit-kotlinx-serialization-converter = { group = "com.jakewharton.retrofit", name = "retrofit2-kotlinx-serialization-converter", version.ref = "retrofitKotlinxSerializationConverter" }
jsoup = { group = "org.jsoup", name = "jsoup", version.ref = "jsoup" }
# DataStore
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastorePreferences" }