@vestra-player/sdk 1.6.14 → 1.6.16
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/CHANGELOG.md +17 -0
- package/dist/commands.d.ts +3 -2
- package/dist/commands.js +158 -179
- package/dist/docs-tree.json.gz +0 -0
- package/dist/plugin/runtime.js +12 -2
- package/dist/plugin/testing.d.ts +51 -24
- package/dist/plugin/testing.js +93 -44
- package/dist/plugin/types.d.ts +18 -7
- package/dist/plugin/ui.js +19 -8
- package/dist/wire.d.ts +6 -4
- package/dist/wire.js +18 -4
- package/llms.txt +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.16
|
|
4
|
+
|
|
5
|
+
**Who must change: nobody.** A data refresh for the player's four built-in panels (player 0.7.6) and one additive read; no API is removed, `apiVersion` stays `vestra/1`.
|
|
6
|
+
|
|
7
|
+
- **`BUILTIN_COMMANDS`**: the Picture, Audio, Subtitles and Playback panels open from four top-level items, **Picture…** (`vestra.video`, `video.picture`, Alt+1), **Audio…** (`audio.workbench`, Alt+2), **Subtitles…** (`tune`, Alt+3) and **Playback…** (`vestra.playback`, `panel`, Alt+4), next to Playlist. The commands their panels hold left the menus for the command palette, with their keys and categories: Video's Pixel Shaders, Deinterlace, Aspect, Crop/Stretch, Framing, Image Processing and Rotation, the picture steps and GPU Rendering; Audio's track, channel, equalizer, preset, sync and processing items; Subtitles' show, style, secondary subtitle, sync and reload items; the playback plugin's seek steps, keyframes, Jump to Time… and speeds; the Reset items of the video, audio and subtitles plugins (the visualizer's Reset ▸ Idle Logo stays). **Subtitle Track ▸ Off** and **Audio Track ▸ No Audio Tracks** are now top-level submenus. New palette commands: Remove External Subtitle (`vestra.subtitles`, `remove`) and Picture Panel (`video.resetPanel`, a reset of the panel's values). Audio ▸ Output Device ▸ No Output Devices (`audio.device.none`) is gone.
|
|
8
|
+
- **`BUILTIN_SUBMENUS`**: the Video, Audio and Subtitles submenus of these plugins are gone; **Subtitle Track** (`vestra.subtitles`) and **Audio Track** (`vestra.audio`) are new, at the top level. Online Subtitles and Snapshot stay.
|
|
9
|
+
- **`plugin.commands.keys("host/<id>")`** reads the keys of the player's own commands (`host/volume-up`, `host/mute`, the ids of the `host` rows of `BUILTIN_COMMANDS`), read-only and current like a plugin's own, so a panel can show the player's key caps beside its controls; `onKeysChange` fires for their changes too. The `commands.keys` answer and event carry them as `host/<id>` entries (a local id has no `/`); player 0.7.6, like `keys` itself. A side effect: rebinding one of the player's own commands now sends `commands.keys` to every plugin listening for it, and a listener in standby is started for it (as for a change to its own keys); `onKeysChange` still fires only when a label the plugin can read changed.
|
|
10
|
+
- **`TestHost`**: `commands.keys` answers the core commands as `host/<id>` too, and `rebind` takes a core command's `host/<id>`.
|
|
11
|
+
|
|
12
|
+
## 1.6.15
|
|
13
|
+
|
|
14
|
+
**Who must change: nobody.** A plugin may now mount one panel per slot (player 0.7.6) instead of one panel in all; plugins with one panel work as before, and `apiVersion` stays `vestra/1`.
|
|
15
|
+
|
|
16
|
+
- **One panel per slot.** `plugin.panels.mount` takes a second call for another slot: a playback plugin can have its control bar in `"bottom"` and its controls in `"adjust"`. Each `Panel` has its own bridge global, properties, callbacks, `state`, `show()`, `toggle()`, `setInteraction()` and menu; disposing one leaves the others, and stopping the plugin unmounts them all. A failed mount affects only that panel. A second panel in the same slot still throws (an `Error`, before anything is sent); the bottom bar and the backdrop still hold one panel for all plugins. Players before 0.7.6 refuse a second panel with `conflict` (they keep one panel per plugin); a plugin that mounts two declares `minPlayerVersion` 0.7.6.
|
|
17
|
+
- **Wire** (additive): `ui.setMount`, `ui.interaction`, `ui.menu` and `ui.unmount` take an optional `slot` naming the panel (without it: the plugin's only panel; `ui.unmount` without it removes every panel); `ui.callback` and `ui.preparing` carry the panel's `slot`, and `ui.callback` keeps `view: "$mount"`. Older players ignore `slot`.
|
|
18
|
+
- **`BUILTIN_COMMANDS`**: the player's seek, frame and speed actions (`host/seek-backward`, `seek-forward`, `frame-back`, `frame-forward`, `rate-down`, `rate-up`, `rate-normal`) leave Playback ▸ Seek and Speed for the command palette (player 0.7.6, with the playback plugin's panel); their keys and categories stay.
|
|
19
|
+
- **`TestHost`**: `panels` (by slot, in mount order) and `mounted(slot?)`; without a slot `mounted()` returns the only panel and throws when there are several. `panel` stays, as the last panel mounted. The handlers take `slot` as the player does; `ui.interaction` stores the locks without it.
|
|
3
20
|
## 1.6.14
|
|
4
21
|
|
|
5
22
|
**Who must change: nobody.** A data refresh: `BUILTIN_COMMANDS` lists the built-in capture plugin's commands as the player registers them since its capture tab; no API change, `apiVersion` stays `vestra/1`.
|
package/dist/commands.d.ts
CHANGED
|
@@ -348,8 +348,9 @@ export type CommandDeclaration = {
|
|
|
348
348
|
};
|
|
349
349
|
/**
|
|
350
350
|
* `commands.keys` (player 0.7.6): each of the plugin's own commands, by
|
|
351
|
-
* local id,
|
|
352
|
-
*
|
|
351
|
+
* local id, and (SDK 1.6.16) each of the player's own as `host/<id>`, with
|
|
352
|
+
* the labels of its current keys; the answer to the request and the data of
|
|
353
|
+
* the event of that name.
|
|
353
354
|
*/
|
|
354
355
|
export type CommandKeys = {
|
|
355
356
|
keys: Record<string, string[]>;
|
package/dist/commands.js
CHANGED
|
@@ -275,32 +275,7 @@ export const BUILTIN_SUBMENUS = Object.freeze([
|
|
|
275
275
|
path: ["Subtitles", "Online Subtitles"],
|
|
276
276
|
plugins: ["vestra.subtitle-online"],
|
|
277
277
|
},
|
|
278
|
-
{ path: ["Subtitles", "Secondary Subtitle"], plugins: ["vestra.subtitles"] },
|
|
279
|
-
{
|
|
280
|
-
path: ["Subtitles", "Secondary Subtitle", "Position"],
|
|
281
|
-
plugins: ["vestra.subtitles"],
|
|
282
|
-
},
|
|
283
|
-
{ path: ["Subtitles", "Subtitle Style"], plugins: ["vestra.subtitles"] },
|
|
284
|
-
{ path: ["Subtitles", "Subtitle Track"], plugins: ["vestra.subtitles"] },
|
|
285
|
-
{ path: ["Subtitles", "Sync"], plugins: ["vestra.subtitles"] },
|
|
286
|
-
{ path: ["Video", "Aspect"], plugins: ["vestra.video"] },
|
|
287
|
-
{ path: ["Video", "Crop/Stretch"], plugins: ["vestra.video"] },
|
|
288
|
-
{ path: ["Video", "Deinterlace"], plugins: ["vestra.video"] },
|
|
289
|
-
{ path: ["Video", "Deinterlace", "Output"], plugins: ["vestra.video"] },
|
|
290
|
-
{ path: ["Video", "Framing"], plugins: ["vestra.video"] },
|
|
291
|
-
{ path: ["Video", "Image Processing"], plugins: ["vestra.video"] },
|
|
292
|
-
{ path: ["Video", "Pixel Shaders"], plugins: ["vestra.video"] },
|
|
293
|
-
{
|
|
294
|
-
path: ["Video", "Pixel Shaders", "HDR Tone Mapping"],
|
|
295
|
-
plugins: ["vestra.video"],
|
|
296
|
-
},
|
|
297
|
-
{ path: ["Video", "Rotation"], plugins: ["vestra.video"] },
|
|
298
278
|
{ path: ["Video", "Snapshot"], plugins: ["vestra.capture"] },
|
|
299
|
-
{ path: ["Audio", "Audio Sync"], plugins: ["vestra.audio"] },
|
|
300
|
-
{ path: ["Audio", "Audio Track"], plugins: ["vestra.audio"] },
|
|
301
|
-
{ path: ["Audio", "Output Device"], plugins: ["vestra.audio"] },
|
|
302
|
-
{ path: ["Audio", "Preset"], plugins: ["vestra.audio"] },
|
|
303
|
-
{ path: ["Audio", "Processing"], plugins: ["vestra.audio"] },
|
|
304
279
|
{ path: ["Screen", "Always on Top"], plugins: ["vestra.window"] },
|
|
305
280
|
{ path: ["Screen", "When Playback Starts"], plugins: ["vestra.window"] },
|
|
306
281
|
{
|
|
@@ -309,6 +284,8 @@ export const BUILTIN_SUBMENUS = Object.freeze([
|
|
|
309
284
|
},
|
|
310
285
|
{ path: ["Settings", "Language"], plugins: ["vestra.preferences"] },
|
|
311
286
|
{ path: ["Copy to Clipboard"], plugins: ["vestra.playback"] },
|
|
287
|
+
{ path: ["Subtitle Track"], plugins: ["vestra.subtitles"] },
|
|
288
|
+
{ path: ["Audio Track"], plugins: ["vestra.audio"] },
|
|
312
289
|
]);
|
|
313
290
|
/** owner | id | key path, or (title) outside the menu | bindings | panel */
|
|
314
291
|
const BUILTIN_COMMAND_TABLE = `
|
|
@@ -330,31 +307,6 @@ vestra.playback | copy-path | Copy to Clipboard ▸ Full Path
|
|
|
330
307
|
host | play-pause | Playback ▸ Play/Pause | Space, Mouse:LeftClick
|
|
331
308
|
host | previous | Playback ▸ Previous | PageUp, Mouse:X2
|
|
332
309
|
host | next | Playback ▸ Next | PageDown, Mouse:X1
|
|
333
|
-
host | frame-back | Playback ▸ Seek ▸ Previous Frame | D
|
|
334
|
-
host | frame-forward | Playback ▸ Seek ▸ Next Frame | F
|
|
335
|
-
vestra.playback | keyframe-back | Playback ▸ Seek ▸ Previous Keyframe | Ctrl+Shift+ArrowLeft
|
|
336
|
-
vestra.playback | keyframe-forward | Playback ▸ Seek ▸ Next Keyframe | Ctrl+Shift+ArrowRight
|
|
337
|
-
host | seek-backward | Playback ▸ Seek ▸ Back 5 s | ArrowLeft
|
|
338
|
-
host | seek-forward | Playback ▸ Seek ▸ Forward 5 s | ArrowRight
|
|
339
|
-
vestra.playback | backward-2 | Playback ▸ Seek ▸ Back 30 s | Ctrl+ArrowLeft
|
|
340
|
-
vestra.playback | forward-2 | Playback ▸ Seek ▸ Forward 30 s | Ctrl+ArrowRight
|
|
341
|
-
vestra.playback | backward-3 | Playback ▸ Seek ▸ Back 60 s | Shift+ArrowLeft
|
|
342
|
-
vestra.playback | forward-3 | Playback ▸ Seek ▸ Forward 60 s | Shift+ArrowRight
|
|
343
|
-
vestra.playback | backward-4 | Playback ▸ Seek ▸ Back 300 s | Ctrl+Alt+ArrowLeft
|
|
344
|
-
vestra.playback | forward-4 | Playback ▸ Seek ▸ Forward 300 s | Ctrl+Alt+ArrowRight
|
|
345
|
-
vestra.subtitles | dialogue-previous | Playback ▸ Seek ▸ Previous Dialogue | Home
|
|
346
|
-
vestra.subtitles | dialogue-next | Playback ▸ Seek ▸ Next Dialogue | End
|
|
347
|
-
vestra.subtitles | dialogue-current | Playback ▸ Seek ▸ Current Subtitle Start | Ctrl+Home
|
|
348
|
-
vestra.playback | jump-start | Playback ▸ Seek ▸ Jump to Start | Backspace
|
|
349
|
-
vestra.playback | time-jump | Playback ▸ Seek ▸ Seek Steps…
|
|
350
|
-
vestra.playback | jump | Playback ▸ Jump to Time… | G
|
|
351
|
-
host | rate-normal | Playback ▸ Speed ▸ Normal | Z
|
|
352
|
-
host | rate-down | Playback ▸ Speed ▸ Slower 0.1 | X
|
|
353
|
-
host | rate-up | Playback ▸ Speed ▸ Faster 0.1 | C
|
|
354
|
-
vestra.playback | rate-05 | Playback ▸ Speed ▸ 0.5×
|
|
355
|
-
vestra.playback | rate-15 | Playback ▸ Speed ▸ 1.5×
|
|
356
|
-
vestra.playback | rate-20 | Playback ▸ Speed ▸ 2×
|
|
357
|
-
vestra.playback | rate-custom | Playback ▸ Speed ▸ Custom…
|
|
358
310
|
vestra.playlist | playlist.add | Playback ▸ Playlist ▸ Add Files…
|
|
359
311
|
vestra.playlist | playlist.link | Playback ▸ Playlist ▸ Add Link…
|
|
360
312
|
vestra.playlist | playlist.add-folder | Playback ▸ Playlist ▸ Add Folder…
|
|
@@ -404,139 +356,19 @@ vestra.marks | ab.count.2 | Playback ▸ A-B Loop ▸ Loop Count ▸ 2 Times
|
|
|
404
356
|
vestra.marks | ab.count.3 | Playback ▸ A-B Loop ▸ Loop Count ▸ 3 Times
|
|
405
357
|
vestra.marks | ab.count.5 | Playback ▸ A-B Loop ▸ Loop Count ▸ 5 Times
|
|
406
358
|
vestra.marks | ab.count.10 | Playback ▸ A-B Loop ▸ Loop Count ▸ 10 Times
|
|
407
|
-
vestra.subtitles | show | Subtitles ▸ Show Subtitles | Alt+H
|
|
408
|
-
vestra.subtitles | track-off | Subtitles ▸ Subtitle Track ▸ Off
|
|
409
|
-
vestra.subtitles | track-cycle | Subtitles ▸ Subtitle Track ▸ Cycle | Alt+L
|
|
410
|
-
vestra.subtitles | second-off | Subtitles ▸ Secondary Subtitle ▸ Off
|
|
411
|
-
vestra.subtitles | second-position-top | Subtitles ▸ Secondary Subtitle ▸ Position ▸ Top
|
|
412
|
-
vestra.subtitles | second-position-aboveMain | Subtitles ▸ Secondary Subtitle ▸ Position ▸ Above Main Subtitle
|
|
413
|
-
vestra.subtitles | bold | Subtitles ▸ Subtitle Style ▸ Bold | Alt+B
|
|
414
|
-
vestra.subtitles | size-up | Subtitles ▸ Subtitle Style ▸ Size + | Alt+PageUp
|
|
415
|
-
vestra.subtitles | size-down | Subtitles ▸ Subtitle Style ▸ Size − | Alt+PageDown
|
|
416
|
-
vestra.subtitles | move-up | Subtitles ▸ Subtitle Style ▸ Move Up
|
|
417
|
-
vestra.subtitles | move-down | Subtitles ▸ Subtitle Style ▸ Move Down
|
|
418
|
-
vestra.subtitles | shadow | Subtitles ▸ Subtitle Style ▸ Shadow
|
|
419
|
-
vestra.subtitles | box | Subtitles ▸ Subtitle Style ▸ Opaque Box
|
|
420
|
-
vestra.subtitles | ass-original | Subtitles ▸ Original ASS/SSA Styles
|
|
421
|
-
vestra.subtitles | sync-earlier | Subtitles ▸ Sync ▸ Earlier 0.5 s | .
|
|
422
|
-
vestra.subtitles | sync-later | Subtitles ▸ Sync ▸ Later 0.5 s | ,
|
|
423
|
-
vestra.subtitles | sync-input | Subtitles ▸ Sync ▸ Adjust Sync…
|
|
424
359
|
vestra.subtitle-online | search | Subtitles ▸ Online Subtitles ▸ Search and Download Subtitles…
|
|
425
360
|
vestra.subtitle-online | settings | Subtitles ▸ Online Subtitles ▸ Online Subtitle Settings…
|
|
426
|
-
vestra.subtitles |
|
|
427
|
-
vestra.subtitles | refresh | Subtitles ▸ Refresh Subtitle Tracks
|
|
428
|
-
vestra.subtitles | tune | Subtitles ▸ Subtitle Tuning…
|
|
429
|
-
vestra.subtitles | settings | Subtitles ▸ Subtitle Settings…
|
|
430
|
-
vestra.video | video.shader.use | Video ▸ Pixel Shaders ▸ Use Shaders | Shift+P
|
|
431
|
-
vestra.video | video.shader.list | Video ▸ Pixel Shaders ▸ Shader List…
|
|
432
|
-
vestra.video | video.shader.folder | Video ▸ Pixel Shaders ▸ Open Shader Folder
|
|
433
|
-
vestra.video | video.shader.reload | Video ▸ Pixel Shaders ▸ Reload Shaders
|
|
434
|
-
vestra.video | video.hdr.auto | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Auto
|
|
435
|
-
vestra.video | video.hdr.off | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Off
|
|
436
|
-
vestra.video | video.hdr.bt.2390 | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ BT.2390
|
|
437
|
-
vestra.video | video.hdr.hable | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Hable
|
|
438
|
-
vestra.video | video.hdr.mobius | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Mobius
|
|
439
|
-
vestra.video | video.hdr.reinhard | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Reinhard
|
|
440
|
-
vestra.video | video.hdr.clip | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Clip
|
|
441
|
-
vestra.video | video.hdr.peak | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Dynamic Peak Detection
|
|
442
|
-
vestra.video | video.hdr.settings | Video ▸ Pixel Shaders ▸ HDR Settings…
|
|
443
|
-
vestra.video | video.deinterlace.cycle | Video ▸ Deinterlace ▸ Cycle | Ctrl+I
|
|
444
|
-
vestra.video | video.deinterlace.auto | Video ▸ Deinterlace ▸ Auto
|
|
445
|
-
vestra.video | video.deinterlace.on | Video ▸ Deinterlace ▸ Always
|
|
446
|
-
vestra.video | video.deinterlace.off | Video ▸ Deinterlace ▸ Never
|
|
447
|
-
vestra.video | video.deinterlace.output.frame | Video ▸ Deinterlace ▸ Output ▸ By Frame
|
|
448
|
-
vestra.video | video.deinterlace.output.field | Video ▸ Deinterlace ▸ Output ▸ By Field (Double Rate)
|
|
449
|
-
vestra.video | video.fit.keep | Video ▸ Aspect ▸ Keep Aspect Ratio
|
|
450
|
-
vestra.video | video.fit.stretch | Video ▸ Aspect ▸ Ignore Aspect Ratio
|
|
451
|
-
vestra.video | video.fit.fill | Video ▸ Aspect ▸ Fill Window (Crop Excess)
|
|
452
|
-
vestra.video | video.aspect.cycle | Video ▸ Aspect ▸ Cycle Aspect Ratio | Shift+F6
|
|
453
|
-
vestra.video | video.aspect.default | Video ▸ Aspect ▸ Default (Source)
|
|
454
|
-
vestra.video | video.aspect.0 | Video ▸ Aspect ▸ 4:3
|
|
455
|
-
vestra.video | video.aspect.1 | Video ▸ Aspect ▸ 16:9
|
|
456
|
-
vestra.video | video.aspect.2 | Video ▸ Aspect ▸ 16:10
|
|
457
|
-
vestra.video | video.aspect.3 | Video ▸ Aspect ▸ 1.85:1
|
|
458
|
-
vestra.video | video.aspect.4 | Video ▸ Aspect ▸ 2.35:1
|
|
459
|
-
vestra.video | video.aspect.custom | Video ▸ Aspect ▸ Custom (x:y)
|
|
460
|
-
vestra.video | video.aspect.edit | Video ▸ Aspect ▸ Custom Aspect Ratio…
|
|
461
|
-
vestra.video | video.reframe.none | Video ▸ Crop/Stretch ▸ None
|
|
462
|
-
vestra.video | video.reframe.pad.0 | Video ▸ Crop/Stretch ▸ Stretch to 4:3
|
|
463
|
-
vestra.video | video.reframe.pad.1 | Video ▸ Crop/Stretch ▸ Stretch to 16:9
|
|
464
|
-
vestra.video | video.reframe.pad.2 | Video ▸ Crop/Stretch ▸ Stretch to 16:10
|
|
465
|
-
vestra.video | video.reframe.pad.3 | Video ▸ Crop/Stretch ▸ Stretch to 1.85:1
|
|
466
|
-
vestra.video | video.reframe.pad.4 | Video ▸ Crop/Stretch ▸ Stretch to 2.35:1
|
|
467
|
-
vestra.video | video.reframe.crop.0 | Video ▸ Crop/Stretch ▸ Crop to 4:3
|
|
468
|
-
vestra.video | video.reframe.crop.1 | Video ▸ Crop/Stretch ▸ Crop to 16:9
|
|
469
|
-
vestra.video | video.reframe.crop.2 | Video ▸ Crop/Stretch ▸ Crop to 16:10
|
|
470
|
-
vestra.video | video.reframe.crop.3 | Video ▸ Crop/Stretch ▸ Crop to 1.85:1
|
|
471
|
-
vestra.video | video.reframe.crop.4 | Video ▸ Crop/Stretch ▸ Crop to 2.35:1
|
|
472
|
-
vestra.video | video.reframe.left | Video ▸ Crop/Stretch ▸ Move Left
|
|
473
|
-
vestra.video | video.reframe.right | Video ▸ Crop/Stretch ▸ Move Right
|
|
474
|
-
vestra.video | video.reframe.up | Video ▸ Crop/Stretch ▸ Move Up
|
|
475
|
-
vestra.video | video.reframe.down | Video ▸ Crop/Stretch ▸ Move Down
|
|
476
|
-
vestra.video | video.frame.zoom-in | Video ▸ Framing ▸ Zoom In | Numpad9, Alt+Plus
|
|
477
|
-
vestra.video | video.frame.zoom-out | Video ▸ Framing ▸ Zoom Out | Numpad1, Alt+-
|
|
478
|
-
vestra.video | video.frame.right | Video ▸ Framing ▸ Pan → | Ctrl+Numpad6, Alt+ArrowRight
|
|
479
|
-
vestra.video | video.frame.left | Video ▸ Framing ▸ Pan ← | Ctrl+Numpad4, Alt+ArrowLeft
|
|
480
|
-
vestra.video | video.frame.up | Video ▸ Framing ▸ Pan ↑ | Ctrl+Numpad8, Alt+ArrowUp
|
|
481
|
-
vestra.video | video.frame.down | Video ▸ Framing ▸ Pan ↓ | Ctrl+Numpad2, Alt+ArrowDown
|
|
482
|
-
vestra.video | video.frame.centre | Video ▸ Framing ▸ Center Frame | Ctrl+Numpad5
|
|
483
|
-
vestra.video | video.flip.vertical | Video ▸ Image Processing ▸ Flip Vertically | Ctrl+P
|
|
484
|
-
vestra.video | video.flip.horizontal | Video ▸ Image Processing ▸ Flip Horizontally | Ctrl+Z
|
|
485
|
-
vestra.video | video.gaussian | Video ▸ Image Processing ▸ Gaussian Blur | Ctrl+B
|
|
486
|
-
vestra.video | video.sharpen | Video ▸ Image Processing ▸ Sharpen | Ctrl+R
|
|
487
|
-
vestra.video | video.edge | Video ▸ Image Processing ▸ Edge Sharpen
|
|
488
|
-
vestra.video | video.deblock | Video ▸ Image Processing ▸ Deblock | Ctrl+H
|
|
489
|
-
vestra.video | video.deband | Video ▸ Image Processing ▸ Deband
|
|
490
|
-
vestra.video | video.denoise.d3 | Video ▸ Image Processing ▸ 3D Denoise | Ctrl+N
|
|
491
|
-
vestra.video | video.denoise.gradual | Video ▸ Image Processing ▸ Gradual Denoise
|
|
492
|
-
vestra.video | video.denoise.temporal | Video ▸ Image Processing ▸ Temporal Denoise | Ctrl+M
|
|
493
|
-
vestra.video | video.frame-blend | Video ▸ Image Processing ▸ Frame Doubling
|
|
494
|
-
vestra.video | video.interpolation | Video ▸ Image Processing ▸ Motion Interpolation
|
|
495
|
-
vestra.video | video.rotate.cycle | Video ▸ Rotation ▸ Cycle | Alt+K
|
|
496
|
-
vestra.video | video.rotate.0 | Video ▸ Rotation ▸ No Rotation
|
|
497
|
-
vestra.video | video.rotate.90 | Video ▸ Rotation ▸ 90°
|
|
498
|
-
vestra.video | video.rotate.180 | Video ▸ Rotation ▸ 180°
|
|
499
|
-
vestra.video | video.rotate.270 | Video ▸ Rotation ▸ 270°
|
|
361
|
+
vestra.subtitles | track-off | Subtitle Track ▸ Off
|
|
500
362
|
vestra.capture | capture.save | Video ▸ Snapshot ▸ Save Current Frame | Ctrl+E
|
|
501
363
|
vestra.capture | capture.panel | Video ▸ Snapshot ▸ Capture… | Alt+S
|
|
502
364
|
vestra.capture | capture.copy | Video ▸ Snapshot ▸ Copy Current Frame | Ctrl+C
|
|
503
365
|
vestra.capture | capture.burst | Video ▸ Snapshot ▸ Burst… | Ctrl+G
|
|
504
366
|
vestra.capture | capture.clip | Video ▸ Snapshot ▸ Export Clip…
|
|
505
|
-
vestra.video | video.picture | Video ▸ Picture Adjustments…
|
|
506
|
-
vestra.video | video.brightness.down | Video ▸ Brightness -1% | W
|
|
507
|
-
vestra.video | video.brightness.up | Video ▸ Brightness +1% | E
|
|
508
|
-
vestra.video | video.contrast.down | Video ▸ Contrast -1% | R
|
|
509
|
-
vestra.video | video.contrast.up | Video ▸ Contrast +1% | T
|
|
510
|
-
vestra.video | video.saturation.down | Video ▸ Saturation -1% | Y
|
|
511
|
-
vestra.video | video.saturation.up | Video ▸ Saturation +1% | U
|
|
512
|
-
vestra.video | video.hue.down | Video ▸ Hue -1% | I
|
|
513
|
-
vestra.video | video.hue.up | Video ▸ Hue +1% | O
|
|
514
|
-
vestra.video | video.gpu-rendering | Video ▸ GPU Rendering (Experimental)
|
|
515
367
|
host | volume-up | Audio ▸ Volume + | ArrowUp, Mouse:WheelUp
|
|
516
368
|
host | volume-down | Audio ▸ Volume − | ArrowDown, Mouse:WheelDown
|
|
517
369
|
host | mute | Audio ▸ Mute | M
|
|
518
|
-
vestra.audio | audio.workbench | Audio ▸ Audio Workbench…
|
|
519
|
-
vestra.audio | audio.track.none | Audio ▸ Audio Track ▸ No Audio Tracks
|
|
520
|
-
vestra.audio | audio.track.cycle | Audio ▸ Audio Track ▸ Cycle Tracks | Alt+A
|
|
521
|
-
vestra.audio | audio.channels.stereo | Audio ▸ Audio Track ▸ Stereo
|
|
522
|
-
vestra.audio | audio.channels.left | Audio ▸ Audio Track ▸ Left Channel
|
|
523
|
-
vestra.audio | audio.channels.right | Audio ▸ Audio Track ▸ Right Channel
|
|
524
|
-
vestra.audio | audio.channels.mono | Audio ▸ Audio Track ▸ Mono Mix
|
|
525
|
-
vestra.audio | audio.channels.swap | Audio ▸ Audio Track ▸ Swap Left and Right
|
|
526
|
-
vestra.audio | audio.device.none | Audio ▸ Output Device ▸ No Output Devices
|
|
527
|
-
vestra.audio | audio.equalizer | Audio ▸ Equalizer | Shift+E
|
|
528
|
-
vestra.audio | audio.preset.0 | Audio ▸ Preset ▸ Flat
|
|
529
|
-
vestra.audio | audio.preset.1 | Audio ▸ Preset ▸ Voice
|
|
530
|
-
vestra.audio | audio.preset.2 | Audio ▸ Preset ▸ Music
|
|
531
|
-
vestra.audio | audio.preset.3 | Audio ▸ Preset ▸ Cinema
|
|
532
|
-
vestra.audio | audio.sync.earlier | Audio ▸ Audio Sync ▸ 50 ms Earlier | >
|
|
533
|
-
vestra.audio | audio.sync.later | Audio ▸ Audio Sync ▸ 50 ms Later | <
|
|
534
|
-
vestra.audio | audio.sync.keep.none | Audio ▸ Audio Sync ▸ Don't Keep
|
|
535
|
-
vestra.audio | audio.sync.keep.session | Audio ▸ Audio Sync ▸ Keep for This Run
|
|
536
|
-
vestra.audio | audio.sync.keep.always | Audio ▸ Audio Sync ▸ Always Keep
|
|
537
|
-
vestra.audio | audio.normalize | Audio ▸ Processing ▸ Normalize | Shift+N
|
|
538
|
-
vestra.audio | audio.clarity | Audio ▸ Processing ▸ Crystalizer | Shift+C
|
|
539
370
|
vestra.visualizer | audio-cover | Audio ▸ Show Album Cover for Audio Only
|
|
371
|
+
vestra.audio | audio.track.none | Audio Track ▸ No Audio Tracks
|
|
540
372
|
host | fullscreen | Toggle Fullscreen | Escape
|
|
541
373
|
vestra.window | pip | Screen ▸ Picture-in-Picture
|
|
542
374
|
vestra.window | mini | Screen ▸ Mini Size | \`
|
|
@@ -557,6 +389,10 @@ vestra.window | top.never | Screen ▸ Always on Top ▸ Never
|
|
|
557
389
|
vestra.window | top.always | Screen ▸ Always on Top ▸ Always
|
|
558
390
|
vestra.window | top.playing | Screen ▸ Always on Top ▸ While Playing
|
|
559
391
|
vestra.window | top.fullscreen | Screen ▸ Always on Top ▸ While Playing in Fullscreen
|
|
392
|
+
vestra.video | video.picture | Picture… | Alt+1
|
|
393
|
+
vestra.audio | audio.workbench | Audio… | Alt+2
|
|
394
|
+
vestra.subtitles | tune | Subtitles… | Alt+3
|
|
395
|
+
vestra.playback | panel | Playback… | Alt+4
|
|
560
396
|
vestra.playlist | playlist.visibility | Playlist | F6
|
|
561
397
|
vestra.info | info.toggle | Playback Info | Tab
|
|
562
398
|
vestra.info | info.properties | Playback Properties… | Ctrl+F1
|
|
@@ -578,13 +414,6 @@ vestra.preferences | language.ko | Settings ▸ Language ▸ 한국어
|
|
|
578
414
|
vestra.preferences | language.de | Settings ▸ Language ▸ Deutsch
|
|
579
415
|
vestra.preferences | language.fr | Settings ▸ Language ▸ Français
|
|
580
416
|
vestra.preferences | language.es | Settings ▸ Language ▸ Español
|
|
581
|
-
vestra.subtitles | move-reset | Reset ▸ Subtitle Position | Alt+Home
|
|
582
|
-
vestra.subtitles | sync-reset | Reset ▸ Subtitle Sync | /
|
|
583
|
-
vestra.video | video.reset | Reset ▸ Picture | Q
|
|
584
|
-
vestra.video | video.frame.reset | Reset ▸ Framing | Numpad5, Alt+Backspace
|
|
585
|
-
vestra.video | video.reframe.reset | Reset ▸ Crop Position
|
|
586
|
-
vestra.audio | audio.sync.reset | Reset ▸ Audio Sync | ?
|
|
587
|
-
vestra.audio | audio.reset | Reset ▸ Audio Processing
|
|
588
417
|
vestra.visualizer | reset-logo | Reset ▸ Idle Logo
|
|
589
418
|
vestra.info | info.about | About Vestra Player… | F1
|
|
590
419
|
vestra.info | info.update | Check for Updates…
|
|
@@ -594,6 +423,33 @@ host | exit-fullscreen | (Leave Fullscreen)
|
|
|
594
423
|
host | sidebar | (Toggle Sidebar)
|
|
595
424
|
host | palette | (Command Palette) | Ctrl+Shift+P
|
|
596
425
|
host | adjust | (Adjust)
|
|
426
|
+
host | frame-back | (Previous Frame) | D
|
|
427
|
+
host | frame-forward | (Next Frame) | F
|
|
428
|
+
host | seek-backward | (Back 5 s) | ArrowLeft
|
|
429
|
+
host | seek-forward | (Forward 5 s) | ArrowRight
|
|
430
|
+
host | rate-normal | (Normal) | Z
|
|
431
|
+
host | rate-down | (Slower 0.1) | X
|
|
432
|
+
host | rate-up | (Faster 0.1) | C
|
|
433
|
+
vestra.audio | audio.track.cycle | (Cycle Tracks) | Alt+A
|
|
434
|
+
vestra.audio | audio.channels.stereo | (Stereo)
|
|
435
|
+
vestra.audio | audio.channels.left | (Left Channel)
|
|
436
|
+
vestra.audio | audio.channels.right | (Right Channel)
|
|
437
|
+
vestra.audio | audio.channels.mono | (Mono Mix)
|
|
438
|
+
vestra.audio | audio.channels.swap | (Swap Left and Right)
|
|
439
|
+
vestra.audio | audio.equalizer | (Equalizer) | Shift+E
|
|
440
|
+
vestra.audio | audio.preset.0 | (Flat)
|
|
441
|
+
vestra.audio | audio.preset.1 | (Voice)
|
|
442
|
+
vestra.audio | audio.preset.2 | (Music)
|
|
443
|
+
vestra.audio | audio.preset.3 | (Cinema)
|
|
444
|
+
vestra.audio | audio.sync.earlier | (50 ms Earlier) | >
|
|
445
|
+
vestra.audio | audio.sync.later | (50 ms Later) | <
|
|
446
|
+
vestra.audio | audio.sync.reset | (Reset) | ?
|
|
447
|
+
vestra.audio | audio.sync.keep.none | (Don't Keep)
|
|
448
|
+
vestra.audio | audio.sync.keep.session | (Keep for This Run)
|
|
449
|
+
vestra.audio | audio.sync.keep.always | (Always Keep)
|
|
450
|
+
vestra.audio | audio.normalize | (Normalize) | Shift+N
|
|
451
|
+
vestra.audio | audio.clarity | (Crystalizer) | Shift+C
|
|
452
|
+
vestra.audio | audio.reset | (Reset)
|
|
597
453
|
vestra.capture | capture.clipExport | (Export Clip Range) | Ctrl+Shift+E
|
|
598
454
|
vestra.capture | capture.saveAs | (Save Current Frame As…)
|
|
599
455
|
vestra.capture | capture.saveScreen | (Save Rendered Frame) | Ctrl+Alt+E
|
|
@@ -615,6 +471,21 @@ vestra.capture | capture.clipStart | (Set Clip Start)
|
|
|
615
471
|
vestra.capture | capture.clipEnd | (Set Clip End)
|
|
616
472
|
vestra.capture | capture.last30 | (Export Last 30 Seconds) | Ctrl+Shift+R
|
|
617
473
|
vestra.info | info.brief | (Brief Info) | Shift+Tab
|
|
474
|
+
vestra.playback | keyframe-back | (Previous Keyframe) | Ctrl+Shift+ArrowLeft
|
|
475
|
+
vestra.playback | keyframe-forward | (Next Keyframe) | Ctrl+Shift+ArrowRight
|
|
476
|
+
vestra.playback | jump | (Jump to Time…) | G
|
|
477
|
+
vestra.playback | jump-start | (Jump to Start) | Backspace
|
|
478
|
+
vestra.playback | time-jump | (Seek Steps…)
|
|
479
|
+
vestra.playback | rate-05 | (0.5×)
|
|
480
|
+
vestra.playback | rate-15 | (1.5×)
|
|
481
|
+
vestra.playback | rate-20 | (2×)
|
|
482
|
+
vestra.playback | rate-custom | (Custom…)
|
|
483
|
+
vestra.playback | backward-2 | (Back 30 s) | Ctrl+ArrowLeft
|
|
484
|
+
vestra.playback | forward-2 | (Forward 30 s) | Ctrl+ArrowRight
|
|
485
|
+
vestra.playback | backward-3 | (Back 60 s) | Shift+ArrowLeft
|
|
486
|
+
vestra.playback | forward-3 | (Forward 60 s) | Shift+ArrowRight
|
|
487
|
+
vestra.playback | backward-4 | (Back 300 s) | Ctrl+Alt+ArrowLeft
|
|
488
|
+
vestra.playback | forward-4 | (Forward 300 s) | Ctrl+Alt+ArrowRight
|
|
618
489
|
vestra.playlist | playlist.play | (Play) | Enter, P | panel
|
|
619
490
|
vestra.playlist | playlist.list-add | (Add Files…) | Ctrl+I | panel
|
|
620
491
|
vestra.playlist | playlist.list-add-folder | (Add Folder…) | Ctrl+O | panel
|
|
@@ -646,6 +517,114 @@ vestra.playlist | playlist.list-open-list | (Open List File…) | F3 | panel
|
|
|
646
517
|
vestra.playlist | playlist.list-save-list | (Save List…) | F2 | panel
|
|
647
518
|
vestra.playlist | playlist.close | (Close List) | F6 | panel
|
|
648
519
|
vestra.playlist | playlist.settings | (Playlist Settings…) | F5 | panel
|
|
520
|
+
vestra.subtitles | show | (Show Subtitles) | Alt+H
|
|
521
|
+
vestra.subtitles | second-off | (Off)
|
|
522
|
+
vestra.subtitles | second-position-top | (Top)
|
|
523
|
+
vestra.subtitles | second-position-aboveMain | (Above Main Subtitle)
|
|
524
|
+
vestra.subtitles | track-cycle | (Cycle) | Alt+L
|
|
525
|
+
vestra.subtitles | size-up | (Size +) | Alt+PageUp
|
|
526
|
+
vestra.subtitles | size-down | (Size −) | Alt+PageDown
|
|
527
|
+
vestra.subtitles | move-up | (Move Up)
|
|
528
|
+
vestra.subtitles | move-down | (Move Down)
|
|
529
|
+
vestra.subtitles | move-reset | (Subtitle Position) | Alt+Home
|
|
530
|
+
vestra.subtitles | bold | (Bold) | Alt+B
|
|
531
|
+
vestra.subtitles | shadow | (Shadow)
|
|
532
|
+
vestra.subtitles | box | (Opaque Box)
|
|
533
|
+
vestra.subtitles | ass-original | (Original ASS/SSA Styles)
|
|
534
|
+
vestra.subtitles | dialogue-previous | (Previous Dialogue) | Home
|
|
535
|
+
vestra.subtitles | dialogue-next | (Next Dialogue) | End
|
|
536
|
+
vestra.subtitles | dialogue-current | (Current Subtitle Start) | Ctrl+Home
|
|
537
|
+
vestra.subtitles | sync-reset | (Subtitle Sync) | /
|
|
538
|
+
vestra.subtitles | sync-input | (Adjust Sync…)
|
|
539
|
+
vestra.subtitles | reload | (Reload Subtitles) | Ctrl+Alt+Y
|
|
540
|
+
vestra.subtitles | refresh | (Refresh Subtitle Tracks)
|
|
541
|
+
vestra.subtitles | remove | (Remove External Subtitle)
|
|
542
|
+
vestra.subtitles | settings | (Subtitle Settings…)
|
|
543
|
+
vestra.subtitles | sync-earlier | (Earlier 0.5 s) | .
|
|
544
|
+
vestra.subtitles | sync-later | (Later 0.5 s) | ,
|
|
545
|
+
vestra.video | video.shader.use | (Use Shaders) | Shift+P
|
|
546
|
+
vestra.video | video.shader.list | (Shader List…)
|
|
547
|
+
vestra.video | video.shader.folder | (Open Shader Folder)
|
|
548
|
+
vestra.video | video.shader.reload | (Reload Shaders)
|
|
549
|
+
vestra.video | video.hdr.auto | (Auto)
|
|
550
|
+
vestra.video | video.hdr.off | (Off)
|
|
551
|
+
vestra.video | video.hdr.bt.2390 | (BT.2390)
|
|
552
|
+
vestra.video | video.hdr.hable | (Hable)
|
|
553
|
+
vestra.video | video.hdr.mobius | (Mobius)
|
|
554
|
+
vestra.video | video.hdr.reinhard | (Reinhard)
|
|
555
|
+
vestra.video | video.hdr.clip | (Clip)
|
|
556
|
+
vestra.video | video.hdr.peak | (Dynamic Peak Detection)
|
|
557
|
+
vestra.video | video.hdr.settings | (HDR Settings…)
|
|
558
|
+
vestra.video | video.deinterlace.cycle | (Cycle) | Ctrl+I
|
|
559
|
+
vestra.video | video.deinterlace.auto | (Auto)
|
|
560
|
+
vestra.video | video.deinterlace.on | (Always)
|
|
561
|
+
vestra.video | video.deinterlace.off | (Never)
|
|
562
|
+
vestra.video | video.deinterlace.output.frame | (By Frame)
|
|
563
|
+
vestra.video | video.deinterlace.output.field | (By Field (Double Rate))
|
|
564
|
+
vestra.video | video.fit.keep | (Keep Aspect Ratio)
|
|
565
|
+
vestra.video | video.fit.stretch | (Ignore Aspect Ratio)
|
|
566
|
+
vestra.video | video.fit.fill | (Fill Window (Crop Excess))
|
|
567
|
+
vestra.video | video.aspect.cycle | (Cycle Aspect Ratio) | Shift+F6
|
|
568
|
+
vestra.video | video.aspect.default | (Default (Source))
|
|
569
|
+
vestra.video | video.aspect.0 | (4:3)
|
|
570
|
+
vestra.video | video.aspect.1 | (16:9)
|
|
571
|
+
vestra.video | video.aspect.2 | (16:10)
|
|
572
|
+
vestra.video | video.aspect.3 | (1.85:1)
|
|
573
|
+
vestra.video | video.aspect.4 | (2.35:1)
|
|
574
|
+
vestra.video | video.aspect.custom | (Custom (x:y))
|
|
575
|
+
vestra.video | video.aspect.edit | (Custom Aspect Ratio…)
|
|
576
|
+
vestra.video | video.reframe.none | (None)
|
|
577
|
+
vestra.video | video.reframe.pad.0 | (Stretch to 4:3)
|
|
578
|
+
vestra.video | video.reframe.pad.1 | (Stretch to 16:9)
|
|
579
|
+
vestra.video | video.reframe.pad.2 | (Stretch to 16:10)
|
|
580
|
+
vestra.video | video.reframe.pad.3 | (Stretch to 1.85:1)
|
|
581
|
+
vestra.video | video.reframe.pad.4 | (Stretch to 2.35:1)
|
|
582
|
+
vestra.video | video.reframe.crop.0 | (Crop to 4:3)
|
|
583
|
+
vestra.video | video.reframe.crop.1 | (Crop to 16:9)
|
|
584
|
+
vestra.video | video.reframe.crop.2 | (Crop to 16:10)
|
|
585
|
+
vestra.video | video.reframe.crop.3 | (Crop to 1.85:1)
|
|
586
|
+
vestra.video | video.reframe.crop.4 | (Crop to 2.35:1)
|
|
587
|
+
vestra.video | video.reframe.left | (Move Left)
|
|
588
|
+
vestra.video | video.reframe.right | (Move Right)
|
|
589
|
+
vestra.video | video.reframe.up | (Move Up)
|
|
590
|
+
vestra.video | video.reframe.down | (Move Down)
|
|
591
|
+
vestra.video | video.reframe.reset | (Crop Position)
|
|
592
|
+
vestra.video | video.frame.zoom-in | (Zoom In) | Alt+Plus, Numpad9
|
|
593
|
+
vestra.video | video.frame.zoom-out | (Zoom Out) | Alt+-, Numpad1
|
|
594
|
+
vestra.video | video.frame.right | (Pan →) | Alt+ArrowRight, Ctrl+Numpad6
|
|
595
|
+
vestra.video | video.frame.left | (Pan ←) | Alt+ArrowLeft, Ctrl+Numpad4
|
|
596
|
+
vestra.video | video.frame.up | (Pan ↑) | Alt+ArrowUp, Ctrl+Numpad8
|
|
597
|
+
vestra.video | video.frame.down | (Pan ↓) | Alt+ArrowDown, Ctrl+Numpad2
|
|
598
|
+
vestra.video | video.frame.centre | (Center Frame) | Ctrl+Numpad5
|
|
599
|
+
vestra.video | video.frame.reset | (Framing) | Alt+Backspace, Numpad5
|
|
600
|
+
vestra.video | video.flip.vertical | (Flip Vertically) | Ctrl+P
|
|
601
|
+
vestra.video | video.flip.horizontal | (Flip Horizontally) | Ctrl+Z
|
|
602
|
+
vestra.video | video.gaussian | (Gaussian Blur) | Ctrl+B
|
|
603
|
+
vestra.video | video.sharpen | (Sharpen) | Ctrl+R
|
|
604
|
+
vestra.video | video.edge | (Edge Sharpen)
|
|
605
|
+
vestra.video | video.deblock | (Deblock) | Ctrl+H
|
|
606
|
+
vestra.video | video.deband | (Deband)
|
|
607
|
+
vestra.video | video.denoise.d3 | (3D Denoise) | Ctrl+N
|
|
608
|
+
vestra.video | video.denoise.gradual | (Gradual Denoise)
|
|
609
|
+
vestra.video | video.denoise.temporal | (Temporal Denoise) | Ctrl+M
|
|
610
|
+
vestra.video | video.frame-blend | (Frame Doubling)
|
|
611
|
+
vestra.video | video.interpolation | (Motion Interpolation)
|
|
612
|
+
vestra.video | video.rotate.cycle | (Cycle) | Alt+K
|
|
613
|
+
vestra.video | video.rotate.0 | (No Rotation)
|
|
614
|
+
vestra.video | video.rotate.90 | (90°)
|
|
615
|
+
vestra.video | video.rotate.180 | (180°)
|
|
616
|
+
vestra.video | video.rotate.270 | (270°)
|
|
617
|
+
vestra.video | video.reset | (Picture) | Q
|
|
618
|
+
vestra.video | video.resetPanel | (Picture Panel)
|
|
619
|
+
vestra.video | video.brightness.down | (Brightness -1%) | W
|
|
620
|
+
vestra.video | video.brightness.up | (Brightness +1%) | E
|
|
621
|
+
vestra.video | video.contrast.down | (Contrast -1%) | R
|
|
622
|
+
vestra.video | video.contrast.up | (Contrast +1%) | T
|
|
623
|
+
vestra.video | video.saturation.down | (Saturation -1%) | Y
|
|
624
|
+
vestra.video | video.saturation.up | (Saturation +1%) | U
|
|
625
|
+
vestra.video | video.hue.down | (Hue -1%) | I
|
|
626
|
+
vestra.video | video.hue.up | (Hue +1%) | O
|
|
627
|
+
vestra.video | video.gpu-rendering | (GPU Rendering (Experimental))
|
|
649
628
|
`;
|
|
650
629
|
/**
|
|
651
630
|
* The commands the player and its built-in plugins register when the
|
package/dist/docs-tree.json.gz
CHANGED
|
Binary file
|
package/dist/plugin/runtime.js
CHANGED
|
@@ -13,7 +13,9 @@ const SDK_DIRECTORY = fileURLToPath(new URL("..", import.meta.url));
|
|
|
13
13
|
export const WAKE_EVENTS = [
|
|
14
14
|
"packages.changed",
|
|
15
15
|
"bindings.changed",
|
|
16
|
-
// Player 0.7.6: sent
|
|
16
|
+
// Player 0.7.6: sent to a plugin whose own keys changed and, from SDK
|
|
17
|
+
// 1.6.16, to every listener when a player command (`host/<id>`) is
|
|
18
|
+
// rebound, which wakes each parked listener.
|
|
17
19
|
"commands.keys",
|
|
18
20
|
"appearance.changed",
|
|
19
21
|
"resolvers.fileTypes",
|
|
@@ -248,7 +250,15 @@ export class Runtime {
|
|
|
248
250
|
this.directory = directory;
|
|
249
251
|
transport.on("ui.callback", (data) => {
|
|
250
252
|
const event = data;
|
|
251
|
-
|
|
253
|
+
// A panel's callback names its slot (player 0.7.6: one panel per
|
|
254
|
+
// slot); older players name only `"$mount"`, and the plugin has one.
|
|
255
|
+
const view = event.view === "$mount"
|
|
256
|
+
? event.slot
|
|
257
|
+
? `panel:${event.slot}`
|
|
258
|
+
: [...this.views.keys()].find((key) => key.startsWith("panel:"))
|
|
259
|
+
: event.view;
|
|
260
|
+
if (view)
|
|
261
|
+
this.views.get(view)?.(event.callback, event.args);
|
|
252
262
|
});
|
|
253
263
|
transport.on("commands.execute", (data) => {
|
|
254
264
|
this.commands.get(data.id)?.();
|
package/dist/plugin/testing.d.ts
CHANGED
|
@@ -480,6 +480,37 @@ export interface MarkdownWire {
|
|
|
480
480
|
/** Remote image address → the file the SDK downloaded for it. */
|
|
481
481
|
images: Record<string, string>;
|
|
482
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* One mounted panel of the plugin under test ({@link TestHost.mounted},
|
|
485
|
+
* {@link TestHost.panels}): a {@link FakeWindow} record with its slot,
|
|
486
|
+
* component and interaction locks.
|
|
487
|
+
*
|
|
488
|
+
* @remarks
|
|
489
|
+
* One per slot the plugin mounted (SDK 1.6.15), kept in
|
|
490
|
+
* {@link TestHost.panels}; disposing a panel removes only its own.
|
|
491
|
+
*
|
|
492
|
+
* @example Check the adjust panel's locks
|
|
493
|
+
* The plugin's adjust panel reports a drag; the test reads the locks it
|
|
494
|
+
* sent. `mounted(slot)` picks one of the plugin's panels by slot.
|
|
495
|
+
* ```ts
|
|
496
|
+
* import assert from "node:assert/strict";
|
|
497
|
+
* declare const host: TestHost;
|
|
498
|
+
* // ---cut---
|
|
499
|
+
* const panel: FakePanel = host.mounted("adjust");
|
|
500
|
+
* assert.deepEqual(panel.locks, { focused: false, dragging: true, popupOpen: false });
|
|
501
|
+
* ```n *
|
|
502
|
+
* @capability None.
|
|
503
|
+
* @since 1.6.15
|
|
504
|
+
* @category Testing
|
|
505
|
+
*/
|
|
506
|
+
export type FakePanel = Omit<FakeWindow, "callbacks" | "userClose"> & {
|
|
507
|
+
/** `"bottom"`, `"sidebar"`, `"adjust"` or `"backdrop"`. */
|
|
508
|
+
slot: string;
|
|
509
|
+
/** The exported component the SDK found in the file. */
|
|
510
|
+
component: string;
|
|
511
|
+
/** The last `panel.setInteraction(...)` locks, `null` before any. */
|
|
512
|
+
locks: Json;
|
|
513
|
+
};
|
|
483
514
|
/**
|
|
484
515
|
* An in-memory fake Vestra Player for plugin tests.
|
|
485
516
|
*
|
|
@@ -597,17 +628,16 @@ export declare class TestHost implements Transport {
|
|
|
597
628
|
/** Tool windows by id (see {@link TestHost.window}). */
|
|
598
629
|
readonly windows: Map<string, FakeWindow>;
|
|
599
630
|
/**
|
|
600
|
-
* The plugin's mounted
|
|
601
|
-
* See {@link TestHost.mounted}.
|
|
631
|
+
* The plugin's mounted panels by slot, in mount order (SDK 1.6.15: one
|
|
632
|
+
* panel per slot). See {@link TestHost.mounted}.
|
|
602
633
|
*/
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
}) | null;
|
|
634
|
+
readonly panels: Map<string, FakePanel>;
|
|
635
|
+
/**
|
|
636
|
+
* The plugin's mounted panel (bottom bar, sidebar, adjust column or
|
|
637
|
+
* backdrop), the last mounted when it has several, or `null`. See
|
|
638
|
+
* {@link TestHost.mounted}.
|
|
639
|
+
*/
|
|
640
|
+
get panel(): FakePanel | null;
|
|
611
641
|
/** The plugin's commands by local id (see {@link TestHost.command}). */
|
|
612
642
|
readonly commands: Map<string, FakeCommand>;
|
|
613
643
|
/** The player's 14 core actions (`host/<id>`), kept apart from the plugin's `commands`. */
|
|
@@ -2527,8 +2557,9 @@ export declare class TestHost implements Transport {
|
|
|
2527
2557
|
*/
|
|
2528
2558
|
get conflicts(): string[][];
|
|
2529
2559
|
/**
|
|
2530
|
-
* Change the keys of one of the plugin's commands
|
|
2531
|
-
*
|
|
2560
|
+
* Change the keys of one of the plugin's commands, or of one of the
|
|
2561
|
+
* player's core commands by its `host/<id>` (SDK 1.6.16), as the user
|
|
2562
|
+
* does in Keyboard Shortcuts (SDK 1.6.6): `inputs` replaces its keys (`[]`
|
|
2532
2563
|
* clears them, as Ignore Default Shortcuts does for every default),
|
|
2533
2564
|
* `null` gives it its own defaults back. It writes
|
|
2534
2565
|
* {@link TestHost.bindings | bindings.overlay}, and the plugin hears it
|
|
@@ -2550,7 +2581,8 @@ export declare class TestHost implements Transport {
|
|
|
2550
2581
|
* ```
|
|
2551
2582
|
*
|
|
2552
2583
|
* @capability None.
|
|
2553
|
-
* @throws `Error` `command` is
|
|
2584
|
+
* @throws `Error` `command` is neither a command of the plugin nor a
|
|
2585
|
+
* core command.
|
|
2554
2586
|
* @since 1.6.6
|
|
2555
2587
|
*/
|
|
2556
2588
|
rebind(command: string, inputs: readonly string[] | null): void;
|
|
@@ -2814,9 +2846,11 @@ export declare class TestHost implements Transport {
|
|
|
2814
2846
|
*/
|
|
2815
2847
|
window(id: string): FakeWindow;
|
|
2816
2848
|
/**
|
|
2817
|
-
* The plugin's mounted panel (bottom bar, sidebar
|
|
2818
|
-
*
|
|
2819
|
-
*
|
|
2849
|
+
* The plugin's mounted panel (bottom bar, sidebar, adjust column or
|
|
2850
|
+
* backdrop): the one in `slot`, or without it the only one (SDK 1.6.15: a
|
|
2851
|
+
* plugin mounts one panel per slot; with several, name the slot). Throws
|
|
2852
|
+
* when there is none. Its `props` use Slint (kebab-case) names; `emit`
|
|
2853
|
+
* fires a callback on the panel's global.
|
|
2820
2854
|
*
|
|
2821
2855
|
* @example Select a row in the plugin's sidebar panel
|
|
2822
2856
|
* The test checks the panel sits in the sidebar and selects its third
|
|
@@ -2835,14 +2869,7 @@ export declare class TestHost implements Transport {
|
|
|
2835
2869
|
* @capability None.
|
|
2836
2870
|
* @since 1.0.0
|
|
2837
2871
|
*/
|
|
2838
|
-
mounted(
|
|
2839
|
-
/** `"bottom"`, `"sidebar"`, `"adjust"` or `"backdrop"`. */
|
|
2840
|
-
slot: string;
|
|
2841
|
-
/** The exported component the SDK found in the file. */
|
|
2842
|
-
component: string;
|
|
2843
|
-
/** The last `panel.setInteraction(...)` locks, `null` before any. */
|
|
2844
|
-
locks: Json;
|
|
2845
|
-
};
|
|
2872
|
+
mounted(slot?: "bottom" | "sidebar" | "adjust" | "backdrop"): FakePanel;
|
|
2846
2873
|
/**
|
|
2847
2874
|
* The parameters of every request of one wire method, oldest first.
|
|
2848
2875
|
*
|
package/dist/plugin/testing.js
CHANGED
|
@@ -330,6 +330,8 @@ const SLOT_LABELS = {
|
|
|
330
330
|
backdrop: "video backdrop",
|
|
331
331
|
adjust: "adjust column",
|
|
332
332
|
};
|
|
333
|
+
/** The view a panel's writes are kept under (the player's, per slot). */
|
|
334
|
+
const mountView = (slot) => slot === "bottom" ? "$mount" : `$mount:${slot}`;
|
|
333
335
|
/** Texts only the test host uses, with their Chinese of SDK 1.5.8. */
|
|
334
336
|
const TEST_ZH_HANS = {
|
|
335
337
|
"this site": "这个网站",
|
|
@@ -521,10 +523,18 @@ export class TestHost {
|
|
|
521
523
|
/** Tool windows by id (see {@link TestHost.window}). */
|
|
522
524
|
windows = new Map();
|
|
523
525
|
/**
|
|
524
|
-
* The plugin's mounted
|
|
525
|
-
* See {@link TestHost.mounted}.
|
|
526
|
+
* The plugin's mounted panels by slot, in mount order (SDK 1.6.15: one
|
|
527
|
+
* panel per slot). See {@link TestHost.mounted}.
|
|
526
528
|
*/
|
|
527
|
-
|
|
529
|
+
panels = new Map();
|
|
530
|
+
/**
|
|
531
|
+
* The plugin's mounted panel (bottom bar, sidebar, adjust column or
|
|
532
|
+
* backdrop), the last mounted when it has several, or `null`. See
|
|
533
|
+
* {@link TestHost.mounted}.
|
|
534
|
+
*/
|
|
535
|
+
get panel() {
|
|
536
|
+
return [...this.panels.values()].at(-1) ?? null;
|
|
537
|
+
}
|
|
528
538
|
/** The plugin's commands by local id (see {@link TestHost.command}). */
|
|
529
539
|
commands = new Map();
|
|
530
540
|
/** The player's 14 core actions (`host/<id>`), kept apart from the plugin's `commands`. */
|
|
@@ -3234,8 +3244,9 @@ export class TestHost {
|
|
|
3234
3244
|
return this.coreCommands.has(id) ? id : `${this.manifestId}/${id}`;
|
|
3235
3245
|
}
|
|
3236
3246
|
/**
|
|
3237
|
-
* Change the keys of one of the plugin's commands
|
|
3238
|
-
*
|
|
3247
|
+
* Change the keys of one of the plugin's commands, or of one of the
|
|
3248
|
+
* player's core commands by its `host/<id>` (SDK 1.6.16), as the user
|
|
3249
|
+
* does in Keyboard Shortcuts (SDK 1.6.6): `inputs` replaces its keys (`[]`
|
|
3239
3250
|
* clears them, as Ignore Default Shortcuts does for every default),
|
|
3240
3251
|
* `null` gives it its own defaults back. It writes
|
|
3241
3252
|
* {@link TestHost.bindings | bindings.overlay}, and the plugin hears it
|
|
@@ -3257,11 +3268,12 @@ export class TestHost {
|
|
|
3257
3268
|
* ```
|
|
3258
3269
|
*
|
|
3259
3270
|
* @capability None.
|
|
3260
|
-
* @throws `Error` `command` is
|
|
3271
|
+
* @throws `Error` `command` is neither a command of the plugin nor a
|
|
3272
|
+
* core command.
|
|
3261
3273
|
* @since 1.6.6
|
|
3262
3274
|
*/
|
|
3263
3275
|
rebind(command, inputs) {
|
|
3264
|
-
if (!this.commands.has(command))
|
|
3276
|
+
if (!this.commands.has(command) && !this.coreCommands.has(command))
|
|
3265
3277
|
throw new Error(`test host: no command ${command}`);
|
|
3266
3278
|
const key = this.#bindingKey(command);
|
|
3267
3279
|
if (inputs === null)
|
|
@@ -3277,15 +3289,19 @@ export class TestHost {
|
|
|
3277
3289
|
#keysRevision = 0;
|
|
3278
3290
|
/**
|
|
3279
3291
|
* `commands.keys` as the player answers it: each of the plugin's own
|
|
3280
|
-
* commands
|
|
3281
|
-
*
|
|
3282
|
-
* them on
|
|
3292
|
+
* commands, and the player's core commands as `host/<id>` (SDK 1.6.16),
|
|
3293
|
+
* with the labels of the keys it holds now (the overlay, else its
|
|
3294
|
+
* defaults; not a key an earlier command holds), as menus write them on
|
|
3295
|
+
* `systemInfo.os`.
|
|
3283
3296
|
*/
|
|
3284
3297
|
#keys() {
|
|
3285
3298
|
const claims = this.#claims();
|
|
3286
3299
|
const mac = this.systemInfo.os === "macos";
|
|
3287
3300
|
const keys = {};
|
|
3288
|
-
for (const [id, { declaration }] of
|
|
3301
|
+
for (const [id, { declaration }] of [
|
|
3302
|
+
...this.commands,
|
|
3303
|
+
...this.coreCommands,
|
|
3304
|
+
]) {
|
|
3289
3305
|
const scope = declaration.focus ? "panel" : "global";
|
|
3290
3306
|
const current = this.bindings.overlay.get(this.#bindingKey(id)) ??
|
|
3291
3307
|
declaration.bindings ??
|
|
@@ -3627,9 +3643,11 @@ export class TestHost {
|
|
|
3627
3643
|
return window;
|
|
3628
3644
|
}
|
|
3629
3645
|
/**
|
|
3630
|
-
* The plugin's mounted panel (bottom bar, sidebar
|
|
3631
|
-
*
|
|
3632
|
-
*
|
|
3646
|
+
* The plugin's mounted panel (bottom bar, sidebar, adjust column or
|
|
3647
|
+
* backdrop): the one in `slot`, or without it the only one (SDK 1.6.15: a
|
|
3648
|
+
* plugin mounts one panel per slot; with several, name the slot). Throws
|
|
3649
|
+
* when there is none. Its `props` use Slint (kebab-case) names; `emit`
|
|
3650
|
+
* fires a callback on the panel's global.
|
|
3633
3651
|
*
|
|
3634
3652
|
* @example Select a row in the plugin's sidebar panel
|
|
3635
3653
|
* The test checks the panel sits in the sidebar and selects its third
|
|
@@ -3648,11 +3666,27 @@ export class TestHost {
|
|
|
3648
3666
|
* @capability None.
|
|
3649
3667
|
* @since 1.0.0
|
|
3650
3668
|
*/
|
|
3651
|
-
mounted() {
|
|
3669
|
+
mounted(slot) {
|
|
3670
|
+
if (slot !== undefined) {
|
|
3671
|
+
const panel = this.panels.get(slot);
|
|
3672
|
+
if (!panel)
|
|
3673
|
+
throw new Error(`no panel mounted in the ${slot}`);
|
|
3674
|
+
return panel;
|
|
3675
|
+
}
|
|
3676
|
+
if (this.panels.size > 1)
|
|
3677
|
+
throw new Error(`panels are mounted in ${[...this.panels.keys()].join(", ")}: name the slot`);
|
|
3652
3678
|
if (!this.panel)
|
|
3653
3679
|
throw new Error("no panel mounted");
|
|
3654
3680
|
return this.panel;
|
|
3655
3681
|
}
|
|
3682
|
+
/** The panel a request is about: its `slot`, else the only one. */
|
|
3683
|
+
#panelFor(p) {
|
|
3684
|
+
const slot = typeof p.slot === "string" ? p.slot : undefined;
|
|
3685
|
+
const panel = slot ? this.panels.get(slot) : this.panel;
|
|
3686
|
+
if (!panel)
|
|
3687
|
+
throw new HostError("missing", "owner has no ready mount");
|
|
3688
|
+
return panel;
|
|
3689
|
+
}
|
|
3656
3690
|
/**
|
|
3657
3691
|
* The parameters of every request of one wire method, oldest first.
|
|
3658
3692
|
*
|
|
@@ -4260,16 +4294,18 @@ export class TestHost {
|
|
|
4260
4294
|
// A sidebar panel is never live (player 0.7.3): the current tab keeps
|
|
4261
4295
|
// the plugin running as busy work, a background tab not at all. The
|
|
4262
4296
|
// adjust column's current tab only while the column is open (0.7.6).
|
|
4263
|
-
|
|
4264
|
-
if (
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
if (
|
|
4269
|
-
|
|
4297
|
+
for (const panel of this.panels.values()) {
|
|
4298
|
+
if (panel.slot === "sidebar") {
|
|
4299
|
+
if (this.layout.sidebar?.owner === 1)
|
|
4300
|
+
reasons.push("its sidebar tab is the current tab");
|
|
4301
|
+
}
|
|
4302
|
+
else if (panel.slot === "adjust") {
|
|
4303
|
+
if (this.layout.adjust?.owner === 1 && this.layout.adjust.preferred)
|
|
4304
|
+
reasons.push("its adjust tab is the current tab");
|
|
4305
|
+
}
|
|
4306
|
+
else
|
|
4307
|
+
reasons.push("a mounted panel");
|
|
4270
4308
|
}
|
|
4271
|
-
else if (this.panel)
|
|
4272
|
-
reasons.push("a mounted panel");
|
|
4273
4309
|
for (const [id, window] of this.windows)
|
|
4274
4310
|
if (window.visible)
|
|
4275
4311
|
reasons.push(`an open window (${id})`);
|
|
@@ -4501,10 +4537,11 @@ export class TestHost {
|
|
|
4501
4537
|
throw new HostError("missing", "view not found");
|
|
4502
4538
|
},
|
|
4503
4539
|
"ui.mount": (p) => {
|
|
4504
|
-
if (this.panel)
|
|
4505
|
-
throw new HostError("conflict", "owner already mounted");
|
|
4506
4540
|
if (!(String(p.slot) in SLOT_LABELS))
|
|
4507
4541
|
throw new HostError("invalid", "unknown mount slot");
|
|
4542
|
+
// One panel per slot and plugin (player 0.7.6).
|
|
4543
|
+
if (this.panels.has(String(p.slot)))
|
|
4544
|
+
throw new HostError("conflict", "this plugin already has a panel in this slot");
|
|
4508
4545
|
// Like the player: one panel in the bottom bar and the backdrop, any
|
|
4509
4546
|
// number of tabs in the sidebar (player 0.7.3; 0.4.x to 0.7.2 took 8)
|
|
4510
4547
|
// and in the adjust column (player 0.7.6).
|
|
@@ -4520,10 +4557,11 @@ export class TestHost {
|
|
|
4520
4557
|
]));
|
|
4521
4558
|
const properties = this.#initialValues(this.#shownValues(p.properties));
|
|
4522
4559
|
this.#seeImages(properties);
|
|
4523
|
-
|
|
4560
|
+
const panelSlot = String(p.slot);
|
|
4561
|
+
this.#resetWrites(mountView(panelSlot));
|
|
4524
4562
|
const host = this;
|
|
4525
|
-
this.
|
|
4526
|
-
slot:
|
|
4563
|
+
this.panels.set(panelSlot, {
|
|
4564
|
+
slot: panelSlot,
|
|
4527
4565
|
file: String(p.file),
|
|
4528
4566
|
component: String(p.component),
|
|
4529
4567
|
visible: true,
|
|
@@ -4532,11 +4570,12 @@ export class TestHost {
|
|
|
4532
4570
|
emit(callback, ...args) {
|
|
4533
4571
|
host.emit("ui.callback", {
|
|
4534
4572
|
view: "$mount",
|
|
4573
|
+
slot: panelSlot,
|
|
4535
4574
|
callback: kebab(callback),
|
|
4536
4575
|
args,
|
|
4537
4576
|
});
|
|
4538
4577
|
},
|
|
4539
|
-
};
|
|
4578
|
+
});
|
|
4540
4579
|
if (p.slot === "backdrop") {
|
|
4541
4580
|
this.backdrop = { owner: this.manifestId, effective: true };
|
|
4542
4581
|
return { status: "ready", prepareMs: 0, shellGeneration: 1 };
|
|
@@ -4551,18 +4590,24 @@ export class TestHost {
|
|
|
4551
4590
|
});
|
|
4552
4591
|
return { status: "ready", prepareMs: 0, shellGeneration: 1 };
|
|
4553
4592
|
},
|
|
4554
|
-
"ui.unmount": () => {
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4593
|
+
"ui.unmount": (p) => {
|
|
4594
|
+
// The slot's panel, or without one every panel (as the player).
|
|
4595
|
+
const slots = typeof p.slot === "string" ? [p.slot] : [...this.panels.keys()];
|
|
4596
|
+
for (const slot of slots) {
|
|
4597
|
+
if (!this.panels.delete(slot))
|
|
4598
|
+
continue;
|
|
4599
|
+
if (slot === "backdrop")
|
|
4600
|
+
this.backdrop = null;
|
|
4601
|
+
else
|
|
4602
|
+
this.#removePanel(slot, 1);
|
|
4603
|
+
}
|
|
4560
4604
|
},
|
|
4561
4605
|
"ui.menu": (p) => {
|
|
4562
|
-
if (!this.
|
|
4606
|
+
if (!this.panels.size)
|
|
4563
4607
|
throw new HostError("unavailable", "panel not shown");
|
|
4564
|
-
const
|
|
4565
|
-
|
|
4608
|
+
const panel = this.#panelFor(p);
|
|
4609
|
+
const tabs = panel.slot === "sidebar" || panel.slot === "adjust"
|
|
4610
|
+
? this.layout[panel.slot]
|
|
4566
4611
|
: null;
|
|
4567
4612
|
if (tabs && tabs.owner !== 1)
|
|
4568
4613
|
throw new HostError("unavailable", "the panel's tab is not the current one");
|
|
@@ -4613,8 +4658,9 @@ export class TestHost {
|
|
|
4613
4658
|
: collapsed
|
|
4614
4659
|
? "fullscreen"
|
|
4615
4660
|
: null;
|
|
4616
|
-
|
|
4617
|
-
|
|
4661
|
+
const panel = this.panels.get(slot);
|
|
4662
|
+
if (panel)
|
|
4663
|
+
panel.visible = p.visible;
|
|
4618
4664
|
}
|
|
4619
4665
|
if (typeof p.detached === "boolean")
|
|
4620
4666
|
state.detached = p.detached;
|
|
@@ -4880,9 +4926,9 @@ export class TestHost {
|
|
|
4880
4926
|
this.emit("sequence.step", { direction });
|
|
4881
4927
|
},
|
|
4882
4928
|
"ui.setMount": (p) => {
|
|
4883
|
-
const panel = this
|
|
4929
|
+
const panel = this.#panelFor(p);
|
|
4884
4930
|
const property = String(p.property);
|
|
4885
|
-
const next = this.#write(
|
|
4931
|
+
const next = this.#write(mountView(panel.slot), property, p, panel.props[property]);
|
|
4886
4932
|
// A part of a value sent in parts is held until the last (player 0.6.0).
|
|
4887
4933
|
if (next !== undefined)
|
|
4888
4934
|
panel.props[property] = next;
|
|
@@ -5122,7 +5168,10 @@ export class TestHost {
|
|
|
5122
5168
|
})));
|
|
5123
5169
|
return { applied: true };
|
|
5124
5170
|
},
|
|
5125
|
-
"ui.interaction": (p) =>
|
|
5171
|
+
"ui.interaction": (p) => {
|
|
5172
|
+
const { slot: _, ...locks } = p;
|
|
5173
|
+
this.#panelFor(p).locks = locks;
|
|
5174
|
+
},
|
|
5126
5175
|
"dialogs.confirm": (p) => {
|
|
5127
5176
|
this.confirms.push(p);
|
|
5128
5177
|
const shown = (field, formatted = false) => p[field] === undefined
|
package/dist/plugin/types.d.ts
CHANGED
|
@@ -1470,8 +1470,11 @@ export interface Commands {
|
|
|
1470
1470
|
* player, and until its answer arrives (a few milliseconds) every
|
|
1471
1471
|
* command reads `[]`; a binding that read it runs again then.
|
|
1472
1472
|
*
|
|
1473
|
-
*
|
|
1474
|
-
*
|
|
1473
|
+
* The plugin's own commands, and the player's own as `host/<id>` (SDK
|
|
1474
|
+
* 1.6.16; `host/volume-up`, `host/mute`: the ids of
|
|
1475
|
+
* {@link "@vestra-player/sdk/testing"!BUILTIN_COMMANDS | BUILTIN_COMMANDS} rows owned by `host`), for a panel that
|
|
1476
|
+
* shows the player's keys beside its own controls; an id the plugin has
|
|
1477
|
+
* not added (or another plugin's) reads `[]`. Needs nothing beyond `commands`, not
|
|
1475
1478
|
* `bindings.manage` (the whole binding table, every plugin's, is
|
|
1476
1479
|
* {@link Bindings.list}). Without the `commands` capability every
|
|
1477
1480
|
* command reads `[]`. Players before 0.7.6 have no `keys` (the player
|
|
@@ -4095,9 +4098,14 @@ export interface BackdropSlot {
|
|
|
4095
4098
|
* or the sidebar moves to or from its floating window, while the global is
|
|
4096
4099
|
* one stable address.
|
|
4097
4100
|
*
|
|
4098
|
-
*
|
|
4099
|
-
*
|
|
4100
|
-
*
|
|
4101
|
+
* A plugin mounts at most one panel per slot (SDK 1.6.15, player 0.7.6;
|
|
4102
|
+
* before, one panel in all): a playback plugin can have its control bar in
|
|
4103
|
+
* `"bottom"` and its controls in `"adjust"`. Each {@link Panel} has its own
|
|
4104
|
+
* bridge, state, `toggle()` and `setInteraction()`; disposing one leaves
|
|
4105
|
+
* the others, and stopping the plugin unmounts them all. The bottom bar and
|
|
4106
|
+
* the backdrop hold one panel for all plugins; the sidebar and the adjust
|
|
4107
|
+
* column one tab per plugin. {@link Panels.bottom}, {@link Panels.sidebar}
|
|
4108
|
+
* and {@link Panels.adjust} describe the positions, whoever mounted there.
|
|
4101
4109
|
*
|
|
4102
4110
|
* @capability ui.mount
|
|
4103
4111
|
*
|
|
@@ -4194,8 +4202,11 @@ export interface Panels {
|
|
|
4194
4202
|
* @returns A {@link Panel} owned by this scope; await {@link Panel.ready}
|
|
4195
4203
|
* for the result.
|
|
4196
4204
|
*
|
|
4197
|
-
* @throws `Error` without a code (throws) This plugin already has a panel
|
|
4198
|
-
*
|
|
4205
|
+
* @throws `Error` without a code (throws) This plugin already has a panel
|
|
4206
|
+
* in this slot (a panel in another slot is fine from player 0.7.6;
|
|
4207
|
+
* players before 0.7.6 refuse a second panel with `conflict`, so a
|
|
4208
|
+
* plugin that mounts two declares `minPlayerVersion` 0.7.6), or the file
|
|
4209
|
+
* exports no component or global, or several and `options`
|
|
4199
4210
|
* does not name one. A file that cannot be read throws Node's file system
|
|
4200
4211
|
* error (`code` `ENOENT` and so on).
|
|
4201
4212
|
* @throws The errors of {@link Panel.ready} (rejects `ready`) The player
|
package/dist/plugin/ui.js
CHANGED
|
@@ -839,13 +839,15 @@ class PanelHandle extends ViewBase {
|
|
|
839
839
|
#locks = { focused: false, dragging: false, popupOpen: false };
|
|
840
840
|
#interaction;
|
|
841
841
|
constructor(scope, slot, file, options) {
|
|
842
|
-
|
|
843
|
-
|
|
842
|
+
// One panel per slot (SDK 1.6.15, player 0.7.6; a player before 0.7.6
|
|
843
|
+
// refuses a second panel with `conflict`).
|
|
844
|
+
if (scope.runtime.views.has(`panel:${slot}`))
|
|
845
|
+
throw new Error(`this plugin already has a panel in the ${slot}`);
|
|
844
846
|
super(scope);
|
|
845
847
|
this.#slot = slot;
|
|
846
848
|
const runtime = scope.runtime;
|
|
847
|
-
runtime.views.set(
|
|
848
|
-
this.#interaction = new Latest((locks) => runtime.host.ui.interaction(locks));
|
|
849
|
+
runtime.views.set(`panel:${slot}`, (callback, args) => this.dispatch(callback, args));
|
|
850
|
+
this.#interaction = new Latest((locks) => runtime.host.ui.interaction(locks, this.#named()));
|
|
849
851
|
const component = options.component ?? exported(runtime.directory, file, "component");
|
|
850
852
|
const global = options.global ?? exported(runtime.directory, file, "global");
|
|
851
853
|
scope.add(this);
|
|
@@ -874,8 +876,17 @@ class PanelHandle extends ViewBase {
|
|
|
874
876
|
live() {
|
|
875
877
|
return this.#mounted && !this.closed;
|
|
876
878
|
}
|
|
879
|
+
/**
|
|
880
|
+
* The slot to name in a request about this panel: only while the plugin
|
|
881
|
+
* has panels in more than one slot (the player then needs it); a plugin
|
|
882
|
+
* with one panel sends what it always sent.
|
|
883
|
+
*/
|
|
884
|
+
#named() {
|
|
885
|
+
const panels = [...this.scope.runtime.views.keys()].filter((key) => key.startsWith("panel:"));
|
|
886
|
+
return panels.length > 1 ? this.#slot : undefined;
|
|
887
|
+
}
|
|
877
888
|
write(property, write) {
|
|
878
|
-
return this.scope.runtime.host.ui.setMount(property, write);
|
|
889
|
+
return this.scope.runtime.host.ui.setMount(property, write, this.#named());
|
|
879
890
|
}
|
|
880
891
|
get state() {
|
|
881
892
|
const service = layoutOf(this.scope.runtime);
|
|
@@ -932,7 +943,7 @@ class PanelHandle extends ViewBase {
|
|
|
932
943
|
}
|
|
933
944
|
async showMenu(items, at) {
|
|
934
945
|
await this.ready;
|
|
935
|
-
await this.scope.runtime.host.ui.menu(items.map((item) => item?.id ?? null), at.x, at.y);
|
|
946
|
+
await this.scope.runtime.host.ui.menu(items.map((item) => item?.id ?? null), at.x, at.y, this.#named());
|
|
936
947
|
}
|
|
937
948
|
onDrop(listener) {
|
|
938
949
|
const watch = dropsOf(this.scope.runtime).listen(this.scope, (event) => this.scope.run(listener, event));
|
|
@@ -950,10 +961,10 @@ class PanelHandle extends ViewBase {
|
|
|
950
961
|
this.scope.forget(this);
|
|
951
962
|
this.#interaction.stop();
|
|
952
963
|
if (this.#mounted)
|
|
953
|
-
await this.scope.runtime.host.ui.unmount().catch(() => { });
|
|
964
|
+
await this.scope.runtime.host.ui.unmount(this.#named()).catch(() => { });
|
|
954
965
|
this.#mounted = false;
|
|
955
966
|
await this.release();
|
|
956
|
-
this.scope.runtime.views.delete(
|
|
967
|
+
this.scope.runtime.views.delete(`panel:${this.#slot}`);
|
|
957
968
|
// Listeners of `onChange` hear `null`.
|
|
958
969
|
this.scope.runtime.invalidate();
|
|
959
970
|
await layoutOf(this.scope.runtime).refresh();
|
package/dist/wire.d.ts
CHANGED
|
@@ -275,6 +275,8 @@ export interface WireTimeline {
|
|
|
275
275
|
marks: WireMark[];
|
|
276
276
|
ranges?: WireRange[];
|
|
277
277
|
}
|
|
278
|
+
/** A panel position (`ui.mount`'s `slot`). */
|
|
279
|
+
export type MountSlot = "bottom" | "sidebar" | "backdrop" | "adjust";
|
|
278
280
|
/** The backdrop as `layout.state` reports it; `null` without one. */
|
|
279
281
|
export interface LayoutBackdrop {
|
|
280
282
|
owner: number;
|
|
@@ -752,14 +754,14 @@ export declare function createWire(transport: Transport): {
|
|
|
752
754
|
prepareMs: number;
|
|
753
755
|
shellGeneration: number;
|
|
754
756
|
}>;
|
|
755
|
-
setMount: (property: string, write: PropertyWrite) => Promise<void>;
|
|
757
|
+
setMount: (property: string, write: PropertyWrite, slot?: MountSlot) => Promise<void>;
|
|
756
758
|
interaction: (locks: {
|
|
757
759
|
focused: boolean;
|
|
758
760
|
dragging: boolean;
|
|
759
761
|
popupOpen: boolean;
|
|
760
|
-
}) => Promise<void>;
|
|
761
|
-
unmount: () => Promise<void>;
|
|
762
|
-
menu: (items: (string | null)[], x: number, y: number) => Promise<void>;
|
|
762
|
+
}, slot?: MountSlot) => Promise<void>;
|
|
763
|
+
unmount: (slot?: MountSlot) => Promise<void>;
|
|
764
|
+
menu: (items: (string | null)[], x: number, y: number, slot?: MountSlot) => Promise<void>;
|
|
763
765
|
open: (id: string, file: string, properties?: Record<string, Json>, callbacks?: string[]) => Promise<void>;
|
|
764
766
|
set: (id: string, property: string, write: PropertyWrite) => Promise<void>;
|
|
765
767
|
show: (id: string, visible: boolean) => Promise<void>;
|
package/dist/wire.js
CHANGED
|
@@ -328,10 +328,24 @@ export function createWire(transport) {
|
|
|
328
328
|
base,
|
|
329
329
|
}),
|
|
330
330
|
mount: (options) => transport.request("ui.mount", options),
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
331
|
+
// `slot`: which of the plugin's panels (player 0.7.6: one per slot;
|
|
332
|
+
// older players have one and ignore it).
|
|
333
|
+
setMount: (property, write, slot) => transport.request("ui.setMount", {
|
|
334
|
+
property,
|
|
335
|
+
...write,
|
|
336
|
+
...(slot ? { slot } : {}),
|
|
337
|
+
}),
|
|
338
|
+
interaction: (locks, slot) => transport.request("ui.interaction", {
|
|
339
|
+
...locks,
|
|
340
|
+
...(slot ? { slot } : {}),
|
|
341
|
+
}),
|
|
342
|
+
unmount: (slot) => transport.request("ui.unmount", slot ? { slot } : undefined),
|
|
343
|
+
menu: (items, x, y, slot) => transport.request("ui.menu", {
|
|
344
|
+
items,
|
|
345
|
+
x,
|
|
346
|
+
y,
|
|
347
|
+
...(slot ? { slot } : {}),
|
|
348
|
+
}),
|
|
335
349
|
open: (id, file, properties = {}, callbacks = []) => transport.request("ui.open", { id, file, properties, callbacks }),
|
|
336
350
|
set: (id, property, write) => transport.request("ui.set", { id, property, ...write }),
|
|
337
351
|
show: (id, visible) => transport.request("ui.show", { id, visible }),
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vestra Player SDK
|
|
2
2
|
|
|
3
|
-
> @vestra-player/sdk 1.6.
|
|
3
|
+
> @vestra-player/sdk 1.6.16: write plugins for Vestra Player in TypeScript (plugin API `vestra/1`). A plugin is a folder with `manifest.json` and an entry module whose default export `activate(plugin)` the player calls. The documentation is a tree of short pages read by path, like `go doc`: the same pages and API as https://vestrasys.github.io/vestra-player-sdk/.
|
|
4
4
|
|
|
5
5
|
## Read the documentation
|
|
6
6
|
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
- `/API/Sources`: 7 entries: ResolverOptions, WebResolverOptions, FileResolverOptions, ResolvedStream, Resolver, Resolvers, ResolvedMedia
|
|
39
39
|
- `/API/Subtitles`: 5 entries: SubtitleTrack, SubtitlesState, SubtitleConditional, Subtitles, SubtitleStyle
|
|
40
40
|
- `/API/UI`: 44 entries: ImageRef, ImageOptions, MarkdownRef, MarkdownOptions, PropValue, PropData, Props, Ui, View, Window, Windows, SlotState, SlotPanel, PanelState, PanelSlot, SidebarSlot, Panel,…
|
|
41
|
-
- `/API/Testing`:
|
|
41
|
+
- `/API/Testing`: 34 entries: CapabilityInfo, CAPABILITY_INFO, MESSAGE_LIMIT, COMMAND_LIMITS, MENU_IDS, BAR_BUTTON_ICONS, BAR_BUTTON_LIMITS, BuiltinSubmenu, BUILTIN_SUBMENUS, BuiltinCommand, BUILTIN_COMMANDS, LOCALES,…
|
|
42
42
|
- `/API/Docs`: 4 entries: DOCS_PAGE_BYTES, DocsOptions, docs, searchDocs
|