Skip to content

Commit

Permalink
Update copy when deleting passwords to consider whether sync enabled …
Browse files Browse the repository at this point in the history
…or not
  • Loading branch information
CDRussell committed May 6, 2024
1 parent 8ac474e commit 3510012
Show file tree
Hide file tree
Showing 30 changed files with 259 additions and 280 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ class AutofillManagementCredentialsMode : DuckDuckGoFragment(R.layout.fragment_a
@Inject
lateinit var browserNav: BrowserNav

@Inject
lateinit var stringBuilder: AutofillManagementStringBuilder

// we need to revert the toolbar title when this fragment is destroyed, so will track its initial value
private var initialActionBarTitle: String? = null

Expand Down Expand Up @@ -176,21 +179,28 @@ class AutofillManagementCredentialsMode : DuckDuckGoFragment(R.layout.fragment_a

private fun launchDeleteLoginConfirmationDialog() {
this.context?.let {
TextAlertDialogBuilder(it)
.setTitle(R.string.autofillDeleteLoginDialogTitle)
.setMessage(R.string.credentialManagementDeletePasswordConfirmationMessage)
.setDestructiveButtons(true)
.setPositiveButton(R.string.autofillDeleteLoginDialogDelete)
.setNegativeButton(R.string.autofillDeleteLoginDialogCancel)
.addEventListener(
object : TextAlertDialogBuilder.EventListener() {
override fun onPositiveButtonClicked() {
viewModel.onDeleteCurrentCredentials()
viewModel.onExitCredentialMode()
}
},
)
.show()
lifecycleScope.launch(dispatchers.io()) {
val dialogTitle = stringBuilder.stringForDeletePasswordDialogConfirmationTitle(numberToDelete = 1)
val dialogMessage = stringBuilder.stringForDeletePasswordDialogConfirmationMessage(numberToDelete = 1)

withContext(dispatchers.main()) {
TextAlertDialogBuilder(it)
.setTitle(dialogTitle)
.setMessage(dialogMessage)
.setDestructiveButtons(true)
.setPositiveButton(R.string.autofillDeleteLoginDialogDelete)
.setNegativeButton(R.string.autofillDeleteLoginDialogCancel)
.addEventListener(
object : TextAlertDialogBuilder.EventListener() {
override fun onPositiveButtonClicked() {
viewModel.onDeleteCurrentCredentials()
viewModel.onExitCredentialMode()
}
},
)
.show()
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import com.duckduckgo.di.scopes.FragmentScope
import com.duckduckgo.mobile.android.R as CommonR
import javax.inject.Inject
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

@InjectWith(FragmentScope::class)
class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill_management_list_mode) {
Expand Down Expand Up @@ -94,6 +95,9 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill
@Inject
lateinit var deviceAuthenticator: DeviceAuthenticator

@Inject
lateinit var stringBuilder: AutofillManagementStringBuilder

val viewModel by lazy {
ViewModelProvider(requireActivity(), viewModelFactory)[AutofillSettingsViewModel::class.java]
}
Expand Down Expand Up @@ -319,61 +323,54 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill

private fun launchDeleteLoginConfirmationDialog(loginCredentials: LoginCredentials) {
this.context?.let {
TextAlertDialogBuilder(it)
.setTitle(R.string.autofillDeleteLoginDialogTitle)
.setMessage(R.string.credentialManagementDeletePasswordConfirmationMessage)
.setDestructiveButtons(true)
.setPositiveButton(R.string.autofillDeleteLoginDialogDelete)
.setNegativeButton(R.string.autofillDeleteLoginDialogCancel)
.addEventListener(
object : TextAlertDialogBuilder.EventListener() {
override fun onPositiveButtonClicked() {
viewModel.onDeleteCredentials(loginCredentials)
}
},
)
.show()
lifecycleScope.launch(dispatchers.io()) {
val dialogTitle = stringBuilder.stringForDeletePasswordDialogConfirmationTitle(numberToDelete = 1)
val dialogMessage = stringBuilder.stringForDeletePasswordDialogConfirmationMessage(numberToDelete = 1)

withContext(dispatchers.main()) {
TextAlertDialogBuilder(it)
.setTitle(dialogTitle)
.setMessage(dialogMessage)
.setDestructiveButtons(true)
.setPositiveButton(R.string.autofillDeleteLoginDialogDelete)
.setNegativeButton(R.string.autofillDeleteLoginDialogCancel)
.addEventListener(
object : TextAlertDialogBuilder.EventListener() {
override fun onPositiveButtonClicked() {
viewModel.onDeleteCredentials(loginCredentials)
}
},
)
.show()
}
}
}
}

private fun launchDeleteAllLoginsConfirmationDialog(numberToDelete: Int) {
val displayStrings = getDisplayStringsForDeletingAllLogins(numberToDelete)

this.context?.let {
TextAlertDialogBuilder(it)
.setTitle(displayStrings.first)
.setMessage(displayStrings.second)
.setDestructiveButtons(true)
.setPositiveButton(R.string.autofillDeleteLoginDialogDelete)
.setNegativeButton(R.string.autofillDeleteLoginDialogCancel)
.setCancellable(true)
.addEventListener(
object : TextAlertDialogBuilder.EventListener() {
override fun onPositiveButtonClicked() {
viewModel.onDeleteAllPasswordsConfirmed()
}
},
)
.show()
}
}

/**
* Returns a pair of strings for the title and message of the delete all logins confirmation dialog.
*
* The strings will change depending on if there is only one login to delete or multiple.
*/
private fun getDisplayStringsForDeletingAllLogins(numberToDelete: Int): Pair<String, String> {
return if (numberToDelete == 1) {
Pair(
getString(R.string.autofillDeleteLoginDialogTitle),
getString(R.string.credentialManagementDeletePasswordConfirmationMessage),
)
} else {
Pair(
resources.getQuantityString(R.plurals.credentialManagementDeleteAllPasswordsConfirmationTitle, numberToDelete, numberToDelete),
getString(R.string.credentialManagementDeleteAllPasswordsConfirmationMessage),
)
lifecycleScope.launch(dispatchers.io()) {
val dialogTitle = stringBuilder.stringForDeletePasswordDialogConfirmationTitle(numberToDelete)
val dialogMessage = stringBuilder.stringForDeletePasswordDialogConfirmationMessage(numberToDelete)

withContext(dispatchers.main()) {
TextAlertDialogBuilder(it)
.setTitle(dialogTitle)
.setMessage(dialogMessage)
.setDestructiveButtons(true)
.setPositiveButton(R.string.autofillDeleteLoginDialogDelete)
.setNegativeButton(R.string.autofillDeleteLoginDialogCancel)
.setCancellable(true)
.addEventListener(
object : TextAlertDialogBuilder.EventListener() {
override fun onPositiveButtonClicked() {
viewModel.onDeleteAllPasswordsConfirmed()
}
},
)
.show()
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2024 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.duckduckgo.autofill.impl.ui.credential.management.viewing

import android.content.Context
import android.content.res.Resources
import com.duckduckgo.autofill.impl.R
import com.duckduckgo.common.utils.DispatcherProvider
import com.duckduckgo.di.scopes.FragmentScope
import com.duckduckgo.sync.api.DeviceSyncState
import com.squareup.anvil.annotations.ContributesBinding
import javax.inject.Inject
import kotlinx.coroutines.withContext

interface AutofillManagementStringBuilder {
fun stringForDeletePasswordDialogConfirmationTitle(numberToDelete: Int): String
suspend fun stringForDeletePasswordDialogConfirmationMessage(numberToDelete: Int): String
}

@ContributesBinding(FragmentScope::class)
class AutofillManagementStringBuilderImpl @Inject constructor(
private val context: Context,
private val deviceSyncState: DeviceSyncState,
private val dispatchers: DispatcherProvider,
) : AutofillManagementStringBuilder {

override fun stringForDeletePasswordDialogConfirmationTitle(numberToDelete: Int): String {
if (numberToDelete == 1) {
return context.getString(R.string.credentialManagementDeleteAllPasswordsDialogConfirmationTitleSingular)
}

return context.resources.getQuantityString(
R.plurals.credentialManagementDeleteAllPasswordsDialogConfirmationTitlePlural,
numberToDelete,
numberToDelete,
)
}

override suspend fun stringForDeletePasswordDialogConfirmationMessage(numberToDelete: Int): String {
val firstMessage = context.resources.deleteAllPasswordsWarning(numberToDelete)
val secondMessage = if (numberToDelete == 1) {
context.resources.getString(R.string.credentialManagementDeleteAllSecondInstructionSingular)
} else {
context.resources.getQuantityString(R.plurals.credentialManagementDeleteAllSecondInstructionPlural, numberToDelete)
}
return "$firstMessage $secondMessage"
}

private suspend fun Resources.deleteAllPasswordsWarning(numberToDelete: Int): String {
return withContext(dispatchers.io()) {
return@withContext if (deviceSyncState.isUserSignedInOnDevice()) {
if (numberToDelete == 1) {
getString(R.string.credentialManagementDeleteAllPasswordsFirstInstructionSyncedSingular)
} else {
getQuantityString(R.plurals.credentialManagementDeleteAllPasswordsFirstInstructionSyncedPlural, numberToDelete)
}
} else {
if (numberToDelete == 1) {
getString(R.string.credentialManagementDeleteAllPasswordsDialogFirstInstructionNotSyncedSingular)
} else {
getQuantityString(R.plurals.credentialManagementDeleteAllPasswordsDialogFirstInstructionNotSyncedPlural, numberToDelete)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@
<string name="saveLoginDialogSubtitle">Паролите се съхраняват сигурно на Вашето устройство.</string>
<string name="autofillManagementAddLogin">Добавяне на парола</string>
<string name="credentialManagementEditLoginTitleHint">Заглавие</string>
<string name="autofillDeleteLoginDialogTitle">Сигурни ли сте, че искате да изтриете тази парола?</string>
<string name="autofillManagementDeletedConfirmation">Паролата е изтрита</string>
<string name="credentialManagementEditLastUpdated" instruction="Placeholder is a date">Последна актуализация %1$s</string>
<string name="autofillDisableAutofillPromptTitle">Искате ли да продължите да запазвате пароли?</string>
Expand All @@ -146,13 +145,6 @@
<string name="credentialManagementClearNeverForThisSiteDialogNegativeButton">Отмени</string>

<string name="credentialManagementDeleteAllPasswordsMenu">Изтриване на всички пароли</string>
<plurals name="credentialManagementDeleteAllPasswordsConfirmationTitle" instruction="Placeholder is a number representing how many passwords will be deleted">
<item quantity="one">Сигурни ли сте, че искате да изтриете %1$d парола?</item>
<item quantity="other">Сигурни ли сте, че искате да изтриете %1$d пароли?</item>
</plurals>

<string name="credentialManagementDeletePasswordConfirmationMessage">Вашата парола ще бъде изтрита от всички синхронизирани устройства. Уверете се, че все още имате друг начин за достъп до акаунта си.</string>
<string name="credentialManagementDeleteAllPasswordsConfirmationMessage">Вашите пароли ще бъдат изтрити от всички синхронизирани устройства. Уверете се, че все още имате друг начин за достъп до Вашите акаунти.</string>

<plurals name="credentialManagementDeleteAllPasswordsSnackbarConfirmation" instruction="Placeholder is a number representing how many passwords were deleted">
<item quantity="one">%1$d изтрита парола</item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@
<string name="saveLoginDialogSubtitle">Hesla se bezpečně ukládají do tvého zařízení.</string>
<string name="autofillManagementAddLogin">Přidat heslo</string>
<string name="credentialManagementEditLoginTitleHint">Název</string>
<string name="autofillDeleteLoginDialogTitle">Opravdu chceš smazat tohle heslo?</string>
<string name="autofillManagementDeletedConfirmation">Heslo smazáno</string>
<string name="credentialManagementEditLastUpdated" instruction="Placeholder is a date">Poslední aktualizace %1$s</string>
<string name="autofillDisableAutofillPromptTitle">Chceš dál ukládat hesla?</string>
Expand All @@ -146,15 +145,6 @@
<string name="credentialManagementClearNeverForThisSiteDialogNegativeButton">Zrušit</string>

<string name="credentialManagementDeleteAllPasswordsMenu">Smazat všechna hesla</string>
<plurals name="credentialManagementDeleteAllPasswordsConfirmationTitle" instruction="Placeholder is a number representing how many passwords will be deleted">
<item quantity="one">Opravdu chceš smazat %1$d heslo?</item>
<item quantity="few">Opravdu chceš smazat %1$d hesla?</item>
<item quantity="many">Opravdu chceš smazat %1$d hesla?</item>
<item quantity="other">Opravdu chceš smazat %1$d hesel?</item>
</plurals>

<string name="credentialManagementDeletePasswordConfirmationMessage">Tvoje heslo se smaže ze všech synchronizovaných zařízení. Zkontroluj si předtím, že se i tak dostaneš ke svému účtu.</string>
<string name="credentialManagementDeleteAllPasswordsConfirmationMessage">Tvoje hesla se smažou ze všech synchronizovaných zařízení. Zkontroluj si předtím, že se k účtům i tak dostaneš.</string>

<plurals name="credentialManagementDeleteAllPasswordsSnackbarConfirmation" instruction="Placeholder is a number representing how many passwords were deleted">
<item quantity="one">%1$d smazané heslo</item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@
<string name="saveLoginDialogSubtitle">Adgangskoder gemmes sikkert på din enhed.</string>
<string name="autofillManagementAddLogin">Tilføj adgangskode</string>
<string name="credentialManagementEditLoginTitleHint">Titel</string>
<string name="autofillDeleteLoginDialogTitle">Er du sikker på, at du vil slette denne adgangskode?</string>
<string name="autofillManagementDeletedConfirmation">Adgangskode slettet</string>
<string name="credentialManagementEditLastUpdated" instruction="Placeholder is a date">Sidst opdateret %1$s</string>
<string name="autofillDisableAutofillPromptTitle">Vil du fortsætte med at gemme adgangskoder?</string>
Expand All @@ -146,13 +145,6 @@
<string name="credentialManagementClearNeverForThisSiteDialogNegativeButton">Annuller</string>

<string name="credentialManagementDeleteAllPasswordsMenu">Slet alle adgangskoder</string>
<plurals name="credentialManagementDeleteAllPasswordsConfirmationTitle" instruction="Placeholder is a number representing how many passwords will be deleted">
<item quantity="one">Er du sikker på, at du vil slette %1$d adgangskode?</item>
<item quantity="other">Er du sikker på, at du vil slette %1$d adgangskoder?</item>
</plurals>

<string name="credentialManagementDeletePasswordConfirmationMessage">Din adgangskode slettes fra alle synkroniserede enheder. Husk at sikre, at du stadig har adgang til din konto.</string>
<string name="credentialManagementDeleteAllPasswordsConfirmationMessage">Dine adgangskoder slettes fra alle synkroniserede enheder. Husk at sikre, at du stadig har adgang til dine konti.</string>

<plurals name="credentialManagementDeleteAllPasswordsSnackbarConfirmation" instruction="Placeholder is a number representing how many passwords were deleted">
<item quantity="one">%1$d adgangskode slettet</item>
Expand Down

0 comments on commit 3510012

Please sign in to comment.