@designcrowd/library.brand-page 5.17.25-undo-12 → 5.17.25-undo-14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/src/{CreatedOnBrandCrowd-de-de-4mxqeHPP.js → CreatedOnBrandCrowd-de-de-D0AQ4h1Y.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-DQN_hGjC.js → CreatedOnBrandCrowd-en-us-Bz9D9FcQ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-gijtJMPK.js → CreatedOnBrandCrowd-es-es-B6EKNEDx.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-BcOADD0V.js → CreatedOnBrandCrowd-fr-ca-DvC5JIAW.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-BcOADD0V.js → CreatedOnBrandCrowd-fr-fr-DvC5JIAW.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-B5eEyjAo.js → CreatedOnBrandCrowd-pt-br-tckhI2rl.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-B5eEyjAo.js → CreatedOnBrandCrowd-pt-pt-tckhI2rl.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-DSGP6AAT.js → CreatedOnDcom-de-de-BJAmW8nU.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-BOuoJM_x.js → CreatedOnDcom-en-us-0IxL5rtr.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-kbiGFyBV.js → CreatedOnDcom-es-es-j1tEaAuh.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-BVFxrE6-.js → CreatedOnDcom-fr-ca-BHD4nfCD.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-92xJGi0w.js → CreatedOnDcom-fr-fr-D4b447yE.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-C40X9FAV.js → CreatedOnDcom-pt-br-6WIaKLxK.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-CXxJUTUx.js → CreatedOnDcom-pt-pt-DSvzJLxn.js} +1 -1
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +22 -8
- package/lib/src/brand-page-maker/stores/history/history-store.d.ts +6 -0
- package/lib/src/brand-page-maker/stores/history/history-store.js +10 -9
- package/lib/src/brand-page-maker/stores/logo-store/logo-store.d.ts +1 -0
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-DaFVTyb9.js → lib-3NPiNYNp.js} +27 -17
- package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +2 -0
- package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +2 -0
- package/lib/src/shared/logo-settings/store/editable-logo-store.d.ts +9 -1
- package/lib/src/shared/logo-settings/store/editable-logo-store.js +33 -0
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +2 -0
- package/package.json +1 -1
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +26 -10
- package/src/brand-page-maker/stores/history/history-store.test.ts +5 -5
- package/src/brand-page-maker/stores/history/history-store.ts +16 -10
- package/src/brand-page-maker/stores/logo-store/logo-store.ts +5 -0
- package/src/shared/logo-settings/store/editable-logo-store.ts +45 -1
|
@@ -567,6 +567,9 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
|
|
|
567
567
|
// restored header logo. The preview rehydrates via the page contents,
|
|
568
568
|
// but `uiLogoSettings` holds its own copy that drives the sidebar
|
|
569
569
|
// "current logo" state — same pattern as `initialiseStoresByBrandPageModelAsync`.
|
|
570
|
+
// Also restores the variations grid + template asset for the
|
|
571
|
+
// snapshot's draft token (both are sidecars to `brandPageData` —
|
|
572
|
+
// BYO upload mutates them out of band).
|
|
570
573
|
this._syncLogoSettingsFromSnapshot(snapshot);
|
|
571
574
|
// 9. If the sidebar is editing a content item that no longer exists in
|
|
572
575
|
// the restored page, fall back to the Content tab so the user doesn't
|
|
@@ -585,15 +588,26 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
|
|
|
585
588
|
logoSettingsStore.setState({
|
|
586
589
|
newState: { selectedLogoImage: logoImage },
|
|
587
590
|
});
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
//
|
|
592
|
-
//
|
|
593
|
-
//
|
|
594
|
-
|
|
595
|
-
|
|
591
|
+
const draftToken = logoImage.logoDraftToken;
|
|
592
|
+
if (!draftToken)
|
|
593
|
+
return;
|
|
594
|
+
// Re-derive `enableEditMode` and the active template asset from the
|
|
595
|
+
// logo-store's draft registry. Drafts are append-only for the session,
|
|
596
|
+
// and BYO upload stamps `templateAsset` onto the registered draft when
|
|
597
|
+
// it lands — so the registered draft is enough to fully restore the
|
|
598
|
+
// sidebar's design/upload chooser without storing anything inside
|
|
599
|
+
// each history entry. The variations grid is restored from the
|
|
600
|
+
// editable-logo store's per-token cache (populated by every
|
|
601
|
+
// `updateEditableLogoImageUrlAsync` render).
|
|
602
|
+
const draft = logoStore.getLogoDraftAssetByToken(draftToken);
|
|
603
|
+
if (draft) {
|
|
596
604
|
editableLogoStore.setEnableEditMode(!draft.isByo);
|
|
605
|
+
if (draft.templateAsset) {
|
|
606
|
+
logoStore.setLogoTemplateAsset(draft.templateAsset);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
editableLogoStore.setLogoDraftToken(draftToken);
|
|
610
|
+
editableLogoStore.restoreVariationsForDraftToken(draftToken);
|
|
597
611
|
},
|
|
598
612
|
_fallbackSidebarIfSelectedContentMissing(snapshot) {
|
|
599
613
|
const contentSettingsStore = useUiContentSettingsStore();
|
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
* with the live store.
|
|
9
9
|
* 2. `sizeBytes === snapshot.length` is automatic and accurate for the V2
|
|
10
10
|
* memory-budget instrumentation.
|
|
11
|
+
*
|
|
12
|
+
* Sidecar state that doesn't live on `brandPageData` (the variations grid in
|
|
13
|
+
* the Logo sidebar, the active `logoTemplateAsset`, the active
|
|
14
|
+
* `logoDraftToken`) is restored on undo by `_syncLogoSettingsFromSnapshot`
|
|
15
|
+
* via per-draft-token caches on the logo / editable-logo stores — keyed off
|
|
16
|
+
* `logoImage.logoDraftToken` which IS in the snapshot.
|
|
11
17
|
*/
|
|
12
18
|
export interface HistoryEntry {
|
|
13
19
|
/** JSON.stringify(BrandPageModel) at the moment of capture. */
|
|
@@ -32,8 +32,10 @@ const CAPTURE_MAX_WAIT_MS = 10000;
|
|
|
32
32
|
// FR-12: 40-entry cap. FR-13: 100 MB memory budget. FR-13c: per-entry
|
|
33
33
|
// oversize threshold — entries above this are skipped + emit telemetry.
|
|
34
34
|
// 25 MB accommodates a high-res BYO logo upload, which renders ~2.5 MB
|
|
35
|
-
// of base64 PNG into each of four viewport sections (~10 MB) plus
|
|
36
|
-
//
|
|
35
|
+
// of base64 PNG into each of four viewport sections (~10 MB) plus per-page
|
|
36
|
+
// logo content blocks. The variations grid (~10 MB) does NOT live in the
|
|
37
|
+
// snapshot — it sits on the editable-logo store keyed by draft token, and
|
|
38
|
+
// is restored on undo from there. The 100 MB total budget still evicts
|
|
37
39
|
// oldest non-baseline entries to keep memory bounded.
|
|
38
40
|
const MAX_ENTRIES = 40;
|
|
39
41
|
const MAX_MEMORY_BYTES = 100 * 1024 * 1024;
|
|
@@ -72,15 +74,14 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
72
74
|
* Synchronous — safe to call inside a microtask without racing a follow-up
|
|
73
75
|
* mutation.
|
|
74
76
|
*/
|
|
75
|
-
function
|
|
77
|
+
function serializeCurrentSnapshot() {
|
|
76
78
|
if (!cachedMakerStore)
|
|
77
79
|
return null;
|
|
78
80
|
try {
|
|
79
|
-
|
|
80
|
-
return JSON.stringify(raw);
|
|
81
|
+
return JSON.stringify(toRaw(cachedMakerStore.brandPageData));
|
|
81
82
|
}
|
|
82
83
|
catch (error) {
|
|
83
|
-
console.error('history-store: failed to serialize
|
|
84
|
+
console.error('history-store: failed to serialize snapshot', error);
|
|
84
85
|
return null;
|
|
85
86
|
}
|
|
86
87
|
}
|
|
@@ -519,7 +520,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
519
520
|
return;
|
|
520
521
|
if (!baselineCaptured.value)
|
|
521
522
|
return;
|
|
522
|
-
const snapshot =
|
|
523
|
+
const snapshot = serializeCurrentSnapshot();
|
|
523
524
|
if (!snapshot)
|
|
524
525
|
return;
|
|
525
526
|
// During the post-init settle window, fold any captured mutation back
|
|
@@ -571,7 +572,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
571
572
|
if (baselineCaptured.value)
|
|
572
573
|
return;
|
|
573
574
|
installWatcher();
|
|
574
|
-
const snapshot =
|
|
575
|
+
const snapshot = serializeCurrentSnapshot();
|
|
575
576
|
if (!snapshot)
|
|
576
577
|
return;
|
|
577
578
|
// Baseline starts a fresh stack of exactly 1 entry with pointer at 0.
|
|
@@ -601,7 +602,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
601
602
|
return 'skipped';
|
|
602
603
|
if (!baselineCaptured.value)
|
|
603
604
|
return 'skipped';
|
|
604
|
-
const snapshot =
|
|
605
|
+
const snapshot = serializeCurrentSnapshot();
|
|
605
606
|
if (!snapshot)
|
|
606
607
|
return 'skipped';
|
|
607
608
|
return commitEntry({ snapshot, ...args });
|
package/lib/src/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as E, a as T, b as s, c as I, d as S, e as N, f as e, B as A, g as O, h as C, i as G, j as D, k as P, l as t, m as R, n as L, o as M, p as o, q as r, r as b, s as n, t as F, u as i, v as l, w as g, x as B, y as c, z as Y, C as U, D as d, E as u, F as H, G as p, H as y, I as K, J as k, K as m, L as V, M as X, N as h, O as v, P as W, Q as f, R as x, S as z, T as w, U as Z, V as j, W as Q, X as q, Y as J, Z as $, $ as aa, a0 as _a, a1 as Ea, a2 as Ta, a3 as sa, a4 as Ia, a5 as Sa, a6 as Na, a7 as ea, a8 as Aa, a9 as Oa, aa as Ca, ab as Ga, ac as Da, ad as Pa, ae as ta, af as Ra, ag as La, ah as Ma, ai as oa, aj as ra, ak as ba, al as na, am as Fa, an as ia, ao as la, ap as ga, aq as Ba, ar as ca, as as Ya, at as Ua, au as da, av as ua, aw as Ha, ax as pa, ay as ya, az as Ka, aA as ka, aB as ma, aC as Va, aD as Xa, aE as ha, aF as va, aG as Wa, aH as fa, aI as xa, aJ as za, aK as wa, aL as Za, aM as ja, aN as Qa, aO as qa, aP as Ja, aQ as $a, aR as a_, aS as __, aT as E_, aU as T_, aV as s_, aW as I_, aX as S_, aY as N_, aZ as e_, a_ as A_, a$ as O_, b0 as C_, b1 as G_, b2 as D_, b3 as P_, b4 as t_, b5 as R_, b6 as L_, b7 as M_, b8 as o_, b9 as r_, ba as b_, bb as n_, bc as F_, bd as i_, be as l_, bf as g_, bg as B_, bh as c_, bi as Y_, bj as U_, bk as d_, bl as u_, bm as H_, bn as p_, bo as y_, bp as K_, bq as k_, br as m_, bs as V_, bt as X_, bu as h_, bv as v_, bw as W_, bx as f_, by as x_, bz as z_, bA as w_, bB as Z_, bC as j_, bD as Q_, bE as q_, bF as J_, bG as $_, bH as aE, bI as _E, bJ as EE, bK as TE, bL as sE, bM as IE, bN as SE, bO as NE, bP as eE, bQ as AE, bR as OE, bS as CE, bT as GE, bU as DE, bV as PE, bW as tE, bX as RE, bY as LE, bZ as ME, b_ as oE, b$ as rE, c0 as bE, c1 as nE, c2 as FE, c3 as iE, c4 as lE, c5 as gE, c6 as BE, c7 as cE, c8 as YE, c9 as UE, ca as dE, cb as uE, cc as HE, cd as pE, ce as yE, cf as KE, cg as kE, ch as mE, ci as VE, cj as XE, ck as hE, cl as vE, cm as WE, cn as fE, co as xE } from "./lib-
|
|
1
|
+
import { A as E, a as T, b as s, c as I, d as S, e as N, f as e, B as A, g as O, h as C, i as G, j as D, k as P, l as t, m as R, n as L, o as M, p as o, q as r, r as b, s as n, t as F, u as i, v as l, w as g, x as B, y as c, z as Y, C as U, D as d, E as u, F as H, G as p, H as y, I as K, J as k, K as m, L as V, M as X, N as h, O as v, P as W, Q as f, R as x, S as z, T as w, U as Z, V as j, W as Q, X as q, Y as J, Z as $, $ as aa, a0 as _a, a1 as Ea, a2 as Ta, a3 as sa, a4 as Ia, a5 as Sa, a6 as Na, a7 as ea, a8 as Aa, a9 as Oa, aa as Ca, ab as Ga, ac as Da, ad as Pa, ae as ta, af as Ra, ag as La, ah as Ma, ai as oa, aj as ra, ak as ba, al as na, am as Fa, an as ia, ao as la, ap as ga, aq as Ba, ar as ca, as as Ya, at as Ua, au as da, av as ua, aw as Ha, ax as pa, ay as ya, az as Ka, aA as ka, aB as ma, aC as Va, aD as Xa, aE as ha, aF as va, aG as Wa, aH as fa, aI as xa, aJ as za, aK as wa, aL as Za, aM as ja, aN as Qa, aO as qa, aP as Ja, aQ as $a, aR as a_, aS as __, aT as E_, aU as T_, aV as s_, aW as I_, aX as S_, aY as N_, aZ as e_, a_ as A_, a$ as O_, b0 as C_, b1 as G_, b2 as D_, b3 as P_, b4 as t_, b5 as R_, b6 as L_, b7 as M_, b8 as o_, b9 as r_, ba as b_, bb as n_, bc as F_, bd as i_, be as l_, bf as g_, bg as B_, bh as c_, bi as Y_, bj as U_, bk as d_, bl as u_, bm as H_, bn as p_, bo as y_, bp as K_, bq as k_, br as m_, bs as V_, bt as X_, bu as h_, bv as v_, bw as W_, bx as f_, by as x_, bz as z_, bA as w_, bB as Z_, bC as j_, bD as Q_, bE as q_, bF as J_, bG as $_, bH as aE, bI as _E, bJ as EE, bK as TE, bL as sE, bM as IE, bN as SE, bO as NE, bP as eE, bQ as AE, bR as OE, bS as CE, bT as GE, bU as DE, bV as PE, bW as tE, bX as RE, bY as LE, bZ as ME, b_ as oE, b$ as rE, c0 as bE, c1 as nE, c2 as FE, c3 as iE, c4 as lE, c5 as gE, c6 as BE, c7 as cE, c8 as YE, c9 as UE, ca as dE, cb as uE, cc as HE, cd as pE, ce as yE, cf as KE, cg as kE, ch as mE, ci as VE, cj as XE, ck as hE, cl as vE, cm as WE, cn as fE, co as xE } from "./lib-3NPiNYNp.js";
|
|
2
2
|
import { createPinia as wE, setActivePinia as ZE } from "pinia";
|
|
3
3
|
export {
|
|
4
4
|
E as ABOUT_SECTION_SETTINGS_CONFIG,
|
|
@@ -60964,10 +60964,9 @@ const Kn = /* @__PURE__ */ Z6(GB1), WB1 = (e, t, n) => {
|
|
|
60964
60964
|
function c() {
|
|
60965
60965
|
if (!d) return null;
|
|
60966
60966
|
try {
|
|
60967
|
-
|
|
60968
|
-
return JSON.stringify(U);
|
|
60967
|
+
return JSON.stringify(vD(d.brandPageData));
|
|
60969
60968
|
} catch (U) {
|
|
60970
|
-
return console.error("history-store: failed to serialize
|
|
60969
|
+
return console.error("history-store: failed to serialize snapshot", U), null;
|
|
60971
60970
|
}
|
|
60972
60971
|
}
|
|
60973
60972
|
const u = /* @__PURE__ */ new Set(["P", "SPAN", "MARK"]), p = /* @__PURE__ */ new Set(["STRONG", "EM", "U", "S"]), g = /* @__PURE__ */ new Set([
|
|
@@ -62190,10 +62189,10 @@ const Kn = /* @__PURE__ */ Z6(GB1), WB1 = (e, t, n) => {
|
|
|
62190
62189
|
R2(() => n.context.isDesignCom, async () => {
|
|
62191
62190
|
const M = P6().toLowerCase(), _ = n.context.isDesignCom ? "Dcom" : "BrandCrowd";
|
|
62192
62191
|
try {
|
|
62193
|
-
const { default: V } = await yk(/* @__PURE__ */ Object.assign({ "./watermark/CreatedOnBrandCrowd-de-de.vue": () => import("./CreatedOnBrandCrowd-de-de-
|
|
62192
|
+
const { default: V } = await yk(/* @__PURE__ */ Object.assign({ "./watermark/CreatedOnBrandCrowd-de-de.vue": () => import("./CreatedOnBrandCrowd-de-de-D0AQ4h1Y.js"), "./watermark/CreatedOnBrandCrowd-en-us.vue": () => import("./CreatedOnBrandCrowd-en-us-Bz9D9FcQ.js"), "./watermark/CreatedOnBrandCrowd-es-es.vue": () => import("./CreatedOnBrandCrowd-es-es-B6EKNEDx.js"), "./watermark/CreatedOnBrandCrowd-fr-ca.vue": () => import("./CreatedOnBrandCrowd-fr-ca-DvC5JIAW.js"), "./watermark/CreatedOnBrandCrowd-fr-fr.vue": () => import("./CreatedOnBrandCrowd-fr-fr-DvC5JIAW.js"), "./watermark/CreatedOnBrandCrowd-pt-br.vue": () => import("./CreatedOnBrandCrowd-pt-br-tckhI2rl.js"), "./watermark/CreatedOnBrandCrowd-pt-pt.vue": () => import("./CreatedOnBrandCrowd-pt-pt-tckhI2rl.js"), "./watermark/CreatedOnDcom-de-de.vue": () => import("./CreatedOnDcom-de-de-BJAmW8nU.js"), "./watermark/CreatedOnDcom-en-us.vue": () => import("./CreatedOnDcom-en-us-0IxL5rtr.js"), "./watermark/CreatedOnDcom-es-es.vue": () => import("./CreatedOnDcom-es-es-j1tEaAuh.js"), "./watermark/CreatedOnDcom-fr-ca.vue": () => import("./CreatedOnDcom-fr-ca-BHD4nfCD.js"), "./watermark/CreatedOnDcom-fr-fr.vue": () => import("./CreatedOnDcom-fr-fr-D4b447yE.js"), "./watermark/CreatedOnDcom-pt-br.vue": () => import("./CreatedOnDcom-pt-br-6WIaKLxK.js"), "./watermark/CreatedOnDcom-pt-pt.vue": () => import("./CreatedOnDcom-pt-pt-DSvzJLxn.js") }), `./watermark/CreatedOn${_}-${M}.vue`, 3);
|
|
62194
62193
|
i.value = V;
|
|
62195
62194
|
} catch {
|
|
62196
|
-
const { default: H } = await yk(/* @__PURE__ */ Object.assign({ "./watermark/CreatedOnBrandCrowd-en-us.vue": () => import("./CreatedOnBrandCrowd-en-us-
|
|
62195
|
+
const { default: H } = await yk(/* @__PURE__ */ Object.assign({ "./watermark/CreatedOnBrandCrowd-en-us.vue": () => import("./CreatedOnBrandCrowd-en-us-Bz9D9FcQ.js"), "./watermark/CreatedOnDcom-en-us.vue": () => import("./CreatedOnDcom-en-us-0IxL5rtr.js") }), `./watermark/CreatedOn${_}-en-us.vue`, 3);
|
|
62197
62196
|
i.value = H;
|
|
62198
62197
|
}
|
|
62199
62198
|
}, {
|
|
@@ -75717,7 +75716,8 @@ const _3 = ne("uiContentSettings", {
|
|
|
75717
75716
|
textObjects: []
|
|
75718
75717
|
},
|
|
75719
75718
|
makerFonts: [],
|
|
75720
|
-
isLogoDraftSaved: !1
|
|
75719
|
+
isLogoDraftSaved: !1,
|
|
75720
|
+
variationsByDraftToken: {}
|
|
75721
75721
|
}),
|
|
75722
75722
|
actions: {
|
|
75723
75723
|
async setStateAsync(e) {
|
|
@@ -75854,7 +75854,16 @@ const _3 = ne("uiContentSettings", {
|
|
|
75854
75854
|
a.logoImageBase64Url = this.getEditableLogoVariationByVariationId(l).base64;
|
|
75855
75855
|
}
|
|
75856
75856
|
});
|
|
75857
|
-
});
|
|
75857
|
+
}), this.logoDraftToken && (this.variationsByDraftToken[this.logoDraftToken] = this.editableLogoVariations.map((s) => ({ ...s })));
|
|
75858
|
+
},
|
|
75859
|
+
/**
|
|
75860
|
+
* Restore the variations grid for `logoDraftToken` from the per-token
|
|
75861
|
+
* cache. Called by `_syncLogoSettingsFromSnapshot` during undo/redo.
|
|
75862
|
+
* Returns true on cache hit.
|
|
75863
|
+
*/
|
|
75864
|
+
restoreVariationsForDraftToken(e) {
|
|
75865
|
+
const t = this.variationsByDraftToken[e];
|
|
75866
|
+
return t ? (this.editableLogoVariations = t.map((n) => ({ ...n })), !0) : !1;
|
|
75858
75867
|
},
|
|
75859
75868
|
async updateMetadataAsync(e, t = !1, n) {
|
|
75860
75869
|
const i = await this.postEditableLogoRequestAsync({
|
|
@@ -75881,12 +75890,13 @@ const _3 = ne("uiContentSettings", {
|
|
|
75881
75890
|
upsertDraftMetadata(e) {
|
|
75882
75891
|
var i;
|
|
75883
75892
|
const t = S4(), n = t.getLogoDraftAssetByToken(this.logoDraftToken);
|
|
75884
|
-
n ? n.metadata = e : t.addLogoDraftAsset({
|
|
75893
|
+
n ? (n.metadata = e, t.logoTemplateAsset && (n.templateAsset = { ...t.logoTemplateAsset })) : t.addLogoDraftAsset({
|
|
75885
75894
|
logoDraftAsset: {
|
|
75886
75895
|
token: this.logoDraftToken,
|
|
75887
75896
|
metadata: e,
|
|
75888
75897
|
tick: Date.now(),
|
|
75889
|
-
isByo: ((i = t.logoTemplateAsset) == null ? void 0 : i.isByo) || !1
|
|
75898
|
+
isByo: ((i = t.logoTemplateAsset) == null ? void 0 : i.isByo) || !1,
|
|
75899
|
+
templateAsset: t.logoTemplateAsset ? { ...t.logoTemplateAsset } : void 0
|
|
75890
75900
|
}
|
|
75891
75901
|
});
|
|
75892
75902
|
},
|
|
@@ -76622,18 +76632,18 @@ const _3 = ne("uiContentSettings", {
|
|
|
76622
76632
|
}), e.isModifiedAfterTemplateApplied !== void 0 && (this.isModifiedAfterTemplateApplied = e.isModifiedAfterTemplateApplied), e.brandPageType && this.setBrandPageType({ brandPageType: e.brandPageType }), this.faviconUrl = e.faviconUrl, this.ogImageUrl = e.ogImageUrl, this.measurementID = e.measurementID, this.adsenseID = e.adsenseID, this.ogTitle = e.ogTitle, this.ogDescription = e.ogDescription, this.cookieOptions = e.cookieOptions, this.saveContactSettings = e.saveContactSettings, this._syncLogoSettingsFromSnapshot(e), this._fallbackSidebarIfSelectedContentMissing(e);
|
|
76623
76633
|
},
|
|
76624
76634
|
_syncLogoSettingsFromSnapshot(e) {
|
|
76625
|
-
var
|
|
76626
|
-
const t = De(), n = K4(), i = S4(), o = e.brandPageType === d1.default ? (
|
|
76627
|
-
(
|
|
76628
|
-
)) == null ? void 0 :
|
|
76635
|
+
var a, l, d, c, u;
|
|
76636
|
+
const t = De(), n = K4(), i = S4(), o = e.brandPageType === d1.default ? (c = (d = (l = (a = e.pages) == null ? void 0 : a[0]) == null ? void 0 : l.contents) == null ? void 0 : d.find(
|
|
76637
|
+
(p) => p.type === "logo"
|
|
76638
|
+
)) == null ? void 0 : c.logoImage : (u = e.pageHeaderDesktop) == null ? void 0 : u.logoImage;
|
|
76629
76639
|
if (!o) return;
|
|
76630
76640
|
t.setState({
|
|
76631
76641
|
newState: { selectedLogoImage: o }
|
|
76632
76642
|
});
|
|
76633
|
-
const s =
|
|
76634
|
-
|
|
76635
|
-
);
|
|
76636
|
-
|
|
76643
|
+
const s = o.logoDraftToken;
|
|
76644
|
+
if (!s) return;
|
|
76645
|
+
const r = i.getLogoDraftAssetByToken(s);
|
|
76646
|
+
r && (n.setEnableEditMode(!r.isByo), r.templateAsset && i.setLogoTemplateAsset(r.templateAsset)), n.setLogoDraftToken(s), n.restoreVariationsForDraftToken(s);
|
|
76637
76647
|
},
|
|
76638
76648
|
_fallbackSidebarIfSelectedContentMissing(e) {
|
|
76639
76649
|
var s;
|
|
@@ -93,6 +93,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
93
93
|
logoTemplateMetadata: string;
|
|
94
94
|
isLogoDraftSaved: boolean;
|
|
95
95
|
isTextOnlyLogo: boolean;
|
|
96
|
+
variationsByDraftToken: Record<string, import("../store/editable-logo-store").EditableLogoVariation[]>;
|
|
96
97
|
} & import("pinia").PiniaCustomStateProperties<import("../store/editable-logo-store").EditableLogoState>) => () => string | undefined;
|
|
97
98
|
}, {
|
|
98
99
|
setStateAsync(payload: {
|
|
@@ -110,6 +111,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
110
111
|
getEditableLogoVariationByVariationId(id: number): any;
|
|
111
112
|
getEditableLogoVariationByBase64(base64: string): any;
|
|
112
113
|
updateEditableLogoImageUrlAsync(defaultPrimaryText?: string | undefined, overrideLogoVariation?: number | undefined, layout?: string | undefined): Promise<void>;
|
|
114
|
+
restoreVariationsForDraftToken(logoDraftToken: string): boolean;
|
|
113
115
|
updateMetadataAsync(defaultPrimaryText?: string | undefined, resetLogoTemplateMetadata?: boolean, layout?: string | undefined): Promise<void>;
|
|
114
116
|
updateEditableLogoImageByVariationAsync(editableLogoVariation: import("../store/editable-logo-store").EditableLogoVariation, defaultPrimaryText?: string | undefined, layout?: string | undefined): Promise<import("../../../clients/fabric-render-client").ModifyLogoDataResponse | null>;
|
|
115
117
|
getDraftMetadata(logoDraftToken: string): string | undefined;
|
|
@@ -281,6 +281,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
281
281
|
logoTemplateMetadata: string;
|
|
282
282
|
isLogoDraftSaved: boolean;
|
|
283
283
|
isTextOnlyLogo: boolean;
|
|
284
|
+
variationsByDraftToken: Record<string, import("../store").EditableLogoVariation[]>;
|
|
284
285
|
} & import("pinia").PiniaCustomStateProperties<import("../store").EditableLogoState>) => () => string | undefined;
|
|
285
286
|
}, {
|
|
286
287
|
setStateAsync(payload: {
|
|
@@ -298,6 +299,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
298
299
|
getEditableLogoVariationByVariationId(id: number): any;
|
|
299
300
|
getEditableLogoVariationByBase64(base64: string): any;
|
|
300
301
|
updateEditableLogoImageUrlAsync(defaultPrimaryText?: string | undefined, overrideLogoVariation?: number | undefined, layout?: string | undefined): Promise<void>;
|
|
302
|
+
restoreVariationsForDraftToken(logoDraftToken: string): boolean;
|
|
301
303
|
updateMetadataAsync(defaultPrimaryText?: string | undefined, resetLogoTemplateMetadata?: boolean, layout?: string | undefined): Promise<void>;
|
|
302
304
|
updateEditableLogoImageByVariationAsync(editableLogoVariation: import("../store").EditableLogoVariation, defaultPrimaryText?: string | undefined, layout?: string | undefined): Promise<import("../../../clients/fabric-render-client").ModifyLogoDataResponse | null>;
|
|
303
305
|
getDraftMetadata(logoDraftToken: string): string | undefined;
|
|
@@ -74,8 +74,9 @@ export interface EditableLogoState {
|
|
|
74
74
|
logoTemplateMetadata: string;
|
|
75
75
|
isLogoDraftSaved: boolean;
|
|
76
76
|
isTextOnlyLogo: boolean;
|
|
77
|
+
variationsByDraftToken: Record<string, EditableLogoVariation[]>;
|
|
77
78
|
}
|
|
78
|
-
export type SetStateAsyncPayload = Omit<EditableLogoState, 'enableEditMode' | 'editableLogoVariations'>;
|
|
79
|
+
export type SetStateAsyncPayload = Omit<EditableLogoState, 'enableEditMode' | 'editableLogoVariations' | 'variationsByDraftToken'>;
|
|
79
80
|
export declare const useUiEditableLogoStore: import("pinia").StoreDefinition<"uiEditableLogo", EditableLogoState, {
|
|
80
81
|
getLogoPrimaryText: (state: {
|
|
81
82
|
enableEditMode: boolean;
|
|
@@ -167,6 +168,7 @@ export declare const useUiEditableLogoStore: import("pinia").StoreDefinition<"ui
|
|
|
167
168
|
logoTemplateMetadata: string;
|
|
168
169
|
isLogoDraftSaved: boolean;
|
|
169
170
|
isTextOnlyLogo: boolean;
|
|
171
|
+
variationsByDraftToken: Record<string, EditableLogoVariation[]>;
|
|
170
172
|
} & import("pinia").PiniaCustomStateProperties<EditableLogoState>) => () => string | undefined;
|
|
171
173
|
}, {
|
|
172
174
|
setStateAsync(payload: {
|
|
@@ -184,6 +186,12 @@ export declare const useUiEditableLogoStore: import("pinia").StoreDefinition<"ui
|
|
|
184
186
|
getEditableLogoVariationByVariationId(id: number): any;
|
|
185
187
|
getEditableLogoVariationByBase64(base64: string): any;
|
|
186
188
|
updateEditableLogoImageUrlAsync(defaultPrimaryText?: string, overrideLogoVariation?: number | undefined, layout?: string): Promise<void>;
|
|
189
|
+
/**
|
|
190
|
+
* Restore the variations grid for `logoDraftToken` from the per-token
|
|
191
|
+
* cache. Called by `_syncLogoSettingsFromSnapshot` during undo/redo.
|
|
192
|
+
* Returns true on cache hit.
|
|
193
|
+
*/
|
|
194
|
+
restoreVariationsForDraftToken(logoDraftToken: string): boolean;
|
|
187
195
|
updateMetadataAsync(defaultPrimaryText?: string, resetLogoTemplateMetadata?: boolean, layout?: string): Promise<void>;
|
|
188
196
|
updateEditableLogoImageByVariationAsync(editableLogoVariation: EditableLogoVariation, defaultPrimaryText?: string, layout?: string): Promise<ModifyLogoDataResponse | null>;
|
|
189
197
|
getDraftMetadata(logoDraftToken: string): string | undefined;
|
|
@@ -74,6 +74,7 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
|
|
|
74
74
|
},
|
|
75
75
|
makerFonts: [],
|
|
76
76
|
isLogoDraftSaved: false,
|
|
77
|
+
variationsByDraftToken: {},
|
|
77
78
|
}),
|
|
78
79
|
actions: {
|
|
79
80
|
async setStateAsync(payload) {
|
|
@@ -242,6 +243,28 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
|
|
|
242
243
|
}
|
|
243
244
|
});
|
|
244
245
|
});
|
|
246
|
+
// Stash the freshly rendered variation set under the active draft
|
|
247
|
+
// token so undo can restore it later without re-rendering. This is
|
|
248
|
+
// the only place in production that meaningfully populates
|
|
249
|
+
// `editableLogoVariations` (BYO upload + designed-logo setStateAsync
|
|
250
|
+
// both funnel here), so caching here keeps every distinct draft's
|
|
251
|
+
// grid available for the lifetime of the session.
|
|
252
|
+
if (this.logoDraftToken) {
|
|
253
|
+
this.variationsByDraftToken[this.logoDraftToken] =
|
|
254
|
+
this.editableLogoVariations.map((v) => ({ ...v }));
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
/**
|
|
258
|
+
* Restore the variations grid for `logoDraftToken` from the per-token
|
|
259
|
+
* cache. Called by `_syncLogoSettingsFromSnapshot` during undo/redo.
|
|
260
|
+
* Returns true on cache hit.
|
|
261
|
+
*/
|
|
262
|
+
restoreVariationsForDraftToken(logoDraftToken) {
|
|
263
|
+
const cached = this.variationsByDraftToken[logoDraftToken];
|
|
264
|
+
if (!cached)
|
|
265
|
+
return false;
|
|
266
|
+
this.editableLogoVariations = cached.map((v) => ({ ...v }));
|
|
267
|
+
return true;
|
|
245
268
|
},
|
|
246
269
|
async updateMetadataAsync(defaultPrimaryText, resetLogoTemplateMetadata = false, layout) {
|
|
247
270
|
const result = await this.postEditableLogoRequestAsync({
|
|
@@ -285,6 +308,13 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
|
|
|
285
308
|
const logoDraft = logoStore.getLogoDraftAssetByToken(this.logoDraftToken);
|
|
286
309
|
if (logoDraft) {
|
|
287
310
|
logoDraft.metadata = metadata;
|
|
311
|
+
// Refresh the template-asset stamp in case the active asset has
|
|
312
|
+
// changed since this draft was first registered (e.g. successive
|
|
313
|
+
// BYO uploads that share an existing draft token would otherwise
|
|
314
|
+
// keep pointing at an older template).
|
|
315
|
+
if (logoStore.logoTemplateAsset) {
|
|
316
|
+
logoDraft.templateAsset = { ...logoStore.logoTemplateAsset };
|
|
317
|
+
}
|
|
288
318
|
}
|
|
289
319
|
else {
|
|
290
320
|
logoStore.addLogoDraftAsset({
|
|
@@ -293,6 +323,9 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
|
|
|
293
323
|
metadata,
|
|
294
324
|
tick: Date.now(),
|
|
295
325
|
isByo: logoStore.logoTemplateAsset?.isByo || false,
|
|
326
|
+
templateAsset: logoStore.logoTemplateAsset
|
|
327
|
+
? { ...logoStore.logoTemplateAsset }
|
|
328
|
+
: undefined,
|
|
296
329
|
},
|
|
297
330
|
});
|
|
298
331
|
}
|
|
@@ -4274,6 +4274,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
4274
4274
|
logoTemplateMetadata: string;
|
|
4275
4275
|
isLogoDraftSaved: boolean;
|
|
4276
4276
|
isTextOnlyLogo: boolean;
|
|
4277
|
+
variationsByDraftToken: Record<string, import("@shared/logo-settings/store").EditableLogoVariation[]>;
|
|
4277
4278
|
} & import("pinia").PiniaCustomStateProperties<import("@shared/logo-settings/store").EditableLogoState>) => () => string | undefined;
|
|
4278
4279
|
}, {
|
|
4279
4280
|
setStateAsync(payload: {
|
|
@@ -4291,6 +4292,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
4291
4292
|
getEditableLogoVariationByVariationId(id: number): any;
|
|
4292
4293
|
getEditableLogoVariationByBase64(base64: string): any;
|
|
4293
4294
|
updateEditableLogoImageUrlAsync(defaultPrimaryText?: string | undefined, overrideLogoVariation?: number | undefined, layout?: string | undefined): Promise<void>;
|
|
4295
|
+
restoreVariationsForDraftToken(logoDraftToken: string): boolean;
|
|
4294
4296
|
updateMetadataAsync(defaultPrimaryText?: string | undefined, resetLogoTemplateMetadata?: boolean, layout?: string | undefined): Promise<void>;
|
|
4295
4297
|
updateEditableLogoImageByVariationAsync(editableLogoVariation: import("@shared/logo-settings/store").EditableLogoVariation, defaultPrimaryText?: string | undefined, layout?: string | undefined): Promise<import("../../../../clients/fabric-render-client").ModifyLogoDataResponse | null>;
|
|
4296
4298
|
getDraftMetadata(logoDraftToken: string): string | undefined;
|
package/package.json
CHANGED
|
@@ -869,6 +869,9 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
|
|
|
869
869
|
// restored header logo. The preview rehydrates via the page contents,
|
|
870
870
|
// but `uiLogoSettings` holds its own copy that drives the sidebar
|
|
871
871
|
// "current logo" state — same pattern as `initialiseStoresByBrandPageModelAsync`.
|
|
872
|
+
// Also restores the variations grid + template asset for the
|
|
873
|
+
// snapshot's draft token (both are sidecars to `brandPageData` —
|
|
874
|
+
// BYO upload mutates them out of band).
|
|
872
875
|
this._syncLogoSettingsFromSnapshot(snapshot);
|
|
873
876
|
|
|
874
877
|
// 9. If the sidebar is editing a content item that no longer exists in
|
|
@@ -897,17 +900,30 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
|
|
|
897
900
|
newState: { selectedLogoImage: logoImage },
|
|
898
901
|
});
|
|
899
902
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
//
|
|
905
|
-
//
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
903
|
+
const draftToken: string | undefined = logoImage.logoDraftToken;
|
|
904
|
+
|
|
905
|
+
if (!draftToken) return;
|
|
906
|
+
|
|
907
|
+
// Re-derive `enableEditMode` and the active template asset from the
|
|
908
|
+
// logo-store's draft registry. Drafts are append-only for the session,
|
|
909
|
+
// and BYO upload stamps `templateAsset` onto the registered draft when
|
|
910
|
+
// it lands — so the registered draft is enough to fully restore the
|
|
911
|
+
// sidebar's design/upload chooser without storing anything inside
|
|
912
|
+
// each history entry. The variations grid is restored from the
|
|
913
|
+
// editable-logo store's per-token cache (populated by every
|
|
914
|
+
// `updateEditableLogoImageUrlAsync` render).
|
|
915
|
+
const draft = logoStore.getLogoDraftAssetByToken(draftToken);
|
|
916
|
+
|
|
917
|
+
if (draft) {
|
|
918
|
+
editableLogoStore.setEnableEditMode(!draft.isByo);
|
|
919
|
+
|
|
920
|
+
if (draft.templateAsset) {
|
|
921
|
+
logoStore.setLogoTemplateAsset(draft.templateAsset);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
909
924
|
|
|
910
|
-
|
|
925
|
+
editableLogoStore.setLogoDraftToken(draftToken);
|
|
926
|
+
editableLogoStore.restoreVariationsForDraftToken(draftToken);
|
|
911
927
|
},
|
|
912
928
|
|
|
913
929
|
_fallbackSidebarIfSelectedContentMissing(snapshot: BrandPageModel): void {
|
|
@@ -82,7 +82,7 @@ describe('history-store (single stack + JSON-string snapshots)', () => {
|
|
|
82
82
|
const entry = store.entries[0];
|
|
83
83
|
|
|
84
84
|
expect(typeof entry.snapshot).toBe('string');
|
|
85
|
-
// Round-trips to the same model via JSON.parse
|
|
85
|
+
// Round-trips to the same model via JSON.parse.
|
|
86
86
|
expect(JSON.parse(entry.snapshot)).toMatchObject(
|
|
87
87
|
mockMakerStore.brandPageData,
|
|
88
88
|
);
|
|
@@ -743,7 +743,7 @@ describe('history-store (single stack + JSON-string snapshots)', () => {
|
|
|
743
743
|
const store = useHistoryStore();
|
|
744
744
|
|
|
745
745
|
await store.captureBaseline();
|
|
746
|
-
const
|
|
746
|
+
const baselineBrandPageData = JSON.parse(store.entries[0].snapshot);
|
|
747
747
|
|
|
748
748
|
captureMutated(store);
|
|
749
749
|
|
|
@@ -755,10 +755,10 @@ describe('history-store (single stack + JSON-string snapshots)', () => {
|
|
|
755
755
|
expect(store.currentIndex).toBe(0);
|
|
756
756
|
expect(store.entries.length).toBe(2); // stack is unchanged, pointer moved
|
|
757
757
|
expect(mockMakerStore.applyHistorySnapshot).toHaveBeenCalledTimes(1);
|
|
758
|
-
// Undo restores the baseline snapshot — the parsed
|
|
759
|
-
//
|
|
758
|
+
// Undo restores the baseline snapshot — the parsed BrandPageModel must
|
|
759
|
+
// round-trip back through applyHistorySnapshot.
|
|
760
760
|
expect(mockMakerStore.applyHistorySnapshot).toHaveBeenCalledWith(
|
|
761
|
-
expect.objectContaining(
|
|
761
|
+
expect.objectContaining(baselineBrandPageData),
|
|
762
762
|
);
|
|
763
763
|
});
|
|
764
764
|
|
|
@@ -15,6 +15,12 @@ import { useEventTracker } from '../../composables/useEventTracker';
|
|
|
15
15
|
* with the live store.
|
|
16
16
|
* 2. `sizeBytes === snapshot.length` is automatic and accurate for the V2
|
|
17
17
|
* memory-budget instrumentation.
|
|
18
|
+
*
|
|
19
|
+
* Sidecar state that doesn't live on `brandPageData` (the variations grid in
|
|
20
|
+
* the Logo sidebar, the active `logoTemplateAsset`, the active
|
|
21
|
+
* `logoDraftToken`) is restored on undo by `_syncLogoSettingsFromSnapshot`
|
|
22
|
+
* via per-draft-token caches on the logo / editable-logo stores — keyed off
|
|
23
|
+
* `logoImage.logoDraftToken` which IS in the snapshot.
|
|
18
24
|
*/
|
|
19
25
|
export interface HistoryEntry {
|
|
20
26
|
/** JSON.stringify(BrandPageModel) at the moment of capture. */
|
|
@@ -66,8 +72,10 @@ const CAPTURE_MAX_WAIT_MS = 10000;
|
|
|
66
72
|
// FR-12: 40-entry cap. FR-13: 100 MB memory budget. FR-13c: per-entry
|
|
67
73
|
// oversize threshold — entries above this are skipped + emit telemetry.
|
|
68
74
|
// 25 MB accommodates a high-res BYO logo upload, which renders ~2.5 MB
|
|
69
|
-
// of base64 PNG into each of four viewport sections (~10 MB) plus
|
|
70
|
-
//
|
|
75
|
+
// of base64 PNG into each of four viewport sections (~10 MB) plus per-page
|
|
76
|
+
// logo content blocks. The variations grid (~10 MB) does NOT live in the
|
|
77
|
+
// snapshot — it sits on the editable-logo store keyed by draft token, and
|
|
78
|
+
// is restored on undo from there. The 100 MB total budget still evicts
|
|
71
79
|
// oldest non-baseline entries to keep memory bounded.
|
|
72
80
|
const MAX_ENTRIES = 40;
|
|
73
81
|
const MAX_MEMORY_BYTES = 100 * 1024 * 1024;
|
|
@@ -118,15 +126,13 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
118
126
|
* Synchronous — safe to call inside a microtask without racing a follow-up
|
|
119
127
|
* mutation.
|
|
120
128
|
*/
|
|
121
|
-
function
|
|
129
|
+
function serializeCurrentSnapshot(): string | null {
|
|
122
130
|
if (!cachedMakerStore) return null;
|
|
123
131
|
|
|
124
132
|
try {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return JSON.stringify(raw);
|
|
133
|
+
return JSON.stringify(toRaw(cachedMakerStore.brandPageData));
|
|
128
134
|
} catch (error) {
|
|
129
|
-
console.error('history-store: failed to serialize
|
|
135
|
+
console.error('history-store: failed to serialize snapshot', error);
|
|
130
136
|
|
|
131
137
|
return null;
|
|
132
138
|
}
|
|
@@ -632,7 +638,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
632
638
|
|
|
633
639
|
if (!baselineCaptured.value) return;
|
|
634
640
|
|
|
635
|
-
const snapshot =
|
|
641
|
+
const snapshot = serializeCurrentSnapshot();
|
|
636
642
|
|
|
637
643
|
if (!snapshot) return;
|
|
638
644
|
|
|
@@ -695,7 +701,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
695
701
|
|
|
696
702
|
installWatcher();
|
|
697
703
|
|
|
698
|
-
const snapshot =
|
|
704
|
+
const snapshot = serializeCurrentSnapshot();
|
|
699
705
|
|
|
700
706
|
if (!snapshot) return;
|
|
701
707
|
|
|
@@ -731,7 +737,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
731
737
|
|
|
732
738
|
if (!baselineCaptured.value) return 'skipped';
|
|
733
739
|
|
|
734
|
-
const snapshot =
|
|
740
|
+
const snapshot = serializeCurrentSnapshot();
|
|
735
741
|
|
|
736
742
|
if (!snapshot) return 'skipped';
|
|
737
743
|
|
|
@@ -14,6 +14,11 @@ export interface LogoDraftAsset {
|
|
|
14
14
|
tick: number;
|
|
15
15
|
isByo: boolean;
|
|
16
16
|
logoEditUrl?: string;
|
|
17
|
+
// The `logoTemplateAsset` active when this draft was created. Stamped at
|
|
18
|
+
// upload/setState time so undo/redo can restore the right template token
|
|
19
|
+
// + isByo flag from a snapshot's `logoDraftToken` alone — without us
|
|
20
|
+
// bloating each history entry with a copy of the asset.
|
|
21
|
+
templateAsset?: LogoTemplateAsset;
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
export interface LogoStoreState {
|
|
@@ -116,11 +116,17 @@ export interface EditableLogoState {
|
|
|
116
116
|
logoTemplateMetadata: string;
|
|
117
117
|
isLogoDraftSaved: boolean;
|
|
118
118
|
isTextOnlyLogo: boolean;
|
|
119
|
+
// Per-draft-token snapshot of `editableLogoVariations`. Repopulated each
|
|
120
|
+
// time `updateEditableLogoImageUrlAsync` finishes rendering for the active
|
|
121
|
+
// draft. Undo/redo reads from this map to restore the variations grid for
|
|
122
|
+
// the snapshot's `logoDraftToken` instead of re-rendering through fabric-
|
|
123
|
+
// render or stuffing 4 base64 PNGs into every history entry.
|
|
124
|
+
variationsByDraftToken: Record<string, EditableLogoVariation[]>;
|
|
119
125
|
}
|
|
120
126
|
|
|
121
127
|
export type SetStateAsyncPayload = Omit<
|
|
122
128
|
EditableLogoState,
|
|
123
|
-
'enableEditMode' | 'editableLogoVariations'
|
|
129
|
+
'enableEditMode' | 'editableLogoVariations' | 'variationsByDraftToken'
|
|
124
130
|
>;
|
|
125
131
|
|
|
126
132
|
export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
|
|
@@ -192,6 +198,7 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
|
|
|
192
198
|
},
|
|
193
199
|
makerFonts: [],
|
|
194
200
|
isLogoDraftSaved: false,
|
|
201
|
+
variationsByDraftToken: {},
|
|
195
202
|
}),
|
|
196
203
|
actions: {
|
|
197
204
|
async setStateAsync(payload: {
|
|
@@ -442,6 +449,32 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
|
|
|
442
449
|
}
|
|
443
450
|
});
|
|
444
451
|
});
|
|
452
|
+
|
|
453
|
+
// Stash the freshly rendered variation set under the active draft
|
|
454
|
+
// token so undo can restore it later without re-rendering. This is
|
|
455
|
+
// the only place in production that meaningfully populates
|
|
456
|
+
// `editableLogoVariations` (BYO upload + designed-logo setStateAsync
|
|
457
|
+
// both funnel here), so caching here keeps every distinct draft's
|
|
458
|
+
// grid available for the lifetime of the session.
|
|
459
|
+
if (this.logoDraftToken) {
|
|
460
|
+
this.variationsByDraftToken[this.logoDraftToken] =
|
|
461
|
+
this.editableLogoVariations.map((v) => ({ ...v }));
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Restore the variations grid for `logoDraftToken` from the per-token
|
|
467
|
+
* cache. Called by `_syncLogoSettingsFromSnapshot` during undo/redo.
|
|
468
|
+
* Returns true on cache hit.
|
|
469
|
+
*/
|
|
470
|
+
restoreVariationsForDraftToken(logoDraftToken: string): boolean {
|
|
471
|
+
const cached = this.variationsByDraftToken[logoDraftToken];
|
|
472
|
+
|
|
473
|
+
if (!cached) return false;
|
|
474
|
+
|
|
475
|
+
this.editableLogoVariations = cached.map((v) => ({ ...v }));
|
|
476
|
+
|
|
477
|
+
return true;
|
|
445
478
|
},
|
|
446
479
|
|
|
447
480
|
async updateMetadataAsync(
|
|
@@ -506,6 +539,14 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
|
|
|
506
539
|
|
|
507
540
|
if (logoDraft) {
|
|
508
541
|
logoDraft.metadata = metadata;
|
|
542
|
+
|
|
543
|
+
// Refresh the template-asset stamp in case the active asset has
|
|
544
|
+
// changed since this draft was first registered (e.g. successive
|
|
545
|
+
// BYO uploads that share an existing draft token would otherwise
|
|
546
|
+
// keep pointing at an older template).
|
|
547
|
+
if (logoStore.logoTemplateAsset) {
|
|
548
|
+
logoDraft.templateAsset = { ...logoStore.logoTemplateAsset };
|
|
549
|
+
}
|
|
509
550
|
} else {
|
|
510
551
|
logoStore.addLogoDraftAsset({
|
|
511
552
|
logoDraftAsset: {
|
|
@@ -513,6 +554,9 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
|
|
|
513
554
|
metadata,
|
|
514
555
|
tick: Date.now(),
|
|
515
556
|
isByo: logoStore.logoTemplateAsset?.isByo || false,
|
|
557
|
+
templateAsset: logoStore.logoTemplateAsset
|
|
558
|
+
? { ...logoStore.logoTemplateAsset }
|
|
559
|
+
: undefined,
|
|
516
560
|
},
|
|
517
561
|
});
|
|
518
562
|
}
|