diff --git a/common/common-ui/src/main/res/drawable/ic_platform_playstore_16.xml b/common/common-ui/src/main/res/drawable/ic_platform_playstore_16.xml new file mode 100644 index 000000000000..15acdd744896 --- /dev/null +++ b/common/common-ui/src/main/res/drawable/ic_platform_playstore_16.xml @@ -0,0 +1,10 @@ + + + diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt index b2e17927cbc9..c1ffcb942bf7 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt @@ -52,7 +52,7 @@ object SubscriptionsConstants { // URLs const val BUY_URL = "https://duckduckgo.com/subscriptions" - const val ACTIVATE_URL = "https://duckduckgo.com/subscriptions/activate" + const val ACTIVATE_URL = "https://duckduckgo.com/subscriptions/activation-flow" const val ITR_URL = "https://duckduckgo.com/identity-theft-restoration" const val FAQS_URL = "https://duckduckgo.com/duckduckgo-help-pages/privacy-pro/" const val PRIVACY_PRO_ETLD = "duckduckgo.com" diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixel.kt index bc1017d325c7..3fc851e8450d 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixel.kt @@ -103,10 +103,6 @@ enum class SubscriptionPixel( baseName = "m_privacy-pro_welcome_add-device_click", type = Unique(), ), - ADD_DEVICE_ENTER_EMAIL_CLICK( - baseName = "m_privacy-pro_add-device_enter-email_click", - type = Count, - ), ONBOARDING_VPN_CLICK( baseName = "m_privacy-pro_welcome_vpn_click", type = Unique(), diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixelSender.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixelSender.kt index d6a597317e58..aaf1af6e3249 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixelSender.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixelSender.kt @@ -22,7 +22,6 @@ import com.duckduckgo.common.utils.extensions.toSanitizedLanguageTag import com.duckduckgo.di.scopes.AppScope import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ACTIVATE_SUBSCRIPTION_ENTER_EMAIL_CLICK import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ACTIVATE_SUBSCRIPTION_RESTORE_PURCHASE_CLICK -import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ADD_DEVICE_ENTER_EMAIL_CLICK import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.APP_SETTINGS_IDTR_CLICK import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.APP_SETTINGS_PIR_CLICK import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.APP_SETTINGS_RESTORE_PURCHASE_CLICK @@ -77,7 +76,6 @@ interface SubscriptionPixelSender { fun reportRestoreAfterPurchaseAttemptSuccess() fun reportSubscriptionActivated() fun reportOnboardingAddDeviceClick() - fun reportAddDeviceEnterEmailClick() fun reportOnboardingVpnClick() fun reportOnboardingPirClick() fun reportOnboardingIdtrClick() @@ -164,9 +162,6 @@ class SubscriptionPixelSenderImpl @Inject constructor( override fun reportOnboardingAddDeviceClick() = fire(ONBOARDING_ADD_DEVICE_CLICK) - override fun reportAddDeviceEnterEmailClick() = - fire(ADD_DEVICE_ENTER_EMAIL_CLICK) - override fun reportOnboardingVpnClick() = fire(ONBOARDING_VPN_CLICK) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingView.kt index 1be5197b2a20..75c91092e91f 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingView.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingView.kt @@ -19,9 +19,7 @@ package com.duckduckgo.subscriptions.impl.settings.views import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet -import android.view.MotionEvent import android.widget.FrameLayout -import android.widget.LinearLayout import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.findViewTreeViewModelStoreOwner @@ -196,13 +194,3 @@ class ProSettingView @JvmOverloads constructor( } } } - -class SubscriptionSettingLayout @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0, -) : LinearLayout(context, attrs, defStyleAttr) { - override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { - return true - } -} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/RestoreSubscriptionActivity.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/RestoreSubscriptionActivity.kt index 5499f14174d3..df5bbd52408f 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/RestoreSubscriptionActivity.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/RestoreSubscriptionActivity.kt @@ -43,7 +43,6 @@ import com.duckduckgo.subscriptions.impl.ui.RestoreSubscriptionViewModel.Command import com.duckduckgo.subscriptions.impl.ui.RestoreSubscriptionViewModel.Command.SubscriptionNotFound import com.duckduckgo.subscriptions.impl.ui.RestoreSubscriptionViewModel.Command.Success import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsActivity.Companion.SubscriptionsSettingsScreenWithEmptyParams -import com.duckduckgo.subscriptions.impl.ui.SubscriptionsWebViewActivityWithParams.ToolbarConfig.CustomTitle import javax.inject.Inject import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -78,16 +77,16 @@ class RestoreSubscriptionActivity : DuckDuckGoActivity() { .onEach { processCommand(it) } .launchIn(lifecycleScope) - binding.googlePlay.setOnClickListener { - viewModel.restoreFromStore() - } + // removing the click listeners from the LineListItems + // so that they don't trigger the selectable background animation when interacted with + binding.restoreSubscriptionEmailTitle.setOnClickListener(null) + binding.restoreSubscriptionGooglePlayTitle.setOnClickListener(null) - with(binding.manageEmailCard) { - emailSubtitle.setText(string.restoreSubscriptionEmailDescription) - emailButton.setText(string.restoreSubscriptionEmailButton) - emailButton.setOnClickListener { - viewModel.restoreFromEmail() - } + binding.restoreSubscriptionEmailLayout.setOnClickListener { + viewModel.restoreFromEmail() + } + binding.restoreSubscriptionGooglePlayLayout.setOnClickListener { + viewModel.restoreFromStore() } } @@ -102,7 +101,6 @@ class RestoreSubscriptionActivity : DuckDuckGoActivity() { this, SubscriptionsWebViewActivityWithParams( url = ACTIVATE_URL, - toolbarConfig = CustomTitle(getString(string.addEmailText)), ), ) startForResultRestore.launch(intent) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SelectableLinearLayout.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SelectableLinearLayout.kt new file mode 100644 index 000000000000..1f3672f6dc86 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SelectableLinearLayout.kt @@ -0,0 +1,35 @@ +/* + * 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.subscriptions.impl.ui + +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import android.widget.LinearLayout + +/** + * A wrapper that can be used when you don't want to pass touch events to children of your layout. + */ +class SelectableLinearLayout @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, +) : LinearLayout(context, attrs, defStyleAttr) { + override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { + return true + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsActivity.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsActivity.kt index fecc699b4d1b..3f3393241bad 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsActivity.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsActivity.kt @@ -43,6 +43,7 @@ import com.duckduckgo.subscriptions.api.SubscriptionStatus.EXPIRED import com.duckduckgo.subscriptions.api.SubscriptionStatus.INACTIVE import com.duckduckgo.subscriptions.impl.R.* import com.duckduckgo.subscriptions.impl.SubscriptionsConstants +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.ACTIVATE_URL import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.BASIC_SUBSCRIPTION import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.FAQS_URL import com.duckduckgo.subscriptions.impl.databinding.ActivitySubscriptionSettingsBinding @@ -51,7 +52,7 @@ import com.duckduckgo.subscriptions.impl.ui.ChangePlanActivity.Companion.ChangeP import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsActivity.Companion.SubscriptionsSettingsScreenWithEmptyParams import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.FinishSignOut -import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToAddEmailScreen +import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToActivationScreen import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToEditEmailScreen import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToPortal import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.SubscriptionDuration.Monthly @@ -117,7 +118,11 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() { } binding.manageEmail.setOnClickListener { - viewModel.onEmailButtonClicked() + viewModel.onEditEmailButtonClicked() + } + + binding.addToDevice.setOnClickListener { + viewModel.onAddToDeviceButtonClicked() } binding.faq.setClickListener { @@ -210,11 +215,12 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() { } if (viewState.email == null) { - binding.manageEmail.setPrimaryText(resources.getString(string.addEmailPrimaryText)) - binding.manageEmail.setSecondaryText(resources.getString(string.addEmailSecondaryText)) + binding.manageEmail.gone() + binding.addToDevice.setSecondaryText(resources.getString(string.addToDeviceSecondaryTextWithoutEmail)) } else { - binding.manageEmail.setPrimaryText(resources.getString(string.editEmailPrimaryText)) - binding.manageEmail.setSecondaryText(viewState.email + "\n\n" + resources.getString(string.editEmailSecondaryText)) + binding.manageEmail.show() + binding.manageEmail.setSecondaryText(viewState.email) + binding.addToDevice.setSecondaryText(resources.getString(string.addToDeviceSecondaryTextWithEmail)) } if (viewState.showFeedback) { @@ -231,7 +237,7 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() { finish() } - GoToAddEmailScreen -> goToAddEmail() + GoToActivationScreen -> goToActivation() GoToEditEmailScreen -> goToEditEmail() is GoToPortal -> { @@ -285,12 +291,11 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() { ) } - private fun goToAddEmail() { + private fun goToActivation() { globalActivityStarter.start( this, SubscriptionsWebViewActivityWithParams( - url = ADD_EMAIL_URL, - toolbarConfig = CustomTitle(getString(string.addEmailText)), + url = ACTIVATE_URL, ), ) } @@ -307,7 +312,6 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() { companion object { const val URL = "https://play.google.com/store/account/subscriptions?sku=%s&package=%s" - const val ADD_EMAIL_URL = "https://duckduckgo.com/subscriptions/add-email" const val MANAGE_URL = "https://duckduckgo.com/subscriptions/manage" const val LEARN_MORE_URL = "https://duckduckgo.com/duckduckgo-help-pages/privacy-pro/adding-email" const val PRIVACY_POLICY_URL = "https://duckduckgo.com/pro/privacy-terms" diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModel.kt index e6be6500a731..d4996344be69 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModel.kt @@ -31,7 +31,7 @@ import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_US import com.duckduckgo.subscriptions.impl.SubscriptionsManager import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.FinishSignOut -import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToAddEmailScreen +import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToActivationScreen import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToEditEmailScreen import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToPortal import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.SubscriptionDuration.Monthly @@ -102,11 +102,15 @@ class SubscriptionSettingsViewModel @Inject constructor( ) } - fun onEmailButtonClicked() { - val state = (viewState.value as? Ready) ?: return - pixelSender.reportAddDeviceEnterEmailClick() + fun onEditEmailButtonClicked() { viewModelScope.launch { - command.send(if (state.email == null) GoToAddEmailScreen else GoToEditEmailScreen) + command.send(GoToEditEmailScreen) + } + } + + fun onAddToDeviceButtonClicked() { + viewModelScope.launch { + command.send(GoToActivationScreen) } } @@ -134,7 +138,7 @@ class SubscriptionSettingsViewModel @Inject constructor( sealed class Command { data object FinishSignOut : Command() data object GoToEditEmailScreen : Command() - data object GoToAddEmailScreen : Command() + data object GoToActivationScreen : Command() data class GoToPortal(val url: String) : Command() } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt index 2f3154729395..d52da434d493 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt @@ -33,7 +33,6 @@ import androidx.activity.result.contract.ActivityResultContracts.StartActivityFo import androidx.annotation.AnyThread import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat -import androidx.core.net.toUri import androidx.fragment.app.DialogFragment import androidx.lifecycle.Lifecycle import androidx.lifecycle.flowWithLifecycle @@ -201,8 +200,6 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD itrJsMessaging.register(it, null) it.webChromeClient = object : WebChromeClient() { - private var url: String? = null - override fun onCreateWindow( view: WebView?, isDialog: Boolean, @@ -219,12 +216,6 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD view: WebView?, newProgress: Int, ) { - view?.url.let { currentUrl -> - if (currentUrl != url) { - url = currentUrl - onUrlChanged(url) - } - } if (newProgress == 100) { if (binding.webview.canGoBack()) { toolbar.setNavigationIcon(R.drawable.ic_arrow_left_24) @@ -421,20 +412,6 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD } } - private fun onUrlChanged(url: String?) { - val addEmailPath = SubscriptionSettingsActivity.ADD_EMAIL_URL.toUri().path ?: return - - val shouldOverrideTitleForAddEmailFlow = url?.toUri()?.path?.startsWith(addEmailPath) ?: false - - updateToolbarTitle( - if (shouldOverrideTitleForAddEmailFlow) { - CustomTitle(getString(string.addEmailText)) - } else { - params.toolbarConfig - }, - ) - } - private fun processCommand(command: Command) { when (command) { is BackToSettings, BackToSettingsActivateSuccess -> backToSettings() diff --git a/subscriptions/subscriptions-impl/src/main/res/drawable/background_email_card.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/background_email_card.xml deleted file mode 100644 index 1ec01e693c30..000000000000 --- a/subscriptions/subscriptions-impl/src/main/res/drawable/background_email_card.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/main/res/drawable/ic_google_play.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_google_play.xml deleted file mode 100644 index a67af448e371..000000000000 --- a/subscriptions/subscriptions-impl/src/main/res/drawable/ic_google_play.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/subscriptions/subscriptions-impl/src/main/res/drawable/ic_privacy_pro_add_device.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_privacy_pro_add_device.xml new file mode 100644 index 000000000000..c66728e98837 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_privacy_pro_add_device.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/subscriptions/subscriptions-impl/src/main/res/drawable/ic_sync.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_sync.xml deleted file mode 100644 index c951347ac875..000000000000 --- a/subscriptions/subscriptions-impl/src/main/res/drawable/ic_sync.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/subscriptions/subscriptions-impl/src/main/res/drawable/ic_sync_desktop.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_sync_desktop.xml deleted file mode 100644 index e749cac238f6..000000000000 --- a/subscriptions/subscriptions-impl/src/main/res/drawable/ic_sync_desktop.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/activity_restore_subscription.xml b/subscriptions/subscriptions-impl/src/main/res/layout/activity_restore_subscription.xml index ab9b63e3cc07..5f36d3aaf656 100644 --- a/subscriptions/subscriptions-impl/src/main/res/layout/activity_restore_subscription.xml +++ b/subscriptions/subscriptions-impl/src/main/res/layout/activity_restore_subscription.xml @@ -15,79 +15,147 @@ --> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + tools:context="com.duckduckgo.subscriptions.impl.ui.RestoreSubscriptionActivity"> + android:id="@+id/includeToolbar" + layout="@layout/include_default_toolbar" /> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fillViewport="true"> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + android:id="@+id/headerImage" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginTop="@dimen/keyline_5" + app:srcCompat="@drawable/ic_privacy_pro_add_device" + tools:ignore="ContentDescription" /> + + + + + + + app:leadingIcon="@drawable/ic_email_16" + app:leadingIconBackground="circular" + app:primaryText="@string/restoreSubscriptionEmailTitle" + app:secondaryText="@string/restoreSubscriptionEmailDescription" /> - + android:orientation="horizontal"> - + + - + + + + + + + android:layout_height="wrap_content" /> - + android:background="?attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:orientation="vertical" + android:paddingVertical="@dimen/keyline_1"> + + + + + + + + + + + diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/activity_subscription_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/activity_subscription_settings.xml index 426a49d89793..9fa3f01d66dc 100644 --- a/subscriptions/subscriptions-impl/src/main/res/layout/activity_subscription_settings.xml +++ b/subscriptions/subscriptions-impl/src/main/res/layout/activity_subscription_settings.xml @@ -119,8 +119,14 @@ android:id="@+id/manageEmail" android:layout_width="match_parent" android:layout_height="wrap_content" - tools:primaryText="@string/addEmailPrimaryText" - tools:secondaryText="@string/addEmailSecondaryText"/> + app:primaryText="@string/editEmailPrimaryText" /> + + - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/view_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/view_settings.xml index 983aca8c830c..24b69b96fa8b 100644 --- a/subscriptions/subscriptions-impl/src/main/res/layout/view_settings.xml +++ b/subscriptions/subscriptions-impl/src/main/res/layout/view_settings.xml @@ -22,7 +22,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - - + - - + - - + - - + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml b/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml index 541cc0c6ad15..913a82ac6235 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml @@ -19,8 +19,6 @@ Cancel OK Privacy Pro - Email - Add Email Manage Email @@ -32,12 +30,13 @@ Subscription Not Found The subscription associated with this Google Play account is no longer active. Your purchases have been restored. - Activate your subscription on this device - Access your Privacy Pro subscription on this device via Google Play or an email address. - Your subscription is automatically available in DuckDuckGo on any device signed in to your Google Play account. - Restore Purchase - Use your email to activate your subscription on this device. - Enter Email + Add your Privacy Pro subscription to this device + Add via Google Play Account + Restore your subscription on Android devices using your Google Play account. + Restore Purchase + Add via Email + Link an email address to your subscription to add Privacy Pro to this device. + Get Started Remove Subscription @@ -51,11 +50,11 @@ Yearly Subscription renews expires - Activate on Other Devices - Add Email - Add an optional email to your subscription to access Privacy\u00A0Pro on other devices. + Add Privacy Pro to Other Devices + Add to Device + Add Privacy Pro to your other devices via Google Play or by linking an email address. + Use the email above to add your subscription on your other devices in the DuckDuckGo app. Go to Settings > Privacy Pro > I Have a Subscription. Edit Email - Use this email to activate your subscription in Settings > Privacy Pro in the DuckDuckGo app on your other devices. Learn More Need help with Privacy Pro? Get answers to frequently asked questions or contact Privacy Pro support from our help pages. Feature availability varies by country. @@ -160,7 +159,7 @@ Subscriptions Subscription Settings - Activate Subscription + I Have a Subscription Privacy Pro Send Feedback \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModelTest.kt index 3a91b57325eb..50ed30f9f4cb 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModelTest.kt @@ -4,23 +4,23 @@ import app.cash.turbine.test import com.duckduckgo.common.test.CoroutineTestRule import com.duckduckgo.subscriptions.api.PrivacyProUnifiedFeedback import com.duckduckgo.subscriptions.api.SubscriptionStatus -import com.duckduckgo.subscriptions.api.SubscriptionStatus.* +import com.duckduckgo.subscriptions.api.SubscriptionStatus.AUTO_RENEWABLE import com.duckduckgo.subscriptions.impl.SubscriptionsConstants import com.duckduckgo.subscriptions.impl.SubscriptionsManager import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.repository.Account import com.duckduckgo.subscriptions.impl.repository.Subscription import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.FinishSignOut -import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToAddEmailScreen +import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToActivationScreen import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToEditEmailScreen import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToPortal import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.SubscriptionDuration.Monthly import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.SubscriptionDuration.Yearly import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.ViewState.Ready import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest -import org.junit.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test @@ -185,85 +185,19 @@ class SubscriptionSettingsViewModelTest { } @Test - fun whenOnEmailButtonClickedAndEmailNotPresentThenSendGoToAddEmailScreenCommand() = runTest { - whenever(subscriptionsManager.subscriptionStatus).thenReturn(flowOf(AUTO_RENEWABLE)) - whenever(privacyProUnifiedFeedback.shouldUseUnifiedFeedback(any())).thenReturn(false) - - whenever(subscriptionsManager.getSubscription()).thenReturn( - Subscription( - productId = SubscriptionsConstants.MONTHLY_PLAN_US, - startedAt = 1234, - expiresOrRenewsAt = 1701694623000, - status = AUTO_RENEWABLE, - platform = "android", - ), - ) - - whenever(subscriptionsManager.getAccount()).thenReturn( - Account(email = null, externalId = "external_id"), - ) - - viewModel.onCreate(mock()) - - viewModel.commands().test { - viewModel.onEmailButtonClicked() - assertEquals(GoToAddEmailScreen, awaitItem()) - cancelAndIgnoreRemainingEvents() - } - } - - @Test - fun whenOnEmailButtonClickedAndEmailNotPresentThenSendGoToEditEmailScreenCommand() = runTest { - whenever(subscriptionsManager.subscriptionStatus).thenReturn(flowOf(AUTO_RENEWABLE)) - whenever(privacyProUnifiedFeedback.shouldUseUnifiedFeedback(any())).thenReturn(false) - - whenever(subscriptionsManager.getSubscription()).thenReturn( - Subscription( - productId = SubscriptionsConstants.MONTHLY_PLAN_US, - startedAt = 1234, - expiresOrRenewsAt = 1701694623000, - status = AUTO_RENEWABLE, - platform = "android", - ), - ) - - whenever(subscriptionsManager.getAccount()).thenReturn( - Account(email = "test@example.com", externalId = "external_id"), - ) - - viewModel.onCreate(mock()) - + fun `when OnEditEmail button clicked then send GoToEditEmailScreen command`() = runTest { viewModel.commands().test { - viewModel.onEmailButtonClicked() + viewModel.onEditEmailButtonClicked() assertEquals(GoToEditEmailScreen, awaitItem()) cancelAndIgnoreRemainingEvents() } } @Test - fun whenOnEmailButtonClickedThenPixelIsSent() = runTest { - whenever(subscriptionsManager.subscriptionStatus).thenReturn(flowOf(AUTO_RENEWABLE)) - whenever(privacyProUnifiedFeedback.shouldUseUnifiedFeedback(any())).thenReturn(false) - - whenever(subscriptionsManager.getSubscription()).thenReturn( - Subscription( - productId = SubscriptionsConstants.MONTHLY_PLAN_US, - startedAt = 1234, - expiresOrRenewsAt = 1701694623000, - status = AUTO_RENEWABLE, - platform = "android", - ), - ) - - whenever(subscriptionsManager.getAccount()).thenReturn( - Account(email = "test@example.com", externalId = "external_id"), - ) - - viewModel.onCreate(mock()) - + fun `when AddToDevice button clicked then send GoToActivationScreen command`() = runTest { viewModel.commands().test { - viewModel.onEmailButtonClicked() - verify(pixelSender).reportAddDeviceEnterEmailClick() + viewModel.onAddToDeviceButtonClicked() + assertEquals(GoToActivationScreen, awaitItem()) cancelAndIgnoreRemainingEvents() } }