Skip to content

Conversation

@mikescamell
Copy link
Contributor

@mikescamell mikescamell commented Jan 12, 2026

Task/Issue URL: https://app.asana.com/1/137249556945/project/1207908166761516/task/1212553599261552?focus=true

Description

This PR adds the ability for users to set a SERP Easter Egg logo as their favourite, which will then display on all DuckDuckGo search result pages.

Features implemented:

  1. Feature toggle - Added remote feature toggle (serpEasterEggLogos.setFavourite) to control the favourite logo functionality
  2. Favourite logo data store - Added FavouriteSerpLogoDataStore to persist the user's favourite logo URL preference
  3. Discovery screen enhancements - Updated the Easter Egg logo screen to:
    - Display a title telling the user they've discovered an Easter Egg logo
    - Added a button to set/unset the logo as favourite
  4. Wiggle animation - Easter Egg logos now play a subtle wiggle animation when displayed in the omnibar:
    - Only plays once per unique logo URL
    - Skips animation for favourite logos
    - Waits for image crossfade to complete before animating
  5. State management fixes - Fixed race conditions that could cause Easter Egg logos to be lost:
    - Preserve existing Easter Egg when onViewModeChanged is called
    - Distinguish between SerpLogo.Normal (explicitly no Easter Egg) and null (pending state)
    - Reset to Dax logo when favourite preference changes

Steps to test this PR

Easter Egg Discovery

  • Search for a term that triggers an Easter Egg logo (e.g., "Southampton FC", "f1", "predator")
  • Verify the Easter Egg logo appears in the omnibar with a wiggle animation
  • Tap on the logo to open the enlarged view
  • Verify the discovery text "You found a hidden logo!" is displayed at the top
  • Verify the "Switch to This Logo" button is visible
  • Tap anywhere outside to dismiss the view
  • Search for another easter egg e.g. "hydra" and anticipate the wiggle animation
  • As the wiggle animation plays click the logo
  • The easter egg logo enlarged view should open and the logo should transition with no glitches
  • Tap anywhere outside to dismiss the view
  • The easter egg logo enlarged view should should transition back to the address with no glitches

Setting a Favourite Logo

  • Tap on the logo to open the enlarged view
  • Open the Easter Egg logo screen
  • Tap "Switch to This Logo"
  • Tap anywhere outside to dismiss the view
  • Search for something that does not have an easter egg logo e.g. "fpl"
  • Verify the favourite logo persists in the omnibar
  • Search for a term that triggers an Easter Egg logo (e.g., "Southampton FC", "f1", "predator") but is not your current favourite logo
  • Verify the favourite logo persists in the omnibar
  • Search for the same term for your favourite logo
  • Verify the logo no longer plays the wiggle animation (since it's now a favourite)

Resetting to Default

  • With a favourite logo set, tap on the logo
  • Verify the button now shows "Reset to Default"
  • Tap "Reset Search Logo"
  • Dismiss the easter egg logo screen
  • Verify the DDG logo is visible
  • Search for something that does not have an easter egg logo e.g. "fpl"
  • Verify the DDG logo is still visible
  • Search for a term that triggers an Easter Egg logo (e.g., "Southampton FC", "f1", "predator")
  • Verify the Easter Egg logo appears in the omnibar with a wiggle animation

Flag off

Index: serp-logos/serp-logos-api/src/main/kotlin/com/duckduckgo/serp/logos/api/SerpEasterEggLogosToggles.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/serp-logos/serp-logos-api/src/main/kotlin/com/duckduckgo/serp/logos/api/SerpEasterEggLogosToggles.kt b/serp-logos/serp-logos-api/src/main/kotlin/com/duckduckgo/serp/logos/api/SerpEasterEggLogosToggles.kt
--- a/serp-logos/serp-logos-api/src/main/kotlin/com/duckduckgo/serp/logos/api/SerpEasterEggLogosToggles.kt	(revision 2a9b098666ba9cd103cbe20e24fa7ff018cf7168)
+++ b/serp-logos/serp-logos-api/src/main/kotlin/com/duckduckgo/serp/logos/api/SerpEasterEggLogosToggles.kt	(date 1769694204288)
@@ -24,6 +24,6 @@
   @Toggle.DefaultValue(DefaultFeatureValue.FALSE)
   fun self(): Toggle

-    @Toggle.DefaultValue(DefaultFeatureValue.TRUE)
+    @Toggle.DefaultValue(DefaultFeatureValue.FALSE)
   fun setFavourite(): Toggle
}

  • Set the logo you just searched for as a favourite
  • Apply the patch above
  • Install the app
  • You should see the logo you set as favourite if you did not navigate away before re-installation
  • Search for a term that triggers an Easter Egg logo (e.g., "Southampton FC", "f1", "predator")
  • The new easter egg logo should show and should not be your favourite (flag off means no favourite so user's don't get stuck with it if we need to turn off the flag)
  • Tap the EasterEgg logo
  • The Easter Egg Logo screen should open
  • Verify the discovery text "You found a hidden logo!" is displayed
  • Verify the "Switch to This Logo" button is not visible
  • Dismiss the easter egg logo screen
  • Search for something that does not have an easter egg logo e.g. "fpl"
  • The DDG logo should show
  • Navigate to a website e.g. ign.com
  • The green shield should be visible
  • General smoke test, do searches in SERP with easter eggs, do non easter egg searches, navigate away to websites.
  • Favourite logo set before turning the flag off does not show

