@swiftbrowser/react 0.17.6 → 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 CHANGED
@@ -397,7 +397,17 @@ 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
@@ -599,7 +609,7 @@ read with a hook). Props, callbacks and external stores need no bridging.
599
609
  styles, `LabeledContent`, `Link`, `Color` as a view, shapes (built-in,
600
610
  custom paths, `UnevenRoundedRectangle`, `ContainerRelativeShape`) with
601
611
  fills, strokes and gradients, `Canvas`, `TimelineView`, `VideoPlayer`,
602
- `Gauge`, `ProgressView`, Swift Charts.
612
+ `AudioPlayer` and `AVQueuePlayer`, `Gauge`, `ProgressView`, Swift Charts.
603
613
  - **Controls**: `Button` (styles, roles, sizes), `Toggle`, `Picker`,
604
614
  `Slider`, `Stepper`, `TextField` and `SecureField` (focus bindings, submit
605
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":"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"}
1
+ {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../../src/components/controls.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- /** `TimelineView` and `VideoPlayer` with `useAVPlayer`. */
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
- private state;
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
- private update;
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":"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"}
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("slider", { value, min, max, step: own.step ?? null, labels }, { slide: (event) => setValue(event.value) }, children.length ? children : void 0),
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
  }
@@ -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
- if (!this.state.loop) this.update({ rate: 0 });
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 VideoPlayer(props) {
4462
- const { own, modifiers } = splitProps(props);
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: own.gravity ?? "resizeAspect",
4480
- controls: own.controls ?? true,
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,