Заголовок задачи синхронизации

This commit is contained in:
2026-05-22 00:20:49 +03:00
parent 233a716e47
commit 07d54b5996
9 changed files with 42 additions and 19 deletions

View File

@@ -1,6 +1,8 @@
package com.github.nullptroma.wallenc.app.di.modules.domain package com.github.nullptroma.wallenc.app.di.modules.domain
import com.github.nullptroma.wallenc.app.sync.StorageSyncTaskTitleFormatter
import com.github.nullptroma.wallenc.domain.interfaces.IStorageSyncEngine import com.github.nullptroma.wallenc.domain.interfaces.IStorageSyncEngine
import com.github.nullptroma.wallenc.domain.tasks.IStorageSyncTaskTitleFormatter
import com.github.nullptroma.wallenc.usecases.StorageSyncEngine import com.github.nullptroma.wallenc.usecases.StorageSyncEngine
import dagger.Binds import dagger.Binds
import dagger.Module import dagger.Module
@@ -15,4 +17,10 @@ abstract class UseCasesModule {
@Binds @Binds
@Singleton @Singleton
abstract fun bindStorageSyncEngine(impl: StorageSyncEngine): IStorageSyncEngine abstract fun bindStorageSyncEngine(impl: StorageSyncEngine): IStorageSyncEngine
@Binds
@Singleton
abstract fun bindStorageSyncTaskTitleFormatter(
impl: StorageSyncTaskTitleFormatter,
): IStorageSyncTaskTitleFormatter
} }

View File

@@ -2,8 +2,6 @@ package com.github.nullptroma.wallenc.app.sync
import com.github.nullptroma.wallenc.domain.datatypes.StorageSyncPaths import com.github.nullptroma.wallenc.domain.datatypes.StorageSyncPaths
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
import com.github.nullptroma.wallenc.ui.R
import com.github.nullptroma.wallenc.ui.resources.UiStringResolver
import com.github.nullptroma.wallenc.domain.tasks.StorageSyncTriggerReason import com.github.nullptroma.wallenc.domain.tasks.StorageSyncTriggerReason
import com.github.nullptroma.wallenc.usecases.RunStorageSyncUseCase import com.github.nullptroma.wallenc.usecases.RunStorageSyncUseCase
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@@ -25,7 +23,6 @@ class StorageSyncBootstrap @Inject constructor(
private val scheduler: StorageSyncScheduler, private val scheduler: StorageSyncScheduler,
private val vaultsManager: IVaultsManager, private val vaultsManager: IVaultsManager,
private val syncRunner: RunStorageSyncUseCase, private val syncRunner: RunStorageSyncUseCase,
private val uiStrings: UiStringResolver,
) { ) {
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
@@ -60,10 +57,7 @@ class StorageSyncBootstrap @Inject constructor(
if (syncRunner.syncRunning.value) { if (syncRunner.syncRunning.value) {
return@collect return@collect
} }
syncRunner.enqueue( syncRunner.enqueue(StorageSyncTriggerReason.Debounce)
displayTitle = uiStrings(R.string.task_title_storage_sync_background),
reason = StorageSyncTriggerReason.Debounce,
)
} }
} }
} }

View File

@@ -0,0 +1,16 @@
package com.github.nullptroma.wallenc.app.sync
import com.github.nullptroma.wallenc.domain.tasks.IStorageSyncTaskTitleFormatter
import com.github.nullptroma.wallenc.domain.tasks.StorageSyncTriggerReason
import com.github.nullptroma.wallenc.ui.resources.UiStringResolver
import com.github.nullptroma.wallenc.ui.resources.storageSyncTaskTitle
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class StorageSyncTaskTitleFormatter @Inject constructor(
private val uiStrings: UiStringResolver,
) : IStorageSyncTaskTitleFormatter {
override fun format(reason: StorageSyncTriggerReason): String =
uiStrings.storageSyncTaskTitle(reason)
}

View File

@@ -0,0 +1,6 @@
package com.github.nullptroma.wallenc.domain.tasks
/** Локализованный заголовок задачи синхронизации хранилищ по источнику запуска. */
fun interface IStorageSyncTaskTitleFormatter {
fun format(reason: StorageSyncTriggerReason): String
}

View File

