@flamingo-stack/openframe-frontend-core 0.0.506 → 0.0.507
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/dist/{chunk-SQ63ZQLT.cjs → chunk-2F44PLTV.cjs} +26 -26
- package/dist/{chunk-SQ63ZQLT.cjs.map → chunk-2F44PLTV.cjs.map} +1 -1
- package/dist/{chunk-Y6M3AEI7.cjs → chunk-3SQ5KXHQ.cjs} +9 -9
- package/dist/{chunk-Y6M3AEI7.cjs.map → chunk-3SQ5KXHQ.cjs.map} +1 -1
- package/dist/{chunk-AZE46XSR.js → chunk-4LTMXDUS.js} +2 -2
- package/dist/{chunk-YEJ362MY.cjs → chunk-7LEL3RIX.cjs} +11 -11
- package/dist/{chunk-YEJ362MY.cjs.map → chunk-7LEL3RIX.cjs.map} +1 -1
- package/dist/{chunk-B3BWWXPM.js → chunk-ADPMHWOE.js} +4 -4
- package/dist/{chunk-CQAW3SDE.cjs → chunk-CWAOV2FK.cjs} +3 -3
- package/dist/{chunk-CQAW3SDE.cjs.map → chunk-CWAOV2FK.cjs.map} +1 -1
- package/dist/{chunk-BURDGVZD.js → chunk-DTYRYB2N.js} +2 -2
- package/dist/{chunk-4VSGKDJ4.js → chunk-I64ABCDX.js} +2 -2
- package/dist/{chunk-BCYKMY3I.js → chunk-KEBYLU3U.js} +2 -2
- package/dist/{chunk-A7KQNCTH.cjs → chunk-LDTR4IVZ.cjs} +31 -31
- package/dist/{chunk-A7KQNCTH.cjs.map → chunk-LDTR4IVZ.cjs.map} +1 -1
- package/dist/{chunk-VYQGUX3N.js → chunk-LRGHJPET.js} +2 -2
- package/dist/{chunk-TMIBSWAU.cjs → chunk-M2GOR3XQ.cjs} +87 -87
- package/dist/{chunk-TMIBSWAU.cjs.map → chunk-M2GOR3XQ.cjs.map} +1 -1
- package/dist/{chunk-WWBKSPJO.cjs → chunk-NIZDKTGL.cjs} +37 -37
- package/dist/{chunk-WWBKSPJO.cjs.map → chunk-NIZDKTGL.cjs.map} +1 -1
- package/dist/{chunk-ZTD6CFEX.js → chunk-OCEKO5CW.js} +27 -5
- package/dist/{chunk-JRSZ42PQ.cjs.map → chunk-OCEKO5CW.js.map} +1 -1
- package/dist/{chunk-ZBPJTMB4.js → chunk-PAGKRNWK.js} +2 -2
- package/dist/{chunk-FVVRY6RF.cjs → chunk-POOMO3PA.cjs} +7 -7
- package/dist/{chunk-FVVRY6RF.cjs.map → chunk-POOMO3PA.cjs.map} +1 -1
- package/dist/{chunk-774WVTFA.cjs → chunk-QTYZMP6D.cjs} +61 -61
- package/dist/{chunk-774WVTFA.cjs.map → chunk-QTYZMP6D.cjs.map} +1 -1
- package/dist/{chunk-PMKDB5ER.cjs → chunk-RHGGEKPQ.cjs} +4 -4
- package/dist/{chunk-PMKDB5ER.cjs.map → chunk-RHGGEKPQ.cjs.map} +1 -1
- package/dist/{chunk-FYZLCTAM.js → chunk-TBMV7I5N.js} +2 -2
- package/dist/{chunk-DCVKIZTV.js → chunk-TLMJHMXJ.js} +6 -6
- package/dist/{chunk-GYN7LLWZ.js → chunk-TSZHM74B.js} +2 -2
- package/dist/{chunk-JRSZ42PQ.cjs → chunk-TWYNR4TZ.cjs} +64 -42
- package/dist/chunk-TWYNR4TZ.cjs.map +1 -0
- package/dist/{chunk-SGHHM6NW.js → chunk-TZRUCD56.js} +5 -5
- package/dist/{chunk-LFPRWMH3.js → chunk-WA7RR64F.js} +4 -4
- package/dist/{chunk-LQ3DUGVD.js → chunk-WJQHJD7J.js} +2 -2
- package/dist/{chunk-EL6RLGC3.cjs → chunk-WK4N5VBX.cjs} +26 -26
- package/dist/{chunk-EL6RLGC3.cjs.map → chunk-WK4N5VBX.cjs.map} +1 -1
- package/dist/{chunk-CHMQNFBG.cjs → chunk-Z42BGM6Q.cjs} +5 -5
- package/dist/{chunk-CHMQNFBG.cjs.map → chunk-Z42BGM6Q.cjs.map} +1 -1
- package/dist/{chunk-JXFRUYTX.cjs → chunk-ZSQHZYCO.cjs} +13 -13
- package/dist/{chunk-JXFRUYTX.cjs.map → chunk-ZSQHZYCO.cjs.map} +1 -1
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/floating-walkthrough-video.d.ts +18 -1
- package/dist/components/features/floating-walkthrough-video.d.ts.map +1 -1
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +22 -22
- package/dist/components/help-center-pages/index.js +13 -13
- package/dist/components/index.cjs +132 -132
- package/dist/components/index.js +11 -11
- package/dist/components/meeting-scheduler/index.cjs +34 -34
- package/dist/components/meeting-scheduler/index.js +3 -3
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/index.cjs +2 -2
- package/dist/components/ui/index.js +1 -1
- package/dist/index.cjs +6 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -1
- package/dist/utils/index.cjs +8 -0
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +7 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/walkthrough-deep-link.d.ts +15 -0
- package/dist/utils/walkthrough-deep-link.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/features/.floating-walkthrough-video.md +38 -0
- package/src/components/features/floating-walkthrough-video.tsx +60 -5
- package/src/utils/index.ts +2 -0
- package/src/utils/walkthrough-deep-link.ts +18 -0
- package/dist/chunk-ZTD6CFEX.js.map +0 -1
- /package/dist/{chunk-AZE46XSR.js.map → chunk-4LTMXDUS.js.map} +0 -0
- /package/dist/{chunk-B3BWWXPM.js.map → chunk-ADPMHWOE.js.map} +0 -0
- /package/dist/{chunk-BURDGVZD.js.map → chunk-DTYRYB2N.js.map} +0 -0
- /package/dist/{chunk-4VSGKDJ4.js.map → chunk-I64ABCDX.js.map} +0 -0
- /package/dist/{chunk-BCYKMY3I.js.map → chunk-KEBYLU3U.js.map} +0 -0
- /package/dist/{chunk-VYQGUX3N.js.map → chunk-LRGHJPET.js.map} +0 -0
- /package/dist/{chunk-ZBPJTMB4.js.map → chunk-PAGKRNWK.js.map} +0 -0
- /package/dist/{chunk-FYZLCTAM.js.map → chunk-TBMV7I5N.js.map} +0 -0
- /package/dist/{chunk-DCVKIZTV.js.map → chunk-TLMJHMXJ.js.map} +0 -0
- /package/dist/{chunk-GYN7LLWZ.js.map → chunk-TSZHM74B.js.map} +0 -0
- /package/dist/{chunk-SGHHM6NW.js.map → chunk-TZRUCD56.js.map} +0 -0
- /package/dist/{chunk-LFPRWMH3.js.map → chunk-WA7RR64F.js.map} +0 -0
- /package/dist/{chunk-LQ3DUGVD.js.map → chunk-WJQHJD7J.js.map} +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walkthrough-video deep link — the ONE home for the query param that opens
|
|
3
|
+
* the floating walkthrough widget's theater full-screen (paused) on page
|
|
4
|
+
* load. Consumed by the widget itself (`FloatingWalkthroughVideo` defaults
|
|
5
|
+
* its `deepLinkParam` prop to this) and by hosts that MINT deep-link URLs
|
|
6
|
+
* (invitation emails) or carry the param across redirects (the hub's
|
|
7
|
+
* auth-wall proxy). Lives beside `dismissal-storage.ts` — the same
|
|
8
|
+
* widget-adjacent naming-layer altitude.
|
|
9
|
+
*/
|
|
10
|
+
/** `?walkthrough=1` — presence-based on the read side (any value counts);
|
|
11
|
+
* `=1` is just the canonical value URL minters write. */
|
|
12
|
+
export declare const WALKTHROUGH_OPEN_QUERY_PARAM = "walkthrough";
|
|
13
|
+
/** Append the theater deep-link param to a URL (absolute or relative). */
|
|
14
|
+
export declare function withWalkthroughOpenParam(url: string): string;
|
|
15
|
+
//# sourceMappingURL=walkthrough-deep-link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walkthrough-deep-link.d.ts","sourceRoot":"","sources":["../../src/utils/walkthrough-deep-link.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;0DAC0D;AAC1D,eAAO,MAAM,4BAA4B,gBAAgB,CAAC;AAE1D,0EAA0E;AAC1E,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5D"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!-- source-hash: 47c31b34796bb8d1bc274d1012e9c9e3 -->
|
|
2
|
+
Floating per-platform walkthrough/demo video widget. Renders a collapsed corner card (hover preview, transport controls, cookie dismissal) that opens a pure-theater dialog — a centered 16:9 stage on a dimmed backdrop. The host supplies the video data and the current pathname; the widget owns every playback state handoff between card, hover preview, and theater.
|
|
3
|
+
|
|
4
|
+
## Key Components
|
|
5
|
+
|
|
6
|
+
### Exports
|
|
7
|
+
|
|
8
|
+
- **`FloatingWalkthroughVideo`** — The widget. Controlled (`open` + `onOpenChange`) or uncontrolled (`defaultOpen`) theater state.
|
|
9
|
+
- **`WalkthroughVideoData`** — Wire-shape contract: `mainVideoUrl` / `youtubeUrl` (YouTube wins when both are set), `posterUrl`, `captionsUrl` (relative `/api/captions/...` path), `title`, `presenterAvatarUrl`, `position` (`'left' | 'right'` bottom-corner pin), `id` (drives id-match cookie dismissal — a new video re-shows a dismissed card).
|
|
10
|
+
- **`FloatingWalkthroughVideoProps`** — See behaviors below for the non-obvious ones.
|
|
11
|
+
|
|
12
|
+
### Key Behaviors
|
|
13
|
+
|
|
14
|
+
- **Appear gate**: the collapsed card mounts after `appearDelayMs` (default 3000 ms) + an idle callback, and never renders when dismissed. The THEATER is deliberately NOT gated — a host `open={true}` or `defaultOpen` can force it before the card appears or after dismissal, which is what makes deep links work.
|
|
15
|
+
- **`deepLinkParam`** — query-param NAME (defaults to `WALKTHROUGH_OPEN_QUERY_PARAM`, `'walkthrough'`, from `utils/walkthrough-deep-link.ts`; pass `''` to disable): when present in `window.location.search` at first client render, the theater opens immediately and PAUSED — `defaultOpen + defaultOpenPaused` decided inside the component, so hosts don't defer their first render to read the URL. Presence-based, read once (deep links arrive by full page load). SSR-safe: the server renders closed and the theater lives in a portal. URL minters (emails, redirects) use the sibling `withWalkthroughOpenParam(url)`.
|
|
16
|
+
- **`defaultOpenPaused`** — with `defaultOpen`, the initial theater session starts PAUSED instead of autoplaying. For deep links (e.g. the hub's `?walkthrough=1`), where the open has no user gesture and unrequested audio/motion would be hostile. File player: both autoplay flags suppressed (MuxPlayer mounts paused on its poster). YouTube: `autoActivate` suppressed instead — the activated iframe hardcodes `autoplay=1`, so the click-to-play facade IS the paused presentation. The paused session is exactly the initial `defaultOpen` theater: it ends when the NEXT (gesture- or host-driven) open mounts a fresh theater, which autoplays as usual. It is deliberately NOT cleared on close — the closing player stays mounted through the dialog's exit animation, and a prop flip there would restart playback.
|
|
17
|
+
- **Resume handoff**: closing the theater mid-play hands the timestamp + mute intent back to the card, which continues playback inline; reopening seeds the theater from the live card position. A finished video reopens at 0, not its own last frame.
|
|
18
|
+
- **Dismissal**: cookie-based, id-matched (mirrors the announcement bar). `dismissal={false}` removes the X entirely; `dismissal.storageKey` is the per-platform cookie name (see `walkthroughDismissCookieName`).
|
|
19
|
+
- **`pathname`**: route identity from the host — the lib can't observe navigation. Changing it re-queries the footer IntersectionObserver target (`hideNearSelector`, default `footer`) that fades the card out over the footer.
|
|
20
|
+
|
|
21
|
+
## Usage Example
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Host layout (hub: components/shared/global-walkthrough-video-client.tsx)
|
|
25
|
+
<FloatingWalkthroughVideo
|
|
26
|
+
video={video}
|
|
27
|
+
pathname={pathname}
|
|
28
|
+
// Deep link (?walkthrough=1) is built in: `deepLinkParam` defaults to
|
|
29
|
+
// WALKTHROUGH_OPEN_QUERY_PARAM — theater opens immediately, PAUSED.
|
|
30
|
+
dismissal={{ storageKey: walkthroughDismissCookieName(platform) }}
|
|
31
|
+
/>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> **Deep-link contract:** prefer `deepLinkParam` — the component reads the URL itself at the right moment. If a host drives `defaultOpen` manually instead, it is a load-time value: decide it BEFORE the component's first render, not by flipping a prop afterwards.
|
|
35
|
+
|
|
36
|
+
## Source
|
|
37
|
+
|
|
38
|
+
[`floating-walkthrough-video.tsx`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/openframe-frontend-core/src/components/features/floating-walkthrough-video.tsx)
|
|
@@ -57,6 +57,7 @@ import {
|
|
|
57
57
|
isWalkthroughDismissed,
|
|
58
58
|
dismissWalkthrough,
|
|
59
59
|
} from '../../utils/dismissal-storage';
|
|
60
|
+
import { WALKTHROUGH_OPEN_QUERY_PARAM } from '../../utils/walkthrough-deep-link';
|
|
60
61
|
|
|
61
62
|
/** Wire-shape data for the widget. Kept as the shared contract the hub DAL
|
|
62
63
|
* re-exports as `PublicWalkthroughVideo & { id }`. `mainVideoUrl`/`youtubeUrl`
|
|
@@ -82,6 +83,23 @@ export interface FloatingWalkthroughVideoProps {
|
|
|
82
83
|
open?: boolean;
|
|
83
84
|
onOpenChange?: (open: boolean) => void;
|
|
84
85
|
defaultOpen?: boolean;
|
|
86
|
+
/** With `defaultOpen`: the initial theater starts PAUSED instead of
|
|
87
|
+
* autoplaying — for deep links (`?walkthrough=1`), where the open has no
|
|
88
|
+
* user gesture and unrequested audio/motion would be hostile. Applies to
|
|
89
|
+
* the initial `defaultOpen` session only: it ends when the NEXT open —
|
|
90
|
+
* gesture-driven (card click) or host-driven (`open` flipping true) —
|
|
91
|
+
* mounts a fresh theater, which autoplays as usual. */
|
|
92
|
+
defaultOpenPaused?: boolean;
|
|
93
|
+
/** Query-param NAME that deep-links into the theater: when present in
|
|
94
|
+
* `window.location.search` at first client render, the theater opens
|
|
95
|
+
* immediately and PAUSED — `defaultOpen + defaultOpenPaused` decided
|
|
96
|
+
* inside the component, so hosts don't defer their first render to read
|
|
97
|
+
* the URL. Defaults to `WALKTHROUGH_OPEN_QUERY_PARAM` ('walkthrough');
|
|
98
|
+
* pass '' to disable. Presence-based (any value counts), read ONCE at
|
|
99
|
+
* mount (deep links arrive by full page load, not client navigation).
|
|
100
|
+
* SSR-safe: the server renders closed, and the theater lives in a portal,
|
|
101
|
+
* so the hydrated (non-portal) markup is identical either way. */
|
|
102
|
+
deepLinkParam?: string;
|
|
85
103
|
label?: string;
|
|
86
104
|
appearDelayMs?: number;
|
|
87
105
|
/** Cookie-based dismissal (id-match, mirrors the announcement bar). `false`
|
|
@@ -111,6 +129,8 @@ export function FloatingWalkthroughVideo({
|
|
|
111
129
|
open: openProp,
|
|
112
130
|
onOpenChange,
|
|
113
131
|
defaultOpen,
|
|
132
|
+
defaultOpenPaused,
|
|
133
|
+
deepLinkParam = WALKTHROUGH_OPEN_QUERY_PARAM,
|
|
114
134
|
label = 'Play Demo Video',
|
|
115
135
|
appearDelayMs = 3000,
|
|
116
136
|
dismissal = {},
|
|
@@ -171,8 +191,29 @@ export function FloatingWalkthroughVideo({
|
|
|
171
191
|
}, []);
|
|
172
192
|
|
|
173
193
|
// --- controlled/uncontrolled open ---
|
|
174
|
-
|
|
194
|
+
// Deep link: read ONCE, synchronously, on the first client render — the
|
|
195
|
+
// theater's autoplay props are load-time, so the decision must exist before
|
|
196
|
+
// the render that mounts it (an effect would be one commit too late). The
|
|
197
|
+
// lazy initializer never re-runs, so client navigation can't re-trigger it.
|
|
198
|
+
const [deepLinkHit] = useState(() => {
|
|
199
|
+
if (!deepLinkParam || typeof window === 'undefined') return false;
|
|
200
|
+
try {
|
|
201
|
+
return new URLSearchParams(window.location.search).has(deepLinkParam);
|
|
202
|
+
} catch {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
const [openState, setOpenState] = useState(Boolean(defaultOpen) || deepLinkHit);
|
|
175
207
|
const open = openProp !== undefined ? openProp : openState;
|
|
208
|
+
// The paused deep-link session — see `defaultOpenPaused`. Load-time-safe:
|
|
209
|
+
// the theater player's autoplay props are read once at construction, and
|
|
210
|
+
// this is set before the first render that mounts it. Cleared on the next
|
|
211
|
+
// OPEN transition only (the prevOpen sync below), right before a fresh
|
|
212
|
+
// theater constructs — never on close, where the closing player is still
|
|
213
|
+
// mounted and a prop flip would restart it (see the sync's comment).
|
|
214
|
+
const [pausedOpenSession, setPausedOpenSession] = useState(
|
|
215
|
+
Boolean(defaultOpen && defaultOpenPaused) || deepLinkHit,
|
|
216
|
+
);
|
|
176
217
|
|
|
177
218
|
// --- refs & continuation state ---
|
|
178
219
|
const previewHandleRef = useRef<VideoPlayerHandle | null>(null);
|
|
@@ -400,6 +441,16 @@ export function FloatingWalkthroughVideo({
|
|
|
400
441
|
const [prevOpen, setPrevOpen] = useState(open);
|
|
401
442
|
if (open !== prevOpen) {
|
|
402
443
|
setPrevOpen(open);
|
|
444
|
+
// RISING edge only: the paused deep-link session ends when the NEXT
|
|
445
|
+
// (gesture- or host-driven) open mounts a fresh theater — this re-render
|
|
446
|
+
// commits the cleared flag before that content constructs, so it
|
|
447
|
+
// autoplays as usual. NEVER clear on close: Radix keeps the closing
|
|
448
|
+
// theater mounted through its exit animation, and flipping the flag then
|
|
449
|
+
// flips `autoPlayUnmuted` false→true on the STILL-MOUNTED player, whose
|
|
450
|
+
// autoplay kick effect resurrects playback — audible after close and
|
|
451
|
+
// doubled against the card's resume player. Idempotent, so a
|
|
452
|
+
// discarded-and-retried render attempt decides the same way.
|
|
453
|
+
if (open && pausedOpenSession) setPausedOpenSession(false);
|
|
403
454
|
// Compared, not cleared: React can discard and re-run a render attempt
|
|
404
455
|
// (concurrent interruption, error retry, a host wrapping setOpen in
|
|
405
456
|
// startTransition). A read-and-clear would decide differently on the
|
|
@@ -874,11 +925,15 @@ export function FloatingWalkthroughVideo({
|
|
|
874
925
|
playerHandleRef={theaterHandleRef}
|
|
875
926
|
// Muted still means PLAYING: without this a deliberately muted
|
|
876
927
|
// card opened a paused theater, breaking parity with the
|
|
877
|
-
// unmuted path.
|
|
878
|
-
|
|
879
|
-
|
|
928
|
+
// unmuted path. EXCEPT the paused deep-link session, which
|
|
929
|
+
// starts fully stopped: no autoplay flag at all, and for
|
|
930
|
+
// YouTube no autoActivate either — the activated iframe
|
|
931
|
+
// hardcodes `autoplay=1`, so staying on the facade IS the
|
|
932
|
+
// paused presentation (clicking it activates and plays).
|
|
933
|
+
autoPlay={theaterStart.muted && !pausedOpenSession}
|
|
934
|
+
autoPlayUnmuted={!theaterStart.muted && !pausedOpenSession}
|
|
880
935
|
startMuted={theaterStart.muted}
|
|
881
|
-
autoActivate
|
|
936
|
+
autoActivate={!pausedOpenSession}
|
|
882
937
|
suspended={suspended}
|
|
883
938
|
onMutedFallbackChange={st => { theaterForcedMuteRef.current = st.muted; }}
|
|
884
939
|
onEnded={() => { endedLatchRef.current = true; }}
|
package/src/utils/index.ts
CHANGED
|
@@ -96,6 +96,8 @@ export * from './announcement-storage'
|
|
|
96
96
|
// cookie id-match dismissal store (walkthrough video widget)
|
|
97
97
|
export * from './dismiss-cookie'
|
|
98
98
|
export * from './dismissal-storage'
|
|
99
|
+
// walkthrough deep-link query param (widget default + host URL minters)
|
|
100
|
+
export * from './walkthrough-deep-link'
|
|
99
101
|
|
|
100
102
|
// Image-proxy URL builder (pure, runtime-configurable)
|
|
101
103
|
export {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walkthrough-video deep link — the ONE home for the query param that opens
|
|
3
|
+
* the floating walkthrough widget's theater full-screen (paused) on page
|
|
4
|
+
* load. Consumed by the widget itself (`FloatingWalkthroughVideo` defaults
|
|
5
|
+
* its `deepLinkParam` prop to this) and by hosts that MINT deep-link URLs
|
|
6
|
+
* (invitation emails) or carry the param across redirects (the hub's
|
|
7
|
+
* auth-wall proxy). Lives beside `dismissal-storage.ts` — the same
|
|
8
|
+
* widget-adjacent naming-layer altitude.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** `?walkthrough=1` — presence-based on the read side (any value counts);
|
|
12
|
+
* `=1` is just the canonical value URL minters write. */
|
|
13
|
+
export const WALKTHROUGH_OPEN_QUERY_PARAM = 'walkthrough';
|
|
14
|
+
|
|
15
|
+
/** Append the theater deep-link param to a URL (absolute or relative). */
|
|
16
|
+
export function withWalkthroughOpenParam(url: string): string {
|
|
17
|
+
return `${url}${url.includes('?') ? '&' : '?'}${WALKTHROUGH_OPEN_QUERY_PARAM}=1`;
|
|
18
|
+
}
|