diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/apps/ui/ManuallyDisableAppProtectionDialog.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/apps/ui/ManuallyDisableAppProtectionDialog.kt index 760a2e726133..8531494913e7 100644 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/apps/ui/ManuallyDisableAppProtectionDialog.kt +++ b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/apps/ui/ManuallyDisableAppProtectionDialog.kt @@ -121,11 +121,6 @@ class ManuallyDisableAppProtectionDialog : DialogFragment() { private const val KEY_APP_PACKAGE_NAME = "KEY_APP_PACKAGE_NAME" private const val KEY_APP_NAME = "KEY_APP_NAME" - const val NO_REASON_NEEDED = 0 - const val STOPPED_WORKING = 1 - const val TRACKING_OK = 2 - const val DONT_USE = 3 - fun instance(appInfo: TrackingProtectionAppInfo): ManuallyDisableAppProtectionDialog { return ManuallyDisableAppProtectionDialog().also { fragment -> val bundle = Bundle() diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/apps/ui/TrackingProtectionAppsAdapter.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/apps/ui/TrackingProtectionAppsAdapter.kt index c3c81de857de..490eb7a45a72 100644 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/apps/ui/TrackingProtectionAppsAdapter.kt +++ b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/apps/ui/TrackingProtectionAppsAdapter.kt @@ -76,10 +76,6 @@ class TrackingProtectionAppsAdapter(val listener: AppProtectionListener) : return excludedApps.size } - fun updateSwitchPosition(position: Int) { - notifyItemChanged(position) - } - private class DiffCallback( private val oldList: List, private val newList: List, diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/breakage/ReportBreakageAppListAdapter.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/breakage/ReportBreakageAppListAdapter.kt index 4cb328c2396c..cf9262856694 100644 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/breakage/ReportBreakageAppListAdapter.kt +++ b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/breakage/ReportBreakageAppListAdapter.kt @@ -24,7 +24,6 @@ import androidx.recyclerview.widget.RecyclerView import com.duckduckgo.app.global.extensions.safeGetApplicationIcon import com.duckduckgo.mobile.android.ui.view.quietlySetIsChecked import com.duckduckgo.mobile.android.vpn.R -import com.duckduckgo.mobile.android.vpn.ui.notification.applyBoldSpanTo import kotlinx.android.synthetic.main.view_device_shield_report_app_breakage_entry.view.* class ReportBreakageAppListAdapter(private val listener: Listener) : RecyclerView.Adapter() { @@ -104,9 +103,7 @@ class ReportBreakageAppListViewHolder(view: View) : RecyclerView.ViewHolder(view position: Int, listener: ReportBreakageAppListAdapter.Listener, ) { - itemView.deviceShieldInstalledAppEntryName.text = - String.format(itemView.context.resources.getString(R.string.atp_ReportBreakageAppEntry), installedApp.name) - .applyBoldSpanTo(listOf(installedApp.name)) + itemView.deviceShieldInstalledAppEntryName.text = installedApp.name itemView.deviceShieldInstalledAppSelector.quietlySetIsChecked(installedApp.isSelected) { _, _ -> listener.onInstalledAppSelected(installedApp, position) diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/breakage/ReportBreakageCategorySingleChoiceActivity.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/breakage/ReportBreakageCategorySingleChoiceActivity.kt index 5c3acf5e2c35..6396c1bff9df 100644 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/breakage/ReportBreakageCategorySingleChoiceActivity.kt +++ b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/breakage/ReportBreakageCategorySingleChoiceActivity.kt @@ -20,7 +20,6 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.util.Base64 -import androidx.appcompat.app.AlertDialog import androidx.core.text.HtmlCompat import androidx.lifecycle.Lifecycle.State.STARTED import androidx.lifecycle.flowWithLifecycle @@ -29,6 +28,7 @@ import com.duckduckgo.anvil.annotations.InjectWith import com.duckduckgo.app.global.DuckDuckGoActivity import com.duckduckgo.di.scopes.ActivityScope import com.duckduckgo.di.scopes.VpnScope +import com.duckduckgo.mobile.android.ui.view.dialog.RadioListAlertDialogBuilder import com.duckduckgo.mobile.android.ui.viewbinding.viewBinding import com.duckduckgo.mobile.android.vpn.R import com.duckduckgo.mobile.android.vpn.breakage.ReportBreakageCategorySingleChoiceViewModel.Command @@ -87,21 +87,28 @@ class ReportBreakageCategorySingleChoiceActivity : DuckDuckGoActivity() { } private fun configureListeners() { - val categories = viewModel.shuffledCategories.map { getString(it.category) }.toTypedArray() - binding.categoriesSelection.setOnClickListener { - AlertDialog.Builder(this) + val categories = viewModel.shuffledCategories.map { it.category } + binding.categoriesSelection.onAction { + RadioListAlertDialogBuilder(this) .setTitle(getString(R.string.atp_ReportBreakageCategoriesTitle)) - .setSingleChoiceItems(categories, viewModel.indexSelected) { _, newIndex -> - viewModel.onCategoryIndexChanged(newIndex) - } - .setPositiveButton(getString(android.R.string.yes)) { dialog, _ -> - viewModel.onCategoryAccepted() - dialog.dismiss() - } - .setNegativeButton(getString(android.R.string.no)) { dialog, _ -> - viewModel.onCategorySelectionCancelled() - dialog.dismiss() - } + .setOptions(categories, viewModel.indexSelected + 1) + .setPositiveButton(android.R.string.ok) + .setNegativeButton(android.R.string.cancel) + .addEventListener( + object : RadioListAlertDialogBuilder.EventListener() { + override fun onRadioItemSelected(selectedItem: Int) { + viewModel.onCategoryIndexChanged(selectedItem - 1) + } + + override fun onPositiveButtonClicked(selectedItem: Int) { + viewModel.onCategoryAccepted() + } + + override fun onNegativeButtonClicked() { + viewModel.onCategorySelectionCancelled() + } + }, + ) .show() } binding.ctaNextFormSubmit.setOnClickListener { viewModel.onSubmitPressed() } @@ -149,7 +156,7 @@ class ReportBreakageCategorySingleChoiceActivity : DuckDuckGoActivity() { private fun render(viewState: ViewState) { val category = viewState.categorySelected?.let { getString(viewState.categorySelected.category) }.orEmpty() - binding.categoriesSelection.setText(category) + binding.categoriesSelection.text = category binding.ctaNextFormSubmit.isEnabled = viewState.submitAllowed } diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/alwayson/AlwaysOnAlertDialogFragment.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/alwayson/AlwaysOnAlertDialogFragment.kt index 5683b199c520..933915fa8ca1 100644 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/alwayson/AlwaysOnAlertDialogFragment.kt +++ b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/alwayson/AlwaysOnAlertDialogFragment.kt @@ -49,7 +49,7 @@ class AlwaysOnAlertDialogFragment private constructor() : BottomSheetDialogFragm private lateinit var listener: Listener private lateinit var fragmentType: FragmentType - override fun getTheme(): Int = R.style.AlwaysOnBottomSheetDialogTheme + override fun getTheme(): Int = com.duckduckgo.mobile.android.R.style.Widget_DuckDuckGo_BottomSheetDialogCollapsed override fun onAttach(context: Context) { AndroidSupportInjection.inject(this) diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/onboarding/VpnOnboardingActivity.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/onboarding/VpnOnboardingActivity.kt index 9706d7fa3428..57b3e3ec681a 100644 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/onboarding/VpnOnboardingActivity.kt +++ b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/onboarding/VpnOnboardingActivity.kt @@ -31,6 +31,7 @@ import com.duckduckgo.anvil.annotations.InjectWith import com.duckduckgo.app.global.DuckDuckGoActivity import com.duckduckgo.appbuildconfig.api.AppBuildConfig import com.duckduckgo.di.scopes.ActivityScope +import com.duckduckgo.mobile.android.ui.view.dialog.TextAlertDialogBuilder import com.duckduckgo.mobile.android.ui.view.getColorFromAttr import com.duckduckgo.mobile.android.ui.viewbinding.viewBinding import com.duckduckgo.mobile.android.vpn.AppTpVpnFeature @@ -43,14 +44,13 @@ import com.duckduckgo.mobile.android.vpn.ui.onboarding.Command.LaunchVPN import com.duckduckgo.mobile.android.vpn.ui.onboarding.Command.RequestVPNPermission import com.duckduckgo.mobile.android.vpn.ui.onboarding.Command.ShowVpnAlwaysOnConflictDialog import com.duckduckgo.mobile.android.vpn.ui.onboarding.Command.ShowVpnConflictDialog -import com.duckduckgo.mobile.android.vpn.ui.tracker_activity.AppTPVpnConflictDialog import com.duckduckgo.mobile.android.vpn.ui.tracker_activity.DeviceShieldTrackerActivity import javax.inject.Inject import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @InjectWith(ActivityScope::class) -class VpnOnboardingActivity : DuckDuckGoActivity(), AppTPVpnConflictDialog.Listener { +class VpnOnboardingActivity : DuckDuckGoActivity() { @Inject lateinit var deviceShieldPixels: DeviceShieldPixels @@ -180,8 +180,8 @@ class VpnOnboardingActivity : DuckDuckGoActivity(), AppTPVpnConflictDialog.Liste private fun processCommand(command: Command) { when (command) { is LaunchVPN -> startVpn() - is ShowVpnConflictDialog -> launchVPNConflictDialog(false) - is ShowVpnAlwaysOnConflictDialog -> launchVPNConflictDialog(true) + is ShowVpnConflictDialog -> showVpnConflictDialog() + is ShowVpnAlwaysOnConflictDialog -> showAlwaysOnConflictDialog() is CheckVPNPermission -> checkVPNPermission() is RequestVPNPermission -> obtainVpnRequestPermission(command.vpnIntent) } @@ -228,21 +228,54 @@ class VpnOnboardingActivity : DuckDuckGoActivity(), AppTPVpnConflictDialog.Liste viewModel.onAppTpEnabled() } - private fun launchVPNConflictDialog(isAlwaysOn: Boolean) { + private fun showVpnConflictDialog() { deviceShieldPixels.didShowVpnConflictDialog() - val dialog = AppTPVpnConflictDialog.instance(this, isAlwaysOn) - dialog.show( - supportFragmentManager, - AppTPVpnConflictDialog.TAG_VPN_CONFLICT_DIALOG, - ) + TextAlertDialogBuilder(this) + .setTitle(R.string.atp_VpnConflictDialogTitle) + .setMessage(R.string.atp_VpnConflictDialogMessage) + .setPositiveButton(R.string.atp_VpnConflictDialogGotIt) + .setNegativeButton(R.string.atp_VpnConflictDialogCancel) + .addEventListener( + object : TextAlertDialogBuilder.EventListener() { + override fun onPositiveButtonClicked() { + onVpnConflictDialogContinue() + } + + override fun onNegativeButtonClicked() { + onVpnConflictDialogDismiss() + } + }, + ) + .show() + } + + private fun showAlwaysOnConflictDialog() { + deviceShieldPixels.didShowVpnConflictDialog() + TextAlertDialogBuilder(this) + .setTitle(R.string.atp_VpnConflictAlwaysOnDialogTitle) + .setMessage(R.string.atp_VpnConflictDialogAlwaysOnMessage) + .setPositiveButton(R.string.atp_VpnConflictDialogOpenSettings) + .setNegativeButton(R.string.atp_VpnConflictDialogCancel) + .addEventListener( + object : TextAlertDialogBuilder.EventListener() { + override fun onPositiveButtonClicked() { + onVpnConflictDialogGoToSettings() + } + + override fun onNegativeButtonClicked() { + onVpnConflictDialogDismiss() + } + }, + ) + .show() } - override fun onVpnConflictDialogDismiss() { + fun onVpnConflictDialogDismiss() { deviceShieldPixels.didChooseToDismissVpnConflictDialog() } @SuppressLint("InlinedApi") - override fun onVpnConflictDialogGoToSettings() { + fun onVpnConflictDialogGoToSettings() { deviceShieldPixels.didChooseToOpenSettingsFromVpnConflictDialog() val intent = if (appBuildConfig.sdkInt >= Build.VERSION_CODES.N) { @@ -254,7 +287,7 @@ class VpnOnboardingActivity : DuckDuckGoActivity(), AppTPVpnConflictDialog.Liste startActivity(intent) } - override fun onVpnConflictDialogContinue() { + fun onVpnConflictDialogContinue() { deviceShieldPixels.didChooseToContinueFromVpnConflictDialog() checkVPNPermission() } diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/AppTPCompanyTrackersActivity.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/AppTPCompanyTrackersActivity.kt index 2a63d071f2a8..d0d34d0bdfb5 100644 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/AppTPCompanyTrackersActivity.kt +++ b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/AppTPCompanyTrackersActivity.kt @@ -136,7 +136,7 @@ class AppTPCompanyTrackersActivity : DuckDuckGoActivity() { private fun renderViewState(viewState: ViewState) { cachedState = viewState - binding.trackingAttempts.text = resources.getQuantityString( + binding.trackingAttempts.primaryText = resources.getQuantityString( R.plurals.atp_CompanyDetailsTrackingAttemptsTitle, viewState.totalTrackingAttempts, viewState.totalTrackingAttempts, diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/AppTPDisableConfirmationDialog.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/AppTPDisableConfirmationDialog.kt deleted file mode 100644 index cd69a86a2586..000000000000 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/AppTPDisableConfirmationDialog.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2019 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.mobile.android.vpn.ui.tracker_activity - -import android.app.Dialog -import android.os.Bundle -import android.widget.Button -import androidx.fragment.app.DialogFragment -import com.duckduckgo.mobile.android.vpn.R -import com.google.android.material.dialog.MaterialAlertDialogBuilder - -class AppTPDisableConfirmationDialog private constructor(private val listener: Listener) : DialogFragment() { - - interface Listener { - fun onOpenAppProtection() - fun onTurnAppTrackingProtectionOff() - fun onDisableDialogCancelled() - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - isCancelable = false - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val rootView = layoutInflater.inflate(R.layout.dialog_tracking_protection_confirm_disable, null) - - val disableOneApp = rootView.findViewById