@vestra-player/sdk 1.6.7 → 1.6.8

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 CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.6.8
4
+
5
+ **Who must change: nobody; authors of a bottom bar should move to `content-min-width`.** Documentation, a read-only Slint property and a removed CLI warning: no change to the TypeScript API, the wire or `TestHost`, `apiVersion` stays `vestra/1`, no new capability. A plugin's `button` declarations stay as they are. A bottom bar that still places `BarButtons` keeps working on player 0.7.6 (it shows that strip, and the player draws no second one); it is deprecated and goes in a later patch.
6
+
7
+ - **The player places the bottom bar's button strip** (player 0.7.6, menu redesign step 3a). It draws the strip at the right end of the bottom slot, also when no plugin mounts a bottom bar (in a band of its own): the plugins' buttons, a » menu, the player's **Command Palette** (`host/palette`, a magnifier) and **Toggle Sidebar**. [Bottom-bar buttons](docs/explanation/commands.md#bottom-bar-buttons) now reads: buttons are ordered by `order`, then by plugin id; lower `order` comes first and stays visible longest; when the strip runs out of room, or more than 8 plugin buttons are declared, the remaining buttons move to the » menu, in the same order; a button is never dropped. Before player 0.7.6 a narrow strip lost its lowest orders first and the player left out all but the eight highest; `BAR_BUTTON_LIMITS.total` is now what the strip holds. [Reference: commands](docs/reference/commands.md#bottom-bar-buttons), [Reference: limits](docs/reference/limits.md#bottom-bar-buttons), `CommandButton`, `CommandOptions.button` and `BAR_BUTTON_LIMITS` say so.
8
+ - **Writing a bottom bar** ([Interface guidelines](docs/guidelines/interface.md#writing-a-bottom-bar)): a bar places nothing. It reports the least width of its own controls in a `content-min-width` length property on the mounted component (the player gives the strip the rest, so the time label is never covered) and ends its row at the strip, reading `BarButtonsHost.width` (new, read only; `fixed` for an optional control kept ahead of plugin buttons) from `@vestra/bar-buttons.slint`. The file stays in the Slint library copy for that global; its `BarButtons` component is deprecated.
9
+ - **`@vestra/bar-buttons.slint`** (the read-only copy of the player's widget library, synced): `BarButtonsHost` gains `width`, `fixed`, `shown` and `more` (out: the strip's width, the cells a bar must leave free (the player's own and the » cell), the plugin buttons in the strip, whether » shows) and the player's `palette`, `overflow` and `room`; the comments describe the player's strip and mark `BarButtons` deprecated.
10
+ - **`vestra-plugin check` no longer warns** that a bottom bar does not place `BarButtons`: since player 0.7.6 that is the right thing to do.
11
+
3
12
  ## 1.6.7
4
13
 
5
14
  **Who must change: nobody.** The 1.6.6 release below, published again under a new number: its npm publish failed (the provenance transparency log returned 500, then 409 for the same tarball), so 1.6.6 never reached npm. Nothing else changed.
@@ -81,7 +81,6 @@ import {
81
81
  basename,
82
82
  dirname,
83
83
  extname,
84
- isAbsolute,
85
84
  join,
86
85
  relative,
87
86
  resolve,
@@ -363,10 +362,7 @@ async function check(target, report = null) {
363
362
  }
364
363
  say(`${target.name}: capabilities declared for every API use`);
365
364
  if (report) return;
366
- for (const line of [
367
- ...(await bottomBarWarnings(target)),
368
- ...(await forWarnings(target)),
369
- ])
365
+ for (const line of await forWarnings(target))
370
366
  console.log(`${target.name}: warning: ${line}`);
371
367
  // Translation warnings never fail the check.
372
368
  if (present(join(target.directory, "locales"))) {
@@ -432,85 +428,6 @@ function slintCode(text) {
432
428
  return out;
433
429
  }
434
430
 
435
- /** Whether `path` lies inside `directory` (not a sibling sharing its prefix). */
436
- function inside(directory, path) {
437
- const rel = relative(resolve(directory), path);
438
- return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
439
- }
440
-
441
- /**
442
- * Whether the Slint file at `file` (relative to the plugin directory)
443
- * imports `BarButtons` from `@vestra/bar-buttons.slint`, itself or
444
- * through the plugin's own Slint files (relative paths, any depth, inside
445
- * the plugin directory). Local re-exports count as such files too:
446
- * `export { Row } from "row.slint"` and `export * from "row.slint"` are
447
- * followed, and `export { BarButtons } from "@vestra/bar-buttons.slint"` (or
448
- * `export * from` it) in a file the bar imports counts as placing it.
449
- * Comments do not count.
450
- */
451
- async function importsBarButtons(target, file, seen = new Set()) {
452
- const path = resolve(target.directory, file);
453
- if (seen.has(path) || !inside(target.directory, path)) return false;
454
- seen.add(path);
455
- const text = await readFile(path, "utf8").catch(() => null);
456
- if (text === null) return false;
457
- const code = slintCode(text);
458
- // { names (or "*"), from }: imports, and re-exports with a source file.
459
- const imports = [
460
- ...code.matchAll(
461
- /\b(?:import|export)\s*(?:(\*)\s*from\s*|\{([^}]*)\}\s*from\s*)?"([^"]+)"/g,
462
- ),
463
- ].map(([, star, names, from]) => ({ names: star ?? names ?? "", from }));
464
- for (const { names, from } of imports)
465
- if (
466
- from === "@vestra/bar-buttons.slint" &&
467
- (names === "*" ||
468
- names
469
- .split(",")
470
- .some((name) => /^BarButtons(\s+as\s+[\w-]+)?$/.test(name.trim())))
471
- )
472
- return true;
473
- for (const { from } of imports) {
474
- if (
475
- from.startsWith("@") ||
476
- !from.endsWith(".slint") ||
477
- from === "std-widgets.slint"
478
- )
479
- continue;
480
- if (await importsBarButtons(target, join(dirname(file), from), seen))
481
- return true;
482
- }
483
- return false;
484
- }
485
-
486
- /**
487
- * A plugin that mounts a bottom bar (`panels.mount("bottom", "<file>")`)
488
- * whose Slint file does not import `BarButtons` (`@vestra/bar-buttons.slint`),
489
- * itself or through its local imports: while it is the bottom bar, no
490
- * plugin's command button shows (SDK 1.5.29). The mount is read from the
491
- * source text: a literal file name in the call.
492
- */
493
- async function bottomBarWarnings(target) {
494
- const { typescript: sources } = await sourceFiles(target);
495
- const files = new Set();
496
- for (const file of sources) {
497
- const text = await readFile(join(target.directory, file), "utf8");
498
- for (const match of text.matchAll(
499
- /\.mount\(\s*["'`]bottom["'`]\s*,\s*["'`]([^"'`$]+)["'`]/g,
500
- ))
501
- files.add(match[1]);
502
- }
503
- const warnings = [];
504
- for (const file of files) {
505
- if (!present(join(target.directory, file))) continue;
506
- if (await importsBarButtons(target, file)) continue;
507
- warnings.push(
508
- `${file} is a bottom bar without BarButtons (import { BarButtons } from "@vestra/bar-buttons.slint"): while it is mounted, the command buttons of every plugin (and the player's sidebar toggle) show nowhere; see docs/guidelines/interface.md#writing-a-bottom-bar`,
509
- );
510
- }
511
- return warnings;
512
- }
513
-
514
431
  /**
515
432
  * A `for` over an array the plugin binds (an `in` or `in-out` property of
516
433
  * array type of a component or global in the same file), outside a
@@ -158,12 +158,11 @@ export declare const BAR_BUTTON_ICONS: readonly ["play", "pause", "stop", "back"
158
158
  /**
159
159
  * The player's limits on bottom-bar buttons (`CommandOptions.button`), the
160
160
  * same values as the player's (its tests check that they agree). A button
161
- * past `perPlugin` or `total` is left out: its command still registers and
162
- * its menu entry stays, and the player logs the button it left out
163
- * (`limit`). Which ones stay: each plugin's first declared button, then the
164
- * `total` highest by order, plugin id and declaration order: as in a narrow
165
- * strip, the lowest order goes first (equal orders: the smaller plugin id,
166
- * then the earlier declaration, goes first).
161
+ * past `perPlugin` has none (its command still registers and its menu entry
162
+ * stays). `total` is what the strip holds: the `total` lowest by order,
163
+ * plugin id and declaration order; the rest are in the strip's » menu, in
164
+ * the same order (older players keep the `total` highest and leave the
165
+ * others out).
167
166
  *
168
167
  * @since 1.5.29
169
168
  *
@@ -172,7 +171,7 @@ export declare const BAR_BUTTON_ICONS: readonly ["play", "pause", "stop", "back"
172
171
  export declare const BAR_BUTTON_LIMITS: {
173
172
  /** Buttons one plugin shows (1). */
174
173
  readonly perPlugin: 1;
175
- /** Buttons the player shows, every plugin together, besides its own sidebar toggle (8). */
174
+ /** Buttons in the strip, every plugin together, besides the player's own (8); the rest are in its » menu. */
176
175
  readonly total: 8;
177
176
  /** The highest `order` (999; the lowest is 0). */
178
177
  readonly maxOrder: 999;
package/dist/commands.js CHANGED
@@ -202,12 +202,11 @@ export const BAR_BUTTON_ICONS = [
202
202
  /**
203
203
  * The player's limits on bottom-bar buttons (`CommandOptions.button`), the
204
204
  * same values as the player's (its tests check that they agree). A button
205
- * past `perPlugin` or `total` is left out: its command still registers and
206
- * its menu entry stays, and the player logs the button it left out
207
- * (`limit`). Which ones stay: each plugin's first declared button, then the
208
- * `total` highest by order, plugin id and declaration order: as in a narrow
209
- * strip, the lowest order goes first (equal orders: the smaller plugin id,
210
- * then the earlier declaration, goes first).
205
+ * past `perPlugin` has none (its command still registers and its menu entry
206
+ * stays). `total` is what the strip holds: the `total` lowest by order,
207
+ * plugin id and declaration order; the rest are in the strip's » menu, in
208
+ * the same order (older players keep the `total` highest and leave the
209
+ * others out).
211
210
  *
212
211
  * @since 1.5.29
213
212
  *
@@ -216,7 +215,7 @@ export const BAR_BUTTON_ICONS = [
216
215
  export const BAR_BUTTON_LIMITS = {
217
216
  /** Buttons one plugin shows (1). */
218
217
  perPlugin: 1,
219
- /** Buttons the player shows, every plugin together, besides its own sidebar toggle (8). */
218
+ /** Buttons in the strip, every plugin together, besides the player's own (8); the rest are in its » menu. */
220
219
  total: 8,
221
220
  /** The highest `order` (999; the lowest is 0). */
222
221
  maxOrder: 999,
Binary file
@@ -2645,8 +2645,8 @@ export declare class TestHost implements Transport {
2645
2645
  * The plugin's bottom-bar buttons (`CommandOptions.button`) as the player
2646
2646
  * shows them: at most one, the first declared (`BAR_BUTTON_LIMITS`; a
2647
2647
  * later one stays a menu item only). Empty once the command is disposed.
2648
- * Whether the bar places them is the bar's business: the list is what
2649
- * the player hands to `BarButtons`.
2648
+ * Whether one is in the strip or its » menu is the player's business
2649
+ * (the room and the other plugins' buttons).
2650
2650
  *
2651
2651
  * @example Click the plugin's bottom-bar button in a test
2652
2652
  * The test finds the plugin's Store button, clicks it and checks that the
@@ -3405,8 +3405,8 @@ export class TestHost {
3405
3405
  * The plugin's bottom-bar buttons (`CommandOptions.button`) as the player
3406
3406
  * shows them: at most one, the first declared (`BAR_BUTTON_LIMITS`; a
3407
3407
  * later one stays a menu item only). Empty once the command is disposed.
3408
- * Whether the bar places them is the bar's business: the list is what
3409
- * the player hands to `BarButtons`.
3408
+ * Whether one is in the strip or its » menu is the player's business
3409
+ * (the room and the other plugins' buttons).
3410
3410
  *
3411
3411
  * @example Click the plugin's bottom-bar button in a test
3412
3412
  * The test finds the plugin's Store button, clicks it and checks that the
@@ -954,17 +954,17 @@ export type BarButtonIcon = "play" | "pause" | "stop" | "back" | "forward" | "op
954
954
  * A command's button on the bottom bar: {@link CommandOptions.button}.
955
955
  *
956
956
  * @remarks
957
- * **Where it shows.** The bottom bar places the player's strip of command
958
- * buttons, `BarButtons` from `@vestra/bar-buttons.slint`, at its right end;
959
- * the player fills it with the buttons of every plugin, left to right by
960
- * `order`, and its own sidebar toggle rightmost. When the window is narrow
961
- * the strip loses cells from its outer (left) end inward: the lowest order
962
- * goes first, the sidebar toggle last. A
963
- * bottom bar that does not place `BarButtons` shows no buttons: the
964
- * command's menu entry stays, and the player logs the buttons it cannot
965
- * show and whose bar hides them. The built-in bar (`vestra.playback`) places
966
- * it; see
967
- * [Writing a bottom bar](../../docs/guidelines/interface.md#writing-a-bottom-bar).
957
+ * **Where it shows.** The player draws the bottom bar's button strip and
958
+ * decides where it goes: today at the right end of the bottom bar; this may
959
+ * change (older players let the bar place `BarButtons` itself). Buttons
960
+ * are ordered by `order`, then by plugin id; lower `order` comes first and
961
+ * stays visible longest. When the strip runs out of room, or more than 8
962
+ * plugin buttons are declared, the remaining buttons move to the strip's »
963
+ * menu, in the same order. A button is never dropped: it is either in the
964
+ * strip or in the » menu, and its command keeps its menu entry, its key and
965
+ * its place in the command palette. Users may pin and unpin buttons later;
966
+ * do not rely on a position. See
967
+ * [Bottom-bar buttons](../../docs/explanation/commands.md#bottom-bar-buttons).
968
968
  *
969
969
  * **What it shows.** The icon, the command's title (translated, a trailing
970
970
  * "…" removed) and its first key as the tooltip ("Plugin Store (F9)"),
@@ -974,9 +974,9 @@ export type BarButtonIcon = "play" | "pause" | "stop" | "back" | "forward" | "op
974
974
  * a command with `checked` shows a small dot under its icon while checked.
975
975
  * A click runs the command exactly like a click on its menu item.
976
976
  *
977
- * **Limits.** One button per plugin and eight in the player
978
- * (`BAR_BUTTON_LIMITS`): a button past them is left out (its command and
979
- * menu entry stay) and the player logs it with `limit`. The button goes
977
+ * **Limits.** One button per plugin, the first it declares (a later one
978
+ * stays a menu item only), and eight in the strip (`BAR_BUTTON_LIMITS`); the
979
+ * rest are in the » menu. The button goes
980
980
  * with its command: disposing the command, or disabling, stopping or
981
981
  * uninstalling the plugin, removes it.
982
982
  *
@@ -984,8 +984,7 @@ export type BarButtonIcon = "play" | "pause" | "stop" | "back" | "forward" | "op
984
984
  * A Store icon appears in the bottom bar's button strip; a click opens
985
985
  * the store window, exactly like the menu item. The player draws the
986
986
  * button from the command's title, keys and state, and places it by
987
- * `order` (200 is where the player's own Plugin Store button sits); a
988
- * bar that does not place `BarButtons` shows only the menu item.
987
+ * `order` (200 is where the player's own Plugin Store button sits).
989
988
  * ```ts
990
989
  * const store = plugin.windows.create("ui/store.slint");
991
990
  * plugin.commands.add({
@@ -1238,8 +1237,8 @@ export interface CommandOptions {
1238
1237
  /**
1239
1238
  * A button for this command on the bottom bar (SDK 1.5.29, player 0.5.10):
1240
1239
  * an icon and a place, `{ icon: "store", order: 200 }`. Needs a `path`: the
1241
- * menu entry is where the command stays reachable when the bar shows no
1242
- * button (a bar without `BarButtons`, a narrow window, a limit). See
1240
+ * menu entry is where the command stays reachable wherever the button
1241
+ * is (the strip or its » menu). See
1243
1242
  * {@link CommandButton} for where it shows, what it shows and the limits.
1244
1243
  * Fails with `invalid` for an unknown icon name, an order outside 0–999 or
1245
1244
  * a button without a path.
package/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # Vestra Player SDK
2
2
 
3
- > @vestra-player/sdk 1.6.7: 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/.
3
+ > @vestra-player/sdk 1.6.8: 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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vestra-player/sdk",
3
- "version": "1.6.7",
3
+ "version": "1.6.8",
4
4
  "description": "Plugin API types, test host and plugin CLI for Vestra Player (apiVersion vestra/1)",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -1,15 +1,26 @@
1
- // Command buttons of a bottom bar (player 0.5.10, SDK 1.5.29): the buttons
1
+ // Command buttons of the bottom bar (player 0.5.10, SDK 1.5.29): the buttons
2
2
  // that plugins' commands contribute (`commands.add({ button })`) and the
3
- // player's sidebar toggle, rightmost. The player fills `BarButtonsHost` in
4
- // every window it composes and runs the clicks; a bottom bar places one
5
- // `BarButtons` in its own layout and gives it the width it can spare:
6
- // import { BarButtons } from "@vestra/bar-buttons.slint";
7
- // strip := BarButtons { x: parent.width - self.width - 4px; room: ...; }
8
- // It shows as many 41×40 cells as fit in `room`, the strip as wide as the
9
- // cells shown (`width`). Cells go from the strip's outer (left) end inward:
10
- // of the plugins' buttons (ascending `order`, left to right) the lowest
11
- // order goes first, and the sidebar toggle goes last. A bar without a `BarButtons` shows none of them (their menu
12
- // entries stay; the player logs which buttons are hidden).
3
+ // player's own. Since SDK 1.6.8 (menu redesign step 3a) the player draws
4
+ // the strip itself, at the right end of the bottom slot, its 40px cells on
5
+ // the slot's bottom edge (a bar's 40px button row), and also when no plugin
6
+ // mounts a bottom bar: `[plugin buttons…][»][Command Palette][Toggle
7
+ // Sidebar]`. A bottom bar places nothing: it lays its controls out left of
8
+ // the strip and says how wide they must stay:
9
+ // import { BarButtonsHost } from "@vestra/bar-buttons.slint";
10
+ // export component MyBar inherits Rectangle {
11
+ // out property <length> content-min-width: ...; // the least your row needs
12
+ // // your row ends at: root.width - BarButtonsHost.width - 4px
13
+ // }
14
+ // The player gives its strip `bar width - content-min-width - 4px` (all of
15
+ // the width without `content-min-width`), so plugin buttons never cover
16
+ // what the bar needs (its time label, UI-BAR-10). Plugin buttons go left to
17
+ // right by ascending `order`, then plugin id, then registration; at most 8
18
+ // are in the strip, and the ones past 8 or past the room are in the `»`
19
+ // menu, in the same order: the lowest order stays longest. `»` shows only
20
+ // while something is in it; the player's own cells always show.
21
+ //
22
+ // `BarButtons` (below) is deprecated: the strip a bar placed itself before
23
+ // SDK 1.6.8. While a bar still places it, the player draws no second strip.
13
24
  //
14
25
  // The cells look like the bar's own icon buttons: a 32×32 plate on hover
15
26
  // and press, the bar's tooltip (ToolTipArea). Every enabled cell draws its
@@ -43,14 +54,56 @@ export struct BarButtonItem {
43
54
  dimmed: bool,
44
55
  }
45
56
 
46
- // Filled by the player; a bar reads it only through `BarButtons`.
57
+ // Filled by the player. A bar reads `width` (to end its own row left of
58
+ // the strip) and `fixed`; everything else is the player's.
47
59
  export global BarButtonsHost {
48
- // The plugins' buttons, left to right, at most 8.
60
+ // The plugins' buttons for the strip, left to right, at most 8.
49
61
  in property <[BarButtonItem]> buttons;
62
+ // How many plugin buttons are past those 8 (always in the `»` menu).
63
+ in property <int> overflow;
50
64
  // The sidebar toggle (`token` "" while there is none).
51
65
  in property <BarButtonItem> toggle;
52
- // Set when a `BarButtons` exists in this window.
66
+ // The command palette (`host/palette`; `token` "" while there is none).
67
+ in property <BarButtonItem> palette;
68
+ // Set when a (deprecated) `BarButtons` exists in this window.
53
69
  in-out property <bool> placed;
70
+ // The width the player gives its strip (the player sets it).
71
+ in-out property <length> room;
72
+ // The player's own cells, always shown (step 3b adds Adjust).
73
+ private property <int> own: (root.palette.token != "" ? 1 : 0) + (root.toggle.token != "" ? 1 : 0);
74
+ // The cells a bar must always leave free, 41px each: the player's own,
75
+ // and the `»` cell whenever any plugin button exists (drawn only on
76
+ // overflow, but always reserved, so `»` never covers the bar). Never
77
+ // depends on `room`. A bar that keeps an optional control ahead of the
78
+ // plugins' buttons counts it in `content-min-width` while it fits
79
+ // beside these.
80
+ out property <int> fixed: root.own + (root.buttons.length > 0 || root.overflow > 0 ? 1 : 0);
81
+ // The strip's layout for a room, as pure functions, so the player's
82
+ // strip binds them to its own `room` (no frame behind the shell's
83
+ // layout) and the properties below give the same numbers for `room`.
84
+ // The plugin buttons in the strip (the first of `buttons`) at `room`.
85
+ public pure function shown-in(room: length) -> int {
86
+ // Cells left for plugin buttons and `»`.
87
+ let free = Math.max(0, Math.floor(room / 41px) - root.own);
88
+ if root.overflow == 0 && root.buttons.length <= free {
89
+ return root.buttons.length;
90
+ }
91
+ return Math.max(0, Math.min(root.buttons.length, free - 1));
92
+ }
93
+ // Whether `»` shows at `room` (a button past 8 or past the room).
94
+ public pure function more-in(room: length) -> bool {
95
+ return root.shown-in(room) < root.buttons.length || root.overflow > 0;
96
+ }
97
+ // The strip's width at `room` (0 while a bar places `BarButtons`).
98
+ public pure function width-in(room: length) -> length {
99
+ if root.placed {
100
+ return 0px;
101
+ }
102
+ return (root.shown-in(room) + (root.more-in(room) ? 1 : 0) + root.own) * 41px;
103
+ }
104
+ out property <int> shown: root.shown-in(root.room);
105
+ out property <bool> more: root.more-in(root.room);
106
+ out property <length> width: root.width-in(root.room);
54
107
  // A click on the cell with this token.
55
108
  callback clicked(string);
56
109
  }
@@ -127,8 +180,11 @@ component Cell inherits Rectangle {
127
180
  }
128
181
  }
129
182
 
130
- // The strip: place it at the bar's right end and give it the width you can
131
- // spare; it is as wide as the cells it shows (read `width` to lay out the rest).
183
+ // Deprecated (SDK 1.6.8; the player places its strip): the strip a bar
184
+ // placed at its right end with the width it could spare. A bar that still
185
+ // places it shows this one instead of the player's (no palette cell, no
186
+ // `»`): the cells that fit in `room`, lost from its outer (left) end
187
+ // inward, the sidebar toggle last; it is as wide as the cells it shows.
132
188
  export component BarButtons {
133
189
  // The width the bar can give the strip; the cells that fit show.
134
190
  in property <length> room;