@swiftbrowser/react 0.17.5 → 0.17.7
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/README.md +20 -6
- package/dist/components/controls.d.ts +2 -0
- package/dist/components/controls.d.ts.map +1 -1
- package/dist/components/images.d.ts +7 -2
- package/dist/components/images.d.ts.map +1 -1
- package/dist/components/media.d.ts +38 -3
- package/dist/components/media.d.ts.map +1 -1
- package/dist/index.js +104 -19
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -397,19 +397,33 @@ systemName="star.fill" /> }`) come back from `resolveSymbol` and draw with
|
|
|
397
397
|
`drawSymbol` at a point, under the context's transform and opacity; they are
|
|
398
398
|
real views laid over the canvas, so they draw above its other commands. `useAVPlayer(url)` is an `AVPlayer` (play, pause, seek,
|
|
399
399
|
mute, volume, rate) that `VideoPlayer` shows in the page's `<video>`; the
|
|
400
|
-
position is read or observed without re-rendering.
|
|
400
|
+
position is read or observed without re-rendering. A player shown by no
|
|
401
|
+
view plays nothing, so an audio app (a playlist, a podcast) puts an
|
|
402
|
+
`<AudioPlayer player={…} />` somewhere that stays mounted: the player at
|
|
403
|
+
no size, out of the way of taps, playing on wherever the screens go.
|
|
404
|
+
`new AVQueuePlayer(urls)` plays its items one after another (`items()`,
|
|
405
|
+
`advanceToNextItem`, `insert`, `remove`), at the same rate, and pauses
|
|
406
|
+
after the last. What plays goes on the lock screen and the media keys
|
|
407
|
+
through the browser's own `navigator.mediaSession`, which the native app
|
|
408
|
+
has too (`@swiftbrowser/native`, "Now playing"). `Slider`'s `onEditingChanged` says when a drag begins and
|
|
409
|
+
ends, so a scrubber bound to the position can stop following it while the
|
|
410
|
+
thumb is held.
|
|
401
411
|
|
|
402
412
|
An image is inert, as a SwiftUI image is. `<AsyncImage url={…}
|
|
403
413
|
webInteractions />` gives a remote picture the browser's own image
|
|
404
414
|
interactions back: a long press's Save / Share / Copy on iOS, dragging it
|
|
405
415
|
out of the page, the right-click menu. Use it on an image with no tap,
|
|
406
416
|
gesture or context menu of its own. `placeholder` shows until the image
|
|
407
|
-
loaded
|
|
408
|
-
`failure` when it could not, and `loadingIndicator` goes over the
|
|
417
|
+
loaded, `failure` when it could not, and `loadingIndicator` goes over the
|
|
409
418
|
placeholder once a load has run for `loadingIndicatorDelay` ms (300 by
|
|
410
419
|
default): a `<ProgressView />` for a big picture on a slow connection,
|
|
411
|
-
nothing for one that comes quickly or from the cache.
|
|
412
|
-
|
|
420
|
+
nothing for one that comes quickly or from the cache. The image's
|
|
421
|
+
modifiers apply in every phase, as a SwiftUI `AsyncImage`'s do: a
|
|
422
|
+
thumbnail with `frame={{ width: 72, height: 48 }}` keeps its box while it
|
|
423
|
+
loads (with no placeholder, an empty one), so the text beside it does not
|
|
424
|
+
move when the picture arrives; a `placeholder` at the picture's aspect
|
|
425
|
+
ratio does the same for a picture drawn at its own shape. All three show
|
|
426
|
+
in a SwiftBrowser Native app too.
|
|
413
427
|
|
|
414
428
|
`keyboardType`, `textContentType`, `textInputAutocapitalization` and
|
|
415
429
|
`autocorrectionDisabled` are SwiftUI's text input hints, for the field they
|
|
@@ -595,7 +609,7 @@ read with a hook). Props, callbacks and external stores need no bridging.
|
|
|
595
609
|
styles, `LabeledContent`, `Link`, `Color` as a view, shapes (built-in,
|
|
596
610
|
custom paths, `UnevenRoundedRectangle`, `ContainerRelativeShape`) with
|
|
597
611
|
fills, strokes and gradients, `Canvas`, `TimelineView`, `VideoPlayer`,
|
|
598
|
-
`Gauge`, `ProgressView`, Swift Charts.
|
|
612
|
+
`AudioPlayer` and `AVQueuePlayer`, `Gauge`, `ProgressView`, Swift Charts.
|
|
599
613
|
- **Controls**: `Button` (styles, roles, sizes), `Toggle`, `Picker`,
|
|
600
614
|
`Slider`, `Stepper`, `TextField` and `SecureField` (focus bindings, submit
|
|
601
615
|
labels), `TextEditor`, `DatePicker`, `ColorPicker`, `ShareLink`, `Menu`,
|
|
@@ -41,6 +41,8 @@ export declare function plainText(element: ReactElement): string;
|
|
|
41
41
|
export interface SliderProps extends ViewModifiers {
|
|
42
42
|
value: BindingValue<number>;
|
|
43
43
|
onChange?: (value: number) => void;
|
|
44
|
+
/** `onEditingChanged`: true as a drag begins, false as it ends (a scrubber stops following the position while the thumb is held). */
|
|
45
|
+
onEditingChanged?: (editing: boolean) => void;
|
|
44
46
|
/** `in: 0...1` */
|
|
45
47
|
range?: readonly [number, number];
|
|
46
48
|
step?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../../src/components/controls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqD,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACxH,OAAO,EAAY,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG5D,OAAO,EAAsE,KAAK,wBAAwB,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AASrJ,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;CAClC;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAoBpD;AAMD,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAKpD;AAMD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,CAAC,CAAC;CACR;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,CAAE,SAAQ,aAAa;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC9B,oGAAoG;IACpG,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAmB1D;AAiBD,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAKvD;AAiBD,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,kBAAkB;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,iBAAiB,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../../src/components/controls.tsx"],"names":[],"mappings":"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"}
|
|
@@ -6,9 +6,14 @@ export interface AsyncImageProps extends ViewModifiers {
|
|
|
6
6
|
url: string;
|
|
7
7
|
/** `.resizable()` on the loaded image. */
|
|
8
8
|
resizable?: boolean;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Shown until the image loaded (nothing by default). The image's modifiers
|
|
11
|
+
* (its frame, aspect ratio, corner radius) apply to it as they do to the
|
|
12
|
+
* picture, as a SwiftUI `AsyncImage`'s do in every phase: a framed image
|
|
13
|
+
* keeps its box while it loads, so the row beside it does not move.
|
|
14
|
+
*/
|
|
10
15
|
placeholder?: ReactNode;
|
|
11
|
-
/** Shown when the image failed to load (the placeholder by default). */
|
|
16
|
+
/** Shown when the image failed to load (the placeholder by default), under the same modifiers. */
|
|
12
17
|
failure?: ReactNode;
|
|
13
18
|
/**
|
|
14
19
|
* Shown over the placeholder once a load has run for `loadingIndicatorDelay`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/components/images.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAG9E,4DAA4D;AAC5D,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB
|
|
1
|
+
{"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/components/images.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAG9E,4DAA4D;AAC5D,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,kGAAkG;IAClG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAmBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,CA2D5D"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** `TimelineView
|
|
1
|
+
/** `TimelineView`, and `VideoPlayer` and `AudioPlayer` with `useAVPlayer` and `AVQueuePlayer`. */
|
|
2
2
|
import type { RendererEvent } from '@swiftbrowser/web/src/protocol';
|
|
3
3
|
import { type ReactNode } from 'react';
|
|
4
4
|
import { type ViewModifiers } from '../modifiers';
|
|
@@ -48,7 +48,7 @@ interface PlayerState {
|
|
|
48
48
|
* reports a second) re-renders nothing: read it or listen with `onTime`.
|
|
49
49
|
*/
|
|
50
50
|
export declare class AVPlayer {
|
|
51
|
-
|
|
51
|
+
protected state: PlayerState;
|
|
52
52
|
private listeners;
|
|
53
53
|
private timeListeners;
|
|
54
54
|
private time;
|
|
@@ -84,7 +84,31 @@ export declare class AVPlayer {
|
|
|
84
84
|
onTime(listener: (time: number) => void): () => void;
|
|
85
85
|
/** @internal The page's report for a view showing this player. */
|
|
86
86
|
handle(event: VideoEvent): void;
|
|
87
|
-
|
|
87
|
+
/** The item played to its end: a looping player plays on, the others pause (`actionAtItemEnd: .pause`; a queue advances). */
|
|
88
|
+
protected ended(): void;
|
|
89
|
+
protected update(changes: Partial<PlayerState>): void;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* `AVQueuePlayer`: a player with the items to play after the current one.
|
|
93
|
+
* When the current item ends the next plays (`actionAtItemEnd: .advance`),
|
|
94
|
+
* at the same rate; with none left the player pauses at the end. `items()`
|
|
95
|
+
* is the current item and the rest; `insert` and `remove` edit the rest.
|
|
96
|
+
*/
|
|
97
|
+
export declare class AVQueuePlayer extends AVPlayer {
|
|
98
|
+
private upcoming;
|
|
99
|
+
constructor(urls?: readonly string[], options?: {
|
|
100
|
+
loop?: boolean;
|
|
101
|
+
});
|
|
102
|
+
/** The current item (if any) and the items after it. */
|
|
103
|
+
items(): string[];
|
|
104
|
+
/** Plays the next item, or ends with nothing (`currentItem` null, paused) when there is none. */
|
|
105
|
+
advanceToNextItem(): void;
|
|
106
|
+
/** Adds `url` after `after` (an item in the queue), or at the end; `after` null puts it first, as `insert(_:after: nil)` does. */
|
|
107
|
+
insert(url: string, after?: string | null): void;
|
|
108
|
+
/** Removes a queued item, or the current one, which advances. */
|
|
109
|
+
remove(url: string): void;
|
|
110
|
+
removeAllItems(): void;
|
|
111
|
+
protected ended(): void;
|
|
88
112
|
}
|
|
89
113
|
/** A player kept for the component's life, re-rendering it when what it plays changes. */
|
|
90
114
|
export declare function useAVPlayer(url?: string | null, options?: {
|
|
@@ -101,5 +125,16 @@ export interface VideoPlayerProps extends ViewModifiers {
|
|
|
101
125
|
}
|
|
102
126
|
/** `VideoPlayer(player:)`: the page's `<video>` showing the player, or black without one. */
|
|
103
127
|
export declare function VideoPlayer(props: VideoPlayerProps): ReactNode;
|
|
128
|
+
/**
|
|
129
|
+
* A player that plays with no view: the element at no size and out of the
|
|
130
|
+
* way of taps, so an audio player (a playlist, a podcast)
|
|
131
|
+
* keeps playing wherever the app's screens go. Put one anywhere in the
|
|
132
|
+
* tree that stays mounted (the root), since a player shown by no
|
|
133
|
+
* `VideoPlayer` or `AudioPlayer` plays nothing. iOS plays a player's sound
|
|
134
|
+
* with no layer the same way.
|
|
135
|
+
*/
|
|
136
|
+
export declare function AudioPlayer({ player }: {
|
|
137
|
+
player: AVPlayer | null;
|
|
138
|
+
}): ReactNode;
|
|
104
139
|
export {};
|
|
105
140
|
//# sourceMappingURL=media.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/components/media.tsx"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/components/media.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -2998,7 +2998,18 @@ function Slider(props) {
|
|
|
2998
2998
|
children.push(/* @__PURE__ */ jsx(Fragment, { children: own.minimumValueLabel }, "min"), /* @__PURE__ */ jsx(Fragment, { children: own.maximumValueLabel }, "max"));
|
|
2999
2999
|
}
|
|
3000
3000
|
return applyModifiers(
|
|
3001
|
-
sb(
|
|
3001
|
+
sb(
|
|
3002
|
+
"slider",
|
|
3003
|
+
{ value, min, max, step: own.step ?? null, labels },
|
|
3004
|
+
{
|
|
3005
|
+
slide: (event) => {
|
|
3006
|
+
if (event.editing === true) own.onEditingChanged?.(true);
|
|
3007
|
+
setValue(event.value);
|
|
3008
|
+
if (event.editing === false) own.onEditingChanged?.(false);
|
|
3009
|
+
}
|
|
3010
|
+
},
|
|
3011
|
+
children.length ? children : void 0
|
|
3012
|
+
),
|
|
3002
3013
|
modifiers
|
|
3003
3014
|
);
|
|
3004
3015
|
}
|
|
@@ -3450,14 +3461,14 @@ function AsyncImage(props) {
|
|
|
3450
3461
|
return applyModifiers(sb("image", { ...imageProps(own), url: own.url, width: 0, height: 0 }), modifiers);
|
|
3451
3462
|
}
|
|
3452
3463
|
if (state === null) {
|
|
3453
|
-
const placeholder2 = own.placeholder ??
|
|
3454
|
-
|
|
3455
|
-
return /* @__PURE__ */ jsxs(ZStack, { children: [
|
|
3464
|
+
const placeholder2 = own.placeholder ?? /* @__PURE__ */ jsx(ZStack, {});
|
|
3465
|
+
const shown = slow && hasIndicator ? /* @__PURE__ */ jsxs(ZStack, { children: [
|
|
3456
3466
|
placeholder2,
|
|
3457
3467
|
own.loadingIndicator
|
|
3458
|
-
] });
|
|
3468
|
+
] }) : placeholder2;
|
|
3469
|
+
return applyModifiers(shown, modifiers);
|
|
3459
3470
|
}
|
|
3460
|
-
if (state === "failed") return own.failure ?? own.placeholder ??
|
|
3471
|
+
if (state === "failed") return applyModifiers(own.failure ?? own.placeholder ?? /* @__PURE__ */ jsx(ZStack, {}), modifiers);
|
|
3461
3472
|
return applyModifiers(sb("image", { ...imageProps(own), url: state.url, width: state.width, height: state.height }), modifiers);
|
|
3462
3473
|
}
|
|
3463
3474
|
function imageProps(own) {
|
|
@@ -4436,18 +4447,73 @@ class AVPlayer {
|
|
|
4436
4447
|
if (event.rate !== void 0) this.update({ rate: event.rate });
|
|
4437
4448
|
break;
|
|
4438
4449
|
case "ended":
|
|
4439
|
-
|
|
4450
|
+
this.ended();
|
|
4440
4451
|
break;
|
|
4441
4452
|
case "error":
|
|
4442
4453
|
this.update({ failed: event.message ?? "error", rate: 0 });
|
|
4443
4454
|
break;
|
|
4444
4455
|
}
|
|
4445
4456
|
}
|
|
4457
|
+
/** The item played to its end: a looping player plays on, the others pause (`actionAtItemEnd: .pause`; a queue advances). */
|
|
4458
|
+
ended() {
|
|
4459
|
+
if (!this.state.loop) this.update({ rate: 0 });
|
|
4460
|
+
}
|
|
4446
4461
|
update(changes) {
|
|
4447
4462
|
this.state = { ...this.state, ...changes };
|
|
4448
4463
|
for (const listener of this.listeners) listener();
|
|
4449
4464
|
}
|
|
4450
4465
|
}
|
|
4466
|
+
class AVQueuePlayer extends AVPlayer {
|
|
4467
|
+
upcoming = [];
|
|
4468
|
+
constructor(urls = [], options = {}) {
|
|
4469
|
+
super(urls[0] ?? null, options);
|
|
4470
|
+
this.upcoming = urls.slice(1);
|
|
4471
|
+
}
|
|
4472
|
+
/** The current item (if any) and the items after it. */
|
|
4473
|
+
items() {
|
|
4474
|
+
return this.url === null ? [...this.upcoming] : [this.url, ...this.upcoming];
|
|
4475
|
+
}
|
|
4476
|
+
/** Plays the next item, or ends with nothing (`currentItem` null, paused) when there is none. */
|
|
4477
|
+
advanceToNextItem() {
|
|
4478
|
+
const next = this.upcoming.shift();
|
|
4479
|
+
if (next === void 0) {
|
|
4480
|
+
this.replaceCurrentItem(null);
|
|
4481
|
+
this.update({ rate: 0 });
|
|
4482
|
+
return;
|
|
4483
|
+
}
|
|
4484
|
+
this.replaceCurrentItem(next);
|
|
4485
|
+
}
|
|
4486
|
+
/** Adds `url` after `after` (an item in the queue), or at the end; `after` null puts it first, as `insert(_:after: nil)` does. */
|
|
4487
|
+
insert(url, after = null) {
|
|
4488
|
+
if (after === null) {
|
|
4489
|
+
this.upcoming.unshift(url);
|
|
4490
|
+
} else {
|
|
4491
|
+
const at = this.upcoming.indexOf(after);
|
|
4492
|
+
if (at === -1) this.upcoming.push(url);
|
|
4493
|
+
else this.upcoming.splice(at + 1, 0, url);
|
|
4494
|
+
}
|
|
4495
|
+
this.update({});
|
|
4496
|
+
}
|
|
4497
|
+
/** Removes a queued item, or the current one, which advances. */
|
|
4498
|
+
remove(url) {
|
|
4499
|
+
if (url === this.url) {
|
|
4500
|
+
this.advanceToNextItem();
|
|
4501
|
+
return;
|
|
4502
|
+
}
|
|
4503
|
+
const at = this.upcoming.indexOf(url);
|
|
4504
|
+
if (at !== -1) this.upcoming.splice(at, 1);
|
|
4505
|
+
this.update({});
|
|
4506
|
+
}
|
|
4507
|
+
removeAllItems() {
|
|
4508
|
+
this.upcoming = [];
|
|
4509
|
+
this.replaceCurrentItem(null);
|
|
4510
|
+
this.update({ rate: 0 });
|
|
4511
|
+
}
|
|
4512
|
+
ended() {
|
|
4513
|
+
if (this.state.loop) return;
|
|
4514
|
+
this.advanceToNextItem();
|
|
4515
|
+
}
|
|
4516
|
+
}
|
|
4451
4517
|
function useAVPlayer(url = null, options = {}) {
|
|
4452
4518
|
const ref = useRef(null);
|
|
4453
4519
|
ref.current ??= new AVPlayer(url, options);
|
|
@@ -4458,16 +4524,8 @@ function useAVPlayer(url = null, options = {}) {
|
|
|
4458
4524
|
}, [player, url]);
|
|
4459
4525
|
return player;
|
|
4460
4526
|
}
|
|
4461
|
-
function
|
|
4462
|
-
|
|
4463
|
-
const player = own.player;
|
|
4464
|
-
const state = useSyncExternalStore(
|
|
4465
|
-
player?.subscribe ?? NO_SUBSCRIBE,
|
|
4466
|
-
() => player?.snapshot ?? null,
|
|
4467
|
-
() => player?.snapshot ?? null
|
|
4468
|
-
);
|
|
4469
|
-
if (!player || !state || !state.url) return applyModifiers(sb("color", { color: { r: 0, g: 0, b: 0, a: 1 } }), modifiers);
|
|
4470
|
-
const video = sb(
|
|
4527
|
+
function videoElement(player, state, options) {
|
|
4528
|
+
return sb(
|
|
4471
4529
|
"video",
|
|
4472
4530
|
{
|
|
4473
4531
|
url: state.url,
|
|
@@ -4476,13 +4534,24 @@ function VideoPlayer(props) {
|
|
|
4476
4534
|
volume: state.volume,
|
|
4477
4535
|
rate: state.rate > 0 ? state.rate : 1,
|
|
4478
4536
|
loop: state.loop,
|
|
4479
|
-
gravity:
|
|
4480
|
-
controls:
|
|
4537
|
+
gravity: options.gravity ?? "resizeAspect",
|
|
4538
|
+
controls: options.controls,
|
|
4481
4539
|
seek: state.seek,
|
|
4482
4540
|
...state.size ? { width: state.size.width, height: state.size.height } : {}
|
|
4483
4541
|
},
|
|
4484
4542
|
{ video: (event) => player.handle(event) }
|
|
4485
4543
|
);
|
|
4544
|
+
}
|
|
4545
|
+
function VideoPlayer(props) {
|
|
4546
|
+
const { own, modifiers } = splitProps(props);
|
|
4547
|
+
const player = own.player;
|
|
4548
|
+
const state = useSyncExternalStore(
|
|
4549
|
+
player?.subscribe ?? NO_SUBSCRIBE,
|
|
4550
|
+
() => player?.snapshot ?? null,
|
|
4551
|
+
() => player?.snapshot ?? null
|
|
4552
|
+
);
|
|
4553
|
+
if (!player || !state || !state.url) return applyModifiers(sb("color", { color: { r: 0, g: 0, b: 0, a: 1 } }), modifiers);
|
|
4554
|
+
const video = videoElement(player, { ...state, url: state.url }, { gravity: own.gravity, controls: own.controls ?? true });
|
|
4486
4555
|
if (own.videoOverlay === void 0) return applyModifiers(video, modifiers);
|
|
4487
4556
|
return applyModifiers(
|
|
4488
4557
|
sb("zstack", { alignment: "center" }, void 0, [/* @__PURE__ */ jsx(Fragment, { children: video }, "video"), /* @__PURE__ */ jsx(Fragment, { children: own.videoOverlay }, "overlay")]),
|
|
@@ -4491,6 +4560,20 @@ function VideoPlayer(props) {
|
|
|
4491
4560
|
}
|
|
4492
4561
|
const NO_SUBSCRIBE = () => () => {
|
|
4493
4562
|
};
|
|
4563
|
+
function AudioPlayer({ player }) {
|
|
4564
|
+
const state = useSyncExternalStore(
|
|
4565
|
+
player?.subscribe ?? NO_SUBSCRIBE,
|
|
4566
|
+
() => player?.snapshot ?? null,
|
|
4567
|
+
() => player?.snapshot ?? null
|
|
4568
|
+
);
|
|
4569
|
+
if (!player || !state || !state.url) return null;
|
|
4570
|
+
return applyModifiers(videoElement(player, { ...state, url: state.url }, { gravity: "resizeAspect", controls: false }), [
|
|
4571
|
+
["frame", { width: 0, height: 0 }],
|
|
4572
|
+
["clipped", true],
|
|
4573
|
+
["opacity", 0],
|
|
4574
|
+
["allowsHitTesting", false]
|
|
4575
|
+
]);
|
|
4576
|
+
}
|
|
4494
4577
|
function PhaseAnimator({ phases, trigger, animation, children }) {
|
|
4495
4578
|
const [index, setIndex] = useState(0);
|
|
4496
4579
|
const hasTrigger = trigger !== void 0;
|
|
@@ -4605,9 +4688,11 @@ function KeyframeAnimator({
|
|
|
4605
4688
|
}
|
|
4606
4689
|
export {
|
|
4607
4690
|
AVPlayer,
|
|
4691
|
+
AVQueuePlayer,
|
|
4608
4692
|
AngularGradient,
|
|
4609
4693
|
AreaMark,
|
|
4610
4694
|
AsyncImage,
|
|
4695
|
+
AudioPlayer,
|
|
4611
4696
|
BarMark,
|
|
4612
4697
|
Button,
|
|
4613
4698
|
Canvas,
|