fix(ui): улучшил vault/sync UX и подписи прогресса
Rescan в заголовке vault, sync-кнопка только при скане релевантных vault, блокировка UI при недоступных meta, remember/open после encrypt, убрал … из task_progress (точки остаются в foreground-сервисе).
This commit is contained in:
@@ -46,6 +46,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.zIndex
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.StorageMetaLoadState
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.Tree
|
||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
@@ -74,7 +75,10 @@ fun StorageTree(
|
||||
val numOfFiles by cur.numberOfFiles.collectAsStateWithLifecycle()
|
||||
val size by cur.size.collectAsStateWithLifecycle()
|
||||
val metaInfo by cur.metaInfo.collectAsStateWithLifecycle()
|
||||
val metaLoadState by cur.metaLoadState.collectAsStateWithLifecycle()
|
||||
val isAvailable by cur.isAvailable.collectAsStateWithLifecycle()
|
||||
val metaUnavailable = metaLoadState == StorageMetaLoadState.Unavailable
|
||||
val rowEnabled = isAvailable && !rowBusy && !metaUnavailable
|
||||
val isEncrypted = metaInfo.encInfo != null
|
||||
val isOpened = isEncryptionOpened(tree)
|
||||
val borderColor =
|
||||
@@ -82,6 +86,7 @@ fun StorageTree(
|
||||
val yesWord = stringResource(R.string.storage_value_yes)
|
||||
val noWord = stringResource(R.string.storage_value_no)
|
||||
val unavailableHint = stringResource(R.string.storage_unavailable_hint)
|
||||
val metaUnavailableHint = stringResource(R.string.storage_meta_unavailable_hint)
|
||||
Column(modifier) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
@@ -112,9 +117,9 @@ fun StorageTree(
|
||||
elevation = CardDefaults.cardElevation(
|
||||
defaultElevation = 4.dp,
|
||||
),
|
||||
enabled = isAvailable && !rowBusy,
|
||||
enabled = rowEnabled,
|
||||
onClick = debouncedLambda(debounceMs = 500) {
|
||||
if (isAvailable && !rowBusy) {
|
||||
if (rowEnabled) {
|
||||
onClick(tree)
|
||||
}
|
||||
},
|
||||
@@ -150,7 +155,13 @@ fun StorageTree(
|
||||
),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
if (!isAvailable) {
|
||||
if (metaUnavailable) {
|
||||
Text(
|
||||
text = metaUnavailableHint,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
} else if (!isAvailable) {
|
||||
Text(
|
||||
text = unavailableHint,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
@@ -191,7 +202,7 @@ fun StorageTree(
|
||||
}
|
||||
IconButton(
|
||||
onClick = { expanded = !expanded },
|
||||
enabled = isAvailable && !rowBusy,
|
||||
enabled = rowEnabled,
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.MoreVert,
|
||||
@@ -210,10 +221,10 @@ fun StorageTree(
|
||||
onDismissRequest = { expanded = false },
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
enabled = isAvailable && !rowBusy,
|
||||
enabled = rowEnabled,
|
||||
onClick = {
|
||||
expanded = false
|
||||
if (isAvailable && !rowBusy) showRenameDialog = true
|
||||
if (rowEnabled) showRenameDialog = true
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
@@ -230,10 +241,10 @@ fun StorageTree(
|
||||
)
|
||||
HorizontalDivider()
|
||||
DropdownMenuItem(
|
||||
enabled = isAvailable && !rowBusy,
|
||||
enabled = rowEnabled,
|
||||
onClick = {
|
||||
expanded = false
|
||||
if (isAvailable && !rowBusy) showRemoveConfirmDialog = true
|
||||
if (rowEnabled) showRemoveConfirmDialog = true
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
@@ -251,10 +262,10 @@ fun StorageTree(
|
||||
if (!isEncrypted) {
|
||||
HorizontalDivider()
|
||||
DropdownMenuItem(
|
||||
enabled = isAvailable && !rowBusy,
|
||||
enabled = rowEnabled,
|
||||
onClick = {
|
||||
expanded = false
|
||||
if (isAvailable && !rowBusy) showSetupEncryptionDialog = true
|
||||
if (rowEnabled) showSetupEncryptionDialog = true
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
@@ -361,7 +372,7 @@ fun StorageTree(
|
||||
if (isEncrypted) {
|
||||
IconButton(
|
||||
onClick = { showLockDialog = true },
|
||||
enabled = isAvailable && !rowBusy,
|
||||
enabled = rowEnabled,
|
||||
) {
|
||||
Icon(
|
||||
if (isOpened) Icons.Default.LockOpen else Icons.Default.Lock,
|
||||
|
||||
@@ -2,8 +2,11 @@ package com.github.nullptroma.wallenc.ui.screens.main.screens.storage
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.StorageMetaLoadState
|
||||
import com.github.nullptroma.wallenc.domain.errors.WallencException
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
import com.github.nullptroma.wallenc.ui.ViewModelBase
|
||||
import com.github.nullptroma.wallenc.ui.resources.UserNotification
|
||||
import com.github.nullptroma.wallenc.ui.resources.toUserNotification
|
||||
import com.github.nullptroma.wallenc.usecases.FindStorageUseCase
|
||||
import com.github.nullptroma.wallenc.usecases.ManageTextSecretsUseCase
|
||||
@@ -43,11 +46,13 @@ class StorageHomeViewModel @Inject constructor(
|
||||
combine(
|
||||
storage.isAvailable,
|
||||
storage.metaInfo,
|
||||
storage.metaLoadState,
|
||||
manageTwoFaTokensUseCase.observe(storage),
|
||||
manageTextSecretsUseCase.observe(storage),
|
||||
) { available, meta, twoFa, secrets ->
|
||||
) { available, meta, metaState, twoFa, secrets ->
|
||||
val metaUnavailable = metaState == StorageMetaLoadState.Unavailable
|
||||
val isRawEncrypted = meta.encInfo != null && !storage.isVirtualStorage
|
||||
val canManageDomainData = available && !isRawEncrypted
|
||||
val canManageDomainData = available && !isRawEncrypted && !metaUnavailable
|
||||
state.value.copy(
|
||||
isLoading = false,
|
||||
storageUuid = storage.uuid.toString(),
|
||||
@@ -58,10 +63,10 @@ class StorageHomeViewModel @Inject constructor(
|
||||
twoFaCount = twoFa.size,
|
||||
textSecretsCount = secrets.size,
|
||||
canManageDomainData = canManageDomainData,
|
||||
errorNotification = if (isRawEncrypted) {
|
||||
WallencException.Feature.NeedsDecryptedView().toUserNotification()
|
||||
} else {
|
||||
null
|
||||
errorNotification = when {
|
||||
metaUnavailable -> UserNotification.TextRes(R.string.storage_home_meta_unavailable)
|
||||
isRawEncrypted -> WallencException.Feature.NeedsDecryptedView().toUserNotification()
|
||||
else -> null
|
||||
},
|
||||
)
|
||||
}.collect { ui ->
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.github.nullptroma.wallenc.ui.screens.main.screens.vault
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.StorageMetaLoadState
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.Tree
|
||||
import com.github.nullptroma.wallenc.domain.errors.toWallencException
|
||||
import com.github.nullptroma.wallenc.domain.interfaces.ILogger
|
||||
@@ -253,9 +254,24 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
ManageStoragesEncryptionUseCase.CanEncryptResult.Allowed -> {
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_encrypting))
|
||||
manageStoragesEncryptionUseCase.enableEncryption(storage, key, encryptPath)
|
||||
manageStoragesEncryptionUseCase.openStorage(storage, key, rememberPassword)
|
||||
if (rememberPassword) {
|
||||
manageStoragesEncryptionUseCase.rememberStorageKey(storage, key)
|
||||
}
|
||||
try {
|
||||
manageStoragesEncryptionUseCase.openStorage(
|
||||
storage,
|
||||
key,
|
||||
rememberPassword = false,
|
||||
)
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_encryption_enabled))
|
||||
_userNotifications.emit(UserNotification.TextRes(R.string.msg_encryption_enabled))
|
||||
} catch (openError: Exception) {
|
||||
logger.debug(TAG, "open after encrypt failed: ${openError.stackTraceToString()}")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_encryption_enabled))
|
||||
_userNotifications.emit(
|
||||
UserNotification.TextRes(R.string.msg_encryption_enabled_open_failed),
|
||||
)
|
||||
}
|
||||
}
|
||||
ManageStoragesEncryptionUseCase.CanEncryptResult.AlreadyEncrypted -> {
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_already_encrypted))
|
||||
@@ -410,6 +426,9 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
|
||||
@StringRes
|
||||
fun getStorageStatusRes(storage: IStorageInfo): Int {
|
||||
if (storage.metaLoadState.value == StorageMetaLoadState.Unavailable) {
|
||||
return R.string.storage_status_meta_unavailable
|
||||
}
|
||||
val encrypted = storage.metaInfo.value.encInfo != null
|
||||
if (!encrypted) return R.string.storage_status_not_encrypted
|
||||
val opened = isEncryptionSessionOpen(storage)
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -42,8 +43,6 @@ import com.github.nullptroma.wallenc.ui.elements.StorageTree
|
||||
import com.github.nullptroma.wallenc.ui.resources.UserNotification
|
||||
import java.util.UUID
|
||||
|
||||
private val VaultRescanBottomInset = 88.dp
|
||||
|
||||
@Composable
|
||||
fun VaultBrowserScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
@@ -115,11 +114,14 @@ fun VaultBrowserScreen(
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
uiState.header?.let { header ->
|
||||
Column(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = stringResource(header.titleResId),
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
@@ -134,6 +136,15 @@ fun VaultBrowserScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
if (showRescan) {
|
||||
FilledTonalButton(
|
||||
onClick = { viewModel.rescanStorages() },
|
||||
enabled = rescanEnabled,
|
||||
) {
|
||||
Text(stringResource(R.string.vault_rescan_storages_action))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fabEnabled) {
|
||||
Text(
|
||||
@@ -200,11 +211,7 @@ fun VaultBrowserScreen(
|
||||
)
|
||||
}
|
||||
item {
|
||||
Spacer(
|
||||
modifier = Modifier.height(
|
||||
if (showRescan) VaultRescanBottomInset else 8.dp,
|
||||
),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,18 +227,6 @@ fun VaultBrowserScreen(
|
||||
content = vaultContent,
|
||||
)
|
||||
|
||||
if (showRescan) {
|
||||
FilledTonalButton(
|
||||
onClick = { viewModel.rescanStorages() },
|
||||
enabled = rescanEnabled,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(bottom = VaultRescanBottomInset),
|
||||
) {
|
||||
Text(stringResource(R.string.vault_rescan_storages_action))
|
||||
}
|
||||
}
|
||||
|
||||
if (showFullscreenLoader) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Box(
|
||||
|
||||
@@ -24,6 +24,7 @@ import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
@@ -44,13 +45,21 @@ class StorageSyncViewModel @Inject constructor(
|
||||
observeVaults()
|
||||
observeStorageSyncPipeline()
|
||||
viewModelScope.launch {
|
||||
vaultsManager.vaults
|
||||
.flatMapLatest { vaults ->
|
||||
if (vaults.isEmpty()) {
|
||||
flowOf(false)
|
||||
combine(
|
||||
vaultsManager.vaults,
|
||||
state.map { it.groups },
|
||||
) { vaults, groups ->
|
||||
val requiredUuids = groups.flatMap { it.storageUuids }.toSet()
|
||||
if (requiredUuids.isEmpty() || vaults.isEmpty()) {
|
||||
false
|
||||
} else {
|
||||
combine(vaults.map { it.storagesScanInProgress }) { flags ->
|
||||
flags.any { it }
|
||||
val opened = vaultsManager.unlockManager.openedStorages.value
|
||||
vaults.any { vault ->
|
||||
val uuidsInVault = vault.storages.value.flatMap { root ->
|
||||
flattenStorages(buildStorageTree(root, opened))
|
||||
}.map { it.uuid }.toSet()
|
||||
uuidsInVault.any { it in requiredUuids } &&
|
||||
vault.storagesScanInProgress.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<string name="screen_title_text_edit">Текст</string>
|
||||
<string name="main_work_status_label">Статус:</string>
|
||||
<string name="main_status_multiple_tasks">Выполняется задач: %1$d</string>
|
||||
<string name="main_status_vault_scanning_storages">Сканирование vault: загрузка списка хранилищ…</string>
|
||||
<string name="main_status_vault_scanning_storages">Сканирование vault: загрузка списка хранилищ</string>
|
||||
<string name="settings_title">Настройки</string>
|
||||
<string name="sync_groups_title">Группы синхронизации</string>
|
||||
<string name="sync_progress_section_title">Синхронизация хранилищ</string>
|
||||
@@ -83,6 +83,9 @@
|
||||
<string name="storage_field_size">Размер: %1$s</string>
|
||||
<string name="storage_field_virtual">Виртуальное: %1$s</string>
|
||||
<string name="storage_unavailable_hint">Хранилище недоступно</string>
|
||||
<string name="storage_meta_unavailable_hint">Метаданные недоступны — переименование, шифрование и открытие отключены</string>
|
||||
<string name="storage_status_meta_unavailable">Метаданные недоступны</string>
|
||||
<string name="storage_home_meta_unavailable">Не удалось загрузить метаданные хранилища. 2FA и текстовые секреты недоступны.</string>
|
||||
<string name="storage_menu_unavailable">Недоступно: %1$s</string>
|
||||
<string name="storage_status_not_encrypted">Не зашифровано</string>
|
||||
<string name="storage_status_encrypted_open">Зашифровано (открыто)</string>
|
||||
@@ -120,23 +123,23 @@
|
||||
<string name="task_title_create_storage">Создание хранилища</string>
|
||||
<string name="task_title_enable_encryption">Включение шифрования</string>
|
||||
<string name="task_title_open_encrypted_storage">Расшифровка и открытие хранилища</string>
|
||||
<string name="task_progress_decrypt_running">Расшифровка…</string>
|
||||
<string name="task_progress_dump_storage_log">Сканирование дерева…</string>
|
||||
<string name="task_progress_create_storage">Создание хранилища…</string>
|
||||
<string name="task_progress_enable_encryption">Шифрование…</string>
|
||||
<string name="task_progress_close_storage">Закрытие хранилища…</string>
|
||||
<string name="task_progress_disable_encryption">Очистка содержимого…</string>
|
||||
<string name="task_progress_rename_storage">Переименование…</string>
|
||||
<string name="task_progress_remove_storage">Удаление…</string>
|
||||
<string name="task_progress_clear_sync_lock">Снятие блокировки…</string>
|
||||
<string name="task_progress_add_remote_vault">Добавление…</string>
|
||||
<string name="task_progress_remove_remote_vault">Удаление…</string>
|
||||
<string name="task_progress_retry_remote_vault">Подключение…</string>
|
||||
<string name="task_progress_rescan_vault_storages">Сканирование хранилищ…</string>
|
||||
<string name="task_progress_save_2fa_token">Сохранение…</string>
|
||||
<string name="task_progress_delete_2fa_token">Удаление…</string>
|
||||
<string name="task_progress_save_text_secret">Сохранение…</string>
|
||||
<string name="task_progress_delete_text_secret">Удаление…</string>
|
||||
<string name="task_progress_decrypt_running">Расшифровка</string>
|
||||
<string name="task_progress_dump_storage_log">Сканирование дерева</string>
|
||||
<string name="task_progress_create_storage">Создание хранилища</string>
|
||||
<string name="task_progress_enable_encryption">Шифрование</string>
|
||||
<string name="task_progress_close_storage">Закрытие хранилища</string>
|
||||
<string name="task_progress_disable_encryption">Очистка содержимого</string>
|
||||
<string name="task_progress_rename_storage">Переименование</string>
|
||||
<string name="task_progress_remove_storage">Удаление</string>
|
||||
<string name="task_progress_clear_sync_lock">Снятие блокировки</string>
|
||||
<string name="task_progress_add_remote_vault">Добавление</string>
|
||||
<string name="task_progress_remove_remote_vault">Удаление</string>
|
||||
<string name="task_progress_retry_remote_vault">Подключение</string>
|
||||
<string name="task_progress_rescan_vault_storages">Сканирование хранилищ</string>
|
||||
<string name="task_progress_save_2fa_token">Сохранение</string>
|
||||
<string name="task_progress_delete_2fa_token">Удаление</string>
|
||||
<string name="task_progress_save_text_secret">Сохранение</string>
|
||||
<string name="task_progress_delete_text_secret">Удаление</string>
|
||||
<string name="task_title_close_encrypted_storage">Закрытие зашифрованного хранилища</string>
|
||||
<string name="task_title_disable_encryption">Отключение шифрования</string>
|
||||
<string name="task_title_rename_storage">Переименование хранилища</string>
|
||||
@@ -175,6 +178,7 @@
|
||||
<string name="vault_link_error_unknown">Не удалось войти</string>
|
||||
<string name="vault_link_error_unsupported_brand">Этот провайдер не поддерживается</string>
|
||||
<string name="msg_encryption_enabled">Шифрование включено</string>
|
||||
<string name="msg_encryption_enabled_open_failed">Шифрование включено; откройте хранилище вручную для просмотра</string>
|
||||
<string name="msg_storage_already_encrypted">Хранилище уже зашифровано</string>
|
||||
<string name="msg_storage_not_empty">Хранилище не пустое</string>
|
||||
<string name="msg_storage_empty_state_unknown">Не удалось определить, пусто ли хранилище</string>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<string name="screen_title_text_edit">Text</string>
|
||||
<string name="main_work_status_label">Status:</string>
|
||||
<string name="main_status_multiple_tasks">Running tasks: %1$d</string>
|
||||
<string name="main_status_vault_scanning_storages">Scanning vault: loading storage list…</string>
|
||||
<string name="main_status_vault_scanning_storages">Scanning vault: loading storage list</string>
|
||||
<string name="settings_title">Settings</string>
|
||||
<string name="sync_groups_title">Sync groups</string>
|
||||
<string name="sync_progress_section_title">Storage sync</string>
|
||||
@@ -83,6 +83,9 @@
|
||||
<string name="storage_field_size">Size: %1$s</string>
|
||||
<string name="storage_field_virtual">Virtual: %1$s</string>
|
||||
<string name="storage_unavailable_hint">Storage unavailable</string>
|
||||
<string name="storage_meta_unavailable_hint">Metadata unavailable — rename, encryption, and open are disabled</string>
|
||||
<string name="storage_status_meta_unavailable">Metadata unavailable</string>
|
||||
<string name="storage_home_meta_unavailable">Storage metadata could not be loaded. 2FA and text secrets are unavailable.</string>
|
||||
<string name="storage_menu_unavailable">Unavailable: %1$s</string>
|
||||
<string name="storage_status_not_encrypted">Not encrypted</string>
|
||||
<string name="storage_status_encrypted_open">Encrypted (open)</string>
|
||||
@@ -120,23 +123,23 @@
|
||||
<string name="task_title_create_storage">Create storage</string>
|
||||
<string name="task_title_enable_encryption">Enable encryption</string>
|
||||
<string name="task_title_open_encrypted_storage">Decrypt and open storage</string>
|
||||
<string name="task_progress_decrypt_running">Decrypting…</string>
|
||||
<string name="task_progress_dump_storage_log">Scanning tree…</string>
|
||||
<string name="task_progress_create_storage">Creating storage…</string>
|
||||
<string name="task_progress_enable_encryption">Encrypting…</string>
|
||||
<string name="task_progress_close_storage">Closing storage…</string>
|
||||
<string name="task_progress_disable_encryption">Clearing content…</string>
|
||||
<string name="task_progress_rename_storage">Renaming…</string>
|
||||
<string name="task_progress_remove_storage">Removing…</string>
|
||||
<string name="task_progress_clear_sync_lock">Clearing sync lock…</string>
|
||||
<string name="task_progress_add_remote_vault">Adding…</string>
|
||||
<string name="task_progress_remove_remote_vault">Removing…</string>
|
||||
<string name="task_progress_retry_remote_vault">Connecting…</string>
|
||||
<string name="task_progress_rescan_vault_storages">Scanning storages…</string>
|
||||
<string name="task_progress_save_2fa_token">Saving…</string>
|
||||
<string name="task_progress_delete_2fa_token">Removing…</string>
|
||||
<string name="task_progress_save_text_secret">Saving…</string>
|
||||
<string name="task_progress_delete_text_secret">Removing…</string>
|
||||
<string name="task_progress_decrypt_running">Decrypting</string>
|
||||
<string name="task_progress_dump_storage_log">Scanning tree</string>
|
||||
<string name="task_progress_create_storage">Creating storage</string>
|
||||
<string name="task_progress_enable_encryption">Encrypting</string>
|
||||
<string name="task_progress_close_storage">Closing storage</string>
|
||||
<string name="task_progress_disable_encryption">Clearing content</string>
|
||||
<string name="task_progress_rename_storage">Renaming</string>
|
||||
<string name="task_progress_remove_storage">Removing</string>
|
||||
<string name="task_progress_clear_sync_lock">Clearing sync lock</string>
|
||||
<string name="task_progress_add_remote_vault">Adding</string>
|
||||
<string name="task_progress_remove_remote_vault">Removing</string>
|
||||
<string name="task_progress_retry_remote_vault">Connecting</string>
|
||||
<string name="task_progress_rescan_vault_storages">Scanning storages</string>
|
||||
<string name="task_progress_save_2fa_token">Saving</string>
|
||||
<string name="task_progress_delete_2fa_token">Removing</string>
|
||||
<string name="task_progress_save_text_secret">Saving</string>
|
||||
<string name="task_progress_delete_text_secret">Removing</string>
|
||||
<string name="task_title_close_encrypted_storage">Close encrypted storage</string>
|
||||
<string name="task_title_disable_encryption">Disable encryption</string>
|
||||
<string name="task_title_rename_storage">Rename storage</string>
|
||||
@@ -175,6 +178,7 @@
|
||||
<string name="vault_link_error_unknown">Sign-in failed</string>
|
||||
<string name="vault_link_error_unsupported_brand">This provider is not supported</string>
|
||||
<string name="msg_encryption_enabled">Encryption enabled</string>
|
||||
<string name="msg_encryption_enabled_open_failed">Encryption enabled; unlock the storage manually to view contents</string>
|
||||
<string name="msg_storage_already_encrypted">Storage is already encrypted</string>
|
||||
<string name="msg_storage_not_empty">Storage is not empty</string>
|
||||
<string name="msg_storage_empty_state_unknown">Could not determine if storage is empty</string>
|
||||
|
||||
Reference in New Issue
Block a user