From 91a1d4d2ca88e06789c0f7845adf6262eb8f755a Mon Sep 17 00:00:00 2001 From: "mr. m" <91018726+mr-cheffy@users.noreply.github.com> Date: Thu, 20 Aug 2026 21:38:09 +0200 Subject: [PATCH] gh-14470: Run sweep animation on first sync (gh-15036) --- src/zen/common/modules/ZenStartup.mjs | 9 +++++++++ src/zen/common/modules/ZenUpdates.mjs | 8 ++++++++ src/zen/sync/ZenSpacesSyncApplier.sys.mjs | 17 +++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/zen/common/modules/ZenStartup.mjs b/src/zen/common/modules/ZenStartup.mjs index a1683d6ad..5766774df 100644 --- a/src/zen/common/modules/ZenStartup.mjs +++ b/src/zen/common/modules/ZenStartup.mjs @@ -4,6 +4,7 @@ import checkForZenUpdates, { createWindowUpdateAnimation, + playWindowSweepAnimation, } from "chrome://browser/content/ZenUpdates.mjs"; class ZenStartup { @@ -195,6 +196,14 @@ class ZenStartup { checkForZenUpdates(); return await createWindowUpdateAnimation(); } + + /** + * Entry point for privileged modules (e.g. the sync applier) to play the + * update sweep animation in this window. + */ + playWindowSweepAnimation() { + return playWindowSweepAnimation(); + } } window.gZenStartup = new ZenStartup(); diff --git a/src/zen/common/modules/ZenUpdates.mjs b/src/zen/common/modules/ZenUpdates.mjs index f0631e022..94599bdee 100644 --- a/src/zen/common/modules/ZenUpdates.mjs +++ b/src/zen/common/modules/ZenUpdates.mjs @@ -61,6 +61,14 @@ export async function createWindowUpdateAnimation() { return; } Services.prefs.setStringPref(ZEN_BUILD_ID_PREF, appID); + await playWindowSweepAnimation(); +} + +/** + * Plays the full-window sweep shown after updates. Also used the first + * time incoming sync data is applied on this profile. + */ +export async function playWindowSweepAnimation() { await gZenWorkspaces.promiseInitialized; const appWrapper = document.getElementById("zen-main-app-wrapper"); const element = document.createElement("div"); diff --git a/src/zen/sync/ZenSpacesSyncApplier.sys.mjs b/src/zen/sync/ZenSpacesSyncApplier.sys.mjs index 398df24c2..555abd2ce 100644 --- a/src/zen/sync/ZenSpacesSyncApplier.sys.mjs +++ b/src/zen/sync/ZenSpacesSyncApplier.sys.mjs @@ -22,6 +22,8 @@ ChromeUtils.defineESModuleGetters(lazy, { "moz-src:///toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs", }); +const FIRST_SYNC_ANIMATION_PREF = "zen.spaces-sync.first-sync-animation-shown"; + /** * Applies batches of incoming Spaces records to the local browser. */ @@ -112,6 +114,7 @@ class nsZenSpacesSyncApplier { } } else { await win.gZenWorkspaces.promiseInitialized; + this.#maybePlayFirstSyncAnimation(win); const removals = this.#routeTombstones(win, deletions); this.#deleteTabs(win, removals.tabs, fail); this.#deleteSplits(win, removals.splits, fail); @@ -141,6 +144,20 @@ class nsZenSpacesSyncApplier { return [...failed]; } + /** + * Plays the update sweep animation over the window the first time + * incoming sync data lands on this profile. + * + * @param {Window} win + */ + #maybePlayFirstSyncAnimation(win) { + if (Services.prefs.getBoolPref(FIRST_SYNC_ANIMATION_PREF, false)) { + return; + } + Services.prefs.setBoolPref(FIRST_SYNC_ANIMATION_PREF, true); + win.gZenStartup.playWindowSweepAnimation(); + } + /** * Tombstones have no payload. Whatever local thing owns the id decides * what kind of deletion this is. Ids with no local counterpart need no