forked from dsutanto/bChot-android
First Commit
This commit is contained in:
45
features/securebackup/impl/build.gradle.kts
Normal file
45
features/securebackup/impl/build.gradle.kts
Normal file
@@ -0,0 +1,45 @@
|
||||
import extension.setupDependencyInjection
|
||||
import extension.testCommonDependencies
|
||||
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023, 2024 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("io.element.android-compose-library")
|
||||
id("kotlin-parcelize")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.features.securebackup.impl"
|
||||
|
||||
testOptions {
|
||||
unitTests {
|
||||
isIncludeAndroidResources = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupDependencyInjection()
|
||||
|
||||
dependencies {
|
||||
implementation(projects.appconfig)
|
||||
implementation(projects.libraries.core)
|
||||
implementation(projects.libraries.androidutils)
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.libraries.matrix.api)
|
||||
implementation(projects.libraries.matrixui)
|
||||
implementation(projects.libraries.designsystem)
|
||||
implementation(projects.libraries.oidc.api)
|
||||
implementation(projects.libraries.uiStrings)
|
||||
implementation(projects.libraries.testtags)
|
||||
api(libs.statemachine)
|
||||
api(projects.features.securebackup.api)
|
||||
|
||||
testCommonDependencies(libs, true)
|
||||
testImplementation(projects.libraries.matrix.test)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl
|
||||
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.ContributesBinding
|
||||
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultSecureBackupEntryPoint : SecureBackupEntryPoint {
|
||||
override fun createNode(
|
||||
parentNode: Node,
|
||||
buildContext: BuildContext,
|
||||
params: SecureBackupEntryPoint.Params,
|
||||
callback: SecureBackupEntryPoint.Callback,
|
||||
): Node {
|
||||
return parentNode.createNode<SecureBackupFlowNode>(
|
||||
buildContext = buildContext,
|
||||
plugins = listOf(params, callback)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl
|
||||
|
||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
|
||||
private val loggerTag = LoggerTag("SecureBackup")
|
||||
val loggerTagRoot = LoggerTag("Root", loggerTag)
|
||||
val loggerTagSetup = LoggerTag("Setup", loggerTag)
|
||||
val loggerTagDisable = LoggerTag("Disable", loggerTag)
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import com.bumble.appyx.navmodel.backstack.BackStack
|
||||
import com.bumble.appyx.navmodel.backstack.operation.pop
|
||||
import com.bumble.appyx.navmodel.backstack.operation.push
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
|
||||
import io.element.android.features.securebackup.impl.disable.SecureBackupDisableNode
|
||||
import io.element.android.features.securebackup.impl.enter.SecureBackupEnterRecoveryKeyNode
|
||||
import io.element.android.features.securebackup.impl.reset.ResetIdentityFlowNode
|
||||
import io.element.android.features.securebackup.impl.root.SecureBackupRootNode
|
||||
import io.element.android.features.securebackup.impl.setup.SecureBackupSetupNode
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
import io.element.android.libraries.architecture.BaseFlowNode
|
||||
import io.element.android.libraries.architecture.appyx.canPop
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
@AssistedInject
|
||||
class SecureBackupFlowNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
) : BaseFlowNode<SecureBackupFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
initialElement = when (plugins.filterIsInstance<SecureBackupEntryPoint.Params>().first().initialElement) {
|
||||
SecureBackupEntryPoint.InitialTarget.Root -> NavTarget.Root
|
||||
SecureBackupEntryPoint.InitialTarget.SetUpRecovery -> NavTarget.Setup
|
||||
SecureBackupEntryPoint.InitialTarget.EnterRecoveryKey -> NavTarget.EnterRecoveryKey
|
||||
is SecureBackupEntryPoint.InitialTarget.ResetIdentity -> NavTarget.ResetIdentity
|
||||
},
|
||||
savedStateMap = buildContext.savedStateMap,
|
||||
),
|
||||
buildContext = buildContext,
|
||||
plugins = plugins
|
||||
) {
|
||||
sealed interface NavTarget : Parcelable {
|
||||
@Parcelize
|
||||
data object Root : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object Setup : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object Change : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object Disable : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object EnterRecoveryKey : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object ResetIdentity : NavTarget
|
||||
}
|
||||
|
||||
private val callback: SecureBackupEntryPoint.Callback = callback()
|
||||
|
||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||
return when (navTarget) {
|
||||
NavTarget.Root -> {
|
||||
val callback = object : SecureBackupRootNode.Callback {
|
||||
override fun navigateToSetup() {
|
||||
backstack.push(NavTarget.Setup)
|
||||
}
|
||||
|
||||
override fun navigateToChange() {
|
||||
backstack.push(NavTarget.Change)
|
||||
}
|
||||
|
||||
override fun navigateToDisable() {
|
||||
backstack.push(NavTarget.Disable)
|
||||
}
|
||||
|
||||
override fun navigateToEnterRecoveryKey() {
|
||||
backstack.push(NavTarget.EnterRecoveryKey)
|
||||
}
|
||||
}
|
||||
createNode<SecureBackupRootNode>(buildContext, listOf(callback))
|
||||
}
|
||||
NavTarget.Setup -> {
|
||||
val inputs = SecureBackupSetupNode.Inputs(
|
||||
isChangeRecoveryKeyUserStory = false,
|
||||
)
|
||||
createNode<SecureBackupSetupNode>(buildContext, listOf(inputs))
|
||||
}
|
||||
NavTarget.Change -> {
|
||||
val inputs = SecureBackupSetupNode.Inputs(
|
||||
isChangeRecoveryKeyUserStory = true,
|
||||
)
|
||||
createNode<SecureBackupSetupNode>(buildContext, listOf(inputs))
|
||||
}
|
||||
NavTarget.Disable -> {
|
||||
createNode<SecureBackupDisableNode>(buildContext)
|
||||
}
|
||||
NavTarget.EnterRecoveryKey -> {
|
||||
val callback = object : SecureBackupEnterRecoveryKeyNode.Callback {
|
||||
override fun onEnterRecoveryKeySuccess() {
|
||||
if (backstack.canPop()) {
|
||||
backstack.pop()
|
||||
} else {
|
||||
callback.onDone()
|
||||
}
|
||||
}
|
||||
}
|
||||
createNode<SecureBackupEnterRecoveryKeyNode>(buildContext, plugins = listOf(callback))
|
||||
}
|
||||
is NavTarget.ResetIdentity -> {
|
||||
val callback = object : ResetIdentityFlowNode.Callback {
|
||||
override fun onDone() {
|
||||
callback.onDone()
|
||||
}
|
||||
}
|
||||
createNode<ResetIdentityFlowNode>(buildContext, listOf(callback))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
BackstackView()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.disable
|
||||
|
||||
sealed interface SecureBackupDisableEvents {
|
||||
data object DisableBackup : SecureBackupDisableEvents
|
||||
data object DismissDialogs : SecureBackupDisableEvents
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.disable
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
@AssistedInject
|
||||
class SecureBackupDisableNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val presenter: SecureBackupDisablePresenter,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = presenter.present()
|
||||
SecureBackupDisableView(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
onSuccess = ::navigateUp,
|
||||
onBackClick = ::navigateUp,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.disable
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.features.securebackup.impl.loggerTagDisable
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
@Inject
|
||||
class SecureBackupDisablePresenter(
|
||||
private val encryptionService: EncryptionService,
|
||||
private val buildMeta: BuildMeta,
|
||||
) : Presenter<SecureBackupDisableState> {
|
||||
@Composable
|
||||
override fun present(): SecureBackupDisableState {
|
||||
val backupState by encryptionService.backupStateStateFlow.collectAsState()
|
||||
Timber.tag(loggerTagDisable.value).d("backupState: $backupState")
|
||||
val disableAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
fun handleEvent(event: SecureBackupDisableEvents) {
|
||||
when (event) {
|
||||
is SecureBackupDisableEvents.DisableBackup -> coroutineScope.disableBackup(disableAction)
|
||||
SecureBackupDisableEvents.DismissDialogs -> {
|
||||
disableAction.value = AsyncAction.Uninitialized
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SecureBackupDisableState(
|
||||
backupState = backupState,
|
||||
disableAction = disableAction.value,
|
||||
appName = buildMeta.applicationName,
|
||||
eventSink = ::handleEvent,
|
||||
)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.disableBackup(disableAction: MutableState<AsyncAction<Unit>>) = launch {
|
||||
suspend {
|
||||
Timber.tag(loggerTagDisable.value).d("Calling encryptionService.disableRecovery()")
|
||||
encryptionService.disableRecovery().getOrThrow()
|
||||
}.runCatchingUpdatingState(disableAction)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.disable
|
||||
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
|
||||
data class SecureBackupDisableState(
|
||||
val backupState: BackupState,
|
||||
val disableAction: AsyncAction<Unit>,
|
||||
val appName: String,
|
||||
val eventSink: (SecureBackupDisableEvents) -> Unit
|
||||
)
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.disable
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
|
||||
open class SecureBackupDisableStateProvider : PreviewParameterProvider<SecureBackupDisableState> {
|
||||
override val values: Sequence<SecureBackupDisableState>
|
||||
get() = sequenceOf(
|
||||
aSecureBackupDisableState(),
|
||||
aSecureBackupDisableState(disableAction = AsyncAction.ConfirmingNoParams),
|
||||
aSecureBackupDisableState(disableAction = AsyncAction.Loading),
|
||||
aSecureBackupDisableState(disableAction = AsyncAction.Failure(Exception("Failed to disable"))),
|
||||
// Add other states here
|
||||
)
|
||||
}
|
||||
|
||||
fun aSecureBackupDisableState(
|
||||
backupState: BackupState = BackupState.UNKNOWN,
|
||||
disableAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
||||
) = SecureBackupDisableState(
|
||||
backupState = backupState,
|
||||
disableAction = disableAction,
|
||||
appName = "Element",
|
||||
eventSink = {}
|
||||
)
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.disable
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
|
||||
import io.element.android.libraries.designsystem.components.BigIcon
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
||||
@Composable
|
||||
fun SecureBackupDisableView(
|
||||
state: SecureBackupDisableState,
|
||||
onSuccess: () -> Unit,
|
||||
onBackClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
FlowStepPage(
|
||||
modifier = modifier,
|
||||
onBackClick = onBackClick,
|
||||
title = stringResource(id = R.string.screen_key_backup_disable_title),
|
||||
subTitle = stringResource(id = R.string.screen_key_backup_disable_description),
|
||||
iconStyle = BigIcon.Style.AlertSolid,
|
||||
buttons = { Buttons(state = state) },
|
||||
) {
|
||||
Content(state = state)
|
||||
}
|
||||
|
||||
AsyncActionView(
|
||||
async = state.disableAction,
|
||||
progressDialog = {},
|
||||
errorMessage = { it.message ?: it.toString() },
|
||||
onErrorDismiss = { state.eventSink.invoke(SecureBackupDisableEvents.DismissDialogs) },
|
||||
onSuccess = { onSuccess() },
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.Buttons(
|
||||
state: SecureBackupDisableState,
|
||||
) {
|
||||
Button(
|
||||
text = stringResource(id = R.string.screen_chat_backup_key_backup_action_disable),
|
||||
showProgress = state.disableAction.isLoading(),
|
||||
destructive = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = { state.eventSink.invoke(SecureBackupDisableEvents.DisableBackup) }
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Content(state: SecureBackupDisableState) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 18.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
SecureBackupDisableItem(stringResource(id = R.string.screen_key_backup_disable_description_point_1))
|
||||
SecureBackupDisableItem(stringResource(id = R.string.screen_key_backup_disable_description_point_2, state.appName))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SecureBackupDisableItem(text: String) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(color = ElementTheme.colors.bgActionSecondaryHovered)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Close(),
|
||||
contentDescription = null,
|
||||
tint = ElementTheme.colors.iconCriticalPrimary,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
Text(
|
||||
text = text,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun SecureBackupDisableViewPreview(
|
||||
@PreviewParameter(SecureBackupDisableStateProvider::class) state: SecureBackupDisableState
|
||||
) = ElementPreview {
|
||||
SecureBackupDisableView(
|
||||
state = state,
|
||||
onSuccess = {},
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.enter
|
||||
|
||||
sealed interface SecureBackupEnterRecoveryKeyEvents {
|
||||
data class OnRecoveryKeyChange(val recoveryKey: String) : SecureBackupEnterRecoveryKeyEvents
|
||||
data class ChangeRecoveryKeyFieldContentsVisibility(val visible: Boolean) : SecureBackupEnterRecoveryKeyEvents
|
||||
data object Submit : SecureBackupEnterRecoveryKeyEvents
|
||||
data object ClearDialog : SecureBackupEnterRecoveryKeyEvents
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.enter
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
@AssistedInject
|
||||
class SecureBackupEnterRecoveryKeyNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val presenter: SecureBackupEnterRecoveryKeyPresenter,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
interface Callback : Plugin {
|
||||
fun onEnterRecoveryKeySuccess()
|
||||
}
|
||||
|
||||
private val callback: Callback = callback()
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = presenter.present()
|
||||
SecureBackupEnterRecoveryKeyView(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
onSuccess = callback::onEnterRecoveryKeySuccess,
|
||||
onBackClick = ::navigateUp,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.enter
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
|
||||
import io.element.android.features.securebackup.impl.tools.RecoveryKeyTools
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Inject
|
||||
class SecureBackupEnterRecoveryKeyPresenter(
|
||||
private val encryptionService: EncryptionService,
|
||||
private val recoveryKeyTools: RecoveryKeyTools,
|
||||
) : Presenter<SecureBackupEnterRecoveryKeyState> {
|
||||
@Composable
|
||||
override fun present(): SecureBackupEnterRecoveryKeyState {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var displayRecoveryKeyFieldContents by rememberSaveable {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
var recoveryKey by rememberSaveable {
|
||||
mutableStateOf("")
|
||||
}
|
||||
val submitAction: MutableState<AsyncAction<Unit>> = remember {
|
||||
mutableStateOf(AsyncAction.Uninitialized)
|
||||
}
|
||||
|
||||
fun handleEvent(event: SecureBackupEnterRecoveryKeyEvents) {
|
||||
when (event) {
|
||||
SecureBackupEnterRecoveryKeyEvents.ClearDialog -> {
|
||||
submitAction.value = AsyncAction.Uninitialized
|
||||
}
|
||||
is SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange -> {
|
||||
val previousRecoveryKey = recoveryKey
|
||||
recoveryKey = if (previousRecoveryKey.isEmpty() && recoveryKeyTools.isRecoveryKeyFormatValid(event.recoveryKey)) {
|
||||
// A Recovery key has been entered, remove the spaces for a better rendering
|
||||
event.recoveryKey.replace("\\s+".toRegex(), "")
|
||||
} else {
|
||||
// Keep the recovery key as entered by the user. May contains spaces.
|
||||
event.recoveryKey
|
||||
}
|
||||
}
|
||||
SecureBackupEnterRecoveryKeyEvents.Submit -> {
|
||||
// No need to remove the spaces, the SDK will do it.
|
||||
coroutineScope.submitRecoveryKey(recoveryKey, submitAction)
|
||||
}
|
||||
is SecureBackupEnterRecoveryKeyEvents.ChangeRecoveryKeyFieldContentsVisibility -> {
|
||||
displayRecoveryKeyFieldContents = event.visible
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SecureBackupEnterRecoveryKeyState(
|
||||
recoveryKeyViewState = RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Enter,
|
||||
formattedRecoveryKey = recoveryKey,
|
||||
displayTextFieldContents = displayRecoveryKeyFieldContents,
|
||||
inProgress = submitAction.value.isLoading(),
|
||||
),
|
||||
isSubmitEnabled = recoveryKey.isNotEmpty() && submitAction.value.isUninitialized(),
|
||||
submitAction = submitAction.value,
|
||||
eventSink = ::handleEvent,
|
||||
)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.submitRecoveryKey(
|
||||
recoveryKey: String,
|
||||
action: MutableState<AsyncAction<Unit>>
|
||||
) = launch {
|
||||
suspend {
|
||||
encryptionService.recover(recoveryKey).getOrThrow()
|
||||
}.runCatchingUpdatingState(action)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.enter
|
||||
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
||||
data class SecureBackupEnterRecoveryKeyState(
|
||||
val recoveryKeyViewState: RecoveryKeyViewState,
|
||||
val isSubmitEnabled: Boolean,
|
||||
val submitAction: AsyncAction<Unit>,
|
||||
val eventSink: (SecureBackupEnterRecoveryKeyEvents) -> Unit
|
||||
)
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.enter
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
|
||||
import io.element.android.features.securebackup.impl.setup.views.aFormattedRecoveryKey
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
||||
open class SecureBackupEnterRecoveryKeyStateProvider : PreviewParameterProvider<SecureBackupEnterRecoveryKeyState> {
|
||||
override val values: Sequence<SecureBackupEnterRecoveryKeyState>
|
||||
get() = sequenceOf(
|
||||
aSecureBackupEnterRecoveryKeyState(recoveryKey = ""),
|
||||
aSecureBackupEnterRecoveryKeyState(),
|
||||
aSecureBackupEnterRecoveryKeyState(submitAction = AsyncAction.Loading),
|
||||
aSecureBackupEnterRecoveryKeyState(submitAction = AsyncAction.Failure(Exception("A Failure"))),
|
||||
aSecureBackupEnterRecoveryKeyState(displayTextFieldContents = false),
|
||||
)
|
||||
}
|
||||
|
||||
fun aSecureBackupEnterRecoveryKeyState(
|
||||
recoveryKey: String = aFormattedRecoveryKey(),
|
||||
isSubmitEnabled: Boolean = recoveryKey.isNotEmpty(),
|
||||
displayTextFieldContents: Boolean = true,
|
||||
submitAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
||||
eventSink: (SecureBackupEnterRecoveryKeyEvents) -> Unit = {},
|
||||
) = SecureBackupEnterRecoveryKeyState(
|
||||
recoveryKeyViewState = RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Enter,
|
||||
formattedRecoveryKey = recoveryKey,
|
||||
displayTextFieldContents = displayTextFieldContents,
|
||||
inProgress = submitAction.isLoading(),
|
||||
),
|
||||
isSubmitEnabled = isSubmitEnabled,
|
||||
submitAction = submitAction,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.enter
|
||||
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.isImeVisible
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
||||
import androidx.compose.foundation.relocation.bringIntoViewRequester
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyView
|
||||
import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
|
||||
import io.element.android.libraries.designsystem.components.BigIcon
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@Composable
|
||||
fun SecureBackupEnterRecoveryKeyView(
|
||||
state: SecureBackupEnterRecoveryKeyState,
|
||||
onSuccess: () -> Unit,
|
||||
onBackClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
AsyncActionView(
|
||||
async = state.submitAction,
|
||||
onSuccess = { onSuccess() },
|
||||
progressDialog = { },
|
||||
errorTitle = { stringResource(id = R.string.screen_recovery_key_confirm_error_title) },
|
||||
errorMessage = { stringResource(id = R.string.screen_recovery_key_confirm_error_content) },
|
||||
onErrorDismiss = { state.eventSink(SecureBackupEnterRecoveryKeyEvents.ClearDialog) },
|
||||
)
|
||||
|
||||
FlowStepPage(
|
||||
modifier = modifier,
|
||||
isScrollable = true,
|
||||
onBackClick = onBackClick,
|
||||
iconStyle = BigIcon.Style.Default(CompoundIcons.KeySolid()),
|
||||
title = stringResource(id = R.string.screen_recovery_key_confirm_title),
|
||||
subTitle = stringResource(id = R.string.screen_recovery_key_confirm_description),
|
||||
buttons = { Buttons(state = state) }
|
||||
) {
|
||||
Content(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
private fun Content(
|
||||
state: SecureBackupEnterRecoveryKeyState,
|
||||
) {
|
||||
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
||||
var isFocused by remember { mutableStateOf(false) }
|
||||
val isImeVisible = WindowInsets.isImeVisible
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
LaunchedEffect(isImeVisible, isFocused) {
|
||||
// When the keyboard is shown, we want to scroll the text field into view
|
||||
if (isImeVisible && isFocused) {
|
||||
coroutineScope.launch {
|
||||
// Delay to ensure the keyboard is fully shown
|
||||
delay(100.milliseconds)
|
||||
bringIntoViewRequester.bringIntoView()
|
||||
}
|
||||
}
|
||||
}
|
||||
RecoveryKeyView(
|
||||
modifier = Modifier
|
||||
.onFocusChanged { isFocused = it.isFocused }
|
||||
.bringIntoViewRequester(bringIntoViewRequester)
|
||||
.padding(top = 52.dp, bottom = 32.dp),
|
||||
state = state.recoveryKeyViewState,
|
||||
onClick = null,
|
||||
onChange = {
|
||||
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange(it))
|
||||
},
|
||||
onSubmit = {
|
||||
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
},
|
||||
toggleRecoveryKeyVisibility = {
|
||||
state.eventSink(SecureBackupEnterRecoveryKeyEvents.ChangeRecoveryKeyFieldContentsVisibility(it))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.Buttons(
|
||||
state: SecureBackupEnterRecoveryKeyState,
|
||||
) {
|
||||
Button(
|
||||
text = stringResource(id = CommonStrings.action_continue),
|
||||
enabled = state.isSubmitEnabled,
|
||||
showProgress = state.submitAction.isLoading(),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = {
|
||||
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun SecureBackupEnterRecoveryKeyViewPreview(
|
||||
@PreviewParameter(SecureBackupEnterRecoveryKeyStateProvider::class) state: SecureBackupEnterRecoveryKeyState
|
||||
) = ElementPreview {
|
||||
SecureBackupEnterRecoveryKeyView(
|
||||
state = state,
|
||||
onSuccess = {},
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset
|
||||
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.di.annotations.SessionCoroutineScope
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.filterIsInstance
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Inject
|
||||
class ResetIdentityFlowManager(
|
||||
private val encryptionService: EncryptionService,
|
||||
@SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope,
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
) {
|
||||
private val resetHandleFlow: MutableStateFlow<AsyncData<IdentityResetHandle?>> = MutableStateFlow(AsyncData.Uninitialized)
|
||||
val currentHandleFlow: StateFlow<AsyncData<IdentityResetHandle?>> = resetHandleFlow
|
||||
private var whenResetIsDoneWaitingJob: Job? = null
|
||||
|
||||
fun whenResetIsDone(block: () -> Unit) {
|
||||
whenResetIsDoneWaitingJob = sessionCoroutineScope.launch {
|
||||
sessionVerificationService.sessionVerifiedStatus.filterIsInstance<SessionVerifiedStatus.Verified>().first()
|
||||
block()
|
||||
}
|
||||
}
|
||||
|
||||
fun getResetHandle(): StateFlow<AsyncData<IdentityResetHandle?>> {
|
||||
return if (resetHandleFlow.value.isLoading() || resetHandleFlow.value.isSuccess()) {
|
||||
resetHandleFlow
|
||||
} else {
|
||||
resetHandleFlow.value = AsyncData.Loading()
|
||||
|
||||
sessionCoroutineScope.launch {
|
||||
encryptionService.startIdentityReset()
|
||||
.onSuccess { handle ->
|
||||
resetHandleFlow.value = AsyncData.Success(handle)
|
||||
}
|
||||
.onFailure {
|
||||
resetHandleFlow.value = AsyncData.Failure(it)
|
||||
}
|
||||
}
|
||||
|
||||
resetHandleFlow
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun cancel() {
|
||||
currentHandleFlow.value.dataOrNull()?.cancel()
|
||||
resetHandleFlow.value = AsyncData.Uninitialized
|
||||
|
||||
whenResetIsDoneWaitingJob?.cancel()
|
||||
whenResetIsDoneWaitingJob = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Parcelable
|
||||
import androidx.activity.compose.LocalActivity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import com.bumble.appyx.navmodel.backstack.BackStack
|
||||
import com.bumble.appyx.navmodel.backstack.operation.push
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.features.securebackup.impl.reset.password.ResetIdentityPasswordNode
|
||||
import io.element.android.features.securebackup.impl.reset.root.ResetIdentityRootNode
|
||||
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
import io.element.android.libraries.architecture.BaseFlowNode
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
import io.element.android.libraries.designsystem.components.ProgressDialog
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
import io.element.android.libraries.di.annotations.SessionCoroutineScope
|
||||
import io.element.android.libraries.matrix.api.encryption.IdentityOidcResetHandle
|
||||
import io.element.android.libraries.matrix.api.encryption.IdentityPasswordResetHandle
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import timber.log.Timber
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
@AssistedInject
|
||||
class ResetIdentityFlowNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val resetIdentityFlowManager: ResetIdentityFlowManager,
|
||||
@SessionCoroutineScope
|
||||
private val sessionCoroutineScope: CoroutineScope,
|
||||
) : BaseFlowNode<ResetIdentityFlowNode.NavTarget>(
|
||||
backstack = BackStack(initialElement = NavTarget.Root, savedStateMap = buildContext.savedStateMap),
|
||||
buildContext = buildContext,
|
||||
plugins = plugins,
|
||||
) {
|
||||
interface Callback : Plugin {
|
||||
fun onDone()
|
||||
}
|
||||
|
||||
private val callback: Callback = callback()
|
||||
|
||||
sealed interface NavTarget : Parcelable {
|
||||
@Parcelize
|
||||
data object Root : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data object ResetPassword : NavTarget
|
||||
}
|
||||
|
||||
private lateinit var activity: Activity
|
||||
private var darkTheme: Boolean = false
|
||||
private var resetJob: Job? = null
|
||||
|
||||
override fun onBuilt() {
|
||||
super.onBuilt()
|
||||
|
||||
lifecycle.addObserver(object : DefaultLifecycleObserver {
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
// If the custom tab / Web browser was opened, we need to cancel the reset job
|
||||
// when we come back to the node if the reset wasn't successful
|
||||
sessionCoroutineScope.launch {
|
||||
cancelResetJob()
|
||||
|
||||
resetIdentityFlowManager.whenResetIsDone {
|
||||
callback.onDone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
// Make sure we cancel the reset job when the node is destroyed, just in case
|
||||
sessionCoroutineScope.launch { cancelResetJob() }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||
return when (navTarget) {
|
||||
is NavTarget.Root -> {
|
||||
val callback = object : ResetIdentityRootNode.Callback {
|
||||
override fun onContinue() {
|
||||
sessionCoroutineScope.startReset()
|
||||
}
|
||||
}
|
||||
createNode<ResetIdentityRootNode>(buildContext, listOf(callback))
|
||||
}
|
||||
is NavTarget.ResetPassword -> {
|
||||
val handle = resetIdentityFlowManager.currentHandleFlow.value.dataOrNull() as? IdentityPasswordResetHandle ?: error("No password handle found")
|
||||
createNode<ResetIdentityPasswordNode>(
|
||||
buildContext,
|
||||
listOf(ResetIdentityPasswordNode.Inputs(handle))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.startReset() = launch {
|
||||
resetIdentityFlowManager.getResetHandle()
|
||||
.collectLatest { state ->
|
||||
when (state) {
|
||||
is AsyncData.Failure -> {
|
||||
cancelResetJob()
|
||||
Timber.e(state.error, "Could not load the reset identity handle.")
|
||||
}
|
||||
is AsyncData.Success -> {
|
||||
when (val handle = state.data) {
|
||||
null -> {
|
||||
Timber.d("No reset handle return, the reset is done.")
|
||||
}
|
||||
is IdentityOidcResetHandle -> {
|
||||
activity.openUrlInChromeCustomTab(null, darkTheme, handle.url)
|
||||
resetJob = launch { handle.resetOidc() }
|
||||
}
|
||||
is IdentityPasswordResetHandle -> backstack.push(NavTarget.ResetPassword)
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun cancelResetJob() {
|
||||
resetJob?.cancel()
|
||||
resetJob = null
|
||||
resetIdentityFlowManager.cancel()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
// Workaround to get the current activity
|
||||
if (!this::activity.isInitialized) {
|
||||
activity = requireNotNull(LocalActivity.current)
|
||||
}
|
||||
darkTheme = !ElementTheme.isLightTheme
|
||||
val startResetState by resetIdentityFlowManager.currentHandleFlow.collectAsState()
|
||||
if (startResetState.isLoading()) {
|
||||
ProgressDialog(
|
||||
properties = DialogProperties(dismissOnBackPress = true, dismissOnClickOutside = true),
|
||||
onDismissRequest = { sessionCoroutineScope.launch { cancelResetJob() } }
|
||||
)
|
||||
}
|
||||
|
||||
BackstackView(modifier)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.password
|
||||
|
||||
sealed interface ResetIdentityPasswordEvent {
|
||||
data class Reset(val password: String) : ResetIdentityPasswordEvent
|
||||
data object DismissError : ResetIdentityPasswordEvent
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.password
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.libraries.architecture.NodeInputs
|
||||
import io.element.android.libraries.architecture.inputs
|
||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
import io.element.android.libraries.matrix.api.encryption.IdentityPasswordResetHandle
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
@AssistedInject
|
||||
class ResetIdentityPasswordNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
coroutineDispatchers: CoroutineDispatchers,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
data class Inputs(val handle: IdentityPasswordResetHandle) : NodeInputs
|
||||
|
||||
private val presenter = ResetIdentityPasswordPresenter(
|
||||
identityPasswordResetHandle = inputs<Inputs>().handle,
|
||||
dispatchers = coroutineDispatchers
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = presenter.present()
|
||||
ResetIdentityPasswordView(
|
||||
state = state,
|
||||
onBack = ::navigateUp
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.password
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.matrix.api.encryption.IdentityPasswordResetHandle
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ResetIdentityPasswordPresenter(
|
||||
private val identityPasswordResetHandle: IdentityPasswordResetHandle,
|
||||
private val dispatchers: CoroutineDispatchers,
|
||||
) : Presenter<ResetIdentityPasswordState> {
|
||||
@Composable
|
||||
override fun present(): ResetIdentityPasswordState {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
val resetAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) }
|
||||
|
||||
fun handleEvent(event: ResetIdentityPasswordEvent) {
|
||||
when (event) {
|
||||
is ResetIdentityPasswordEvent.Reset -> coroutineScope.reset(event.password, resetAction)
|
||||
ResetIdentityPasswordEvent.DismissError -> resetAction.value = AsyncAction.Uninitialized
|
||||
}
|
||||
}
|
||||
|
||||
return ResetIdentityPasswordState(
|
||||
resetAction = resetAction.value,
|
||||
eventSink = ::handleEvent,
|
||||
)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.reset(password: String, action: MutableState<AsyncAction<Unit>>) = launch(dispatchers.io) {
|
||||
suspend {
|
||||
identityPasswordResetHandle.resetPassword(password).getOrThrow()
|
||||
}.runCatchingUpdatingState(action)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.password
|
||||
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
||||
data class ResetIdentityPasswordState(
|
||||
val resetAction: AsyncAction<Unit>,
|
||||
val eventSink: (ResetIdentityPasswordEvent) -> Unit,
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.password
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
|
||||
class ResetIdentityPasswordStateProvider : PreviewParameterProvider<ResetIdentityPasswordState> {
|
||||
override val values: Sequence<ResetIdentityPasswordState>
|
||||
get() = sequenceOf(
|
||||
aResetIdentityPasswordState(),
|
||||
aResetIdentityPasswordState(resetAction = AsyncAction.Loading),
|
||||
aResetIdentityPasswordState(resetAction = AsyncAction.Success(Unit)),
|
||||
aResetIdentityPasswordState(resetAction = AsyncAction.Failure(IllegalStateException("Failed"))),
|
||||
)
|
||||
}
|
||||
|
||||
private fun aResetIdentityPasswordState(
|
||||
resetAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
||||
eventSink: (ResetIdentityPasswordEvent) -> Unit = {},
|
||||
) = ResetIdentityPasswordState(
|
||||
resetAction = resetAction,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.password
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
|
||||
import io.element.android.libraries.designsystem.components.BigIcon
|
||||
import io.element.android.libraries.designsystem.components.ProgressDialog
|
||||
import io.element.android.libraries.designsystem.components.form.textFieldState
|
||||
import io.element.android.libraries.designsystem.modifiers.onTabOrEnterKeyFocusNext
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.TextField
|
||||
import io.element.android.libraries.designsystem.theme.components.TextFieldValidity
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
fun ResetIdentityPasswordView(
|
||||
state: ResetIdentityPasswordState,
|
||||
onBack: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val passwordState = textFieldState(stateValue = "")
|
||||
FlowStepPage(
|
||||
modifier = modifier,
|
||||
iconStyle = BigIcon.Style.Default(CompoundIcons.LockSolid()),
|
||||
title = stringResource(R.string.screen_reset_encryption_password_title),
|
||||
subTitle = stringResource(R.string.screen_reset_encryption_password_subtitle),
|
||||
onBackClick = onBack,
|
||||
content = {
|
||||
Content(
|
||||
text = passwordState.value,
|
||||
onTextChange = { newText ->
|
||||
if (state.resetAction.isFailure()) {
|
||||
state.eventSink(ResetIdentityPasswordEvent.DismissError)
|
||||
}
|
||||
passwordState.value = newText
|
||||
},
|
||||
hasError = state.resetAction.isFailure(),
|
||||
)
|
||||
},
|
||||
buttons = {
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(CommonStrings.action_reset_identity),
|
||||
onClick = { state.eventSink(ResetIdentityPasswordEvent.Reset(passwordState.value)) },
|
||||
destructive = true,
|
||||
enabled = passwordState.value.isNotEmpty(),
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
// On success we need to wait until the screen is automatically dismissed, so we keep the progress dialog
|
||||
if (state.resetAction.isLoading() || state.resetAction.isSuccess()) {
|
||||
ProgressDialog()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Content(text: String, onTextChange: (String) -> Unit, hasError: Boolean) {
|
||||
var showPassword by remember { mutableStateOf(false) }
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.onTabOrEnterKeyFocusNext(LocalFocusManager.current),
|
||||
value = text,
|
||||
onValueChange = onTextChange,
|
||||
placeholder = stringResource(CommonStrings.common_password),
|
||||
singleLine = true,
|
||||
visualTransformation = if (showPassword) VisualTransformation.None else PasswordVisualTransformation(),
|
||||
trailingIcon = {
|
||||
val image =
|
||||
if (showPassword) CompoundIcons.VisibilityOn() else CompoundIcons.VisibilityOff()
|
||||
val description =
|
||||
if (showPassword) stringResource(CommonStrings.a11y_hide_password) else stringResource(CommonStrings.a11y_show_password)
|
||||
|
||||
Box(Modifier.clickable { showPassword = !showPassword }) {
|
||||
Icon(imageVector = image, description)
|
||||
}
|
||||
},
|
||||
validity = if (hasError) TextFieldValidity.Invalid else TextFieldValidity.None,
|
||||
supportingText = if (hasError) {
|
||||
stringResource(R.string.screen_reset_encryption_password_error)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun ResetIdentityPasswordViewPreview(@PreviewParameter(ResetIdentityPasswordStateProvider::class) state: ResetIdentityPasswordState) {
|
||||
ElementPreview {
|
||||
ResetIdentityPasswordView(
|
||||
state = state,
|
||||
onBack = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.root
|
||||
|
||||
sealed interface ResetIdentityRootEvent {
|
||||
data object Continue : ResetIdentityRootEvent
|
||||
data object DismissDialog : ResetIdentityRootEvent
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.root
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
@AssistedInject
|
||||
class ResetIdentityRootNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
interface Callback : Plugin {
|
||||
fun onContinue()
|
||||
}
|
||||
|
||||
private val callback: Callback = callback()
|
||||
private val presenter = ResetIdentityRootPresenter()
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = presenter.present()
|
||||
ResetIdentityRootView(
|
||||
modifier = modifier,
|
||||
state = state,
|
||||
onContinue = callback::onContinue,
|
||||
onBack = ::navigateUp,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.root
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
|
||||
class ResetIdentityRootPresenter : Presenter<ResetIdentityRootState> {
|
||||
@Composable
|
||||
override fun present(): ResetIdentityRootState {
|
||||
var displayConfirmDialog by remember { mutableStateOf(false) }
|
||||
|
||||
fun handleEvent(event: ResetIdentityRootEvent) {
|
||||
displayConfirmDialog = when (event) {
|
||||
ResetIdentityRootEvent.Continue -> true
|
||||
ResetIdentityRootEvent.DismissDialog -> false
|
||||
}
|
||||
}
|
||||
|
||||
return ResetIdentityRootState(
|
||||
displayConfirmationDialog = displayConfirmDialog,
|
||||
eventSink = ::handleEvent,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.root
|
||||
|
||||
data class ResetIdentityRootState(
|
||||
val displayConfirmationDialog: Boolean,
|
||||
val eventSink: (ResetIdentityRootEvent) -> Unit,
|
||||
)
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.root
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
||||
class ResetIdentityRootStateProvider : PreviewParameterProvider<ResetIdentityRootState> {
|
||||
override val values: Sequence<ResetIdentityRootState>
|
||||
get() = sequenceOf(
|
||||
ResetIdentityRootState(
|
||||
displayConfirmationDialog = false,
|
||||
eventSink = {}
|
||||
),
|
||||
ResetIdentityRootState(
|
||||
displayConfirmationDialog = true,
|
||||
eventSink = {}
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.root
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.libraries.designsystem.atomic.organisms.InfoListItem
|
||||
import io.element.android.libraries.designsystem.atomic.organisms.InfoListOrganism
|
||||
import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
|
||||
import io.element.android.libraries.designsystem.components.BigIcon
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
fun ResetIdentityRootView(
|
||||
state: ResetIdentityRootState,
|
||||
onContinue: () -> Unit,
|
||||
onBack: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
FlowStepPage(
|
||||
modifier = modifier,
|
||||
iconStyle = BigIcon.Style.AlertSolid,
|
||||
title = stringResource(R.string.screen_encryption_reset_title),
|
||||
isScrollable = true,
|
||||
content = { Content() },
|
||||
buttons = {
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.screen_encryption_reset_action_continue_reset),
|
||||
onClick = { state.eventSink(ResetIdentityRootEvent.Continue) },
|
||||
destructive = true,
|
||||
)
|
||||
},
|
||||
onBackClick = onBack,
|
||||
)
|
||||
|
||||
if (state.displayConfirmationDialog) {
|
||||
ConfirmationDialog(
|
||||
title = stringResource(R.string.screen_reset_encryption_confirmation_alert_title),
|
||||
content = stringResource(R.string.screen_reset_encryption_confirmation_alert_subtitle),
|
||||
submitText = stringResource(R.string.screen_reset_encryption_confirmation_alert_action),
|
||||
onSubmitClick = {
|
||||
state.eventSink(ResetIdentityRootEvent.DismissDialog)
|
||||
onContinue()
|
||||
},
|
||||
destructiveSubmit = true,
|
||||
onDismiss = { state.eventSink(ResetIdentityRootEvent.DismissDialog) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Content() {
|
||||
Column(
|
||||
modifier = Modifier.padding(top = 8.dp, bottom = 40.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(24.dp),
|
||||
) {
|
||||
InfoListOrganism(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
items = persistentListOf(
|
||||
InfoListItem(
|
||||
message = stringResource(R.string.screen_encryption_reset_bullet_1),
|
||||
iconComposable = {
|
||||
Icon(
|
||||
modifier = Modifier.size(20.dp),
|
||||
imageVector = CompoundIcons.Check(),
|
||||
contentDescription = null,
|
||||
tint = ElementTheme.colors.iconSuccessPrimary,
|
||||
)
|
||||
},
|
||||
),
|
||||
InfoListItem(
|
||||
message = stringResource(R.string.screen_encryption_reset_bullet_2),
|
||||
iconComposable = {
|
||||
Icon(
|
||||
modifier = Modifier.size(20.dp),
|
||||
imageVector = CompoundIcons.Info(),
|
||||
contentDescription = null,
|
||||
tint = ElementTheme.colors.iconSecondary,
|
||||
)
|
||||
},
|
||||
),
|
||||
InfoListItem(
|
||||
message = stringResource(R.string.screen_encryption_reset_bullet_3),
|
||||
iconComposable = {
|
||||
Icon(
|
||||
modifier = Modifier.size(20.dp),
|
||||
imageVector = CompoundIcons.Info(),
|
||||
contentDescription = null,
|
||||
tint = ElementTheme.colors.iconSecondary,
|
||||
)
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(R.string.screen_encryption_reset_footer),
|
||||
style = ElementTheme.typography.fontBodyMdMedium,
|
||||
color = ElementTheme.colors.textActionPrimary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun ResetIdentityRootViewPreview(@PreviewParameter(ResetIdentityRootStateProvider::class) state: ResetIdentityRootState) {
|
||||
ElementPreview {
|
||||
ResetIdentityRootView(
|
||||
state = state,
|
||||
onContinue = {},
|
||||
onBack = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.root
|
||||
|
||||
sealed interface SecureBackupRootEvents {
|
||||
data object RetryKeyBackupState : SecureBackupRootEvents
|
||||
data object EnableKeyStorage : SecureBackupRootEvents
|
||||
data object DisplayKeyStorageDisabledError : SecureBackupRootEvents
|
||||
data object DismissDialog : SecureBackupRootEvents
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.root
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.platform.UriHandler
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.appconfig.LearnMoreConfig
|
||||
import io.element.android.libraries.architecture.callback
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
@AssistedInject
|
||||
class SecureBackupRootNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val presenter: SecureBackupRootPresenter,
|
||||
) : Node(
|
||||
buildContext = buildContext,
|
||||
plugins = plugins
|
||||
) {
|
||||
interface Callback : Plugin {
|
||||
fun navigateToSetup()
|
||||
fun navigateToChange()
|
||||
fun navigateToDisable()
|
||||
fun navigateToEnterRecoveryKey()
|
||||
}
|
||||
|
||||
private val callback: Callback = callback()
|
||||
|
||||
private fun onLearnMoreClick(uriHandler: UriHandler) {
|
||||
uriHandler.openUri(LearnMoreConfig.SECURE_BACKUP_URL)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = presenter.present()
|
||||
val uriHandler = LocalUriHandler.current
|
||||
SecureBackupRootView(
|
||||
state = state,
|
||||
onBackClick = ::navigateUp,
|
||||
onSetupClick = callback::navigateToSetup,
|
||||
onChangeClick = callback::navigateToChange,
|
||||
onDisableClick = callback::navigateToDisable,
|
||||
onConfirmRecoveryKeyClick = callback::navigateToEnterRecoveryKey,
|
||||
onLearnMoreClick = { onLearnMoreClick(uriHandler) },
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.root
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.features.securebackup.impl.loggerTagDisable
|
||||
import io.element.android.features.securebackup.impl.loggerTagRoot
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
@Inject
|
||||
class SecureBackupRootPresenter(
|
||||
private val encryptionService: EncryptionService,
|
||||
private val buildMeta: BuildMeta,
|
||||
private val snackbarDispatcher: SnackbarDispatcher,
|
||||
) : Presenter<SecureBackupRootState> {
|
||||
@Composable
|
||||
override fun present(): SecureBackupRootState {
|
||||
val localCoroutineScope = rememberCoroutineScope()
|
||||
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
||||
|
||||
val backupState by encryptionService.backupStateStateFlow.collectAsState()
|
||||
val recoveryState by encryptionService.recoveryStateStateFlow.collectAsState()
|
||||
val enableAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
|
||||
var displayKeyStorageDisabledError by remember { mutableStateOf(false) }
|
||||
Timber.tag(loggerTagRoot.value).d("backupState: $backupState")
|
||||
Timber.tag(loggerTagRoot.value).d("recoveryState: $recoveryState")
|
||||
|
||||
val doesBackupExistOnServerAction: MutableState<AsyncData<Boolean>> = remember { mutableStateOf(AsyncData.Uninitialized) }
|
||||
|
||||
LaunchedEffect(backupState) {
|
||||
if (backupState == BackupState.UNKNOWN) {
|
||||
getKeyBackupStatus(doesBackupExistOnServerAction)
|
||||
}
|
||||
}
|
||||
|
||||
fun handleEvent(event: SecureBackupRootEvents) {
|
||||
when (event) {
|
||||
SecureBackupRootEvents.RetryKeyBackupState -> localCoroutineScope.getKeyBackupStatus(doesBackupExistOnServerAction)
|
||||
SecureBackupRootEvents.EnableKeyStorage -> localCoroutineScope.enableBackup(enableAction)
|
||||
SecureBackupRootEvents.DismissDialog -> {
|
||||
enableAction.value = AsyncAction.Uninitialized
|
||||
displayKeyStorageDisabledError = false
|
||||
}
|
||||
SecureBackupRootEvents.DisplayKeyStorageDisabledError -> displayKeyStorageDisabledError = true
|
||||
}
|
||||
}
|
||||
|
||||
return SecureBackupRootState(
|
||||
enableAction = enableAction.value,
|
||||
backupState = backupState,
|
||||
doesBackupExistOnServer = doesBackupExistOnServerAction.value,
|
||||
recoveryState = recoveryState,
|
||||
appName = buildMeta.applicationName,
|
||||
displayKeyStorageDisabledError = displayKeyStorageDisabledError,
|
||||
snackbarMessage = snackbarMessage,
|
||||
eventSink = ::handleEvent,
|
||||
)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.getKeyBackupStatus(action: MutableState<AsyncData<Boolean>>) = launch {
|
||||
suspend {
|
||||
encryptionService.doesBackupExistOnServer().getOrThrow()
|
||||
}.runCatchingUpdatingState(action)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.enableBackup(action: MutableState<AsyncAction<Unit>>) = launch {
|
||||
suspend {
|
||||
Timber.tag(loggerTagDisable.value).d("Calling encryptionService.enableBackups()")
|
||||
encryptionService.enableBackups().getOrThrow()
|
||||
}.runCatchingUpdatingState(action)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.root
|
||||
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
|
||||
data class SecureBackupRootState(
|
||||
val enableAction: AsyncAction<Unit>,
|
||||
val backupState: BackupState,
|
||||
val doesBackupExistOnServer: AsyncData<Boolean>,
|
||||
val recoveryState: RecoveryState,
|
||||
val appName: String,
|
||||
val displayKeyStorageDisabledError: Boolean,
|
||||
val snackbarMessage: SnackbarMessage?,
|
||||
val eventSink: (SecureBackupRootEvents) -> Unit,
|
||||
) {
|
||||
val isKeyStorageEnabled: Boolean
|
||||
get() = when (backupState) {
|
||||
BackupState.UNKNOWN -> doesBackupExistOnServer.dataOrNull() == true
|
||||
BackupState.CREATING,
|
||||
BackupState.ENABLING,
|
||||
BackupState.RESUMING,
|
||||
BackupState.DOWNLOADING,
|
||||
BackupState.ENABLED -> true
|
||||
BackupState.WAITING_FOR_SYNC,
|
||||
BackupState.DISABLING -> false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.root
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
|
||||
open class SecureBackupRootStateProvider : PreviewParameterProvider<SecureBackupRootState> {
|
||||
override val values: Sequence<SecureBackupRootState>
|
||||
get() = sequenceOf(
|
||||
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = AsyncData.Uninitialized),
|
||||
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = AsyncData.Success(true)),
|
||||
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = AsyncData.Success(false)),
|
||||
aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = AsyncData.Failure(Exception("An error"))),
|
||||
aSecureBackupRootState(backupState = BackupState.WAITING_FOR_SYNC),
|
||||
aSecureBackupRootState(backupState = BackupState.CREATING),
|
||||
aSecureBackupRootState(
|
||||
backupState = BackupState.CREATING,
|
||||
enableAction = AsyncAction.Failure(Exception("Error")),
|
||||
),
|
||||
aSecureBackupRootState(backupState = BackupState.ENABLING),
|
||||
aSecureBackupRootState(backupState = BackupState.RESUMING),
|
||||
aSecureBackupRootState(backupState = BackupState.DOWNLOADING),
|
||||
aSecureBackupRootState(backupState = BackupState.DISABLING),
|
||||
aSecureBackupRootState(backupState = BackupState.ENABLED),
|
||||
aSecureBackupRootState(backupState = BackupState.ENABLED, recoveryState = RecoveryState.UNKNOWN),
|
||||
aSecureBackupRootState(backupState = BackupState.ENABLED, recoveryState = RecoveryState.ENABLED),
|
||||
aSecureBackupRootState(backupState = BackupState.ENABLED, recoveryState = RecoveryState.DISABLED),
|
||||
aSecureBackupRootState(backupState = BackupState.ENABLED, recoveryState = RecoveryState.INCOMPLETE),
|
||||
aSecureBackupRootState(
|
||||
backupState = BackupState.UNKNOWN,
|
||||
doesBackupExistOnServer = AsyncData.Success(false),
|
||||
recoveryState = RecoveryState.ENABLED,
|
||||
),
|
||||
aSecureBackupRootState(
|
||||
backupState = BackupState.UNKNOWN,
|
||||
doesBackupExistOnServer = AsyncData.Success(false),
|
||||
recoveryState = RecoveryState.ENABLED,
|
||||
displayKeyStorageDisabledError = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun aSecureBackupRootState(
|
||||
enableAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
|
||||
backupState: BackupState = BackupState.UNKNOWN,
|
||||
doesBackupExistOnServer: AsyncData<Boolean> = AsyncData.Uninitialized,
|
||||
recoveryState: RecoveryState = RecoveryState.UNKNOWN,
|
||||
displayKeyStorageDisabledError: Boolean = false,
|
||||
snackbarMessage: SnackbarMessage? = null,
|
||||
) = SecureBackupRootState(
|
||||
enableAction = enableAction,
|
||||
backupState = backupState,
|
||||
doesBackupExistOnServer = doesBackupExistOnServer,
|
||||
recoveryState = recoveryState,
|
||||
appName = "Element",
|
||||
displayKeyStorageDisabledError = displayKeyStorageDisabledError,
|
||||
snackbarMessage = snackbarMessage,
|
||||
eventSink = {},
|
||||
)
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.root
|
||||
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.progressSemantics
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.designsystem.components.async.AsyncActionView
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
||||
import io.element.android.libraries.designsystem.components.list.ListItemContent
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferencePage
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.text.buildAnnotatedStringWithStyledPart
|
||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider
|
||||
import io.element.android.libraries.designsystem.theme.components.ListItem
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
fun SecureBackupRootView(
|
||||
state: SecureBackupRootState,
|
||||
onBackClick: () -> Unit,
|
||||
onSetupClick: () -> Unit,
|
||||
onChangeClick: () -> Unit,
|
||||
onDisableClick: () -> Unit,
|
||||
onConfirmRecoveryKeyClick: () -> Unit,
|
||||
onLearnMoreClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage)
|
||||
|
||||
PreferencePage(
|
||||
modifier = modifier,
|
||||
onBackClick = onBackClick,
|
||||
title = stringResource(id = CommonStrings.common_encryption),
|
||||
snackbarHost = { SnackbarHost(snackbarHostState) },
|
||||
) {
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_chat_backup_key_backup_title),
|
||||
)
|
||||
},
|
||||
supportingContent = {
|
||||
Text(
|
||||
text = buildAnnotatedStringWithStyledPart(
|
||||
fullTextRes = R.string.screen_chat_backup_key_backup_description,
|
||||
coloredTextRes = CommonStrings.action_learn_more,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
underline = false,
|
||||
bold = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onClick = onLearnMoreClick,
|
||||
)
|
||||
|
||||
// Disable / Enable key storage
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_chat_backup_key_storage_toggle_title),
|
||||
)
|
||||
},
|
||||
trailingContent = when (state.backupState) {
|
||||
BackupState.WAITING_FOR_SYNC,
|
||||
BackupState.DISABLING -> ListItemContent.Custom { LoadingView() }
|
||||
BackupState.UNKNOWN -> {
|
||||
when (state.doesBackupExistOnServer) {
|
||||
is AsyncData.Success -> {
|
||||
ListItemContent.Switch(checked = state.doesBackupExistOnServer.data)
|
||||
}
|
||||
is AsyncData.Loading,
|
||||
AsyncData.Uninitialized -> ListItemContent.Custom { LoadingView() }
|
||||
is AsyncData.Failure -> ListItemContent.Custom {
|
||||
Text(
|
||||
text = stringResource(id = CommonStrings.action_retry)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
BackupState.CREATING,
|
||||
BackupState.ENABLING,
|
||||
BackupState.RESUMING,
|
||||
BackupState.ENABLED,
|
||||
BackupState.DOWNLOADING -> ListItemContent.Switch(checked = true)
|
||||
},
|
||||
onClick = {
|
||||
when (state.backupState) {
|
||||
BackupState.WAITING_FOR_SYNC,
|
||||
BackupState.DISABLING -> Unit
|
||||
BackupState.UNKNOWN -> {
|
||||
when (state.doesBackupExistOnServer) {
|
||||
is AsyncData.Success -> {
|
||||
if (state.doesBackupExistOnServer.data) {
|
||||
onDisableClick()
|
||||
} else {
|
||||
state.eventSink.invoke(SecureBackupRootEvents.EnableKeyStorage)
|
||||
}
|
||||
}
|
||||
is AsyncData.Loading,
|
||||
AsyncData.Uninitialized -> Unit
|
||||
is AsyncData.Failure -> state.eventSink.invoke(SecureBackupRootEvents.RetryKeyBackupState)
|
||||
}
|
||||
}
|
||||
BackupState.CREATING,
|
||||
BackupState.ENABLING,
|
||||
BackupState.RESUMING,
|
||||
BackupState.ENABLED,
|
||||
BackupState.DOWNLOADING -> onDisableClick()
|
||||
}
|
||||
},
|
||||
)
|
||||
HorizontalDivider()
|
||||
// Setup recovery
|
||||
when (state.recoveryState) {
|
||||
RecoveryState.UNKNOWN,
|
||||
RecoveryState.WAITING_FOR_SYNC -> Unit
|
||||
RecoveryState.DISABLED -> {
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_chat_backup_recovery_action_setup),
|
||||
)
|
||||
},
|
||||
supportingContent = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_chat_backup_recovery_action_setup_description, state.appName),
|
||||
)
|
||||
},
|
||||
trailingContent = ListItemContent.Badge,
|
||||
enabled = state.isKeyStorageEnabled,
|
||||
alwaysClickable = true,
|
||||
onClick = {
|
||||
if (state.isKeyStorageEnabled) {
|
||||
onSetupClick()
|
||||
} else {
|
||||
state.eventSink.invoke(SecureBackupRootEvents.DisplayKeyStorageDisabledError)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
RecoveryState.ENABLED -> {
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_chat_backup_recovery_action_change),
|
||||
)
|
||||
},
|
||||
supportingContent = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_chat_backup_recovery_action_change_description),
|
||||
)
|
||||
},
|
||||
enabled = state.isKeyStorageEnabled,
|
||||
alwaysClickable = true,
|
||||
onClick = {
|
||||
if (state.isKeyStorageEnabled) {
|
||||
onChangeClick()
|
||||
} else {
|
||||
state.eventSink.invoke(SecureBackupRootEvents.DisplayKeyStorageDisabledError)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
RecoveryState.INCOMPLETE ->
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_chat_backup_recovery_action_confirm),
|
||||
)
|
||||
},
|
||||
supportingContent = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_chat_backup_recovery_action_confirm_description),
|
||||
)
|
||||
},
|
||||
trailingContent = ListItemContent.Badge,
|
||||
enabled = state.isKeyStorageEnabled,
|
||||
alwaysClickable = true,
|
||||
onClick = {
|
||||
if (state.isKeyStorageEnabled) {
|
||||
onConfirmRecoveryKeyClick()
|
||||
} else {
|
||||
state.eventSink.invoke(SecureBackupRootEvents.DisplayKeyStorageDisabledError)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
AsyncActionView(
|
||||
async = state.enableAction,
|
||||
progressDialog = { },
|
||||
onSuccess = { },
|
||||
onErrorDismiss = { state.eventSink.invoke(SecureBackupRootEvents.DismissDialog) }
|
||||
)
|
||||
if (state.displayKeyStorageDisabledError) {
|
||||
ErrorDialog(
|
||||
title = null,
|
||||
content = stringResource(id = R.string.screen_chat_backup_key_storage_disabled_error),
|
||||
onSubmit = { state.eventSink.invoke(SecureBackupRootEvents.DismissDialog) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LoadingView() {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier
|
||||
.progressSemantics()
|
||||
.size(24.dp),
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun SecureBackupRootViewPreview(
|
||||
@PreviewParameter(SecureBackupRootStateProvider::class) state: SecureBackupRootState
|
||||
) = ElementPreview {
|
||||
SecureBackupRootView(
|
||||
state = state,
|
||||
onBackClick = {},
|
||||
onSetupClick = {},
|
||||
onChangeClick = {},
|
||||
onDisableClick = {},
|
||||
onConfirmRecoveryKeyClick = {},
|
||||
onLearnMoreClick = {},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup
|
||||
|
||||
sealed interface SecureBackupSetupEvents {
|
||||
data object CreateRecoveryKey : SecureBackupSetupEvents
|
||||
data object RecoveryKeyHasBeenSaved : SecureBackupSetupEvents
|
||||
data object Done : SecureBackupSetupEvents
|
||||
data object DismissDialog : SecureBackupSetupEvents
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.libraries.architecture.NodeInputs
|
||||
import io.element.android.libraries.architecture.inputs
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
@AssistedInject
|
||||
class SecureBackupSetupNode(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
presenterFactory: SecureBackupSetupPresenter.Factory,
|
||||
private val snackbarDispatcher: SnackbarDispatcher,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
data class Inputs(
|
||||
val isChangeRecoveryKeyUserStory: Boolean,
|
||||
) : NodeInputs
|
||||
|
||||
private val inputs = inputs<Inputs>()
|
||||
|
||||
private val presenter = presenterFactory.create(inputs.isChangeRecoveryKeyUserStory)
|
||||
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = presenter.present()
|
||||
SecureBackupSetupView(
|
||||
state = state,
|
||||
onSuccess = {
|
||||
postSuccessSnackbar()
|
||||
navigateUp()
|
||||
},
|
||||
onBackClick = ::navigateUp,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
private fun postSuccessSnackbar() {
|
||||
snackbarDispatcher.post(
|
||||
SnackbarMessage(
|
||||
messageResId = if (inputs.isChangeRecoveryKeyUserStory) {
|
||||
R.string.screen_recovery_key_change_success
|
||||
} else {
|
||||
R.string.screen_recovery_key_setup_success
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import com.freeletics.flowredux.compose.StateAndDispatch
|
||||
import com.freeletics.flowredux.compose.rememberStateAndDispatch
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.features.securebackup.impl.loggerTagSetup
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.encryption.EnableRecoveryProgress
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
@AssistedInject
|
||||
class SecureBackupSetupPresenter(
|
||||
@Assisted private val isChangeRecoveryKeyUserStory: Boolean,
|
||||
private val stateMachine: SecureBackupSetupStateMachine,
|
||||
private val encryptionService: EncryptionService,
|
||||
) : Presenter<SecureBackupSetupState> {
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(isChangeRecoveryKeyUserStory: Boolean): SecureBackupSetupPresenter
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun present(): SecureBackupSetupState {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val stateAndDispatch = stateMachine.rememberStateAndDispatch()
|
||||
val setupState by remember {
|
||||
derivedStateOf { stateAndDispatch.state.value.toSetupState() }
|
||||
}
|
||||
var showSaveConfirmationDialog by remember { mutableStateOf(false) }
|
||||
|
||||
fun handleEvent(event: SecureBackupSetupEvents) {
|
||||
when (event) {
|
||||
SecureBackupSetupEvents.CreateRecoveryKey -> {
|
||||
coroutineScope.createOrChangeRecoveryKey(stateAndDispatch)
|
||||
}
|
||||
SecureBackupSetupEvents.RecoveryKeyHasBeenSaved ->
|
||||
stateAndDispatch.dispatchAction(SecureBackupSetupStateMachine.Event.UserSavedKey)
|
||||
SecureBackupSetupEvents.DismissDialog -> {
|
||||
showSaveConfirmationDialog = false
|
||||
stateAndDispatch.dispatchAction(SecureBackupSetupStateMachine.Event.ClearError)
|
||||
}
|
||||
SecureBackupSetupEvents.Done -> {
|
||||
showSaveConfirmationDialog = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val recoveryKeyViewState = RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = if (isChangeRecoveryKeyUserStory) RecoveryKeyUserStory.Change else RecoveryKeyUserStory.Setup,
|
||||
formattedRecoveryKey = setupState.recoveryKey(),
|
||||
displayTextFieldContents = true,
|
||||
inProgress = setupState is SetupState.Creating,
|
||||
)
|
||||
|
||||
return SecureBackupSetupState(
|
||||
isChangeRecoveryKeyUserStory = isChangeRecoveryKeyUserStory,
|
||||
recoveryKeyViewState = recoveryKeyViewState,
|
||||
setupState = setupState,
|
||||
showSaveConfirmationDialog = showSaveConfirmationDialog,
|
||||
eventSink = ::handleEvent,
|
||||
)
|
||||
}
|
||||
|
||||
private fun SecureBackupSetupStateMachine.State?.toSetupState(): SetupState {
|
||||
return when (this) {
|
||||
null,
|
||||
SecureBackupSetupStateMachine.State.Initial -> SetupState.Init
|
||||
SecureBackupSetupStateMachine.State.CreatingKey -> SetupState.Creating
|
||||
is SecureBackupSetupStateMachine.State.KeyCreated -> SetupState.Created(formattedRecoveryKey = key)
|
||||
is SecureBackupSetupStateMachine.State.KeyCreatedAndSaved -> SetupState.CreatedAndSaved(formattedRecoveryKey = key)
|
||||
is SecureBackupSetupStateMachine.State.Error -> SetupState.Error(exception)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.createOrChangeRecoveryKey(
|
||||
stateAndDispatch: StateAndDispatch<SecureBackupSetupStateMachine.State, SecureBackupSetupStateMachine.Event>
|
||||
) = launch {
|
||||
stateAndDispatch.dispatchAction(SecureBackupSetupStateMachine.Event.UserCreatesKey)
|
||||
if (isChangeRecoveryKeyUserStory) {
|
||||
Timber.tag(loggerTagSetup.value).d("Calling encryptionService.resetRecoveryKey()")
|
||||
encryptionService.resetRecoveryKey().fold(
|
||||
onSuccess = {
|
||||
stateAndDispatch.dispatchAction(SecureBackupSetupStateMachine.Event.SdkHasCreatedKey(it))
|
||||
},
|
||||
onFailure = {
|
||||
if (it is Exception) {
|
||||
stateAndDispatch.dispatchAction(SecureBackupSetupStateMachine.Event.SdkError(it))
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
observeEncryptionService(stateAndDispatch)
|
||||
Timber.tag(loggerTagSetup.value).d("Calling encryptionService.enableRecovery()")
|
||||
encryptionService.enableRecovery(waitForBackupsToUpload = false).onFailure {
|
||||
Timber.tag(loggerTagSetup.value).e(it, "Failed to enable recovery")
|
||||
if (it is Exception) {
|
||||
stateAndDispatch.dispatchAction(SecureBackupSetupStateMachine.Event.SdkError(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.observeEncryptionService(
|
||||
stateAndDispatch: StateAndDispatch<SecureBackupSetupStateMachine.State, SecureBackupSetupStateMachine.Event>
|
||||
) = launch {
|
||||
encryptionService.enableRecoveryProgressStateFlow.collect { enableRecoveryProgress ->
|
||||
Timber.tag(loggerTagSetup.value).d("New enableRecoveryProgress: ${enableRecoveryProgress.javaClass.simpleName}")
|
||||
when (enableRecoveryProgress) {
|
||||
is EnableRecoveryProgress.Starting,
|
||||
is EnableRecoveryProgress.CreatingBackup,
|
||||
is EnableRecoveryProgress.CreatingRecoveryKey,
|
||||
is EnableRecoveryProgress.BackingUp,
|
||||
is EnableRecoveryProgress.RoomKeyUploadError -> Unit
|
||||
is EnableRecoveryProgress.Done ->
|
||||
stateAndDispatch.dispatchAction(SecureBackupSetupStateMachine.Event.SdkHasCreatedKey(enableRecoveryProgress.recoveryKey))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup
|
||||
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
|
||||
|
||||
data class SecureBackupSetupState(
|
||||
val isChangeRecoveryKeyUserStory: Boolean,
|
||||
val recoveryKeyViewState: RecoveryKeyViewState,
|
||||
val showSaveConfirmationDialog: Boolean,
|
||||
val setupState: SetupState,
|
||||
val eventSink: (SecureBackupSetupEvents) -> Unit
|
||||
)
|
||||
|
||||
sealed interface SetupState {
|
||||
data object Init : SetupState
|
||||
data object Creating : SetupState
|
||||
data class Created(val formattedRecoveryKey: String) : SetupState
|
||||
data class CreatedAndSaved(val formattedRecoveryKey: String) : SetupState
|
||||
data class Error(val exception: Exception) : SetupState
|
||||
}
|
||||
|
||||
fun SetupState.recoveryKey(): String? = when (this) {
|
||||
is SetupState.Created -> formattedRecoveryKey
|
||||
is SetupState.CreatedAndSaved -> formattedRecoveryKey
|
||||
else -> null
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:Suppress("WildcardImport")
|
||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup
|
||||
|
||||
import com.freeletics.flowredux.dsl.FlowReduxStateMachine
|
||||
import dev.zacsweers.metro.Inject
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import com.freeletics.flowredux.dsl.State as MachineState
|
||||
|
||||
@Inject
|
||||
class SecureBackupSetupStateMachine : FlowReduxStateMachine<SecureBackupSetupStateMachine.State, SecureBackupSetupStateMachine.Event>(
|
||||
initialState = State.Initial
|
||||
) {
|
||||
init {
|
||||
spec {
|
||||
inState<State.Initial> {
|
||||
on { _: Event.UserCreatesKey, state: MachineState<State.Initial> ->
|
||||
state.override { State.CreatingKey }
|
||||
}
|
||||
}
|
||||
inState<State.CreatingKey> {
|
||||
on { event: Event.SdkError, state: MachineState<State.CreatingKey> ->
|
||||
state.override { State.Error(event.exception) }
|
||||
}
|
||||
on { event: Event.SdkHasCreatedKey, state: MachineState<State.CreatingKey> ->
|
||||
state.override { State.KeyCreated(event.key) }
|
||||
}
|
||||
}
|
||||
inState<State.KeyCreated> {
|
||||
on { _: Event.UserSavedKey, state: MachineState<State.KeyCreated> ->
|
||||
state.override { State.KeyCreatedAndSaved(state.snapshot.key) }
|
||||
}
|
||||
}
|
||||
inState<State.Error> {
|
||||
on { _: Event.ClearError, state: MachineState<State.Error> ->
|
||||
state.override { State.Initial }
|
||||
}
|
||||
}
|
||||
inState<State.KeyCreatedAndSaved> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface State {
|
||||
data object Initial : State
|
||||
data object CreatingKey : State
|
||||
data class KeyCreated(val key: String) : State
|
||||
data class KeyCreatedAndSaved(val key: String) : State
|
||||
data class Error(val exception: Exception) : State
|
||||
}
|
||||
|
||||
sealed interface Event {
|
||||
data object UserCreatesKey : Event
|
||||
data class SdkHasCreatedKey(val key: String) : Event
|
||||
data class SdkError(val exception: Exception) : Event
|
||||
data object UserSavedKey : Event
|
||||
data object ClearError : Event
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
|
||||
import io.element.android.features.securebackup.impl.setup.views.aFormattedRecoveryKey
|
||||
|
||||
open class SecureBackupSetupStateProvider : PreviewParameterProvider<SecureBackupSetupState> {
|
||||
override val values: Sequence<SecureBackupSetupState>
|
||||
get() = sequenceOf(
|
||||
aSecureBackupSetupState(setupState = SetupState.Init),
|
||||
aSecureBackupSetupState(setupState = SetupState.Creating),
|
||||
aSecureBackupSetupState(setupState = SetupState.Created(aFormattedRecoveryKey())),
|
||||
aSecureBackupSetupState(setupState = SetupState.CreatedAndSaved(aFormattedRecoveryKey())),
|
||||
aSecureBackupSetupState(
|
||||
setupState = SetupState.CreatedAndSaved(aFormattedRecoveryKey()),
|
||||
showSaveConfirmationDialog = true,
|
||||
),
|
||||
aSecureBackupSetupState(setupState = SetupState.Error(Exception("Test error"))),
|
||||
// Add other states here
|
||||
)
|
||||
}
|
||||
|
||||
fun aSecureBackupSetupState(
|
||||
setupState: SetupState = SetupState.Init,
|
||||
showSaveConfirmationDialog: Boolean = false,
|
||||
) = SecureBackupSetupState(
|
||||
isChangeRecoveryKeyUserStory = false,
|
||||
setupState = setupState,
|
||||
showSaveConfirmationDialog = showSaveConfirmationDialog,
|
||||
recoveryKeyViewState = setupState.toRecoveryKeyViewState(),
|
||||
eventSink = {}
|
||||
)
|
||||
|
||||
private fun SetupState.toRecoveryKeyViewState(): RecoveryKeyViewState {
|
||||
return RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Setup,
|
||||
formattedRecoveryKey = recoveryKey(),
|
||||
displayTextFieldContents = true,
|
||||
inProgress = this is SetupState.Creating,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup
|
||||
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyView
|
||||
import io.element.android.libraries.androidutils.system.copyToClipboard
|
||||
import io.element.android.libraries.androidutils.system.startSharePlainTextIntent
|
||||
import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
|
||||
import io.element.android.libraries.designsystem.components.BigIcon
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.IconSource
|
||||
import io.element.android.libraries.designsystem.theme.components.OutlinedButton
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
fun SecureBackupSetupView(
|
||||
state: SecureBackupSetupState,
|
||||
onSuccess: () -> Unit,
|
||||
onBackClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
FlowStepPage(
|
||||
modifier = modifier,
|
||||
onBackClick = onBackClick.takeIf { state.canGoBack() },
|
||||
title = title(state),
|
||||
subTitle = subtitle(state),
|
||||
iconStyle = BigIcon.Style.Default(CompoundIcons.KeySolid()),
|
||||
buttons = { Buttons(state, onFinish = onSuccess) },
|
||||
) {
|
||||
Content(state = state)
|
||||
}
|
||||
|
||||
if (state.setupState is SetupState.Error) {
|
||||
ErrorDialog(
|
||||
title = stringResource(id = CommonStrings.common_something_went_wrong),
|
||||
content = stringResource(id = CommonStrings.common_something_went_wrong_message),
|
||||
onSubmit = {
|
||||
state.eventSink.invoke(SecureBackupSetupEvents.DismissDialog)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if (state.showSaveConfirmationDialog) {
|
||||
ConfirmationDialog(
|
||||
title = stringResource(id = R.string.screen_recovery_key_setup_confirmation_title),
|
||||
content = stringResource(id = R.string.screen_recovery_key_setup_confirmation_description),
|
||||
submitText = stringResource(id = CommonStrings.action_continue),
|
||||
onSubmitClick = onSuccess,
|
||||
onDismiss = {
|
||||
state.eventSink.invoke(SecureBackupSetupEvents.DismissDialog)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun SecureBackupSetupState.canGoBack(): Boolean {
|
||||
return recoveryKeyViewState.formattedRecoveryKey == null
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun title(state: SecureBackupSetupState): String {
|
||||
return when (state.setupState) {
|
||||
SetupState.Init,
|
||||
SetupState.Creating,
|
||||
is SetupState.Error -> if (state.isChangeRecoveryKeyUserStory) {
|
||||
stringResource(id = R.string.screen_recovery_key_change_title)
|
||||
} else {
|
||||
stringResource(id = R.string.screen_recovery_key_setup_title)
|
||||
}
|
||||
is SetupState.Created,
|
||||
is SetupState.CreatedAndSaved ->
|
||||
stringResource(id = R.string.screen_recovery_key_save_title)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun subtitle(state: SecureBackupSetupState): String {
|
||||
return when (state.setupState) {
|
||||
SetupState.Init,
|
||||
SetupState.Creating,
|
||||
is SetupState.Error -> if (state.isChangeRecoveryKeyUserStory) {
|
||||
stringResource(id = R.string.screen_recovery_key_change_description)
|
||||
} else {
|
||||
stringResource(id = R.string.screen_recovery_key_setup_description)
|
||||
}
|
||||
is SetupState.Created,
|
||||
is SetupState.CreatedAndSaved ->
|
||||
stringResource(id = R.string.screen_recovery_key_save_description)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Content(
|
||||
state: SecureBackupSetupState,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val formattedRecoveryKey = state.recoveryKeyViewState.formattedRecoveryKey
|
||||
val clickLambda = if (formattedRecoveryKey != null) {
|
||||
{
|
||||
context.copyToClipboard(
|
||||
formattedRecoveryKey,
|
||||
context.getString(R.string.screen_recovery_key_copied_to_clipboard)
|
||||
)
|
||||
state.eventSink.invoke(SecureBackupSetupEvents.RecoveryKeyHasBeenSaved)
|
||||
}
|
||||
} else {
|
||||
if (!state.recoveryKeyViewState.inProgress) {
|
||||
{
|
||||
state.eventSink.invoke(SecureBackupSetupEvents.CreateRecoveryKey)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
RecoveryKeyView(
|
||||
modifier = Modifier.padding(top = 52.dp),
|
||||
state = state.recoveryKeyViewState,
|
||||
onClick = clickLambda,
|
||||
onChange = null,
|
||||
onSubmit = null,
|
||||
toggleRecoveryKeyVisibility = {},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.Buttons(
|
||||
state: SecureBackupSetupState,
|
||||
onFinish: () -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val chooserTitle = stringResource(id = R.string.screen_recovery_key_save_action)
|
||||
when (state.setupState) {
|
||||
SetupState.Init,
|
||||
SetupState.Creating,
|
||||
is SetupState.Error -> {
|
||||
Button(
|
||||
text = stringResource(id = CommonStrings.action_done),
|
||||
enabled = false,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = onFinish
|
||||
)
|
||||
}
|
||||
is SetupState.Created,
|
||||
is SetupState.CreatedAndSaved -> {
|
||||
OutlinedButton(
|
||||
text = stringResource(id = R.string.screen_recovery_key_save_action),
|
||||
leadingIcon = IconSource.Vector(CompoundIcons.Download()),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = {
|
||||
context.startSharePlainTextIntent(
|
||||
activityResultLauncher = null,
|
||||
chooserTitle = chooserTitle,
|
||||
text = state.setupState.recoveryKey()!!,
|
||||
)
|
||||
state.eventSink.invoke(SecureBackupSetupEvents.RecoveryKeyHasBeenSaved)
|
||||
},
|
||||
)
|
||||
Button(
|
||||
text = stringResource(id = CommonStrings.action_done),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = {
|
||||
if (state.setupState is SetupState.CreatedAndSaved) {
|
||||
onFinish()
|
||||
} else {
|
||||
state.eventSink.invoke(SecureBackupSetupEvents.Done)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun SecureBackupSetupViewPreview(
|
||||
@PreviewParameter(SecureBackupSetupStateProvider::class) state: SecureBackupSetupState
|
||||
) = ElementPreview {
|
||||
SecureBackupSetupView(
|
||||
state = state,
|
||||
onSuccess = {},
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun SecureBackupSetupViewChangePreview(
|
||||
@PreviewParameter(SecureBackupSetupStateProvider::class) state: SecureBackupSetupState
|
||||
) = ElementPreview {
|
||||
SecureBackupSetupView(
|
||||
state = state.copy(
|
||||
isChangeRecoveryKeyUserStory = true,
|
||||
recoveryKeyViewState = state.recoveryKeyViewState.copy(recoveryKeyUserStory = RecoveryKeyUserStory.Change),
|
||||
),
|
||||
onSuccess = {},
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup.views
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.progressSemantics
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.autofill.ContentType
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentType
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.features.securebackup.impl.tools.RecoveryKeyVisualTransformation
|
||||
import io.element.android.libraries.designsystem.modifiers.clickableIfNotNull
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.components.TextField
|
||||
import io.element.android.libraries.testtags.TestTags
|
||||
import io.element.android.libraries.testtags.testTag
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
internal fun RecoveryKeyView(
|
||||
state: RecoveryKeyViewState,
|
||||
onClick: (() -> Unit)?,
|
||||
onChange: ((String) -> Unit)?,
|
||||
onSubmit: (() -> Unit)?,
|
||||
toggleRecoveryKeyVisibility: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = CommonStrings.common_recovery_key),
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
)
|
||||
RecoveryKeyContent(state, onClick, onChange, onSubmit, toggleRecoveryKeyVisibility)
|
||||
RecoveryKeyFooter(state)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RecoveryKeyContent(
|
||||
state: RecoveryKeyViewState,
|
||||
onClick: (() -> Unit)?,
|
||||
onChange: ((String) -> Unit)?,
|
||||
onSubmit: (() -> Unit)?,
|
||||
toggleRecoveryKeyVisibility: (Boolean) -> Unit,
|
||||
) {
|
||||
when (state.recoveryKeyUserStory) {
|
||||
RecoveryKeyUserStory.Setup,
|
||||
RecoveryKeyUserStory.Change -> RecoveryKeyStaticContent(state, onClick)
|
||||
RecoveryKeyUserStory.Enter -> RecoveryKeyFormContent(
|
||||
state = state,
|
||||
toggleRecoveryKeyVisibility = toggleRecoveryKeyVisibility,
|
||||
onChange = onChange,
|
||||
onSubmit = onSubmit,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RecoveryKeyStaticContent(
|
||||
state: RecoveryKeyViewState,
|
||||
onClick: (() -> Unit)?,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(10.dp))
|
||||
.background(
|
||||
color = ElementTheme.colors.bgSubtleSecondary,
|
||||
)
|
||||
.clickableIfNotNull(onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 11.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
if (state.formattedRecoveryKey != null) {
|
||||
RecoveryKeyWithCopy(
|
||||
recoveryKey = state.formattedRecoveryKey,
|
||||
alpha = 1f,
|
||||
)
|
||||
} else {
|
||||
// Use an invisible recovery key to ensure that the Box size is correct.
|
||||
val fakeFormattedRecoveryKey = List(12) { "XXXX" }.joinToString(" ")
|
||||
RecoveryKeyWithCopy(
|
||||
recoveryKey = fakeFormattedRecoveryKey,
|
||||
alpha = 0f,
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
if (state.inProgress) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier
|
||||
.progressSemantics()
|
||||
.padding(end = 8.dp)
|
||||
.size(16.dp),
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
strokeWidth = 1.5.dp,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = stringResource(
|
||||
id = when {
|
||||
state.inProgress -> R.string.screen_recovery_key_generating_key
|
||||
state.recoveryKeyUserStory == RecoveryKeyUserStory.Change -> R.string.screen_recovery_key_change_generate_key
|
||||
else -> R.string.screen_recovery_key_setup_generate_key
|
||||
}
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RecoveryKeyWithCopy(
|
||||
recoveryKey: String,
|
||||
alpha: Float,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.alpha(alpha),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Text(
|
||||
text = recoveryKey,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
style = ElementTheme.typography.fontBodyLgRegular.copy(fontFamily = FontFamily.Monospace),
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Copy(),
|
||||
contentDescription = stringResource(id = CommonStrings.action_copy),
|
||||
tint = ElementTheme.colors.iconSecondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RecoveryKeyFormContent(
|
||||
state: RecoveryKeyViewState,
|
||||
toggleRecoveryKeyVisibility: (Boolean) -> Unit,
|
||||
onChange: ((String) -> Unit)?,
|
||||
onSubmit: (() -> Unit)?,
|
||||
) {
|
||||
onChange ?: error("onChange should not be null")
|
||||
onSubmit ?: error("onSubmit should not be null")
|
||||
if (state.inProgress) {
|
||||
// Ensure recovery key is hidden when user submits the form
|
||||
toggleRecoveryKeyVisibility(false)
|
||||
}
|
||||
val keyHasSpace = state.formattedRecoveryKey.orEmpty().contains(" ")
|
||||
val recoveryKeyVisualTransformation = remember(keyHasSpace, state.displayTextFieldContents) {
|
||||
if (state.displayTextFieldContents) {
|
||||
// Do not apply a visual transformation if the key has spaces, to let user enter passphrase
|
||||
if (keyHasSpace) VisualTransformation.None else RecoveryKeyVisualTransformation()
|
||||
} else {
|
||||
PasswordVisualTransformation()
|
||||
}
|
||||
}
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag(TestTags.recoveryKey)
|
||||
.semantics {
|
||||
contentType = ContentType.Password
|
||||
},
|
||||
minLines = 2,
|
||||
value = state.formattedRecoveryKey.orEmpty(),
|
||||
onValueChange = onChange,
|
||||
enabled = state.inProgress.not(),
|
||||
visualTransformation = recoveryKeyVisualTransformation,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Password,
|
||||
imeAction = ImeAction.Done,
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { onSubmit() }
|
||||
),
|
||||
placeholder = stringResource(id = R.string.screen_recovery_key_confirm_key_placeholder),
|
||||
trailingIcon = {
|
||||
val image =
|
||||
if (state.displayTextFieldContents) CompoundIcons.VisibilityOn() else CompoundIcons.VisibilityOff()
|
||||
val description =
|
||||
if (state.displayTextFieldContents) stringResource(CommonStrings.a11y_hide_password) else stringResource(CommonStrings.a11y_show_password)
|
||||
Box(Modifier.clickable { toggleRecoveryKeyVisibility(!state.displayTextFieldContents) }) {
|
||||
Icon(
|
||||
imageVector = image,
|
||||
contentDescription = description,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RecoveryKeyFooter(state: RecoveryKeyViewState) {
|
||||
when (state.recoveryKeyUserStory) {
|
||||
RecoveryKeyUserStory.Setup,
|
||||
RecoveryKeyUserStory.Change -> {
|
||||
if (state.formattedRecoveryKey == null) {
|
||||
Text(
|
||||
text = stringResource(
|
||||
id = if (state.recoveryKeyUserStory == RecoveryKeyUserStory.Change) {
|
||||
R.string.screen_recovery_key_change_generate_key_description
|
||||
} else {
|
||||
R.string.screen_recovery_key_setup_generate_key_description
|
||||
}
|
||||
),
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
style = ElementTheme.typography.fontBodySmRegular,
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_recovery_key_save_key_description),
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
style = ElementTheme.typography.fontBodySmRegular,
|
||||
)
|
||||
}
|
||||
}
|
||||
RecoveryKeyUserStory.Enter -> {
|
||||
Text(
|
||||
text = stringResource(id = R.string.screen_recovery_key_confirm_key_description),
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
style = ElementTheme.typography.fontBodySmRegular,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun RecoveryKeyViewPreview(
|
||||
@PreviewParameter(RecoveryKeyViewStateProvider::class) state: RecoveryKeyViewState
|
||||
) = ElementPreview {
|
||||
RecoveryKeyView(
|
||||
state = state,
|
||||
onClick = {},
|
||||
onChange = {},
|
||||
onSubmit = {},
|
||||
toggleRecoveryKeyVisibility = {},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup.views
|
||||
|
||||
data class RecoveryKeyViewState(
|
||||
val recoveryKeyUserStory: RecoveryKeyUserStory,
|
||||
val formattedRecoveryKey: String?,
|
||||
val displayTextFieldContents: Boolean,
|
||||
val inProgress: Boolean,
|
||||
)
|
||||
|
||||
enum class RecoveryKeyUserStory {
|
||||
Setup,
|
||||
Change,
|
||||
Enter,
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup.views
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
||||
open class RecoveryKeyViewStateProvider : PreviewParameterProvider<RecoveryKeyViewState> {
|
||||
override val values: Sequence<RecoveryKeyViewState>
|
||||
get() = sequenceOf(RecoveryKeyUserStory.Setup, RecoveryKeyUserStory.Change, RecoveryKeyUserStory.Enter)
|
||||
.flatMap {
|
||||
sequenceOf(
|
||||
aRecoveryKeyViewState(recoveryKeyUserStory = it),
|
||||
aRecoveryKeyViewState(recoveryKeyUserStory = it, inProgress = true),
|
||||
aRecoveryKeyViewState(recoveryKeyUserStory = it, formattedRecoveryKey = aFormattedRecoveryKey()),
|
||||
aRecoveryKeyViewState(recoveryKeyUserStory = it, formattedRecoveryKey = aFormattedRecoveryKey(), inProgress = true),
|
||||
)
|
||||
} + sequenceOf(
|
||||
aRecoveryKeyViewState(recoveryKeyUserStory = RecoveryKeyUserStory.Enter, formattedRecoveryKey = aFormattedRecoveryKey().replace(" ", "")),
|
||||
aRecoveryKeyViewState(recoveryKeyUserStory = RecoveryKeyUserStory.Enter, formattedRecoveryKey = "This is a passphrase with spaces"),
|
||||
aRecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Enter,
|
||||
formattedRecoveryKey = aFormattedRecoveryKey().replace(" ", ""),
|
||||
displayTextFieldContents = false
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun aRecoveryKeyViewState(
|
||||
recoveryKeyUserStory: RecoveryKeyUserStory = RecoveryKeyUserStory.Setup,
|
||||
formattedRecoveryKey: String? = null,
|
||||
inProgress: Boolean = false,
|
||||
displayTextFieldContents: Boolean = true,
|
||||
) = RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = recoveryKeyUserStory,
|
||||
formattedRecoveryKey = formattedRecoveryKey,
|
||||
displayTextFieldContents = displayTextFieldContents,
|
||||
inProgress = inProgress,
|
||||
)
|
||||
|
||||
internal fun aFormattedRecoveryKey(): String {
|
||||
return "Estm dfyU adhD h8y6 Estm dfyU adhD h8y6 Estm dfyU adhD h8y6"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.tools
|
||||
|
||||
import dev.zacsweers.metro.Inject
|
||||
|
||||
private const val RECOVERY_KEY_LENGTH = 48
|
||||
private const val BASE_58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
|
||||
@Inject
|
||||
class RecoveryKeyTools {
|
||||
fun isRecoveryKeyFormatValid(recoveryKey: String): Boolean {
|
||||
val recoveryKeyWithoutSpace = recoveryKey.replace("\\s+".toRegex(), "")
|
||||
return recoveryKeyWithoutSpace.length == RECOVERY_KEY_LENGTH && recoveryKeyWithoutSpace.all { BASE_58_ALPHABET.contains(it) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.tools
|
||||
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.input.OffsetMapping
|
||||
import androidx.compose.ui.text.input.TransformedText
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
|
||||
class RecoveryKeyVisualTransformation : VisualTransformation {
|
||||
override fun filter(text: AnnotatedString): TransformedText {
|
||||
return TransformedText(
|
||||
text = AnnotatedString(
|
||||
text.text
|
||||
.chunked(4)
|
||||
.joinToString(separator = " ")
|
||||
),
|
||||
offsetMapping = RecoveryKeyOffsetMapping(text.text),
|
||||
)
|
||||
}
|
||||
|
||||
class RecoveryKeyOffsetMapping(private val text: String) : OffsetMapping {
|
||||
override fun originalToTransformed(offset: Int): Int {
|
||||
if (offset == 0) return 0
|
||||
val numberOfChunks = offset / 4
|
||||
return if (offset == text.length && offset % 4 == 0) {
|
||||
offset + numberOfChunks - 1
|
||||
} else {
|
||||
offset + numberOfChunks
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformedToOriginal(offset: Int): Int {
|
||||
val numberOfChunks = offset / 5
|
||||
return offset - numberOfChunks
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Выключыць рэзервовае капіраванне"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Уключыце рэзервовае капіраванне"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Надзейна захоўвайце вашу крыптаграфічную ідэнтыфікацыю і ключы паведамленняў на серверы. Гэта дазволіць вам праглядаць гісторыю паведамленняў на любых новых прыладах.%1$s ."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Сховішча ключоў"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Змяніць ключ аднаўлення"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Увядзіце ключ аднаўлення"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Ваша сховішча ключоў зараз не сінхранізавана."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Наладзьце аднаўленне"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Атрымайце доступ да зашыфраваных паведамленняў, калі вы страціце ўсе свае прылады або выйдзеце з сістэмы %1$s усюды."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Адкрыйце %1$s на настольнай прыладзе"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Увайдзіце ў свой уліковы запіс яшчэ раз"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Калі будзе прапанавана пацвердзіць вашу прыладу, выберыце %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Скінуць усе”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Выконвайце інструкцыі, каб стварыць новы ключ аднаўлення"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Захавайце новы ключ аднаўлення ў ме́неджэры пароляў або ў зашыфраванай нататке"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Скіньце шыфраванне для вашага ўліковага запісу з дапамогай іншай прылады"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Працягнуць скід"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Дадзеныя вашага ўліковага запісу, кантакты, налады і спіс чатаў будуць захаваны"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Вы страціце існуючую гісторыю паведамленняў"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Вам трэба будзе зноў запэўніць ўсе вашы існуючыя прылады і кантакты"</string>
|
||||
<string name="screen_encryption_reset_footer">"Працягвайце, толькі калі вы ўпэўненыя, што страцілі ўсе астатнія прылады і ключ аднаўлення."</string>
|
||||
<string name="screen_encryption_reset_title">"Скіньце ключы пацверджання, калі вы не можаце пацвердзіць яго іншым спосабам"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Адключыць"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Вы страціце зашыфраваныя паведамленні, калі выйдзеце з усіх прылад."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Вы ўпэўнены, што хочаце адключыць рэзервовае капіраванне?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Адключэнне рэзервовага капіравання прывядзе да выдалення бягучай рэзервовай копіі ключа шыфравання і адключэння іншых функцый бяспекі. У гэтым выпадку вы:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Не будзеце мець зашыфраванай гісторыі паведамленняў на новых прыладах"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Страціце доступ да зашыфраваных паведамленняў, калі вы выйдзеце з усіх сеансаў %1$s"</string>
|
||||
<string name="screen_key_backup_disable_title">"Вы ўпэўнены, што хочаце адключыць рэзервовае капіраванне?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Атрымайце новы ключ аднаўлення, калі вы страцілі існуючы. Пасля змены ключа аднаўлення ваш стары больш не будзе працаваць."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Стварыць новы ключ аднаўлення"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Ні з кім не дзяліцеся гэтым!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Ключ аднаўлення зменены"</string>
|
||||
<string name="screen_recovery_key_change_title">"Змяніць ключ аднаўлення?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Стварыць новы ключ аднаўлення"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Пераканайцеся, што ніхто не бачыць гэты экран!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Паўтарыце спробу, каб пацвердзіць доступ да сховішча ключоў."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Няправільны ключ аднаўлення"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Калі ў вас ёсць ключ аднаўлення або парольная фраза, гэта таксама будзе працаваць."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Увесці…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Страцілі ключ аднаўлення?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Ключ аднаўлення пацверджаны"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Ключ аднаўлення скапіраваны"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Стварэнне…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Захаваць ключ аднаўлення"</string>
|
||||
<string name="screen_recovery_key_save_description">"Запішыце гэты ключ аднаўлення ў бяспечным месцы, напрыклад, у менеджэры пароляў, у зашыфраванай нататцы або ў фізічным сейфе."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Націсніце, каб скапіяваць ключ аднаўлення"</string>
|
||||
<string name="screen_recovery_key_save_title">"Захавайце ключ аднаўлення"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Пасля гэтага кроку вы не зможаце атрымаць доступ да новага ключа аднаўлення."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Вы захавалі свой ключ аднаўлення?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Рэзервовая копія чата абаронена ключом аднаўлення. Калі пасля настройкі вам спатрэбіцца новы ключ аднаўлення, вы можаце стварыць яго нанова, выбраўшы \"Змяніць ключ аднаўлення\"."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Стварыце ключ аднаўлення"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Ні з кім не дзяліцеся гэтым!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Наладка аднаўлення прайшла паспяхова"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Наладзьце аднаўленне"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Так, скінуць зараз"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Гэты працэс незваротны."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Вы ўпэўнены, што хочаце скінуць шыфраванне?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Адбылася невядомая памылка. Калі ласка, праверце правільнасць пароля вашага ўліковага запісу і паўтарыце спробу."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Увесці…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Пацвердзіце, што вы хочаце скінуць шыфраванне"</string>
|
||||
<string name="screen_reset_encryption_password_title">"Каб працягнуць, увядзіце пароль уліковага запісу"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Изтриване на хранилището за ключове"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Включване на резервните копия"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Съхранявайте сигурно криптографската си самоличност и ключовете за съобщения на сървъра. Това ще ви позволи да преглеждате историята на съобщенията си на всички нови устройства.%1$s ."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Съхранение на ключове"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"За да настроите възстановяването, трябва да включите съхранението на ключове."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Разрешаване на съхранението на ключове"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Промяна на ключа за възстановяване"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Възстановете криптографската си самоличност и историята на съобщенията с ключ за възстановяване, ако сте загубили всичките си съществуващи устройства."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Въвеждане на ключ за възстановяване"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Хранилището ви за ключове в момента не е синхронизирано."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Изключване"</string>
|
||||
<string name="screen_key_backup_disable_description">"Изтриването на хранилището за ключове ще премахне вашата криптографска самоличност и ключове за съобщения от сървъра и ще изключи следните функции за сигурност:"</string>
|
||||
<string name="screen_key_backup_disable_title">"Сигурни ли сте, че искате да изключите хранилището на ключове и да го изтриете?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Вземете нов ключ за възстановяване, ако сте загубили съществуващия си. След като промените ключа си за възстановяване, старият ви вече няма да работи."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Генериране на нов ключ за възстановяване"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Не споделяйте това с никого!"</string>
|
||||
<string name="screen_recovery_key_change_title">"Промяна на ключа за възстановяване?"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Уверете се, че никой не може да види този екран!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Моля, опитайте отново, за да потвърдите достъпа до хранилището за ключове."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Неправилен ключ за възстановяване"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Ако имате ключ за сигурност или фраза за сигурност, това също ще работи."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Въведете…"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Ключът за възстановяване е потвърден"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Въведете ключа си за възстановяване"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Копиран ключ за възстановяване"</string>
|
||||
<string name="screen_recovery_key_save_action">"Запазване на ключа за възстановяване"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Вашето хранилище за ключове е защитено с ключ за възстановяване. Ако имате нужда от нов ключ за възстановяване след настройката, можете да го създадете отново, като изберете „Промяна на ключа за възстановяване“."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Не споделяйте това с никого!"</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Въведете…"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Vypnout zálohování"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Zapnout zálohování"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Bezpečně uložte svou kryptografickou identitu a klíče zpráv na serveru. To vám umožní zobrazit historii zpráv na všech nových zařízeních. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Úložiště klíčů"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Pro nastavení obnovení musí být zapnuto úložiště klíčů."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Nahrát klíče z tohoto zařízení"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Povolit ukládání klíčů"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Změnit klíč pro obnovení"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Obnovte svou kryptografickou identitu a historii zpráv pomocí klíče pro obnovení, pokud jste ztratili všechna stávající zařízení."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Zadejte klíč pro obnovení"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Vaše úložiště klíčů je momentálně nesynchronizované."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Nastavení obnovy"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Získejte přístup ke svým zašifrovaným zprávám, pokud ztratíte všechna zařízení nebo jste všude odhlášeni z %1$s."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Otevřít %1$s na stolním počítači"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Znovu se přihlaste ke svému účtu"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Když budete vyzváni k ověření vašeho zařízení, vyberte %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"\"Resetovat vše\""</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Postupujte podle pokynů k vytvoření nového obnovovacího klíče"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Uložte nový klíč pro obnovení do správce hesel nebo do zašifrované poznámky"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Obnovte šifrování účtu pomocí jiného zařízení"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Pokračovat v resetování"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Podrobnosti o vašem účtu, kontaktech, preferencích a seznamu chatu budou zachovány"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Ztratíte svou stávající historii zpráv"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Budete muset znovu ověřit všechna stávající zařízení a kontakty"</string>
|
||||
<string name="screen_encryption_reset_footer">"Obnovte svou identitu pouze v případě, že nemáte přístup k jinému přihlášenému zařízení a ztratili jste klíč pro obnovení."</string>
|
||||
<string name="screen_encryption_reset_title">"Obnovte svou identitu v případě, že nemůžete potvrdit jiným způsobem"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Vypnout"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Pokud se odhlásíte ze všech zařízení, přijdete o zašifrované zprávy."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Opravdu chcete vypnout zálohování?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Vypnutím zálohování odstraníte zálohu aktuálního šifrovacího klíče a vypnete další bezpečnostní funkce. V tomto případě budete:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Nemít v nových zařízeních šifrovanou historii zpráv"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Ztratíte přístup k šifrovaným zprávám, pokud jste všude odhlášeni z %1$s"</string>
|
||||
<string name="screen_key_backup_disable_title">"Opravdu chcete vypnout zálohování?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Získejte nový klíč pro obnovení, pokud jste ztratili stávající klíč. Po změně klíče pro obnovení již váš starý klíč nebude fungovat."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Vygenerovat nový klíč pro obnovení"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Toto s nikým nesdílejte!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Klíč pro obnovení byl změněn"</string>
|
||||
<string name="screen_recovery_key_change_title">"Změnit klíč pro obnovení?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Vytvořit nový klíč pro obnovení"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Ujistěte se, že tuto obrazovku nikdo nevidí!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Zkuste prosím znovu potvrdit přístup k úložišti klíčů."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Nesprávný klíč pro obnovení"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Pokud máte bezpečnostní klíč nebo bezpečnostní frázi, bude to fungovat také."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Zadejte…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Ztratili jste klíč pro obnovení?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Klíč pro obnovení potvrzen"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Zadejte klíč pro obnovení"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Klíč pro obnovení zkopírován"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Generování…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Uložit klíč pro obnovení"</string>
|
||||
<string name="screen_recovery_key_save_description">"Zapište si tento obnovovací klíč na bezpečné místo, jako je správce hesel, zašifrovaná poznámka nebo fyzický trezor."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Klepnutím zkopírujte klíč pro obnovení"</string>
|
||||
<string name="screen_recovery_key_save_title">"Uložte si klíč pro obnovení"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Po tomto kroku nebudete mít přístup k novému klíči pro obnovení."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Uložili jste si klíč pro obnovení?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Záloha chatu je chráněna klíčem pro obnovení. Pokud potřebujete nový klíč pro obnovení po nastavení, můžete jej znovu vytvořit výběrem možnosti „Změnit klíč pro obnovení“."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Vygenerovat klíč pro obnovení"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Toto s nikým nesdílejte!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Nastavení obnovení bylo úspěšné"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Nastavení obnovy"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Ano, resetovat nyní"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Tento proces je nevratný."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Opravdu chcete obnovit svou identitu?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Došlo k neznámé chybě. Zkontrolujte, zda je heslo k účtu správné a zkuste to znovu."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Zadejte…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Potvrďte, že chcete obnovit svou identitu."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Pro pokračování zadejte heslo k účtu"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Dileu storfa allweddi"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Trowch y copi wrth gefn ymlaen"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Cadwch eich hunaniaeth cryptograffig a\'ch allweddi neges yn ddiogel ar y gweinydd. Bydd hyn yn caniatáu ichi weld hanes eich neges ar unrhyw ddyfeisiau newydd. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Storio allweddi"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Rhaid troi storio allweddi ymlaen i osod adferiad."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Llwythwch allweddi i fyny o\'r ddyfais hon"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Caniatáu storio allweddi"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Newid yr allwedd adfer"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Adferwch eich hunaniaeth cryptograffig a hanes negeseuon gydag allwedd adfer os ydych chi wedi colli\'ch holl ddyfeisiau presennol."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Rhowch eich allwedd adfer"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Nid yw eich storfa allweddi wedi\'i chydweddu ar hyn o bryd."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Gosod adfer"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Cael mynediad i\'ch negeseuon wedi\'u hamgryptio os byddwch yn colli\'ch holl ddyfeisiau neu\'n cael eich allgofnodi o %1$s ym mhobman."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Agor %1$s mewn dyfais bwrdd gwaith"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Mewngofnodwch i\'ch cyfrif eto"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Pan fydd gofyn i chi ddilysu\'ch dyfais, dewiswch %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Ailosod y cyfan“"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Dilynwch y cyfarwyddiadau i greu allwedd adfer newydd"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Cadwch eich allwedd adfer newydd mewn rheolwr cyfrinair neu mewn nodyn wedi\'i amgryptio"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Ailosodwch yr amgryptio ar gyfer eich cyfrif gan ddefnyddio dyfais arall"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Parhau i ailosod"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Bydd manylion eich cyfrif, eich cysylltiadau, eich dewisiadau a\'ch rhestr sgwrsio yn cael eu cadw"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Byddwch yn colli unrhyw hanes neges sydd wedi\'i gadw dim ond ar y gweinydd"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Bydd angen i chi wirio\'ch holl ddyfeisiau a chysylltiadau presennol eto"</string>
|
||||
<string name="screen_encryption_reset_footer">"Ailosodwch eich hunaniaeth dim ond os nad oes gennych fynediad i ddyfais arall sydd wedi\'i mewngofnodi a\'ch bod wedi colli\'ch allwedd adfer."</string>
|
||||
<string name="screen_encryption_reset_title">"Methu cadarnhau? Bydd angen i chi ailosod eich hunaniaeth."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Diffodd"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Byddwch yn colli eich negeseuon wedi\'u hamgryptio os ydych wedi\'ch allgofnodi o bob dyfais."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Ydych chi\'n siŵr eich bod am ddiffodd copi wrth gefn?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Bydd dileu storfa allweddi\'n tynnu eich hunaniaeth cryptograffig a\'ch allweddi neges o\'r gweinydd ac yn diffodd y nodweddion diogelwch canlynol:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Bydd gennych chi ddim hanes negeseuon wedi\'i amgryptio ar ddyfeisiau newydd"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Byddwch yn colli mynediad i\'ch negeseuon wedi\'u hamgryptio os ydych wedi\'ch allgofnodi o %1$s ym mhobman"</string>
|
||||
<string name="screen_key_backup_disable_title">"Ydych chi\'n siŵr eich bod am ddiffodd storfa allweddi a\'i dileu?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Cael allwedd adfer newydd os ydych chi wedi colli\'ch un presennol. Ar ôl newid eich allwedd adfer, fydd eich hen un ddim yn gweithio mwyach."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Cynhyrchu allwedd adfer newydd"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Peidiwch â rhannu hwn gyda neb!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Newidwyd yr allwedd adfer"</string>
|
||||
<string name="screen_recovery_key_change_title">"Newid yr allwedd adfer?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Creu allwedd adfer newydd"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Gwnewch yn siŵr nad oes neb yn gallu gweld y sgrin hon!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Ceisiwch eto i gadarnhau mynediad i\'ch storfa allweddi."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Allwedd adfer anghywir"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Os oes gennych allwedd ddiogelwch neu ymadrodd diogelwch, bydd hyn yn gweithio hefyd."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Rhowch…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Wedi colli eich allwedd adfer?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Wedi cadarnhau\'r allwedd adfer"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Rhowch eich allwedd adfer"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Allwedd adfer wedi\'i chopïo"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Yn cynhyrchu…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Cadw allwedd adfer"</string>
|
||||
<string name="screen_recovery_key_save_description">"Ysgrifennwch yr allwedd adfer hon yn rhywle diogel, fel rheolwr cyfrinair, nodyn wedi\'i amgryptio, neu mewn man dan glo."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Tapiwch i gopïo\'r allwedd adfer"</string>
|
||||
<string name="screen_recovery_key_save_title">"Cadwch eich allwedd adfer yn rhywle diogel"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Fyddwch chi ddim yn gallu cyrchu\'ch allwedd adfer newydd ar ôl y cam hwn."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Ydych chi wedi cadw\'ch allwedd adfer?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Mae eich storfa allweddi wedi\'i diogelu gan allwedd adfer. Os oes angen allwedd adfer newydd arnoch ar ôl gosod, gallwch ei hail-greu trwy ddewis \'Newid allwedd adfer\'."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Cynhyrchwch eich allwedd adfer"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Peidiwch â rhannu hwn gyda neb!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Llwyddiant wrth osod adferiad"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Gosod adfer"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Iawn, ailosod nawr"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Does dim posib dadwneud y broses hon."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Ydych chi\'n siŵr eich bod am ailosod eich hunaniaeth?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Digwyddodd gwall anhysbys. Gwiriwch fod cyfrinair eich cyfrif yn gywir a cheisio eto."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Rhowch…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Cadarnhewch eich bod am ailosod eich hunaniaeth."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Rhowch eich cyfrinair cyfrif i barhau"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Slet nøglelager"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Aktivér sikkerhedskopiering"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Gem din kryptografiske identitet og meddelelsesnøgler sikkert på serveren. Dette giver dig mulighed for at se din meddelelseshistorik på alle nye enheder. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Nøgleopbevaring"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Nøglelagring skal være slået til for at konfigurere gendannelse."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Upload nøgler fra denne enhed"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Tillad lagring af nøgler"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Skift gendannelsesnøgle"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Gendan din kryptografiske identitet og beskedhistorik med en gendannelsesnøgle, hvis du har mistet alle dine eksisterende enheder."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Indtast gendannelsesnøgle"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Din nøglelagring er i øjeblikket ikke synkroniseret."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Opsæt gendannelse"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Få adgang til dine krypterede meddelelser, hvis du mister alle dine enheder eller er logget ud af %1$s overalt."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Åbn %1$s på en stationær enhed"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Log ind på din konto igen"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Når du bliver bedt om at verificere din enhed, skal du vælge %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"\"Nulstil alle\""</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Følg instruktionerne for at oprette en ny gendannelsesnøgle"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Gem din nye gendannelsesnøgle i en adgangskodeadministrator eller i en krypteret note"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Nulstil krypteringen for din konto ved hjælp af en anden enhed"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Fortsæt nulstilling"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Dine kontodetaljer, kontakter, personlige indstilliger og samtaler vil blive gemt"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Du mister al beskedhistorik, der kun er gemt på serveren."</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Du bliver nødt til at verificere alle dine eksisterende enheder og kontakter påny"</string>
|
||||
<string name="screen_encryption_reset_footer">"Nulstil kun din identitet, hvis du ikke har adgang til en anden enhed, der er logget ind, og du har mistet din gendannelsesnøgle."</string>
|
||||
<string name="screen_encryption_reset_title">"Kan du ikke bekræfte? Du skal nulstille din identitet."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Slå fra"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Du mister dine krypterede meddelelser, hvis du er logget ud af alle enheder."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Er du sikker på, at du vil slå sikkerhedskopiering fra?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Hvis du sletter nøglelageret, fjernes din kryptografiske identitet og meddelelsesnøgler fra serveren og følgende sikkerhedsfunktioner deaktiveres:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Du vil ikke kunne se historikken for krypterede beskeder på nye enheder"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Du mister adgangen til dine krypterede meddelelser, hvis du er logget ud %1$s overalt"</string>
|
||||
<string name="screen_key_backup_disable_title">"Er du sikker på, at du vil deaktivere nøglelagring og slette lageret?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Få en ny gendannelsesnøgle, hvis du har mistet din eksisterende. Når du har ændret din gendannelsesnøgle, fungerer din gamle ikke længere."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Generer en ny gendannelsesnøgle"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Del ikke dette med nogen!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Gendannelsesnøgle ændret"</string>
|
||||
<string name="screen_recovery_key_change_title">"Skift gendannelsesnøgle?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Opret ny gendannelsesnøgle"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Sørg for, at ingen kan se denne skærm!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Prøv igen for at bekræfte adgangen til dit nøglelager."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Forkert gendannelsesnøgle"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Hvis du har en sikkerhedsnøgle eller sikkerhedssætning, kan en af dem også bruges."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Indtast…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Mistet din gendannelsesnøgle?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Gendannelsesnøgle bekræftet"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Indtast din gendannelsesnøgle"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Kopieret gendannelsesnøgle"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Genererer…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Gem gendannelsesnøgle"</string>
|
||||
<string name="screen_recovery_key_save_description">"Skriv denne gendannelsesnøgle et sikkert sted, som en adgangskodeadministrator, en krypteret note eller på papir, som du lægger i et fysisk pengeskab."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Tryk for at kopiere gendannelsesnøglen"</string>
|
||||
<string name="screen_recovery_key_save_title">"Gem din gendannelsesnøgle et sikkert sted"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Du vil ikke kunne få adgang til din nye gendannelsesnøgle efter dette trin."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Har du gemt din gendannelsesnøgle?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Din nøglelager er beskyttet af en gendannelsesnøgle. Hvis du har brug for en ny gendannelsesnøgle efter installationen, kan du oprette den ved at vælge \'Skift gendannelsesnøgle\'."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Generer din gendannelsesnøgle"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Del ikke dette med nogen!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Opsætning af gendannelse lykkedes"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Opsæt gendannelse"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Ja, nulstil nu"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Denne proces er irreversibel."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Er du sikker på, at du ønsker at nulstille din identitet?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Der opstod en ukendt fejl. Kontroller, at adgangskoden til din konto er korrekt, og prøv igen."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Indtast…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Bekræft, at du ønsker at nulstille din identitet."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Indtast adgangskoden til din konto for at fortsætte"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Backup deaktivieren"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Backup aktivieren"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Speichere deine kryptographische Identität und die Nachrichtenschlüssel auf dem Server. Auf diese Weise kannst du deinen Nachrichtenverlauf auf neuen Geräten einsehen. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Schlüsselspeicher"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Der Schlüsselspeicher muss aktiviert sein, um Datenwiederherstellung zu ermöglichen."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Schlüssel von diesem Gerät hochladen"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Schlüsselspeicherung zulassen"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Wiederherstellungsschlüssel ändern"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Stelle deine kryptographische Identität und deinen Nachrichtenverlauf mit einem Wiederherstellungsschlüssel wieder her, falls du deine Geräte verloren hast."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Wiederherstellungsschlüssel eingeben"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Dein Schlüssel ist derzeit nicht synchronisiert."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Wiederherstellung einrichten"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Erhalte Zugriff auf deine verschlüsselten Nachrichten, wenn du alle deine Geräte verloren hast oder überall von %1$s abgemeldet bist."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">
|
||||
"Öffne "
|
||||
<b>"%1$s"</b>
|
||||
" auf einem "
|
||||
<b>"Desktop-Gerät"</b>
|
||||
</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Melde dich erneut bei deinem Konto an"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Bei der Aufforderung, dein Gerät zu verifizieren, wähle %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"Alles zurücksetzen"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Folge den Anweisungen, um einen neuen Wiederherstellungsschlüssel zu erstellen"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Verwahre deinen neuen Wiederherstellungsschlüssel in einem Passwortmanager oder einer verschlüsselten Datei"</string>
|
||||
<string name="screen_create_new_recovery_key_title">
|
||||
"Erstelle einen neuen "
|
||||
<b>"Wiederherstellungsschlüssel"</b>
|
||||
" mit einem anderen Gerät"
|
||||
</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Zurücksetzen fortsetzen"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Deine Kontodaten, Kontakte, Einstellungen und die Liste der Chats bleiben erhalten"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Du verlierst alle bisherigen Nachrichten, wenn sie ausschließlich auf dem Server gespeichert sein sollten."</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Du musst alle deine bestehenden Geräte und Kontakte erneut verifizieren."</string>
|
||||
<string name="screen_encryption_reset_footer">"Setze deine Identität nur dann zurück, wenn du keinen Zugriff mehr auf ein anderes angemeldetes Gerät hast und auch deinen Wiederherstellungsschlüssel verloren hast."</string>
|
||||
<string name="screen_encryption_reset_title">"Bestätigung unmöglich? Dann musst du deine Identität zurücksetzen."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Ausschalten"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Du verlierst deine verschlüsselten Nachrichten, wenn du auf allen Geräten abgemeldet bist."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Bist du sicher, dass du das Backup deaktivieren willst?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Das Löschen des Schlüsselspeichers entfernt deine kryptografische Identität und deine Nachrichtenschlüssel vom Server. Die folgenden Sicherheitsfunktionen werden deaktiviert:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Kein Nachrichtenverlauf für verschlüsselte Nachrichten auf neuen Geräten"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Kein Zugriff auf verschlüsselten Nachrichten, wenn du überall von %1$s abgemeldet bist"</string>
|
||||
<string name="screen_key_backup_disable_title">"Möchtest du die Speicherung der Schlüssel wirklich deaktivieren und entfernen?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Erhalte einen neuen Wiederherstellungsschlüssel wenn du deinen bisherigen verloren hast. Danach funktioniert dein alter Schlüssel nicht mehr."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Wiederherstellungsschlüssel erstellen"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Teile das mit niemandem!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Wiederherstellungsschlüssel geändert"</string>
|
||||
<string name="screen_recovery_key_change_title">"Wiederherstellungsschlüssel ändern?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Neuen Wiederherstellungsschlüssel erstellen"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Sorge dafür, dass niemand diesen Bildschirm sehen kann!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Bitte versuche erneut, den Zugriff auf deinen Schlüsselspeicher zu bestätigen."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Falscher Wiederherstellungsschlüssel"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Dies funktioniert auch mit einem Sicherheitsschlüssel oder Sicherheitsphrase."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Eingeben…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Wiederherstellungschlüssel vergessen?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Wiederherstellungsschlüssel bestätigt"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Gib deinen Wiederherstellungsschlüssel ein"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Wiederherstellungsschlüssel kopiert"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Generieren…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Wiederherstellungsschlüssel speichern"</string>
|
||||
<string name="screen_recovery_key_save_description">"Bewahre den Wiederherstellungsschlüssel an einer sicheren Stelle auf, wie zum Beispiel in einem Passwort-Manager, in einer verschlüsselten Datei oder in einem Safe. "</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Tippe, um den Wiederherstellungsschlüssel zu kopieren"</string>
|
||||
<string name="screen_recovery_key_save_title">"Speichere deinen Wiederherstellungsschlüssel"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Nach diesem Schritt kannst du nicht mehr auf deinen neuen Wiederherstellungsschlüssel zugreifen."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Hast du deinen Wiederherstellungsschlüssel gespeichert?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Dein Schlüsselspeicher wird durch einen Wiederherstellungsschlüssel geschützt. Wenn du nach der Einrichtung einen neuen Wiederherstellungsschlüssel benötigst, kannst du durch Auswahl von „Wiederherstellungsschlüssel ändern“ einen neuen erzeugen."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Wiederherstellungsschlüssel erstellen"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Teile das mit niemandem!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Einrichtung der Wiederherstellung erfolgreich"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Wiederherstellung einrichten"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Ja, zurücksetzen"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Das Zurücksetzen kann nicht rückgängig gemacht werden."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Bist du sicher, dass du deine Identität zurücksetzen möchtest?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Es ist ein unbekannter Fehler aufgetreten. Bitte überprüfe das Passwort deines Kontos und versuche es erneut."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Eingeben…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Bestätige, dass du deine Identität zurücksetzen möchtest."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Gib dein Passwort ein, um fortzufahren"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Απενεργοποίηση αντιγράφων ασφαλείας"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Ενεργοποίηση αντιγράφων ασφαλείας"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Αποθήκευσε την κρυπτογραφική σου ταυτότητα και τα κλειδιά μηνυμάτων με ασφάλεια στον διακομιστή. Αυτό θα σου επιτρέψει να δεις το ιστορικό μηνυμάτων σου σε οποιεσδήποτε νέες συσκευές. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Χώρος αποθήκευσης κλειδιού"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Η αποθήκευση κλειδιών πρέπει να είναι ενεργοποιημένη για να ρυθμίσεις την ανάκτηση."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Μεταφόρτωση κλειδιών από αυτήν τη συσκευή"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Να επιτρέπεται η αποθήκευση κλειδιών"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Αλλαγή κλειδιού ανάκτησης"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Ανάκτησε την κρυπτογραφική σου ταυτότητα και το ιστορικό μηνυμάτων με ένα κλειδί ανάκτησης εάν έχεις χάσει όλες τις υπάρχουσες συσκευές σου."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Εισαγωγή κλειδιού ανάκτησης"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Ο αποθηκευτικός χώρος κλειδιών σου δεν είναι συγχρονισμένος αυτήν τη στιγμή."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Ρύθμιση ανάκτησης"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Απόκτησε πρόσβαση στα κρυπτογραφημένα σου μηνύματα εάν χάσεις όλες τις συσκευές σου ή έχεις αποσυνδεθεί από το %1$s παντού."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Άνοιγμα %1$s σε συσκευή υπολογιστή"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Συνδέσου ξανά στο λογαριασμό σου"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Όταν σου ζητηθεί να επαληθεύσεις τη συσκευή σου, επέλεξε %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"«Επαναφορά όλων»"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Ακολούθησε τις οδηγίες για να δημιουργήσεις ένα νέο κλειδί ανάκτησης"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Αποθήκευσε το νέο κλειδί ανάκτησης σε έναν διαχειριστή κωδικών πρόσβασης ή σε κρυπτογραφημένη σημείωση"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Επανάφερε την κρυπτογράφηση για το λογαριασμό σου χρησιμοποιώντας άλλη συσκευή"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Συνέχιση επαναφοράς"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Τα στοιχεία του λογαριασμού σου, οι επαφές, οι προτιμήσεις και η λίστα συνομιλιών θα διατηρηθούν"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Θα χάσεις το υπάρχον ιστορικό μηνυμάτων σου"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Θα χρειαστεί να επαληθεύσεις ξανά όλες τις υπάρχουσες συσκευές και επαφές σου"</string>
|
||||
<string name="screen_encryption_reset_footer">"Επανάφερε την ταυτότητά σου μόνο εάν δεν έχεις πρόσβαση σε άλλη συνδεδεμένη συσκευή και έχεις χάσει το κλειδί ανάκτησης."</string>
|
||||
<string name="screen_encryption_reset_title">"Δεν μπορείς να επιβεβαιώσεις; Θα χρειαστεί να επαναφέρεις την ταυτότητά σου."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Απενεργοποίηση"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Θα χάσεις τα κρυπτογραφημένα μηνύματά σου εάν αποσυνδεθείς από όλες τις συσκευές."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Σίγουρα θες να απενεργοποιήσεις τα αντίγραφα ασφαλείας;"</string>
|
||||
<string name="screen_key_backup_disable_description">"Η απενεργοποίηση του αντιγράφου ασφαλείας θα καταργήσει το τρέχον αντίγραφο ασφαλείας κλειδιού κρυπτογράφησης και θα απενεργοποιήσει άλλες δυνατότητες ασφαλείας. Σε αυτή την περίπτωση, θα:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Να μην έχεις κρυπτογραφημένο ιστορικό μηνυμάτων στις νέες συσκευές"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Χάσεις την πρόσβαση στα κρυπτογραφημένα μηνύματά σου εάν είσαι αποσυνδεδεμένος από %1$s παντού"</string>
|
||||
<string name="screen_key_backup_disable_title">"Σίγουρα θες να απενεργοποιήσεις τα αντίγραφα ασφαλείας;"</string>
|
||||
<string name="screen_recovery_key_change_description">"Απόκτησε ένα νέο κλειδί ανάκτησης εάν έχεις χάσει το υπάρχον. Αφού αλλάξεις το κλειδί ανάκτησης, το παλιό δεν θα λειτουργεί πλέον."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Δημιουργία νέου κλειδιού ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Μην το μοιραστείς με κανέναν!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Το κλειδί ανάκτησης άλλαξε"</string>
|
||||
<string name="screen_recovery_key_change_title">"Αλλαγή κλειδιού ανάκτησης;"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Δημιουργία νέου κλειδιού ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Βεβαιώσου ότι κανείς δεν μπορεί να δει αυτήν την οθόνη!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Προσπάθησε ξανά για να επιβεβαιώσεις την πρόσβαση στον αποθηκευτικό χώρο κλειδιών σου."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Λανθασμένο κλειδί ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Εάν έχεις ένα κλειδί ασφαλείας ή μια φράση ασφαλείας, θα λειτουργήσει επίσης."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Εισαγωγή…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Έχασες το κλειδί ανάκτησης;"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Επιβεβαιώθηκε το κλειδί ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Εισήγαγε το κλειδί ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Αντιγράφηκε το κλειδί ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Δημιουργία…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Αποθήκευση κλειδιού ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_save_description">"Γράψε αυτό το κλειδί ανάκτησης κάπου ασφαλές, όπως έναν διαχειριστή κωδικών πρόσβασης, μια κρυπτογραφημένη σημείωση ή ένα φυσικό χρηματοκιβώτιο."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Πάτα για να αντιγράψεις το κλειδί ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_save_title">"Αποθήκευσε το κλειδί ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Δεν θα μπορείς να αποκτήσεις πρόσβαση στο νέο κλειδί ανάκτησης μετά από αυτό το βήμα."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Έχεις αποθηκεύσει το κλειδί ανάκτησης;"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Το αντίγραφο ασφαλείας της συνομιλίας σου προστατεύεται από ένα κλειδί ανάκτησης. Εάν χρειαστείς ένα νέο κλειδί ανάκτησης μετά την εγκατάσταση, μπορείς να δημιουργήσεις ξανά επιλέγοντας «Αλλαγή κλειδιού ανάκτησης»."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Δημιουργία κλειδιού ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Μην το μοιραστείς με κανέναν!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Επιτυχής ρύθμιση ανάκτησης"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Ρύθμιση ανάκτησης"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Ναι, επαναφορά τώρα"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Η διαδικασία είναι μη αναστρέψιμη."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Σίγουρα θες να επαναφέρεις την ταυτότητά σου;"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Συνέβη ένα άγνωστο σφάλμα. Έλεγξε ότι ο κωδικός πρόσβασης του λογαριασμού σου είναι σωστός και δοκίμασε ξανά."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Εισαγωγή…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Επιβεβαίωσε ότι θες να επαναφέρεις την ταυτότητά σου."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Εισήγαγε τον κωδικό πρόσβασης του λογαριασμού σου για να συνεχίσεις"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Borrar almacén de claves"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Activar copia de seguridad"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Almacena tu identidad criptográfica y las claves de tus mensajes de forma segura en el servidor. Esto te permitirá ver tu historial de mensajes en cualquier dispositivo nuevo. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Almacenamiento de claves"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"El almacenamiento de claves debe estar activado para configurar la recuperación."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Subir claves desde este dispositivo"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Permitir almacenamiento de claves"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Cambiar la clave de recuperación"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Recupera tu identidad criptográfica y tu historial de mensajes con una clave de recuperación si has perdido todos tus dispositivos actuales."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Introduce la clave de recuperación"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Tu almacén de claves no está sincronizado actualmente."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Configurar la recuperación"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Accede a tus mensajes cifrados si pierdes todos tus dispositivos o cierras sesión de %1$s en cualquier lugar."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Abre %1$s en un dispositivo de escritorio"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Vuelve a iniciar sesión en tu cuenta"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Cuando se te pida que verifiques tu dispositivo, selecciona %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"«Restablecer todo»"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Sigue las instrucciones para crear una nueva clave de recuperación"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Guarda tu nueva clave de recuperación en un administrador de contraseñas o en una nota cifrada"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Restablece el cifrado de tu cuenta usando otro dispositivo"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Continuar con el restablecimiento"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Se conservarán los detalles de tu cuenta, tus contactos, tus preferencias y tu lista de chats"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Perderás cualquier historial de mensajes que solo esté almacenado en el servidor"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Tendrás que verificar de nuevo todos tus dispositivos y contactos existentes"</string>
|
||||
<string name="screen_encryption_reset_footer">"Restablece tu identidad solo si no tienes acceso a otro dispositivo en el que hayas iniciado sesión y has perdido tu clave de recuperación."</string>
|
||||
<string name="screen_encryption_reset_title">"¿No puedes confirmar? Tendrás que restablecer tu identidad."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Desactivar"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Perderás tus mensajes cifrados si cierras sesión en todos los dispositivos."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"¿Estás seguro de que quieres desactivar la copia de seguridad?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Al borrar el almacén de claves, se eliminarán del servidor tu identidad criptográfica y claves de los mensajes, y se desactivarán las siguientes funciones de seguridad:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"No tendrás un historial de mensajes cifrados en nuevos dispositivos"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Perderás el acceso a tus mensajes cifrados si cierras sesión en %1$s en todas partes"</string>
|
||||
<string name="screen_key_backup_disable_title">"¿Estás seguro de que quieres desactivar el almacenamiento de claves y borrarlo?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Obtén una nueva clave de recuperación si has perdido la que tenías. Después de cambiar la clave de recuperación, la anterior dejará de funcionar."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Generar una nueva clave de recuperación"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"¡No la compartas con nadie!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Clave de recuperación cambiada"</string>
|
||||
<string name="screen_recovery_key_change_title">"¿Cambiar la clave de recuperación?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Crear nueva clave de recuperación"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"¡Asegúrate de que nadie pueda ver esta pantalla!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Inténtalo de nuevo para confirmar el acceso a tu almacén de claves."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Clave de recuperación incorrecta"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Si tienes una clave o frase de seguridad, también funcionará."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Introducir…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"¿Perdiste tu clave de recuperación?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Clave de recuperación confirmada"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Introduce tu clave de recuperación"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Clave de recuperación copiada"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Generando…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Guardar clave de recuperación"</string>
|
||||
<string name="screen_recovery_key_save_description">"Anota esta clave de recuperación en un lugar seguro, como un administrador de contraseñas, una nota cifrada o una caja fuerte física."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Pulsa para copiar la clave de recuperación"</string>
|
||||
<string name="screen_recovery_key_save_title">"Guardar tu clave de recuperación"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"No podrás acceder a tu nueva clave de recuperación después de este paso."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"¿Has guardado tu clave de recuperación?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Tu almacén de claves está protegido por una clave de recuperación. Si necesitas una nueva clave de recuperación después de la configuración, puedes volver a crearla seleccionando «Cambiar la clave de recuperación»."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Generar tu clave de recuperación"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"¡No la compartas con nadie!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Configuración de recuperación terminada"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Configurar la recuperación"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Sí, restablecer ahora"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Este proceso es irreversible."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"¿Estás seguro de que quieres restablecer tu identidad?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Se ha producido un error desconocido. Comprueba que la contraseña de tu cuenta sea correcta y vuelve a intentarlo."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Introducir…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Confirma que quieres restablecer tu identidad."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Introduce la contraseña de tu cuenta para continuar"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Lülita võtmete varundamine välja"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Lülita võtmete varundamine sisse"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Salvesta oma krüptoidentiteet ja sõnumite krüptovõtmed turvaliselt serveris. See tagab, et sinu sõnumite ajalugu on alati loetav, ka kõikides uutes seadmetes. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Krüptovõtmete varundus"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Taastamise seadistamiseks peab võtmehoidla olema sisselülitatud."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Laadi siin seadmes leiduvad võtmed üles"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Luba krüptovõtmete salvestamine"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Muuda taastevõtit"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Kui sa oled kaotanud ligipääsu kõikidele oma olemasolevatele seadmetele, siis sa saad taastevõtme abil taastada ligipääsu oma krüptoidentiteedile ja sõnumite ajaloole."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Sisesta taastevõti"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Sinu krüptovõtmete varundus pole hetkel enam sünkroonis."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Seadista andmete taastamine"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Säilita ligipääs oma krüptitud sõnumitele ka siis, kui sa kaotad kõik oma seadmed ja/või logid kõikjal välja rakendusest %1$s."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Ava %1$s töölauaga seadmes"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Logi uuesti sisse oma kasutajakontole"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Kui sul palutakse seadet verifitseerida, vali %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"„Lähtesta kõik“"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Uue taastevõtme loomiseks palun järgi juhendit"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Salvesta oma uus taastevõti kas salasõnahalduris, krüptitud failis või mõnel muul turvalisel viisil"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Lähtesta oma konto krüptimine mõnest muust oma seadmest"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Jätka lähtestamisega"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Sinu kasutajakonto andmed, kontaktid, eelistused ja vestluste loend säiluvad"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Sa kaotad seniste sõnumite ajaloo"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Sa pead kõik oma olemasolevad seadmed ja kontaktid uuesti verifitseerima"</string>
|
||||
<string name="screen_encryption_reset_footer">"Lähtesta oma identiteet vaid siis, kui sul pole ligipääsu mitte ühelegi oma seadmele ja sa oled kaotanud oma taastevõtme."</string>
|
||||
<string name="screen_encryption_reset_title">"Kui sa ühtegi muud võimalust ei leia, siis lähtesta oma identiteet."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Lülita välja"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Kui sa logid välja kõikidest oma seadmetest, siis sa kaotad ligipääsu oma krüptitud sõnumitele."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Kas sa oled kindel, et soovid varukoopiate tegemise välja lülitada?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Varunduse väljalülitamisel kustutatakse hetkel olemasolev sinu krüptovõtmete varukoopia ning lülituvad välja veel mõned turvafunktsionaalsused. Sellisel juhul sul:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"sul ei ole krüptitud sõnumite ajalugu uutes seadmetes"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"sa kaotad ligipääsu oma krüptitud sõnumitele, kui sa logid kõikjal välja rakendusest %1$s"</string>
|
||||
<string name="screen_key_backup_disable_title">"Kas sa oled kindel, et soovid varunduse välja lülitada?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Kui oled vana taastevõtme kaotanud, siis loo uus. Peale seda muudatust vana taastevõti enam ei tööta."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Loo uus taastevõti"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Ära jaga seda kellegagi"</string>
|
||||
<string name="screen_recovery_key_change_success">"Taastevõti on muudetud"</string>
|
||||
<string name="screen_recovery_key_change_title">"Kas muudame taastevõtme?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Loo uus taastevõti"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Palun vaata, et keegi teine ei näeks seda ekraanivaadet!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Kinnitamaks ligipääsu sinu krüptovõtmete varundusele, palun proovi uuesti"</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Vigane taastevõti"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Kui sul on turvavõti või turvafraas, siis need toimivad ka."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Sisesta…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Kas sa oled taastevõtme kaotanud?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Taastevõti on kinnitatud"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Sisesta oma taastevõti"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Taastevõti on kopeeritud lõikelauale"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Loome…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Salvesta taastevõti"</string>
|
||||
<string name="screen_recovery_key_save_description">"Palun märgi taastevõti üles ja hoia seda turvaliselt, näiteks digitaalses salasõnalaekas, krüptitud märkmetes või vana kooli seifis."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Taastevõtme kopeerimiseks puuduta"</string>
|
||||
<string name="screen_recovery_key_save_title">"Salvesta oma taastevõti"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Peale seda sammu sul pole enam ligipääsu oma taastevõtmele."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Kas sa oled oma taastevõtme talletanud?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Sinu vestluste varundus on krüptitud taastevõtmega. Kui peale muutusi peaks vaja olema uut taastevõtit, siis palun kasuta valikut „Loo taastevõti“"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Loo oma taastevõti"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Ära jaga seda kellegagi"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Andmete taastamise seadistamine õnnestus"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Seadista andmete taastamine"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Jah, lähtesta nüüd"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"See tegevus on tagasipöördumatu."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Kas sa oled kindel, et soovid oma andmete krüptimist lähtestada?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Tekkis teadmata viga. Palun kontrolli, kas sinu kasutajakonto salasõna on õige ja proovi uuesti."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Sisesta…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Palun kinnita, et soovid oma andmete krüptimist lähtestada."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Jätkamaks sisesta oma kasutajakonto salasõna"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Ezabatu gakoen biltegia"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Aktibatu babeskopia"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Gorde zure identitate-kriptografikoa eta mezuen gakoak modu seguruan zerbitzarian. Horrek zure mezuen historia edozein gailu berritan ikusteko aukera emango dizu. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Gakoen biltegiratzea"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Aldatu berreskuratze-gakoa"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Sartu berreskuratze-gakoa"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Zure giltzen-biltegiratzea gaur-gaurkoz sinkronizatu gabe dago."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Konfiguratu berreskurapena"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Ireki %1$s mahaigaineko gailu batean"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Hasi saioa berriro zure kontuan"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Gailua egiaztatzeko eskatzen zaizunean, hautatu %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"\"Berrezarri guztia\""</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Jarraitu argibideak berreskuratze-gako berri bat sortzeko"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Gorde berreskuratze-gako berria pasahitz-kudeatzaile batean edo enkriptatutako ohar batean"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Berrezarri zure kontuaren enkriptazioa beste gailu bat erabiliz"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Jarraitu berrezarpenarekin"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Zure kontuaren xehetasunak, kontaktuak, hobespenak eta txat-zerrenda gordeko dira"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Zerbitzarian soilik gordeta dagoen mezuen historia galduko duzu"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Zure gailu eta kontaktu guztiak berriro egiaztatu beharko dituzu"</string>
|
||||
<string name="screen_encryption_reset_title">"Ezin duzu baieztatu? Zure identitatea berrezarri beharko duzu."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Desaktibatu"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Enkriptatutako mezuak galduko dituzu gailu guztietan saioa amaitzen baduzu."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Ziur babeskopia desaktibatu nahi duzula?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Gakoen biltegiratzea ezabatuz gero, zure identitate kriptografikoa eta mezuen gakoak zerbitzaritik kenduko dira eta honako segurtasun ezaugarriak desaktibatu egingo dira:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Aurrerantzean ez duzu mezuen historia enkriptatuta izango gailu berrietan"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Gailu guztietan amaitzen baduzu %1$s saioa, enkriptatutako mezuetarako sarbidea galduko duzu"</string>
|
||||
<string name="screen_key_backup_disable_title">"Ziur gakoen biltegia desaktibatu eta ezabatu nahi duzula?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Lortu berreskuratze-gako berri bat lehendik duzuna galdu baduzu. Berreskuratze-gakoa aldatu ondoren, zaharrak ez du funtzionatuko."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Sortu berreskuratze-gako berri bat"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Ez partekatu inorekin!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Berreskuratze-gakoa aldatu da"</string>
|
||||
<string name="screen_recovery_key_change_title">"Berreskuratze-gakoa aldatu?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Sortu berreskuratze-gako berria"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Egiaztatu inork ezin duela pantaila hau ikusi!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Berreskuratze-gako okerra"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Segurtasun-gako edo -esaldi bat baduzu, honek ere balio du."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Sartu…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Berreskuratze-gakoa galdu duzu?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Berreskuratze-gakoa berretsi da"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Sartu zure berreskuratze-gakoa"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Berreskuratze-gakoa kopiatu da"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Sortzen…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Gorde berreskuratze-gakoa"</string>
|
||||
<string name="screen_recovery_key_save_description">"Idatzi berreskuratze-gako hau leku seguru batean, esate baterako, pasahitzen kudeatzaile, enkriptatutako ohar, edo kutxa gotor fisiko batean."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Sakatu berreskuratze-gakoa kopiatzeko"</string>
|
||||
<string name="screen_recovery_key_save_title">"Gorde berreskuratze-gakoa leku seguru batean"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Ezingo duzu berreskuratze-gako berria atzitu urrats honen ondoren."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Gorde al duzu berreskuratze-gakoa?"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Sortu berreskuratze-gakoa"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Ez partekatu inorekin!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Berreskuratzea ondo konfiguratu da"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Konfiguratu berreskurapena"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Bai, berrezarri orain"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Ezin da desegin."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Ziur zure identitatea berrezarri nahi duzula?"</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Sartu…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Berretsi zure identitatea berrezarri nahi duzula."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Idatzi kontuaren pasahitza aurrera egiteko"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"خاموش کردن پشتیبان"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"روشن کردن پشتیبان"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"ذخیرهٔ کلیدهای پیامها و هویت رمزنگاریتان به صورت امن روی کارساز. این کار میگذارد تاریخچهٔ پیامهایتان را روی هر افزارهٔ جدیدی ببینید. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"ذخیرهساز کلید"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"بارگذاری کلیدها از ین افزاره"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"اجازهٔ ذخیرهٔ کلید"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"تغییر کلید بازیابی"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"ورود کلید بازیابی"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"ذخیرهساز کلیدتان از همگام بودن در آمده."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"برپایی بازیابی"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"اگر همه دستگاههایتان را گم کردید یا از سیستم خارج شدید، به پیامهای رمزگذاریشدهتان دسترسی پیدا کنید%1$s همه جا."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"گشودن %1$s در افزارهٔ میزکار"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"ورود دوباره به حسابتان"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"گزینش %1$s هنگام درخواست تأیید افزارهتان"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"«بازنشانی همه»"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"پیروی از دستورالعملها برای ایجاد کلید بازیابی جدید"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"ذخیرهٔ کلید بازیابی جدیدتان در مدیر گذرواژه یا یادداشت رمز شده"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"بازنشانی رمزنگاری برای حسابتان با استفاده از افزارهای دیگر"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"ادامهٔ بازنشانی"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"جزییات حساب، آشنایان، ترجیحات و سیاههٔ گپهایتان حفظ خواهند شد"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"تاریخچهٔ گپهایتان را از دست خواهید داد"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"لازم است دوباره همهٔ آشنایان و افزارههای موجودتان را تأیید کنید"</string>
|
||||
<string name="screen_encryption_reset_footer">"فقط اگر به افزارهای وارد شده از پیش دسترسی ندارید و کلید بازیابیتان را گم کردهاید بازنشانی کنید."</string>
|
||||
<string name="screen_encryption_reset_title">"نمیتوانید تأیید کنید؟ لازم است هویتتان را بازنشانی کنید."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"خاموش کردن"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"اگر از سیستم همه دستگاه ها خارج شده باشید، پیام های رمزگذاری شده خود را از دست خواهید داد."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"مطمئنید که میخواهید پشتیبان گیری را خاموش کنید؟"</string>
|
||||
<string name="screen_key_backup_disable_description">"حذف فضای ذخیره سازی کلید، هویت رمزنگاری و کلیدهای پیام شما را از کارساز حذف می کند و ویژگی های امنیتی زیر را خاموش می کند:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"سابقه پیام رمزگذاری شده در دستگاه های جدید نخواهید داشت"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"اگر از %1$s در همه جا خارج شده باشید، دسترسی به پیام های رمزگذاری شده خود را از دست خواهید داد"</string>
|
||||
<string name="screen_key_backup_disable_title">"مطمئنید که میخواهید فضای ذخیره سازی کلید را خاموش کرده و آن را حذف کنید؟"</string>
|
||||
<string name="screen_recovery_key_change_description">"گرفتن کلید بازیابی جدید در صورت فراموشی کلید کنونی. پس از تغییر دادن کلید بازیابیتان، کلید پیشین دیگر کار نخواهد کرد."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"تولید کلید بازیابی جدید"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"با کسی همرسانیش نکنید!"</string>
|
||||
<string name="screen_recovery_key_change_success">"کلید بازیابی تغییر کرد"</string>
|
||||
<string name="screen_recovery_key_change_title">"تغییر کلید بازیابی؟"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"ایجاد کلید بازیابی جدید"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"اطمینان از این که کسی نمیتواند این صفحه را ببیند!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"لطفاً برای دسترسی به ذخیرهساز کلیدتان دوباره تلاش کنید."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"کلید بازیابی اشتباه"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"کلید امنیتی یا عبارت امنیتی نیز باید کار کنند."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"ورود…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"گم کردن کلید بازیابیتان؟"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"کلید بازیابی تأیید شد"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"ورود کلید بازیابیتان"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"کلید بازیابی رونوشت شد"</string>
|
||||
<string name="screen_recovery_key_generating_key">"تولید کردن…"</string>
|
||||
<string name="screen_recovery_key_save_action">"ذخیرهٔ کلید بازیابی"</string>
|
||||
<string name="screen_recovery_key_save_description">"این کلید بازیابی را در جایی امن چون مدیر گذرواژه، یادداشت رمز شده یا گاوصندوق فیزیکی بنویسید."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"زدن برای رونوشت از کلید بازیابی"</string>
|
||||
<string name="screen_recovery_key_save_title">"ذخیرهٔ کلید بازیابیتان"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"پس از این برپایی قادر به دسترسی به کلید بازیابی جدیدتان نخواهید بود."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"کلید بازیابیتان را ذخیره کردهاید؟"</string>
|
||||
<string name="screen_recovery_key_setup_description">"پشتیبان گپتان با کلید بازیابی محافظت میشود. اگر پس از برپایی نیاز به کلید بازیابی جدیدی داشتید میتوانید با گزینش «دگرگونی کلید بازیابی» دوباره ایجادش کنید."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"تولید کلید بازیابیتان"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"با کسی همرسانیش نکنید!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"برپایی بازیابی موفّق بود"</string>
|
||||
<string name="screen_recovery_key_setup_title">"برپایی بازیابی"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"بله. اکنون بازنشانی شود"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"این فرایند بازگشتناپذیر است."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"ورود…"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Ota avainten säilytys pois käytöstä"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Ota varmuuskopiointi käyttöön"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Säilytä kryptografinen identiteettisi ja viestien avaimet turvallisesti palvelimellasi. Tämän avulla pääset käsiksi viestihistoriaan uusillakin laitteilla. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Avainten säilytys"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Avainten säilytys on oltava käytössä, jotta palautus voidaan ottaa käyttöön."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Lataa avaimet tästä laitteesta"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Salli avainten säilytys"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Vaihda palautusavain"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Palauta kryptografinen identiteettisi ja viestihistoriasi palautusavaimella, jos olet menettänyt kaikki nykyiset laitteesi."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Syötä palautusavain"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Avainten säilytys ei ole tällä hetkellä synkronoitu."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Ota palautus käyttöön"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Pääset käsiksi salattuihin viesteihisi, jos menetät kaikki laitteesi tai olet kirjautunut ulos %1$s -sovelluksesta kaikkialla."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Avaa %1$s tietokoneella"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Kirjaudu tilillesi uudelleen"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Kun sinua pyydetään vahvistamaan laitteesi, valitse %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Nollaa kaikki”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Seuraa ohjeita uuden palautusavaimen luomiseksi"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Tallenna uusi palautusavaimesi salasanojen hallintaohjelmaan tai salattuun muistiinpanoon"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Nollaa tilisi salaus toisella laitteella"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Jatka nollausta"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Tilitietosi, yhteystiedot, asetukset ja keskustelulista säilytetään"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Menetät kaiken viestihistorian, joka on tallella vain palvelimella"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Sinun on vahvistettava kaikki olemassa olevat laitteesi ja yhteystietosi uudelleen"</string>
|
||||
<string name="screen_encryption_reset_footer">"Nollaa identiteettisi vain, jos et voi käyttää toista laitetta, johon olet kirjautunut, ja olet kadottanut palautusavaimesi."</string>
|
||||
<string name="screen_encryption_reset_title">"Etkö voi vahvistaa? Sinun on nollattava identiteettisi."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Poista käytöstä"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Menetät salatut viestisi, jos kirjaudut ulos kaikista laitteista."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Haluatko varmasti poistaa varmuuskopioinnin käytöstä?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Avainten säilytyksen poistaminen poistaa sinun kryptografisen identiteetin ja viestien avaimet palvelimeltasi ja poistaa seuraavat suojausominausuudet käytöstä:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Et saa salattua viestihistoriaa uusilla laitteilla"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Menetät pääsyn salattuihin viestihisi, jos kirjaudut ulos %1$s -sovelluksesta kaikkialla."</string>
|
||||
<string name="screen_key_backup_disable_title">"Haluatko varmasti ottaa avainten säilytyksen pois käytöstä ja poistaa sen?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Hanki uusi palautusavain, jos olet kadottanut nykyisen avaimen. Palautusavaimen vaihtamisen jälkeen vanha avaimesi ei enää toimi."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Luo uusi palautusavain"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Älä jaa tätä kenenkään kanssa!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Palautusavain vaihdettu"</string>
|
||||
<string name="screen_recovery_key_change_title">"Vaihdetaanko palautusavain?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Luo uusi palautusavain"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Varmista, ettei kukaan näe tätä ruutua!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Yritä uudelleen vahvistaaksesi pääsyn avainten säilytykseen."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Väärä palautusavain"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Jos sinulla on turva-avain tai turvalause, sekin toimii."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Syötä…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Hukkasitko palautusavaimesi?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Palautusavain vahvistettu"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Syötä palautusavaimesi"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Palautusavain kopioitu"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Luodaan…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Tallenna palautusavain"</string>
|
||||
<string name="screen_recovery_key_save_description">"Kirjoita tämä palautusavain turvalliseen paikkaan, kuten salasanojen hallintaohjelmaan, salattuun muistiinpanoon tai fyysiseen kassakaappiin."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Kopioi palautusavain napauttamalla"</string>
|
||||
<string name="screen_recovery_key_save_title">"Tallenna palautusavain turvalliseen paikkaan"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Et voi palata katsomaan uutta palautusavaintasi uudelleen tämän vaiheen jälkeen."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Oletko tallentanut palautusavaimesi?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Avainten säilytys on suojattu palautusavaimella. Jos tarvitset uuden palautusavaimen tämän jälkeen, voit luoda uuden valitsemalla ‘Vaihda palautusavain’."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Luo palautusavaimesi"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Älä jaa tätä kenenkään kanssa!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Palautuksen käyttöönotto onnistui"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Ota palautus käyttöön"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Kyllä, nollaa nyt"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Tätä prosessia ei voi peruuttaa."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Haluatko varmasti nollata identiteettisi?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Tapahtui tuntematon virhe. Tarkista, että tilisi salasana on oikein ja yritä uudelleen."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Syötä…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Vahvista, että haluat nollata identiteettisi."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Kirjoita tilisi salasana jatkaaksesi"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Désactiver la sauvegarde"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Activer la sauvegarde"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Stockez votre identité cryptographique et vos clés de message en toute sécurité sur le serveur. Cela vous permettra de consulter l’historique de vos messages sur tous les nouveaux appareils. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Stockage des clés"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Le stockage des clés doit être activé pour configurer la restauration."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Télécharger les clés depuis cet appareil"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Autoriser le stockage des clés"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Changer la clé de récupération"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Récupérez votre identité cryptographique et l’historique de vos messages à l’aide d’une clé de récupération si vous avez perdu tous vos appareils existants."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Utiliser la clé de récupération"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Le stockage de vos clés est actuellement désynchronisé."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Configurer la sauvegarde"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Accédez à vos messages chiffrés si vous perdez tous vos appareils ou que vous êtes déconnecté de %1$s partout."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Ouvrez %1$s sur un ordinateur"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Connectez-vous à nouveau à votre compte"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Lorsque vous devrez vérifier la session, choisissez %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Réinitialiser”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Suivez les instructions pour créer une nouvelle clé de récupération"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Enregistrez votre nouvelle clé dans un gestionnaire de mots de passe ou dans une note chiffrée"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Réinitialisez le chiffrement de votre compte en utilisant un autre appareil"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Continuer la réinitialisation"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Les détails de votre compte, vos contacts, vos préférences et votre liste de discussions seront conservés"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Vous perdrez l’historique de vos messages"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Vous devrez vérifier à nouveau tous vos appareils et tous vos contacts"</string>
|
||||
<string name="screen_encryption_reset_footer">"Ne réinitialisez votre identité que si vous n’avez plus accès à aucune autre session et que vous avez perdu votre clé de récupération."</string>
|
||||
<string name="screen_encryption_reset_title">"Vous ne pouvez pas confirmer ? Vous devez réinitialiser votre identité."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Désactiver"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Vous perdrez vos messages chiffrés si vous vous déconnectez de toutes vos sessions."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Êtes-vous certain de vouloir désactiver la sauvegarde ?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Désactiver la sauvegarde supprimera votre clé de récupération actuelle et désactivera d’autres mesures de sécurité. Dans ce cas :"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Pas d’accès à l’historique des discussions chiffrées sur vos nouveaux appareils"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Perte de l’accès à vos messages chiffrés si vous êtes déconnecté de %1$s partout"</string>
|
||||
<string name="screen_key_backup_disable_title">"Êtes-vous certain de vouloir désactiver la sauvegarde ?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Obtenez une nouvelle clé de récupération dans le cas où vous avez oublié l’ancienne. Après le changement, l’ancienne clé ne sera plus utilisable."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Générer une nouvelle clé"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Ne partagez cela avec personne !"</string>
|
||||
<string name="screen_recovery_key_change_success">"Clé de récupération modifée"</string>
|
||||
<string name="screen_recovery_key_change_title">"Changer la clé de récupération ?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Créer une nouvelle clé de récupération"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Assurez vous que personne d’autre ne regarde votre écran !"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Veuillez réessayer pour confirmer l’accès à votre stockage de clés."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Clé de récupération incorrecte"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Si vous avez une clé de sécurité ou une phrase de sécurité, cela fonctionnera également."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Saisissez la clé ici…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Clé de récupération perdue ?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Clé de récupération confirmée"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Saisissez votre clé de récupération"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Clé de récupération copiée"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Génération…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Enregistrer la clé"</string>
|
||||
<string name="screen_recovery_key_save_description">"Recopier cette clé de récupération dans un endroit sûr, comme un gestionnaire de mots de passe, une note chiffrée ou un coffre-fort physique."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Taper pour copier la clé"</string>
|
||||
<string name="screen_recovery_key_save_title">"Sauvegarder la clé"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"La clé ne pourra plus être affichée après cette étape."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Avez-vous sauvegardé votre clé de récupération ?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Votre sauvegarde est protégée par votre clé de récupération. Si vous avez besoin d’une nouvelle clé après la configuration, vous pourrez en créer une nouvelle en cliquant sur \"Changer la clé de récupération\"."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Générer la clé de récupération"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Ne partagez cela avec personne !"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Sauvegarde mise en place avec succès"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Configurer la sauvegarde"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Oui, réinitialisez maintenant"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Cette opération ne peut pas être annulée."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Êtes-vous sûr de vouloir réinitialiser votre identité ?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Une erreur s’est produite. Vérifiez que le mot de passe de votre compte est correct et réessayez."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Saisissez la clé ici…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Veuillez confirmer que vous souhaitez réinitialiser votre identité."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Saisissez le mot de passe de votre compte pour continuer"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Biztonsági mentés kikapcsolása"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Biztonsági mentés bekapcsolása"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Tárolja kriptográfiai személyazonosságát és üzenetkulcsait biztonságosan a kiszolgálón. Ez lehetővé teszi, hogy bármilyen új eszközön megtekinthesse üzenetelőzményeit. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Kulcstároló"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"A helyreállítás beállításához be kell kapcsolni a kulcstárolást."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Kulcsok feltöltése erről az eszközről"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Kulcstárolás engedélyezése"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Helyreállítási kulcs módosítása"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Ha az összes meglévő eszközét elvesztette, akkor egy helyreállítási kulccsal visszaszerezheti a kriptográfiai személyazonosságát és az üzenetelőzményeit."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Adja meg a helyreállítási kulcsot"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"A kulcstároló jelenleg nincs szinkronizálva."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Helyreállítás beállítása"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Szerezzen hozzáférést a titkosított üzeneteihez, ha elvesztette az összes eszközét, vagy ha mindenütt kijelentkezett az %1$sből."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Nyissa meg az %1$set egy asztali eszközön"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Jelentkezzen be újra a fiókjába"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Amikor az eszköz ellenőrzését kéri, válassza ezt a lehetőséget: %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"„Minden visszaállítása”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Kövesse az utasításokat egy új helyreállítási kulcs létrehozásához"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Mentse az új helyreállítási kulcsot egy jelszókezelőbe vagy egy titkosított jegyzetbe."</string>
|
||||
<string name="screen_create_new_recovery_key_title">"A fiók titkosításának visszaállítása egy másik eszköz használatával"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Visszaállítás folytatása"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"A fiókadatok, a kapcsolatok, a beállítások és a csevegéslista megmarad"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Elveszíti meglévő üzenetelőzményeit"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Újból ellenőriznie kell az összes meglévő eszközét és csevegőpartnerét"</string>
|
||||
<string name="screen_encryption_reset_footer">"Csak akkor állítsa vissza a személyazonosságát, ha nem fér hozzá másik bejelentkezett eszközhöz, és elvesztette a helyreállítási kulcsot."</string>
|
||||
<string name="screen_encryption_reset_title">"Állítsa alaphelyzetbe a személyazonosságát, ha más módon nem tudja megerősíteni"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Kikapcsolás"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Ha kijelentkezik az összes eszközéről, akkor elveszti a titkosított üzeneteit."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Biztos, hogy kikapcsolja a biztonsági mentéseket?"</string>
|
||||
<string name="screen_key_backup_disable_description">"A biztonsági mentés kikapcsolása eltávolítja a jelenlegi titkosítási kulcsának mentését, és kikapcsol más biztonsági funkciókat is. Ebben az esetben:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Nem lesznek meg a titkosított üzenetek előzményei az új eszközein"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Elveszti a hozzáférését a titkosított üzeneteihez, ha mindenhol kilép az %1$sből"</string>
|
||||
<string name="screen_key_backup_disable_title">"Biztos, hogy kikapcsolja a biztonsági mentéseket?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Szerezzen új helyreállítási kulcsot, ha elvesztette a meglévőt. A helyreállítása kulcsa módosítása után a régi már nem fog működni."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Új helyreállítási kulcs előállítása"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Ezt ne ossza meg senkivel!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Helyreállítási kulcs lecserélve"</string>
|
||||
<string name="screen_recovery_key_change_title">"Módosítja a helyreállítási kulcsot?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Új helyreállítási kulcs létrehozása"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Győződjön meg arról, hogy senki sem látja ezt a képernyőt!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Próbálja újra megerősíteni a kulcstárolóhoz való hozzáférést."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Helytelen helyreállítási kulcs"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Ha van biztonsági kulcsa vagy biztonsági jelmondata, akkor ez is fog működni."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Megadás…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Elvesztette a helyreállítási kulcsát?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Helyreállítási kulcs megerősítve"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Adja meg a helyreállítási kulcsot"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Helyreállítási kulcs másolva"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Előállítás…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Helyreállítási kulcs mentése"</string>
|
||||
<string name="screen_recovery_key_save_description">"Írja le a helyreállítási kulcsát valami biztonságos helyre, például mentse egy jelszókezelőbe, egy titkosított jegyzetbe vagy egy fizikai széfbe."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Koppintson a helyreállítási kulcs másolásához"</string>
|
||||
<string name="screen_recovery_key_save_title">"Mentse el a helyreállítási kulcsát"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Ezután a lépés után nem fog tudni hozzáférni az új helyreállítási kulcsához."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Mentette a helyreállítási kulcsát?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"A csevegései biztonsági mentését a helyreállítási kulcsa védi. Ha új helyreállítási kulcsra van szüksége a beállítás után, akkor a „Helyreállítási kulcs módosítása” választásával újból létrehozhat egyet."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Helyreállítási kulcs előállítása"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Ezt ne ossza meg senkivel!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"A helyreállítás beállítása sikeres"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Helyreállítás beállítása"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Igen, visszaállítás most"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Ez a folyamat visszafordíthatatlan."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Biztos, hogy visszaállítja a titkosítást?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Ismeretlen hiba történt. Ellenőrizze, hogy a fiókja jelszava helyes-e, és próbálja meg újra."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Megadás…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Erősítse meg, hogy vissza szeretné állítani a titkosítást."</string>
|
||||
<string name="screen_reset_encryption_password_title">"A folytatáshoz adja meg fiókja jelszavát"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Matikan pencadangan"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Nyalakan pencadangan"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Simpan identitas kriptografi Anda dan kunci-kunci pesan secara aman di server. Ini akan memungkinkan Anda untuk melihat riwayat pesan Anda di perangkat yang baru. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Penyimpanan kunci"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Penyimpanan kunci harus diaktifkan untuk menyiapkan pemulihan."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Unggah kunci dari perangkat ini"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Izinkan penyimpanan kunci"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Ubah kunci pemulihan"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Pulihkan identitas kriptografi dan riwayat pesan Anda dengan kunci pemulihan jika Anda kehilangan semua perangkat yang ada."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Masukkan kunci pemulihan"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Penyimpanan kunci Anda saat ini tidak sinkron."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Siapkan pemulihan"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Dapatkan akses ke pesan terenkripsi Anda jika Anda kehilangan semua perangkat Anda atau keluar dari %1$s di mana pun."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Buka %1$s di perangkat desktop"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Masuk ke akun Anda lagi"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Saat diminta untuk memverifikasi perangkat Anda, pilih %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Atur ulang semua”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Ikuti petunjuk untuk membuat kunci pemulihan baru"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Simpan kunci pemulihan baru Anda dalam pengelola kata sandi atau catatan terenkripsi"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Atur ulang enkripsi untuk akun Anda menggunakan perangkat lain"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Lanjutkan pengaturan ulang"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Detail akun, kontak, preferensi, dan daftar obrolan Anda akan disimpan"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Anda akan kehilangan riwayat pesan yang hanya disimpan di server"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Anda perlu memverifikasi semua perangkat dan kontak yang ada lagi"</string>
|
||||
<string name="screen_encryption_reset_footer">"Hanya atur ulang identitas Anda jika Anda tidak memiliki akses ke perangkat lain yang masuk dan Anda kehilangan kunci pemulihan."</string>
|
||||
<string name="screen_encryption_reset_title">"Tidak dapat mengonfirmasi? Anda perlu mengatur ulang identitas Anda."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Matikan"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Anda akan kehilangan pesan terenkripsi jika Anda keluar dari semua perangkat."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Apakah Anda yakin ingin mematikan pencadangan?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Mematikan pencadangan akan menghapus pencadangan kunci terenkripsi saat ini dan mematikan fitur keamanan lainnya. Dalam hal ini, Anda akan:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Tidak memiliki riwayat pesan terenkripsi di perangkat baru"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Kehilangan akses ke pesan terenkripsi Anda jika keluar dari %1$s di mana pun"</string>
|
||||
<string name="screen_key_backup_disable_title">"Apakah Anda yakin ingin mematikan pencadangan?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Dapatkan kunci pemulihan yang baru jika Anda kehilangan kunci pemulihan saat ini. Setelah mengganti kunci pemulihan Anda, yang lama tidak akan bekerja lagi."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Buat kunci pemulihan baru"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Jangan bagikan ini kepada siapa pun!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Kunci pemulihan diganti"</string>
|
||||
<string name="screen_recovery_key_change_title">"Ubah kunci pemulihan?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Buat kunci pemulihan baru"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Pastikan tidak ada yang bisa melihat layar ini!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Silakan coba lagi untuk mengonfirmasi akses ke penyimpanan kunci Anda."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Kunci pemulihan salah"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Jika Anda memiliki kunci keamanan atau frasa keamanan, ini juga bisa digunakan."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Masukkan…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Kehilangan kunci pemulihan Anda?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Kunci pemulihan dikonfirmasi"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Masukkan kunci pemulihan Anda"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Kunci pemulihan disalin"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Membuat…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Simpan kunci pemulihan"</string>
|
||||
<string name="screen_recovery_key_save_description">"Tuliskan kunci pemulihan ini di tempat yang aman, seperti pengelola kata sandi, catatan terenkripsi, atau brankas fisik."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Ketuk untuk menyalin kunci pemulihan"</string>
|
||||
<string name="screen_recovery_key_save_title">"Simpan kunci pemulihan Anda"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Anda tidak akan dapat mengakses kunci pemulihan Anda setelah langkah ini."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Apakah Anda sudah menyimpan kunci pemulihan Anda?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Pencadangan percakapan Anda sedang dilindungi oleh sebuah kunci pemulihan. Jika Anda perlu kunci pemulihan yang baru setelah penyiapan, Anda dapat membuat ulang dengan memilih \'Ubah kunci pemulihan\'."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Buat kunci pemulihan Anda"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Jangan bagikan ini kepada siapa pun!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Penyiapan pemulihan berhasil"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Siapkan pemulihan"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Ya, atur ulang sekarang"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Proses ini tidak dapat diurungkan."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Apakah Anda yakin ingin mengatur ulang identitas Anda?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Terjadi kesalahan yang tidak diketahui. Harap periksa apakah kata sandi akun Anda sudah benar dan coba lagi."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Masukkan…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Konfirmasikan bahwa Anda ingin mengatur ulang identitas Anda."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Masukkan kata sandi akun Anda untuk melanjutkan"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Disattiva il backup"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Attiva il backup"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Archivia la tua identità crittografica e le chiavi dei messaggi in modo sicuro sul server. Ciò ti consentirà di visualizzare la cronologia dei messaggi su tutti i nuovi dispositivi. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Archiviazione chiavi"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"L\'archiviazione delle chiavi deve essere attivata per configurare il ripristino."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Carica le chiavi da questo dispositivo"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Consenti l\'archiviazione delle chiavi"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Cambia la chiave di recupero"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Recupera la tua identità crittografica e la cronologia dei messaggi con una chiave di recupero se hai perso tutti i dispositivi esistenti."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Inserisci la chiave di recupero"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"L\'archiviazione delle chiavi non è sincronizzata."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Configura il recupero"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Ottieni l\'accesso ai tuoi messaggi criptati nel caso perdi tutti i dispositivi o vieni disconnesso da %1$s su tutti i dispositivi."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Apri %1$s in un dispositivo desktop"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Accedi nuovamente al tuo account"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Quando ti viene chiesto di verificare il tuo dispositivo, seleziona %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Reimposta tutto”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Segui le istruzioni per creare una nuova chiave di recupero"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Salva la tua nuova chiave di recupero in un gestore di password o in una nota criptata"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Reimposta la crittografia del tuo account utilizzando un altro dispositivo"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Continua il ripristino"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"I dettagli del tuo account, i contatti, le preferenze e l\'elenco delle conversazioni verranno conservati"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Perderai la cronologia dei messaggi esistente"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Dovrai verificare nuovamente tutti i dispositivi e i contatti esistenti"</string>
|
||||
<string name="screen_encryption_reset_footer">"Reimposta la tua identità solo se non hai accesso a un altro dispositivo su cui hai effettuato l\'accesso e hai perso la chiave di recupero."</string>
|
||||
<string name="screen_encryption_reset_title">"Reimposta la tua identità nel caso in cui non riesci a confermare in un altro modo"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Disattiva"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Perderai i tuoi messaggi cifrati se sei disconnesso da tutti i dispositivi."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Vuoi davvero disattivare il backup?"</string>
|
||||
<string name="screen_key_backup_disable_description">"La disattivazione del backup rimuoverà il backup dell\'attuale chiave crittografica e disattiverà altre funzioni di sicurezza. In questo caso:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Non avrai la cronologia dei messaggi cifrati su nuovi dispositivi"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Perderai l\'accesso ai tuoi messaggi cifrati se ti sei disconnesso da %1$s ovunque"</string>
|
||||
<string name="screen_key_backup_disable_title">"Vuoi davvero disattivare il backup?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Ottieni una nuova chiave di recupero se hai perso quella esistente. Dopo averla cambiata, quella vecchia non funzionerà più."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Genera una nuova chiave di recupero"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Non condividerla con nessuno!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Chiave di recupero cambiata"</string>
|
||||
<string name="screen_recovery_key_change_title">"Cambiare la chiave di recupero?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Crea una nuova chiave di recupero"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Assicurati che nessuno possa vedere questa schermata!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Riprova per confermare l\'accesso all\'archivio delle chiavi."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Chiave di recupero errata"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Se hai una chiave di sicurezza o una password, andrà bene anche questo."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Inserisci…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Hai perso la chiave di recupero?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Chiave di recupero confermata"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Inserisci la tua chiave di recupero"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Chiave di recupero copiata"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Generazione…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Salva la chiave di recupero"</string>
|
||||
<string name="screen_recovery_key_save_description">"Annota questa chiave di recupero in un posto sicuro, come un gestore di password, una nota criptata o una cassaforte fisica."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Tocca per copiare la chiave di recupero"</string>
|
||||
<string name="screen_recovery_key_save_title">"Salva la tua chiave di recupero"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Dopo questo passaggio non potrai accedere alla nuova chiave di recupero."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Hai salvato la chiave di recupero?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Il backup della chat è protetto da una chiave di recupero. Se hai bisogno di una nuova chiave di recupero dopo la configurazione, puoi ricrearla selezionando \"Cambia chiave di recupero\"."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Genera la tua chiave di recupero"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Non condividerla con nessuno!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Configurazione del recupero completata"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Configura il recupero"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Sì, reimposta ora"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Questo processo è irreversibile."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Sei sicuro di voler reimpostare la crittografia?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Si è verificato un errore sconosciuto. Controlla che la password del tuo account sia corretta e riprova."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Inserisci…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Conferma di voler reimpostare la crittografia."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Inserisci la password del tuo account per continuare"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"სარეზერვო ასლის გამორთვა"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"სარეზერვო ასლის ჩართვა"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"სარეზერვო ასლი უზრუნველყოფს იმას, რომ თქვენ შეტყობინებების ისტორიას არ დაკარგავთ. %1$s"</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"გასაღების საცავი"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"აღდგენის გასაღების შეცვლა"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"შეიყვანეთ აღდგენის გასაღები"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"თქვენი ჩატის სარეზერვო ასლი ამჟამად არ არის სინქრონიზებული."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"აღდგენის დაყენება"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"მიიღეთ წვდომა თქვენს დაშიფრულ შეტყობინებებზე, თუ დაკარგავთ თქვენს ყველა მოწყობილობას ან გამოხვალთ სისტემიდან %1$s-დან ყველგან."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"გახსენით %1$s კომპიუტერზე"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"შედით თქვენს ანგარიშში კიდევ ერთხელ"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"გაანულეთ თქვენი ანგარიშის დაშიფვრა სხვა მოწყობილობის დახმარებით"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"გამორთვა"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"თქვენ დაკარგავთ დაშიფრულ შეტყობინებებს, თუ ყველა მოწყობილობიდან გამოხვალთ."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"დარწმუნებული ხართ, რომ გსურთ გამორთოთ სარეზერვო ასლი?"</string>
|
||||
<string name="screen_key_backup_disable_description">"სარეზერვო ასლის გამორთვა წაშლის თქვენი მიმდინარე დაშიფვრის გასაღების სარეზერვო ასლს და გამორთავს უსაფრთხოების სხვა ფუნქციებს. ამ შემთხვევაში, თქვენ:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"არ გექნებათ დაშიფვრული შეტყობინებების ისტორია ახალ მოწყობილობებზე"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"დაკარვავთ წვდომას დაშიფრულ შეტყობინებებზე თუ ყველგან გამოხვალთ %1$s-დან"</string>
|
||||
<string name="screen_key_backup_disable_title">"დარწმუნებული ხართ, რომ გსურთ გამორთოთ სარეზერვო ასლი?"</string>
|
||||
<string name="screen_recovery_key_change_description">"მიიღეთ ახალი აღდგენის გასაღები, თუ დაკარგეთ არსებული. აღდგენის გასაღების შეცვლის შემდეგ, ძველი აღარ იმუშავებს."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"ახალი აღდგენის გასაღების შექმნა"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"არავის გაუზიაროთ!"</string>
|
||||
<string name="screen_recovery_key_change_success">"აღდგენის გასაღები შეიცვალა"</string>
|
||||
<string name="screen_recovery_key_change_title">"გსურთ აღდგენის გასაღების შეცვლა?"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"დარწმუნდით, რომ ვერავინ ხედავს ამ ეკრანს!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"გთხოვთ, სცადოთ წვდომის დადასტურება გასაღებების დამგროვებელთან კვლავ."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"აღდგენის არასწორი გასაღები"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"თუ თქვენ გაქვთ უსაფრთხოების გასაღები ან უსაფრთხოების ფრაზა, ეს ასევე იმუშავებს."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"შეყვანა"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"აღდგენის გასაღები დადასტურებულია"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"დაკოპირებულია აღდგენის გასაღები"</string>
|
||||
<string name="screen_recovery_key_generating_key">"გენერირება…"</string>
|
||||
<string name="screen_recovery_key_save_action">"აღდგენის გასაღების შენახვა"</string>
|
||||
<string name="screen_recovery_key_save_description">"ჩაწერეთ ეს აღდგენის გასაღები სადმე უსაფრთხო ადგილას, მაგალითად პაროლების მენეჯერში, დაშიფრულ შენიშვნაში ან ფიზიკურ სეიფში."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"აღდგენის გასაღების დასაკოპირებლად, დააწკაპუნეთ"</string>
|
||||
<string name="screen_recovery_key_save_title">"შეინახეთ აღდგენის გასაღები"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"თქვენ ვერ შეძლებთ წვდომას თქვენი ახალი აღდგენის გასაღებზე ამ ნაბიჯის შემდეგ."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"შეინახეთ თქვენი აღდგენის გასაღები?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"თქვენი ჩატის სარეზერვო ასლი დაცულია აღდგენის გასაღებით. თუ დაყენების შემდეგ გჭირდებათ ახალი აღდგენის გასაღები, შეგიძლიათ ხელახლა შექმნათ „აღდგენის გასაღების შეცვლის“ არჩევით."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"შექმენით აღდგენის გასაღები"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"არავის გაუზიაროთ!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"აღდგენის დაყენება წარმატებით დასრულდა"</string>
|
||||
<string name="screen_recovery_key_setup_title">"აღდგენის დაყენება"</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"შეყვანა"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"백업 비활성화"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"백업 활성화"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"암호화 신원 및 메시지 키를 서버에 안전하게 저장하세요. 이로써 새로운 기기에서 메시지 이력을 확인할 수 있습니다. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"키 저장소"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"복구 설정을 하려면 키 저장을 켜야 합니다."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"이 장치에서 키 업로드"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"키 저장 허용"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"복구 키 변경"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"기존의 모든 기기를 분실한 경우, 복구 키를 사용하여 암호화 ID와 메시지 기록을 복구할 수 있습니다."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"복구 키를 입력하세요"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"현재 키 저장소가 동기화되지 않았습니다."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"복구 설정"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"모든 기기를 분실하거나 %1$s 에서 로그아웃된 경우에도 암호화된 메시지에 액세스할 수 있습니다."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"데스크톱 장치에서 %1$s 을 엽니다."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"계정에 다시 로그인하세요"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"장치를 확인하라는 메시지가 표시되면, %1$s 을 선택하세요"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“모든 항목을 초기화합니다”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"지침에 따라 새 복구 키를 만드세요."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"새 복구 키를 암호 관리자 또는 암호화된 메모에 저장하세요."</string>
|
||||
<string name="screen_create_new_recovery_key_title">"다른 기기를 사용하여 계정의 암호화를 재설정하세요."</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"계속 재설정"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"귀하의 계정 정보, 연락처, 기본 설정 및 채팅 목록은 보관됩니다"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"서버에만 저장된 모든 메시지 기록이 손실됩니다."</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"기존 장치와 연락처를 모두 다시 확인해야 합니다."</string>
|
||||
<string name="screen_encryption_reset_footer">"다른 로그인 기기에 액세스할 수 없고 복구 키를 분실한 경우에만 ID를 재설정하세요."</string>
|
||||
<string name="screen_encryption_reset_title">"확인할 수 없나요? 신원을 재설정해야 합니다."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"비활성화"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"모든 장치에서 로그아웃하면 암호화된 메시지가 삭제됩니다."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"정말로 백업을 비활성화하시겠어요?"</string>
|
||||
<string name="screen_key_backup_disable_description">"키 저장소를 삭제하면 서버에서 암호화 신원 및 메시지 키가 삭제되며 다음과 같은 보안 기능이 비활성화됩니다:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"새 장치에는 암호화된 메시지 기록이 남아 있지 않습니다."</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"%1$s 에서 모든 세션이 종료되면 암호화된 메시지에 액세스할 수 없게 됩니다."</string>
|
||||
<string name="screen_key_backup_disable_title">"정말로 키 저장소를 비활성화하고 삭제하시겠습니까?"</string>
|
||||
<string name="screen_recovery_key_change_description">"기존 복구 키를 분실한 경우 새 복구 키를 받으세요. 복구 키를 변경하면 이전 키는 더 이상 사용할 수 없습니다."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"새로운 복구 키 생성"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"이 내용을 누구와도 공유하지 마십시오!"</string>
|
||||
<string name="screen_recovery_key_change_success">"복구 키가 변경되었습니다."</string>
|
||||
<string name="screen_recovery_key_change_title">"복구 키 변경하시겠습니까?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"새 복구 키 만들기"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"아무도 이 화면을 볼 수 없도록 하세요!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"키 저장소에 대한 액세스를 확인하시려면 다시 시도해 주세요."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"잘못된 복구 키"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"보안 키나 보안 문구를 가지고 있다면 이 방법도 작동합니다."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"입력…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"복구 키를 분실하셨나요?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"복구 키 확인됨"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"복구 키를 입력하세요"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"복사된 복구 키"</string>
|
||||
<string name="screen_recovery_key_generating_key">"생성 중…"</string>
|
||||
<string name="screen_recovery_key_save_action">"복구 키 저장"</string>
|
||||
<string name="screen_recovery_key_save_description">"이 복구 키를 암호 관리자, 암호화된 메모 또는 물리적 금고와 같은 안전한 곳에 기록해 두십시오."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"탭하여 복구 키 복사"</string>
|
||||
<string name="screen_recovery_key_save_title">"복구 키를 안전한 곳에 보관하세요."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"이 단계를 완료하면 새 recovery key에 액세스할 수 없습니다."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"복구 키를 저장하셨습니까?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"키 저장소는 복구 키로 보호됩니다. 설정 후 새로운 복구 키가 필요한 경우 \'복구 키 변경\'을 선택하여 재작성할 수 있습니다."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"복구 키 생성"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"이 내용을 누구와도 공유하지 마십시오!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"복구 설정 성공"</string>
|
||||
<string name="screen_recovery_key_setup_title">"복구 설정"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"네, 지금 재설정하세요"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"이 과정은 되돌릴 수 없습니다."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"정말로 신원을 재설정하시겠습니까?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"알 수 없는 오류가 발생했습니다. 계정 비밀번호가 올바른지 확인하고 다시 시도하십시오."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"입력…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"신원 재설정을 확인하시겠습니까?"</string>
|
||||
<string name="screen_reset_encryption_password_title">"계정 비밀번호를 입력하여 진행하세요"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Slett nøkkellagring"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Slå på sikkerhetskopiering"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Lagre din kryptografiske identitet og meldingsnøkler sikkert på serveren. Dette gjør at du kan se meldingshistorikken din på alle nye enheter. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Nøkkellagring"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Nøkkellagring må være slått på for å konfigurere gjenoppretting."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Last opp nøkler fra denne enheten"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Tillat nøkkellagring"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Endre gjenopprettingsnøkkel"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Gjenopprett din kryptografiske identitet og meldingshistorikk med en gjenopprettingsnøkkel hvis du har mistet alle dine brukte enheter."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Skriv inn gjenopprettingsnøkkel"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Nøkkellagringen din er for øyeblikket ikke synkronisert."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Konfigurer gjenoppretting"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Få tilgang til de krypterte meldingene dine hvis du mister alle enhetene dine eller blir logget ut av %1$s overalt."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Åpne %1$s på en datamaskin"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Logg på kontoen din igjen"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Når du blir bedt om å verifisere din enhet, velger du %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"Tilbakestill alt"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Følg instruksjonene for å opprette en ny gjenopprettingsnøkkel"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Du bør lagre din nye gjenopprettingsnøkkel i en passordbehandler eller i et kryptert notat"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Tilbakestill krypteringen for kontoen din ved hjelp av en annen enhet"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Fortsett tilbakestillingen"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Dine kontodetaljer, kontakter, innstillinger og chatteliste vil bli beholdt"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Du mister all meldingshistorikk som bare er lagret på serveren"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Du må verifisere alle eksisterende enheter og kontakter på nytt"</string>
|
||||
<string name="screen_encryption_reset_footer">"Tilbakestill identiteten din bare hvis du ikke har tilgang til en annen pålogget enhet og du har mistet gjenopprettingsnøkkelen."</string>
|
||||
<string name="screen_encryption_reset_title">"Kan du ikke bekrefte? Du må tilbakestille identiteten din."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Slå av"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Du mister de krypterte meldingene dine hvis du er logget ut av alle enheter."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Er du sikker på at du vil slå av sikkerhetskopiering?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Sletting av nøkkellagring vil fjerne din kryptografiske identitet og meldingsnøkler fra serveren og deaktivere følgende sikkerhetsfunksjoner:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Du vil ikke ha kryptert meldingshistorikk på nye enheter"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Du mister tilgangen til de krypterte meldingene dine hvis du er logget ut av %1$s overalt"</string>
|
||||
<string name="screen_key_backup_disable_title">"Er du sikker på at du vil slå av nøkkellagring og slette den?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Få en ny gjenopprettingsnøkkel hvis du har mistet den eksisterende. Etter at du har endret gjenopprettingsnøkkelen, vil den gamle ikke lenger fungere."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Generer en ny gjenopprettingsnøkkel"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Ikke del dette med noen!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Gjenopprettingsnøkkel endret"</string>
|
||||
<string name="screen_recovery_key_change_title">"Endre gjenopprettingsnøkkelen?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Opprett ny gjenopprettingsnøkkel"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Sørg for at ingen kan se denne skjermen!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Prøv igjen for å verifisere tilgangen til nøkkellageret ditt."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Feil gjenopprettingsnøkkel"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Hvis du har en sikkerhetsnøkkel eller sikkerhetsfrase, vil dette også fungere."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Angi…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Har du mistet gjenopprettingsnøkkelen?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Gjenopprettingsnøkkel bekreftet"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Skriv inn gjenopprettingsnøkkelen din"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Kopiert gjenopprettingsnøkkel"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Genererer…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Lagre gjenopprettingsnøkkelen"</string>
|
||||
<string name="screen_recovery_key_save_description">"Skriv ned denne gjenopprettingsnøkkelen på et trygt sted, for eksempel i en passordbehandler, på en kryptert lapp eller i en fysisk safe."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Trykk for å kopiere gjenopprettingsnøkkelen"</string>
|
||||
<string name="screen_recovery_key_save_title">"Lagre gjenopprettingsnøkkelen på et trygt sted"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Du vil ikke ha tilgang til den nye gjenopprettingsnøkkelen etter dette trinnet."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Har du lagret gjenopprettingsnøkkelen din?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Nøkkellagringen din er beskyttet av en gjenopprettingsnøkkel. Hvis du trenger en ny gjenopprettingsnøkkel etter konfigureringen, kan du opprette den på nytt ved å velge «Endre gjenopprettingsnøkkel»."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Generer gjenopprettingsnøkkelen din"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Ikke del dette med noen!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Gjenopprettingsoppsett vellykket"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Konfigurer gjenoppretting"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Ja, tilbakestill nå"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Denne prosessen kan ikke angres."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Er du sikker på at du vil tilbakestille identiteten din?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"En ukjent feil har oppstått. Vennligst sjekk at passordet ditt er riktig og prøv igjen."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Angi…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Bekreft at du vil tilbakestille identiteten din."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Skriv inn passordet til kontoen din for å fortsette"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Back-up uitschakelen"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Back-up inschakelen"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Sla je cryptografische identiteit en berichtsleutels veilig op de server op. Zo kun je je berichtgeschiedenis bekijken op nieuwe apparaten. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Sleutelopslag"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Herstelsleutel wijzigen"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Voer herstelsleutel in"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Je sleutelopslag is momenteel niet gesynchroniseerd."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Herstelmogelijkheid instellen"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Krijg toegang tot je versleutelde berichten als je al je apparaten kwijtraakt of overal uit %1$s bent uitgelogd."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Open %1$s op een desktopapparaat"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Log opnieuw in op je account"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Wanneer je wordt gevraagd om je apparaat te verifiëren, selecteer %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Alles opnieuw instellen”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Volg de instructies om een nieuwe herstelsleutel te maken"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Sla je nieuwe herstelsleutel op in een wachtwoordmanager of versleutelde notitie"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Stel de versleuteling voor je account opnieuw in met een ander apparaat"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Doorgaan met opnieuw instellen"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Je accountgegevens, contacten, voorkeuren en chatlijst worden bewaard"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Je verliest alle berichtgeschiedenis die alleen op de server is opgeslagen"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Je moet al je bestaande apparaten en contacten opnieuw verifiëren"</string>
|
||||
<string name="screen_encryption_reset_footer">"Stel je identiteit alleen opnieuw in als je geen toegang hebt tot een ander aangemeld apparaat en je je herstelsleutel kwijt bent."</string>
|
||||
<string name="screen_encryption_reset_title">"Kun je dit niet bevestigen? Je zult je identiteit opnieuw moeten instellen."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Uitschakelen"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Je verliest je versleutelde berichten als je bent uitgelogd op alle apparaten."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Weet je zeker dat je de back-up wilt uitschakelen?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Als je de back-up uitschakelt, verwijder je de back-up van je huidige versleuteling en schakel je andere beveiligingsfuncties uit. In dit geval zul je:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Geen berichtgeschiedenis hebben van versleutelde berichten op nieuwe apparaten"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Toegang verliezen tot je versleutelde berichten als je overal uit %1$s bent uitgelogd."</string>
|
||||
<string name="screen_key_backup_disable_title">"Weet je zeker dat je de back-up wilt uitschakelen?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Maak een nieuwe herstelsleutel aan als je je bestaande kwijt bent. Nadat je je herstelsleutel hebt gewijzigd, werkt je oude herstelsleutel niet meer."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Genereer een nieuwe herstelsleutel"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Deel dit met niemand!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Herstelsleutel gewijzigd"</string>
|
||||
<string name="screen_recovery_key_change_title">"Herstelsleutel wijzigen?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Maak een nieuwe herstelsleutel"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Zorg ervoor dat niemand dit scherm kan zien!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Probeer het opnieuw om toegang tot je sleutelopslag te bevestigen."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Onjuiste herstelsleutel"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Als je een beveiligingssleutel of beveiligingszin hebt, werkt dit ook."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Voer in…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Herstelsleutel kwijt?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Herstelsleutel bevestigd"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Herstelsleutel gekopieerd"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Genereren…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Herstelsleutel opslaan"</string>
|
||||
<string name="screen_recovery_key_save_description">"Bewaar je herstelsleutel op een veilige plek, zoals in een wachtwoordbeheerder, een versleutelde notitie of in een fysieke kluis."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Tik om de herstelsleutel te kopiëren"</string>
|
||||
<string name="screen_recovery_key_save_title">"Sla je herstelsleutel op"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Na deze stap kun je je nieuwe herstelsleutel niet meer inzien."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Heb je je herstelsleutel opgeslagen?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Je chatback-up wordt beschermd door een herstelsleutel. Als je na de installatie een nieuwe herstelsleutel nodig hebt, kun je deze opnieuw aanmaken door \'Herstelsleutel wijzigen\' te selecteren."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Genereer je herstelsleutel"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Deel dit met niemand!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Herstelmogelijkheid succesvol ingesteld"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Herstelmogelijkheid instellen"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Ja, nu opnieuw instellen"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Dit proces is onomkeerbaar."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Weet je zeker dat je je identiteit opnieuw wilt instellen?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Er is een onbekende fout opgetreden. Controleer of het wachtwoord van je account juist is en probeer het opnieuw."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Voer in…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Bevestig dat je je identiteit opnieuw wilt instellen."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Voer het wachtwoord van je account in om verder te gaan"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Wyłącz backup"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Włącz backup"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Bezpiecznie przechowuj swoją tożsamość kryptograficzną i klucze wiadomości na serwerze. Umożliwi to przeglądanie historii wiadomości na każdym nowym urządzeniu. %1$s"</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Magazyn kluczy"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Magazyn kluczy musi być włączony, aby włączyć przywracanie."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Prześlij klucze z tego urządzenia"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Zezwól na magazynowanie kluczy"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Zmień klucz przywracania"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Odzyskaj swoją tożsamość kryptograficzną i historię wiadomości za pomocą klucza przywracania, jeśli utraciłeś dostęp do wszystkich swoich urządzeń."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Wprowadź klucz przywracania"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Magazyn kluczy nie jest zsynchronizowany."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Skonfiguruj przywracanie"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Uzyskaj dostęp do swoich wiadomości szyfrowanych, jeśli utracisz wszystkie swoje urządzenia lub zostaniesz wylogowany z %1$s."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Otwórz %1$s na urządzeniu stacjonarnym"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Zaloguj się ponownie na swoje konto"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Gdy pojawi się prośba o weryfikację urządzenia, wybierz %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Resetuj wszystko”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Postępuj zgodnie z instrukcjami, aby utworzyć nowy klucz przywracania"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Zapisz nowy klucz przywracania w menedżerze haseł lub notatce szyfrowanej"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Resetuj szyfrowanie swojego konta za pomocą drugiego urządzenia"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Kontynuuj resetowanie"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Szczegóły konta, kontakty, preferencje i lista czatów zostaną zachowane"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Utracisz istniejącą historię wiadomości"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Wymagana będzie ponowna weryfikacja istniejących urządzeń i kontaktów"</string>
|
||||
<string name="screen_encryption_reset_footer">"Zresetuj swoją tożsamość tylko wtedy, gdy nie jesteś zalogowany na żadnym urządzeniu i straciłeś swój klucz przywracania."</string>
|
||||
<string name="screen_encryption_reset_title">"Zresetuj swoją tożsamość, jeśli nie możesz jej potwierdzić w inny sposób"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Wyłącz"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Jeśli wylogujesz się ze wszystkich urządzeń, stracisz wszystkie wiadomości szyfrowane."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Czy na pewno chcesz wyłączyć backup?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Wyłączenie backupu spowoduje usunięcie kopii klucza szyfrowania i wyłączenie innych funkcji bezpieczeństwa. W takim przypadku będziesz:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Posiadał historii wiadomości szyfrowanych na nowych urządzeniach"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Utracisz dostęp do wiadomości szyfrowanych, jeśli zostaniesz wszędzie wylogowany z %1$s"</string>
|
||||
<string name="screen_key_backup_disable_title">"Czy na pewno chcesz wyłączyć backup?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Uzyskaj nowy klucz przywracania, jeśli straciłeś dostęp do obecnego. Po zmianie klucza przywracania stary nie będzie już działał."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Generuj nowy klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Nie udostępniaj tego nikomu!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Zmieniono klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_change_title">"Zmienić klucz przywracania?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Utwórz nowy klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Upewnij się, że nikt nie widzi tego ekranu!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Spróbuj ponownie potwierdzić dostęp do magazynu kluczy."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Nieprawidłowy klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"To też zadziała, jeśli posiadasz klucz lub frazę bezpieczeństwa."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Wprowadź…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Zgubiłeś swój kod przywracania?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Potwierdzono klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Wprowadź klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Skopiowano klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Generuję…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Zapisz klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_save_description">"Zapisz klucz przywracania w bezpiecznym miejscu, np. w menedżerze haseł, notatce szyfrowanej lub sejfie."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Stuknij, by skopiować klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_save_title">"Zapisz klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Po tym kroku nie będziesz mieć dostępu do nowego klucza przywracania."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Czy zapisałeś swój klucz przywracania?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Backup czatu jest chroniony przez klucz przywracania. Jeśli potrzebujesz utworzyć nowy klucz, możesz to zrobić wybierając `Zmień klucz przywracania`."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Wygeneruj klucz przywracania"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Nie udostępniaj tego nikomu!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Skonfigurowano przywracanie pomyślnie"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Skonfiguruj przywracanie"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Tak, zresetuj teraz"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Tego procesu nie można odwrócić."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Czy na pewno chcesz zresetować szyfrowanie?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Wystąpił nieznany błąd. Sprawdź, czy hasło jest poprawne i spróbuj ponownie."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Wprowadź…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Potwierdź, że chcesz zresetować szyfrowanie."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Wprowadź hasło, aby kontynuować"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Apagar o armazenamento de chaves"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Ativar o backup"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Armazene sua identidade criptográfica e chaves de mensagem com segurança no servidor. Isso permitirá que você visualize seu histórico de mensagens em dispositivos futuros. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Armazenamento de chaves"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"O armazenamento de chaves deve ser ativado para configurar a recuperação."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Enviar chaves a partir deste dispositivo"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Permitir o armazenamento de chaves"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Alterar chave de recuperação"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Recupere sua identidade criptográfica e o histórico de mensagens com uma chave de recuperação, caso você tenha perdido todos os dispositivos existentes."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Digitar chave de recuperação"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Seu armazenamento de chaves está fora de sincronia no momento."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Configurar a recuperação"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Tenha acesso às suas mensagens criptografadas se você perder todos os seus dispositivos ou for desconectado do %1$s em todos os dispositivos."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Abra o %1$s em um computador"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Entre na sua conta novamente"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Ao ser solicitado para verificar o seu dispositivo, selecione %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"\"Redefinir tudo\""</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Siga as instruções para criar uma nova chave de recuperação"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Salve sua nova chave de recuperação em um gerenciador de senhas ou em uma nota criptografada"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Redefinir a criptografia da sua conta usando outro dispositivo"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Continuar a redefinição"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Os detalhes da sua conta, contatos, preferências e lista de conversas serão mantidos"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Você perderá qualquer histórico de mensagens armazenado somente no servidor"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Você precisará verificar todos os seus dispositivos e contatos existentes novamente."</string>
|
||||
<string name="screen_encryption_reset_footer">"Redefina sua identidade somente se você não tiver acesso a outro dispositivo conectado e se tiver perdido sua chave de recuperação."</string>
|
||||
<string name="screen_encryption_reset_title">"Não consegue confirmar? Você precisará redefinir sua identidade."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Desativar"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Você perderá suas mensagens criptografadas se for desconectado de todos os dispositivos."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Tem certeza de que deseja desativar o backup?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Ao apagar o armazenamento de chaves, a sua identidade criptográfica e as chaves das mensagens serão apagadas do servidor e os seguintes recursos de segurança serão desativados:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Você não terá o histórico de mensagens criptografadas em dispositivos novos"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Você perderá o acesso às suas mensagens criptografadas se for desconectado de %1$s em todos os dispositivos"</string>
|
||||
<string name="screen_key_backup_disable_title">"Tem certeza de que deseja desativar o armazenamento de chaves e apagá-lo?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Obtenha uma nova chave de recuperação caso tenha perdido a existente. Depois de alterar sua chave de recuperação, a antiga não funcionará mais."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Gerar uma nova chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Não compartilhe isso com ninguém!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Chave de recuperação alterada"</string>
|
||||
<string name="screen_recovery_key_change_title">"Alterar chave de recuperação?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Criar uma nova chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Certifique-se de que ninguém possa ver essa tela!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Tente novamente para confirmar o acesso ao seu armazenamento de chaves."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Chave de recuperação incorreta"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Se você tiver uma chave de segurança ou frase de segurança, isso também funcionará."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Digite…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Perdeu sua chave de recuperação?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Chave de recuperação confirmada"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Digite sua chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Chave de recuperação copiada"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Gerando…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Salvar chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_save_description">"Anote essa chave de recuperação em algum lugar seguro, como um gerenciador de senhas, uma nota criptografada ou um cofre físico."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Toque para copiar a chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_save_title">"Guarde sua chave de recuperação em um lugar seguro"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Você não poderá acessar sua nova chave de recuperação após essa etapa."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Você salvou sua chave de recuperação?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Seu armazenamento de chaves é protegido por uma chave de recuperação. Se precisar de uma nova chave de recuperação após a configuração, você pode recriá-la selecionando “Alterar chave de recuperação”."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Gere sua chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Não compartilhe isso com ninguém!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Configuração de recuperação bem-sucedida"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Configurar a recuperação"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Sim, redefinir agora"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Esse processo é irreversível."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Você tem certeza de que deseja redefinir sua identidade?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Ocorreu um erro desconhecido. Verifique se a senha da sua conta está correta e tente novamente."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Digite…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Confirme que você deseja redefinir sua identidade."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Digite a senha de sua conta para continuar"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Desativar a cópia de segurança"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Ativar a cópia de segurança"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Guarda a tua identidade criptográfica e as chaves de mensagens de forma segura no servidor. Isto permitir-te-á ver o teu histórico de mensagens em qualquer dispositivo novo. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Armazenamento de chaves"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"O armazenamento de chaves deve ser ativado para configurar a recuperação."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Carrega chaves a partir deste dispositivo"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Permite o armazenamento de chaves"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Alterar chave de recuperação"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Recupera a tua identidade criptográfica e o histórico de mensagens com uma chave de recuperação, caso tenhas perdido todos os teus dispositivos existentes."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Insere a chave de recuperação"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"O teu armazenamento de chaves está atualmente dessincronizado."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Configurar recuperação"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Obtém acesso às tuas mensagens cifradas mesmo se perderes todos os teus dispositivos ou se terminares todas as tuas sessões %1$s."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Abre a %1$s num computador"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Iniciar sessão novamente"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Quando te for pedido para verificares o teu dispositivo, seleciona %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Repor tudo”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Segue as instruções para criar uma nova chave de recuperação"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Guarda a tua nova chave de recuperação num gestor de senhas ou numa nota cifrada"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Repor a cifragem da tua conta utilizando outro dispositivo"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Continuar a reposição"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Os detalhes da tua conta, contactos, preferências e lista de conversas serão mantidos."</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Perderás o acesso ao teu histórico de mensagens existente"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Necessitarás de verificar todos os teus dispositivos e contactos novamente."</string>
|
||||
<string name="screen_encryption_reset_footer">"Repõe a tua identidade apenas se não tiveres acesso a mais nenhum dispositivo com sessão iniciada e se tiveres perdido a tua chave de recuperação."</string>
|
||||
<string name="screen_encryption_reset_title">"Repõe a tua identidade caso não consigas confirmar de outra forma"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Desligar"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Perderás as tuas mensagens cifradas se tiveres terminado a sessão em todos os teus dispositivos."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Tens a certeza que queres desativar a cópia de segurança?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Desativar a cópia de segurança irá remover a atual cópia da chave de cifragem e desativar outras funcionalidades de segurança. Neste caso, irás:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Não ter o histórico de mensagens cifradas em novos dispositivos"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Perder o acesso às tuas mensagens cifradas se terminares todas as sessões %1$s"</string>
|
||||
<string name="screen_key_backup_disable_title">"Tens a certeza que queres desativar a cópia de segurança?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Obtém uma nova chave de recuperação se tiveres perdido a atual. Depois de a alterares, a antiga deixará de funcionar."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Gerar uma nova chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Não partilhes isto com ninguém!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Chave de recuperação alterada"</string>
|
||||
<string name="screen_recovery_key_change_title">"Alterar a chave de recuperação?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Criar nova chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Certifica-te de que ninguém consegue ver esta página!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Tenta novamente para confirmar o acesso ao teu armazenamento de chaves."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Chave de recuperação incorreta"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Também funciona se tiveres uma chave ou frase de segurança."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Inserir…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Perdeste a tua chave?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Chave de recuperação confirmada"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Introduz a tua chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Chave de recuperação copiada"</string>
|
||||
<string name="screen_recovery_key_generating_key">"A gerar…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Guardar chave"</string>
|
||||
<string name="screen_recovery_key_save_description">"Anota esta chave de recuperação num local seguro, como um gestor de palavras-passe, uma nota encriptada ou um cofre físico."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Toca para copiar a chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_save_title">"Guarda a tua chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Não poderás aceder à tua nova chave de recuperação após este passo."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Guardaste a tua chave de recuperação?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"A tua cópia de segurança das conversas está protegida por uma chave de recuperação. Se precisares de uma nova chave após a configuração, podes recriá-la selecionando \"Alterar chave de recuperação\"."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Gerar a tua chave de recuperação"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Não partilhes isto com ninguém!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Recuperação configurada com sucesso"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Configurar recuperação"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Sim, repor agora"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Este processo é irreversível."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Tens a certeza que pretendes repor a tua cifra?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Um erro desconhecido aconteceu. Verifique se a senha da sua conta está correta e tente novamente."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Inserir…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Confirma que pretendes realmente repor a tua cifra."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Insere a tua palavra-passe para continuares"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Dezactivați backupul"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Activați backupul"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Stocați identitatea criptografică și cheile de mesaje în siguranță pe server. Acest lucru vă va permite să vizualizați mesajele anterioare pe orice dispozitiv nou. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Backup"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Stocarea cheilor trebuie activată pentru a configura recuperarea."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Încărcați cheile de pe acest dispozitiv"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Permiteți stocarea cheilor"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Schimbați cheia de recuperare"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Recuperați-vă identitatea criptografică și mesajele anterioare cu o cheie de recuperare dacă ați pierdut toate dispozitivele existente."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Introduceți cheia de recuperare"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Backup-ul pentru chat nu este sincronizat în prezent."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Configurați recuperarea"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Obțineți acces la mesajele dumneavoastră criptate dacă vă pierdeți toate dispozitivele sau sunteți deconectat de la %1$s peste tot."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Deschideți %1$s pe un dispozitiv desktop"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Conectați-vă din nou la contul dumneavoastră"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Când vi se cere să vă verificați dispozitivul, selectați%1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"„Resetați tot”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Urmați instrucțiunile pentru a crea o nouă cheie de recuperare"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Salvați noua cheie de recuperare într-un manager de parole sau o notă criptată"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Resetați criptarea contului dumneavoastră folosind un alt dispozitiv"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Continuați resetarea"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Detaliile contului, contactele, preferințele și lista de chat vor fi păstrate"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Veți pierde mesajele anterioare care au fost stocate doar pe server"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Va trebui să verificați din nou toate dispozitivele și contactele existente"</string>
|
||||
<string name="screen_encryption_reset_footer">"Resetați-vă identitatea numai dacă nu aveți acces la un alt dispozitiv conectat și ați pierdut cheia de recuperare."</string>
|
||||
<string name="screen_encryption_reset_title">"Nu puteți confirma? Va trebui să vă resetați identitatea."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Dezactivare"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Veți pierde mesajele criptate dacă sunteți deconectat de pe toate dispozitivele."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Sunteți sigur că doriți să dezactivați backup-ul?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Dezactivarea backup-ului va șterge backup-ul curent și va dezactiva alte măsuri de securitate. În acest caz, veți:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Nu veți avea mesajele anterioare criptate pe dispozitive noi"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Veți pierde accesul la mesajele criptate dacă sunteți deconectat de pe %1$s peste tot"</string>
|
||||
<string name="screen_key_backup_disable_title">"Sunteți sigur că doriți să dezactivați backup-ul?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Obțineți o nouă cheie de recuperare dacă ați pierdut-o pe cea existentă. După schimbarea cheii de recuperare, cea veche nu va mai funcționa."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Generați o nouă cheie de recuperare"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Nu împărtășiți cheia cu nimeni!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Cheia de recuperare a fost schimbată"</string>
|
||||
<string name="screen_recovery_key_change_title">"Schimbați cheia de recuperare?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Creați o nouă cheie de recuperare"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Asigurați-vă că nimeni nu poate vedea acest ecran!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Vă rugăm să încercați din nou să confirmați accesul la backup."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Cheie de recuperare incorectă"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Dacă aveți o cheie de securitate sau o frază de securitate, aceasta va funcționa și ea."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Introduceți…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Ați pierdut cheia de recuperare?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Cheia de recuperare confirmată"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Introduceți cheia de recuperare"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Cheia de recuperare copiată"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Se generează…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Salvați cheia de recuperare"</string>
|
||||
<string name="screen_recovery_key_save_description">"Notați cheia de recuperare undeva în siguranță sau salvați-o într-un manager de parole."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Apăsați pentru a copia cheia de recuperare"</string>
|
||||
<string name="screen_recovery_key_save_title">"Salvați cheia de recuperare"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Nu veți putea accesa noua cheie de recuperare după acest pas."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Ați salvat cheia de recuperare?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Backup-ul pentru chat este protejat de o cheie de recuperare. Dacă aveți nevoie de o nouă cheie de recuperare după configurare, puteți să o recreați selectând „Schimbați cheia de recuperare”."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Generați cheia de recuperare"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Nu împărtășiți cheia cu nimeni!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Configurarea recuperării a reușit"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Configurați recuperarea"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Da, resetați acum"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Acest proces este ireversibil."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Sunteți sigur că doriți să vă resetați identitatea?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"S-a produs o eroare necunoscută. Vă rugăm să verificați dacă parola contului dvs. este corectă și să încercați din nou."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Introduceți…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Confirmați că doriți să vă resetați identitatea."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Introduceți parola contului pentru a continua"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Удалить хранилище ключей"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Включить резервное копирование"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Сохраните вашу криптографическую идентификацию и ключи сообщений в безопасности на сервере. Это позволит вам просматривать историю сообщений на любых новых устройствах.%1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Хранилище ключей"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Для настройки восстановления необходимо включить хранилище ключей."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Загрузить ключи с этого устройства"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Разрешить хранение ключей"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Изменить ключ восстановления"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Если вы потеряли все существующие устройства, то сможете восстановить свою криптографическую идентификацию и историю сообщений с помощью ключа восстановления"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Введите ключ восстановления"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"В настоящее время резервная копия ваших чатов не синхронизирована."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Настроить восстановление"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Получите доступ к зашифрованным сообщениям, если вы потеряете все свои устройства или выйдете из системы %1$s отовсюду."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Откройте %1$s на компьютере"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Войдите в свой аккаунт еще раз"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Когда вас попросят подтвердить устройство, выберите %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Сбросить все”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Следуйте инструкциям, чтобы создать новый ключ восстановления"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Сохраните новый ключ восстановления в менеджере паролей или зашифрованной заметке"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Сбросьте шифрование вашей учетной записи с помощью другого устройства."</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Продолжить сброс"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Данные вашей учетной записи, контакты, настройки и список чатов будут сохранены"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Вы потеряете существующую историю сообщений"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Вам нужно будет заново подтвердить все существующие устройства и контакты."</string>
|
||||
<string name="screen_encryption_reset_footer">"Сбрасывайте данные только в том случае, если у вас нет доступа к другому устройству, на котором выполнен вход, и вы потеряли ключ восстановления."</string>
|
||||
<string name="screen_encryption_reset_title">"Сбросьте ключи подтверждения, если вы не можете подтвердить свою личность другим способом."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Выключить"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Вы потеряете зашифрованные сообщения, если выйдете из всех устройств."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Вы действительно хотите отключить резервное копирование?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Удаление хранилища ключей приведёт к удалению вашей криптографической идентификации и ключей сообщений с сервера, а также отключению следующих функций безопасности:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Нет зашифрованной истории сообщений на новых устройствах"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Вы потеряете доступ к зашифрованным сообщениям, если выйдете из %1$s везде"</string>
|
||||
<string name="screen_key_backup_disable_title">"Вы уверены, что хотите отключить хранение ключей и удалить их?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Получите новый ключ восстановления, если вы потеряли существующий. После смены ключа восстановления старый ключ больше не будет работать."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Создать новый ключ восстановления"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Не сообщайте эту информацию никому!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Ключ восстановления изменен"</string>
|
||||
<string name="screen_recovery_key_change_title">"Изменить ключ восстановления?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Создать новый ключ восстановления"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Убедитесь, что никто не видит этот экран!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Пожалуйста, попробуйте еще раз, чтобы подтвердить доступ к резервной копии чата."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Неверный ключ восстановления"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Если у вас есть пароль для восстановления или секретный пароль/ключ, это тоже сработает."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Вход…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Потеряли ключ восстановления?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Ключ восстановления подтвержден"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Введите ключ восстановления"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Ключ восстановления скопирован"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Генерация…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Сохранить ключ восстановления"</string>
|
||||
<string name="screen_recovery_key_save_description">"Запишите данный ключ восстановления в безопасном месте, например в диспетчере паролей, зашифрованной заметке или физическом сейфе."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Нажмите, чтобы скопировать ключ восстановления"</string>
|
||||
<string name="screen_recovery_key_save_title">"Сохраните ключ восстановления"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"После этого шага вы не сможете получить доступ к новому ключу восстановления."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Вы сохранили ключ восстановления?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Ваше хранилище ключей защищено ключом восстановления. Если после настройки вам понадобится новый ключ восстановления, вы можете его пересоздать, выбрав «Изменить ключ восстановления»."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Создайте ключ восстановления"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Не сообщайте эту информацию никому!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Настройка восстановления выполнена успешно"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Настроить восстановление"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Да, сбросить сейчас"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Этот процесс необратим."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Вы действительно хотите сбросить шифрование?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Произошла неизвестная ошибка. Проверьте правильность пароля учетной записи и повторите попытку."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Вход…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Подтвердите, что вы хотите сбросить шифрование."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Введите пароль своей учетной записи, чтобы продолжить"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Vypnúť zálohovanie"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Zapnúť zálohovanie"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Uložte svoju kryptografickú identitu a kľúče správ bezpečne na server. To vám umožní zobraziť históriu správ na všetkých nových zariadeniach. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Úložisko kľúčov"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Úložisko kľúčov musí byť zapnuté, aby bolo možné nastaviť obnovenie."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Nahrať kľúče z tohto zariadenia"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Povoliť úložisko kľúčov"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Zmeniť kľúč na obnovenie"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Obnovte svoju kryptografickú totožnosť a históriu správ pomocou kľúča na obnovenie, ak ste stratili všetky svoje existujúce zariadenia."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Zadajte kľúč na obnovenie"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Vaše úložisko kľúčov nie je momentálne synchronizované."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Nastaviť obnovenie"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Získajte prístup k vašim šifrovaným správam aj keď stratíte všetky svoje zariadenia alebo sa odhlásite zo všetkých %1$s zariadení."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Otvoriť %1$s v stolnom počítači"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Znova sa prihláste do svojho účtu"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Keď sa zobrazí výzva na overenie vášho zariadenia, vyberte %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"\"Obnoviť všetko\""</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Postupujte podľa pokynov na vytvorenie nového kľúča na obnovenie"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Uložte si nový kľúč na obnovenie do správcu hesiel alebo do zašifrovanej poznámky"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Obnovte šifrovanie vášho účtu pomocou iného zariadenia"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Pokračovať v obnovovaní"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Údaje o vašom účte, kontakty, predvoľby a zoznam konverzácií budú zachované"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Stratíte svoju existujúcu históriu správ"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Budete musieť znova overiť všetky existujúce zariadenia a kontakty"</string>
|
||||
<string name="screen_encryption_reset_footer">"Obnovte svoju totožnosť iba vtedy, ak nemáte prístup k inému prihlásenému zariadeniu a stratili ste kľúč na obnovenie."</string>
|
||||
<string name="screen_encryption_reset_title">"Znovu nastavte svoju totožnosť v prípade, že ju nemôžete potvrdiť iným spôsobom"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Vypnúť"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Stratíte prístup k svojim zašifrovaným správam, ak sa odhlásite zo všetkých zariadení"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Ste si istí, že chcete vypnúť zálohovanie?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Vypnutím zálohovania sa odstráni aktuálna záloha šifrovacích kľúčov a vypnú sa ďalšie bezpečnostné funkcie. V tomto prípade:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Na nových zariadeniach nebudete mať zašifrovanú históriu správ"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Stratíte prístup k svojim zašifrovaným správam, ak sa odhlásite z aplikácie %1$s na všetkých zariadeniach"</string>
|
||||
<string name="screen_key_backup_disable_title">"Ste si istí, že chcete vypnúť zálohovanie?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Získajte nový kľúč na obnovenie, ak ste stratili svoj existujúci. Po zmene kľúča na obnovenie už starý kľúč nebude fungovať."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Vygenerovať nový kľúč na obnovenie"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Nezdieľajte to s nikým!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Kľúč na obnovenie bol zmenený"</string>
|
||||
<string name="screen_recovery_key_change_title">"Zmeniť kľúč na obnovenie?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Vytvoriť nový kľúč na obnovenie"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Uistite sa, že túto obrazovku nikto nevidí!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Skúste prosím znova potvrdiť prístup k úložisku kľúčov."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Nesprávny kľúč na obnovenie"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Ak máte bezpečnostný kľúč alebo bezpečnostnú frázu, bude to fungovať tiež."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Zadať…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Stratili ste kľúč na obnovenie?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Kľúč na obnovu potvrdený"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Zadajte kľúč na obnovenie"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Skopírovaný kľúč na obnovenie"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Generovanie…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Uložiť kľúč na obnovenie"</string>
|
||||
<string name="screen_recovery_key_save_description">"Zapíšte si tento kľúč na obnovenie na bezpečné miesto, napríklad do správcu hesiel, šifrovanej poznámky alebo fyzického trezoru."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Ťuknutím skopírujte kľúč na obnovenie"</string>
|
||||
<string name="screen_recovery_key_save_title">"Uložte svoj kľúč na obnovenie"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Po tomto kroku nebudete mať prístup k novému kľúču na obnovenie."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Uložili ste kľúč na obnovenie?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Vaša záloha konverzácie je chránená kľúčom na obnovenie. Ak potrebujete nový kľúč na obnovenie, po nastavení si ho môžete znova vytvoriť výberom položky „Zmeniť kľúč na obnovenie“."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Vygenerujte si váš kľúč na obnovenie"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Nezdieľajte to s nikým!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Úspešné nastavenie obnovy"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Nastaviť obnovenie"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Áno, znovu nastaviť teraz"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Tento proces je nezvratný."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Naozaj chcete obnoviť svoje šifrovanie?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Nastala neznáma chyba. Skontrolujte, či je heslo vášho účtu správne a skúste to znova."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Zadať…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Potvrďte, že chcete obnoviť svoje šifrovanie."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Ak chcete pokračovať, zadajte heslo účtu"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Stäng av säkerhetskopiering"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Slå på säkerhetskopiering"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Lagra din kryptografiska identitet och dina meddelandenycklar säkert på servern. Detta gör att du kan se din meddelandehistorik på alla nya enheter. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Nyckellagring"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Nyckellagring måste vara aktiverat för att konfigurera återställning."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Ladda upp nycklar från den här enheten"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Tillåt lagring av nycklar"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Byt återställningsnyckel"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Återställ din kryptografiska identitet och meddelandehistorik med en återställningsnyckel om du har tappat bort alla dina befintliga enheter."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Ange återställningsnyckel"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Din nyckellagring är för närvarande osynkroniserad."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Ställ in återställning"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Få tillgång till dina krypterade meddelanden om du tappar bort alla dina enheter eller blir utloggad ur %1$s överallt."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Öppna %1$s på en skrivbordsenhet"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Logga in på ditt konto igen"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"När du ombeds att verifiera din enhet, välj %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"”Återställ alla”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Följ anvisningarna för att skapa en ny återställningsnyckel"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Spara din nya återställningsnyckel i en lösenordshanterare eller krypterad anteckning"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Återställ krypteringen för ditt konto med en annan enhet"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Fortsätt återställning"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Dina kontouppgifter, kontakter, inställningar och chattlistor kommer bevaras"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Du kommer att förlora din befintliga meddelandehistorik"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Du måste verifiera alla dina befintliga enheter och kontakter igen"</string>
|
||||
<string name="screen_encryption_reset_footer">"Återställ bara din identitet om du inte har tillgång till en annan inloggad enhet och du har tappat bort din återställningsnyckel."</string>
|
||||
<string name="screen_encryption_reset_title">"Återställ din identitet ifall du inte kan bekräfta på annat sätt"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Stäng av"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Du kommer att förlora dina krypterade meddelanden om du loggas ut från alla enheter."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Är du säker på att du vill stänga av säkerhetskopiering?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Om du stänger av säkerhetskopiering tas din nuvarande säkerhetskopiering av krypteringsnycklar bort och andra säkerhetsfunktioner stängs av. I det här fallet kommer du att:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Inte ha krypterad meddelandehistorik på nya enheter"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Förlora åtkomsten till dina krypterade meddelanden om du loggas ut ur %1$s överallt"</string>
|
||||
<string name="screen_key_backup_disable_title">"Är du säker på att du vill stänga av säkerhetskopiering?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Få en ny återställningsnyckel om du har tappat bort din befintliga. När du har bytt din återställningsnyckel fungerar din gamla inte längre."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Generera en ny återställningsnyckel"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Dela inte detta med någon!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Återställningsnyckel ändrad"</string>
|
||||
<string name="screen_recovery_key_change_title">"Byt återställningsnyckel?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Skapa ny återställningsnyckel"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Se till att ingen kan se den här skärmen"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Vänligen pröva igen för att bekräfta åtkomsten till din nyckellagring."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Felaktig återställningsnyckel"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Om du har en säkerhetsnyckel eller säkerhetsfras så funkar den också."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Ange …"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Blivit av med din återställningsnyckel?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Återställningsnyckel bekräftad"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Ange din återställningsnyckel"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Kopierade återställningsnyckel"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Genererar …"</string>
|
||||
<string name="screen_recovery_key_save_action">"Spara återställningsnyckeln"</string>
|
||||
<string name="screen_recovery_key_save_description">"Skriv ner den här återställningsnyckeln någonstans säkert, som en lösenordshanterare, en krypterad anteckning eller ett kassaskåp."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Tryck för att kopiera återställningsnyckeln"</string>
|
||||
<string name="screen_recovery_key_save_title">"Spara din återställningsnyckel"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Du kommer inte att kunna komma åt din nya återställningsnyckel efter det här steget."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Har du sparat din återställningsnyckel?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Din chattsäkerhetskopia skyddas av en återställningsnyckel. Om du behöver en ny återställningsnyckel efter installationen kan du återskapa genom att välja ”Byt återställningsnyckel”."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Generera din återställningsnyckel"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Dela inte detta med någon!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Konfiguration av återställning lyckades"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Ställ in återställning"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Ja, återställ nu"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Denna process är irreversibel."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Är du säker på att du vill återställa din kryptering?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Ett okänt fel inträffade. Kontrollera att ditt kontolösenord är korrekt och försök igen."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Ange …"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Bekräfta att du vill återställa din kryptering."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Ange ditt kontolösenord för att fortsätta"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Anahtar depolamasını sil"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Yedeklemeyi aç"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Kriptografik kimliğinizi ve mesaj anahtarlarınızı sunucuda güvenli bir şekilde saklayın. Bu, mesaj geçmişinizi herhangi bir yeni cihazda görüntülemenize olanak tanır. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Anahtar Depolama"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Kurtarmayı ayarlamak için anahtar depolama alanı açık olmalıdır."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Anahtarları bu cihazdan yükle"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Anahtar depolamaya izin ver"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Kurtarma anahtarını değiştir"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Mevcut tüm cihazlarınızı kaybettiyseniz, kurtarma anahtarıyla şifreleme kimliğinizi ve mesaj geçmişinizi kurtarın."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Kurtarma anahtarını girin"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Anahtar depolama alanınız şu anda senkronize değil."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Kurtarmayı ayarlayın"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Tüm cihazlarınızı kaybettiğinizde veya %1$s adresinden çıkış yaptığınızda şifrelenmiş mesajlarınıza her yerden erişin."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Masaüstü cihazında aç %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Hesabınızda tekrar oturum açın"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Cihazınızı doğrulamanız istendiğinde %1$s öğesini seçin"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"\"Tümünü sıfırla\""</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Yeni bir kurtarma anahtarı oluşturmak için talimatları izleyin"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Yeni kurtarma anahtarınızı bir parola yöneticisine veya şifreli bir nota kaydedin"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Hesabınızın şifrelemesini başka bir cihaz kullanarak sıfırlayın"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Sıfırlamaya devam et"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Hesap bilgileriniz, kişileriniz, tercihleriniz ve sohbet listeniz saklanacaktır"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Yalnızca sunucuda depolanan mesaj geçmişlerini kaybedeceksiniz"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Mevcut tüm cihazlarınızı ve kişilerinizi tekrar doğrulamanız gerekecek"</string>
|
||||
<string name="screen_encryption_reset_footer">"Kimliğinizi yalnızca oturum açtığınız başka bir cihaza erişiminiz yoksa ve kurtarma anahtarınızı kaybettiyseniz sıfırlayın."</string>
|
||||
<string name="screen_encryption_reset_title">"Onaylayamıyor musunuz? Kimliğinizi sıfırlamanız gerekecek."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Kapat"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Tüm cihazlardan çıkış yaparsanız şifrelenmiş mesajlarınızı kaybedersiniz."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Yedeklemeyi kapatmak istediğinizden emin misiniz?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Anahtar depolamanın silinmesi kriptografik kimliğinizi ve mesaj anahtarlarınızı sunucudan kaldıracak ve aşağıdaki güvenlik özelliklerini kapatacaktır:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Yeni cihazlarda şifrelenmiş mesaj geçmişine sahip olmayacaksınız"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"%1$s adresinden her yerde oturumunuzu kapatırsanız şifrelenmiş mesajlarınıza erişiminizi kaybedersiniz"</string>
|
||||
<string name="screen_key_backup_disable_title">"Anahtar depolamayı kapatmak ve silmek istediğinizden emin misiniz?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Mevcut kurtarma anahtarınızı kaybettiyseniz yeni bir kurtarma anahtarı alın. Kurtarma anahtarınızı değiştirdikten sonra eski anahtarınız artık çalışmayacaktır."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Yeni bir kurtarma anahtarı oluştur"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Bunu kimseyle paylaşmayın!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Kurtarma anahtarı değiştirildi"</string>
|
||||
<string name="screen_recovery_key_change_title">"Kurtarma anahtarını değiştir?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Yeni kurtarma anahtarı oluştur"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Bu ekranı kimsenin göremediğinden emin olun!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Anahtar depolama alanınıza erişimi onaylamak için lütfen tekrar deneyin."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Yanlış kurtarma anahtarı"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Bir güvenlik anahtarınız veya güvenlik ifadeniz varsa, bu da işe yarayacaktır."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Gir…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Kurtarma anahtarınızı mı kaybettiniz?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Kurtarma anahtarı onaylandı"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Kurtarma anahtarınızı girin"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Kurtarma anahtarı kopyalandı"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Oluşturuluyor…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Kurtarma anahtarını kaydet"</string>
|
||||
<string name="screen_recovery_key_save_description">"Bu kurtarma anahtarını şifre yöneticisi, şifreli not veya fiziksel kasa gibi güvenli bir yere kaydedin."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Kurtarma anahtarını kopyalamak için dokunun"</string>
|
||||
<string name="screen_recovery_key_save_title">"Kurtarma anahtarınızı güvenli bir yere kaydedin"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Bu adımdan sonra yeni kurtarma anahtarınıza erişemeyeceksiniz."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Kurtarma anahtarınızı kaydettiniz mi?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Anahtar depolama alanınız bir kurtarma anahtarıyla korunmaktadır. Kurulumdan sonra yeni bir kurtarma anahtarına ihtiyacınız olursa, \"Kurtarma anahtarını değiştir\"i seçerek yeniden oluşturabilirsiniz."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Kurtarma anahtarınızı oluşturun"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Bunu kimseyle paylaşmayın!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Kurtarma kurulumu başarılı"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Kurtarmayı ayarlayın"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Evet, şimdi sıfırla"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Bu işlem geri alınamaz."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Kimliğinizi sıfırlamak istediğinizden emin misiniz?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Bilinmeyen bir hata oluştu. Lütfen hesap şifrenizin doğru olup olmadığını kontrol edin ve tekrar deneyin."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Gir…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Kimliğinizi sıfırlamak istediğinizi onaylayın."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Devam etmek için hesap şifrenizi girin"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Вимкнути резервне копіювання"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Увімкнути резервне копіювання"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Зберігайте свій криптографічний ідентифікатор і ключі повідомлень на сервері. Це дозволить вам переглядати історію повідомлень на будь-яких нових пристроях. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Резервне копіювання"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Щоб налаштувати відновлення, потрібно ввімкнути зберігання ключів."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Завантажте ключі з цього пристрою"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Дозволити зберігання ключів"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Змінити ключ відновлення"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Відновіть криптографічну ідентичність та історію повідомлень за допомогою ключа відновлення, якщо ви втратили всі наявні пристрої."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Введіть ключ відновлення"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Сховище ключів наразі не синхронізовано."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Налаштувати відновлення"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Отримайте доступ до своїх зашифрованих повідомлень, якщо ви втратите всі свої пристрої або вийшли з %1$s на всіх пристроях."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Відкрийте %1$s на комп\'ютері"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Увійдіть до вашого облікового запису знову"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Коли вас попросять підтвердити пристрій, виберіть %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Скинути все”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Дотримуйтесь інструкцій, щоб створити новий ключ відновлення"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Збережіть новий ключ відновлення у менеджері паролів або зашифрованій нотатці"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Скинути шифрування облікового запису за допомогою іншого пристрою"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Продовжити скидання налаштувань"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Дані вашого облікового запису, контакти, налаштування й бесіди будуть збережені"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Ви втратите свою наявну історію повідомлень"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Вам доведеться верифікувати всі наявні пристрої та контакти повторно"</string>
|
||||
<string name="screen_encryption_reset_footer">"Скидайте ідентичність тільки якщо ви не маєте доступу до інших пристроїв в обліковому записі та втратили свій ключ відновлення."</string>
|
||||
<string name="screen_encryption_reset_title">"Не можете підтвердити? Вам доведеться скинути свою ідентичність."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Вимкнути"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Ви втратите зашифровані повідомлення, якщо вийдете з усіх пристроїв."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Ви впевнені, що хочете вимкнути резервне копіювання?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Вимкнення резервного копіювання призведе до видалення поточної резервної копії ключа шифрування та вимкнення інших функцій безпеки. В такому разі ви:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Не матимете історії зашифрованих повідомлень на нових пристроях"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Втратите доступ до зашифрованих повідомлень, якщо вийдете з усіх сеансів %1$s"</string>
|
||||
<string name="screen_key_backup_disable_title">"Ви впевнені, що хочете вимкнути резервне копіювання?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Отримайте новий ключ відновлення, якщо ви втратили наявний ключ. Після зміни ключа відновлення ваш попередній більше не працюватиме."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Згенерувати новий ключ відновлення"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Не діліться цим ні з ким!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Ключ відновлення змінено"</string>
|
||||
<string name="screen_recovery_key_change_title">"Змінити ключ відновлення?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Створити новий ключ відновлення"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Впевніться, що ніхто не дивиться!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Будь ласка, спробуйте ще раз, щоб підтвердити доступ до сховища ключів."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Неправильний ключ відновлення"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Якщо у вас є ключ безпеки або фраза безпеки, це теж спрацює."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Входимо…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Загубили ключ відновлення?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Ключ відновлення підтверджено"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Введіть ключ відновлення"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Скопійовано ключ відновлення"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Створення…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Зберегти ключ відновлення"</string>
|
||||
<string name="screen_recovery_key_save_description">"Запишіть цей ключ відновлення в безпечне місце, наприклад, у менеджер паролей, зашифровану записку або власноруч у фізично безпечному місці."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Торкніться, щоб скопіювати ключ відновлення"</string>
|
||||
<string name="screen_recovery_key_save_title">"Збережіть ключ відновлення"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Після цього кроку ви не зможете отримати доступ до нового ключа відновлення."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Ви зберегли ключ відновлення?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Ваша резервна копія чату захищена ключем відновлення. Якщо вам потрібен новий ключ відновлення після налаштування, ви можете відтворити, вибравши «Змінити ключ відновлення»."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Згенеруйте ключ відновлення"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Не діліться цим ні з ким!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Налаштування відновлення виконано успішно"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Налаштувати відновлення"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Так, скинути зараз"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Цей процес незворотний."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Ви впевнені, що хочете скинути шифрування?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Сталася невідома помилка. Будь ласка, перевірте правильність пароля свого облікового запису та повторіть спробу."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Входимо…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Підтвердьте, що ви хочете скинути шифрування."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Введіть пароль облікового запису, щоб продовжити"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"کلید کا ذخیرہ حذف کریں"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"پشتارہ چالو کریں"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"خادم پر اپنی تشفیری شناخت اور پیغام کی کلیدیں محفوظ طریقے سے ذخیرہ کریں۔ اس سے آپ کسی بھی نئے آلات پر اپنے پیغام کی سرگزشت دیکھ سکیں گے۔ %1$s۔"</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"کلید ذخیرہ"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"بازیابی کی کلید تبدیل کریں"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"بازیابی کلید درج کریں"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"آپ کا کلیدی ذخیرہ فی الحال غیر ہم وقت ساز ہے۔"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"بازیابی مرتب کریں"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"اگر آپ اپنے تمام آلات کھو دیتے ہیں یا ہر جگہ %1$s سے خارج ہیں تو اپنے مرموز کردہ پیغامات تک رسائی حاصل کریں۔"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"%1$s کو برمیز آلے میں کھولیں"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"اپنے کھاتہ میں چوبارہ داخل ہوں"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"جب اپنے آلے کی توثیق کا کہا جائے، %1$s منتخب کریں"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"”تمام بحال کریں“"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"نئی بازیابی کلید بنانے کیلئے ہدایات پر عمل کریں"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"اپنی نئی بازیابی کلید کو لفظ عبور منتظم یا مرکوز کردہ ملحوظہ میں محفوظ کریں"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"کسی دوسرے آلے کا استعمال کرتے ہوئے اپنے کھاتہ کیلئے مرموز کاری کو بحال کریں"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"ری سیٹ جاری رکھیں"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"آپ کے کھاتہ کی تفصیلات، رابطے، ترجیحات اور گفتگو کی فہرست رکھی جائے گی۔"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"آپ کسی بھی پیغام کی سرگزشت کو کھو دیں گے جو صرف خادم پر محفوظ ہے۔"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"آپ کو اپنے تمام موجودہ آلات اور رابطوں کی دوبارہ توثیق کرنی ہوگی۔"</string>
|
||||
<string name="screen_encryption_reset_footer">"اپنی شناخت صرف اس صورت میں بحال کر دیں جب آپ کو کسی دوسرے دخول کردہ آلے تک رسائی حاصل نہ ہو اور آپ اپنی بازیابی کلید کھو چکے ہوں۔"</string>
|
||||
<string name="screen_encryption_reset_title">"تصدیق نہیں کر سکتے؟ آپ کو اپنی شناخت بحال کر دینے کی ضرورت ہوگی۔"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"بند کریں"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"آپ اپنے مرموز کردہ پیغامات کھو جائیں گے اگر آپ تمام آلات سے خارج ہو جائیں۔"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"کیا آپ کو یقین ہے کہ آپ بپشتارہ بند کرنا چاہتے ہیں؟"</string>
|
||||
<string name="screen_key_backup_disable_description">"کلید کے ذخیرہ کو حذف کرنے سے خادم سے آپ کی تشفیری شناخت اور پیغام کی کلیدیں ہٹ جائیں گی اور درج ذیل حفاظتی خصوصیات بند ہو جائیں گی:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"آپکے پاس نئے آلات پر مرموز کردہ پیغامات کی سرگزشت نہیں ہوگی"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"اگر آپ ہر جگہ %1$s سے خارج ہیں تو آپ اپنے مرموز کردہ پیغامات تک رسائی کھو دیں گے۔"</string>
|
||||
<string name="screen_key_backup_disable_title">"کیا آپ کو یقین ہے کہ آپ جلد کے ذخیرہ کو بند کرنا اور اسے حذف کرنا چاہتے ہیں؟"</string>
|
||||
<string name="screen_recovery_key_change_description">"اگر آپ نے اپنی موجودہ کھو دی ہے تو نئی بازیابی کلید حاصل کریں۔ اپنی بازیابی کلید کو تبدیل کرنے کے بعد، آپ کی پرانی اب کام نہیں کرے گی۔"</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"نئی بازیابی کلید تولید کریں"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"کسی کے ساتھ اس کا اشتراک نہ کریں!"</string>
|
||||
<string name="screen_recovery_key_change_success">"بازیابی کلید بدل دی"</string>
|
||||
<string name="screen_recovery_key_change_title">"بازیابی کلید بدلیں؟"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"نئی بازیابی کلید تخلیق کریں"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"یقینی بنائیں کہ کوئی بھی اس صفحۂ نمائش کو نہیں دیکھ سکتا!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"برائے مہربانی اپنے کلید کے ذخیرے تک رسائی کی تصدیق کرنے کے لیے دوبارہ کوشش کریں۔"</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"غلط بازیابی کلید"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"اگر آپ کے پاس حفاظتی کلید یا حفاظتی فقرہ ہے، یہ بھی کام کرے گا۔"</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"درج کریں…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"اپنی بازیابی کلید کھو دی؟"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"بازیابی کلید کی تصدیق ہوگئی"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"بازیابی کلید نقل شدہ"</string>
|
||||
<string name="screen_recovery_key_generating_key">"تولید کر رہ ہے…"</string>
|
||||
<string name="screen_recovery_key_save_action">"بازیابی کلید محفوظ کریں"</string>
|
||||
<string name="screen_recovery_key_save_description">"اس بازیابی کی کلید کو کہیں محفوظ جگہ لکھیں ، جیسے لفظ عبور منتظم، مرموز کردہ ملحوظہ، یا جسمانی سیف۔"</string>
|
||||
<string name="screen_recovery_key_save_key_description">"ریکوری کلید نقل کرنے کے لیے تھپتھپائیں۔"</string>
|
||||
<string name="screen_recovery_key_save_title">"اپنی بازیابی کلید کو محفوظ جگہ پر محفوظ کریں"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"اس مرحلے کے بعد آپ اپنی نئی بازیابی کلید تک رسائی حاصل نہیں کرسکیں گے۔"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"کیا آپ نے اپنی بازیابی کی کلید محفوظ کی ہے؟"</string>
|
||||
<string name="screen_recovery_key_setup_description">"آپ کا کلید کا ذخیرہ بازیابی کلید کے ذریعہ محفوظ ہے۔ اگر آپ کو مرتب کرنے کے بعد ایک نئی بازیابی کلید کی ضرورت ہے تو ، آپ \'بازیابی کلید بدلیں\' منتخب کرکے اسے دوبارہ تخلیق کرسکتے ہیں۔"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"اپنی بازیابی کلید تولید کریں"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"کسی کے ساتھ اس کا اشتراک نہ کریں!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"ریکوری مرتب کامیاب"</string>
|
||||
<string name="screen_recovery_key_setup_title">"بازیابی مرتب کریں"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"ہاں، اب بحال کر دیں"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"یہ عملیہ ناقابل تلافی ہے۔"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"کیا آپ کو یقین ہے کہ آپ اپنی شناخت بحال کر دینا چاہتے ہیں؟"</string>
|
||||
<string name="screen_reset_encryption_password_error">"ایک نامعلوم غلطی ہو گئی۔ براہ کرم چیک کریں کہ آپ کے اکاؤنٹ کا پاسورڈ درست ہے اور دوبارہ کوشش کریں۔"</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"درج کریں…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"تصدیق کریں کہ آپ اپنی شناخت بحال کر دینا چاہتے ہیں۔"</string>
|
||||
<string name="screen_reset_encryption_password_title">"جاری رکھنے کے لیے اپنے کھاتہ کا لفظ عبور درج کریں۔"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Zaxiralashni o\'chirib qo\'ying"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Zaxiralashni yoqing"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Kryptografik shaxsiyatingizni va xabar kalitlaringizni serverda xavfsiz saqlang. Bu sizga har qanday yangi qurilmalarda xabar tarixingizni ko\'rish imkonini beradi. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Kalitlar ombori"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Tiklashni sozlash uchun kalitlar xotirasini yoqish kerak."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Bu qurilmadan kalitlarni yuklash"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Kalit saqlashga ruxsat berish"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Qayta tiklash kalitini o\'zgartiring"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Agar barcha mavjud qurilmalaringizni yoʻqotgan boʻlsangiz, tiklash kaliti yordamida kriptografik shaxsingizni va xabarlar tarixingizni qayta tiklang."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Tiklash kalitini kiriting"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Kalit xotirasi hozirda sinxronlanmagan."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Qayta tiklashni sozlang"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Agar barcha qurilmalaringizni yo‘qotib qo‘ysangiz yoki tizimdan chiqqan bo‘lsangiz, shifrlangan xabarlaringizga ruxsat oling%1$s hamma joyda."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"%1$s ni kompyuterda oching"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Hisobingizga qaytadan kiring"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"Qurilmangizni tasdiqlash soʻralganda, %1$s ni tanlang"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"ʻʻHammasini asliga qaytarishʼʼ"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Yangi tiklash kalitini yaratish uchun koʻrsatmalarga amal qiling"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Yangi tiklash kalitingizni parol menejeriga yoki shifrlangan yozuvga saqlab qoʻying"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Hisobingiz shifrini boshqa qurilma orqali asliga qaytaring"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Qayta tiklashda davom eting"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Hisob maʼlumotlaringiz, kontaktlaringiz, sozlamalaringiz va suhbatlar roʻyxatingiz saqlanib qoladi"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"Faqat serverda saqlangan har qanday xabarlar tarixi oʻchib ketadi"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"Barcha mavjud qurilma va kontaktlarni qayta tasdiqlashingiz kerak boʻladi"</string>
|
||||
<string name="screen_encryption_reset_footer">"Agar boshqa hisobga kirilgan qurilmaga kira olmasangiz va tiklash kaliti yo‘qolgan bo‘lsa, shaxsingizni tiklang."</string>
|
||||
<string name="screen_encryption_reset_title">"Tasdiqlanmadimi? Shaxsingizni tiklashingiz kerak."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"O\'chirish"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"Agar barcha qurilmalardan chiqqan boʻlsangiz, shifrlangan xabarlaringizni yoʻqotasiz."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Haqiqatan ham zaxiralashni o‘chirib qo‘ymoqchimisiz?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Zaxiralashni o‘chirib qo‘ysangiz, joriy shifrlash kaliti zaxira nusxasi o‘chiriladi va boshqa xavfsizlik funksiyalari o‘chiriladi. Bunday holda siz:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"Yangi qurilmalarda shifrlangan xabarlar tarixi mavjud emas"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"Agar tizimdan chiqqan boʻlsangiz, shifrlangan xabarlaringizga kirish huquqini yoʻqotasiz%1$s hamma joyda"</string>
|
||||
<string name="screen_key_backup_disable_title">"Haqiqatan ham zaxiralashni o‘chirib qo‘ymoqchimisiz?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Mavjud kalitingizni yo\'qotgan bo\'lsangiz, yangi tiklash kalitini oling. Qayta tiklash kalitini almashtirganingizdan so\'ng, eski kalitingiz ishlamaydi."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Yangi tiklash kalitini yarating"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Buni hech kimga ulashmang!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Qayta tiklash kaliti oʻzgartirildi"</string>
|
||||
<string name="screen_recovery_key_change_title">"Qayta tiklash kaliti almashtirilsinmi?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Yangi tiklash kalitini yaratish"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Hech kim bu ekranni kora olmasligiga ishonch hosil qiling!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Kalit xotirasiga kirishni tasdiqlash uchun qayta urinib koʻring."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Notoʻgʻri tiklash kaliti"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"Agar sizda xavfsizlik kaliti yoki xavfsizlik iborasi bolsa, bu ham ishlaydi."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Kirish…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Tiklanish kalitingizni yoʻqotdingizmi?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Qayta tiklash kaliti tasdiqlandi"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Qayta tiklash kalitingizni kiriting"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Qayta tiklash kaliti nusxalandi"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Yaratilmoqda…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Qayta tiklash kalitini saqlang"</string>
|
||||
<string name="screen_recovery_key_save_description">"Qayta tiklash kalitingizni xavfsiz joyga yozing yoki parol menejerida saqlang."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Qayta tiklash kalitidan nusxa olish uchun bosing"</string>
|
||||
<string name="screen_recovery_key_save_title">"Zaxira kalitingizni saqlang"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"Ushbu qadamdan so‘ng siz yangi tiklash kalitingizga kira olmaysiz."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Zaxira kalitingizni saqladingizmi?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Suhbatingiz zaxira nusxasi tiklash kaliti bilan himoyalangan. Agar sozlashdan keyin sizga yangi tiklash kaliti kerak boʻlsa, “Qayta tiklash kalitini oʻzgartirish”ni tanlash orqali qayta yaratishingiz mumkin."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Qayta tiklash kalitini yarating"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Buni hech kimga ulashmang!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Qayta tiklash muvaffaqiyatli sozlandi"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Qayta tiklashni sozlang"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Ha, hozir asliga qaytarish"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"Bu jarayonni ortga qaytarib boʻlmaydi."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Haqiqatan ham shaxsingizni qayta tiklamoqchimisiz?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"Noma’lum xato yuz berdi. Iltimos, hisobingiz parolining to‘g‘riligini tekshiring va qaytadan urinib ko‘ring."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Kirish…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Shaxsingizni tiklashni tasdiqlang."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Davom etish uchun hisobingiz parolini kiriting"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"關閉備份功能"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"開啟備份功能"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"在伺服器上安全地儲存您的密碼學身份與訊息金鑰。這將讓您可以在任何新裝置上檢視訊息歷史紀錄。%1$s"</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"金鑰儲存空間"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"必須開啟金鑰儲存空間才能設定復原。"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"從此裝置上傳金鑰"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"允許金鑰儲存空間"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"變更復原金鑰"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"若您遺失了您現有的所有裝置,請使用復原金鑰來還原您的密碼學身份與訊息歷史紀錄。"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"輸入復原金鑰"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"您的金鑰儲存空間目前並未同步。"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"設定復原"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"若您遺失所有裝置,或是徹底登出了 %1$s,就可以存取您的加密訊息。"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"在桌上型裝置中開啟 %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"再次登入您的帳號"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"當要求驗證您的裝置時,請選取 %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"「重設全部」"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"按照說明建立新復原金鑰"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"將您的新復原金鑰儲存在密碼管理程式或加密筆記中"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"使用其他裝置重設您帳號的加密"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"繼續重設"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"您的帳號詳細資訊、聯絡人、偏好設定與聊天清單都會保留"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"您將會遺失僅儲存在伺服器上的任何訊息歷史紀錄"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"您將需要再次驗證所有現有裝置與聯絡人"</string>
|
||||
<string name="screen_encryption_reset_footer">"僅當您無法存取其他已登入裝置且遺失復原金鑰時才重設您的身份。"</string>
|
||||
<string name="screen_encryption_reset_title">"無法確認?您需要重設身份。"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"關閉"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"若您登出所有裝置,您將失去加密訊息。"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"您確定您要關閉備份嗎?"</string>
|
||||
<string name="screen_key_backup_disable_description">"刪除金鑰儲存空間會從伺服器移除您的密碼學身份與訊息金鑰,並關閉以下安全性功能:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"您將無法在新裝置上存取加密訊息歷史紀錄"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"若您徹底登出 %1$s,您將無法存取加密訊息"</string>
|
||||
<string name="screen_key_backup_disable_title">"您確定要關閉金鑰儲存空間並刪除它嗎?"</string>
|
||||
<string name="screen_recovery_key_change_description">"若您遺失現有的復原金鑰,請產生新的復原金鑰。變更復原金鑰後,舊金鑰將不再有效。"</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"產生新的復原金鑰"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"不要與任何人分享!"</string>
|
||||
<string name="screen_recovery_key_change_success">"復原金鑰已變更"</string>
|
||||
<string name="screen_recovery_key_change_title">"變更復原金鑰?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"建立新復原金鑰"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"確保沒有人可以看到此畫面!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"請再試一次確認對您金鑰儲存空間的存取權。"</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"復原金鑰不正確"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"若您有安全金鑰或安全密語也可以正常運作。"</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"輸入……"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"遺失了您的復原金鑰?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"復原金鑰已確認"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"輸入您的復原金鑰"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"已複製復原金鑰"</string>
|
||||
<string name="screen_recovery_key_generating_key">"正在產生……"</string>
|
||||
<string name="screen_recovery_key_save_action">"儲存復原金鑰"</string>
|
||||
<string name="screen_recovery_key_save_description">"將此復原金鑰記在安全的地方,例如密碼管理程式、加密筆記或實體保險箱中。"</string>
|
||||
<string name="screen_recovery_key_save_key_description">"點擊以複製復原金鑰"</string>
|
||||
<string name="screen_recovery_key_save_title">"將復原金鑰儲存在安全的地方"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"在此步驟後,您將無法存取新的復原金鑰。"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"您儲存復原金鑰了嗎?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"您的金鑰儲存空間由復原金鑰保護。若您在設定後需要新的復原金鑰,您可以透過選取「變更復原金鑰」來重新建立。"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"產生您的復原金鑰"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"不要與任何人分享!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"復原設定成功"</string>
|
||||
<string name="screen_recovery_key_setup_title">"設定復原"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"是的,立刻重設"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"此過程不可逆。"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"您確定您想要重設您的身份嗎?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"發生了未知錯誤。請檢查您帳號的密碼是否正確,然後再試一次。"</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"輸入……"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"確認您要重設您的身份。"</string>
|
||||
<string name="screen_reset_encryption_password_title">"輸入您帳號的密碼以繼續"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"关闭备份"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"开启备份"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"将您的密码学身份和消息密钥安全地存储在服务器上。这样您就可以在任何新设备上查看您的消息历史记录。%1$s。"</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"密钥存储"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"必须打开密钥存储才能设置恢复。"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"从此设备上传密钥"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"允许密钥存储"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"更改恢复密钥"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"如果您丢失了所有现有设备,使用恢复密钥恢复您的密码学身份和消息历史记录。"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"输入恢复密钥"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"您的密钥存储当前不同步。"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"设置恢复"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"在丢失或从 %1$s 登出所有设备的情况下访问加密消息。"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"在桌面设备中打开 %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"再次登录您的账户"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"当要求验证您的设备时,选择 %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"「全部重置」"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"按照说明创建新的恢复密钥"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"将新的恢复密钥保存在密码管理器或加密备忘录中"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"使用其他设备重置账户的加密"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"继续重置"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"您的账户信息、联系人、偏好设置和聊天列表将被保留"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"您将丢失现有的消息历史记录"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"您将需要再次验证所有您的现有设备和联系人"</string>
|
||||
<string name="screen_encryption_reset_footer">"仅当您无法访问其他已登录设备并且丢失了恢复密钥时才重置您的身份。"</string>
|
||||
<string name="screen_encryption_reset_title">"如果您无法通过其他方式确认,请重置您的身份"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"关闭"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"如果您登出所有设备,您的加密消息将丢失。"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"您确定要关闭备份吗?"</string>
|
||||
<string name="screen_key_backup_disable_description">"关闭备份将删除您当前的加密密钥备份并关闭其他安全功能。在这种情况下,你将:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"新设备上没有加密消息的历史记录"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"如果您在所有设备上登出了 %1$s,那将无法访问加密消息"</string>
|
||||
<string name="screen_key_backup_disable_title">"您确定要关闭备份吗?"</string>
|
||||
<string name="screen_recovery_key_change_description">"如果您丢失了现有的恢复密钥,请获取新的恢复密钥。更改恢复密钥后,您的旧密钥将不再起作用。"</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"生成新的恢复密钥"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"不要告诉任何人!"</string>
|
||||
<string name="screen_recovery_key_change_success">"恢复密钥已更改"</string>
|
||||
<string name="screen_recovery_key_change_title">"更改恢复密钥?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"创建新的恢复密钥"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"确保没有人能看到这个界面!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"请重试以确认访问您的密钥存储。"</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"恢复密钥不正确"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"如果您有安全密钥或安全短语,也可以用。"</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"输入……"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"丢失了恢复密钥?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"恢复密钥已确认"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"输入恢复密钥"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"恢复密钥已复制"</string>
|
||||
<string name="screen_recovery_key_generating_key">"正在生成……"</string>
|
||||
<string name="screen_recovery_key_save_action">"保存恢复密钥"</string>
|
||||
<string name="screen_recovery_key_save_description">"将此恢复密钥保存在安全的地方,例如密码管理器、加密笔记或物理保险箱。"</string>
|
||||
<string name="screen_recovery_key_save_key_description">"点击复制恢复密钥"</string>
|
||||
<string name="screen_recovery_key_save_title">"保存您的恢复密钥"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"完成此步骤后,您将无法访问新的恢复密钥。"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"您保存了恢复密钥吗?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"您的聊天备份受恢复密钥保护。如果您在安装后需要新的恢复密钥,则可以通过选择「更改恢复密钥」来重新创建。"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"生成恢复密钥"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"不要告诉任何人!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"恢复设置成功"</string>
|
||||
<string name="screen_recovery_key_setup_title">"设置恢复"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"是的,立即重置"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"此过程不可逆。"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"您确定要重置加密吗?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"发生未知错误。请检查您的帐户密码是否正确,然后重试。"</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"输入……"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"确认您要重置加密。"</string>
|
||||
<string name="screen_reset_encryption_password_title">"输入您的账户密码以继续"</string>
|
||||
</resources>
|
||||
70
features/securebackup/impl/src/main/res/values/localazy.xml
Normal file
70
features/securebackup/impl/src/main/res/values/localazy.xml
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_chat_backup_key_backup_action_disable">"Delete key storage"</string>
|
||||
<string name="screen_chat_backup_key_backup_action_enable">"Turn on backup"</string>
|
||||
<string name="screen_chat_backup_key_backup_description">"Store your cryptographic identity and message keys securely on the server. This will allow you to view your message history on any new devices. %1$s."</string>
|
||||
<string name="screen_chat_backup_key_backup_title">"Key storage"</string>
|
||||
<string name="screen_chat_backup_key_storage_disabled_error">"Key storage must be turned on to set up recovery."</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_description">"Upload keys from this device"</string>
|
||||
<string name="screen_chat_backup_key_storage_toggle_title">"Allow key storage"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change">"Change recovery key"</string>
|
||||
<string name="screen_chat_backup_recovery_action_change_description">"Recover your cryptographic identity and message history with a recovery key if you’ve lost all your existing devices."</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm">"Enter recovery key"</string>
|
||||
<string name="screen_chat_backup_recovery_action_confirm_description">"Your key storage is currently out of sync."</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup">"Set up recovery"</string>
|
||||
<string name="screen_chat_backup_recovery_action_setup_description">"Get access to your encrypted messages if you lose all your devices or are signed out of %1$s everywhere."</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_1">"Open %1$s in a desktop device"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_2">"Sign into your account again"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3">"When asked to verify your device, select %1$s"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_3_reset_all">"“Reset all”"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_4">"Follow the instructions to create a new recovery key"</string>
|
||||
<string name="screen_create_new_recovery_key_list_item_5">"Save your new recovery key in a password manager or encrypted note"</string>
|
||||
<string name="screen_create_new_recovery_key_title">"Reset the encryption for your account using another device"</string>
|
||||
<string name="screen_encryption_reset_action_continue_reset">"Continue reset"</string>
|
||||
<string name="screen_encryption_reset_bullet_1">"Your account details, contacts, preferences, and chat list will be kept"</string>
|
||||
<string name="screen_encryption_reset_bullet_2">"You will lose any message history that’s stored only on the server"</string>
|
||||
<string name="screen_encryption_reset_bullet_3">"You will need to verify all your existing devices and contacts again"</string>
|
||||
<string name="screen_encryption_reset_footer">"Only reset your identity if you don’t have access to another signed-in device and you’ve lost your recovery key."</string>
|
||||
<string name="screen_encryption_reset_title">"Can\'t confirm? You’ll need to reset your identity."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_action_turn_off">"Turn off"</string>
|
||||
<string name="screen_key_backup_disable_confirmation_description">"You will lose your encrypted messages if you are signed out of all devices."</string>
|
||||
<string name="screen_key_backup_disable_confirmation_title">"Are you sure you want to turn off backup?"</string>
|
||||
<string name="screen_key_backup_disable_description">"Deleting key storage will remove your cryptographic identity and message keys from the server and turn off the following security features:"</string>
|
||||
<string name="screen_key_backup_disable_description_point_1">"You will not have encrypted message history on new devices"</string>
|
||||
<string name="screen_key_backup_disable_description_point_2">"You will lose access to your encrypted messages if you are signed out of %1$s everywhere"</string>
|
||||
<string name="screen_key_backup_disable_title">"Are you sure you want to turn off key storage and delete it?"</string>
|
||||
<string name="screen_recovery_key_change_description">"Get a new recovery key if you\'ve lost your existing one. After changing your recovery key, your old one will no longer work."</string>
|
||||
<string name="screen_recovery_key_change_generate_key">"Generate a new recovery key"</string>
|
||||
<string name="screen_recovery_key_change_generate_key_description">"Do not share this with anyone!"</string>
|
||||
<string name="screen_recovery_key_change_success">"Recovery key changed"</string>
|
||||
<string name="screen_recovery_key_change_title">"Change recovery key?"</string>
|
||||
<string name="screen_recovery_key_confirm_create_new_recovery_key">"Create new recovery key"</string>
|
||||
<string name="screen_recovery_key_confirm_description">"Make sure nobody can see this screen!"</string>
|
||||
<string name="screen_recovery_key_confirm_error_content">"Please try again to confirm access to your key storage."</string>
|
||||
<string name="screen_recovery_key_confirm_error_title">"Incorrect recovery key"</string>
|
||||
<string name="screen_recovery_key_confirm_key_description">"If you have a security key or security phrase, this will work too."</string>
|
||||
<string name="screen_recovery_key_confirm_key_placeholder">"Enter…"</string>
|
||||
<string name="screen_recovery_key_confirm_lost_recovery_key">"Lost your recovery key?"</string>
|
||||
<string name="screen_recovery_key_confirm_success">"Recovery key confirmed"</string>
|
||||
<string name="screen_recovery_key_confirm_title">"Enter your recovery key"</string>
|
||||
<string name="screen_recovery_key_copied_to_clipboard">"Copied recovery key"</string>
|
||||
<string name="screen_recovery_key_generating_key">"Generating…"</string>
|
||||
<string name="screen_recovery_key_save_action">"Save recovery key"</string>
|
||||
<string name="screen_recovery_key_save_description">"Write down this recovery key somewhere safe, like a password manager, encrypted note, or a physical safe."</string>
|
||||
<string name="screen_recovery_key_save_key_description">"Tap to copy recovery key"</string>
|
||||
<string name="screen_recovery_key_save_title">"Save your recovery key somewhere safe"</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_description">"You will not be able to access your new recovery key after this step."</string>
|
||||
<string name="screen_recovery_key_setup_confirmation_title">"Have you saved your recovery key?"</string>
|
||||
<string name="screen_recovery_key_setup_description">"Your key storage is protected by a recovery key. If you need a new recovery key after setup, you can recreate it by selecting ‘Change recovery key’."</string>
|
||||
<string name="screen_recovery_key_setup_generate_key">"Generate your recovery key"</string>
|
||||
<string name="screen_recovery_key_setup_generate_key_description">"Do not share this with anyone!"</string>
|
||||
<string name="screen_recovery_key_setup_success">"Recovery setup successful"</string>
|
||||
<string name="screen_recovery_key_setup_title">"Set up recovery"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_action">"Yes, reset now"</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_subtitle">"This process is irreversible."</string>
|
||||
<string name="screen_reset_encryption_confirmation_alert_title">"Are you sure you want to reset your identity?"</string>
|
||||
<string name="screen_reset_encryption_password_error">"An unknown error happened. Please check your account password is correct and try again."</string>
|
||||
<string name="screen_reset_encryption_password_placeholder">"Enter…"</string>
|
||||
<string name="screen_reset_encryption_password_subtitle">"Confirm that you want to reset your identity."</string>
|
||||
<string name="screen_reset_encryption_password_title">"Enter your account password to continue"</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl
|
||||
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.testing.junit4.util.MainDispatcherRule
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
import io.element.android.tests.testutils.node.TestParentNode
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class DefaultSecureBackupEntryPointTest {
|
||||
@get:Rule
|
||||
val instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
|
||||
@get:Rule
|
||||
val mainDispatcherRule = MainDispatcherRule()
|
||||
|
||||
@Test
|
||||
fun `test node builder`() {
|
||||
val entryPoint = DefaultSecureBackupEntryPoint()
|
||||
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||
SecureBackupFlowNode(
|
||||
buildContext = buildContext,
|
||||
plugins = plugins,
|
||||
)
|
||||
}
|
||||
val callback = object : SecureBackupEntryPoint.Callback {
|
||||
override fun onDone() = lambdaError()
|
||||
}
|
||||
val params = SecureBackupEntryPoint.Params(SecureBackupEntryPoint.InitialTarget.ResetIdentity)
|
||||
val result = entryPoint.createNode(
|
||||
parentNode = parentNode,
|
||||
buildContext = BuildContext.root(null),
|
||||
params = params,
|
||||
callback = callback,
|
||||
)
|
||||
assertThat(result).isInstanceOf(SecureBackupFlowNode::class.java)
|
||||
assertThat(result.plugins).contains(params)
|
||||
assertThat(result.plugins).contains(callback)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.disable
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class SecureBackupDisablePresenterTest {
|
||||
@get:Rule
|
||||
val warmUpRule = WarmUpRule()
|
||||
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = createSecureBackupDisablePresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
|
||||
assertThat(initialState.disableAction).isEqualTo(AsyncAction.Uninitialized)
|
||||
assertThat(initialState.appName).isEqualTo("Element")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - user delete backup success`() = runTest {
|
||||
val presenter = createSecureBackupDisablePresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.disableAction).isEqualTo(AsyncAction.Uninitialized)
|
||||
initialState.eventSink(SecureBackupDisableEvents.DisableBackup)
|
||||
val loadingState = awaitItem()
|
||||
assertThat(loadingState.disableAction).isInstanceOf(AsyncAction.Loading::class.java)
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.disableAction).isEqualTo(AsyncAction.Success(Unit))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - user delete backup error`() = runTest {
|
||||
val encryptionService = FakeEncryptionService().apply {
|
||||
givenDisableRecoveryFailure(Exception("failure"))
|
||||
}
|
||||
val presenter = createSecureBackupDisablePresenter(
|
||||
encryptionService = encryptionService
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.disableAction).isEqualTo(AsyncAction.Uninitialized)
|
||||
initialState.eventSink(SecureBackupDisableEvents.DisableBackup)
|
||||
val loadingState = awaitItem()
|
||||
assertThat(loadingState.disableAction).isInstanceOf(AsyncAction.Loading::class.java)
|
||||
val errorState = awaitItem()
|
||||
assertThat(errorState.disableAction).isInstanceOf(AsyncAction.Failure::class.java)
|
||||
errorState.eventSink(SecureBackupDisableEvents.DismissDialogs)
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.disableAction).isEqualTo(AsyncAction.Uninitialized)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSecureBackupDisablePresenter(
|
||||
encryptionService: EncryptionService = FakeEncryptionService(),
|
||||
appName: String = "Element",
|
||||
): SecureBackupDisablePresenter {
|
||||
return SecureBackupDisablePresenter(
|
||||
encryptionService = encryptionService,
|
||||
buildMeta = aBuildMeta(
|
||||
applicationName = appName,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.enter
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
|
||||
import io.element.android.features.securebackup.impl.tools.RecoveryKeyTools
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class SecureBackupEnterRecoveryKeyPresenterTest {
|
||||
@get:Rule
|
||||
val warmUpRule = WarmUpRule()
|
||||
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = createPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.isSubmitEnabled).isFalse()
|
||||
assertThat(initialState.submitAction).isEqualTo(AsyncAction.Uninitialized)
|
||||
assertThat(initialState.recoveryKeyViewState).isEqualTo(
|
||||
RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Enter,
|
||||
formattedRecoveryKey = "",
|
||||
displayTextFieldContents = false,
|
||||
inProgress = false,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - enter recovery key`() = runTest {
|
||||
val encryptionService = FakeEncryptionService()
|
||||
val presenter = createPresenter(encryptionService)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange("1234"))
|
||||
val withRecoveryKeyState = awaitItem()
|
||||
assertThat(withRecoveryKeyState.isSubmitEnabled).isTrue()
|
||||
assertThat(withRecoveryKeyState.recoveryKeyViewState).isEqualTo(
|
||||
RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Enter,
|
||||
formattedRecoveryKey = "1234",
|
||||
displayTextFieldContents = false,
|
||||
inProgress = false,
|
||||
)
|
||||
)
|
||||
encryptionService.givenRecoverFailure(AN_EXCEPTION)
|
||||
withRecoveryKeyState.eventSink(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
val loadingState = awaitItem()
|
||||
assertThat(loadingState.submitAction).isEqualTo(AsyncAction.Loading)
|
||||
assertThat(loadingState.isSubmitEnabled).isFalse()
|
||||
val errorState = awaitItem()
|
||||
assertThat(errorState.submitAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
|
||||
assertThat(errorState.isSubmitEnabled).isFalse()
|
||||
errorState.eventSink(SecureBackupEnterRecoveryKeyEvents.ClearDialog)
|
||||
val clearedState = awaitItem()
|
||||
assertThat(clearedState.submitAction).isEqualTo(AsyncAction.Uninitialized)
|
||||
assertThat(clearedState.isSubmitEnabled).isTrue()
|
||||
encryptionService.givenRecoverFailure(null)
|
||||
clearedState.eventSink(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
val loadingState2 = awaitItem()
|
||||
assertThat(loadingState2.submitAction).isEqualTo(AsyncAction.Loading)
|
||||
assertThat(loadingState2.isSubmitEnabled).isFalse()
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.submitAction).isEqualTo(AsyncAction.Success(Unit))
|
||||
assertThat(finalState.isSubmitEnabled).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPresenter(
|
||||
encryptionService: EncryptionService = FakeEncryptionService(),
|
||||
) = SecureBackupEnterRecoveryKeyPresenter(
|
||||
encryptionService = encryptionService,
|
||||
recoveryKeyTools = RecoveryKeyTools(),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.enter
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performImeAction
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.securebackup.impl.setup.views.aFormattedRecoveryKey
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SecureBackupEnterRecoveryKeyViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `back key pressed - calls onBackClick`() {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back button clicked - calls onBackClick`() {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(),
|
||||
onBackClick = callback,
|
||||
)
|
||||
rule.pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `tapping on Continue when key is valid - calls expected action`() {
|
||||
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
|
||||
)
|
||||
rule.clickOn(CommonStrings.action_continue)
|
||||
|
||||
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `entering a char emits the expected event`() {
|
||||
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
|
||||
val keyValue = aFormattedRecoveryKey()
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
|
||||
)
|
||||
rule.onNodeWithText(keyValue).performTextInput("X")
|
||||
recorder.assertSingle(
|
||||
SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange("X$keyValue")
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h1024dp")
|
||||
fun `toggling the visibility of the textfield changes it`() {
|
||||
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
|
||||
val keyValue = aFormattedRecoveryKey()
|
||||
rule.setSecureBackupEnterRecoveryKeyView(aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder))
|
||||
|
||||
// Initially, the text field should be visible
|
||||
rule.onNodeWithText(keyValue).assertExists()
|
||||
|
||||
rule.onNodeWithContentDescription(rule.activity.getString(CommonStrings.a11y_hide_password)).performClick()
|
||||
|
||||
rule.waitForIdle()
|
||||
|
||||
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.ChangeRecoveryKeyFieldContentsVisibility(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `validating from keyboard emits the expected event`() {
|
||||
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
|
||||
val keyValue = aFormattedRecoveryKey()
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
|
||||
)
|
||||
rule.onNodeWithText(keyValue).performImeAction()
|
||||
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.Submit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when submit action succeeds - calls onDone`() {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setSecureBackupEnterRecoveryKeyView(
|
||||
aSecureBackupEnterRecoveryKeyState(submitAction = AsyncAction.Success(Unit)),
|
||||
onDone = callback,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setSecureBackupEnterRecoveryKeyView(
|
||||
state: SecureBackupEnterRecoveryKeyState,
|
||||
onDone: () -> Unit = EnsureNeverCalled(),
|
||||
onBackClick: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
setContent {
|
||||
SecureBackupEnterRecoveryKeyView(
|
||||
state = state,
|
||||
onSuccess = onDone,
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset
|
||||
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
||||
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
|
||||
import io.element.android.libraries.matrix.test.encryption.FakeIdentityPasswordResetHandle
|
||||
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
class ResetIdentityFlowManagerTest {
|
||||
@Test
|
||||
fun `getResetHandle - emits a reset handle`() = runTest {
|
||||
val startResetLambda = lambdaRecorder<Result<IdentityResetHandle?>> { Result.success(FakeIdentityPasswordResetHandle()) }
|
||||
val encryptionService = FakeEncryptionService(startIdentityResetLambda = startResetLambda)
|
||||
val flowManager = createFlowManager(encryptionService = encryptionService)
|
||||
|
||||
flowManager.getResetHandle().test {
|
||||
assertThat(awaitItem().isLoading()).isTrue()
|
||||
assertThat(awaitItem().isSuccess()).isTrue()
|
||||
startResetLambda.assertions().isCalledOnce()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getResetHandle - om successful handle retrieval returns that same handle`() = runTest {
|
||||
val startResetLambda = lambdaRecorder<Result<IdentityResetHandle?>> { Result.success(FakeIdentityPasswordResetHandle()) }
|
||||
val encryptionService = FakeEncryptionService(startIdentityResetLambda = startResetLambda)
|
||||
val flowManager = createFlowManager(encryptionService = encryptionService)
|
||||
|
||||
var result: AsyncData.Success<IdentityResetHandle>? = null
|
||||
flowManager.getResetHandle().test {
|
||||
assertThat(awaitItem().isLoading()).isTrue()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
result = awaitItem() as? AsyncData.Success<IdentityResetHandle>
|
||||
assertThat(result).isNotNull()
|
||||
}
|
||||
|
||||
flowManager.getResetHandle().test {
|
||||
assertThat(awaitItem()).isSameInstanceAs(result)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getResetHandle - will success if it receives a null reset handle`() = runTest {
|
||||
val startResetLambda = lambdaRecorder<Result<IdentityResetHandle?>> { Result.success(null) }
|
||||
val encryptionService = FakeEncryptionService(startIdentityResetLambda = startResetLambda)
|
||||
val flowManager = createFlowManager(encryptionService = encryptionService)
|
||||
|
||||
flowManager.getResetHandle().test {
|
||||
assertThat(awaitItem().isLoading()).isTrue()
|
||||
val finalItem = awaitItem()
|
||||
assertThat(finalItem.isSuccess()).isTrue()
|
||||
assertThat(finalItem.dataOrNull()).isNull()
|
||||
startResetLambda.assertions().isCalledOnce()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getResetHandle - fails gracefully when receiving an exception from the encryption service`() = runTest {
|
||||
val startResetLambda = lambdaRecorder<Result<IdentityResetHandle?>> { Result.failure(IllegalStateException("Failure")) }
|
||||
val encryptionService = FakeEncryptionService(startIdentityResetLambda = startResetLambda)
|
||||
val flowManager = createFlowManager(encryptionService = encryptionService)
|
||||
|
||||
flowManager.getResetHandle().test {
|
||||
assertThat(awaitItem().isLoading()).isTrue()
|
||||
assertThat(awaitItem().isFailure()).isTrue()
|
||||
startResetLambda.assertions().isCalledOnce()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cancel - resets the state and calls cancel on the reset handle`() = runTest {
|
||||
val cancelLambda = lambdaRecorder<Unit> { }
|
||||
val resetHandle = FakeIdentityPasswordResetHandle(cancelLambda = cancelLambda)
|
||||
val startResetLambda = lambdaRecorder<Result<IdentityResetHandle?>> { Result.success(resetHandle) }
|
||||
val encryptionService = FakeEncryptionService(startIdentityResetLambda = startResetLambda)
|
||||
val flowManager = createFlowManager(encryptionService = encryptionService)
|
||||
|
||||
flowManager.getResetHandle().test {
|
||||
assertThat(awaitItem().isLoading()).isTrue()
|
||||
assertThat(awaitItem().isSuccess()).isTrue()
|
||||
|
||||
flowManager.cancel()
|
||||
cancelLambda.assertions().isCalledOnce()
|
||||
assertThat(awaitItem().isUninitialized()).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun `whenResetIsDone - will trigger the lambda when verification status is verified`() = runTest {
|
||||
val verificationService = FakeSessionVerificationService()
|
||||
val flowManager = createFlowManager(sessionVerificationService = verificationService)
|
||||
var isDone = false
|
||||
|
||||
flowManager.whenResetIsDone {
|
||||
isDone = true
|
||||
}
|
||||
|
||||
assertThat(isDone).isFalse()
|
||||
|
||||
verificationService.emitVerifiedStatus(SessionVerifiedStatus.Unknown)
|
||||
advanceUntilIdle()
|
||||
assertThat(isDone).isFalse()
|
||||
|
||||
verificationService.emitVerifiedStatus(SessionVerifiedStatus.NotVerified)
|
||||
advanceUntilIdle()
|
||||
assertThat(isDone).isFalse()
|
||||
|
||||
verificationService.emitVerifiedStatus(SessionVerifiedStatus.Verified)
|
||||
advanceUntilIdle()
|
||||
assertThat(isDone).isTrue()
|
||||
}
|
||||
|
||||
private fun TestScope.createFlowManager(
|
||||
encryptionService: FakeEncryptionService = FakeEncryptionService(),
|
||||
sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(),
|
||||
) = ResetIdentityFlowManager(
|
||||
encryptionService = encryptionService,
|
||||
sessionCoroutineScope = this,
|
||||
sessionVerificationService = sessionVerificationService,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.password
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.matrix.test.encryption.FakeIdentityPasswordResetHandle
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
class ResetIdentityPasswordPresenterTest {
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = createPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.resetAction.isUninitialized()).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - Reset event succeeds`() = runTest {
|
||||
val resetLambda = lambdaRecorder<String, Result<Unit>> { _ -> Result.success(Unit) }
|
||||
val resetHandle = FakeIdentityPasswordResetHandle(resetPasswordLambda = resetLambda)
|
||||
val presenter = createPresenter(identityResetHandle = resetHandle)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ResetIdentityPasswordEvent.Reset("password"))
|
||||
assertThat(awaitItem().resetAction.isLoading()).isTrue()
|
||||
assertThat(awaitItem().resetAction.isSuccess()).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - Reset event can fail gracefully`() = runTest {
|
||||
val resetLambda = lambdaRecorder<String, Result<Unit>> { _ -> Result.failure(IllegalStateException("Failed")) }
|
||||
val resetHandle = FakeIdentityPasswordResetHandle(resetPasswordLambda = resetLambda)
|
||||
val presenter = createPresenter(identityResetHandle = resetHandle)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ResetIdentityPasswordEvent.Reset("password"))
|
||||
assertThat(awaitItem().resetAction.isLoading()).isTrue()
|
||||
assertThat(awaitItem().resetAction.isFailure()).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - DismissError event resets the state`() = runTest {
|
||||
val resetLambda = lambdaRecorder<String, Result<Unit>> { _ -> Result.failure(IllegalStateException("Failed")) }
|
||||
val resetHandle = FakeIdentityPasswordResetHandle(resetPasswordLambda = resetLambda)
|
||||
val presenter = createPresenter(identityResetHandle = resetHandle)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ResetIdentityPasswordEvent.Reset("password"))
|
||||
assertThat(awaitItem().resetAction.isLoading()).isTrue()
|
||||
assertThat(awaitItem().resetAction.isFailure()).isTrue()
|
||||
|
||||
initialState.eventSink(ResetIdentityPasswordEvent.DismissError)
|
||||
assertThat(awaitItem().resetAction.isUninitialized()).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
private fun TestScope.createPresenter(
|
||||
identityResetHandle: FakeIdentityPasswordResetHandle = FakeIdentityPasswordResetHandle(),
|
||||
) = ResetIdentityPasswordPresenter(
|
||||
identityPasswordResetHandle = identityResetHandle,
|
||||
dispatchers = testCoroutineDispatchers(),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.password
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ResetIdentityPasswordViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `pressing the back HW button invokes the expected callback`() {
|
||||
ensureCalledOnce {
|
||||
rule.setResetPasswordView(
|
||||
ResetIdentityPasswordState(resetAction = AsyncAction.Uninitialized, eventSink = {}),
|
||||
onBack = it,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on the back navigation button invokes the expected callback`() {
|
||||
ensureCalledOnce {
|
||||
rule.setResetPasswordView(
|
||||
ResetIdentityPasswordState(resetAction = AsyncAction.Uninitialized, eventSink = {}),
|
||||
onBack = it,
|
||||
)
|
||||
rule.pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking 'Reset identity' confirms the reset`() {
|
||||
val eventsRecorder = EventsRecorder<ResetIdentityPasswordEvent>()
|
||||
rule.setResetPasswordView(
|
||||
ResetIdentityPasswordState(resetAction = AsyncAction.Uninitialized, eventSink = eventsRecorder),
|
||||
)
|
||||
rule.onNodeWithText("Password").performTextInput("A password")
|
||||
|
||||
rule.clickOn(CommonStrings.action_reset_identity)
|
||||
|
||||
eventsRecorder.assertSingle(ResetIdentityPasswordEvent.Reset("A password"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `modifying the password dismisses the error state`() {
|
||||
val eventsRecorder = EventsRecorder<ResetIdentityPasswordEvent>()
|
||||
rule.setResetPasswordView(
|
||||
ResetIdentityPasswordState(resetAction = AsyncAction.Failure(IllegalStateException("A failure")), eventSink = eventsRecorder),
|
||||
)
|
||||
rule.onNodeWithText("Password").performTextInput("A password")
|
||||
|
||||
eventsRecorder.assertSingle(ResetIdentityPasswordEvent.DismissError)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setResetPasswordView(
|
||||
state: ResetIdentityPasswordState,
|
||||
onBack: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
setContent {
|
||||
ResetIdentityPasswordView(state = state, onBack = onBack)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.root
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
class ResetIdentityRootPresenterTest {
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = ResetIdentityRootPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.displayConfirmationDialog).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - Continue event displays the confirmation dialog`() = runTest {
|
||||
val presenter = ResetIdentityRootPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ResetIdentityRootEvent.Continue)
|
||||
|
||||
assertThat(awaitItem().displayConfirmationDialog).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - DismissDialog event hides the confirmation dialog`() = runTest {
|
||||
val presenter = ResetIdentityRootPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(ResetIdentityRootEvent.Continue)
|
||||
assertThat(awaitItem().displayConfirmationDialog).isTrue()
|
||||
|
||||
initialState.eventSink(ResetIdentityRootEvent.DismissDialog)
|
||||
assertThat(awaitItem().displayConfirmationDialog).isFalse()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.reset.root
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.element.android.features.securebackup.impl.R
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.tests.testutils.EnsureNeverCalled
|
||||
import io.element.android.tests.testutils.EventsRecorder
|
||||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.pressBack
|
||||
import io.element.android.tests.testutils.pressBackKey
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ResetIdentityRootViewTest {
|
||||
@get:Rule
|
||||
val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `pressing the back HW button invokes the expected callback`() {
|
||||
ensureCalledOnce {
|
||||
rule.setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = false, eventSink = {}),
|
||||
onBack = it,
|
||||
)
|
||||
rule.pressBackKey()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on the back navigation button invokes the expected callback`() {
|
||||
ensureCalledOnce {
|
||||
rule.setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = false, eventSink = {}),
|
||||
onBack = it,
|
||||
)
|
||||
rule.pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "h720dp")
|
||||
fun `clicking Continue displays the confirmation dialog`() {
|
||||
val eventsRecorder = EventsRecorder<ResetIdentityRootEvent>()
|
||||
rule.setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = false, eventSink = eventsRecorder),
|
||||
)
|
||||
|
||||
rule.clickOn(R.string.screen_encryption_reset_action_continue_reset)
|
||||
|
||||
eventsRecorder.assertSingle(ResetIdentityRootEvent.Continue)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking 'Yes, reset now' confirms the reset`() {
|
||||
ensureCalledOnce {
|
||||
rule.setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = true, eventSink = {}),
|
||||
onContinue = it,
|
||||
)
|
||||
rule.clickOn(R.string.screen_reset_encryption_confirmation_alert_action)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking Cancel dismisses the dialog`() {
|
||||
val eventsRecorder = EventsRecorder<ResetIdentityRootEvent>()
|
||||
rule.setResetRootView(
|
||||
ResetIdentityRootState(displayConfirmationDialog = true, eventSink = eventsRecorder),
|
||||
)
|
||||
|
||||
rule.clickOn(CommonStrings.action_cancel)
|
||||
eventsRecorder.assertSingle(ResetIdentityRootEvent.DismissDialog)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setResetRootView(
|
||||
state: ResetIdentityRootState,
|
||||
onBack: () -> Unit = EnsureNeverCalled(),
|
||||
onContinue: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
setContent {
|
||||
ResetIdentityRootView(state = state, onContinue = onContinue, onBack = onBack)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.root
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class SecureBackupRootPresenterTest {
|
||||
@get:Rule
|
||||
val warmUpRule = WarmUpRule()
|
||||
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = createSecureBackupRootPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(2)
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
|
||||
assertThat(initialState.doesBackupExistOnServer.dataOrNull()).isTrue()
|
||||
assertThat(initialState.enableAction).isEqualTo(AsyncAction.Uninitialized)
|
||||
assertThat(initialState.displayKeyStorageDisabledError).isFalse()
|
||||
assertThat(initialState.recoveryState).isEqualTo(RecoveryState.UNKNOWN)
|
||||
assertThat(initialState.appName).isEqualTo("Element")
|
||||
assertThat(initialState.snackbarMessage).isNull()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - Unknown state`() = runTest {
|
||||
val encryptionService = FakeEncryptionService()
|
||||
val presenter = createSecureBackupRootPresenter(
|
||||
encryptionService = encryptionService,
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
encryptionService.givenDoesBackupExistOnServerResult(Result.failure(AN_EXCEPTION))
|
||||
assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
|
||||
assertThat(initialState.doesBackupExistOnServer).isEqualTo(AsyncData.Uninitialized)
|
||||
val loadingState1 = awaitItem()
|
||||
assertThat(loadingState1.doesBackupExistOnServer).isInstanceOf(AsyncData.Loading::class.java)
|
||||
val errorState = awaitItem()
|
||||
assertThat(errorState.doesBackupExistOnServer).isEqualTo(AsyncData.Failure<Boolean>(AN_EXCEPTION))
|
||||
encryptionService.givenDoesBackupExistOnServerResult(Result.success(false))
|
||||
errorState.eventSink.invoke(SecureBackupRootEvents.RetryKeyBackupState)
|
||||
val loadingState2 = awaitItem()
|
||||
assertThat(loadingState2.doesBackupExistOnServer).isInstanceOf(AsyncData.Loading::class.java)
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.doesBackupExistOnServer.dataOrNull()).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - setting up encryption when key storage is disabled should emit a state to render a dialog`() = runTest {
|
||||
val presenter = createSecureBackupRootPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(2)
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(SecureBackupRootEvents.DisplayKeyStorageDisabledError)
|
||||
assertThat(awaitItem().displayKeyStorageDisabledError).isTrue()
|
||||
initialState.eventSink(SecureBackupRootEvents.DismissDialog)
|
||||
assertThat(awaitItem().displayKeyStorageDisabledError).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - enable key storage invoke the expected API`() = runTest {
|
||||
val presenter = createSecureBackupRootPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(2)
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink(SecureBackupRootEvents.EnableKeyStorage)
|
||||
assertThat(awaitItem().enableAction.isLoading()).isTrue()
|
||||
assertThat(awaitItem().enableAction.isSuccess()).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSecureBackupRootPresenter(
|
||||
encryptionService: EncryptionService = FakeEncryptionService(),
|
||||
appName: String = "Element",
|
||||
): SecureBackupRootPresenter {
|
||||
return SecureBackupRootPresenter(
|
||||
encryptionService = encryptionService,
|
||||
buildMeta = aBuildMeta(applicationName = appName),
|
||||
snackbarDispatcher = SnackbarDispatcher(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.root
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
import org.junit.Test
|
||||
|
||||
class SecureBackupRootStateTest {
|
||||
@Test
|
||||
fun `isKeyStorageEnabled should be true for all these backup states`() {
|
||||
listOf(
|
||||
BackupState.CREATING,
|
||||
BackupState.ENABLING,
|
||||
BackupState.RESUMING,
|
||||
BackupState.DOWNLOADING,
|
||||
BackupState.ENABLED,
|
||||
).forEach { backupState ->
|
||||
assertThat(aSecureBackupRootState(backupState = backupState).isKeyStorageEnabled).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isKeyStorageEnabled should be false for all these backup states`() {
|
||||
listOf(
|
||||
BackupState.WAITING_FOR_SYNC,
|
||||
BackupState.DISABLING,
|
||||
).forEach { backupState ->
|
||||
assertThat(aSecureBackupRootState(backupState = backupState).isKeyStorageEnabled).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isKeyStorageEnabled should have value depending on doesBackupExistOnServer when state is UNKNOWN`() {
|
||||
assertThat(
|
||||
aSecureBackupRootState(
|
||||
backupState = BackupState.UNKNOWN,
|
||||
doesBackupExistOnServer = AsyncData.Success(true),
|
||||
).isKeyStorageEnabled
|
||||
).isTrue()
|
||||
|
||||
listOf(
|
||||
AsyncData.Uninitialized,
|
||||
AsyncData.Loading(),
|
||||
AsyncData.Failure(AN_EXCEPTION),
|
||||
AsyncData.Success(false),
|
||||
).forEach { doesBackupExistOnServer ->
|
||||
assertThat(
|
||||
aSecureBackupRootState(
|
||||
backupState = BackupState.UNKNOWN,
|
||||
doesBackupExistOnServer = doesBackupExistOnServer,
|
||||
).isKeyStorageEnabled
|
||||
).isFalse()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.setup
|
||||
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
|
||||
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
|
||||
import io.element.android.libraries.matrix.api.encryption.EnableRecoveryProgress
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.test.A_RECOVERY_KEY
|
||||
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class SecureBackupSetupPresenterTest {
|
||||
@get:Rule
|
||||
val warmUpRule = WarmUpRule()
|
||||
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val presenter = createSecureBackupSetupPresenter()
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.isChangeRecoveryKeyUserStory).isFalse()
|
||||
assertThat(initialState.setupState).isEqualTo(SetupState.Init)
|
||||
assertThat(initialState.showSaveConfirmationDialog).isFalse()
|
||||
assertThat(initialState.recoveryKeyViewState).isEqualTo(
|
||||
RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Setup,
|
||||
formattedRecoveryKey = null,
|
||||
displayTextFieldContents = true,
|
||||
inProgress = false,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - create recovery key and save it`() = runTest {
|
||||
val encryptionService = FakeEncryptionService()
|
||||
val presenter = createSecureBackupSetupPresenter(
|
||||
encryptionService = encryptionService
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(SecureBackupSetupEvents.CreateRecoveryKey)
|
||||
val creatingState = awaitItem()
|
||||
assertThat(creatingState.setupState).isEqualTo(SetupState.Creating)
|
||||
assertThat(creatingState.recoveryKeyViewState).isEqualTo(
|
||||
RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Setup,
|
||||
formattedRecoveryKey = null,
|
||||
displayTextFieldContents = true,
|
||||
inProgress = true,
|
||||
)
|
||||
)
|
||||
encryptionService.emitEnableRecoveryProgress(EnableRecoveryProgress.Done(A_RECOVERY_KEY))
|
||||
val createdState = awaitItem()
|
||||
assertThat(createdState.setupState).isEqualTo(SetupState.Created(A_RECOVERY_KEY))
|
||||
assertThat(createdState.recoveryKeyViewState).isEqualTo(
|
||||
RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Setup,
|
||||
formattedRecoveryKey = A_RECOVERY_KEY,
|
||||
displayTextFieldContents = true,
|
||||
inProgress = false,
|
||||
)
|
||||
)
|
||||
createdState.eventSink.invoke(SecureBackupSetupEvents.RecoveryKeyHasBeenSaved)
|
||||
val createdAndSaveState = awaitItem()
|
||||
assertThat(createdAndSaveState.setupState).isInstanceOf(SetupState.CreatedAndSaved::class.java)
|
||||
createdAndSaveState.eventSink.invoke(SecureBackupSetupEvents.Done)
|
||||
val doneState = awaitItem()
|
||||
assertThat(doneState.showSaveConfirmationDialog).isTrue()
|
||||
doneState.eventSink.invoke(SecureBackupSetupEvents.DismissDialog)
|
||||
val doneStateCancelled = awaitItem()
|
||||
assertThat(doneStateCancelled.showSaveConfirmationDialog).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - initial state change key`() = runTest {
|
||||
val presenter = createSecureBackupSetupPresenter(
|
||||
isChangeRecoveryKeyUserStory = true,
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.isChangeRecoveryKeyUserStory).isTrue()
|
||||
assertThat(initialState.setupState).isEqualTo(SetupState.Init)
|
||||
assertThat(initialState.recoveryKeyViewState).isEqualTo(
|
||||
RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Change,
|
||||
formattedRecoveryKey = null,
|
||||
displayTextFieldContents = true,
|
||||
inProgress = false,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - handle errors`() = runTest {
|
||||
val encryptionService = FakeEncryptionService(
|
||||
enableRecoveryLambda = { Result.failure(IllegalStateException("Test error")) }
|
||||
)
|
||||
val presenter = createSecureBackupSetupPresenter(
|
||||
isChangeRecoveryKeyUserStory = false,
|
||||
encryptionService = encryptionService
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.isChangeRecoveryKeyUserStory).isFalse()
|
||||
assertThat(initialState.setupState).isEqualTo(SetupState.Init)
|
||||
|
||||
initialState.eventSink(SecureBackupSetupEvents.CreateRecoveryKey)
|
||||
val creatingState = awaitItem()
|
||||
assertThat(creatingState.setupState).isEqualTo(SetupState.Creating)
|
||||
val failedState = awaitItem()
|
||||
assertThat(failedState.setupState).isInstanceOf(SetupState.Error::class.java)
|
||||
failedState.eventSink(SecureBackupSetupEvents.DismissDialog)
|
||||
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.setupState).isEqualTo(SetupState.Init)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - change recovery key and save it`() = runTest {
|
||||
val encryptionService = FakeEncryptionService()
|
||||
val presenter = createSecureBackupSetupPresenter(
|
||||
isChangeRecoveryKeyUserStory = true,
|
||||
encryptionService = encryptionService
|
||||
)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
initialState.eventSink.invoke(SecureBackupSetupEvents.CreateRecoveryKey)
|
||||
val creatingState = awaitItem()
|
||||
assertThat(creatingState.setupState).isEqualTo(SetupState.Creating)
|
||||
assertThat(creatingState.recoveryKeyViewState).isEqualTo(
|
||||
RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Change,
|
||||
formattedRecoveryKey = null,
|
||||
displayTextFieldContents = true,
|
||||
inProgress = true,
|
||||
)
|
||||
)
|
||||
val createdState = awaitItem()
|
||||
assertThat(createdState.setupState).isEqualTo(SetupState.Created(FakeEncryptionService.FAKE_RECOVERY_KEY))
|
||||
assertThat(createdState.recoveryKeyViewState).isEqualTo(
|
||||
RecoveryKeyViewState(
|
||||
recoveryKeyUserStory = RecoveryKeyUserStory.Change,
|
||||
formattedRecoveryKey = FakeEncryptionService.FAKE_RECOVERY_KEY,
|
||||
displayTextFieldContents = true,
|
||||
inProgress = false,
|
||||
)
|
||||
)
|
||||
createdState.eventSink.invoke(SecureBackupSetupEvents.RecoveryKeyHasBeenSaved)
|
||||
val createdAndSaveState = awaitItem()
|
||||
assertThat(createdAndSaveState.setupState).isInstanceOf(SetupState.CreatedAndSaved::class.java)
|
||||
createdAndSaveState.eventSink.invoke(SecureBackupSetupEvents.Done)
|
||||
val doneState = awaitItem()
|
||||
assertThat(doneState.showSaveConfirmationDialog).isTrue()
|
||||
doneState.eventSink.invoke(SecureBackupSetupEvents.DismissDialog)
|
||||
val doneStateCancelled = awaitItem()
|
||||
assertThat(doneStateCancelled.showSaveConfirmationDialog).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSecureBackupSetupPresenter(
|
||||
isChangeRecoveryKeyUserStory: Boolean = false,
|
||||
encryptionService: EncryptionService = FakeEncryptionService(
|
||||
enableRecoveryLambda = { Result.success(Unit) },
|
||||
),
|
||||
): SecureBackupSetupPresenter {
|
||||
return SecureBackupSetupPresenter(
|
||||
isChangeRecoveryKeyUserStory = isChangeRecoveryKeyUserStory,
|
||||
stateMachine = SecureBackupSetupStateMachine(),
|
||||
encryptionService = encryptionService,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.tools
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
|
||||
class RecoveryKeyToolsTest {
|
||||
@Test
|
||||
fun `isRecoveryKeyFormatValid return false for invalid key`() {
|
||||
val sut = RecoveryKeyTools()
|
||||
assertThat(sut.isRecoveryKeyFormatValid("")).isFalse()
|
||||
// Wrong size
|
||||
assertThat(sut.isRecoveryKeyFormatValid("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabc")).isFalse()
|
||||
assertThat(sut.isRecoveryKeyFormatValid("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcda")).isFalse()
|
||||
// Wrong alphabet 0
|
||||
assertThat(sut.isRecoveryKeyFormatValid("0bcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd")).isFalse()
|
||||
// Wrong alphabet O
|
||||
assertThat(sut.isRecoveryKeyFormatValid("Obcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd")).isFalse()
|
||||
// Wrong alphabet l
|
||||
assertThat(sut.isRecoveryKeyFormatValid("lbcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd")).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isRecoveryKeyFormatValid return true for valid key`() {
|
||||
val sut = RecoveryKeyTools()
|
||||
assertThat(sut.isRecoveryKeyFormatValid("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd")).isTrue()
|
||||
// Spaces does not count
|
||||
assertThat(sut.isRecoveryKeyFormatValid("abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd")).isTrue()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.tools
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
|
||||
class RecoveryKeyVisualTransformationTest {
|
||||
@Test
|
||||
fun `RecoveryKeyOffsetMapping computes correct originalToTransformed values`() {
|
||||
var sut = RecoveryKeyVisualTransformation.RecoveryKeyOffsetMapping("")
|
||||
assertThat(sut.originalToTransformed(0)).isEqualTo(0)
|
||||
|
||||
sut = RecoveryKeyVisualTransformation.RecoveryKeyOffsetMapping("a")
|
||||
assertThat(sut.originalToTransformed(0)).isEqualTo(0)
|
||||
assertThat(sut.originalToTransformed(1)).isEqualTo(1)
|
||||
|
||||
sut = RecoveryKeyVisualTransformation.RecoveryKeyOffsetMapping("ab")
|
||||
assertThat(sut.originalToTransformed(0)).isEqualTo(0)
|
||||
assertThat(sut.originalToTransformed(1)).isEqualTo(1)
|
||||
assertThat(sut.originalToTransformed(2)).isEqualTo(2)
|
||||
|
||||
sut = RecoveryKeyVisualTransformation.RecoveryKeyOffsetMapping("abc")
|
||||
assertThat(sut.originalToTransformed(0)).isEqualTo(0)
|
||||
assertThat(sut.originalToTransformed(1)).isEqualTo(1)
|
||||
assertThat(sut.originalToTransformed(2)).isEqualTo(2)
|
||||
assertThat(sut.originalToTransformed(3)).isEqualTo(3)
|
||||
|
||||
sut = RecoveryKeyVisualTransformation.RecoveryKeyOffsetMapping("abcd")
|
||||
assertThat(sut.originalToTransformed(0)).isEqualTo(0)
|
||||
assertThat(sut.originalToTransformed(1)).isEqualTo(1)
|
||||
assertThat(sut.originalToTransformed(2)).isEqualTo(2)
|
||||
assertThat(sut.originalToTransformed(3)).isEqualTo(3)
|
||||
assertThat(sut.originalToTransformed(4)).isEqualTo(4)
|
||||
|
||||
sut = RecoveryKeyVisualTransformation.RecoveryKeyOffsetMapping("abcde")
|
||||
assertThat(sut.originalToTransformed(0)).isEqualTo(0)
|
||||
assertThat(sut.originalToTransformed(1)).isEqualTo(1)
|
||||
assertThat(sut.originalToTransformed(2)).isEqualTo(2)
|
||||
assertThat(sut.originalToTransformed(3)).isEqualTo(3)
|
||||
assertThat(sut.originalToTransformed(4)).isEqualTo(5)
|
||||
assertThat(sut.originalToTransformed(5)).isEqualTo(6)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `RecoveryKeyOffsetMapping computes correct transformedToOriginal values`() {
|
||||
// text parameter is not used by transformedToOriginal
|
||||
val sut = RecoveryKeyVisualTransformation.RecoveryKeyOffsetMapping("")
|
||||
assertThat(sut.transformedToOriginal(0)).isEqualTo(0)
|
||||
assertThat(sut.transformedToOriginal(1)).isEqualTo(1)
|
||||
assertThat(sut.transformedToOriginal(2)).isEqualTo(2)
|
||||
assertThat(sut.transformedToOriginal(3)).isEqualTo(3)
|
||||
assertThat(sut.transformedToOriginal(4)).isEqualTo(4)
|
||||
assertThat(sut.transformedToOriginal(5)).isEqualTo(4)
|
||||
assertThat(sut.transformedToOriginal(6)).isEqualTo(5)
|
||||
assertThat(sut.transformedToOriginal(7)).isEqualTo(6)
|
||||
assertThat(sut.transformedToOriginal(8)).isEqualTo(7)
|
||||
assertThat(sut.transformedToOriginal(9)).isEqualTo(8)
|
||||
assertThat(sut.transformedToOriginal(10)).isEqualTo(8)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user