@@ -23,6 +23,9 @@ fun TaskLogKey.resolve(resolver: UiStringResolver): String = when (this) {
} }
} }
fun UiStringResolver.storageSyncTaskTitle(reason: StorageSyncTriggerReason): String =
this(R.string.task_title_storage_sync, resolveSyncTriggerReason(reason))
private fun UiStringResolver.resolveSyncTriggerReason(reason: StorageSyncTriggerReason): String = private fun UiStringResolver.resolveSyncTriggerReason(reason: StorageSyncTriggerReason): String =
when (reason) { when (reason) {
StorageSyncTriggerReason.Debounce -> this(R.string.task_sync_trigger_debounce) StorageSyncTriggerReason.Debounce -> this(R.string.task_sync_trigger_debounce)

View File

@@ -208,10 +208,7 @@ class StorageSyncViewModel @Inject constructor(
} }
fun runSyncNow() { fun runSyncNow() {
val started = runStorageSyncUseCase.enqueue( val started = runStorageSyncUseCase.enqueue(StorageSyncTriggerReason.SyncTab)
displayTitle = uiStrings(R.string.task_title_storage_sync),
reason = StorageSyncTriggerReason.SyncTab,
)
if (!started) { if (!started) {
updateState( updateState(
state.value.copy( state.value.copy(

View File

@@ -149,8 +149,7 @@
<string name="task_title_remove_remote_vault">Удаление удалённого хранилища</string> <string name="task_title_remove_remote_vault">Удаление удалённого хранилища</string>
<string name="task_title_retry_remote_vault">Повторное подключение удалённого хранилища</string> <string name="task_title_retry_remote_vault">Повторное подключение удалённого хранилища</string>
<string name="task_title_rescan_vault_storages">Обновление списка хранилищ</string> <string name="task_title_rescan_vault_storages">Обновление списка хранилищ</string>
<string name="task_title_storage_sync">Синхронизация хранилищ</string> <string name="task_title_storage_sync">Синхронизация хранилищ (%1$s)</string>
<string name="task_title_storage_sync_background">Фоновая синхронизация хранилищ</string>
<string name="task_title_save_2fa_token">Сохранение 2FA токена</string> <string name="task_title_save_2fa_token">Сохранение 2FA токена</string>
<string name="task_title_delete_2fa_token">Удаление 2FA токена</string> <string name="task_title_delete_2fa_token">Удаление 2FA токена</string>
<string name="task_title_save_text_secret">Сохранение текстового секрета</string> <string name="task_title_save_text_secret">Сохранение текстового секрета</string>

View File

@@ -149,8 +149,7 @@
<string name="task_title_remove_remote_vault">Remove remote vault</string> <string name="task_title_remove_remote_vault">Remove remote vault</string>
<string name="task_title_retry_remote_vault">Retry remote vault connection</string> <string name="task_title_retry_remote_vault">Retry remote vault connection</string>
<string name="task_title_rescan_vault_storages">Rescan vault storages</string> <string name="task_title_rescan_vault_storages">Rescan vault storages</string>
<string name="task_title_storage_sync">Storage sync</string> <string name="task_title_storage_sync">Storage sync (%1$s)</string>
<string name="task_title_storage_sync_background">Background storage sync</string>
<string name="task_title_save_2fa_token">Save 2FA token</string> <string name="task_title_save_2fa_token">Save 2FA token</string>
<string name="task_title_delete_2fa_token">Delete 2FA token</string> <string name="task_title_delete_2fa_token">Delete 2FA token</string>
<string name="task_title_save_text_secret">Save text secret</string> <string name="task_title_save_text_secret">Save text secret</string>

View File

@@ -3,6 +3,7 @@ package com.github.nullptroma.wallenc.usecases
import com.github.nullptroma.wallenc.domain.errors.toWallencException import com.github.nullptroma.wallenc.domain.errors.toWallencException
import com.github.nullptroma.wallenc.domain.interfaces.IStorageSyncEngine import com.github.nullptroma.wallenc.domain.interfaces.IStorageSyncEngine
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
import com.github.nullptroma.wallenc.domain.tasks.IStorageSyncTaskTitleFormatter
import com.github.nullptroma.wallenc.domain.tasks.StorageSyncTriggerReason import com.github.nullptroma.wallenc.domain.tasks.StorageSyncTriggerReason
import com.github.nullptroma.wallenc.domain.tasks.TaskId import com.github.nullptroma.wallenc.domain.tasks.TaskId
import com.github.nullptroma.wallenc.domain.tasks.TaskLogKey import com.github.nullptroma.wallenc.domain.tasks.TaskLogKey
@@ -21,6 +22,7 @@ class RunStorageSyncUseCase @Inject constructor(
private val orchestrator: ITaskOrchestrator, private val orchestrator: ITaskOrchestrator,
private val syncEngine: IStorageSyncEngine, private val syncEngine: IStorageSyncEngine,
private val syncReadiness: StorageSyncReadiness, private val syncReadiness: StorageSyncReadiness,
private val taskTitleFormatter: IStorageSyncTaskTitleFormatter,
) { ) {
private val running = AtomicBoolean(false) private val running = AtomicBoolean(false)
@@ -31,18 +33,17 @@ class RunStorageSyncUseCase @Inject constructor(
val activeSyncTaskId: StateFlow<TaskId?> = _activeSyncTaskId.asStateFlow() val activeSyncTaskId: StateFlow<TaskId?> = _activeSyncTaskId.asStateFlow()
/** /**
* @param displayTitle заголовок задачи в UI (локализованный на стороне вызова) * @param reason источник запуска — заголовок задачи и лог пайплайна
* @param reason источник запуска — попадает в лог пайплайна
* @return false, если синхронизация уже в очереди или выполняется — новая задача не создана * @return false, если синхронизация уже в очереди или выполняется — новая задача не создана
*/ */
fun enqueue(displayTitle: String, reason: StorageSyncTriggerReason): Boolean { fun enqueue(reason: StorageSyncTriggerReason): Boolean {
if (!running.compareAndSet(false, true)) { if (!running.compareAndSet(false, true)) {
return false return false
} }
_syncRunning.value = true _syncRunning.value = true
try { try {
val taskId = orchestrator.enqueue( val taskId = orchestrator.enqueue(
title = displayTitle, title = taskTitleFormatter.format(reason),
dispatcher = Dispatchers.IO, dispatcher = Dispatchers.IO,
work = { ctx -> work = { ctx ->
try { try {