@oxyhq/bloom 1.3.0 → 1.5.0
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/docs/media-flight.mdx +77 -1
- package/lib/commonjs/media-flight/MediaFlightHost.js +2 -0
- package/lib/commonjs/media-flight/MediaFlightHost.js.map +1 -1
- package/lib/commonjs/media-flight/MediaFlightHost.web.js +3 -1
- package/lib/commonjs/media-flight/MediaFlightHost.web.js.map +1 -1
- package/lib/commonjs/media-flight/MediaFlightLayer.web.js +49 -24
- package/lib/commonjs/media-flight/MediaFlightLayer.web.js.map +1 -1
- package/lib/commonjs/media-flight/MediaSurface.js +38 -5
- package/lib/commonjs/media-flight/MediaSurface.js.map +1 -1
- package/lib/commonjs/media-flight/constants.js +23 -1
- package/lib/commonjs/media-flight/constants.js.map +1 -1
- package/lib/commonjs/media-flight/media-node.web.js +29 -6
- package/lib/commonjs/media-flight/media-node.web.js.map +1 -1
- package/lib/commonjs/media-flight/store.js +4 -1
- package/lib/commonjs/media-flight/store.js.map +1 -1
- package/lib/module/media-flight/MediaFlightHost.js +2 -0
- package/lib/module/media-flight/MediaFlightHost.js.map +1 -1
- package/lib/module/media-flight/MediaFlightHost.web.js +3 -1
- package/lib/module/media-flight/MediaFlightHost.web.js.map +1 -1
- package/lib/module/media-flight/MediaFlightLayer.web.js +50 -25
- package/lib/module/media-flight/MediaFlightLayer.web.js.map +1 -1
- package/lib/module/media-flight/MediaSurface.js +39 -6
- package/lib/module/media-flight/MediaSurface.js.map +1 -1
- package/lib/module/media-flight/constants.js +22 -0
- package/lib/module/media-flight/constants.js.map +1 -1
- package/lib/module/media-flight/media-node.web.js +29 -6
- package/lib/module/media-flight/media-node.web.js.map +1 -1
- package/lib/module/media-flight/store.js +4 -1
- package/lib/module/media-flight/store.js.map +1 -1
- package/lib/typescript/commonjs/media-flight/MediaFlightHost.d.ts +1 -1
- package/lib/typescript/commonjs/media-flight/MediaFlightHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/media-flight/MediaFlightHost.web.d.ts +1 -1
- package/lib/typescript/commonjs/media-flight/MediaFlightHost.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/media-flight/MediaFlightLayer.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/media-flight/MediaSurface.d.ts +13 -2
- package/lib/typescript/commonjs/media-flight/MediaSurface.d.ts.map +1 -1
- package/lib/typescript/commonjs/media-flight/constants.d.ts +20 -0
- package/lib/typescript/commonjs/media-flight/constants.d.ts.map +1 -1
- package/lib/typescript/commonjs/media-flight/media-node.web.d.ts +17 -3
- package/lib/typescript/commonjs/media-flight/media-node.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/media-flight/store.d.ts +4 -1
- package/lib/typescript/commonjs/media-flight/store.d.ts.map +1 -1
- package/lib/typescript/commonjs/media-flight/types.d.ts +49 -0
- package/lib/typescript/commonjs/media-flight/types.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/MediaFlightHost.d.ts +1 -1
- package/lib/typescript/module/media-flight/MediaFlightHost.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/MediaFlightHost.web.d.ts +1 -1
- package/lib/typescript/module/media-flight/MediaFlightHost.web.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/MediaFlightLayer.web.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/MediaSurface.d.ts +13 -2
- package/lib/typescript/module/media-flight/MediaSurface.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/constants.d.ts +20 -0
- package/lib/typescript/module/media-flight/constants.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/media-node.web.d.ts +17 -3
- package/lib/typescript/module/media-flight/media-node.web.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/store.d.ts +4 -1
- package/lib/typescript/module/media-flight/store.d.ts.map +1 -1
- package/lib/typescript/module/media-flight/types.d.ts +49 -0
- package/lib/typescript/module/media-flight/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/media-flight/MediaFlightHost.tsx +2 -0
- package/src/media-flight/MediaFlightHost.web.tsx +3 -2
- package/src/media-flight/MediaFlightLayer.web.tsx +58 -38
- package/src/media-flight/MediaSurface.tsx +62 -8
- package/src/media-flight/constants.ts +22 -0
- package/src/media-flight/media-node.web.ts +48 -10
- package/src/media-flight/store.ts +4 -1
- package/src/media-flight/types.ts +51 -0
package/docs/media-flight.mdx
CHANGED
|
@@ -135,7 +135,10 @@ leaves the DOM. What that buys is **not** the unbind beside it: expo-video
|
|
|
135
135
|
answers a null player with `removeAttribute('src'); load()`, and the media
|
|
136
136
|
element load algorithm pauses WITHOUT firing `pause`, so the outgoing element
|
|
137
137
|
goes quiet and its removal mirrors nothing. Unbinding alone would not help —
|
|
138
|
-
`unmountVideoView` never clears the `onpause` it installed
|
|
138
|
+
`unmountVideoView` never clears the `onpause` it installed
|
|
139
|
+
(`scripts/probe-expo-video-listener-leak.mjs` measures that upstream defect
|
|
140
|
+
against expo-video's own class, and confirms the fix it is missing would close
|
|
141
|
+
it). Measured in real
|
|
139
142
|
Chrome with controls, and against real builds: without that commit the
|
|
140
143
|
destination ends stopped, with it playing and in position.
|
|
141
144
|
|
|
@@ -274,6 +277,79 @@ about the call site says which one you got.
|
|
|
274
277
|
nothing can want it back — no claim and no flight live for that id — which is
|
|
275
278
|
a fact the registry reads rather than a timeout it guesses.
|
|
276
279
|
|
|
280
|
+
### Paint the video yourself
|
|
281
|
+
|
|
282
|
+
`MediaFlightHost` mounts a `VideoView` with the handful of props Bloom knows
|
|
283
|
+
about. That is not enough the moment a consumer needs something only its OWN
|
|
284
|
+
element can give it — a `ref` for `startPictureInPicture()` or
|
|
285
|
+
`enterFullscreen()`, expo-video's picture-in-picture callbacks,
|
|
286
|
+
`onFirstFrameRender`, anything expo-video adds next. Measured in a consuming
|
|
287
|
+
app: adopting the host without this left a picture-in-picture BUTTON on screen
|
|
288
|
+
whose ref was attached to nothing. It rendered, it was pressable, and it did
|
|
289
|
+
nothing, silently.
|
|
290
|
+
|
|
291
|
+
So build the element yourself and let Bloom decide only what it must:
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
<MediaFlightHost
|
|
295
|
+
id={mediaId}
|
|
296
|
+
content={{ kind: 'video', player }}
|
|
297
|
+
renderVideo={useCallback((props) => (
|
|
298
|
+
<VideoView
|
|
299
|
+
{...props} // player, style, contentFit
|
|
300
|
+
ref={videoViewRef}
|
|
301
|
+
allowsPictureInPicture={isWatched}
|
|
302
|
+
onFirstFrameRender={handleFirstFrame}
|
|
303
|
+
/>
|
|
304
|
+
), [isWatched, handleFirstFrame])}
|
|
305
|
+
/>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Three things about the props Bloom passes:
|
|
309
|
+
|
|
310
|
+
- **Spread `style`.** A DOM `<video>` is a replaced element: `inset: 0` with
|
|
311
|
+
`width/height: auto` paints it at its intrinsic 300×150 inside whatever box it
|
|
312
|
+
was given. Bloom's style carries the sizing.
|
|
313
|
+
- **Pass `player` straight through, including `null`.** Null means unbind now,
|
|
314
|
+
and expo-video answers it by emptying the source — which pauses the element
|
|
315
|
+
without an event, which is what stops an outgoing surface from pausing the one
|
|
316
|
+
the viewer just landed on.
|
|
317
|
+
- **Memoise the slot.** It is part of what a host publishes to the layer,
|
|
318
|
+
compared by identity.
|
|
319
|
+
|
|
320
|
+
All three fail silently and only in production, so Bloom says so in development
|
|
321
|
+
instead: a slot that changes identity five times warns once about `useCallback`,
|
|
322
|
+
and a media element that does not fill its wrapper warns once with both
|
|
323
|
+
rectangles. Neither is a gate — they are the three trap-doors of this contract
|
|
324
|
+
turned into three messages.
|
|
325
|
+
|
|
326
|
+
The flight itself never brings an element. Its claim on a shared node says only
|
|
327
|
+
WHERE the node lives — a flight that published its own render would swap a
|
|
328
|
+
consumer's element out for Bloom's and back again, which is two remounts in the
|
|
329
|
+
middle of the one operation whose whole point is that the element is never
|
|
330
|
+
rebuilt.
|
|
331
|
+
|
|
332
|
+
### What the slot proved about the mechanism
|
|
333
|
+
|
|
334
|
+
The slot exists because of picture-in-picture. What it FOUND is worth more.
|
|
335
|
+
|
|
336
|
+
Before it, a flight published a *render* of its own alongside its position — so
|
|
337
|
+
for the length of a leg the layer painted the media its own way. With Bloom's
|
|
338
|
+
own view that is invisible: rebuilding the element and not rebuilding it produce
|
|
339
|
+
exactly the same tree, the same props and the same picture. The moment a
|
|
340
|
+
consumer's element went through the same path, it stopped being invisible: the
|
|
341
|
+
element was swapped out at take-off and back at the landing, two remounts inside
|
|
342
|
+
the one operation whose entire purpose is that the element is never rebuilt, and
|
|
343
|
+
the original ended the flight disconnected.
|
|
344
|
+
|
|
345
|
+
**The abstraction was hiding the defect the abstraction existed to prevent.** No
|
|
346
|
+
sharper test found it; giving up ownership of the element did. That is why a
|
|
347
|
+
flight's claim on a shared node now says only WHERE the node lives, and why the
|
|
348
|
+
mutation that gives it a render back fails three identity tests by name.
|
|
349
|
+
|
|
350
|
+
Keep it that way. A claim that carries a render again will look like a
|
|
351
|
+
simplification and will pass everything except those three.
|
|
352
|
+
|
|
277
353
|
### The flight outranks every host
|
|
278
354
|
|
|
279
355
|
A destination that mounts mid-flight claims its id, and the layer keeps the node
|
|
@@ -28,6 +28,7 @@ function MediaFlightHost({
|
|
|
28
28
|
content,
|
|
29
29
|
style,
|
|
30
30
|
contentFit = 'cover',
|
|
31
|
+
renderVideo,
|
|
31
32
|
nativeControls = false,
|
|
32
33
|
accessibilityLabel,
|
|
33
34
|
surfaceType,
|
|
@@ -44,6 +45,7 @@ function MediaFlightHost({
|
|
|
44
45
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MediaSurface.MediaSurface, {
|
|
45
46
|
content: content,
|
|
46
47
|
contentFit: contentFit,
|
|
48
|
+
renderVideo: renderVideo,
|
|
47
49
|
nativeControls: nativeControls,
|
|
48
50
|
accessibilityLabel: accessibilityLabel,
|
|
49
51
|
surfaceType: surfaceType,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_reactNative","_MediaSurface","_store","_jsxRuntime","MediaFlightHost","id","content","style","contentFit","nativeControls","accessibilityLabel","surfaceType","pointerEvents","flightId","setNode","useCallback","node","registerAnchor","jsx","View","ref","children","MediaSurface","StyleSheet","absoluteFill","displayName"],"sourceRoot":"../../../src","sources":["media-flight/MediaFlightHost.tsx"],"mappings":";;;;;;AAaA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,aAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AAAyC,IAAAI,WAAA,GAAAJ,OAAA;AAjBzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAQO,SAASK,eAAeA,CAAC;EAC9BC,EAAE;EACFC,OAAO;EACPC,KAAK;EACLC,UAAU,GAAG,OAAO;EACpBC,cAAc,GAAG,KAAK;EACtBC,kBAAkB;EAClBC,WAAW;EACXC,aAAa;EACbC;AACoB,CAAC,EAAE;EACvB;EACA;EACA,MAAMC,OAAO,GAAG,IAAAC,kBAAW,EACxBC,IAAiB,IAAK,IAAAC,qBAAc,
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNative","_MediaSurface","_store","_jsxRuntime","MediaFlightHost","id","content","style","contentFit","renderVideo","nativeControls","accessibilityLabel","surfaceType","pointerEvents","flightId","setNode","useCallback","node","registerAnchor","jsx","View","ref","children","MediaSurface","StyleSheet","absoluteFill","displayName"],"sourceRoot":"../../../src","sources":["media-flight/MediaFlightHost.tsx"],"mappings":";;;;;;AAaA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,aAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AAAyC,IAAAI,WAAA,GAAAJ,OAAA;AAjBzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAQO,SAASK,eAAeA,CAAC;EAC9BC,EAAE;EACFC,OAAO;EACPC,KAAK;EACLC,UAAU,GAAG,OAAO;EACpBC,WAAW;EACXC,cAAc,GAAG,KAAK;EACtBC,kBAAkB;EAClBC,WAAW;EACXC,aAAa;EACbC;AACoB,CAAC,EAAE;EACvB;EACA;EACA,MAAMC,OAAO,GAAG,IAAAC,kBAAW,EACxBC,IAAiB,IAAK,IAAAC,qBAAc,EAACb,EAAE,EAAEY,IAAI,CAAC,EAC/C,CAACZ,EAAE,CACL,CAAC;EAED,oBACE,IAAAF,WAAA,CAAAgB,GAAA,EAACnB,YAAA,CAAAoB,IAAI;IAACC,GAAG,EAAEN,OAAQ;IAACR,KAAK,EAAEA,KAAM;IAACM,aAAa,EAAEA,aAAc;IAAAS,QAAA,eAC7D,IAAAnB,WAAA,CAAAgB,GAAA,EAAClB,aAAA,CAAAsB,YAAY;MACXjB,OAAO,EAAEA,OAAQ;MACjBE,UAAU,EAAEA,UAAW;MACvBC,WAAW,EAAEA,WAAY;MACzBC,cAAc,EAAEA,cAAe;MAC/BC,kBAAkB,EAAEA,kBAAmB;MACvCC,WAAW,EAAEA,WAAY;MACzBE,QAAQ,EAAEA,QAAS;MACnBP,KAAK,EAAEiB,uBAAU,CAACC;IAAa,CAChC;EAAC,CACE,CAAC;AAEX;AAEArB,eAAe,CAACsB,WAAW,GAAG,iBAAiB","ignoreList":[]}
|
|
@@ -30,6 +30,7 @@ function MediaFlightHost({
|
|
|
30
30
|
content,
|
|
31
31
|
style,
|
|
32
32
|
contentFit = 'cover',
|
|
33
|
+
renderVideo,
|
|
33
34
|
nativeControls = false,
|
|
34
35
|
accessibilityLabel,
|
|
35
36
|
pointerEvents,
|
|
@@ -45,10 +46,11 @@ function MediaFlightHost({
|
|
|
45
46
|
const render = (0, _react.useMemo)(() => ({
|
|
46
47
|
content,
|
|
47
48
|
contentFit,
|
|
49
|
+
renderVideo,
|
|
48
50
|
nativeControls,
|
|
49
51
|
accessibilityLabel,
|
|
50
52
|
flightId
|
|
51
|
-
}), [content, contentFit, nativeControls, accessibilityLabel, flightId]);
|
|
53
|
+
}), [content, contentFit, renderVideo, nativeControls, accessibilityLabel, flightId]);
|
|
52
54
|
const renderRef = (0, _react.useRef)(render);
|
|
53
55
|
|
|
54
56
|
// Declared FIRST so it runs first on mount: it seeds the ref the claim below
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_reactNative","_mediaNodeWeb","_store","_jsxRuntime","MediaFlightHost","id","content","style","contentFit","nativeControls","accessibilityLabel","pointerEvents","flightId","node","setNode","useState","setHost","useCallback","next","registerAnchor","render","useMemo","renderRef","useRef","useLayoutEffect","current","el","claimMediaNode","HOST_RANK","undefined","hasFlight","handOffFlight","releaseMediaNode","jsx","View","ref","displayName"],"sourceRoot":"../../../src","sources":["media-flight/MediaFlightHost.web.tsx"],"mappings":";;;;;;AAeA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,aAAA,GAAAF,OAAA;AAMA,IAAAG,MAAA,GAAAH,OAAA;AAAmE,IAAAI,WAAA,GAAAJ,OAAA;AAxBnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaO,SAASK,eAAeA,CAAC;EAC9BC,EAAE;EACFC,OAAO;EACPC,KAAK;EACLC,UAAU,GAAG,OAAO;EACpBC,cAAc,GAAG,KAAK;EACtBC,kBAAkB;EAClBC,aAAa;EACbC;AACoB,CAAC,EAAE;EACvB;EACA;EACA,MAAM,CAACC,IAAI,EAAEC,OAAO,CAAC,GAAG,IAAAC,eAAQ,EAAc,IAAI,CAAC;EAEnD,MAAMC,OAAO,GAAG,IAAAC,kBAAW,EACxBC,IAAiB,IAAK;IACrB,IAAAC,qBAAc,
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNative","_mediaNodeWeb","_store","_jsxRuntime","MediaFlightHost","id","content","style","contentFit","renderVideo","nativeControls","accessibilityLabel","pointerEvents","flightId","node","setNode","useState","setHost","useCallback","next","registerAnchor","render","useMemo","renderRef","useRef","useLayoutEffect","current","el","claimMediaNode","HOST_RANK","undefined","hasFlight","handOffFlight","releaseMediaNode","jsx","View","ref","displayName"],"sourceRoot":"../../../src","sources":["media-flight/MediaFlightHost.web.tsx"],"mappings":";;;;;;AAeA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,aAAA,GAAAF,OAAA;AAMA,IAAAG,MAAA,GAAAH,OAAA;AAAmE,IAAAI,WAAA,GAAAJ,OAAA;AAxBnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaO,SAASK,eAAeA,CAAC;EAC9BC,EAAE;EACFC,OAAO;EACPC,KAAK;EACLC,UAAU,GAAG,OAAO;EACpBC,WAAW;EACXC,cAAc,GAAG,KAAK;EACtBC,kBAAkB;EAClBC,aAAa;EACbC;AACoB,CAAC,EAAE;EACvB;EACA;EACA,MAAM,CAACC,IAAI,EAAEC,OAAO,CAAC,GAAG,IAAAC,eAAQ,EAAc,IAAI,CAAC;EAEnD,MAAMC,OAAO,GAAG,IAAAC,kBAAW,EACxBC,IAAiB,IAAK;IACrB,IAAAC,qBAAc,EAACf,EAAE,EAAEc,IAAI,CAAC;IACxBJ,OAAO,CAACI,IAAI,CAAC;EACf,CAAC,EACD,CAACd,EAAE,CACL,CAAC;EAED,MAAMgB,MAAM,GAAG,IAAAC,cAAO,EACpB,OAAO;IAAEhB,OAAO;IAAEE,UAAU;IAAEC,WAAW;IAAEC,cAAc;IAAEC,kBAAkB;IAAEE;EAAS,CAAC,CAAC,EAC1F,CAACP,OAAO,EAAEE,UAAU,EAAEC,WAAW,EAAEC,cAAc,EAAEC,kBAAkB,EAAEE,QAAQ,CACjF,CAAC;EACD,MAAMU,SAAS,GAAG,IAAAC,aAAM,EAACH,MAAM,CAAC;;EAEhC;EACA;EACA;EACA;EACA,IAAAI,sBAAe,EAAC,MAAM;IACpBF,SAAS,CAACG,OAAO,GAAGL,MAAM;IAC1B,MAAMM,EAAE,GAAGb,IAAqC;IAChD,IAAIa,EAAE,KAAK,IAAI,EAAE,IAAAC,4BAAc,EAACvB,EAAE,EAAEsB,EAAE,EAAEE,uBAAS,EAAER,MAAM,CAAC;EAC5D,CAAC,EAAE,CAAChB,EAAE,EAAES,IAAI,EAAEO,MAAM,CAAC,CAAC;;EAEtB;EACA;EACA,IAAAI,sBAAe,EAAC,MAAM;IACpB,MAAME,EAAE,GAAGb,IAAqC;IAChD,IAAIa,EAAE,KAAK,IAAI,EAAE,OAAOG,SAAS;IACjC,IAAAF,4BAAc,EAACvB,EAAE,EAAEsB,EAAE,EAAEE,uBAAS,EAAEN,SAAS,CAACG,OAAO,CAAC;IACpD;IACA;IACA;IACA;IACA;IACA,IAAI,IAAAK,gBAAS,EAAC1B,EAAE,CAAC,EAAE,IAAA2B,oBAAa,EAAC3B,EAAE,CAAC;IACpC,OAAO,MAAM,IAAA4B,8BAAgB,EAAC5B,EAAE,EAAEsB,EAAE,EAAEE,uBAAS,CAAC;EAClD,CAAC,EAAE,CAACxB,EAAE,EAAES,IAAI,CAAC,CAAC;EAEd,oBAAO,IAAAX,WAAA,CAAA+B,GAAA,EAAClC,YAAA,CAAAmC,IAAI;IAACC,GAAG,EAAEnB,OAAQ;IAACV,KAAK,EAAEA,KAAM;IAACK,aAAa,EAAEA;EAAc,CAAE,CAAC;AAC3E;AAEAR,eAAe,CAACiC,WAAW,GAAG,iBAAiB","ignoreList":[]}
|
|
@@ -8,6 +8,7 @@ var _react = require("react");
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _reactDom = require("react-dom");
|
|
10
10
|
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
|
|
11
|
+
var _constants = require("./constants.js");
|
|
11
12
|
var _index = require("../overlay/index.js");
|
|
12
13
|
var _indexWeb = require("../portal/index.web.js");
|
|
13
14
|
var _MediaSurface = require("./MediaSurface.js");
|
|
@@ -74,19 +75,59 @@ function SharedMediaNode({
|
|
|
74
75
|
const {
|
|
75
76
|
content,
|
|
76
77
|
contentFit,
|
|
78
|
+
renderVideo,
|
|
77
79
|
nativeControls,
|
|
78
80
|
accessibilityLabel,
|
|
79
81
|
flightId
|
|
80
82
|
} = node.render;
|
|
83
|
+
|
|
84
|
+
// DOES THE MEDIA ACTUALLY FILL ITS BOX?
|
|
85
|
+
//
|
|
86
|
+
// Bloom hands a `renderVideo` slot a style that sizes a replaced element, and
|
|
87
|
+
// a slot that forgets to spread it paints a 300x150 `<video>` inside whatever
|
|
88
|
+
// box it was given — correct in every other respect, wrong on screen, and
|
|
89
|
+
// reported by nothing. That defect shipped once from Bloom's own view and
|
|
90
|
+
// cost a day to find; a consumer writing the slot can reproduce it in a line.
|
|
91
|
+
//
|
|
92
|
+
// Measured one frame after the commit, because layout has to have happened.
|
|
93
|
+
(0, _react.useEffect)(() => {
|
|
94
|
+
if (process.env.NODE_ENV === 'production' || renderVideo === undefined) return undefined;
|
|
95
|
+
const frame = requestAnimationFrame(() => warnIfNotFilling(node.wrapper));
|
|
96
|
+
return () => cancelAnimationFrame(frame);
|
|
97
|
+
}, [node.wrapper, renderVideo]);
|
|
81
98
|
return /*#__PURE__*/(0, _reactDom.createPortal)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_MediaSurface.MediaSurface, {
|
|
82
99
|
content: content,
|
|
83
100
|
contentFit: contentFit,
|
|
101
|
+
renderVideo: renderVideo,
|
|
84
102
|
nativeControls: nativeControls,
|
|
85
103
|
accessibilityLabel: accessibilityLabel,
|
|
86
104
|
flightId: flightId,
|
|
87
105
|
style: _reactNative.StyleSheet.absoluteFill
|
|
88
106
|
}), node.wrapper);
|
|
89
107
|
}
|
|
108
|
+
let hasWarnedAboutFill = false;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* One warning per module lifetime, and none in production — same mechanism as
|
|
112
|
+
* `warnExpoVideoUnavailable`.
|
|
113
|
+
*
|
|
114
|
+
* It compares the media element with the WRAPPER, not with a fixed size: the
|
|
115
|
+
* invariant is "the media fills the box it was given", and a box that happens
|
|
116
|
+
* to be 300x150 is not a defect.
|
|
117
|
+
*/
|
|
118
|
+
function warnIfNotFilling(wrapper) {
|
|
119
|
+
if (hasWarnedAboutFill || !wrapper.isConnected) return;
|
|
120
|
+
const media = wrapper.querySelector('video');
|
|
121
|
+
if (media === null) return;
|
|
122
|
+
const box = wrapper.getBoundingClientRect();
|
|
123
|
+
const painted = media.getBoundingClientRect();
|
|
124
|
+
if (box.width === 0 || box.height === 0) return;
|
|
125
|
+
const off = Math.abs(painted.width - box.width) > _constants.SLOT_FILL_TOLERANCE_PX || Math.abs(painted.height - box.height) > _constants.SLOT_FILL_TOLERANCE_PX;
|
|
126
|
+
if (!off) return;
|
|
127
|
+
hasWarnedAboutFill = true;
|
|
128
|
+
// eslint-disable-next-line no-console
|
|
129
|
+
console.warn(`[Bloom] A \`renderVideo\` element is ${Math.round(painted.width)}x${Math.round(painted.height)} ` + `inside a ${Math.round(box.width)}x${Math.round(box.height)} box. A DOM \`<video>\` is a ` + 'REPLACED element: without an explicit size it paints at its intrinsic 300x150 whatever ' + 'its inset says. Spread the `style` Bloom passes the slot.');
|
|
130
|
+
}
|
|
90
131
|
|
|
91
132
|
/**
|
|
92
133
|
* One flying surface. See `MediaFlightLayer.tsx` for why the size is animated
|
|
@@ -131,21 +172,12 @@ function MediaFlightSurface({
|
|
|
131
172
|
top: to.y,
|
|
132
173
|
borderRadius: cornerRadius
|
|
133
174
|
}, boxStyle];
|
|
134
|
-
const render = (0, _react.useMemo)(() => ({
|
|
135
|
-
content,
|
|
136
|
-
contentFit,
|
|
137
|
-
nativeControls: false,
|
|
138
|
-
accessibilityLabel: undefined,
|
|
139
|
-
// A flying surface never hands off to itself.
|
|
140
|
-
flightId: undefined
|
|
141
|
-
}), [content, contentFit]);
|
|
142
175
|
|
|
143
176
|
// The shared node is already painting this media. The flight is then a BOX
|
|
144
177
|
// that borrows it for the length of the leg, never a second copy.
|
|
145
178
|
if (shared) return /*#__PURE__*/(0, _jsxRuntime.jsx)(FlyingSharedNode, {
|
|
146
179
|
id: id,
|
|
147
|
-
style: box
|
|
148
|
-
render: render
|
|
180
|
+
style: box
|
|
149
181
|
});
|
|
150
182
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_MediaSurface.MediaSurface, {
|
|
151
183
|
content: content,
|
|
@@ -174,27 +206,20 @@ function MediaFlightSurface({
|
|
|
174
206
|
*/
|
|
175
207
|
function FlyingSharedNode({
|
|
176
208
|
id,
|
|
177
|
-
style
|
|
178
|
-
render
|
|
209
|
+
style
|
|
179
210
|
}) {
|
|
180
211
|
const [node, setNode] = (0, _react.useState)(null);
|
|
181
212
|
const setBox = (0, _react.useCallback)(next => setNode(next), []);
|
|
182
|
-
const renderRef = (0, _react.useRef)(render);
|
|
183
|
-
|
|
184
|
-
// Declared first so it runs first on mount, and afterwards is what pushes
|
|
185
|
-
// prop changes into a live claim IN PLACE — releasing and re-claiming would
|
|
186
|
-
// move the node away and back, and a move away is a removal.
|
|
187
|
-
(0, _react.useLayoutEffect)(() => {
|
|
188
|
-
renderRef.current = render;
|
|
189
|
-
const el = node;
|
|
190
|
-
if (el !== null) (0, _mediaNodeWeb.claimMediaNode)(id, el, _mediaNodeWeb.FLIGHT_RANK, render);
|
|
191
|
-
}, [id, node, render]);
|
|
192
213
|
|
|
193
|
-
//
|
|
214
|
+
// A POSITION-ONLY claim: it says where the node lives for the length of the
|
|
215
|
+
// leg and nothing about what is painted in it. A flight that published a
|
|
216
|
+
// render of its own would replace the hosts' — and swap a consumer's own
|
|
217
|
+
// element out and back, which is two remounts in the middle of the one
|
|
218
|
+
// operation whose whole point is that the element is never rebuilt.
|
|
194
219
|
(0, _react.useLayoutEffect)(() => {
|
|
195
220
|
const el = node;
|
|
196
221
|
if (el === null) return undefined;
|
|
197
|
-
(0, _mediaNodeWeb.claimMediaNode)(id, el, _mediaNodeWeb.FLIGHT_RANK
|
|
222
|
+
(0, _mediaNodeWeb.claimMediaNode)(id, el, _mediaNodeWeb.FLIGHT_RANK);
|
|
198
223
|
return () => (0, _mediaNodeWeb.releaseMediaNode)(id, el, _mediaNodeWeb.FLIGHT_RANK);
|
|
199
224
|
}, [id, node]);
|
|
200
225
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_reactNative","_reactDom","_reactNativeReanimated","_interopRequireWildcard","_index","_indexWeb","_MediaSurface","_mediaNodeWeb","_store","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","MediaFlightLayer","flights","useSyncExternalStore","subscribeToFlights","getFlights","nodes","subscribeToMediaNodes","getMediaNodes","length","jsxs","Fragment","children","map","node","jsx","SharedMediaNode","id","Portal","OverlayRoot","flight","MediaFlightSurface","shared","some","displayName","content","contentFit","nativeControls","accessibilityLabel","flightId","render","createPortal","MediaSurface","style","StyleSheet","absoluteFill","
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNative","_reactDom","_reactNativeReanimated","_interopRequireWildcard","_constants","_index","_indexWeb","_MediaSurface","_mediaNodeWeb","_store","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","MediaFlightLayer","flights","useSyncExternalStore","subscribeToFlights","getFlights","nodes","subscribeToMediaNodes","getMediaNodes","length","jsxs","Fragment","children","map","node","jsx","SharedMediaNode","id","Portal","OverlayRoot","flight","MediaFlightSurface","shared","some","displayName","content","contentFit","renderVideo","nativeControls","accessibilityLabel","flightId","render","useEffect","process","env","NODE_ENV","undefined","frame","requestAnimationFrame","warnIfNotFilling","wrapper","cancelAnimationFrame","createPortal","MediaSurface","style","StyleSheet","absoluteFill","hasWarnedAboutFill","isConnected","media","querySelector","box","getBoundingClientRect","painted","width","height","off","Math","abs","SLOT_FILL_TOLERANCE_PX","console","warn","round","from","to","progress","cornerRadius","surfaceType","unbinding","notifySurfaceMounted","originX","x","originY","y","boxStyle","useAnimatedStyle","transform","translateX","interpolate","value","translateY","styles","left","top","borderRadius","FlyingSharedNode","detached","pointerEvents","setNode","useState","setBox","useCallback","next","useLayoutEffect","el","claimMediaNode","FLIGHT_RANK","releaseMediaNode","View","ref","create","position","overflow"],"sourceRoot":"../../../src","sources":["media-flight/MediaFlightLayer.web.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -10,6 +10,7 @@ var _react = require("react");
|
|
|
10
10
|
var _reactNative = require("react-native");
|
|
11
11
|
var _expoImage = require("expo-image");
|
|
12
12
|
var _reactNativeReanimated = _interopRequireDefault(require("react-native-reanimated"));
|
|
13
|
+
var _constants = require("./constants.js");
|
|
13
14
|
var _store = require("./store.js");
|
|
14
15
|
var _expoVideoModule = require("./expo-video-module.js");
|
|
15
16
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -64,6 +65,7 @@ const MediaSurface = exports.MediaSurface = /*#__PURE__*/(0, _react.memo)(functi
|
|
|
64
65
|
style,
|
|
65
66
|
contentFit = 'contain',
|
|
66
67
|
surfaceType = 'textureView',
|
|
68
|
+
renderVideo,
|
|
67
69
|
nativeControls = false,
|
|
68
70
|
accessibilityLabel,
|
|
69
71
|
pointerEvents,
|
|
@@ -75,6 +77,18 @@ const MediaSurface = exports.MediaSurface = /*#__PURE__*/(0, _react.memo)(functi
|
|
|
75
77
|
// supports.
|
|
76
78
|
const [mountedSurfaceType] = (0, _react.useState)(surfaceType);
|
|
77
79
|
|
|
80
|
+
// A slot rebuilt on every render republishes this surface to the layer on
|
|
81
|
+
// every render, which nothing at runtime reports — the picture is correct and
|
|
82
|
+
// the app is doing work in proportion to how often its rows re-render. The
|
|
83
|
+
// counter lives in an effect rather than in render: a render-phase ref write
|
|
84
|
+
// makes the React Compiler bail on the whole component.
|
|
85
|
+
const slotChurn = (0, _react.useRef)(0);
|
|
86
|
+
(0, _react.useEffect)(() => {
|
|
87
|
+
if (renderVideo === undefined) return;
|
|
88
|
+
slotChurn.current += 1;
|
|
89
|
+
if (slotChurn.current === _constants.SLOT_IDENTITY_CHURN_LIMIT) warnSlotNotMemoised();
|
|
90
|
+
}, [renderVideo]);
|
|
91
|
+
|
|
78
92
|
// Both arms report the same fact — "there is a picture here now" — because the
|
|
79
93
|
// destination of a flight can be either, and a caller should not have to know
|
|
80
94
|
// which one it wired. expo-video raises `onFirstFrameRender` from `loadeddata`
|
|
@@ -83,10 +97,11 @@ const MediaSurface = exports.MediaSurface = /*#__PURE__*/(0, _react.memo)(functi
|
|
|
83
97
|
if (flightId !== undefined) (0, _store.handOffFlight)(flightId);
|
|
84
98
|
}, [flightId]);
|
|
85
99
|
const still = content.kind === 'video' ? content.poster : content.uri;
|
|
86
|
-
// Loaded for the video arm only, and only when
|
|
87
|
-
// surface must never make an app resolve an optional
|
|
88
|
-
|
|
89
|
-
|
|
100
|
+
// Loaded for the video arm only, and only when Bloom is the one building the
|
|
101
|
+
// element — an image surface must never make an app resolve an optional
|
|
102
|
+
// native peer, and neither must a consumer that brought its own view.
|
|
103
|
+
const expoVideo = content.kind === 'video' && renderVideo === undefined ? (0, _expoVideoModule.loadExpoVideo)() : null;
|
|
104
|
+
if (content.kind === 'video' && renderVideo === undefined && expoVideo === null) {
|
|
90
105
|
// Degrade to the poster rather than to nothing: a black hole where a video
|
|
91
106
|
// should be reads as a broken app, a still frame reads as a video that has
|
|
92
107
|
// not started. The warning is what makes the difference visible to the
|
|
@@ -118,7 +133,13 @@ const MediaSurface = exports.MediaSurface = /*#__PURE__*/(0, _react.memo)(functi
|
|
|
118
133
|
,
|
|
119
134
|
onLoad: content.kind === 'video' ? undefined : reportLive,
|
|
120
135
|
...webDraggableProps
|
|
121
|
-
}), content.kind === 'video' &&
|
|
136
|
+
}), content.kind === 'video' && renderVideo !== undefined ? renderVideo({
|
|
137
|
+
player: detached ? null : content.player,
|
|
138
|
+
// The same style Bloom's own view gets, for the same reason: a
|
|
139
|
+
// replaced element that is not told its size paints at 300x150.
|
|
140
|
+
style: [_reactNative.StyleSheet.absoluteFill, styles.fillReplaced],
|
|
141
|
+
contentFit
|
|
142
|
+
}) : null, content.kind === 'video' && renderVideo === undefined && expoVideo !== null ? /*#__PURE__*/(0, _jsxRuntime.jsx)(expoVideo.VideoView, {
|
|
122
143
|
player: detached ? null : content.player,
|
|
123
144
|
contentFit: contentFit,
|
|
124
145
|
surfaceType: mountedSurfaceType,
|
|
@@ -141,6 +162,18 @@ const MediaSurface = exports.MediaSurface = /*#__PURE__*/(0, _react.memo)(functi
|
|
|
141
162
|
});
|
|
142
163
|
});
|
|
143
164
|
MediaSurface.displayName = 'MediaSurface';
|
|
165
|
+
let hasWarnedAboutSlotChurn = false;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* One warning per module lifetime, and none in production — same mechanism as
|
|
169
|
+
* `warnExpoVideoUnavailable`.
|
|
170
|
+
*/
|
|
171
|
+
function warnSlotNotMemoised() {
|
|
172
|
+
if (process.env.NODE_ENV === 'production' || hasWarnedAboutSlotChurn) return;
|
|
173
|
+
hasWarnedAboutSlotChurn = true;
|
|
174
|
+
// eslint-disable-next-line no-console
|
|
175
|
+
console.warn(`[Bloom] A \`renderVideo\` slot changed identity ${_constants.SLOT_IDENTITY_CHURN_LIMIT} times. ` + 'It is part of what a media host publishes to the flight layer and is compared by ' + 'identity, so a slot rebuilt on every render republishes the surface on every render. ' + 'Wrap it in `useCallback` with the props it actually reads.');
|
|
176
|
+
}
|
|
144
177
|
|
|
145
178
|
/**
|
|
146
179
|
* The STILL of a media item — a video's poster, or the image itself — and never
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_reactNative","_expoImage","_reactNativeReanimated","_interopRequireDefault","_store","_expoVideoModule","_jsxRuntime","e","__esModule","default","webDraggableProps","Platform","OS","draggable","MediaSurface","exports","memo","content","style","contentFit","surfaceType","nativeControls","accessibilityLabel","pointerEvents","flightId","detached","mountedSurfaceType","useState","
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNative","_expoImage","_reactNativeReanimated","_interopRequireDefault","_constants","_store","_expoVideoModule","_jsxRuntime","e","__esModule","default","webDraggableProps","Platform","OS","draggable","MediaSurface","exports","memo","content","style","contentFit","surfaceType","renderVideo","nativeControls","accessibilityLabel","pointerEvents","flightId","detached","mountedSurfaceType","useState","slotChurn","useRef","useEffect","undefined","current","SLOT_IDENTITY_CHURN_LIMIT","warnSlotNotMemoised","reportLive","useCallback","handOffFlight","still","kind","poster","uri","expoVideo","loadExpoVideo","warnExpoVideoUnavailable","jsxs","View","styles","box","children","jsx","Image","source","StyleSheet","absoluteFill","transition","onLoad","player","fillReplaced","VideoView","onFirstFrameRender","displayName","hasWarnedAboutSlotChurn","process","env","NODE_ENV","console","warn","MediaPoster","EmptyMediaSurface","empty","create","width","height","overflow","backgroundColor"],"sourceRoot":"../../../src","sources":["media-flight/MediaSurface.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.SURFACE_MOUNT_TIMEOUT_MS = void 0;
|
|
6
|
+
exports.SURFACE_MOUNT_TIMEOUT_MS = exports.SLOT_IDENTITY_CHURN_LIMIT = exports.SLOT_FILL_TOLERANCE_PX = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* How long `flyTo` will wait for `<MediaFlightLayer>` to commit the surface
|
|
9
9
|
* before letting the caller carry on regardless (ms).
|
|
@@ -36,4 +36,26 @@ const SURFACE_MOUNT_TIMEOUT_MS = exports.SURFACE_MOUNT_TIMEOUT_MS = 250;
|
|
|
36
36
|
* `flyBack(id)` and `releaseFlight(id)` are the escape hatches, and they are
|
|
37
37
|
* the caller's to use.
|
|
38
38
|
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* How many times a video slot may change identity before Bloom says so.
|
|
42
|
+
*
|
|
43
|
+
* `renderVideo` is part of what a host publishes to the layer and is compared
|
|
44
|
+
* by identity, so an unmemoised slot republishes on every render of the row it
|
|
45
|
+
* lives in — silently, and only under load. Five is well past any legitimate
|
|
46
|
+
* cause (a mute toggle, a fit change) and far below the churn of a slot rebuilt
|
|
47
|
+
* per render in a scrolling feed.
|
|
48
|
+
*/
|
|
49
|
+
const SLOT_IDENTITY_CHURN_LIMIT = exports.SLOT_IDENTITY_CHURN_LIMIT = 5;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* How far a media element may sit from the box it is supposed to fill, in px,
|
|
53
|
+
* before Bloom says so.
|
|
54
|
+
*
|
|
55
|
+
* Two, not zero: subpixel layout and a box mid-animation both land within a
|
|
56
|
+
* pixel, and the defect this catches is not subtle — a `<video>` that never
|
|
57
|
+
* received Bloom's sizing style paints at its intrinsic 300x150 inside whatever
|
|
58
|
+
* box it was given.
|
|
59
|
+
*/
|
|
60
|
+
const SLOT_FILL_TOLERANCE_PX = exports.SLOT_FILL_TOLERANCE_PX = 2;
|
|
39
61
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["SURFACE_MOUNT_TIMEOUT_MS","exports"],"sourceRoot":"../../../src","sources":["media-flight/constants.ts"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,wBAAwB,GAAAC,OAAA,CAAAD,wBAAA,GAAG,GAAG;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["SURFACE_MOUNT_TIMEOUT_MS","exports","SLOT_IDENTITY_CHURN_LIMIT","SLOT_FILL_TOLERANCE_PX"],"sourceRoot":"../../../src","sources":["media-flight/constants.ts"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,wBAAwB,GAAAC,OAAA,CAAAD,wBAAA,GAAG,GAAG;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAME,yBAAyB,GAAAD,OAAA,CAAAC,yBAAA,GAAG,CAAC;;AAE1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,sBAAsB,GAAAF,OAAA,CAAAE,sBAAA,GAAG,CAAC","ignoreList":[]}
|
|
@@ -128,20 +128,43 @@ function recordFor(id, render) {
|
|
|
128
128
|
const reg = registry();
|
|
129
129
|
let record = reg.nodes.get(id);
|
|
130
130
|
if (!record) {
|
|
131
|
+
// A position-only claim can be the first one in: a flight can take off
|
|
132
|
+
// before the host it flies from has committed. `EMPTY_RENDER` paints
|
|
133
|
+
// nothing until a host says what, which is the honest state.
|
|
131
134
|
record = {
|
|
132
135
|
wrapper: makeWrapper(),
|
|
133
136
|
claims: [],
|
|
134
|
-
render
|
|
137
|
+
render: render ?? EMPTY_RENDER
|
|
135
138
|
};
|
|
136
139
|
reg.nodes.set(id, record);
|
|
137
140
|
}
|
|
138
141
|
return record;
|
|
139
142
|
}
|
|
140
143
|
|
|
144
|
+
/** Nothing to paint yet. Replaced by the first host claim that arrives. */
|
|
145
|
+
const EMPTY_RENDER = {
|
|
146
|
+
content: {
|
|
147
|
+
uri: ''
|
|
148
|
+
},
|
|
149
|
+
contentFit: 'cover',
|
|
150
|
+
renderVideo: undefined,
|
|
151
|
+
nativeControls: false,
|
|
152
|
+
accessibilityLabel: undefined,
|
|
153
|
+
flightId: undefined
|
|
154
|
+
};
|
|
155
|
+
|
|
141
156
|
/** The claim that currently holds the node: highest rank, then most recent. */
|
|
142
157
|
function topClaim(record) {
|
|
158
|
+
return pick(record.claims);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** The highest-ranked claim that says what to PAINT. See `MediaNodeClaim.render`. */
|
|
162
|
+
function topRender(record) {
|
|
163
|
+
return pick(record.claims.filter(claim => claim.render !== undefined));
|
|
164
|
+
}
|
|
165
|
+
function pick(claims) {
|
|
143
166
|
let best = null;
|
|
144
|
-
for (const claim of
|
|
167
|
+
for (const claim of claims) {
|
|
145
168
|
if (best === null || claim.rank > best.rank || claim.rank === best.rank && claim.seq > best.seq) {
|
|
146
169
|
best = claim;
|
|
147
170
|
}
|
|
@@ -165,6 +188,7 @@ function place(record) {
|
|
|
165
188
|
}
|
|
166
189
|
function sameRender(a, b) {
|
|
167
190
|
if (a.contentFit !== b.contentFit) return false;
|
|
191
|
+
if (a.renderVideo !== b.renderVideo) return false;
|
|
168
192
|
if (a.nativeControls !== b.nativeControls) return false;
|
|
169
193
|
if (a.accessibilityLabel !== b.accessibilityLabel) return false;
|
|
170
194
|
if (a.flightId !== b.flightId) return false;
|
|
@@ -179,7 +203,7 @@ function sameRender(a, b) {
|
|
|
179
203
|
function publish(reg) {
|
|
180
204
|
const next = [];
|
|
181
205
|
for (const [id, record] of reg.nodes) {
|
|
182
|
-
record.render =
|
|
206
|
+
record.render = topRender(record)?.render ?? record.render;
|
|
183
207
|
next.push({
|
|
184
208
|
id,
|
|
185
209
|
wrapper: record.wrapper,
|
|
@@ -212,9 +236,8 @@ function claimMediaNode(id, el, rank, render) {
|
|
|
212
236
|
const record = recordFor(id, render);
|
|
213
237
|
const existing = record.claims.find(claim => claim.el === el && claim.rank === rank);
|
|
214
238
|
if (existing !== undefined) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
239
|
+
const unchanged = existing.render === render || existing.render !== undefined && render !== undefined && sameRender(existing.render, render);
|
|
240
|
+
if (unchanged && record.wrapper.parentElement === topClaim(record)?.el) return;
|
|
218
241
|
existing.render = render;
|
|
219
242
|
} else {
|
|
220
243
|
reg.seq += 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_store","require","HOST_RANK","exports","FLIGHT_RANK","registry","globalThis","__oxyhq_bloom_media_nodes__","nodes","Map","listeners","Set","snapshot","holder","seq","HOLDER_ID","reg","document","isConnected","existing","getElementById","created","createElement","id","style","cssText","setAttribute","body","appendChild","makeWrapper","wrapper","recordFor","render","record","get","claims","set","
|
|
1
|
+
{"version":3,"names":["_store","require","HOST_RANK","exports","FLIGHT_RANK","registry","globalThis","__oxyhq_bloom_media_nodes__","nodes","Map","listeners","Set","snapshot","holder","seq","HOLDER_ID","reg","document","isConnected","existing","getElementById","created","createElement","id","style","cssText","setAttribute","body","appendChild","makeWrapper","wrapper","recordFor","render","record","get","claims","EMPTY_RENDER","set","content","uri","contentFit","renderVideo","undefined","nativeControls","accessibilityLabel","flightId","topClaim","pick","topRender","filter","claim","best","rank","place","target","el","parentElement","sameRender","a","b","x","y","kind","player","poster","publish","next","push","previous","unchanged","length","every","view","i","candidate","listener","claimMediaNode","find","releaseMediaNode","before","hasFlight","delete","remove","hasMediaNode","subscribeToMediaNodes","add","getMediaNodes","resetMediaNodes","values","clear"],"sourceRoot":"../../../src","sources":["media-flight/media-node.web.ts"],"mappings":"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","ignoreList":[]}
|