Переключение языка
This commit is contained in:
@@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.rounded.List
|
||||
import androidx.compose.material.icons.rounded.Menu
|
||||
import androidx.compose.material.icons.rounded.Settings
|
||||
import androidx.compose.material.icons.rounded.Sync
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -99,13 +100,11 @@ fun WallencNavRoot(
|
||||
StorageSyncRoute::class.qualifiedName!!,
|
||||
Icons.Rounded.Sync,
|
||||
),
|
||||
// Settings temporarily hidden from top-level menu.
|
||||
// Uncomment to restore:
|
||||
// SettingsRoute::class.qualifiedName!! to NavBarItemData(
|
||||
// R.string.nav_label_settings,
|
||||
// SettingsRoute::class.qualifiedName!!,
|
||||
// Icons.Rounded.Settings,
|
||||
// ),
|
||||
SettingsRoute::class.qualifiedName!! to NavBarItemData(
|
||||
R.string.nav_label_settings,
|
||||
SettingsRoute::class.qualifiedName!!,
|
||||
Icons.Rounded.Settings,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.github.nullptroma.wallenc.ui.locale
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
enum class AppLanguage {
|
||||
System,
|
||||
English,
|
||||
Russian,
|
||||
}
|
||||
|
||||
interface AppLocaleController {
|
||||
val language: Flow<AppLanguage>
|
||||
|
||||
suspend fun setLanguage(language: AppLanguage)
|
||||
|
||||
/** Applies persisted locale; call from [android.app.Application.onCreate]. */
|
||||
suspend fun applyStoredLocale()
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.github.nullptroma.wallenc.ui.resources
|
||||
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogKey
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
|
||||
fun TaskLogKey.resolve(resolver: UiStringResolver): String = when (this) {
|
||||
TaskLogKey.SyncStarted -> resolver(R.string.task_log_sync_started)
|
||||
TaskLogKey.SyncFinished -> resolver(R.string.task_log_sync_finished)
|
||||
is TaskLogKey.SyncFailed -> {
|
||||
val notification = error.toUserNotification().resolve(resolver)
|
||||
resolver(R.string.task_log_sync_failed, notification)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.github.nullptroma.wallenc.ui.resources
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLine
|
||||
|
||||
@Composable
|
||||
fun TaskLogLine.displayText(): String {
|
||||
val key = logKey
|
||||
if (key != null) {
|
||||
val context = LocalContext.current
|
||||
val resolver = UiStringResolver { id, args ->
|
||||
if (args.isEmpty()) {
|
||||
context.getString(id)
|
||||
} else {
|
||||
context.getString(id, *args)
|
||||
}
|
||||
}
|
||||
return key.resolve(resolver)
|
||||
}
|
||||
return message
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.github.nullptroma.wallenc.ui.resources
|
||||
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskProgressLabel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.VaultTaskStep
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
|
||||
fun TaskProgressLabel.resolve(resolver: UiStringResolver): String = when (this) {
|
||||
TaskProgressLabel.SyncNoGroups -> resolver(R.string.sync_progress_no_groups)
|
||||
TaskProgressLabel.SyncStarted -> resolver(R.string.sync_progress_started)
|
||||
TaskProgressLabel.SyncCompleted -> resolver(R.string.sync_progress_completed)
|
||||
is TaskProgressLabel.SyncPreparing -> resolver(R.string.sync_progress_preparing, groupCount)
|
||||
|
||||
is TaskProgressLabel.SyncGroupPreparing -> resolver(R.string.sync_progress_group_preparing, groupId)
|
||||
is TaskProgressLabel.SyncGroupNotFound -> resolver(R.string.sync_progress_group_not_found, groupId)
|
||||
is TaskProgressLabel.SyncGroupSkippedTooFewStorages ->
|
||||
resolver(R.string.sync_progress_group_skipped_few_storages, groupId)
|
||||
is TaskProgressLabel.SyncGroupSkippedIncompatibleEncryption ->
|
||||
resolver(R.string.sync_progress_group_skipped_incompatible, groupId, count)
|
||||
is TaskProgressLabel.SyncGroupAcquiringLocks ->
|
||||
resolver(R.string.sync_progress_group_acquiring_locks, groupId)
|
||||
is TaskProgressLabel.SyncGroupLockProgress ->
|
||||
resolver(R.string.sync_progress_group_lock, groupId, current, total)
|
||||
is TaskProgressLabel.SyncGroupLockFailed ->
|
||||
resolver(R.string.sync_progress_group_lock_failed, groupId)
|
||||
is TaskProgressLabel.SyncGroupReadingJournals ->
|
||||
resolver(R.string.sync_progress_group_reading_journals, groupId)
|
||||
is TaskProgressLabel.SyncGroupCancelled ->
|
||||
resolver(R.string.sync_progress_group_cancelled, groupId)
|
||||
is TaskProgressLabel.SyncGroupJournalProgress ->
|
||||
resolver(R.string.sync_progress_group_journal, groupId, current, total)
|
||||
is TaskProgressLabel.SyncGroupNoJournalEntries ->
|
||||
resolver(R.string.sync_progress_group_no_entries, groupId)
|
||||
is TaskProgressLabel.SyncGroupProcessingEntries ->
|
||||
resolver(R.string.sync_progress_group_processing, groupId, count)
|
||||
is TaskProgressLabel.SyncGroupEntryProgress ->
|
||||
resolver(R.string.sync_progress_group_entry, groupId, current, total)
|
||||
is TaskProgressLabel.SyncGroupCompleted ->
|
||||
resolver(R.string.sync_progress_group_completed, groupId)
|
||||
is TaskProgressLabel.SyncGroupRenewingLocks ->
|
||||
resolver(R.string.sync_progress_group_renewing_locks, groupId)
|
||||
is TaskProgressLabel.SyncGroupLockRenewalFailed ->
|
||||
resolver(R.string.sync_progress_group_lock_renewal_failed, groupId)
|
||||
|
||||
is TaskProgressLabel.ClearContentProgress ->
|
||||
resolver(R.string.task_progress_clear_content, done, total)
|
||||
|
||||
is TaskProgressLabel.VaultTask -> when (step) {
|
||||
VaultTaskStep.DumpStorageLog -> resolver(R.string.task_progress_dump_storage_log)
|
||||
VaultTaskStep.CreateStorage -> resolver(R.string.task_progress_create_storage)
|
||||
VaultTaskStep.EnableEncryption -> resolver(R.string.task_progress_enable_encryption)
|
||||
VaultTaskStep.DecryptRunning -> resolver(R.string.task_progress_decrypt_running)
|
||||
VaultTaskStep.CloseStorage -> resolver(R.string.task_progress_close_storage)
|
||||
VaultTaskStep.DisableEncryption -> resolver(R.string.task_progress_disable_encryption)
|
||||
VaultTaskStep.RenameStorage -> resolver(R.string.task_progress_rename_storage)
|
||||
VaultTaskStep.RemoveStorage -> resolver(R.string.task_progress_remove_storage)
|
||||
VaultTaskStep.ClearSyncLock -> resolver(R.string.task_progress_clear_sync_lock)
|
||||
VaultTaskStep.AddRemoteVault -> resolver(R.string.task_progress_add_remote_vault)
|
||||
VaultTaskStep.RemoveRemoteVault -> resolver(R.string.task_progress_remove_remote_vault)
|
||||
VaultTaskStep.RetryRemoteVault -> resolver(R.string.task_progress_retry_remote_vault)
|
||||
VaultTaskStep.Save2FaToken -> resolver(R.string.task_progress_save_2fa_token)
|
||||
VaultTaskStep.Delete2FaToken -> resolver(R.string.task_progress_delete_2fa_token)
|
||||
VaultTaskStep.SaveTextSecret -> resolver(R.string.task_progress_save_text_secret)
|
||||
VaultTaskStep.DeleteTextSecret -> resolver(R.string.task_progress_delete_text_secret)
|
||||
}
|
||||
|
||||
is TaskProgressLabel.TestElapsed ->
|
||||
resolver(R.string.task_pipeline_test_elapsed, elapsedSec, totalSec)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.github.nullptroma.wallenc.ui.resources
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskProgressLabel
|
||||
|
||||
@Composable
|
||||
fun TaskProgressLabel.resolveText(): String {
|
||||
val context = LocalContext.current
|
||||
return resolve(
|
||||
UiStringResolver { id, args ->
|
||||
if (args.isEmpty()) {
|
||||
context.getString(id)
|
||||
} else {
|
||||
context.getString(id, *args)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -14,3 +14,14 @@ fun UserNotification.resolveText(): String = when (this) {
|
||||
}
|
||||
is UserNotification.Plain -> message
|
||||
}
|
||||
|
||||
fun UserNotification.resolve(resolver: UiStringResolver): String = when (this) {
|
||||
is UserNotification.TextRes -> {
|
||||
if (formatArgs.isEmpty()) {
|
||||
resolver(id)
|
||||
} else {
|
||||
resolver(id, *formatArgs.toTypedArray())
|
||||
}
|
||||
}
|
||||
is UserNotification.Plain -> message
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
import com.github.nullptroma.wallenc.ui.ViewModelBase
|
||||
import com.github.nullptroma.wallenc.ui.resources.UiStringResolver
|
||||
import com.github.nullptroma.wallenc.ui.resources.resolve
|
||||
import com.github.nullptroma.wallenc.ui.screens.ScreenRoute
|
||||
import com.github.nullptroma.wallenc.ui.screens.main.screens.remotes.RemoteVaultsRoute
|
||||
import com.github.nullptroma.wallenc.ui.screens.main.screens.vault.LocalVaultRoute
|
||||
@@ -127,7 +128,7 @@ class MainViewModel @Inject constructor(
|
||||
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 label = progress?.label?.resolve(uiStrings)
|
||||
val line = if (label != null) "$title$TITLE_LABEL_SEPARATOR$label" else title
|
||||
return MainWorkStatus.Active(
|
||||
line = line,
|
||||
|
||||
@@ -4,6 +4,8 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskProgressLabel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.VaultTaskStep
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
import com.github.nullptroma.wallenc.ui.ViewModelBase
|
||||
import com.github.nullptroma.wallenc.ui.resources.UiStringResolver
|
||||
@@ -77,12 +79,12 @@ class RemoteVaultsViewModel @Inject constructor(
|
||||
dispatcher = Dispatchers.IO,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_add_remote_vault))
|
||||
ctx.log(TaskLogLevel.Info, "Adding vault…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.AddRemoteVault))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_adding_vault))
|
||||
vaultRegistrar.register(registration)
|
||||
ctx.log(TaskLogLevel.Info, "Vault added")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_vault_added))
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "Failed to add vault")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_add_vault_failed))
|
||||
} finally {
|
||||
withContext(Dispatchers.Main.immediate) {
|
||||
setBusy(false)
|
||||
@@ -110,12 +112,12 @@ class RemoteVaultsViewModel @Inject constructor(
|
||||
dispatcher = Dispatchers.IO,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_remove_remote_vault))
|
||||
ctx.log(TaskLogLevel.Info, "Removing remote vault…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.RemoveRemoteVault))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_removing_remote_vault))
|
||||
vaultRegistrar.unregister(uuid)
|
||||
ctx.log(TaskLogLevel.Info, "Remote vault removed")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_remote_vault_removed))
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "Failed to remove vault")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_remove_vault_failed))
|
||||
} finally {
|
||||
withContext(Dispatchers.Main.immediate) {
|
||||
setBusy(false)
|
||||
@@ -133,12 +135,12 @@ class RemoteVaultsViewModel @Inject constructor(
|
||||
dispatcher = Dispatchers.IO,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_retry_remote_vault))
|
||||
ctx.log(TaskLogLevel.Info, "Retrying remote vault connection…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.RetryRemoteVault))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_retrying_vault))
|
||||
vaultRegistrar.retry(vaultUuid)
|
||||
ctx.log(TaskLogLevel.Info, "Retry requested")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_retry_requested))
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "Failed to retry remote vault")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_retry_vault_failed))
|
||||
} finally {
|
||||
withContext(Dispatchers.Main.immediate) {
|
||||
setBusy(false)
|
||||
|
||||
@@ -88,6 +88,7 @@ fun TextSecretDetailsScreen(
|
||||
|
||||
LazyColumn(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
items(secret.items) { item ->
|
||||
val clipboardFallbackLabel = stringResource(R.string.text_secret_clipboard_fallback_label)
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.elevatedCardColors(
|
||||
@@ -118,7 +119,7 @@ fun TextSecretDetailsScreen(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
val clipData = ClipData.newPlainText(
|
||||
item.label ?: "value",
|
||||
item.label ?: clipboardFallbackLabel,
|
||||
item.value,
|
||||
)
|
||||
clipboard.setClipEntry(clipData.toClipEntry())
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.github.nullptroma.wallenc.ui.screens.main.screens.storage.secrets
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskProgressLabel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.VaultTaskStep
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskId
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
@@ -105,7 +107,7 @@ class TextSecretDetailsViewModel @Inject constructor(
|
||||
dispatcher = Dispatchers.IO,
|
||||
busyStorageUuid = storage.uuid,
|
||||
work = { ctx ->
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_delete_text_secret))
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.DeleteTextSecret))
|
||||
manageTextSecretsUseCase.delete(storage, secretId)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -5,6 +5,8 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.TextSecretEntryRecord
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.TextSecretRecord
|
||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskProgressLabel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.VaultTaskStep
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskId
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
@@ -110,7 +112,7 @@ class TextSecretEditViewModel @Inject constructor(
|
||||
dispatcher = Dispatchers.IO,
|
||||
busyStorageUuid = storage.uuid,
|
||||
work = { ctx ->
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_save_text_secret))
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.SaveTextSecret))
|
||||
if (existingId == null) {
|
||||
manageTextSecretsUseCase.create(
|
||||
storageInfo = storage,
|
||||
|
||||
@@ -4,6 +4,8 @@ import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.TwoFaTokenRecord
|
||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskProgressLabel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.VaultTaskStep
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
import com.github.nullptroma.wallenc.domain.errors.WallencException
|
||||
@@ -104,7 +106,7 @@ class TwoFaTokensViewModel @Inject constructor(
|
||||
dispatcher = Dispatchers.IO,
|
||||
busyStorageUuid = storage.uuid,
|
||||
work = { ctx ->
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_save_2fa_token))
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.Save2FaToken))
|
||||
if (existingId == null) {
|
||||
manageTwoFaTokensUseCase.create(
|
||||
storageInfo = storage,
|
||||
@@ -152,7 +154,7 @@ class TwoFaTokensViewModel @Inject constructor(
|
||||
dispatcher = Dispatchers.IO,
|
||||
busyStorageUuid = storage.uuid,
|
||||
work = { ctx ->
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_delete_2fa_token))
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.Delete2FaToken))
|
||||
manageTwoFaTokensUseCase.delete(storage, id)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -36,6 +36,8 @@ import com.github.nullptroma.wallenc.domain.tasks.PipelineTask
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
import com.github.nullptroma.wallenc.ui.resources.displayText
|
||||
import com.github.nullptroma.wallenc.ui.resources.resolveText
|
||||
import com.github.nullptroma.wallenc.ui.resources.toUserNotification
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@@ -97,7 +99,7 @@ fun TaskPipelineScreen(
|
||||
TaskLogLevel.Error -> "E"
|
||||
}
|
||||
Text(
|
||||
"[$prefix] ${line.message}",
|
||||
"[$prefix] ${line.displayText()}",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -185,7 +187,7 @@ private fun TaskRow(task: PipelineTask, isRunning: Boolean) {
|
||||
else MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
val runningProgress = (task.state as? TaskRunState.Running)?.progress
|
||||
val progressLabel = runningProgress?.label?.takeIf { it.isNotBlank() }
|
||||
val progressLabel = runningProgress?.label?.resolveText()
|
||||
val stateLabel = when (val s = task.state) {
|
||||
TaskRunState.Queued -> stringResource(R.string.task_state_queued)
|
||||
is TaskRunState.Running ->
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.github.nullptroma.wallenc.ui.screens.main.screens.tasks
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskProgressLabel
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
import com.github.nullptroma.wallenc.ui.resources.UiStringResolver
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@@ -29,17 +30,17 @@ class TaskPipelineViewModel @Inject constructor(
|
||||
dispatcher = Dispatchers.Default,
|
||||
work = { ctx ->
|
||||
val steps = if (safeDurationSec == 0) 1 else safeDurationSec * 10
|
||||
ctx.log(TaskLogLevel.Info, "Test task started for ${safeDurationSec}s")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_test_started, safeDurationSec))
|
||||
for (step in 0..steps) {
|
||||
val fraction = step.toFloat() / steps.toFloat()
|
||||
val elapsedMs = (fraction * safeDurationSec * 1000).toInt()
|
||||
val elapsedSec = ((fraction * safeDurationSec * 1000).toInt()) / 1000
|
||||
ctx.reportProgress(
|
||||
fraction = if (infinityIndeterminateProgress) null else fraction,
|
||||
label = "Elapsed: ${elapsedMs / 1000}s / ${safeDurationSec}s",
|
||||
label = TaskProgressLabel.TestElapsed(elapsedSec, safeDurationSec),
|
||||
)
|
||||
if (step < steps) delay(100)
|
||||
}
|
||||
ctx.log(TaskLogLevel.Info, "Test task finished")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_test_finished))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo
|
||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskProgressLabel
|
||||
import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
||||
import com.github.nullptroma.wallenc.domain.tasks.VaultTaskStep
|
||||
import com.github.nullptroma.wallenc.usecases.GetOpenedStoragesUseCase
|
||||
import com.github.nullptroma.wallenc.usecases.ManageStoragesEncryptionUseCase
|
||||
import com.github.nullptroma.wallenc.usecases.ManageVaultUseCase
|
||||
@@ -162,9 +164,9 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
dispatcher = Dispatchers.IO,
|
||||
busyStorageUuid = id,
|
||||
work = { ctx ->
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_dump_storage_log))
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.DumpStorageLog))
|
||||
storageFileManagementUseCase.setStorage(storage)
|
||||
ctx.log(TaskLogLevel.Info, "Enumerating files and directories…")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_enumerating))
|
||||
val files: List<IFile>
|
||||
val dirs: List<IDirectory>
|
||||
val time = measureTimeMillis {
|
||||
@@ -181,7 +183,7 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
logger.debug("Storage", storage.toPrintable())
|
||||
ctx.log(
|
||||
TaskLogLevel.Info,
|
||||
"Done: ${files.size} files, ${dirs.size} dirs in ${time}ms (see app log for lines)",
|
||||
uiStrings(R.string.task_log_enumerate_done, files.size, dirs.size, time),
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -204,17 +206,17 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
locksVaultStorageList = true,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_create_storage))
|
||||
ctx.log(TaskLogLevel.Info, "Creating storage…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.CreateStorage))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_creating_storage))
|
||||
val uuid = resolveCreateVaultUuid()
|
||||
?: throw IllegalStateException("Vault is not available")
|
||||
logger.debug(TAG, "createStorage: vaultUuid=$uuid")
|
||||
val storage = manageVaultUseCase.createStorage(uuid)
|
||||
ctx.log(TaskLogLevel.Info, "Storage created")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_storage_created))
|
||||
logger.debug(TAG, "createStorage: done storageUuid=${storage.uuid}")
|
||||
} catch (e: Exception) {
|
||||
logger.debug(TAG, "createStorage failed: ${e.stackTraceToString()}")
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: e.toString())
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_add_vault_failed))
|
||||
throw e
|
||||
}
|
||||
},
|
||||
@@ -239,35 +241,35 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
busyStorageUuid = id,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_enable_encryption))
|
||||
ctx.log(TaskLogLevel.Info, "Checking storage…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.EnableEncryption))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_checking_storage))
|
||||
when (manageStoragesEncryptionUseCase.canEncrypt(storage)) {
|
||||
ManageStoragesEncryptionUseCase.CanEncryptResult.Allowed -> {
|
||||
ctx.log(TaskLogLevel.Info, "Encrypting…")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_encrypting))
|
||||
manageStoragesEncryptionUseCase.enableEncryption(storage, key, encryptPath)
|
||||
manageStoragesEncryptionUseCase.openStorage(storage, key, rememberPassword)
|
||||
ctx.log(TaskLogLevel.Info, "Encryption enabled")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_encryption_enabled))
|
||||
_userNotifications.emit(UserNotification.TextRes(R.string.msg_encryption_enabled))
|
||||
}
|
||||
ManageStoragesEncryptionUseCase.CanEncryptResult.AlreadyEncrypted -> {
|
||||
ctx.log(TaskLogLevel.Info, "Storage is already encrypted")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_already_encrypted))
|
||||
_userNotifications.emit(UserNotification.TextRes(R.string.msg_storage_already_encrypted))
|
||||
}
|
||||
ManageStoragesEncryptionUseCase.CanEncryptResult.StorageIsNotEmpty -> {
|
||||
ctx.log(TaskLogLevel.Info, "Storage is not empty")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_not_empty))
|
||||
_userNotifications.emit(UserNotification.TextRes(R.string.msg_storage_not_empty))
|
||||
}
|
||||
ManageStoragesEncryptionUseCase.CanEncryptResult.StorageStateUnknown -> {
|
||||
ctx.log(TaskLogLevel.Info, "Cannot determine whether storage is empty")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_empty_unknown))
|
||||
_userNotifications.emit(UserNotification.TextRes(R.string.msg_storage_empty_state_unknown))
|
||||
}
|
||||
ManageStoragesEncryptionUseCase.CanEncryptResult.UnsupportedStorageType -> {
|
||||
ctx.log(TaskLogLevel.Info, "Unsupported storage type")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_unsupported_type))
|
||||
_userNotifications.emit(UserNotification.TextRes(R.string.msg_unsupported_storage_type))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "Failed to enable encryption")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_enable_encryption_failed))
|
||||
emitTaskError(e)
|
||||
}
|
||||
},
|
||||
@@ -287,12 +289,12 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
busyStorageUuid = id,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_decrypt_running))
|
||||
ctx.log(TaskLogLevel.Info, "Opening encrypted storage…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.DecryptRunning))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_opening_storage))
|
||||
manageStoragesEncryptionUseCase.openStorage(storage, key, rememberPassword)
|
||||
ctx.log(TaskLogLevel.Info, "Storage opened")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_storage_opened))
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "Failed to open encrypted storage")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_open_storage_failed))
|
||||
emitTaskError(e)
|
||||
}
|
||||
},
|
||||
@@ -311,12 +313,12 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
busyStorageUuid = id,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_close_storage))
|
||||
ctx.log(TaskLogLevel.Info, "Closing storage…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.CloseStorage))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_closing_storage))
|
||||
manageStoragesEncryptionUseCase.closeStorage(storage)
|
||||
ctx.log(TaskLogLevel.Info, "Storage closed")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_storage_closed))
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "Failed to close encrypted storage")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_close_storage_failed))
|
||||
emitTaskError(e)
|
||||
}
|
||||
},
|
||||
@@ -335,17 +337,18 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
busyStorageUuid = id,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_disable_encryption))
|
||||
ctx.log(TaskLogLevel.Info, "Disabling encryption…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.DisableEncryption))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_disabling_encryption))
|
||||
manageStoragesEncryptionUseCase.clearAndDisableEncryption(storage) { p ->
|
||||
val label = p.label?.takeIf { it.isNotBlank() }
|
||||
?: uiStrings(R.string.task_progress_disable_encryption)
|
||||
ctx.reportProgress(p.fraction, label)
|
||||
ctx.reportProgress(
|
||||
p.fraction,
|
||||
p.label ?: TaskProgressLabel.VaultTask(VaultTaskStep.DisableEncryption),
|
||||
)
|
||||
}
|
||||
ctx.log(TaskLogLevel.Info, "Encryption disabled")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_encryption_disabled))
|
||||
_userNotifications.emit(UserNotification.TextRes(R.string.msg_encryption_disabled))
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "Failed")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_disable_encryption_failed))
|
||||
emitTaskError(e)
|
||||
}
|
||||
},
|
||||
@@ -364,12 +367,12 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
busyStorageUuid = id,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_rename_storage))
|
||||
ctx.log(TaskLogLevel.Info, "Renaming…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.RenameStorage))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_renaming))
|
||||
renameStorageUseCase.rename(storage, newName)
|
||||
ctx.log(TaskLogLevel.Info, "Renamed")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_renamed))
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "Rename failed")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_rename_failed))
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -388,12 +391,12 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
locksVaultStorageList = true,
|
||||
work = { ctx ->
|
||||
try {
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_remove_storage))
|
||||
ctx.log(TaskLogLevel.Info, "Removing storage…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.RemoveStorage))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_removing_storage))
|
||||
removeStorageUseCase.remove(storage)
|
||||
ctx.log(TaskLogLevel.Info, "Removed")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_removed))
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "Remove failed")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_remove_failed))
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -435,17 +438,17 @@ abstract class AbstractVaultBrowserViewModel(
|
||||
try {
|
||||
val s = storage as? IStorage
|
||||
if (s == null) {
|
||||
ctx.log(TaskLogLevel.Error, "Invalid storage")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_invalid_storage))
|
||||
_userNotifications.emit(UserNotification.TextRes(R.string.msg_invalid_storage_for_sync_lock))
|
||||
return@enqueue
|
||||
}
|
||||
ctx.reportProgress(null, uiStrings(R.string.task_progress_clear_sync_lock))
|
||||
ctx.log(TaskLogLevel.Info, "Clearing sync lock…")
|
||||
ctx.reportProgress(null, TaskProgressLabel.VaultTask(VaultTaskStep.ClearSyncLock))
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_clearing_sync_lock))
|
||||
s.accessor.forceClearSyncLock()
|
||||
ctx.log(TaskLogLevel.Info, "Sync lock cleared")
|
||||
ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_sync_lock_cleared))
|
||||
_userNotifications.emit(UserNotification.TextRes(R.string.msg_sync_lock_cleared))
|
||||
} catch (e: Exception) {
|
||||
ctx.log(TaskLogLevel.Error, e.message ?: "clear sync lock failed")
|
||||
ctx.log(TaskLogLevel.Error, uiStrings(R.string.task_log_clear_sync_lock_failed))
|
||||
emitTaskError(e)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,21 +2,86 @@ package com.github.nullptroma.wallenc.ui.screens.settings
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.selection.selectable
|
||||
import androidx.compose.foundation.selection.selectableGroup
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
import com.github.nullptroma.wallenc.ui.locale.AppLanguage
|
||||
|
||||
@Composable
|
||||
fun SettingsScreen(modifier: Modifier, viewModel: SettingsViewModel) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
|
||||
Column(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.settings_title))
|
||||
Text(
|
||||
text = stringResource(id = R.string.settings_title),
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.settings_language_section),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
Column(Modifier.selectableGroup()) {
|
||||
LanguageOption(
|
||||
label = stringResource(R.string.settings_language_system),
|
||||
selected = state.selectedLanguage == AppLanguage.System,
|
||||
onClick = { viewModel.setLanguage(AppLanguage.System) },
|
||||
)
|
||||
LanguageOption(
|
||||
label = stringResource(R.string.settings_language_english),
|
||||
selected = state.selectedLanguage == AppLanguage.English,
|
||||
onClick = { viewModel.setLanguage(AppLanguage.English) },
|
||||
)
|
||||
LanguageOption(
|
||||
label = stringResource(R.string.settings_language_russian),
|
||||
selected = state.selectedLanguage == AppLanguage.Russian,
|
||||
onClick = { viewModel.setLanguage(AppLanguage.Russian) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LanguageOption(
|
||||
label: String,
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.selectable(
|
||||
selected = selected,
|
||||
onClick = onClick,
|
||||
role = Role.RadioButton,
|
||||
)
|
||||
.padding(vertical = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
RadioButton(selected = selected, onClick = onClick)
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
package com.github.nullptroma.wallenc.ui.screens.settings
|
||||
|
||||
class SettingsScreenState
|
||||
import com.github.nullptroma.wallenc.ui.locale.AppLanguage
|
||||
|
||||
data class SettingsScreenState(
|
||||
val selectedLanguage: AppLanguage = AppLanguage.System,
|
||||
)
|
||||
|
||||
@@ -1,8 +1,29 @@
|
||||
package com.github.nullptroma.wallenc.ui.screens.settings
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.github.nullptroma.wallenc.ui.ViewModelBase
|
||||
import com.github.nullptroma.wallenc.ui.locale.AppLanguage
|
||||
import com.github.nullptroma.wallenc.ui.locale.AppLocaleController
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class SettingsViewModel @javax.inject.Inject constructor() :
|
||||
ViewModelBase<SettingsScreenState>(SettingsScreenState())
|
||||
class SettingsViewModel @Inject constructor(
|
||||
private val appLocaleController: AppLocaleController,
|
||||
) : ViewModelBase<SettingsScreenState>(SettingsScreenState()) {
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
appLocaleController.language.collect { language ->
|
||||
updateState(state.value.copy(selectedLanguage = language))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setLanguage(language: AppLanguage) {
|
||||
viewModelScope.launch {
|
||||
appLocaleController.setLanguage(language)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
||||
import com.github.nullptroma.wallenc.ui.R
|
||||
import com.github.nullptroma.wallenc.ui.ViewModelBase
|
||||
import com.github.nullptroma.wallenc.ui.resources.UiStringResolver
|
||||
import com.github.nullptroma.wallenc.ui.resources.resolve
|
||||
import com.github.nullptroma.wallenc.ui.resources.UserNotification
|
||||
import com.github.nullptroma.wallenc.usecases.AddStorageToSyncGroupResult
|
||||
import com.github.nullptroma.wallenc.usecases.ManageStorageSyncGroupsUseCase
|
||||
@@ -74,7 +75,7 @@ class StorageSyncViewModel @Inject constructor(
|
||||
Triple(
|
||||
syncRunning,
|
||||
progress?.fraction,
|
||||
progress?.label?.takeIf { it.isNotBlank() },
|
||||
progress?.label?.resolve(uiStrings),
|
||||
)
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
|
||||
337
ui/src/main/res/values-ru/strings.xml
Normal file
337
ui/src/main/res/values-ru/strings.xml
Normal file
@@ -0,0 +1,337 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="nav_label_local_vault">Локальное хранилище</string>
|
||||
<string name="nav_cd_local_vault">Локальное хранилище</string>
|
||||
<string name="nav_label_remote_vaults">Удалённые хранилища</string>
|
||||
<string name="nav_cd_remote_vaults">Удалённые хранилища</string>
|
||||
<string name="nav_label_main">Главная</string>
|
||||
<string name="nav_label_sync">Синхронизация</string>
|
||||
<string name="nav_label_settings">Настройки</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="settings_title">Настройки</string>
|
||||
<string name="sync_groups_title">Группы синхронизации</string>
|
||||
<string name="sync_progress_section_title">Синхронизация хранилищ</string>
|
||||
<string name="sync_groups_busy_section_title">Сохранение групп синхронизации</string>
|
||||
<string name="sync_run_now">Запустить синхронизацию</string>
|
||||
<string name="sync_cd_run_now">Запустить синхронизацию сейчас</string>
|
||||
<string name="sync_refresh">Обновить</string>
|
||||
<string name="sync_add_storage">Добавить хранилище в группу</string>
|
||||
<string name="sync_remove_group">Удалить группу</string>
|
||||
<string name="sync_group_empty">В группе нет хранилищ</string>
|
||||
<string name="sync_remove_storage">Убрать хранилище из группы</string>
|
||||
<string name="sync_picker_back">Назад</string>
|
||||
<string name="sync_cd_picker_back">Закрыть выбор хранилища</string>
|
||||
<string name="sync_picker_title">Выбор хранилища для %1$s</string>
|
||||
<string name="sync_picker_add">Добавить</string>
|
||||
<string name="sync_picker_added">Добавлено</string>
|
||||
<string name="sync_picker_cd_add">Добавить хранилище в группу</string>
|
||||
<string name="sync_picker_no_storages">В этом хранилище нет доступных каталогов</string>
|
||||
<string name="sync_picker_expand">Развернуть</string>
|
||||
<string name="sync_picker_collapse">Свернуть</string>
|
||||
<string name="sync_fab_create_group_cd">Создать группу синхронизации</string>
|
||||
<string name="sync_group_mixed_encryption_warning">В группе разное шифрование: задайте единый режим</string>
|
||||
<string name="sync_group_incompatible_warning">Несовместимые хранилища в группе: %1$d</string>
|
||||
<string name="sync_group_policy_line">Политика шифрования группы: %1$s</string>
|
||||
<string name="sync_group_policy_unset">Не определена (группа пуста)</string>
|
||||
<string name="sync_group_policy_plain">Только незашифрованные</string>
|
||||
<string name="sync_group_policy_password">Только зашифрованные с паролем группы</string>
|
||||
<string name="sync_remove_group_confirm_title">Удалить группу?</string>
|
||||
<string name="sync_remove_group_confirm_message">Удалить группу синхронизации «%1$s»?</string>
|
||||
<string name="sync_remove_storage_confirm_title">Убрать хранилище?</string>
|
||||
<string name="sync_remove_storage_confirm_message">Убрать хранилище «%1$s» из группы?</string>
|
||||
<string name="sync_confirm_delete">Удалить</string>
|
||||
<string name="sync_cancel">Отмена</string>
|
||||
<string name="sync_msg_group_created">Создана группа %1$s</string>
|
||||
<string name="sync_msg_group_removed">Группа удалена</string>
|
||||
<string name="sync_msg_storage_added">Хранилище добавлено в %1$s</string>
|
||||
<string name="sync_msg_storage_removed">Хранилище убрано из %1$s</string>
|
||||
<string name="sync_msg_storage_already_added">Хранилище уже добавлено в группу</string>
|
||||
<string name="sync_msg_only_plain_storage_allowed">В группы синхронизации можно добавлять только незашифрованные хранилища</string>
|
||||
<string name="sync_msg_storage_encryption_key_required">Для зашифрованного хранилища нужно знать пароль (откройте его перед добавлением)</string>
|
||||
<string name="sync_msg_storage_incompatible_encryption">Хранилище не совместимо с политикой шифрования группы</string>
|
||||
<string name="sync_msg_virtual_storage_not_supported">Нельзя добавлять открытое виртуальное хранилище: синхронизация работает с исходными raw storage</string>
|
||||
<string name="sync_msg_task_enqueued">Задача синхронизации поставлена в очередь</string>
|
||||
<string name="sync_msg_sync_already_running">Синхронизация уже выполняется</string>
|
||||
<string name="sync_msg_blocked_during_sync">Дождитесь окончания синхронизации</string>
|
||||
<string name="sync_encryption_unknown">Неизвестно</string>
|
||||
<string name="sync_storage_encryption_line">Шифрование: %1$s</string>
|
||||
<string name="sync_storage_missing_title">Не найдено в текущих vault</string>
|
||||
<string name="sync_storage_pending_vault_scan">Ожидание: список хранилищ в vault ещё загружается</string>
|
||||
<string name="sync_storage_not_in_vaults">Нет в дереве хранилищ (удалено, другой аккаунт или не прошёл init)</string>
|
||||
<string name="sync_storage_unreachable">Хранилище недоступно (vault или сеть)</string>
|
||||
<string name="no_name"><без имени></string>
|
||||
<string name="show_storage_item_menu">Меню хранилища</string>
|
||||
<string name="storage_row_task_running_cd">Выполняется операция с этим хранилищем</string>
|
||||
<string name="storage_menu_busy">%1$s (задача выполняется)</string>
|
||||
<string name="rename">Переименовать</string>
|
||||
<string name="remove">Удалить</string>
|
||||
<string name="encrypt">Шифрование</string>
|
||||
<string name="new_name_title">Новое имя</string>
|
||||
<string name="remove_confirmation_dialog">Удалить хранилище «%1$s»?</string>
|
||||
<string name="storage_lock_actions">Действия с шифрованием</string>
|
||||
<string name="storage_sync_lock_checking">Проверка блокировки…</string>
|
||||
<string name="storage_sync_unlock_action">Снять блокировку синхронизации</string>
|
||||
<string name="storage_sync_not_locked">Синхронизация не заблокирована</string>
|
||||
<string name="storage_field_available">Доступно: %1$s</string>
|
||||
<string name="storage_value_yes">да</string>
|
||||
<string name="storage_value_no">нет</string>
|
||||
<string name="storage_field_files">Файлов: %1$s</string>
|
||||
<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_menu_unavailable">Недоступно: %1$s</string>
|
||||
<string name="storage_status_not_encrypted">Не зашифровано</string>
|
||||
<string name="storage_status_encrypted_open">Зашифровано (открыто)</string>
|
||||
<string name="storage_status_encrypted_closed">Зашифровано (закрыто)</string>
|
||||
<string name="vault_fab_add_storage_cd">Создать хранилище</string>
|
||||
<string name="vault_fab_add_storage_disabled_cd">Создание недоступно: хранилище недоступно</string>
|
||||
<string name="vault_fab_add_storage_busy_cd">Создание хранилища уже выполняется</string>
|
||||
<string name="vault_msg_storage_pipeline_busy">С этим хранилищем уже выполняется операция</string>
|
||||
<string name="vault_msg_vault_list_mutation_busy">Список хранилищ сейчас меняется — подождите</string>
|
||||
<string name="vault_unavailable_banner">Хранилище недоступно. Проверьте сеть, путь или разблокировку.</string>
|
||||
<string name="vault_loading_storages">Загрузка списка хранилищ…</string>
|
||||
<string name="vault_empty_list_hint">В этом хранилище пока нет каталогов. Создайте хранилище кнопкой «+», когда оно доступно.</string>
|
||||
<string name="task_pipeline_title">Очередь задач</string>
|
||||
<string name="task_pipeline_jobs">Задачи</string>
|
||||
<string name="task_pipeline_log">Журнал</string>
|
||||
<string name="task_pipeline_cancel_all">Отменить все</string>
|
||||
<string name="task_pipeline_open">Открыть очередь задач</string>
|
||||
<string name="task_pipeline_run_test">Тестовая задача</string>
|
||||
<string name="task_pipeline_test_dialog_title">Параметры тестовой задачи</string>
|
||||
<string name="task_pipeline_test_dialog_duration">Длительность: %1$d с</string>
|
||||
<string name="task_pipeline_test_dialog_start">Запустить</string>
|
||||
<string name="task_pipeline_test_dialog_cancel">Отмена</string>
|
||||
<string name="task_pipeline_test_dialog_infinity">Бесконечно (неопределённый прогресс)</string>
|
||||
<string name="task_pipeline_test_running">Тестовая задача (%1$d с)</string>
|
||||
<string name="task_pipeline_test_running_infinity">Тестовая задача (%1$d с, ∞)</string>
|
||||
<string name="task_state_queued">В очереди</string>
|
||||
<string name="task_state_running">Выполняется</string>
|
||||
<string name="task_state_completed">Завершено</string>
|
||||
<string name="task_state_cancelled">Отменено</string>
|
||||
<string name="task_state_failed">Ошибка: %1$s</string>
|
||||
<string name="task_title_dump_storage_log">Выгрузка дерева в журнал</string>
|
||||
<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_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>
|
||||
<string name="task_title_remove_storage">Удаление хранилища</string>
|
||||
<string name="task_title_clear_sync_lock">Снятие блокировки синхронизации</string>
|
||||
<string name="task_title_add_remote_vault">Добавление удалённого хранилища</string>
|
||||
<string name="task_title_remove_remote_vault">Удаление удалённого хранилища</string>
|
||||
<string name="task_title_retry_remote_vault">Повторное подключение удалённого хранилища</string>
|
||||
<string name="task_title_storage_sync">Синхронизация хранилищ</string>
|
||||
<string name="task_title_storage_sync_background">Фоновая синхронизация хранилищ</string>
|
||||
<string name="task_title_save_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_delete_text_secret">Удаление текстового секрета</string>
|
||||
<string name="error_storage_not_found">Хранилище не найдено</string>
|
||||
<string name="error_storage_locked_view">Откройте расшифрованное отображение storage для работы с этим разделом</string>
|
||||
<string name="error_secret_not_found">Секрет не найден</string>
|
||||
<string name="error_storage_not_writable">Хранилище недоступно для записи</string>
|
||||
<string name="error_file_not_found">Файл не найден</string>
|
||||
<string name="error_incorrect_password">Неверный пароль</string>
|
||||
<string name="error_storage_not_encrypted">Хранилище не зашифровано</string>
|
||||
<string name="error_enc_info_missing">Отсутствуют метаданные шифрования</string>
|
||||
<string name="error_delete_root_forbidden">Нельзя удалить корень хранилища</string>
|
||||
<string name="error_not_a_file">Ожидался файл</string>
|
||||
<string name="error_not_a_directory">Ожидалась папка</string>
|
||||
<string name="error_path_is_file">Путь указывает на файл, а не на папку</string>
|
||||
<string name="error_cannot_write_over_directory">Нельзя записать поверх папки</string>
|
||||
<string name="error_unexpected_state">Хранилище в неожиданном состоянии</string>
|
||||
<string name="error_network">Ошибка сети или сервера</string>
|
||||
<string name="error_disk_resource_locked">Ресурс временно заблокирован. Повторите позже.</string>
|
||||
<string name="error_unknown">Что-то пошло не так</string>
|
||||
<string name="sync_error_group_not_found">Группа синхронизации не найдена</string>
|
||||
<string name="vault_link_error_auth">Не удалось войти</string>
|
||||
<string name="vault_link_error_not_registered">Вход не готов. Перезапустите приложение.</string>
|
||||
<string name="vault_link_error_unknown">Не удалось войти</string>
|
||||
<string name="vault_link_error_unsupported_brand">Этот провайдер не поддерживается</string>
|
||||
<string name="msg_encryption_enabled">Шифрование включено</string>
|
||||
<string name="msg_storage_already_encrypted">Хранилище уже зашифровано</string>
|
||||
<string name="msg_storage_not_empty">Хранилище не пустое</string>
|
||||
<string name="msg_storage_empty_state_unknown">Не удалось определить, пусто ли хранилище</string>
|
||||
<string name="msg_unsupported_storage_type">Неподдерживаемый тип хранилища</string>
|
||||
<string name="msg_encryption_disabled">Шифрование отключено</string>
|
||||
<string name="msg_invalid_storage_for_sync_lock">Некорректное хранилище</string>
|
||||
<string name="msg_sync_lock_cleared">Блокировка синхронизации снята</string>
|
||||
<string name="remote_vaults_add_cd">Добавить удалённое хранилище</string>
|
||||
<string name="remote_vaults_empty_hint">Пока нет удалённых хранилищ. Нажмите «+», чтобы добавить Yandex.</string>
|
||||
<string name="remote_vaults_add_title">Добавить хранилище</string>
|
||||
<string name="remote_vaults_add_pick_provider">Выберите провайдера:</string>
|
||||
<string name="remote_vaults_provider_yandex">Яндекс</string>
|
||||
<string name="remote_vaults_add_cancel">Отмена</string>
|
||||
<string name="remote_vault_type_yandex">Яндекс</string>
|
||||
<string name="remote_vault_unavailable">Хранилище временно недоступно</string>
|
||||
<string name="remote_vault_retry_action">Повторить подключение</string>
|
||||
<string name="remote_vault_retrying">Пробую подключиться…</string>
|
||||
<string name="remote_vault_delete_cd">Удалить удалённое хранилище</string>
|
||||
<string name="remote_vault_remove_title">Удалить удалённое хранилище?</string>
|
||||
<string name="remote_vault_remove_message">Удалить «%1$s» с этого устройства? Данные на сервере не удаляются.</string>
|
||||
<string name="dialog_cancel">Отмена</string>
|
||||
<string name="dialog_ok">ОК</string>
|
||||
<string name="dialog_encryption_enable_title">Включить шифрование</string>
|
||||
<string name="dialog_password_label">Пароль</string>
|
||||
<string name="dialog_encrypt_paths">Шифровать пути</string>
|
||||
<string name="dialog_apply">Применить</string>
|
||||
<string name="dialog_open_encrypted_title">Открыть зашифрованное хранилище</string>
|
||||
<string name="dialog_remember_password">Запомнить пароль</string>
|
||||
<string name="dialog_open">Открыть</string>
|
||||
<string name="dialog_close">Закрыть</string>
|
||||
<string name="dialog_disable_encryption">Отключить шифрование</string>
|
||||
<string name="dialog_done">Готово</string>
|
||||
<string name="vault_type_local_device">Локальное устройство</string>
|
||||
<string name="vault_type_remote">Удалённое: %1$s</string>
|
||||
<string name="vault_type_unknown">Неизвестный тип</string>
|
||||
<string name="vault_title_local">Локальное хранилище</string>
|
||||
<string name="vault_title_unknown">Неизвестное хранилище</string>
|
||||
<string name="enc_status_not_encrypted">Не зашифровано</string>
|
||||
<string name="enc_status_encrypted_open">Зашифровано (открыто)</string>
|
||||
<string name="enc_status_encrypted">Зашифровано</string>
|
||||
<string name="text_edit_screen_title">Текст</string>
|
||||
<string name="text_edit_screen_placeholder">Содержимое: %1$s</string>
|
||||
<string name="storage_home_unnamed_storage">Storage</string>
|
||||
<string name="storage_home_status_line">Статус: %1$s, %2$s</string>
|
||||
<string name="storage_home_status_available">доступно</string>
|
||||
<string name="storage_home_status_unavailable">недоступно</string>
|
||||
<string name="storage_home_status_encrypted">зашифровано</string>
|
||||
<string name="storage_home_status_not_encrypted">не зашифровано</string>
|
||||
<string name="storage_home_two_fa_title">2FA токены (%1$d)</string>
|
||||
<string name="storage_home_open_two_fa">Открыть 2FA</string>
|
||||
<string name="storage_home_two_fa_subtitle">Коды и секреты двухфакторной аутентификации</string>
|
||||
<string name="storage_home_text_secrets_title">Текстовые секреты (%1$d)</string>
|
||||
<string name="storage_home_open_text_secrets">Открыть текстовые секреты</string>
|
||||
<string name="storage_home_text_secrets_subtitle">Заметки, токены и произвольные пары ключ-значение</string>
|
||||
<string name="storage_home_future_sections">Скоро здесь появятся Files, Media и другие типы данных.</string>
|
||||
<string name="two_fa_add_token">Добавить токен</string>
|
||||
<string name="two_fa_empty_state">Пока нет 2FA токенов</string>
|
||||
<string name="two_fa_create_title">Новый 2FA токен</string>
|
||||
<string name="two_fa_edit_title">Редактирование 2FA токена</string>
|
||||
<string name="two_fa_field_issuer">Сервис</string>
|
||||
<string name="two_fa_field_account">Аккаунт</string>
|
||||
<string name="two_fa_field_secret">Секрет</string>
|
||||
<string name="two_fa_field_notes_optional">Заметка (опционально)</string>
|
||||
<string name="two_fa_field_digits">Количество цифр кода (обычно 6 или 8)</string>
|
||||
<string name="two_fa_field_period_seconds">Период обновления в секундах (обычно 30)</string>
|
||||
<string name="two_fa_field_algorithm">Алгоритм (SHA1, SHA256, SHA512)</string>
|
||||
<string name="two_fa_field_digits_value">Количество цифр: %1$d</string>
|
||||
<string name="two_fa_field_period_seconds_value">Период обновления: %1$d с</string>
|
||||
<string name="two_fa_code_unavailable">------</string>
|
||||
<string name="two_fa_code_refresh_in">Обновление через %1$d с</string>
|
||||
<string name="two_fa_code_refresh_label">Обновление через</string>
|
||||
<string name="two_fa_code_refresh_seconds">%1$d с</string>
|
||||
<string name="two_fa_code_invalid_secret">Неверный секрет или формат</string>
|
||||
<string name="two_fa_copy_code_hint">Нажмите, чтобы скопировать код</string>
|
||||
<string name="two_fa_scan_qr_action">Сканировать QR</string>
|
||||
<string name="two_fa_scan_qr_title">Сканирование QR-кода TOTP</string>
|
||||
<string name="two_fa_scan_qr_invalid">QR-код не содержит валидный otpauth://totp URI</string>
|
||||
<string name="two_fa_camera_permission_required">Нужно разрешение на камеру для сканирования QR</string>
|
||||
<string name="text_secret_create">Создать секрет</string>
|
||||
<string name="text_secret_edit">Редактировать секрет</string>
|
||||
<string name="text_secret_title">Название</string>
|
||||
<string name="text_secret_empty_state">Пока нет текстовых секретов</string>
|
||||
<string name="text_secret_items_count">Элементов: %1$d</string>
|
||||
<string name="text_secret_item_without_label">Без названия</string>
|
||||
<string name="text_secret_more_fields">ещё полей: %1$d</string>
|
||||
<string name="text_secret_item_label_optional">Название (опционально)</string>
|
||||
<string name="text_secret_item_value">Значение</string>
|
||||
<string name="text_secret_add_item">Добавить пару</string>
|
||||
<string name="text_secret_copy_value">Скопировать значение</string>
|
||||
<string name="save">Сохранить</string>
|
||||
<string name="cancel">Отмена</string>
|
||||
<string name="open">Открыть</string>
|
||||
<string name="edit">Редактировать</string>
|
||||
<string name="common_unknown">Неизвестно</string>
|
||||
<string name="settings_language_section">Язык</string>
|
||||
<string name="settings_language_system">Как в системе</string>
|
||||
<string name="settings_language_english">English</string>
|
||||
<string name="settings_language_russian">Русский</string>
|
||||
<string name="task_pipeline_test_elapsed">Прошло: %1$d с / %2$d с</string>
|
||||
<string name="text_secret_clipboard_fallback_label">значение</string>
|
||||
<string name="sync_progress_no_groups">Синхронизация: группы не настроены</string>
|
||||
<string name="sync_progress_preparing">Синхронизация: подготовка %1$d групп</string>
|
||||
<string name="sync_progress_started">Синхронизация: запущена</string>
|
||||
<string name="sync_progress_completed">Синхронизация: завершена</string>
|
||||
<string name="sync_progress_group_preparing">Синхронизация: группа «%1$s» — подготовка</string>
|
||||
<string name="sync_progress_group_not_found">Синхронизация: группа «%1$s» не найдена</string>
|
||||
<string name="sync_progress_group_skipped_few_storages">Синхронизация: группа «%1$s» пропущена (нужно минимум 2 хранилища)</string>
|
||||
<string name="sync_progress_group_skipped_incompatible">Синхронизация: группа «%1$s» пропущена (несовместимое шифрование: %2$d)</string>
|
||||
<string name="sync_progress_group_acquiring_locks">Синхронизация: группа «%1$s» — получение блокировок</string>
|
||||
<string name="sync_progress_group_lock">Синхронизация: группа «%1$s» — блокировка %2$d/%3$d</string>
|
||||
<string name="sync_progress_group_lock_failed">Синхронизация: группа «%1$s» — блокировка не получена, пропуск</string>
|
||||
<string name="sync_progress_group_reading_journals">Синхронизация: группа «%1$s» — чтение журналов</string>
|
||||
<string name="sync_progress_group_cancelled">Синхронизация: группа «%1$s» отменена новым запуском</string>
|
||||
<string name="sync_progress_group_journal">Синхронизация: группа «%1$s» — журнал %2$d/%3$d</string>
|
||||
<string name="sync_progress_group_no_entries">Синхронизация: группа «%1$s» — нет записей в журнале</string>
|
||||
<string name="sync_progress_group_processing">Синхронизация: группа «%1$s» — обработка %2$d записей</string>
|
||||
<string name="sync_progress_group_entry">Синхронизация: группа «%1$s» — запись %2$d/%3$d</string>
|
||||
<string name="sync_progress_group_completed">Синхронизация: группа «%1$s» завершена</string>
|
||||
<string name="sync_progress_group_renewing_locks">Синхронизация: группа «%1$s» — продление блокировок</string>
|
||||
<string name="sync_progress_group_lock_renewal_failed">Синхронизация: группа «%1$s» — не удалось продлить блокировку</string>
|
||||
<string name="task_progress_clear_content">%1$d / %2$d</string>
|
||||
<string name="task_log_sync_started">Синхронизация хранилищ запущена</string>
|
||||
<string name="task_log_sync_finished">Синхронизация хранилищ завершена</string>
|
||||
<string name="task_log_sync_failed">Синхронизация не удалась: %1$s</string>
|
||||
<string name="task_log_enumerating">Перечисление файлов и папок…</string>
|
||||
<string name="task_log_enumerate_done">Готово: %1$d файлов, %2$d папок за %3$d мс (подробности в журнале приложения)</string>
|
||||
<string name="task_log_creating_storage">Создание хранилища…</string>
|
||||
<string name="task_log_storage_created">Хранилище создано</string>
|
||||
<string name="task_log_checking_storage">Проверка хранилища…</string>
|
||||
<string name="task_log_encrypting">Шифрование…</string>
|
||||
<string name="task_log_encryption_enabled">Шифрование включено</string>
|
||||
<string name="task_log_already_encrypted">Хранилище уже зашифровано</string>
|
||||
<string name="task_log_not_empty">Хранилище не пустое</string>
|
||||
<string name="task_log_empty_unknown">Не удалось определить, пусто ли хранилище</string>
|
||||
<string name="task_log_unsupported_type">Неподдерживаемый тип хранилища</string>
|
||||
<string name="task_log_enable_encryption_failed">Не удалось включить шифрование</string>
|
||||
<string name="task_log_opening_storage">Открытие зашифрованного хранилища…</string>
|
||||
<string name="task_log_storage_opened">Хранилище открыто</string>
|
||||
<string name="task_log_open_storage_failed">Не удалось открыть хранилище</string>
|
||||
<string name="task_log_closing_storage">Закрытие хранилища…</string>
|
||||
<string name="task_log_storage_closed">Хранилище закрыто</string>
|
||||
<string name="task_log_close_storage_failed">Не удалось закрыть хранилище</string>
|
||||
<string name="task_log_disabling_encryption">Отключение шифрования…</string>
|
||||
<string name="task_log_encryption_disabled">Шифрование отключено</string>
|
||||
<string name="task_log_disable_encryption_failed">Не удалось отключить шифрование</string>
|
||||
<string name="task_log_renaming">Переименование…</string>
|
||||
<string name="task_log_renamed">Переименовано</string>
|
||||
<string name="task_log_rename_failed">Не удалось переименовать</string>
|
||||
<string name="task_log_removing_storage">Удаление хранилища…</string>
|
||||
<string name="task_log_removed">Удалено</string>
|
||||
<string name="task_log_remove_failed">Не удалось удалить</string>
|
||||
<string name="task_log_invalid_storage">Некорректное хранилище</string>
|
||||
<string name="task_log_clearing_sync_lock">Снятие блокировки синхронизации…</string>
|
||||
<string name="task_log_sync_lock_cleared">Блокировка синхронизации снята</string>
|
||||
<string name="task_log_clear_sync_lock_failed">Не удалось снять блокировку</string>
|
||||
<string name="task_log_adding_vault">Добавление хранилища…</string>
|
||||
<string name="task_log_vault_added">Хранилище добавлено</string>
|
||||
<string name="task_log_add_vault_failed">Не удалось добавить хранилище</string>
|
||||
<string name="task_log_removing_remote_vault">Удаление удалённого хранилища…</string>
|
||||
<string name="task_log_remote_vault_removed">Удалённое хранилище удалено</string>
|
||||
<string name="task_log_remove_vault_failed">Не удалось удалить хранилище</string>
|
||||
<string name="task_log_retrying_vault">Повторное подключение…</string>
|
||||
<string name="task_log_retry_requested">Повтор запрошен</string>
|
||||
<string name="task_log_retry_vault_failed">Не удалось повторить подключение</string>
|
||||
<string name="task_log_test_started">Тестовая задача запущена на %1$d с</string>
|
||||
<string name="task_log_test_finished">Тестовая задача завершена</string>
|
||||
</resources>
|
||||
@@ -1,290 +1,337 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="nav_label_local_vault">Локальное хранилище</string>
|
||||
<string name="nav_cd_local_vault">Локальное хранилище</string>
|
||||
<string name="nav_label_remote_vaults">Удалённые хранилища</string>
|
||||
<string name="nav_cd_remote_vaults">Удалённые хранилища</string>
|
||||
<string name="nav_label_main">Главная</string>
|
||||
<string name="nav_label_sync">Синхронизация</string>
|
||||
<string name="nav_label_settings">Настройки</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="settings_title">Настройки</string>
|
||||
<string name="sync_groups_title">Группы синхронизации</string>
|
||||
<string name="sync_progress_section_title">Синхронизация хранилищ</string>
|
||||
<string name="sync_groups_busy_section_title">Сохранение групп синхронизации</string>
|
||||
<string name="sync_run_now">Запустить синхронизацию</string>
|
||||
<string name="sync_cd_run_now">Запустить синхронизацию сейчас</string>
|
||||
<string name="sync_refresh">Обновить</string>
|
||||
<string name="sync_add_storage">Добавить хранилище в группу</string>
|
||||
<string name="sync_remove_group">Удалить группу</string>
|
||||
<string name="sync_group_empty">В группе нет хранилищ</string>
|
||||
<string name="sync_remove_storage">Убрать хранилище из группы</string>
|
||||
<string name="sync_picker_back">Назад</string>
|
||||
<string name="sync_cd_picker_back">Закрыть выбор хранилища</string>
|
||||
<string name="sync_picker_title">Выбор хранилища для %1$s</string>
|
||||
<string name="sync_picker_add">Добавить</string>
|
||||
<string name="sync_picker_added">Добавлено</string>
|
||||
<string name="sync_picker_cd_add">Добавить хранилище в группу</string>
|
||||
<string name="sync_picker_no_storages">В этом хранилище нет доступных каталогов</string>
|
||||
<string name="sync_picker_expand">Развернуть</string>
|
||||
<string name="sync_picker_collapse">Свернуть</string>
|
||||
<string name="sync_fab_create_group_cd">Создать группу синхронизации</string>
|
||||
<string name="sync_group_mixed_encryption_warning">В группе разное шифрование: задайте единый режим</string>
|
||||
<string name="sync_group_incompatible_warning">Несовместимые хранилища в группе: %1$d</string>
|
||||
<string name="sync_group_policy_line">Политика шифрования группы: %1$s</string>
|
||||
<string name="sync_group_policy_unset">Не определена (группа пуста)</string>
|
||||
<string name="sync_group_policy_plain">Только незашифрованные</string>
|
||||
<string name="sync_group_policy_password">Только зашифрованные с паролем группы</string>
|
||||
<string name="sync_remove_group_confirm_title">Удалить группу?</string>
|
||||
<string name="sync_remove_group_confirm_message">Удалить группу синхронизации «%1$s»?</string>
|
||||
<string name="sync_remove_storage_confirm_title">Убрать хранилище?</string>
|
||||
<string name="sync_remove_storage_confirm_message">Убрать хранилище «%1$s» из группы?</string>
|
||||
<string name="sync_confirm_delete">Удалить</string>
|
||||
<string name="sync_cancel">Отмена</string>
|
||||
<string name="sync_msg_group_created">Создана группа %1$s</string>
|
||||
<string name="sync_msg_group_removed">Группа удалена</string>
|
||||
<string name="sync_msg_storage_added">Хранилище добавлено в %1$s</string>
|
||||
<string name="sync_msg_storage_removed">Хранилище убрано из %1$s</string>
|
||||
<string name="sync_msg_storage_already_added">Хранилище уже добавлено в группу</string>
|
||||
<string name="sync_msg_only_plain_storage_allowed">В группы синхронизации можно добавлять только незашифрованные хранилища</string>
|
||||
<string name="sync_msg_storage_encryption_key_required">Для зашифрованного хранилища нужно знать пароль (откройте его перед добавлением)</string>
|
||||
<string name="sync_msg_storage_incompatible_encryption">Хранилище не совместимо с политикой шифрования группы</string>
|
||||
<string name="sync_msg_virtual_storage_not_supported">Нельзя добавлять открытое виртуальное хранилище: синхронизация работает с исходными raw storage</string>
|
||||
<string name="sync_msg_task_enqueued">Задача синхронизации поставлена в очередь</string>
|
||||
<string name="sync_msg_sync_already_running">Синхронизация уже выполняется</string>
|
||||
<string name="sync_msg_blocked_during_sync">Дождитесь окончания синхронизации</string>
|
||||
<string name="sync_encryption_unknown">Неизвестно</string>
|
||||
<string name="sync_storage_encryption_line">Шифрование: %1$s</string>
|
||||
<string name="sync_storage_missing_title">Не найдено в текущих vault</string>
|
||||
<string name="sync_storage_pending_vault_scan">Ожидание: список хранилищ в vault ещё загружается</string>
|
||||
<string name="sync_storage_not_in_vaults">Нет в дереве хранилищ (удалено, другой аккаунт или не прошёл init)</string>
|
||||
<string name="sync_storage_unreachable">Хранилище недоступно (vault или сеть)</string>
|
||||
|
||||
<string name="no_name"><без имени></string>
|
||||
<string name="show_storage_item_menu">Меню хранилища</string>
|
||||
<string name="storage_row_task_running_cd">Выполняется операция с этим хранилищем</string>
|
||||
<string name="storage_menu_busy">%1$s (задача выполняется)</string>
|
||||
<string name="rename">Переименовать</string>
|
||||
<string name="remove">Удалить</string>
|
||||
<string name="encrypt">Шифрование</string>
|
||||
<string name="new_name_title">Новое имя</string>
|
||||
<string name="remove_confirmation_dialog">Удалить хранилище «%1$s»?</string>
|
||||
<string name="storage_lock_actions">Действия с шифрованием</string>
|
||||
<string name="storage_sync_lock_checking">Проверка блокировки…</string>
|
||||
<string name="storage_sync_unlock_action">Снять блокировку синхронизации</string>
|
||||
<string name="storage_sync_not_locked">Синхронизация не заблокирована</string>
|
||||
|
||||
<string name="storage_field_available">Доступно: %1$s</string>
|
||||
<string name="storage_value_yes">да</string>
|
||||
<string name="storage_value_no">нет</string>
|
||||
<string name="storage_field_files">Файлов: %1$s</string>
|
||||
<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_menu_unavailable">Недоступно: %1$s</string>
|
||||
|
||||
<string name="storage_status_not_encrypted">Не зашифровано</string>
|
||||
<string name="storage_status_encrypted_open">Зашифровано (открыто)</string>
|
||||
<string name="storage_status_encrypted_closed">Зашифровано (закрыто)</string>
|
||||
|
||||
<string name="vault_fab_add_storage_cd">Создать хранилище</string>
|
||||
<string name="vault_fab_add_storage_disabled_cd">Создание недоступно: хранилище недоступно</string>
|
||||
<string name="vault_fab_add_storage_busy_cd">Создание хранилища уже выполняется</string>
|
||||
<string name="vault_msg_storage_pipeline_busy">С этим хранилищем уже выполняется операция</string>
|
||||
<string name="vault_msg_vault_list_mutation_busy">Список хранилищ сейчас меняется — подождите</string>
|
||||
<string name="vault_unavailable_banner">Хранилище недоступно. Проверьте сеть, путь или разблокировку.</string>
|
||||
<string name="vault_loading_storages">Загрузка списка хранилищ…</string>
|
||||
<string name="vault_empty_list_hint">В этом хранилище пока нет каталогов. Создайте хранилище кнопкой «+», когда оно доступно.</string>
|
||||
|
||||
<string name="task_pipeline_title">Очередь задач</string>
|
||||
<string name="task_pipeline_jobs">Задачи</string>
|
||||
<string name="task_pipeline_log">Журнал</string>
|
||||
<string name="task_pipeline_cancel_all">Отменить все</string>
|
||||
<string name="task_pipeline_open">Открыть очередь задач</string>
|
||||
<string name="task_pipeline_run_test">Тестовая задача</string>
|
||||
<string name="task_pipeline_test_dialog_title">Параметры тестовой задачи</string>
|
||||
<string name="task_pipeline_test_dialog_duration">Длительность: %1$d с</string>
|
||||
<string name="task_pipeline_test_dialog_start">Запустить</string>
|
||||
<string name="task_pipeline_test_dialog_cancel">Отмена</string>
|
||||
<string name="task_pipeline_test_dialog_infinity">Бесконечно (неопределённый прогресс)</string>
|
||||
<string name="task_pipeline_test_running">Тестовая задача (%1$d с)</string>
|
||||
<string name="task_pipeline_test_running_infinity">Тестовая задача (%1$d с, ∞)</string>
|
||||
<string name="task_state_queued">В очереди</string>
|
||||
<string name="task_state_running">Выполняется</string>
|
||||
<string name="task_state_completed">Завершено</string>
|
||||
<string name="task_state_cancelled">Отменено</string>
|
||||
<string name="task_state_failed">Ошибка: %1$s</string>
|
||||
|
||||
<string name="task_title_dump_storage_log">Выгрузка дерева в журнал</string>
|
||||
<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_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>
|
||||
<string name="task_title_remove_storage">Удаление хранилища</string>
|
||||
<string name="task_title_clear_sync_lock">Снятие блокировки синхронизации</string>
|
||||
<string name="task_title_add_remote_vault">Добавление удалённого хранилища</string>
|
||||
<string name="task_title_remove_remote_vault">Удаление удалённого хранилища</string>
|
||||
<string name="task_title_retry_remote_vault">Повторное подключение удалённого хранилища</string>
|
||||
<string name="task_title_storage_sync">Синхронизация хранилищ</string>
|
||||
<string name="task_title_storage_sync_background">Фоновая синхронизация хранилищ</string>
|
||||
<string name="task_title_save_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_delete_text_secret">Удаление текстового секрета</string>
|
||||
|
||||
<string name="error_storage_not_found">Хранилище не найдено</string>
|
||||
<string name="error_storage_locked_view">Откройте расшифрованное отображение storage для работы с этим разделом</string>
|
||||
<string name="error_secret_not_found">Секрет не найден</string>
|
||||
<string name="error_storage_not_writable">Хранилище недоступно для записи</string>
|
||||
<string name="error_file_not_found">Файл не найден</string>
|
||||
<string name="error_incorrect_password">Неверный пароль</string>
|
||||
<string name="error_storage_not_encrypted">Хранилище не зашифровано</string>
|
||||
<string name="error_enc_info_missing">Отсутствуют метаданные шифрования</string>
|
||||
<string name="error_delete_root_forbidden">Нельзя удалить корень хранилища</string>
|
||||
<string name="error_not_a_file">Ожидался файл</string>
|
||||
<string name="error_not_a_directory">Ожидалась папка</string>
|
||||
<string name="error_path_is_file">Путь указывает на файл, а не на папку</string>
|
||||
<string name="error_cannot_write_over_directory">Нельзя записать поверх папки</string>
|
||||
<string name="error_unexpected_state">Хранилище в неожиданном состоянии</string>
|
||||
<string name="error_network">Ошибка сети или сервера</string>
|
||||
<string name="error_disk_resource_locked">Ресурс временно заблокирован. Повторите позже.</string>
|
||||
<string name="error_unknown">Что-то пошло не так</string>
|
||||
<string name="sync_error_group_not_found">Группа синхронизации не найдена</string>
|
||||
<string name="vault_link_error_auth">Не удалось войти</string>
|
||||
<string name="vault_link_error_not_registered">Вход не готов. Перезапустите приложение.</string>
|
||||
<string name="vault_link_error_unknown">Не удалось войти</string>
|
||||
<string name="vault_link_error_unsupported_brand">Этот провайдер не поддерживается</string>
|
||||
|
||||
<string name="msg_encryption_enabled">Шифрование включено</string>
|
||||
<string name="msg_storage_already_encrypted">Хранилище уже зашифровано</string>
|
||||
<string name="msg_storage_not_empty">Хранилище не пустое</string>
|
||||
<string name="msg_storage_empty_state_unknown">Не удалось определить, пусто ли хранилище</string>
|
||||
<string name="msg_unsupported_storage_type">Неподдерживаемый тип хранилища</string>
|
||||
<string name="msg_failed_enable_encryption">Не удалось включить шифрование: %1$s</string>
|
||||
<string name="msg_failed_open_storage">Не удалось открыть хранилище: %1$s</string>
|
||||
<string name="msg_failed_close_storage">Не удалось закрыть хранилище: %1$s</string>
|
||||
<string name="msg_encryption_disabled">Шифрование отключено</string>
|
||||
<string name="msg_failed_disable_encryption">Не удалось отключить шифрование: %1$s</string>
|
||||
<string name="msg_invalid_storage_for_sync_lock">Некорректное хранилище</string>
|
||||
<string name="msg_sync_lock_cleared">Блокировка синхронизации снята</string>
|
||||
<string name="msg_sync_lock_clear_failed">Не удалось снять блокировку: %1$s</string>
|
||||
|
||||
<string name="remote_vaults_add_cd">Добавить удалённое хранилище</string>
|
||||
<string name="remote_vaults_empty_hint">Пока нет удалённых хранилищ. Нажмите «+», чтобы добавить Yandex.</string>
|
||||
<string name="remote_vaults_add_title">Добавить хранилище</string>
|
||||
<string name="remote_vaults_add_pick_provider">Выберите провайдера:</string>
|
||||
<string name="remote_vaults_provider_yandex">Яндекс</string>
|
||||
<string name="remote_vaults_add_cancel">Отмена</string>
|
||||
<string name="remote_vault_type_yandex">Яндекс</string>
|
||||
<string name="remote_vault_unavailable">Хранилище временно недоступно</string>
|
||||
<string name="remote_vault_retry_action">Повторить подключение</string>
|
||||
<string name="remote_vault_retrying">Пробую подключиться…</string>
|
||||
<string name="remote_vault_delete_cd">Удалить удалённое хранилище</string>
|
||||
<string name="remote_vault_remove_title">Удалить удалённое хранилище?</string>
|
||||
<string name="remote_vault_remove_message">Удалить «%1$s» с этого устройства? Данные на сервере не удаляются.</string>
|
||||
|
||||
<string name="dialog_cancel">Отмена</string>
|
||||
<string name="dialog_ok">ОК</string>
|
||||
<string name="dialog_encryption_enable_title">Включить шифрование</string>
|
||||
<string name="dialog_password_label">Пароль</string>
|
||||
<string name="dialog_encrypt_paths">Шифровать пути</string>
|
||||
<string name="dialog_apply">Применить</string>
|
||||
<string name="dialog_open_encrypted_title">Открыть зашифрованное хранилище</string>
|
||||
<string name="dialog_remember_password">Запомнить пароль</string>
|
||||
<string name="dialog_open">Открыть</string>
|
||||
<string name="dialog_close">Закрыть</string>
|
||||
<string name="dialog_disable_encryption">Отключить шифрование</string>
|
||||
<string name="dialog_done">Готово</string>
|
||||
|
||||
<string name="vault_type_local_device">Локальное устройство</string>
|
||||
<string name="vault_type_remote">Удалённое: %1$s</string>
|
||||
<string name="vault_type_unknown">Неизвестный тип</string>
|
||||
<string name="vault_title_local">Локальное хранилище</string>
|
||||
<string name="vault_title_unknown">Неизвестное хранилище</string>
|
||||
|
||||
<string name="enc_status_not_encrypted">Не зашифровано</string>
|
||||
<string name="enc_status_encrypted_open">Зашифровано (открыто)</string>
|
||||
<string name="enc_status_encrypted">Зашифровано</string>
|
||||
|
||||
<string name="text_edit_screen_title">Текст</string>
|
||||
<string name="text_edit_screen_placeholder">Содержимое: %1$s</string>
|
||||
|
||||
<string name="nav_label_local_vault">Local vault</string>
|
||||
<string name="nav_cd_local_vault">Local vault</string>
|
||||
<string name="nav_label_remote_vaults">Remote vaults</string>
|
||||
<string name="nav_cd_remote_vaults">Remote vaults</string>
|
||||
<string name="nav_label_main">Home</string>
|
||||
<string name="nav_label_sync">Sync</string>
|
||||
<string name="nav_label_settings">Settings</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="settings_title">Settings</string>
|
||||
<string name="sync_groups_title">Sync groups</string>
|
||||
<string name="sync_progress_section_title">Storage sync</string>
|
||||
<string name="sync_groups_busy_section_title">Saving sync groups</string>
|
||||
<string name="sync_run_now">Run sync now</string>
|
||||
<string name="sync_cd_run_now">Run sync now</string>
|
||||
<string name="sync_refresh">Refresh</string>
|
||||
<string name="sync_add_storage">Add storage to group</string>
|
||||
<string name="sync_remove_group">Remove group</string>
|
||||
<string name="sync_group_empty">No storages in this group</string>
|
||||
<string name="sync_remove_storage">Remove storage from group</string>
|
||||
<string name="sync_picker_back">Back</string>
|
||||
<string name="sync_cd_picker_back">Close storage picker</string>
|
||||
<string name="sync_picker_title">Pick storage for %1$s</string>
|
||||
<string name="sync_picker_add">Add</string>
|
||||
<string name="sync_picker_added">Added</string>
|
||||
<string name="sync_picker_cd_add">Add storage to group</string>
|
||||
<string name="sync_picker_no_storages">No available folders in this vault</string>
|
||||
<string name="sync_picker_expand">Expand</string>
|
||||
<string name="sync_picker_collapse">Collapse</string>
|
||||
<string name="sync_fab_create_group_cd">Create sync group</string>
|
||||
<string name="sync_group_mixed_encryption_warning">Mixed encryption in group: set a single mode</string>
|
||||
<string name="sync_group_incompatible_warning">Incompatible storages in group: %1$d</string>
|
||||
<string name="sync_group_policy_line">Group encryption policy: %1$s</string>
|
||||
<string name="sync_group_policy_unset">Not set (group is empty)</string>
|
||||
<string name="sync_group_policy_plain">Unencrypted only</string>
|
||||
<string name="sync_group_policy_password">Password-encrypted with group password</string>
|
||||
<string name="sync_remove_group_confirm_title">Remove group?</string>
|
||||
<string name="sync_remove_group_confirm_message">Remove sync group "%1$s"?</string>
|
||||
<string name="sync_remove_storage_confirm_title">Remove storage?</string>
|
||||
<string name="sync_remove_storage_confirm_message">Remove storage "%1$s" from the group?</string>
|
||||
<string name="sync_confirm_delete">Delete</string>
|
||||
<string name="sync_cancel">Cancel</string>
|
||||
<string name="sync_msg_group_created">Created group %1$s</string>
|
||||
<string name="sync_msg_group_removed">Group removed</string>
|
||||
<string name="sync_msg_storage_added">Storage added to %1$s</string>
|
||||
<string name="sync_msg_storage_removed">Storage removed from %1$s</string>
|
||||
<string name="sync_msg_storage_already_added">Storage is already in the group</string>
|
||||
<string name="sync_msg_only_plain_storage_allowed">Only unencrypted storages can be added to sync groups</string>
|
||||
<string name="sync_msg_storage_encryption_key_required">Encrypted storage requires the password (open it before adding)</string>
|
||||
<string name="sync_msg_storage_incompatible_encryption">Storage is not compatible with the group encryption policy</string>
|
||||
<string name="sync_msg_virtual_storage_not_supported">Cannot add an open virtual storage: sync works with raw storages</string>
|
||||
<string name="sync_msg_task_enqueued">Sync task queued</string>
|
||||
<string name="sync_msg_sync_already_running">Sync is already running</string>
|
||||
<string name="sync_msg_blocked_during_sync">Wait for sync to finish</string>
|
||||
<string name="sync_encryption_unknown">Unknown</string>
|
||||
<string name="sync_storage_encryption_line">Encryption: %1$s</string>
|
||||
<string name="sync_storage_missing_title">Not found in current vaults</string>
|
||||
<string name="sync_storage_pending_vault_scan">Waiting: vault storage list is still loading</string>
|
||||
<string name="sync_storage_not_in_vaults">Not in storage tree (removed, different account, or init failed)</string>
|
||||
<string name="sync_storage_unreachable">Storage unavailable (vault or network)</string>
|
||||
<string name="no_name"><no name></string>
|
||||
<string name="show_storage_item_menu">Storage menu</string>
|
||||
<string name="storage_row_task_running_cd">Operation in progress for this storage</string>
|
||||
<string name="storage_menu_busy">%1$s (task running)</string>
|
||||
<string name="rename">Rename</string>
|
||||
<string name="remove">Remove</string>
|
||||
<string name="encrypt">Encryption</string>
|
||||
<string name="new_name_title">New name</string>
|
||||
<string name="remove_confirmation_dialog">Remove storage "%1$s"?</string>
|
||||
<string name="storage_lock_actions">Encryption actions</string>
|
||||
<string name="storage_sync_lock_checking">Checking lock…</string>
|
||||
<string name="storage_sync_unlock_action">Clear sync lock</string>
|
||||
<string name="storage_sync_not_locked">Sync is not locked</string>
|
||||
<string name="storage_field_available">Available: %1$s</string>
|
||||
<string name="storage_value_yes">yes</string>
|
||||
<string name="storage_value_no">no</string>
|
||||
<string name="storage_field_files">Files: %1$s</string>
|
||||
<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_menu_unavailable">Unavailable: %1$s</string>
|
||||
<string name="storage_status_not_encrypted">Not encrypted</string>
|
||||
<string name="storage_status_encrypted_open">Encrypted (open)</string>
|
||||
<string name="storage_status_encrypted_closed">Encrypted (locked)</string>
|
||||
<string name="vault_fab_add_storage_cd">Create storage</string>
|
||||
<string name="vault_fab_add_storage_disabled_cd">Create unavailable: vault offline</string>
|
||||
<string name="vault_fab_add_storage_busy_cd">Storage creation already running</string>
|
||||
<string name="vault_msg_storage_pipeline_busy">An operation is already running for this storage</string>
|
||||
<string name="vault_msg_vault_list_mutation_busy">Storage list is changing — please wait</string>
|
||||
<string name="vault_unavailable_banner">Vault unavailable. Check network, path, or unlock.</string>
|
||||
<string name="vault_loading_storages">Loading storage list…</string>
|
||||
<string name="vault_empty_list_hint">No folders yet. Create storage with "+" when available.</string>
|
||||
<string name="task_pipeline_title">Task queue</string>
|
||||
<string name="task_pipeline_jobs">Tasks</string>
|
||||
<string name="task_pipeline_log">Log</string>
|
||||
<string name="task_pipeline_cancel_all">Cancel all</string>
|
||||
<string name="task_pipeline_open">Open task queue</string>
|
||||
<string name="task_pipeline_run_test">Test task</string>
|
||||
<string name="task_pipeline_test_dialog_title">Test task parameters</string>
|
||||
<string name="task_pipeline_test_dialog_duration">Duration: %1$d s</string>
|
||||
<string name="task_pipeline_test_dialog_start">Start</string>
|
||||
<string name="task_pipeline_test_dialog_cancel">Cancel</string>
|
||||
<string name="task_pipeline_test_dialog_infinity">Infinite (indeterminate progress)</string>
|
||||
<string name="task_pipeline_test_running">Test task (%1$d s)</string>
|
||||
<string name="task_pipeline_test_running_infinity">Test task (%1$d s, ∞)</string>
|
||||
<string name="task_state_queued">Queued</string>
|
||||
<string name="task_state_running">Running</string>
|
||||
<string name="task_state_completed">Completed</string>
|
||||
<string name="task_state_cancelled">Cancelled</string>
|
||||
<string name="task_state_failed">Error: %1$s</string>
|
||||
<string name="task_title_dump_storage_log">Export tree to log</string>
|
||||
<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_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>
|
||||
<string name="task_title_remove_storage">Remove storage</string>
|
||||
<string name="task_title_clear_sync_lock">Clear sync lock</string>
|
||||
<string name="task_title_add_remote_vault">Add 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_storage_sync">Storage sync</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_delete_2fa_token">Delete 2FA token</string>
|
||||
<string name="task_title_save_text_secret">Save text secret</string>
|
||||
<string name="task_title_delete_text_secret">Delete text secret</string>
|
||||
<string name="error_storage_not_found">Storage not found</string>
|
||||
<string name="error_storage_locked_view">Open decrypted storage view to use this section</string>
|
||||
<string name="error_secret_not_found">Secret not found</string>
|
||||
<string name="error_storage_not_writable">Storage is not writable</string>
|
||||
<string name="error_file_not_found">File not found</string>
|
||||
<string name="error_incorrect_password">Incorrect password</string>
|
||||
<string name="error_storage_not_encrypted">Storage is not encrypted</string>
|
||||
<string name="error_enc_info_missing">Encryption metadata missing</string>
|
||||
<string name="error_delete_root_forbidden">Cannot delete storage root</string>
|
||||
<string name="error_not_a_file">Expected a file</string>
|
||||
<string name="error_not_a_directory">Expected a folder</string>
|
||||
<string name="error_path_is_file">Path points to a file, not a folder</string>
|
||||
<string name="error_cannot_write_over_directory">Cannot write over a folder</string>
|
||||
<string name="error_unexpected_state">Storage in unexpected state</string>
|
||||
<string name="error_network">Network or server error</string>
|
||||
<string name="error_disk_resource_locked">Resource is temporarily locked. Try again later.</string>
|
||||
<string name="error_unknown">Something went wrong</string>
|
||||
<string name="sync_error_group_not_found">Sync group not found</string>
|
||||
<string name="vault_link_error_auth">Sign-in failed</string>
|
||||
<string name="vault_link_error_not_registered">Sign-in is not ready. Restart the app.</string>
|
||||
<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_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>
|
||||
<string name="msg_unsupported_storage_type">Unsupported storage type</string>
|
||||
<string name="msg_encryption_disabled">Encryption disabled</string>
|
||||
<string name="msg_invalid_storage_for_sync_lock">Invalid storage</string>
|
||||
<string name="msg_sync_lock_cleared">Sync lock cleared</string>
|
||||
<string name="remote_vaults_add_cd">Add remote vault</string>
|
||||
<string name="remote_vaults_empty_hint">No remote vaults yet. Tap "+" to add Yandex.</string>
|
||||
<string name="remote_vaults_add_title">Add vault</string>
|
||||
<string name="remote_vaults_add_pick_provider">Choose a provider:</string>
|
||||
<string name="remote_vaults_provider_yandex">Yandex</string>
|
||||
<string name="remote_vaults_add_cancel">Cancel</string>
|
||||
<string name="remote_vault_type_yandex">Yandex</string>
|
||||
<string name="remote_vault_unavailable">Vault temporarily unavailable</string>
|
||||
<string name="remote_vault_retry_action">Retry connection</string>
|
||||
<string name="remote_vault_retrying">Connecting…</string>
|
||||
<string name="remote_vault_delete_cd">Remove remote vault</string>
|
||||
<string name="remote_vault_remove_title">Remove remote vault?</string>
|
||||
<string name="remote_vault_remove_message">Remove "%1$s" from this device? Server data is not deleted.</string>
|
||||
<string name="dialog_cancel">Cancel</string>
|
||||
<string name="dialog_ok">OK</string>
|
||||
<string name="dialog_encryption_enable_title">Enable encryption</string>
|
||||
<string name="dialog_password_label">Password</string>
|
||||
<string name="dialog_encrypt_paths">Encrypt paths</string>
|
||||
<string name="dialog_apply">Apply</string>
|
||||
<string name="dialog_open_encrypted_title">Open encrypted storage</string>
|
||||
<string name="dialog_remember_password">Remember password</string>
|
||||
<string name="dialog_open">Open</string>
|
||||
<string name="dialog_close">Close</string>
|
||||
<string name="dialog_disable_encryption">Disable encryption</string>
|
||||
<string name="dialog_done">Done</string>
|
||||
<string name="vault_type_local_device">Local device</string>
|
||||
<string name="vault_type_remote">Remote: %1$s</string>
|
||||
<string name="vault_type_unknown">Unknown type</string>
|
||||
<string name="vault_title_local">Local vault</string>
|
||||
<string name="vault_title_unknown">Unknown vault</string>
|
||||
<string name="enc_status_not_encrypted">Not encrypted</string>
|
||||
<string name="enc_status_encrypted_open">Encrypted (open)</string>
|
||||
<string name="enc_status_encrypted">Encrypted</string>
|
||||
<string name="text_edit_screen_title">Text</string>
|
||||
<string name="text_edit_screen_placeholder">Content: %1$s</string>
|
||||
<string name="storage_home_unnamed_storage">Storage</string>
|
||||
<string name="storage_home_status_line">Статус: %1$s, %2$s</string>
|
||||
<string name="storage_home_status_available">доступно</string>
|
||||
<string name="storage_home_status_unavailable">недоступно</string>
|
||||
<string name="storage_home_status_encrypted">зашифровано</string>
|
||||
<string name="storage_home_status_not_encrypted">не зашифровано</string>
|
||||
<string name="storage_home_two_fa_title">2FA токены (%1$d)</string>
|
||||
<string name="storage_home_open_two_fa">Открыть 2FA</string>
|
||||
<string name="storage_home_two_fa_subtitle">Коды и секреты двухфакторной аутентификации</string>
|
||||
<string name="storage_home_text_secrets_title">Текстовые секреты (%1$d)</string>
|
||||
<string name="storage_home_open_text_secrets">Открыть текстовые секреты</string>
|
||||
<string name="storage_home_text_secrets_subtitle">Заметки, токены и произвольные пары ключ-значение</string>
|
||||
<string name="storage_home_future_sections">Скоро здесь появятся Files, Media и другие типы данных.</string>
|
||||
|
||||
<string name="two_fa_add_token">Добавить токен</string>
|
||||
<string name="two_fa_empty_state">Пока нет 2FA токенов</string>
|
||||
<string name="two_fa_create_title">Новый 2FA токен</string>
|
||||
<string name="two_fa_edit_title">Редактирование 2FA токена</string>
|
||||
<string name="two_fa_field_issuer">Сервис</string>
|
||||
<string name="two_fa_field_account">Аккаунт</string>
|
||||
<string name="two_fa_field_secret">Секрет</string>
|
||||
<string name="two_fa_field_notes_optional">Заметка (опционально)</string>
|
||||
<string name="two_fa_field_digits">Количество цифр кода (обычно 6 или 8)</string>
|
||||
<string name="two_fa_field_period_seconds">Период обновления в секундах (обычно 30)</string>
|
||||
<string name="two_fa_field_algorithm">Алгоритм (SHA1, SHA256, SHA512)</string>
|
||||
<string name="two_fa_field_digits_value">Количество цифр: %1$d</string>
|
||||
<string name="two_fa_field_period_seconds_value">Период обновления: %1$d с</string>
|
||||
<string name="storage_home_status_line">Status: %1$s, %2$s</string>
|
||||
<string name="storage_home_status_available">available</string>
|
||||
<string name="storage_home_status_unavailable">unavailable</string>
|
||||
<string name="storage_home_status_encrypted">encrypted</string>
|
||||
<string name="storage_home_status_not_encrypted">not encrypted</string>
|
||||
<string name="storage_home_two_fa_title">2FA tokens (%1$d)</string>
|
||||
<string name="storage_home_open_two_fa">Open 2FA</string>
|
||||
<string name="storage_home_two_fa_subtitle">Two-factor authentication codes and secrets</string>
|
||||
<string name="storage_home_text_secrets_title">Text secrets (%1$d)</string>
|
||||
<string name="storage_home_open_text_secrets">Open text secrets</string>
|
||||
<string name="storage_home_text_secrets_subtitle">Notes, tokens, and arbitrary key-value pairs</string>
|
||||
<string name="storage_home_future_sections">Files, Media, and more will appear here soon.</string>
|
||||
<string name="two_fa_add_token">Add token</string>
|
||||
<string name="two_fa_empty_state">No 2FA tokens yet</string>
|
||||
<string name="two_fa_create_title">New 2FA token</string>
|
||||
<string name="two_fa_edit_title">Edit 2FA token</string>
|
||||
<string name="two_fa_field_issuer">Service</string>
|
||||
<string name="two_fa_field_account">Account</string>
|
||||
<string name="two_fa_field_secret">Secret</string>
|
||||
<string name="two_fa_field_notes_optional">Note (optional)</string>
|
||||
<string name="two_fa_field_digits">Code digits (usually 6 or 8)</string>
|
||||
<string name="two_fa_field_period_seconds">Refresh period in seconds (usually 30)</string>
|
||||
<string name="two_fa_field_algorithm">Algorithm (SHA1, SHA256, SHA512)</string>
|
||||
<string name="two_fa_field_digits_value">Digits: %1$d</string>
|
||||
<string name="two_fa_field_period_seconds_value">Refresh period: %1$d s</string>
|
||||
<string name="two_fa_code_unavailable">------</string>
|
||||
<string name="two_fa_code_refresh_in">Обновление через %1$d с</string>
|
||||
<string name="two_fa_code_refresh_label">Обновление через</string>
|
||||
<string name="two_fa_code_refresh_seconds">%1$d с</string>
|
||||
<string name="two_fa_code_invalid_secret">Неверный секрет или формат</string>
|
||||
<string name="two_fa_copy_code_hint">Нажмите, чтобы скопировать код</string>
|
||||
<string name="two_fa_scan_qr_action">Сканировать QR</string>
|
||||
<string name="two_fa_scan_qr_title">Сканирование QR-кода TOTP</string>
|
||||
<string name="two_fa_scan_qr_invalid">QR-код не содержит валидный otpauth://totp URI</string>
|
||||
<string name="two_fa_camera_permission_required">Нужно разрешение на камеру для сканирования QR</string>
|
||||
|
||||
<string name="text_secret_create">Создать секрет</string>
|
||||
<string name="text_secret_edit">Редактировать секрет</string>
|
||||
<string name="text_secret_title">Название</string>
|
||||
<string name="text_secret_empty_state">Пока нет текстовых секретов</string>
|
||||
<string name="text_secret_items_count">Элементов: %1$d</string>
|
||||
<string name="text_secret_item_without_label">Без названия</string>
|
||||
<string name="text_secret_more_fields">ещё полей: %1$d</string>
|
||||
<string name="text_secret_item_label_optional">Название (опционально)</string>
|
||||
<string name="text_secret_item_value">Значение</string>
|
||||
<string name="text_secret_add_item">Добавить пару</string>
|
||||
<string name="text_secret_copy_value">Скопировать значение</string>
|
||||
|
||||
<string name="save">Сохранить</string>
|
||||
<string name="cancel">Отмена</string>
|
||||
<string name="open">Открыть</string>
|
||||
<string name="edit">Редактировать</string>
|
||||
|
||||
<string name="common_unknown">Неизвестно</string>
|
||||
<string name="two_fa_code_refresh_in">Refresh in %1$d s</string>
|
||||
<string name="two_fa_code_refresh_label">Refresh in</string>
|
||||
<string name="two_fa_code_refresh_seconds">%1$d s</string>
|
||||
<string name="two_fa_code_invalid_secret">Invalid secret or format</string>
|
||||
<string name="two_fa_copy_code_hint">Tap to copy code</string>
|
||||
<string name="two_fa_scan_qr_action">Scan QR</string>
|
||||
<string name="two_fa_scan_qr_title">Scan TOTP QR code</string>
|
||||
<string name="two_fa_scan_qr_invalid">QR code does not contain a valid otpauth://totp URI</string>
|
||||
<string name="two_fa_camera_permission_required">Camera permission is required to scan QR</string>
|
||||
<string name="text_secret_create">Create secret</string>
|
||||
<string name="text_secret_edit">Edit secret</string>
|
||||
<string name="text_secret_title">Title</string>
|
||||
<string name="text_secret_empty_state">No text secrets yet</string>
|
||||
<string name="text_secret_items_count">Items: %1$d</string>
|
||||
<string name="text_secret_item_without_label">Untitled</string>
|
||||
<string name="text_secret_more_fields">more fields: %1$d</string>
|
||||
<string name="text_secret_item_label_optional">Label (optional)</string>
|
||||
<string name="text_secret_item_value">Value</string>
|
||||
<string name="text_secret_add_item">Add field</string>
|
||||
<string name="text_secret_copy_value">Copy value</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="open">Open</string>
|
||||
<string name="edit">Edit</string>
|
||||
<string name="common_unknown">Unknown</string>
|
||||
<string name="settings_language_section">Language</string>
|
||||
<string name="settings_language_system">System default</string>
|
||||
<string name="settings_language_english">English</string>
|
||||
<string name="settings_language_russian">Russian</string>
|
||||
<string name="task_pipeline_test_elapsed">Elapsed: %1$d s / %2$d s</string>
|
||||
<string name="text_secret_clipboard_fallback_label">value</string>
|
||||
<string name="sync_progress_no_groups">Storage sync: no groups configured</string>
|
||||
<string name="sync_progress_preparing">Storage sync: preparing %1$d groups</string>
|
||||
<string name="sync_progress_started">Storage sync: started</string>
|
||||
<string name="sync_progress_completed">Storage sync: completed</string>
|
||||
<string name="sync_progress_group_preparing">Storage sync: group "%1$s" preparing</string>
|
||||
<string name="sync_progress_group_not_found">Storage sync: group "%1$s" not found</string>
|
||||
<string name="sync_progress_group_skipped_few_storages">Storage sync: group "%1$s" skipped (need at least 2 storages)</string>
|
||||
<string name="sync_progress_group_skipped_incompatible">Storage sync: group "%1$s" skipped (incompatible encryption: %2$d)</string>
|
||||
<string name="sync_progress_group_acquiring_locks">Storage sync: group "%1$s" acquiring locks</string>
|
||||
<string name="sync_progress_group_lock">Storage sync: group "%1$s" lock %2$d/%3$d</string>
|
||||
<string name="sync_progress_group_lock_failed">Storage sync: group "%1$s" lock failed, group skipped</string>
|
||||
<string name="sync_progress_group_reading_journals">Storage sync: group "%1$s" reading journals</string>
|
||||
<string name="sync_progress_group_cancelled">Storage sync: group "%1$s" cancelled by newer run</string>
|
||||
<string name="sync_progress_group_journal">Storage sync: group "%1$s" journal %2$d/%3$d</string>
|
||||
<string name="sync_progress_group_no_entries">Storage sync: group "%1$s" no journal entries</string>
|
||||
<string name="sync_progress_group_processing">Storage sync: group "%1$s" processing %2$d entries</string>
|
||||
<string name="sync_progress_group_entry">Storage sync: group "%1$s" entry %2$d/%3$d</string>
|
||||
<string name="sync_progress_group_completed">Storage sync: group "%1$s" completed</string>
|
||||
<string name="sync_progress_group_renewing_locks">Storage sync: group "%1$s" renewing locks</string>
|
||||
<string name="sync_progress_group_lock_renewal_failed">Storage sync: group "%1$s" lock renewal failed</string>
|
||||
<string name="task_progress_clear_content">%1$d / %2$d</string>
|
||||
<string name="task_log_sync_started">Storage sync started</string>
|
||||
<string name="task_log_sync_finished">Storage sync finished</string>
|
||||
<string name="task_log_sync_failed">Storage sync failed: %1$s</string>
|
||||
<string name="task_log_enumerating">Enumerating files and directories…</string>
|
||||
<string name="task_log_enumerate_done">Done: %1$d files, %2$d dirs in %3$d ms (see app log for lines)</string>
|
||||
<string name="task_log_creating_storage">Creating storage…</string>
|
||||
<string name="task_log_storage_created">Storage created</string>
|
||||
<string name="task_log_checking_storage">Checking storage…</string>
|
||||
<string name="task_log_encrypting">Encrypting…</string>
|
||||
<string name="task_log_encryption_enabled">Encryption enabled</string>
|
||||
<string name="task_log_already_encrypted">Storage is already encrypted</string>
|
||||
<string name="task_log_not_empty">Storage is not empty</string>
|
||||
<string name="task_log_empty_unknown">Cannot determine whether storage is empty</string>
|
||||
<string name="task_log_unsupported_type">Unsupported storage type</string>
|
||||
<string name="task_log_enable_encryption_failed">Failed to enable encryption</string>
|
||||
<string name="task_log_opening_storage">Opening encrypted storage…</string>
|
||||
<string name="task_log_storage_opened">Storage opened</string>
|
||||
<string name="task_log_open_storage_failed">Failed to open encrypted storage</string>
|
||||
<string name="task_log_closing_storage">Closing storage…</string>
|
||||
<string name="task_log_storage_closed">Storage closed</string>
|
||||
<string name="task_log_close_storage_failed">Failed to close encrypted storage</string>
|
||||
<string name="task_log_disabling_encryption">Disabling encryption…</string>
|
||||
<string name="task_log_encryption_disabled">Encryption disabled</string>
|
||||
<string name="task_log_disable_encryption_failed">Failed to disable encryption</string>
|
||||
<string name="task_log_renaming">Renaming…</string>
|
||||
<string name="task_log_renamed">Renamed</string>
|
||||
<string name="task_log_rename_failed">Rename failed</string>
|
||||
<string name="task_log_removing_storage">Removing storage…</string>
|
||||
<string name="task_log_removed">Removed</string>
|
||||
<string name="task_log_remove_failed">Remove failed</string>
|
||||
<string name="task_log_invalid_storage">Invalid storage</string>
|
||||
<string name="task_log_clearing_sync_lock">Clearing sync lock…</string>
|
||||
<string name="task_log_sync_lock_cleared">Sync lock cleared</string>
|
||||
<string name="task_log_clear_sync_lock_failed">Failed to clear sync lock</string>
|
||||
<string name="task_log_adding_vault">Adding vault…</string>
|
||||
<string name="task_log_vault_added">Vault added</string>
|
||||
<string name="task_log_add_vault_failed">Failed to add vault</string>
|
||||
<string name="task_log_removing_remote_vault">Removing remote vault…</string>
|
||||
<string name="task_log_remote_vault_removed">Remote vault removed</string>
|
||||
<string name="task_log_remove_vault_failed">Failed to remove vault</string>
|
||||
<string name="task_log_retrying_vault">Retrying remote vault connection…</string>
|
||||
<string name="task_log_retry_requested">Retry requested</string>
|
||||
<string name="task_log_retry_vault_failed">Failed to retry remote vault</string>
|
||||
<string name="task_log_test_started">Test task started for %1$d s</string>
|
||||
<string name="task_log_test_finished">Test task finished</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user