Улучшение UI/UX

This commit is contained in:
2026-05-13 18:11:48 +03:00
parent abac9d93eb
commit c6df089668
7 changed files with 235 additions and 69 deletions

View File

@@ -2,8 +2,12 @@ package com.github.nullptroma.wallenc.usecases
import com.github.nullptroma.wallenc.domain.interfaces.IStorageSyncEngine
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
import com.github.nullptroma.wallenc.domain.tasks.TaskId
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import java.util.concurrent.atomic.AtomicBoolean
class RunStorageSyncUseCase(
@@ -12,37 +16,53 @@ class RunStorageSyncUseCase(
) {
private val running = AtomicBoolean(false)
private val _syncRunning = MutableStateFlow(false)
val syncRunning: StateFlow<Boolean> = _syncRunning.asStateFlow()
private val _activeSyncTaskId = MutableStateFlow<TaskId?>(null)
val activeSyncTaskId: StateFlow<TaskId?> = _activeSyncTaskId.asStateFlow()
/**
* @param displayTitle заголовок задачи в UI (локализованный на стороне вызова)
* @param logReason техническая метка для логов (не для UI)
* @return false, если синхронизация уже в очереди или выполняется — новая задача не создана
*/
fun enqueue(displayTitle: String, logReason: String) {
orchestrator.enqueue(
title = displayTitle,
dispatcher = Dispatchers.IO,
work = { ctx ->
if (!running.compareAndSet(false, true)) {
ctx.log(TaskLogLevel.Info, "Storage sync skipped (already running), reason=$logReason")
return@enqueue
}
try {
ctx.log(TaskLogLevel.Info, "Storage sync started, reason=$logReason")
ctx.reportProgress(null, "Storage sync: started")
syncEngine.syncAllGroups { fraction, label ->
ctx.reportProgress(fraction, label)
fun enqueue(displayTitle: String, logReason: String): Boolean {
if (!running.compareAndSet(false, true)) {
return false
}
_syncRunning.value = true
try {
val taskId = orchestrator.enqueue(
title = displayTitle,
dispatcher = Dispatchers.IO,
work = { ctx ->
try {
ctx.log(TaskLogLevel.Info, "Storage sync started, reason=$logReason")
ctx.reportProgress(null, "Storage sync: started")
syncEngine.syncAllGroups { fraction, label ->
ctx.reportProgress(fraction, label)
}
ctx.log(TaskLogLevel.Info, "Storage sync finished")
ctx.reportProgress(null, "Storage sync: completed")
} catch (e: Exception) {
ctx.log(TaskLogLevel.Error, "Storage sync failed: ${e.message}")
ctx.reportProgress(null, "Storage sync: failed - ${e.message}")
} finally {
running.set(false)
_syncRunning.value = false
_activeSyncTaskId.value = null
}
ctx.log(TaskLogLevel.Info, "Storage sync finished")
ctx.reportProgress(null, "Storage sync: completed")
}
catch (e: Exception) {
ctx.log(TaskLogLevel.Error, "Storage sync failed: ${e.message}")
ctx.reportProgress(null, "Storage sync: failed - ${e.message}")
}
finally {
running.set(false)
}
},
)
},
)
_activeSyncTaskId.value = taskId
return true
} catch (t: Throwable) {
running.set(false)
_syncRunning.value = false
_activeSyncTaskId.value = null
throw t
}
}
suspend fun runBlocking() {