diff --git a/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/main/MainViewModel.kt b/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/main/MainViewModel.kt index 7ae4564..ce8fce2 100644 --- a/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/main/MainViewModel.kt +++ b/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/main/MainViewModel.kt @@ -7,7 +7,9 @@ import androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi import androidx.lifecycle.viewmodel.compose.saveable import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator +import com.github.nullptroma.wallenc.domain.tasks.PipelineState import com.github.nullptroma.wallenc.domain.tasks.TaskForegroundUiState +import com.github.nullptroma.wallenc.domain.tasks.TaskProgress import com.github.nullptroma.wallenc.domain.tasks.TaskRunState import com.github.nullptroma.wallenc.ui.R import com.github.nullptroma.wallenc.ui.ViewModelBase @@ -76,7 +78,7 @@ class MainViewModel @Inject constructor( private fun mapWorkStatus( fg: TaskForegroundUiState, - pipe: com.github.nullptroma.wallenc.domain.tasks.PipelineState, + pipe: PipelineState, anyVaultScanning: Boolean, ): MainWorkStatus { when (fg) { @@ -85,23 +87,14 @@ class MainViewModel @Inject constructor( return mapBackgroundWork(pipe, anyVaultScanning) } val head = fg.tasks.first() - val p = head.progress - val frac = p?.fraction - val indeterminate = p == null || frac == null - val label = p?.label?.takeIf { it.isNotBlank() } - val line = if (label != null) "${head.title} — $label" else head.title - return MainWorkStatus.Active( - line = line, - progressFraction = frac, - indeterminate = indeterminate, - ) + return activeWorkStatusFromProgress(head.title, head.progress) } TaskForegroundUiState.Hidden -> return mapBackgroundWork(pipe, anyVaultScanning) } } private fun mapBackgroundWork( - pipe: com.github.nullptroma.wallenc.domain.tasks.PipelineState, + pipe: PipelineState, anyVaultScanning: Boolean, ): MainWorkStatus { val fromPipeline = mapPipelineRunningOnly(pipe) @@ -116,23 +109,13 @@ class MainViewModel @Inject constructor( return MainWorkStatus.Idle } - private fun mapPipelineRunningOnly( - pipe: com.github.nullptroma.wallenc.domain.tasks.PipelineState, - ): MainWorkStatus? { + private fun mapPipelineRunningOnly(pipe: PipelineState): MainWorkStatus? { val running = pipe.tasks.filter { it.id in pipe.runningTaskIds } if (running.isEmpty()) return null if (running.size == 1) { val t = running.first() - val prog = (t.state as? TaskRunState.Running)?.progress - val frac = prog?.fraction - val indeterminate = prog == null || frac == null - val label = prog?.label?.takeIf { it.isNotBlank() } - val line = if (label != null) "${t.title} — $label" else t.title - return MainWorkStatus.Active( - line = line, - progressFraction = frac, - indeterminate = indeterminate, - ) + val progress = (t.state as? TaskRunState.Running)?.progress + return activeWorkStatusFromProgress(t.title, progress) } return MainWorkStatus.Active( line = uiStrings(R.string.main_status_multiple_tasks, running.size), @@ -140,4 +123,20 @@ class MainViewModel @Inject constructor( indeterminate = true, ) } + + private fun activeWorkStatusFromProgress(title: String, progress: TaskProgress?): MainWorkStatus.Active { + val frac = progress?.fraction + val indeterminate = progress == null || frac == null + val label = progress?.label?.takeIf { it.isNotBlank() } + val line = if (label != null) "$title$TITLE_LABEL_SEPARATOR$label" else title + return MainWorkStatus.Active( + line = line, + progressFraction = frac, + indeterminate = indeterminate, + ) + } + + private companion object { + private const val TITLE_LABEL_SEPARATOR = " — " + } } diff --git a/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/sync/StorageSyncViewModel.kt b/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/sync/StorageSyncViewModel.kt index 4932b38..cd741ca 100644 --- a/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/sync/StorageSyncViewModel.kt +++ b/ui/src/main/java/com/github/nullptroma/wallenc/ui/screens/sync/StorageSyncViewModel.kt @@ -54,46 +54,28 @@ class StorageSyncViewModel @Inject constructor( fun refreshGroups() { viewModelScope.launch { - val groups = groupsUseCase.getGroups() - updateState( - state.value.copy( - groups = groups.map { StorageSyncGroupUi(it.id, it.storageUuids) }, - ), - ) + updateState(state.value.copy(groups = reloadGroupsUi())) } } fun createGroup() { viewModelScope.launch { - updateState(state.value.copy(isBusy = true, userMessage = null)) - val group = groupsUseCase.createGroup() - val groups = groupsUseCase.getGroups() - updateState( - state.value.copy( - groups = groups.map { StorageSyncGroupUi(it.id, it.storageUuids) }, - pickerGroupId = null, - isBusy = false, - userMessage = UserNotification.TextRes( - R.string.sync_msg_group_created, - listOf(group.id), - ), - ), - ) + withGroupMutationBusy(clearPicker = true) { + val group = groupsUseCase.createGroup() + UserNotification.TextRes( + R.string.sync_msg_group_created, + listOf(group.id), + ) + } } } fun removeGroup(groupId: String) { viewModelScope.launch { - updateState(state.value.copy(isBusy = true, userMessage = null)) - groupsUseCase.removeGroup(groupId) - val groups = groupsUseCase.getGroups() - updateState( - state.value.copy( - groups = groups.map { StorageSyncGroupUi(it.id, it.storageUuids) }, - isBusy = false, - userMessage = UserNotification.TextRes(R.string.sync_msg_group_removed), - ), - ) + withGroupMutationBusy { + groupsUseCase.removeGroup(groupId) + UserNotification.TextRes(R.string.sync_msg_group_removed) + } } } @@ -126,37 +108,25 @@ class StorageSyncViewModel @Inject constructor( fun addStorageToCurrentGroup(storageUuid: UUID) { val groupId = state.value.pickerGroupId ?: return viewModelScope.launch { - updateState(state.value.copy(isBusy = true, userMessage = null)) - groupsUseCase.addStorageToGroup(groupId, storageUuid) - val groups = groupsUseCase.getGroups() - updateState( - state.value.copy( - groups = groups.map { StorageSyncGroupUi(it.id, it.storageUuids) }, - isBusy = false, - userMessage = UserNotification.TextRes( - R.string.sync_msg_storage_added, - listOf(groupId), - ), - ), - ) + withGroupMutationBusy { + groupsUseCase.addStorageToGroup(groupId, storageUuid) + UserNotification.TextRes( + R.string.sync_msg_storage_added, + listOf(groupId), + ) + } } } fun removeStorageFromGroup(groupId: String, storageUuid: UUID) { viewModelScope.launch { - updateState(state.value.copy(isBusy = true, userMessage = null)) - groupsUseCase.removeStorageFromGroup(groupId, storageUuid) - val groups = groupsUseCase.getGroups() - updateState( - state.value.copy( - groups = groups.map { StorageSyncGroupUi(it.id, it.storageUuids) }, - isBusy = false, - userMessage = UserNotification.TextRes( - R.string.sync_msg_storage_removed, - listOf(groupId), - ), - ), - ) + withGroupMutationBusy { + groupsUseCase.removeStorageFromGroup(groupId, storageUuid) + UserNotification.TextRes( + R.string.sync_msg_storage_removed, + listOf(groupId), + ) + } } } @@ -319,4 +289,24 @@ class StorageSyncViewModel @Inject constructor( val storage: IStorage, val children: List, ) + + private suspend fun reloadGroupsUi(): List = + groupsUseCase.getGroups().map { StorageSyncGroupUi(it.id, it.storageUuids) } + + private suspend fun withGroupMutationBusy( + clearPicker: Boolean = false, + block: suspend () -> UserNotification?, + ) { + updateState(state.value.copy(isBusy = true, userMessage = null)) + val message = block() + val groups = reloadGroupsUi() + updateState( + state.value.copy( + groups = groups, + pickerGroupId = if (clearPicker) null else state.value.pickerGroupId, + isBusy = false, + userMessage = message, + ), + ) + } }