@flamingo-stack/openframe-frontend-core 0.0.843 → 0.0.845
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/{case-study-card-VN3JBNF5.cjs → case-study-card-DJOHIHYU.cjs} +3 -3
- package/dist/{chunk-SOQVKIWM.cjs → chunk-7P3UJHEG.cjs} +3 -3
- package/dist/{chunk-QBZ73IK7.cjs → chunk-7VKKA64D.cjs} +39 -39
- package/dist/{chunk-23DVVS4I.cjs → chunk-ABL5OBSF.cjs} +110 -110
- package/dist/{chunk-EUEPGHY4.cjs → chunk-BIOSHDXQ.cjs} +14 -11
- package/dist/{chunk-4ASUUB3A.cjs → chunk-BZZE4KIV.cjs} +71 -71
- package/dist/{chunk-2WGA2IRN.cjs → chunk-D3GUIEDW.cjs} +182 -182
- package/dist/{chunk-MWQOM2EI.cjs → chunk-D5DMWXF2.cjs} +4 -4
- package/dist/{chunk-NMLNZCK2.cjs → chunk-DGQDGCQH.cjs} +2 -2
- package/dist/{chunk-DUB2UVYS.cjs → chunk-EEYYIRS2.cjs} +51 -51
- package/dist/{chunk-6HFTSVVC.cjs → chunk-FLW4WULE.cjs} +8 -8
- package/dist/{chunk-SOTTMZ6U.cjs → chunk-HPXET3LH.cjs} +17 -17
- package/dist/{chunk-3IXW2EKO.cjs → chunk-IU7MNE3S.cjs} +62 -62
- package/dist/{chunk-QPJUQ5YU.cjs → chunk-J2ZSGOUC.cjs} +14 -14
- package/dist/{chunk-2H5D2PUC.cjs → chunk-LOGXNO4Y.cjs} +20 -20
- package/dist/{chunk-6CZVQ72C.cjs → chunk-PGAMWM6C.cjs} +3 -3
- package/dist/{chunk-QJRZVIQP.cjs → chunk-PJSTK3OK.cjs} +34 -34
- package/dist/{chunk-6M764K5Z.cjs → chunk-QK2A334V.cjs} +5 -5
- package/dist/{chunk-SC36S7DJ.cjs → chunk-RAJ5FYFL.cjs} +2 -2
- package/dist/{chunk-WPMJUYW3.cjs → chunk-SIFRIUPW.cjs} +79 -79
- package/dist/{chunk-5CPEMPNP.cjs → chunk-TBOWFTEN.cjs} +2 -2
- package/dist/{chunk-OGINOWMT.cjs → chunk-TRCMVH5W.cjs} +3 -3
- package/dist/{chunk-2JZFXGHE.cjs → chunk-TRZN6NGN.cjs} +4 -4
- package/dist/{chunk-RSZZTB5T.cjs → chunk-URP6GYTD.cjs} +49 -49
- package/dist/{chunk-HLMA6CDT.cjs → chunk-VQF4QN7D.cjs} +74 -74
- package/dist/{chunk-USUVHAQ7.cjs → chunk-X432Y6RM.cjs} +29 -1
- package/dist/{chunk-ZXEWBJUE.cjs → chunk-ZWDENGHZ.cjs} +11 -11
- package/dist/{cloud-tenants-VPYROTKH.cjs → cloud-tenants-BAEVUGHO.cjs} +10 -10
- package/dist/components/case-studies/index.cjs +25 -25
- package/dist/components/chat/index.cjs +8 -8
- package/dist/components/contact/index.cjs +11 -11
- package/dist/components/docs/index.cjs +14 -14
- package/dist/components/embeds/index.cjs +11 -11
- package/dist/components/faq/index.cjs +12 -12
- package/dist/components/features/index.cjs +10 -10
- package/dist/components/features/software/update-settings-fields.d.ts.map +1 -1
- package/dist/components/features/software/update-settings-fields.js +1 -1
- package/dist/components/features/video-hover-preview.d.ts +7 -1
- package/dist/components/features/video-hover-preview.d.ts.map +1 -1
- package/dist/components/features/video-hover-preview.js +4 -1
- package/dist/components/features/video-shared.d.ts +2 -0
- package/dist/components/features/video-shared.d.ts.map +1 -1
- package/dist/components/features/video-shared.js +29 -1
- package/dist/components/help-center-pages/index.cjs +85 -85
- package/dist/components/index.cjs +55 -55
- package/dist/components/meeting-scheduler/index.cjs +36 -36
- package/dist/components/navigation/index.cjs +13 -13
- package/dist/components/onboarding-guides/index.cjs +13 -13
- package/dist/components/product-demo/index.cjs +19 -19
- package/dist/components/related-content/index.cjs +6 -6
- package/dist/components/tickets/index.cjs +15 -15
- package/dist/components/ui/index.cjs +10 -10
- package/dist/{devices-W76BAABE.cjs → devices-IXWCDJAP.cjs} +11 -11
- package/dist/{embeddable-chat-C6DUH2JL.cjs → embeddable-chat-Z3S37SSM.cjs} +78 -78
- package/dist/index.cjs +14 -14
- package/dist/{knowledge-ILAIWOSY.cjs → knowledge-LMWQ6EOF.cjs} +11 -11
- package/dist/{logs-VCPRFJGB.cjs → logs-PRYX25NH.cjs} +17 -17
- package/dist/{policies-3BNAW4M5.cjs → policies-PQZNRL3M.cjs} +14 -14
- package/dist/{scripts-VFFSJDYV.cjs → scripts-LDPZN73H.cjs} +15 -15
- package/dist/{software-update-VTBTLCZO.cjs → software-update-URVEWPXZ.cjs} +13 -13
- package/dist/{video-file-player-IHO66P2Q.cjs → video-file-player-XMOB234V.cjs} +11 -11
- package/package.json +1 -1
- package/src/components/features/software/update-settings-fields.tsx +19 -16
- package/src/components/features/video-hover-preview.tsx +48 -38
- package/src/components/features/video-shared.tsx +36 -0
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
* - Player mount is controlled via `playerMounted` (the strip's shared gate)
|
|
19
19
|
* OR self-managed here via a two-way near-viewport observer (standalone
|
|
20
20
|
* editor cards). Exactly one path is ever active.
|
|
21
|
+
* - Inside that gate the player waits for the visitor's first input: until then
|
|
22
|
+
* the card is its poster, and a visitor who only reads the first screen loads
|
|
23
|
+
* no player (the largest script a page can load, 1.1 MB to parse). From that
|
|
24
|
+
* input on it mounts near the screen, because a hover must find a player with
|
|
25
|
+
* its stream loaded: mounting on the first hover made the bites strip start
|
|
26
|
+
* late and stutter, and was removed (CU-17tkuw5xp4q).
|
|
21
27
|
*/
|
|
22
28
|
|
|
23
29
|
import type React from 'react';
|
|
@@ -30,7 +36,7 @@ import { useCoverImageFallback } from '../chat/entity-cards/use-cover-image-fall
|
|
|
30
36
|
import { toMuxPreviewUrl } from './mux-origins';
|
|
31
37
|
import { Video } from './video';
|
|
32
38
|
import { VideoPlayBadge } from './video-center-badge';
|
|
33
|
-
import type
|
|
39
|
+
import { useVisitorActed, type VideoPlayerHandle, type VideoMutedFallbackState } from './video-shared';
|
|
34
40
|
|
|
35
41
|
export interface VideoHoverPreviewSurfaceProps {
|
|
36
42
|
/** Source URL (Mux HLS / Supabase mp4). Rendition-capped internally. */
|
|
@@ -126,6 +132,8 @@ export function VideoHoverPreviewSurface({
|
|
|
126
132
|
}, [gateControlled]);
|
|
127
133
|
// Continuation forces the media + player on regardless of hover/viewport gate.
|
|
128
134
|
const showMedia = continuation || (gateControlled ? playerMounted : isNear);
|
|
135
|
+
const visitorActed = useVisitorActed();
|
|
136
|
+
const showPlayer = continuation || active || visitorActed;
|
|
129
137
|
|
|
130
138
|
// Poster resolution — the shared entity-card cover fallback chain: the real
|
|
131
139
|
// thumbnail, dropped on load error. Null → first-frame facade (unless the
|
|
@@ -160,43 +168,45 @@ export function VideoHoverPreviewSurface({
|
|
|
160
168
|
|
|
161
169
|
{badge === 'play' && !active && !continuation && <VideoPlayBadge className="absolute inset-0 z-10 m-auto" />}
|
|
162
170
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
171
|
+
{showPlayer && (
|
|
172
|
+
<div
|
|
173
|
+
className="absolute inset-0"
|
|
174
|
+
style={{ '--media-background-color': 'transparent' } as React.CSSProperties}
|
|
175
|
+
>
|
|
176
|
+
<Video
|
|
177
|
+
// Remount between modes: `startTime` + autoplay are LOAD-TIME
|
|
178
|
+
// props (playback-core binds them to one-shot durationchange /
|
|
179
|
+
// loadstart handlers), so re-propping an already-loaded element
|
|
180
|
+
// silently drops the seek. Only a Mux preview rewrite changed
|
|
181
|
+
// `src` before, which is why HLS resumed and plain MP4 did not.
|
|
182
|
+
key={continuation ? 'continuation' : 'preview'}
|
|
183
|
+
kind="file"
|
|
184
|
+
// Rendition-capped in BOTH modes: the cap was only skipped
|
|
185
|
+
// because changing `src` used to be the sole trigger for the
|
|
186
|
+
// seek; the explicit key handles that now, and a 320px mini
|
|
187
|
+
// player should never pull the uncapped manifest.
|
|
188
|
+
url={previewUrl}
|
|
189
|
+
poster={posterUrl}
|
|
190
|
+
{...(continuation
|
|
191
|
+
? {
|
|
192
|
+
startTime,
|
|
193
|
+
autoPlay: autoPlay && startMuted,
|
|
194
|
+
startMuted,
|
|
195
|
+
autoPlayUnmuted: autoPlay && !startMuted,
|
|
196
|
+
}
|
|
197
|
+
: { playWhenHovered: active })}
|
|
198
|
+
chromeless
|
|
199
|
+
layout="fill"
|
|
200
|
+
fit={fit}
|
|
201
|
+
preload={preload}
|
|
202
|
+
mutedIntent={mutedIntent}
|
|
203
|
+
hideMutedBadge={hideMutedBadge}
|
|
204
|
+
onMutedFallbackChange={onMutedFallbackChange}
|
|
205
|
+
onEnded={onEnded}
|
|
206
|
+
playerHandleRef={previewHandleRef}
|
|
207
|
+
/>
|
|
208
|
+
</div>
|
|
209
|
+
)}
|
|
200
210
|
</>
|
|
201
211
|
) : (
|
|
202
212
|
<div className="absolute inset-0 bg-ods-card" />
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type React from 'react';
|
|
15
|
+
import { useSyncExternalStore } from 'react';
|
|
15
16
|
import { Button } from '../ui/button';
|
|
16
17
|
|
|
17
18
|
// =============================================================================
|
|
@@ -51,6 +52,41 @@ if (typeof window !== 'undefined') {
|
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
// =============================================================================
|
|
56
|
+
// The visitor's first input (module scope). Wider than activation above: a mouse
|
|
57
|
+
// that moves or a wheel that turns counts, because a hover comes after one. Until
|
|
58
|
+
// it, a hover preview draws its poster and loads no player, the largest script a
|
|
59
|
+
// page can load (`VideoHoverPreviewSurface`).
|
|
60
|
+
// =============================================================================
|
|
61
|
+
|
|
62
|
+
const VISITOR_INPUT_EVENTS = ['pointermove', 'pointerdown', 'keydown', 'wheel'] as const;
|
|
63
|
+
let visitorActed = false;
|
|
64
|
+
const visitorActedListeners = new Set<() => void>();
|
|
65
|
+
if (typeof window !== 'undefined') {
|
|
66
|
+
const markActed = () => {
|
|
67
|
+
visitorActed = true;
|
|
68
|
+
for (const type of VISITOR_INPUT_EVENTS) window.removeEventListener(type, markActed, true);
|
|
69
|
+
for (const listener of visitorActedListeners) listener();
|
|
70
|
+
visitorActedListeners.clear();
|
|
71
|
+
};
|
|
72
|
+
for (const type of VISITOR_INPUT_EVENTS) window.addEventListener(type, markActed, { capture: true, passive: true });
|
|
73
|
+
}
|
|
74
|
+
function subscribeToVisitorActed(listener: () => void): () => void {
|
|
75
|
+
if (visitorActed) return () => undefined;
|
|
76
|
+
visitorActedListeners.add(listener);
|
|
77
|
+
return () => {
|
|
78
|
+
visitorActedListeners.delete(listener);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** True once the visitor has moved the pointer, touched the page, turned the wheel or pressed a key. False on the server. */
|
|
82
|
+
export function useVisitorActed(): boolean {
|
|
83
|
+
return useSyncExternalStore(
|
|
84
|
+
subscribeToVisitorActed,
|
|
85
|
+
() => visitorActed,
|
|
86
|
+
() => false,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
54
90
|
// =============================================================================
|
|
55
91
|
// Playback-failure handling
|
|
56
92
|
// =============================================================================
|