Skip to content

Commit ebc6508

Browse files
committed
Don't show preimport dialog when launching from password import promo
1 parent 92e9ebd commit ebc6508

File tree

8 files changed

+97
-23
lines changed

8 files changed

+97
-23
lines changed

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillPasswordsManagementViewModel.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsMa
8787
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.DuckAddressStatus.NotManageable
8888
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.DuckAddressStatus.SettingActivationStatus
8989
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchDeleteAllPasswordsConfirmation
90-
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchImportPasswordsFromGooglePasswordManager
90+
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchImportGooglePasswords
9191
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchReportAutofillBreakageConfirmation
9292
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchResetNeverSaveListConfirmation
9393
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.PromptUserToAuthenticateMassDeletion
@@ -454,7 +454,7 @@ class AutofillPasswordsManagementViewModel @Inject constructor(
454454
viewModelScope.launch(dispatchers.io()) {
455455
autofillEffectDispatcher.effects.collect { effect ->
456456
when {
457-
effect is LaunchImportPasswords -> addCommand(LaunchImportPasswordsFromGooglePasswordManager)
457+
effect is LaunchImportPasswords -> addCommand(LaunchImportGooglePasswords(showImportInstructions = false))
458458
}
459459
}
460460
}
@@ -740,7 +740,7 @@ class AutofillPasswordsManagementViewModel @Inject constructor(
740740

741741
fun onImportPasswordsFromGooglePasswordManager() {
742742
viewModelScope.launch(dispatchers.io()) {
743-
addCommand(LaunchImportPasswordsFromGooglePasswordManager)
743+
addCommand(LaunchImportGooglePasswords(showImportInstructions = true))
744744
}
745745
}
746746

@@ -904,7 +904,7 @@ class AutofillPasswordsManagementViewModel @Inject constructor(
904904
data object LaunchResetNeverSaveListConfirmation : ListModeCommand()
905905
data class LaunchDeleteAllPasswordsConfirmation(val numberToDelete: Int) : ListModeCommand()
906906
data class PromptUserToAuthenticateMassDeletion(val authConfiguration: AuthConfiguration) : ListModeCommand()
907-
data object LaunchImportPasswordsFromGooglePasswordManager : ListModeCommand()
907+
data class LaunchImportGooglePasswords(val showImportInstructions: Boolean) : ListModeCommand()
908908
data class LaunchReportAutofillBreakageConfirmation(val eTldPlusOne: String) : ListModeCommand()
909909
data object ShowUserReportSentMessage : ListModeCommand()
910910
data object ReevalutePromotions : ListModeCommand()

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialog.kt

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,15 @@ import com.duckduckgo.autofill.impl.importing.gpm.webflow.ImportGooglePassword
4242
import com.duckduckgo.autofill.impl.importing.gpm.webflow.ImportGooglePasswordResult
4343
import com.duckduckgo.autofill.impl.ui.credential.dialog.animateClosed
4444
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.ImportPasswordsPixelSender
45+
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewMode.DeterminingFirstView
46+
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewMode.FlowTerminated
4547
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewMode.ImportError
4648
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewMode.ImportSuccess
4749
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewMode.Importing
4850
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewMode.PreImport
4951
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewState
52+
import com.duckduckgo.common.ui.view.gone
53+
import com.duckduckgo.common.ui.view.show
5054
import com.duckduckgo.common.utils.FragmentViewModelFactory
5155
import com.duckduckgo.common.utils.extensions.html
5256
import com.duckduckgo.di.scopes.FragmentScope
@@ -109,13 +113,15 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() {
109113
when (it) {
110114
is ImportGooglePasswordResult.Success -> viewModel.onImportFlowFinishedSuccessfully()
111115
is ImportGooglePasswordResult.Error -> viewModel.onImportFlowFinishedWithError(it.reason)
112-
is ImportGooglePasswordResult.UserCancelled -> viewModel.onImportFlowCancelledByUser(it.stage)
116+
is ImportGooglePasswordResult.UserCancelled -> viewModel.onImportFlowCancelledByUser(it.stage, canShowPreImportDialog())
113117
else -> {}
114118
}
115119
}
116120
}
117121

118122
private fun switchDialogShowImportInProgressView() {
123+
showDialogContent()
124+
119125
binding.prePostViewSwitcher.displayedChild = 1
120126
binding.postflow.inProgressFinishedViewSwitcher.displayedChild = 0
121127
}
@@ -126,10 +132,13 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() {
126132
}
127133

128134
private fun switchDialogShowPreImportView() {
135+
showDialogContent()
129136
binding.prePostViewSwitcher.displayedChild = 0
130137
}
131138

132139
private fun processSuccessResult(result: CredentialImporter.ImportResult.Finished) {
140+
showDialogContent()
141+
133142
binding.postflow.importFinished.errorNotImported.visibility = View.GONE
134143
binding.postflow.appIcon.setImageDrawable(
135144
ContextCompat.getDrawable(
@@ -154,6 +163,8 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() {
154163
}
155164

156165
private fun processErrorResult() {
166+
showDialogContent()
167+
157168
binding.postflow.importFinished.resultsImported.visibility = View.GONE
158169
binding.postflow.importFinished.duplicatesNotImported.visibility = View.GONE
159170
binding.postflow.importFinished.errorNotImported.visibility = View.VISIBLE
@@ -169,6 +180,14 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() {
169180
switchDialogShowImportResultsView()
170181
}
171182

183+
private fun showDialogContent() {
184+
binding.root.show()
185+
}
186+
187+
private fun hideDialogContent() {
188+
binding.root.gone()
189+
}
190+
172191
override fun onAttach(context: Context) {
173192
AndroidSupportInjection.inject(this)
174193
super.onAttach(context)
@@ -180,16 +199,24 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() {
180199
if (savedInstanceState != null) {
181200
// If being created after a configuration change, dismiss the dialog as the WebView will be re-created too
182201
dismiss()
202+
return
203+
}
204+
205+
// check if we should show the initial instructional prompt
206+
if (canShowPreImportDialog()) {
207+
viewModel.shouldShowInitialInstructionalPrompt()
208+
} else {
209+
startImportWebFlow()
183210
}
184211
}
185212

213+
private fun canShowPreImportDialog() = arguments?.getBoolean(KEY_SHOW_INITIAL_INSTRUCTIONAL_PROMPT, true) ?: true
214+
186215
override fun onCreateView(
187216
inflater: LayoutInflater,
188217
container: ViewGroup?,
189218
savedInstanceState: Bundle?,
190219
): View {
191-
importPasswordsPixelSender.onImportPasswordsDialogDisplayed()
192-
193220
_binding = ContentImportFromGooglePasswordDialogBinding.inflate(inflater, container, false)
194221
configureViews(binding)
195222
observeViewModel()
@@ -208,6 +235,8 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() {
208235
is ImportError -> processErrorResult()
209236
is ImportSuccess -> processSuccessResult(viewState.viewMode.importResult)
210237
is Importing -> switchDialogShowImportInProgressView()
238+
is DeterminingFirstView -> hideDialogContent()
239+
is FlowTerminated -> dismiss()
211240
}
212241
}
213242

@@ -233,6 +262,11 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() {
233262
}
234263

235264
private fun onImportGcmButtonClicked() {
265+
startImportWebFlow()
266+
importPasswordsPixelSender.onImportPasswordsDialogImportButtonClicked()
267+
}
268+
269+
private fun startImportWebFlow() {
236270
authorizationGracePeriod.requestExtendedGracePeriod()
237271

238272
val intent = globalActivityStarter.startIntent(
@@ -241,8 +275,6 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() {
241275
)
242276
importGooglePasswordsFlowLauncher.launch(intent)
243277

244-
importPasswordsPixelSender.onImportPasswordsDialogImportButtonClicked()
245-
246278
// we don't want the eventual dismissal of this dialog to count as a cancellation
247279
ignoreCancellationEvents = true
248280
}
@@ -266,8 +298,13 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() {
266298

267299
companion object {
268300

269-
fun instance(): ImportFromGooglePasswordsDialog {
301+
private const val KEY_SHOW_INITIAL_INSTRUCTIONAL_PROMPT = "showInitialInstructionalPrompt"
302+
303+
fun instance(showInitialInstructionalPrompt: Boolean): ImportFromGooglePasswordsDialog {
270304
val fragment = ImportFromGooglePasswordsDialog()
305+
fragment.arguments = Bundle().apply {
306+
putBoolean(KEY_SHOW_INITIAL_INSTRUCTIONAL_PROMPT, showInitialInstructionalPrompt)
307+
}
271308
return fragment
272309
}
273310
}

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialogViewModel.kt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.duckduckgo.autofill.impl.importing.CredentialImporter
2323
import com.duckduckgo.autofill.impl.importing.CredentialImporter.ImportResult
2424
import com.duckduckgo.autofill.impl.importing.gpm.webflow.ImportGooglePasswordsWebFlowViewModel.UserCannotImportReason
2525
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.ImportPasswordsPixelSender
26+
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewMode.DeterminingFirstView
2627
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewMode.Importing
2728
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialogViewModel.ViewMode.PreImport
2829
import com.duckduckgo.common.utils.DispatcherProvider
@@ -68,8 +69,12 @@ class ImportFromGooglePasswordsDialogViewModel @Inject constructor(
6869
_viewState.value = ViewState(viewMode = ViewMode.ImportError)
6970
}
7071

71-
fun onImportFlowCancelledByUser(stage: String) {
72+
fun onImportFlowCancelledByUser(stage: String, canShowPreImportDialog: Boolean) {
7273
importPasswordsPixelSender.onUserCancelledImportWebFlow(stage)
74+
75+
if (!canShowPreImportDialog) {
76+
_viewState.value = ViewState(viewMode = ViewMode.FlowTerminated)
77+
}
7378
}
7479

7580
private fun fireImportSuccessPixel(savedCredentials: Int, numberSkipped: Int) {
@@ -80,15 +85,22 @@ class ImportFromGooglePasswordsDialogViewModel @Inject constructor(
8085
importPasswordsPixelSender.onImportFailed(reason)
8186
}
8287

88+
fun shouldShowInitialInstructionalPrompt() {
89+
importPasswordsPixelSender.onImportPasswordsDialogDisplayed()
90+
_viewState.value = viewState.value.copy(viewMode = PreImport)
91+
}
92+
8393
private val _viewState = MutableStateFlow(ViewState())
8494
val viewState: StateFlow<ViewState> = _viewState
8595

86-
data class ViewState(val viewMode: ViewMode = PreImport)
96+
data class ViewState(val viewMode: ViewMode = DeterminingFirstView)
8797

8898
sealed interface ViewMode {
99+
data object DeterminingFirstView : ViewMode
89100
data object PreImport : ViewMode
90101
data object Importing : ViewMode
91102
data class ImportSuccess(val importResult: ImportResult.Finished) : ViewMode
92103
data object ImportError : ViewMode
104+
data object FlowTerminated : ViewMode
93105
}
94106
}

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListMode.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementR
4949
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementRecyclerAdapter.CredentialsLoadedState.Loading
5050
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel
5151
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchDeleteAllPasswordsConfirmation
52-
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchImportPasswordsFromGooglePasswordManager
52+
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchImportGooglePasswords
5353
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchReportAutofillBreakageConfirmation
5454
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchResetNeverSaveListConfirmation
5555
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.PromptUserToAuthenticateMassDeletion
@@ -339,7 +339,7 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill
339339
LaunchResetNeverSaveListConfirmation -> launchResetNeverSavedSitesConfirmation()
340340
is LaunchDeleteAllPasswordsConfirmation -> launchDeleteAllLoginsConfirmationDialog(command.numberToDelete)
341341
is PromptUserToAuthenticateMassDeletion -> promptUserToAuthenticateMassDeletion(command.authConfiguration)
342-
is LaunchImportPasswordsFromGooglePasswordManager -> launchImportPasswordsScreen()
342+
is LaunchImportGooglePasswords -> launchImportPasswordsScreen(showInitialInstructionalPrompt = command.showImportInstructions)
343343
is LaunchReportAutofillBreakageConfirmation -> launchReportBreakageConfirmation(command.eTldPlusOne)
344344
is ShowUserReportSentMessage -> showUserReportSentMessage()
345345
is ReevalutePromotions -> evaluatePromotions()
@@ -357,9 +357,9 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill
357357
Snackbar.make(binding.root, R.string.autofillManagementReportBreakageSuccessMessage, Snackbar.LENGTH_LONG).show()
358358
}
359359

360-
private fun launchImportPasswordsScreen() {
360+
private fun launchImportPasswordsScreen(showInitialInstructionalPrompt: Boolean) {
361361
context?.let {
362-
val dialog = ImportFromGooglePasswordsDialog.instance()
362+
val dialog = ImportFromGooglePasswordsDialog.instance(showInitialInstructionalPrompt = showInitialInstructionalPrompt)
363363
dialog.show(parentFragmentManager, IMPORT_FROM_GPM_DIALOG_TAG)
364364
}
365365
}

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListModeLegacy.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementR
5555
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementRecyclerAdapterLegacy.ContextMenuAction.Edit
5656
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel
5757
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchDeleteAllPasswordsConfirmation
58-
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchImportPasswordsFromGooglePasswordManager
58+
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchImportGooglePasswords
5959
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchReportAutofillBreakageConfirmation
6060
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchResetNeverSaveListConfirmation
6161
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.PromptUserToAuthenticateMassDeletion
@@ -421,7 +421,7 @@ class AutofillManagementListModeLegacy : DuckDuckGoFragment(R.layout.fragment_au
421421
LaunchResetNeverSaveListConfirmation -> launchResetNeverSavedSitesConfirmation()
422422
is LaunchDeleteAllPasswordsConfirmation -> launchDeleteAllLoginsConfirmationDialog(command.numberToDelete)
423423
is PromptUserToAuthenticateMassDeletion -> promptUserToAuthenticateMassDeletion(command.authConfiguration)
424-
is LaunchImportPasswordsFromGooglePasswordManager -> launchImportPasswordsScreen()
424+
is LaunchImportGooglePasswords -> launchImportPasswordsScreen(command.showImportInstructions)
425425
is LaunchReportAutofillBreakageConfirmation -> launchReportBreakageConfirmation(command.eTldPlusOne)
426426
is ShowUserReportSentMessage -> showUserReportSentMessage()
427427
is ReevalutePromotions -> configurePromotionsContainer()
@@ -433,9 +433,9 @@ class AutofillManagementListModeLegacy : DuckDuckGoFragment(R.layout.fragment_au
433433
Snackbar.make(binding.root, R.string.autofillManagementReportBreakageSuccessMessage, Snackbar.LENGTH_LONG).show()
434434
}
435435

436-
private fun launchImportPasswordsScreen() {
436+
private fun launchImportPasswordsScreen(showImportInstructions: Boolean) {
437437
context?.let {
438-
val dialog = ImportFromGooglePasswordsDialog.instance()
438+
val dialog = ImportFromGooglePasswordsDialog.instance(showInitialInstructionalPrompt = showImportInstructions)
439439
dialog.show(parentFragmentManager, IMPORT_FROM_GPM_DIALOG_TAG)
440440
}
441441
}

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ class AutofillSettingsActivity : DuckDuckGoActivity() {
223223
}
224224

225225
private fun launchImportPasswordsScreen() {
226-
val dialog = ImportFromGooglePasswordsDialog.instance()
226+
val dialog = ImportFromGooglePasswordsDialog.instance(showInitialInstructionalPrompt = true)
227227
dialog.show(supportFragmentManager, IMPORT_FROM_GPM_DIALOG_TAG)
228228
}
229229

autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillSettingsActivityScreenViewModelTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsMa
7676
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.CredentialMode.EditingExisting
7777
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand
7878
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchDeleteAllPasswordsConfirmation
79-
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchImportPasswordsFromGooglePasswordManager
79+
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchImportGooglePasswords
8080
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.LaunchReportAutofillBreakageConfirmation
8181
import com.duckduckgo.autofill.impl.ui.credential.management.AutofillPasswordsManagementViewModel.ListModeCommand.PromptUserToAuthenticateMassDeletion
8282
import com.duckduckgo.autofill.impl.ui.credential.management.searching.CredentialListFilter
@@ -1069,7 +1069,7 @@ class AutofillSettingsActivityScreenViewModelTest {
10691069

10701070
testee.commandsListView.test {
10711071
val commands = awaitItem()
1072-
assertTrue(commands.contains(LaunchImportPasswordsFromGooglePasswordManager))
1072+
assertTrue(commands.contains(LaunchImportGooglePasswords(true)))
10731073
cancelAndIgnoreRemainingEvents()
10741074
}
10751075
}

0 commit comments

Comments
 (0)