@vestra-player/sdk 1.5.58 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/docs-tree.json.gz +0 -0
- package/dist/plugin/types.d.ts +7 -0
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/slint/vestra/markdown.slint +172 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.0
|
|
4
|
+
|
|
5
|
+
**Who must change: nobody.** No change to the TypeScript API, the wire or `TestHost`, `apiVersion` stays `vestra/1`, no new capability. New since 1.5.58 for plugin authors: Markdown the user can select and copy (`selectable` on `MarkdownView` and `MarkdownBlocks`, `plain` and `links` on `MarkdownBlock`, in the SDK's copy of the player's `@vestra/markdown.slint`; a plugin that uses them sets `"minPlayerVersion": "0.6.8"`), and, from player 0.6.7, plugins started on demand by default: a plugin starts on its first use and is stopped when idle, so `activate` can run many times and must never wait for its own commands or views (see 1.5.58). This is a minor release because it adds backward-compatible API and marks that milestone; nothing is removed or changed, and a plugin built with 1.5.x keeps working as it is.
|
|
6
|
+
|
|
7
|
+
- **Selectable Markdown** (player 0.6.8; the SDK's `slint/vestra/markdown.slint` is synced with the player's). `MarkdownView` and `MarkdownBlocks` take `in property <bool> selectable: false`. With `true`, a paragraph, heading, list item or quote without links is shown as its plain text in a read-only selectable text field (right-click Copy / Select All, where Copy with nothing selected copies the whole block; Ctrl+C / Ctrl+A; each field is a Tab stop); a block with links keeps its clickable links, and its right-click menu copies it as plain text with each address after its link text, `text (url)`, plus Copy Link when it has one link. Code blocks are always selectable, whatever `selectable` says (in player 0.6.8 this applies to every plugin's Markdown). A selection stays inside one block and is lost when its row scrolls out of a `MarkdownView`. `MarkdownBlock` gains `plain: string` (the block as plain text) and `links: [string]` (its link addresses). Older players do not have the property: set `"minPlayerVersion": "0.6.8"` before using it. See [Reference: theme › Markdown](docs/reference/theme.md#markdown).
|
|
8
|
+
- **Start retries corrected** ([How the player runs and talks to plugins](docs/explanation/host-and-node.md#the-start-deadline), [Reference: limits](docs/reference/limits.md#plugin-processes), [How a plugin runs](docs/explanation/plugins.md#restarts-activate-can-run-more-than-once)). 1.5.58 said a start that is not ready within the start timeout is tried up to three more times. That was player 0.6.6; from player 0.6.7 a timed-out start gets one try (60 s) and is not retried, and only a process that cannot be created is tried again (about 250 ms, 500 ms and 1 s apart).
|
|
9
|
+
|
|
3
10
|
## 1.5.58
|
|
4
11
|
|
|
5
12
|
**Who must change: nobody.** Documentation only: no change to the TypeScript API, the wire or `TestHost`, `apiVersion` stays `vestra/1`, no new capability, no player version needed. Plugin authors should read what the player's new plugin supervisor does with their plugin (player 0.6.6, and the defaults planned for 0.6.7), and check that `activate` never waits for its own commands or views.
|
package/dist/docs-tree.json.gz
CHANGED
|
Binary file
|
package/dist/plugin/types.d.ts
CHANGED
|
@@ -1773,6 +1773,13 @@ export interface Ui {
|
|
|
1773
1773
|
* the list on every streamed chunk keeps the scroll position and costs
|
|
1774
1774
|
* little.
|
|
1775
1775
|
*
|
|
1776
|
+
* From player 0.6.8 both views take `selectable: true` (default `false`):
|
|
1777
|
+
* the user can select and copy the text, one block at a time; blocks with
|
|
1778
|
+
* links keep their clickable links and copy as `text (url)`. Code blocks
|
|
1779
|
+
* are always selectable. `MarkdownBlock.plain` (the block as plain text)
|
|
1780
|
+
* and `MarkdownBlock.links` (its link addresses) are readable in Slint.
|
|
1781
|
+
* See [Reference: theme › Markdown](../../docs/reference/theme.md#markdown).
|
|
1782
|
+
*
|
|
1776
1783
|
* @capability None.
|
|
1777
1784
|
* @player 0.2.0 (set `"minPlayerVersion": "0.2.0"` in the manifest)
|
|
1778
1785
|
*
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vestra Player SDK
|
|
2
2
|
|
|
3
|
-
> @vestra-player/sdk 1.
|
|
3
|
+
> @vestra-player/sdk 1.6.0: 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
|
@@ -9,7 +9,15 @@
|
|
|
9
9
|
// row (a chat message: a `[MarkdownBlock]` field of the row's struct).
|
|
10
10
|
// `code-copy: true` adds a Copy button to code blocks that reports
|
|
11
11
|
// `copy-code(code)`; the plugin copies it (`plugin.clipboard`).
|
|
12
|
-
|
|
12
|
+
// `selectable: true` lets the user select and copy text with the mouse:
|
|
13
|
+
// paragraphs, headings, list items and quotes without links then show their
|
|
14
|
+
// plain text (`MarkdownBlock.plain`, no inline styles) in a read-only text
|
|
15
|
+
// field, one field per block, with a Copy / Select All menu. A block with
|
|
16
|
+
// links keeps its styled text (links stay clickable); its right-click menu
|
|
17
|
+
// copies the block as plain text with each address after its link text,
|
|
18
|
+
// `text (url)`, and offers Copy Link when the block has one link. Code
|
|
19
|
+
// blocks are always selectable.
|
|
20
|
+
import { ListView, Palette } from "std-widgets.slint";
|
|
13
21
|
import { Theme } from "theme.slint";
|
|
14
22
|
import { Icon } from "icons.slint";
|
|
15
23
|
|
|
@@ -36,21 +44,130 @@ export struct MarkdownBlock {
|
|
|
36
44
|
// Task list item: 0 none, 1 open, 2 done (a drawn box, no font glyph).
|
|
37
45
|
task: int,
|
|
38
46
|
text: styled-text,
|
|
47
|
+
// The block's text without styles, what `selectable` shows: a code
|
|
48
|
+
// block's code, a table's cells (tab-separated lines), an image's alt.
|
|
49
|
+
plain: string,
|
|
39
50
|
code: string,
|
|
40
51
|
image: image,
|
|
41
52
|
has-image: bool,
|
|
42
53
|
image-width: int,
|
|
43
54
|
image-height: int,
|
|
44
55
|
alt: string,
|
|
56
|
+
// The addresses of the block's links, in order.
|
|
57
|
+
links: [string],
|
|
45
58
|
rows: [MarkdownRow],
|
|
46
59
|
// Table column alignment: "left", "center", "right" or "" (left).
|
|
47
60
|
aligns: [string],
|
|
48
61
|
}
|
|
49
62
|
|
|
63
|
+
// Read-only text the user can select: a right-click menu with Copy and
|
|
64
|
+
// Select All (as Slint's own text fields; Copy without a selection copies
|
|
65
|
+
// the whole block), and Ctrl+C / Ctrl+A (⌘C / ⌘A) while it has focus. No
|
|
66
|
+
// caret, as selectable text on a web page. Each one is a Tab stop, and
|
|
67
|
+
// while one has focus the arrow keys move in it (Slint 1.18's read-only
|
|
68
|
+
// TextInput).
|
|
69
|
+
component SelectableText {
|
|
70
|
+
in property <string> text;
|
|
71
|
+
in property <brush> color: Theme.text;
|
|
72
|
+
in property <length> font-size: Theme.font-tab;
|
|
73
|
+
in property <int> font-weight: 400;
|
|
74
|
+
in property <string> font-family;
|
|
75
|
+
min-height: input.min-height;
|
|
76
|
+
preferred-height: input.preferred-height;
|
|
77
|
+
ContextMenuArea {
|
|
78
|
+
Menu {
|
|
79
|
+
MenuItem {
|
|
80
|
+
title: @tr("Copy");
|
|
81
|
+
enabled: root.text != "";
|
|
82
|
+
activated => {
|
|
83
|
+
if input.anchor-position-byte-offset == input.cursor-position-byte-offset {
|
|
84
|
+
input.select-all();
|
|
85
|
+
input.copy();
|
|
86
|
+
input.clear-selection();
|
|
87
|
+
} else {
|
|
88
|
+
input.copy();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
MenuItem {
|
|
93
|
+
title: @tr("Select All");
|
|
94
|
+
enabled: root.text != "";
|
|
95
|
+
activated => { input.select-all(); }
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
input := TextInput {
|
|
99
|
+
width: root.width;
|
|
100
|
+
height: root.height;
|
|
101
|
+
text: root.text;
|
|
102
|
+
read-only: true;
|
|
103
|
+
single-line: false;
|
|
104
|
+
wrap: word-wrap;
|
|
105
|
+
color: root.color;
|
|
106
|
+
font-size: root.font-size;
|
|
107
|
+
font-weight: root.font-weight;
|
|
108
|
+
font-family: root.font-family;
|
|
109
|
+
text-cursor-width: 0px;
|
|
110
|
+
// The std-widgets LineEdit's selection colours, legible in both
|
|
111
|
+
// palettes (as the info plugin's properties).
|
|
112
|
+
selection-background-color: Palette.selection-background;
|
|
113
|
+
selection-foreground-color: Palette.selection-foreground;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// A block with links in a selectable view: its styled text (links stay
|
|
119
|
+
// clickable) under a right-click menu that copies `plain` (with the
|
|
120
|
+
// addresses) and, for one link, the link. The menu lies above the text: a
|
|
121
|
+
// left click passes through it to the links.
|
|
122
|
+
component LinkText {
|
|
123
|
+
in property <styled-text> text;
|
|
124
|
+
in property <string> plain;
|
|
125
|
+
in property <[string]> links;
|
|
126
|
+
in property <brush> color: Theme.text;
|
|
127
|
+
in property <length> font-size: Theme.font-tab;
|
|
128
|
+
callback link-clicked(string);
|
|
129
|
+
min-height: styled.min-height;
|
|
130
|
+
preferred-height: styled.preferred-height;
|
|
131
|
+
function put(text: string) {
|
|
132
|
+
clip.text = text;
|
|
133
|
+
clip.select-all();
|
|
134
|
+
clip.copy();
|
|
135
|
+
}
|
|
136
|
+
styled := StyledText {
|
|
137
|
+
width: root.width;
|
|
138
|
+
height: root.height;
|
|
139
|
+
text: root.text;
|
|
140
|
+
default-color: root.color;
|
|
141
|
+
default-font-size: root.font-size;
|
|
142
|
+
link-color: Theme.accent;
|
|
143
|
+
link-clicked(url) => { root.link-clicked(url); }
|
|
144
|
+
}
|
|
145
|
+
ContextMenuArea {
|
|
146
|
+
Menu {
|
|
147
|
+
MenuItem {
|
|
148
|
+
title: @tr("Copy");
|
|
149
|
+
activated => { root.put(root.plain); }
|
|
150
|
+
}
|
|
151
|
+
if root.links.length == 1: MenuItem {
|
|
152
|
+
title: @tr("Copy Link");
|
|
153
|
+
activated => { root.put(root.links[0]); }
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Puts text on the clipboard (Slint has no clipboard function).
|
|
158
|
+
clip := TextInput {
|
|
159
|
+
visible: false;
|
|
160
|
+
width: 0px;
|
|
161
|
+
height: 0px;
|
|
162
|
+
read-only: true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
50
166
|
component MarkdownBlockView {
|
|
51
167
|
in property <MarkdownBlock> block;
|
|
52
168
|
in property <length> available;
|
|
53
169
|
in property <bool> code-copy;
|
|
170
|
+
in property <bool> selectable;
|
|
54
171
|
callback link-clicked(string);
|
|
55
172
|
callback copy-code(string);
|
|
56
173
|
private property <length> quote-indent: block.quote * 12px;
|
|
@@ -61,7 +178,21 @@ component MarkdownBlockView {
|
|
|
61
178
|
HorizontalLayout {
|
|
62
179
|
padding-left: root.quote-indent + root.list-indent;
|
|
63
180
|
VerticalLayout {
|
|
64
|
-
if block.kind == "heading":
|
|
181
|
+
if block.kind == "heading" && root.selectable && block.links.length > 0: LinkText {
|
|
182
|
+
width: root.inner;
|
|
183
|
+
text: block.text;
|
|
184
|
+
plain: block.plain;
|
|
185
|
+
links: block.links;
|
|
186
|
+
font-size: root.heading-size;
|
|
187
|
+
link-clicked(url) => { root.link-clicked(url); }
|
|
188
|
+
}
|
|
189
|
+
if block.kind == "heading" && root.selectable && block.links.length == 0: SelectableText {
|
|
190
|
+
width: root.inner;
|
|
191
|
+
text: block.plain;
|
|
192
|
+
font-size: root.heading-size;
|
|
193
|
+
font-weight: 700;
|
|
194
|
+
}
|
|
195
|
+
if block.kind == "heading" && !root.selectable: StyledText {
|
|
65
196
|
width: root.inner;
|
|
66
197
|
text: block.text;
|
|
67
198
|
default-color: Theme.text;
|
|
@@ -69,7 +200,20 @@ component MarkdownBlockView {
|
|
|
69
200
|
link-color: Theme.accent;
|
|
70
201
|
link-clicked(url) => { root.link-clicked(url); }
|
|
71
202
|
}
|
|
72
|
-
if block.kind == "paragraph":
|
|
203
|
+
if block.kind == "paragraph" && root.selectable && block.links.length > 0: LinkText {
|
|
204
|
+
width: root.inner;
|
|
205
|
+
text: block.text;
|
|
206
|
+
plain: block.plain;
|
|
207
|
+
links: block.links;
|
|
208
|
+
color: block.quote > 0 ? Theme.text-dim : Theme.text;
|
|
209
|
+
link-clicked(url) => { root.link-clicked(url); }
|
|
210
|
+
}
|
|
211
|
+
if block.kind == "paragraph" && root.selectable && block.links.length == 0: SelectableText {
|
|
212
|
+
width: root.inner;
|
|
213
|
+
text: block.plain;
|
|
214
|
+
color: block.quote > 0 ? Theme.text-dim : Theme.text;
|
|
215
|
+
}
|
|
216
|
+
if block.kind == "paragraph" && !root.selectable: StyledText {
|
|
73
217
|
width: root.inner;
|
|
74
218
|
text: block.text;
|
|
75
219
|
default-color: block.quote > 0 ? Theme.text-dim : Theme.text;
|
|
@@ -106,7 +250,18 @@ component MarkdownBlockView {
|
|
|
106
250
|
}
|
|
107
251
|
}
|
|
108
252
|
}
|
|
109
|
-
|
|
253
|
+
if root.selectable && block.links.length > 0: LinkText {
|
|
254
|
+
width: root.inner - 20px;
|
|
255
|
+
text: block.text;
|
|
256
|
+
plain: block.plain;
|
|
257
|
+
links: block.links;
|
|
258
|
+
link-clicked(url) => { root.link-clicked(url); }
|
|
259
|
+
}
|
|
260
|
+
if root.selectable && block.links.length == 0: SelectableText {
|
|
261
|
+
width: root.inner - 20px;
|
|
262
|
+
text: block.plain;
|
|
263
|
+
}
|
|
264
|
+
if !root.selectable: StyledText {
|
|
110
265
|
width: root.inner - 20px;
|
|
111
266
|
text: block.text;
|
|
112
267
|
default-color: Theme.text;
|
|
@@ -123,12 +278,12 @@ component MarkdownBlockView {
|
|
|
123
278
|
VerticalLayout {
|
|
124
279
|
padding: 6px;
|
|
125
280
|
// Plain lines in the monospace font; CJK falls back.
|
|
126
|
-
|
|
281
|
+
// Always selectable: code is there to be copied.
|
|
282
|
+
SelectableText {
|
|
127
283
|
width: root.inner - 12px;
|
|
128
|
-
text: block.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
default-font-size: Theme.font-body;
|
|
284
|
+
text: block.code;
|
|
285
|
+
font-family: Theme.font-mono;
|
|
286
|
+
font-size: Theme.font-body;
|
|
132
287
|
}
|
|
133
288
|
}
|
|
134
289
|
if root.code-copy: Rectangle {
|
|
@@ -216,6 +371,8 @@ export component MarkdownBlocks inherits Rectangle {
|
|
|
216
371
|
in property <[MarkdownBlock]> blocks;
|
|
217
372
|
// A Copy button on code blocks, reporting `copy-code(code)`.
|
|
218
373
|
in property <bool> code-copy: false;
|
|
374
|
+
// Text the user can select and copy (see the top of this file).
|
|
375
|
+
in property <bool> selectable: false;
|
|
219
376
|
callback link-clicked(string);
|
|
220
377
|
callback copy-code(string);
|
|
221
378
|
min-height: column.min-height;
|
|
@@ -228,6 +385,7 @@ export component MarkdownBlocks inherits Rectangle {
|
|
|
228
385
|
block: block;
|
|
229
386
|
available: root.width;
|
|
230
387
|
code-copy: root.code-copy;
|
|
388
|
+
selectable: root.selectable;
|
|
231
389
|
link-clicked(url) => { root.link-clicked(url); }
|
|
232
390
|
copy-code(code) => { root.copy-code(code); }
|
|
233
391
|
}
|
|
@@ -244,6 +402,10 @@ export component MarkdownView inherits Rectangle {
|
|
|
244
402
|
in property <length> inset: 10px;
|
|
245
403
|
// A Copy button on code blocks, reporting `copy-code(code)`.
|
|
246
404
|
in property <bool> code-copy: false;
|
|
405
|
+
// Text the user can select and copy (see the top of this file). A
|
|
406
|
+
// selection is lost when its block scrolls out of view (the `ListView`
|
|
407
|
+
// drops the row).
|
|
408
|
+
in property <bool> selectable: false;
|
|
247
409
|
callback link-clicked(string);
|
|
248
410
|
callback copy-code(string);
|
|
249
411
|
list := ListView {
|
|
@@ -261,6 +423,7 @@ export component MarkdownView inherits Rectangle {
|
|
|
261
423
|
block: block;
|
|
262
424
|
available: self.width;
|
|
263
425
|
code-copy: root.code-copy;
|
|
426
|
+
selectable: root.selectable;
|
|
264
427
|
link-clicked(url) => { root.link-clicked(url); }
|
|
265
428
|
copy-code(code) => { root.copy-code(code); }
|
|
266
429
|
}
|