diff --git a/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayout.kt b/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayout.kt index ac45bf4079e0..cc6a082871b4 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayout.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/omnibar/OmnibarLayout.kt @@ -586,6 +586,12 @@ class OmnibarLayout @JvmOverloads constructor( duckAISidebar.setOnClickListener { omnibarItemPressedListener?.onDuckAISidebarButtonPressed() } + newCustomTabToolbarContainer.customTabInnerContainer.setOnClickListener { + cancelCustomTabAnimations() + } + trackersAnimation.setOnClickListener { + cancelAddressBarAnimations() + } } override fun setLogoClickListener(logoClickListener: LogoClickListener) { @@ -1038,6 +1044,12 @@ class OmnibarLayout @JvmOverloads constructor( } } + private fun cancelCustomTabAnimations() { + if (this::animatorHelper.isInitialized) { + animatorHelper.cancelAnimations(customTabViews()) + } + } + private fun startTrackersAnimation(events: List?, isCustomTab: Boolean) { if (!isCustomTab) { if (addressBarTrackersAnimationFeatureToggle.feature().isEnabled()) { diff --git a/app/src/main/java/com/duckduckgo/app/browser/omnibar/animations/addressbar/BrowserLottieTrackersAnimatorHelper.kt b/app/src/main/java/com/duckduckgo/app/browser/omnibar/animations/addressbar/BrowserLottieTrackersAnimatorHelper.kt index 7ea690e4d1ca..72ceaf50b626 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/omnibar/animations/addressbar/BrowserLottieTrackersAnimatorHelper.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/omnibar/animations/addressbar/BrowserLottieTrackersAnimatorHelper.kt @@ -62,6 +62,7 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( private lateinit var cookieScene: ViewGroup private lateinit var cookieViewBackground: View private var cookieCosmeticHide: Boolean = false + private var currentShieldViews: List = emptyList() private var enqueueCookiesAnimation = false private var isCookiesAnimationRunning = false @@ -69,6 +70,7 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( private val conflatedJob = ConflatedJob() private val coroutineScope = CoroutineScope(SupervisorJob() + dispatcherProvider.main()) + private val runningCookieAnimators = mutableListOf() lateinit var firstScene: Scene lateinit var secondScene: Scene @@ -146,6 +148,8 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( ) { if (isCookiesAnimationRunning || addressBarTrackersAnimator.isAnimationRunning) return + currentShieldViews = shieldViews + addressBarTrackersAnimator.startAnimation( context = context, sceneRoot = sceneRoot, @@ -163,6 +167,9 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( } }, ) + sceneRoot.setOnClickListener { + cancelAnimations(omnibarViews, shieldViews) + } } override fun createCookiesAnimation( @@ -199,12 +206,15 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( override fun cancelAnimations( omnibarViews: List, + shieldViews: List, ) { conflatedJob.cancel() addressBarTrackersAnimator.cancelAnimation() stopTrackersAnimation() stopCookiesAnimation() + enqueueCookiesAnimation = false omnibarViews.forEach { it.alpha = 1f } + shieldViews.forEach { it.alpha = 1f } } private fun tryToStartCookiesAnimation( @@ -222,6 +232,11 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( omnibarViews: List, ) { if (omnibarViews.any { it.id == R.id.customTabDomain }) return // Do not show cookies animation in custom tabs + + // Cancel any running animators before starting new ones + runningCookieAnimators.forEach { it.cancel() } + runningCookieAnimators.clear() + isCookiesAnimationRunning = true if (cookieCosmeticHide) { @@ -233,7 +248,7 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( } hasCookiesAnimationBeenCanceled = false - val allOmnibarViews: List = (omnibarViews).filterNotNull().toList() + val allOmnibarViews: List = omnibarViews cookieView.show() cookieView.alpha = 0F if (theme.isLightModeEnabled()) { @@ -272,6 +287,7 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( listener?.onAnimationFinished() }, ) + runningCookieAnimators.add(this) start() } } else { @@ -280,6 +296,7 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( } }, ) + runningCookieAnimators.add(this) start() } } @@ -298,6 +315,7 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( if (!hasCookiesAnimationBeenCanceled) { AnimatorSet().apply { play(commonAddressBarAnimationHelper.animateViewsIn(allOmnibarViews)) + runningCookieAnimators.add(this) start() } cookieScene.gone() @@ -339,6 +357,7 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( cookieView.playAnimation() }, ) + runningCookieAnimators.add(this) start() } } @@ -408,13 +427,36 @@ class BrowserLottieTrackersAnimatorHelper @Inject constructor( private fun stopCookiesAnimation() { if (!::cookieViewBackground.isInitialized || !::cookieView.isInitialized) return - hasCookiesAnimationBeenCanceled = true - if (this::firstScene.isInitialized) { - TransitionManager.go(firstScene) + // Always cancel any pending animators and transitions to prevent glimpses + runningCookieAnimators.forEach { animator -> + animator.cancel() + animator.removeAllListeners() } + runningCookieAnimators.clear() + + // Cancel cookie view animations + cookieView.cancelAnimation() + cookieView.removeAllAnimatorListeners() + + // End any ongoing transitions without triggering new ones + if (::cookieScene.isInitialized) { + TransitionManager.endTransitions(cookieScene) + cookieScene.gone() + } + + // If animation was already stopped by user, skip redundant state updates + if (userHasCanceledCookieAnimation && !isCookiesAnimationRunning) { + return + } + + hasCookiesAnimationBeenCanceled = true + isCookiesAnimationRunning = false + + // Reset view states directly without triggering transitions shieldAnimation?.alpha = 1f + currentShieldViews.forEach { it.alpha = 1f } cookieViewBackground.alpha = 0f - cookieScene.gone() + cookieView.alpha = 0f cookieView.gone() } diff --git a/app/src/main/java/com/duckduckgo/app/browser/omnibar/animations/addressbar/BrowserTrackersAnimatorHelper.kt b/app/src/main/java/com/duckduckgo/app/browser/omnibar/animations/addressbar/BrowserTrackersAnimatorHelper.kt index 5bcb3d644473..62197e82d93e 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/omnibar/animations/addressbar/BrowserTrackersAnimatorHelper.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/omnibar/animations/addressbar/BrowserTrackersAnimatorHelper.kt @@ -92,9 +92,11 @@ interface BrowserTrackersAnimatorHelper { * Cancel a running animation. * * @param omnibarViews are the views that should become visible after canceling the running animation. + * @param shieldViews are the shield views that should become visible after canceling the running animation. */ fun cancelAnimations( omnibarViews: List, + shieldViews: List = emptyList(), ) /**