Skip to content

Commit 026f49f

Browse files
authored
update subscription activation screens (#5325)
Task/Issue URL: https://app.asana.com/0/1208671518894266/1208848139000087
1 parent 29091ad commit 026f49f

21 files changed

+309
-481
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="16dp"
3+
android:height="16dp"
4+
android:viewportWidth="16"
5+
android:viewportHeight="16">
6+
<path
7+
android:pathData="M2.874,14.978L8.5,8.919L10.388,10.951L3.631,14.852C3.385,14.994 3.119,15.028 2.874,14.978ZM2.011,14.069C2.004,14.018 2,13.965 2,13.911L2,2.089C2,2.035 2.004,1.982 2.011,1.931L7.647,8L2.011,14.069ZM2.873,1.022L8.5,7.082L10.388,5.048L3.631,1.148C3.385,1.006 3.119,0.972 2.873,1.022ZM11.498,5.69L9.353,8L11.498,10.31L13.869,8.942C14.594,8.523 14.594,7.477 13.869,7.058L11.498,5.69Z"
8+
android:fillColor="?attr/daxColorPrimaryIcon"
9+
android:fillType="evenOdd"/>
10+
</vector>

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ object SubscriptionsConstants {
5252

5353
// URLs
5454
const val BUY_URL = "https://duckduckgo.com/subscriptions"
55-
const val ACTIVATE_URL = "https://duckduckgo.com/subscriptions/activate"
55+
const val ACTIVATE_URL = "https://duckduckgo.com/subscriptions/activation-flow"
5656
const val ITR_URL = "https://duckduckgo.com/identity-theft-restoration"
5757
const val FAQS_URL = "https://duckduckgo.com/duckduckgo-help-pages/privacy-pro/"
5858
const val PRIVACY_PRO_ETLD = "duckduckgo.com"

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixel.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ enum class SubscriptionPixel(
103103
baseName = "m_privacy-pro_welcome_add-device_click",
104104
type = Unique(),
105105
),
106-
ADD_DEVICE_ENTER_EMAIL_CLICK(
107-
baseName = "m_privacy-pro_add-device_enter-email_click",
108-
type = Count,
109-
),
110106
ONBOARDING_VPN_CLICK(
111107
baseName = "m_privacy-pro_welcome_vpn_click",
112108
type = Unique(),

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixelSender.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import com.duckduckgo.common.utils.extensions.toSanitizedLanguageTag
2222
import com.duckduckgo.di.scopes.AppScope
2323
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ACTIVATE_SUBSCRIPTION_ENTER_EMAIL_CLICK
2424
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ACTIVATE_SUBSCRIPTION_RESTORE_PURCHASE_CLICK
25-
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ADD_DEVICE_ENTER_EMAIL_CLICK
2625
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.APP_SETTINGS_IDTR_CLICK
2726
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.APP_SETTINGS_PIR_CLICK
2827
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.APP_SETTINGS_RESTORE_PURCHASE_CLICK
@@ -77,7 +76,6 @@ interface SubscriptionPixelSender {
7776
fun reportRestoreAfterPurchaseAttemptSuccess()
7877
fun reportSubscriptionActivated()
7978
fun reportOnboardingAddDeviceClick()
80-
fun reportAddDeviceEnterEmailClick()
8179
fun reportOnboardingVpnClick()
8280
fun reportOnboardingPirClick()
8381
fun reportOnboardingIdtrClick()
@@ -164,9 +162,6 @@ class SubscriptionPixelSenderImpl @Inject constructor(
164162
override fun reportOnboardingAddDeviceClick() =
165163
fire(ONBOARDING_ADD_DEVICE_CLICK)
166164

167-
override fun reportAddDeviceEnterEmailClick() =
168-
fire(ADD_DEVICE_ENTER_EMAIL_CLICK)
169-
170165
override fun reportOnboardingVpnClick() =
171166
fire(ONBOARDING_VPN_CLICK)
172167

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingView.kt

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ package com.duckduckgo.subscriptions.impl.settings.views
1919
import android.annotation.SuppressLint
2020
import android.content.Context
2121
import android.util.AttributeSet
22-
import android.view.MotionEvent
2322
import android.widget.FrameLayout
24-
import android.widget.LinearLayout
2523
import androidx.lifecycle.ViewModelProvider
2624
import androidx.lifecycle.findViewTreeLifecycleOwner
2725
import androidx.lifecycle.findViewTreeViewModelStoreOwner
@@ -196,13 +194,3 @@ class ProSettingView @JvmOverloads constructor(
196194
}
197195
}
198196
}
199-
200-
class SubscriptionSettingLayout @JvmOverloads constructor(
201-
context: Context,
202-
attrs: AttributeSet? = null,
203-
defStyleAttr: Int = 0,
204-
) : LinearLayout(context, attrs, defStyleAttr) {
205-
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
206-
return true
207-
}
208-
}

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/RestoreSubscriptionActivity.kt

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import com.duckduckgo.subscriptions.impl.ui.RestoreSubscriptionViewModel.Command
4343
import com.duckduckgo.subscriptions.impl.ui.RestoreSubscriptionViewModel.Command.SubscriptionNotFound
4444
import com.duckduckgo.subscriptions.impl.ui.RestoreSubscriptionViewModel.Command.Success
4545
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsActivity.Companion.SubscriptionsSettingsScreenWithEmptyParams
46-
import com.duckduckgo.subscriptions.impl.ui.SubscriptionsWebViewActivityWithParams.ToolbarConfig.CustomTitle
4746
import javax.inject.Inject
4847
import kotlinx.coroutines.flow.launchIn
4948
import kotlinx.coroutines.flow.onEach
@@ -78,16 +77,16 @@ class RestoreSubscriptionActivity : DuckDuckGoActivity() {
7877
.onEach { processCommand(it) }
7978
.launchIn(lifecycleScope)
8079

81-
binding.googlePlay.setOnClickListener {
82-
viewModel.restoreFromStore()
83-
}
80+
// removing the click listeners from the LineListItems
81+
// so that they don't trigger the selectable background animation when interacted with
82+
binding.restoreSubscriptionEmailTitle.setOnClickListener(null)
83+
binding.restoreSubscriptionGooglePlayTitle.setOnClickListener(null)
8484

85-
with(binding.manageEmailCard) {
86-
emailSubtitle.setText(string.restoreSubscriptionEmailDescription)
87-
emailButton.setText(string.restoreSubscriptionEmailButton)
88-
emailButton.setOnClickListener {
89-
viewModel.restoreFromEmail()
90-
}
85+
binding.restoreSubscriptionEmailLayout.setOnClickListener {
86+
viewModel.restoreFromEmail()
87+
}
88+
binding.restoreSubscriptionGooglePlayLayout.setOnClickListener {
89+
viewModel.restoreFromStore()
9190
}
9291
}
9392

@@ -102,7 +101,6 @@ class RestoreSubscriptionActivity : DuckDuckGoActivity() {
102101
this,
103102
SubscriptionsWebViewActivityWithParams(
104103
url = ACTIVATE_URL,
105-
toolbarConfig = CustomTitle(getString(string.addEmailText)),
106104
),
107105
)
108106
startForResultRestore.launch(intent)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2024 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.subscriptions.impl.ui
18+
19+
import android.content.Context
20+
import android.util.AttributeSet
21+
import android.view.MotionEvent
22+
import android.widget.LinearLayout
23+
24+
/**
25+
* A wrapper that can be used when you don't want to pass touch events to children of your layout.
26+
*/
27+
class SelectableLinearLayout @JvmOverloads constructor(
28+
context: Context,
29+
attrs: AttributeSet? = null,
30+
defStyleAttr: Int = 0,
31+
) : LinearLayout(context, attrs, defStyleAttr) {
32+
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
33+
return true
34+
}
35+
}

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsActivity.kt

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import com.duckduckgo.subscriptions.api.SubscriptionStatus.EXPIRED
4343
import com.duckduckgo.subscriptions.api.SubscriptionStatus.INACTIVE
4444
import com.duckduckgo.subscriptions.impl.R.*
4545
import com.duckduckgo.subscriptions.impl.SubscriptionsConstants
46+
import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.ACTIVATE_URL
4647
import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.BASIC_SUBSCRIPTION
4748
import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.FAQS_URL
4849
import com.duckduckgo.subscriptions.impl.databinding.ActivitySubscriptionSettingsBinding
@@ -51,7 +52,7 @@ import com.duckduckgo.subscriptions.impl.ui.ChangePlanActivity.Companion.ChangeP
5152
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsActivity.Companion.SubscriptionsSettingsScreenWithEmptyParams
5253
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command
5354
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.FinishSignOut
54-
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToAddEmailScreen
55+
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToActivationScreen
5556
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToEditEmailScreen
5657
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToPortal
5758
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.SubscriptionDuration.Monthly
@@ -117,7 +118,11 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() {
117118
}
118119

119120
binding.manageEmail.setOnClickListener {
120-
viewModel.onEmailButtonClicked()
121+
viewModel.onEditEmailButtonClicked()
122+
}
123+
124+
binding.addToDevice.setOnClickListener {
125+
viewModel.onAddToDeviceButtonClicked()
121126
}
122127

123128
binding.faq.setClickListener {
@@ -210,11 +215,12 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() {
210215
}
211216

212217
if (viewState.email == null) {
213-
binding.manageEmail.setPrimaryText(resources.getString(string.addEmailPrimaryText))
214-
binding.manageEmail.setSecondaryText(resources.getString(string.addEmailSecondaryText))
218+
binding.manageEmail.gone()
219+
binding.addToDevice.setSecondaryText(resources.getString(string.addToDeviceSecondaryTextWithoutEmail))
215220
} else {
216-
binding.manageEmail.setPrimaryText(resources.getString(string.editEmailPrimaryText))
217-
binding.manageEmail.setSecondaryText(viewState.email + "\n\n" + resources.getString(string.editEmailSecondaryText))
221+
binding.manageEmail.show()
222+
binding.manageEmail.setSecondaryText(viewState.email)
223+
binding.addToDevice.setSecondaryText(resources.getString(string.addToDeviceSecondaryTextWithEmail))
218224
}
219225

220226
if (viewState.showFeedback) {
@@ -231,7 +237,7 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() {
231237
finish()
232238
}
233239

234-
GoToAddEmailScreen -> goToAddEmail()
240+
GoToActivationScreen -> goToActivation()
235241
GoToEditEmailScreen -> goToEditEmail()
236242

237243
is GoToPortal -> {
@@ -285,12 +291,11 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() {
285291
)
286292
}
287293

288-
private fun goToAddEmail() {
294+
private fun goToActivation() {
289295
globalActivityStarter.start(
290296
this,
291297
SubscriptionsWebViewActivityWithParams(
292-
url = ADD_EMAIL_URL,
293-
toolbarConfig = CustomTitle(getString(string.addEmailText)),
298+
url = ACTIVATE_URL,
294299
),
295300
)
296301
}
@@ -307,7 +312,6 @@ class SubscriptionSettingsActivity : DuckDuckGoActivity() {
307312

308313
companion object {
309314
const val URL = "https://play.google.com/store/account/subscriptions?sku=%s&package=%s"
310-
const val ADD_EMAIL_URL = "https://duckduckgo.com/subscriptions/add-email"
311315
const val MANAGE_URL = "https://duckduckgo.com/subscriptions/manage"
312316
const val LEARN_MORE_URL = "https://duckduckgo.com/duckduckgo-help-pages/privacy-pro/adding-email"
313317
const val PRIVACY_POLICY_URL = "https://duckduckgo.com/pro/privacy-terms"

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModel.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_US
3131
import com.duckduckgo.subscriptions.impl.SubscriptionsManager
3232
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender
3333
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.FinishSignOut
34-
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToAddEmailScreen
34+
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToActivationScreen
3535
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToEditEmailScreen
3636
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Command.GoToPortal
3737
import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.SubscriptionDuration.Monthly
@@ -102,11 +102,15 @@ class SubscriptionSettingsViewModel @Inject constructor(
102102
)
103103
}
104104

105-
fun onEmailButtonClicked() {
106-
val state = (viewState.value as? Ready) ?: return
107-
pixelSender.reportAddDeviceEnterEmailClick()
105+
fun onEditEmailButtonClicked() {
108106
viewModelScope.launch {
109-
command.send(if (state.email == null) GoToAddEmailScreen else GoToEditEmailScreen)
107+
command.send(GoToEditEmailScreen)
108+
}
109+
}
110+
111+
fun onAddToDeviceButtonClicked() {
112+
viewModelScope.launch {
113+
command.send(GoToActivationScreen)
110114
}
111115
}
112116

@@ -134,7 +138,7 @@ class SubscriptionSettingsViewModel @Inject constructor(
134138
sealed class Command {
135139
data object FinishSignOut : Command()
136140
data object GoToEditEmailScreen : Command()
137-
data object GoToAddEmailScreen : Command()
141+
data object GoToActivationScreen : Command()
138142
data class GoToPortal(val url: String) : Command()
139143
}
140144

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import androidx.activity.result.contract.ActivityResultContracts.StartActivityFo
3333
import androidx.annotation.AnyThread
3434
import androidx.appcompat.widget.Toolbar
3535
import androidx.core.content.ContextCompat
36-
import androidx.core.net.toUri
3736
import androidx.fragment.app.DialogFragment
3837
import androidx.lifecycle.Lifecycle
3938
import androidx.lifecycle.flowWithLifecycle
@@ -201,8 +200,6 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD
201200
itrJsMessaging.register(it, null)
202201
it.webChromeClient = object : WebChromeClient() {
203202

204-
private var url: String? = null
205-
206203
override fun onCreateWindow(
207204
view: WebView?,
208205
isDialog: Boolean,
@@ -219,12 +216,6 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD
219216
view: WebView?,
220217
newProgress: Int,
221218
) {
222-
view?.url.let { currentUrl ->
223-
if (currentUrl != url) {
224-
url = currentUrl
225-
onUrlChanged(url)
226-
}
227-
}
228219
if (newProgress == 100) {
229220
if (binding.webview.canGoBack()) {
230221
toolbar.setNavigationIcon(R.drawable.ic_arrow_left_24)
@@ -421,20 +412,6 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD
421412
}
422413
}
423414

424-
private fun onUrlChanged(url: String?) {
425-
val addEmailPath = SubscriptionSettingsActivity.ADD_EMAIL_URL.toUri().path ?: return
426-
427-
val shouldOverrideTitleForAddEmailFlow = url?.toUri()?.path?.startsWith(addEmailPath) ?: false
428-
429-
updateToolbarTitle(
430-
if (shouldOverrideTitleForAddEmailFlow) {
431-
CustomTitle(getString(string.addEmailText))
432-
} else {
433-
params.toolbarConfig
434-
},
435-
)
436-
}
437-
438415
private fun processCommand(command: Command) {
439416
when (command) {
440417
is BackToSettings, BackToSettingsActivateSuccess -> backToSettings()

0 commit comments

Comments
 (0)