@@ -86,7 +86,6 @@ import com.duckduckgo.app.global.ViewModelFactory
8686import com.duckduckgo.app.global.device.DeviceInfo
8787import com.duckduckgo.app.global.model.orderedTrackingEntities
8888import com.duckduckgo.app.global.view.*
89- import com.duckduckgo.app.privacy.model.PrivacyGrade
9089import com.duckduckgo.app.privacy.renderer.icon
9190import com.duckduckgo.app.statistics.VariantManager
9291import com.duckduckgo.app.statistics.pixels.Pixel
@@ -136,7 +135,7 @@ import javax.inject.Inject
136135import kotlin.concurrent.thread
137136import kotlin.coroutines.CoroutineContext
138137
139- class BrowserTabFragment : Fragment (), FindListener, CoroutineScope, DaxDialogListener {
138+ class BrowserTabFragment : Fragment (), FindListener, CoroutineScope, DaxDialogListener, TrackersAnimatorListener {
140139
141140 private val supervisorJob = SupervisorJob ()
142141
@@ -300,6 +299,8 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
300299
301300 decorateWithFeatures()
302301
302+ animatorHelper.setListener(this )
303+
303304 if (savedInstanceState == null ) {
304305 viewModel.onViewReady()
305306 messageFromPreviousTab?.let {
@@ -432,6 +433,10 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
432433 it.let { viewModel.onSurveyChanged(it) }
433434 })
434435
436+ viewModel.privacyGradeViewState.observe(viewLifecycleOwner, Observer {
437+ it.let { renderer.renderPrivacyGrade(it) }
438+ })
439+
435440 addTabsObserver()
436441 }
437442
@@ -488,7 +493,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
488493
489494 private fun processCommand (it : Command ? ) {
490495 if (it !is Command .DaxCommand ) {
491- renderer.cancelAllAnimations ()
496+ renderer.cancelTrackersAnimation ()
492497 }
493498 when (it) {
494499 is Command .Refresh -> refresh()
@@ -740,15 +745,6 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
740745 toolbar.privacyGradeButton.setOnClickListener {
741746 browserActivity?.launchPrivacyDashboard()
742747 }
743-
744- viewModel.privacyGrade.observe(viewLifecycleOwner, Observer <PrivacyGrade > {
745- Timber .d(" Observed grade: $it " )
746- it?.let { privacyGrade ->
747- val drawable = context?.getDrawable(privacyGrade.icon()) ? : return @let
748- privacyGradeButton?.setImageDrawable(drawable)
749- privacyGradeButton?.isEnabled = privacyGrade != PrivacyGrade .UNKNOWN
750- }
751- })
752748 }
753749
754750 private fun configureFindInPage () {
@@ -1044,6 +1040,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
10441040 }
10451041
10461042 override fun onDestroy () {
1043+ animatorHelper.removeListener()
10471044 supervisorJob.cancel()
10481045 popupMenu.dismiss()
10491046 destroyWebView()
@@ -1183,7 +1180,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
11831180 }
11841181
11851182 private fun finishTrackerAnimation () {
1186- animatorHelper.finishTrackerAnimation(omnibarViews(), networksContainer )
1183+ animatorHelper.finishTrackerAnimation(omnibarViews(), animationContainer )
11871184 }
11881185
11891186 private fun showHideTipsDialog (cta : Cta ) {
@@ -1220,7 +1217,11 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
12201217 .show()
12211218 }
12221219
1223- fun omnibarViews (): List <View > = listOf (clearTextButton, omnibarTextInput, privacyGradeButton, searchIcon)
1220+ fun omnibarViews (): List <View > = listOf (clearTextButton, omnibarTextInput, searchIcon)
1221+
1222+ override fun onAnimationFinished () {
1223+ viewModel.stopShowingEmptyGrade()
1224+ }
12241225
12251226 companion object {
12261227 private const val TAB_ID_ARG = " TAB_ID_ARG"
@@ -1495,6 +1496,40 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
14951496 private var lastSeenGlobalViewState: GlobalLayoutViewState ? = null
14961497 private var lastSeenAutoCompleteViewState: AutoCompleteViewState ? = null
14971498 private var lastSeenCtaViewState: CtaViewState ? = null
1499+ private var lastSeenPrivacyGradeViewState: PrivacyGradeViewState ? = null
1500+
1501+ fun renderPrivacyGrade (viewState : PrivacyGradeViewState ) {
1502+
1503+ renderIfChanged(viewState, lastSeenPrivacyGradeViewState) {
1504+
1505+ val oldGrade = lastSeenPrivacyGradeViewState?.privacyGrade
1506+ val oldShowEmptyGrade = lastSeenPrivacyGradeViewState?.showEmptyGrade
1507+ val grade = viewState.privacyGrade
1508+ val newShowEmptyGrade = viewState.showEmptyGrade
1509+
1510+ val canChangeGrade = (oldGrade != grade && ! newShowEmptyGrade) || (oldGrade == grade && oldShowEmptyGrade != newShowEmptyGrade)
1511+ lastSeenPrivacyGradeViewState = viewState
1512+
1513+ if (canChangeGrade) {
1514+ context?.let {
1515+ val drawable = if (viewState.showEmptyGrade) {
1516+ ContextCompat .getDrawable(it, R .drawable.privacygrade_icon_loading)
1517+ } else {
1518+ ContextCompat .getDrawable(it, viewState.privacyGrade.icon())
1519+ }
1520+ privacyGradeButton?.setImageDrawable(drawable)
1521+ }
1522+ }
1523+
1524+ privacyGradeButton?.isEnabled = viewState.isEnabled
1525+
1526+ if (viewState.shouldAnimate) {
1527+ animatorHelper.startPulseAnimation(privacyGradeButton)
1528+ } else {
1529+ animatorHelper.stopPulseAnimation()
1530+ }
1531+ }
1532+ }
14981533
14991534 fun renderAutocomplete (viewState : AutoCompleteViewState ) {
15001535 renderIfChanged(viewState, lastSeenAutoCompleteViewState) {
@@ -1514,7 +1549,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
15141549 lastSeenOmnibarViewState = viewState
15151550
15161551 if (viewState.isEditing) {
1517- cancelAllAnimations ()
1552+ cancelTrackersAnimation ()
15181553 }
15191554
15201555 if (shouldUpdateOmnibarTextInput(viewState, viewState.omnibarText)) {
@@ -1558,7 +1593,7 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
15581593
15591594 if (viewState.privacyOn) {
15601595 if (lastSeenOmnibarViewState?.isEditing == true ) {
1561- cancelAllAnimations ()
1596+ cancelTrackersAnimation ()
15621597 }
15631598
15641599 if (viewState.progress == MAX_PROGRESS ) {
@@ -1578,23 +1613,14 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
15781613 val events = site?.orderedTrackingEntities()
15791614
15801615 activity?.let { activity ->
1581- animatorHelper.startTrackersAnimation(
1582- lastSeenCtaViewState?.cta,
1583- activity,
1584- networksContainer,
1585- omnibarViews(),
1586- events
1587- )
1616+ animatorHelper.startTrackersAnimation(lastSeenCtaViewState?.cta, activity, animationContainer, omnibarViews(), events)
15881617 }
15891618 }
15901619 }
15911620 }
15921621
1593- fun cancelAllAnimations () {
1594- animatorHelper.cancelAnimations()
1595- networksContainer.alpha = 0f
1596- clearTextButton.alpha = 1f
1597- omnibarTextInput.alpha = 1f
1622+ fun cancelTrackersAnimation () {
1623+ animatorHelper.cancelAnimations(omnibarViews(), animationContainer)
15981624 }
15991625
16001626 fun renderGlobalViewState (viewState : GlobalLayoutViewState ) {
0 commit comments