Dispatch log callbacks to main thread

Move allLogs/bufferedLogs mutations in appendLogs, clearLogs,
and setDefaultLogLevel into viewModelScope.launch(Dispatchers.Main)
to avoid concurrent iteration from the search debounce flow.
This commit is contained in:
世界
2026-03-21 12:40:41 +08:00
parent 3692d54420
commit cf145b5374

View File

@@ -81,15 +81,19 @@ class LogViewModel :
override fun setDefaultLogLevel(level: Int) { override fun setDefaultLogLevel(level: Int) {
val logLevel = LogLevel.entries.find { it.priority == level } ?: error("Unknown log level: $level") val logLevel = LogLevel.entries.find { it.priority == level } ?: error("Unknown log level: $level")
_uiState.update { it.copy(defaultLogLevel = logLevel) } viewModelScope.launch(Dispatchers.Main) {
updateDisplayedLogs() _uiState.update { it.copy(defaultLogLevel = logLevel) }
updateDisplayedLogs()
}
} }
override fun clearLogs() { override fun clearLogs() {
allLogs.clear() viewModelScope.launch(Dispatchers.Main) {
bufferedLogs.clear() allLogs.clear()
_uiState.update { it.copy(isPaused = false) } bufferedLogs.clear()
updateDisplayedLogs() _uiState.update { it.copy(isPaused = false) }
updateDisplayedLogs()
}
} }
override fun requestClearLogs() { override fun requestClearLogs() {
@@ -104,23 +108,25 @@ class LogViewModel :
override fun appendLogs(message: List<LogEntry>) { override fun appendLogs(message: List<LogEntry>) {
val processedLogs = message.map { processLogEntry(it) } val processedLogs = message.map { processLogEntry(it) }
if (_uiState.value.isPaused) { viewModelScope.launch(Dispatchers.Main) {
bufferedLogs.addAll(processedLogs) if (_uiState.value.isPaused) {
} else { bufferedLogs.addAll(processedLogs)
val totalSize = allLogs.size + processedLogs.size } else {
val removeCount = (totalSize - maxLines).coerceAtLeast(0) val totalSize = allLogs.size + processedLogs.size
val removeCount = (totalSize - maxLines).coerceAtLeast(0)
if (removeCount > 0) { if (removeCount > 0) {
repeat(removeCount) { repeat(removeCount) {
allLogs.removeFirst() allLogs.removeFirst()
}
} }
}
allLogs.addAll(processedLogs) allLogs.addAll(processedLogs)
updateDisplayedLogs() updateDisplayedLogs()
if (_autoScrollEnabled.value && !_uiState.value.isPaused && !_uiState.value.isSearchActive) { if (_autoScrollEnabled.value && !_uiState.value.isPaused && !_uiState.value.isSearchActive) {
scrollToBottom() scrollToBottom()
}
} }
} }
} }