UI changes

Before After
before-light-mode after-light-mode
before-dark-mode after-dark-mode

Note

Medium Risk
Moderate risk: adds new persisted preference (DataStore), new UI state/animation paths, and changes SERP logo selection logic in BrowserTabViewModel/omnibar rendering, which could cause regressions in address-bar icon state or transitions.

Overview
Adds a new “favourite SERP Easter Egg logo” capability: users can set/unset a discovered Easter Egg logo, persist the chosen logo URL via a new DataStore, and have that logo override normal SERP logo extraction on DuckDuckGo search result pages when the serpEasterEggLogos.setFavourite toggle is enabled.

Updates the Easter Egg logo discovery screen to show discovery text and a favourite toggle button, introduces a one-time “wiggle” animation for non-favourite Easter Egg logos in the omnibar, and adds explicit cancellation of the logo animation when launching the logo screen to avoid transition glitches. Tests are expanded across BrowserTabViewModel, OmnibarLayoutViewModel, and serp-logos to cover toggle/favourite interactions and state preservation.

Written by Cursor Bugbot for commit b0e3498. This will update automatically on new commits. Configure here.

@mikescamell mikescamell changed the title Feature/mike/allow setting of favourite serp easter egg logo Allow setting of favourite serp easter egg logo Jan 12, 2026
@mikescamell mikescamell force-pushed the feature/mike/allow-setting-of-favourite-serp-easter-egg-logo branch 2 times, most recently from 19e36d2 to 3b8dd59 Compare January 13, 2026 17:48
@mikescamell mikescamell force-pushed the feature/mike/allow-setting-of-favourite-serp-easter-egg-logo branch 6 times, most recently from 7362335 to b763bc4 Compare February 2, 2026 09:02
@mikescamell mikescamell marked this pull request as ready for review February 2, 2026 09:46
@anikiki anikiki self-requested a review February 2, 2026 10:19
@mikescamell mikescamell force-pushed the feature/mike/allow-setting-of-favourite-serp-easter-egg-logo branch from b763bc4 to bff3474 Compare February 2, 2026 15:32
@mikescamell mikescamell force-pushed the feature/mike/allow-setting-of-favourite-serp-easter-egg-logo branch from bff3474 to cf15f2f Compare February 2, 2026 16:04
@mikescamell mikescamell force-pushed the feature/mike/allow-setting-of-favourite-serp-easter-egg-logo branch from cae2868 to 20a6686 Compare February 2, 2026 16:31
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

We now include a title to tell the user they have discovered an easter egg logo and allow them to set the logo as their favourite via the newly added button on screen.
When an Easter Egg logo is displayed in the omnibar (from a special
search like "f1"), it now plays a subtle wiggle animation once
the image loads. The animation:

- Only plays once per unique logo URL (prevents re-triggering on
  ViewState updates)
- Skips animation for favourite logos (set by user preference)

We also need to make sure we cancel the wobble animation before the shared element transition otherwise it becomes glitchy.
When a SERP page loads with an Easter Egg logo, two events occur
in non-deterministic order: onViewModeChanged and
onExternalOmnibarStateChanged. If onViewModeChanged was called
after the Easter Egg was already set, it would overwrite the
leadingIconState with Dax because it always passed logoUrl = null.

This fix preserves the existing Easter Egg URL in onViewModeChanged
by extracting it from the current state before updating, following
the same pattern already used in onExternalLoadingStateChanged.
When navigating between searches, onExternalOmnibarStateChanged may be
called with serpLogo = null before the new logo extraction completes.
Previously this would clear the existing Easter Egg logo, causing Dax
to briefly flash or persist if timing was unfavorable.

Now we distinguish between:
- SerpLogo.Normal: Explicitly no Easter Egg, clear and show Dax
- null: Unknown/pending state, preserve existing Easter Egg if present

This prevents the logo from being lost during navigation between
Easter Egg searches.
No need to extract an existing logo if we have a favourite set. Also prevents getting into any weird state.
…te button clicked

Matches iOS and request from Ship Review
… on SERP page in BrowserTabViewModel

Moves the logic to ensure we set a Favourite EasterEgg logo to the BrowserTabViewModel. This makes the OmnibarViewModel dumber like before adding the favourite feature, leaving responsibility to the caller (BrowserTab) to decide what should be shown.

Add flow observer that combines favourite toggle state and favourite URL
to reactively update the serpLogo when:
- Favourite logo is set: Show the favourite Easter egg logo
- Favourite logo is cleared: Show Dax (Normal logo)
- Feature is disabled: Let normal extraction handle it

Only reacts when on a SERP page to avoid unnecessary updates on other pages.
When a favourite SERP logo is cleared while on a SERP page, the
omnibarViewState.serpLogo should update from EasterEgg to Normal,
but currently it stays stale.

This test verifies the expected behavior and will pass once a flow
observer is added to BrowserTabViewModel to react to favourite logo
changes
@mikescamell mikescamell force-pushed the feature/mike/allow-setting-of-favourite-serp-easter-egg-logo branch from 500da4f to b0e3498 Compare February 4, 2026 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants