@bendyline/docblocks-react 2.7.5 → 2.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.txt +26 -26
- package/dist/{AiDiagrams-5P657GFC.js → AiDiagrams-7KBAOXPB.js} +4 -2
- package/dist/{AiEditorAssistant-V4MZRC6Q.js → AiEditorAssistant-4B2PFFOT.js} +128 -12
- package/dist/{AiStudyDialog-GSCFTG3G.js → AiStudyDialog-JPVFFZBB.js} +14 -4
- package/dist/{AudioExportDialog-IOYIEAER.js → AudioExportDialog-EICCBSSE.js} +1 -1
- package/dist/{ExportDialog-LGWBXIWN.js → ExportDialog-EYDGTJ3S.js} +1 -1
- package/dist/{ExportToolbarControls-HOV424TO.js → ExportToolbarControls-2XY2CKGH.js} +45 -4
- package/dist/{PresentationMaker-H5B44Q7P.js → PresentationMaker-VYQKNL3L.js} +2 -2
- package/dist/{SpeechToolbarControl-KNI2C4JJ.js → SpeechToolbarControl-E6OSJGHL.js} +217 -71
- package/dist/{TextFromNarration-EYOMW2IW.js → TextFromNarration-ME6FAYWO.js} +1 -1
- package/dist/{WorkspaceSearchPanel-J6BKEZQJ.js → WorkspaceSearchPanel-MEBBTK7F.js} +3 -3
- package/dist/{chunk-I44HKDQX.js → chunk-3TSJQESW.js} +16 -3
- package/dist/chunk-5OIHB3SR.js +1162 -0
- package/dist/chunk-6QHZNL6C.js +208 -0
- package/dist/{chunk-FBPCURCS.js → chunk-7HBKKXRV.js} +291 -82
- package/dist/{chunk-KBDZDFPU.js → chunk-BNKIPCXO.js} +4 -1
- package/dist/{chunk-2IYBBFQX.js → chunk-BZRYQENB.js} +59 -16
- package/dist/{chunk-GFK4TCKN.js → chunk-G63YXKBC.js} +8 -5
- package/dist/{chunk-DICE7VBJ.js → chunk-KHQ44ZFA.js} +16 -1
- package/dist/{chunk-CUCWCZRO.js → chunk-N7AKLJPY.js} +143 -98
- package/dist/{chunk-USKX66SA.js → chunk-T2PA7QEF.js} +1 -1
- package/dist/editor.js +2 -2
- package/dist/export/index.js +1 -1
- package/dist/index.js +232 -134
- package/dist/settings/index.js +2 -1
- package/package.json +8 -8
- package/src/styles/docblocks.css +547 -11
- package/dist/chunk-I4JURPYS.js +0 -812
- package/dist/{QuickOpenDialog-ENVFGIHS.js → QuickOpenDialog-3QEX7RZG.js} +3 -3
|
@@ -1,18 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HighlightedText
|
|
3
|
+
} from "./chunk-TBLZBNQF.js";
|
|
1
4
|
import {
|
|
2
5
|
Dialog
|
|
3
6
|
} from "./chunk-VJPGZCFS.js";
|
|
4
7
|
|
|
5
8
|
// src/Settings/AiSettings.tsx
|
|
6
|
-
import { useCallback, useEffect as useEffect2, useId, useRef as useRef2, useState as useState2 } from "react";
|
|
9
|
+
import { useCallback, useEffect as useEffect2, useId as useId2, useRef as useRef2, useState as useState2 } from "react";
|
|
7
10
|
|
|
8
11
|
// src/Settings/AiKnowledgeSettings.tsx
|
|
9
|
-
import { useEffect, useRef, useState } from "react";
|
|
12
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
13
|
+
import { createPortal } from "react-dom";
|
|
10
14
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
15
|
function sizedArticle(bytes) {
|
|
12
16
|
const megabytes = String(Math.max(1, Math.round(bytes / 1024 ** 2)));
|
|
13
17
|
const an = megabytes.startsWith("8") || megabytes.length % 3 === 2 && (megabytes.startsWith("11") || megabytes.startsWith("18"));
|
|
14
18
|
return `${an ? "an" : "a"} ${megabytes} MB`;
|
|
15
19
|
}
|
|
20
|
+
function catalogFacts(catalog, version) {
|
|
21
|
+
return [
|
|
22
|
+
`Version ${version}`,
|
|
23
|
+
catalog.documents === null ? null : `${catalog.documents.toLocaleString()} documents`,
|
|
24
|
+
catalog.downloadBytes === null ? null : `${(catalog.downloadBytes / 1024 ** 2).toFixed(1)} MB`
|
|
25
|
+
].filter((part) => part !== null).join(" \xB7 ");
|
|
26
|
+
}
|
|
27
|
+
function catalogSummary(catalog) {
|
|
28
|
+
if (catalog.state === "downloading")
|
|
29
|
+
return catalog.percent === null ? "Downloading\u2026" : `Downloading ${Math.round(catalog.percent)}%`;
|
|
30
|
+
if (catalog.state === "error") return "Needs attention";
|
|
31
|
+
const use = catalog.enabled ? "In use" : "Not in use";
|
|
32
|
+
return catalog.updateAvailable ? `${use} \xB7 Update available` : use;
|
|
33
|
+
}
|
|
34
|
+
function matchRanges(text, query) {
|
|
35
|
+
if (!query) return [];
|
|
36
|
+
const haystack = text.toLowerCase();
|
|
37
|
+
const ranges = [];
|
|
38
|
+
for (let at = haystack.indexOf(query); at >= 0; at = haystack.indexOf(query, at + query.length))
|
|
39
|
+
ranges.push([at, at + query.length]);
|
|
40
|
+
return ranges;
|
|
41
|
+
}
|
|
16
42
|
function AiKnowledgeSettings({ knowledge }) {
|
|
17
43
|
const [state, setState] = useState(null);
|
|
18
44
|
const [error, setError] = useState(null);
|
|
@@ -20,9 +46,10 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
20
46
|
const [unsupported, setUnsupported] = useState(null);
|
|
21
47
|
const [busy, setBusy] = useState(false);
|
|
22
48
|
const [revision, setRevision] = useState(0);
|
|
23
|
-
const [
|
|
24
|
-
const [
|
|
49
|
+
const [adding, setAdding] = useState(false);
|
|
50
|
+
const [expanded, setExpanded] = useState(() => /* @__PURE__ */ new Set());
|
|
25
51
|
const [removing, setRemoving] = useState(null);
|
|
52
|
+
const binHeadingId = useId();
|
|
26
53
|
const generation = useRef(0);
|
|
27
54
|
useEffect(
|
|
28
55
|
() => () => {
|
|
@@ -33,7 +60,7 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
33
60
|
useEffect(() => {
|
|
34
61
|
let live = true;
|
|
35
62
|
let timer;
|
|
36
|
-
const
|
|
63
|
+
const refresh2 = async () => {
|
|
37
64
|
try {
|
|
38
65
|
const result = await knowledge.state();
|
|
39
66
|
if (!live) return;
|
|
@@ -46,13 +73,13 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
46
73
|
setLoadError(null);
|
|
47
74
|
setUnsupported(null);
|
|
48
75
|
if (result.value.improvement?.downloading || result.value.catalogs.some((catalog) => catalog.state === "downloading")) {
|
|
49
|
-
timer = setTimeout(() => void
|
|
76
|
+
timer = setTimeout(() => void refresh2(), 1500);
|
|
50
77
|
}
|
|
51
78
|
} catch {
|
|
52
79
|
if (live) setLoadError("Could not refresh knowledge catalogs. Try again.");
|
|
53
80
|
}
|
|
54
81
|
};
|
|
55
|
-
void
|
|
82
|
+
void refresh2();
|
|
56
83
|
return () => {
|
|
57
84
|
live = false;
|
|
58
85
|
if (timer) clearTimeout(timer);
|
|
@@ -76,9 +103,21 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
76
103
|
if (current === generation.current) setBusy(false);
|
|
77
104
|
}
|
|
78
105
|
};
|
|
79
|
-
const
|
|
80
|
-
|
|
106
|
+
const refresh = () => setRevision((value) => value + 1);
|
|
107
|
+
const showAdd = (open) => {
|
|
108
|
+
setError(null);
|
|
109
|
+
setAdding(open);
|
|
110
|
+
if (open) refresh();
|
|
111
|
+
};
|
|
112
|
+
const toggle = (catalogId) => setExpanded((current) => {
|
|
113
|
+
const next = new Set(current);
|
|
114
|
+
if (!next.delete(catalogId)) next.add(catalogId);
|
|
115
|
+
return next;
|
|
116
|
+
});
|
|
117
|
+
const downloaded = state?.catalogs.filter(
|
|
118
|
+
(catalog) => catalog.installedVersion !== null || catalog.state === "downloading"
|
|
81
119
|
) ?? [];
|
|
120
|
+
const problem = error ?? loadError;
|
|
82
121
|
if (unsupported)
|
|
83
122
|
return /* @__PURE__ */ jsxs("section", { className: "db-settings-ai-knowledge", "aria-label": "Knowledge catalogs", children: [
|
|
84
123
|
/* @__PURE__ */ jsx("h3", { className: "db-settings-select-header", children: "Knowledge catalogs" }),
|
|
@@ -87,8 +126,17 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
87
126
|
return /* @__PURE__ */ jsxs("section", { className: "db-settings-ai-knowledge", "aria-label": "Knowledge catalogs", children: [
|
|
88
127
|
/* @__PURE__ */ jsx("h3", { className: "db-settings-select-header", children: "Knowledge catalogs" }),
|
|
89
128
|
/* @__PURE__ */ jsx("p", { className: "db-settings-hint", children: "Add reference material for AI writing, review, and chat. Relevant passages from enabled catalogs are included in each request." }),
|
|
90
|
-
|
|
129
|
+
problem && !adding && /* @__PURE__ */ jsx("p", { className: "db-settings-hint db-settings-ai-error", role: "alert", children: problem }),
|
|
91
130
|
!state && !loadError && /* @__PURE__ */ jsx("p", { className: "db-settings-hint", role: "status", children: "Loading knowledge catalogs\u2026" }),
|
|
131
|
+
!state && loadError && /* @__PURE__ */ jsx(
|
|
132
|
+
"button",
|
|
133
|
+
{
|
|
134
|
+
type: "button",
|
|
135
|
+
className: "db-settings-action db-settings-action--secondary",
|
|
136
|
+
onClick: refresh,
|
|
137
|
+
children: "Try again"
|
|
138
|
+
}
|
|
139
|
+
),
|
|
92
140
|
state?.improvement && !state.improvement.downloading && /* @__PURE__ */ jsx("p", { className: "db-settings-hint", children: /* @__PURE__ */ jsxs(
|
|
93
141
|
"button",
|
|
94
142
|
{
|
|
@@ -103,52 +151,90 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
103
151
|
]
|
|
104
152
|
}
|
|
105
153
|
) }),
|
|
106
|
-
/* @__PURE__ */ jsxs("div", { className: "db-
|
|
107
|
-
/* @__PURE__ */
|
|
108
|
-
"
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
disabled: busy,
|
|
123
|
-
onClick: () => setRevision((value) => value + 1),
|
|
124
|
-
children: "Refresh catalogs"
|
|
125
|
-
}
|
|
126
|
-
)
|
|
127
|
-
] }),
|
|
128
|
-
state && /* @__PURE__ */ jsxs("label", { className: "db-settings-select", children: [
|
|
129
|
-
/* @__PURE__ */ jsx("span", { className: "db-settings-select-header", children: "Find a catalog" }),
|
|
130
|
-
/* @__PURE__ */ jsx(
|
|
131
|
-
"input",
|
|
154
|
+
state && /* @__PURE__ */ jsxs("div", { className: "db-knowledge-bin", children: [
|
|
155
|
+
/* @__PURE__ */ jsxs("div", { className: "db-knowledge-bin-header", children: [
|
|
156
|
+
/* @__PURE__ */ jsx("h4", { id: binHeadingId, className: "db-knowledge-bin-title", children: "Downloaded catalogs" }),
|
|
157
|
+
/* @__PURE__ */ jsx("span", { className: "db-knowledge-bin-count", "aria-hidden": "true", children: downloaded.length }),
|
|
158
|
+
/* @__PURE__ */ jsx(
|
|
159
|
+
"button",
|
|
160
|
+
{
|
|
161
|
+
type: "button",
|
|
162
|
+
className: "db-settings-action db-settings-action--secondary",
|
|
163
|
+
onClick: () => showAdd(true),
|
|
164
|
+
children: "Add catalog\u2026"
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
] }),
|
|
168
|
+
downloaded.length === 0 ? /* @__PURE__ */ jsx("p", { className: "db-settings-hint db-knowledge-bin-empty", children: "No catalogs downloaded yet. Add a catalog to give AI writing, review, and chat reference material." }) : /* @__PURE__ */ jsx("ul", { className: "db-knowledge-bin-list", "aria-labelledby": binHeadingId, children: downloaded.map((catalog) => /* @__PURE__ */ jsx(
|
|
169
|
+
DownloadedCatalog,
|
|
132
170
|
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
171
|
+
catalog,
|
|
172
|
+
expanded: expanded.has(catalog.id),
|
|
173
|
+
removing: removing === catalog.id,
|
|
174
|
+
busy,
|
|
175
|
+
onToggle: () => toggle(catalog.id),
|
|
176
|
+
onRemoving: (confirming) => setRemoving(confirming ? catalog.id : null),
|
|
177
|
+
onAction: (action) => void update(action)
|
|
178
|
+
},
|
|
179
|
+
catalog.id
|
|
180
|
+
)) })
|
|
139
181
|
] }),
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
182
|
+
adding && state && /* @__PURE__ */ jsx(
|
|
183
|
+
AddCatalogDialog,
|
|
184
|
+
{
|
|
185
|
+
catalogs: state.catalogs,
|
|
186
|
+
busy,
|
|
187
|
+
problem,
|
|
188
|
+
onAction: (action) => void update(action),
|
|
189
|
+
onRefresh: refresh,
|
|
190
|
+
onClose: () => showAdd(false)
|
|
191
|
+
}
|
|
192
|
+
)
|
|
193
|
+
] });
|
|
194
|
+
}
|
|
195
|
+
function DownloadedCatalog({
|
|
196
|
+
catalog,
|
|
197
|
+
expanded,
|
|
198
|
+
removing,
|
|
199
|
+
busy,
|
|
200
|
+
onToggle,
|
|
201
|
+
onRemoving,
|
|
202
|
+
onAction
|
|
203
|
+
}) {
|
|
204
|
+
const bodyId = useId();
|
|
205
|
+
return /* @__PURE__ */ jsxs("li", { className: "db-knowledge-item", children: [
|
|
206
|
+
/* @__PURE__ */ jsxs(
|
|
207
|
+
"button",
|
|
208
|
+
{
|
|
209
|
+
type: "button",
|
|
210
|
+
className: "db-knowledge-item-toggle",
|
|
211
|
+
"aria-expanded": expanded,
|
|
212
|
+
"aria-controls": expanded ? bodyId : void 0,
|
|
213
|
+
onClick: onToggle,
|
|
214
|
+
children: [
|
|
215
|
+
/* @__PURE__ */ jsx(
|
|
216
|
+
"span",
|
|
217
|
+
{
|
|
218
|
+
className: `db-knowledge-item-caret${expanded ? " db-knowledge-item-caret--open" : ""}`,
|
|
219
|
+
"aria-hidden": "true"
|
|
220
|
+
}
|
|
221
|
+
),
|
|
222
|
+
/* @__PURE__ */ jsx("span", { className: "db-knowledge-item-name", children: catalog.name }),
|
|
223
|
+
/* @__PURE__ */ jsx(
|
|
224
|
+
"span",
|
|
225
|
+
{
|
|
226
|
+
className: `db-knowledge-item-summary${catalog.state === "error" ? " db-knowledge-item-summary--error" : ""}`,
|
|
227
|
+
children: catalogSummary(catalog)
|
|
228
|
+
}
|
|
229
|
+
)
|
|
230
|
+
]
|
|
231
|
+
}
|
|
232
|
+
),
|
|
233
|
+
expanded && /* @__PURE__ */ jsxs("div", { id: bodyId, className: "db-knowledge-item-body", children: [
|
|
143
234
|
/* @__PURE__ */ jsx("p", { className: "db-settings-hint", children: catalog.description }),
|
|
144
|
-
/* @__PURE__ */
|
|
145
|
-
"Version ",
|
|
146
|
-
catalog.installedVersion ?? catalog.version,
|
|
147
|
-
catalog.documents === null ? "" : ` \xB7 ${catalog.documents.toLocaleString()} documents`,
|
|
148
|
-
catalog.downloadBytes === null ? "" : ` \xB7 ${(catalog.downloadBytes / 1024 ** 2).toFixed(1)} MB download`
|
|
149
|
-
] }),
|
|
235
|
+
/* @__PURE__ */ jsx("p", { className: "db-settings-hint", children: catalogFacts(catalog, catalog.installedVersion ?? catalog.version) }),
|
|
150
236
|
catalog.message && /* @__PURE__ */ jsx("p", { className: "db-settings-hint", role: catalog.state === "error" ? "alert" : "status", children: catalog.message }),
|
|
151
|
-
catalog.state === "downloading" ? /* @__PURE__ */ jsxs(
|
|
237
|
+
catalog.state === "downloading" ? /* @__PURE__ */ jsxs("div", { className: "db-settings-ai-knowledge-actions", children: [
|
|
152
238
|
/* @__PURE__ */ jsx(
|
|
153
239
|
"progress",
|
|
154
240
|
{
|
|
@@ -163,19 +249,19 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
163
249
|
type: "button",
|
|
164
250
|
className: "db-settings-action db-settings-action--secondary",
|
|
165
251
|
disabled: busy,
|
|
166
|
-
onClick: () =>
|
|
252
|
+
onClick: () => onAction({ action: "cancel", catalogId: catalog.id }),
|
|
167
253
|
children: "Cancel download"
|
|
168
254
|
}
|
|
169
255
|
)
|
|
170
256
|
] }) : /* @__PURE__ */ jsxs("div", { className: "db-settings-ai-knowledge-actions", children: [
|
|
171
|
-
|
|
257
|
+
/* @__PURE__ */ jsxs("label", { className: "db-settings-checkbox", children: [
|
|
172
258
|
/* @__PURE__ */ jsx(
|
|
173
259
|
"input",
|
|
174
260
|
{
|
|
175
261
|
type: "checkbox",
|
|
176
262
|
checked: catalog.enabled,
|
|
177
263
|
disabled: busy,
|
|
178
|
-
onChange: (event) =>
|
|
264
|
+
onChange: (event) => onAction({
|
|
179
265
|
action: event.currentTarget.checked ? "enable" : "disable",
|
|
180
266
|
catalogId: catalog.id
|
|
181
267
|
})
|
|
@@ -184,23 +270,26 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
184
270
|
"Use ",
|
|
185
271
|
catalog.name
|
|
186
272
|
] }),
|
|
187
|
-
|
|
273
|
+
catalog.updateAvailable && /* @__PURE__ */ jsxs(
|
|
188
274
|
"button",
|
|
189
275
|
{
|
|
190
276
|
type: "button",
|
|
191
277
|
className: "db-settings-action",
|
|
192
278
|
disabled: busy,
|
|
193
|
-
onClick: () =>
|
|
194
|
-
children:
|
|
279
|
+
onClick: () => onAction({ action: "install", catalogId: catalog.id }),
|
|
280
|
+
children: [
|
|
281
|
+
"Update to ",
|
|
282
|
+
catalog.version
|
|
283
|
+
]
|
|
195
284
|
}
|
|
196
285
|
),
|
|
197
|
-
|
|
286
|
+
/* @__PURE__ */ jsxs(
|
|
198
287
|
"button",
|
|
199
288
|
{
|
|
200
289
|
type: "button",
|
|
201
290
|
className: "db-settings-action db-settings-action--secondary",
|
|
202
291
|
disabled: busy,
|
|
203
|
-
onClick: () =>
|
|
292
|
+
onClick: () => onRemoving(true),
|
|
204
293
|
children: [
|
|
205
294
|
"Remove ",
|
|
206
295
|
catalog.name,
|
|
@@ -209,34 +298,154 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
209
298
|
}
|
|
210
299
|
)
|
|
211
300
|
] }),
|
|
212
|
-
removing
|
|
301
|
+
removing && /* @__PURE__ */ jsxs("div", { role: "group", "aria-label": `Confirm removal of ${catalog.name}`, children: [
|
|
213
302
|
/* @__PURE__ */ jsxs("p", { className: "db-settings-hint", children: [
|
|
214
303
|
"Remove ",
|
|
215
304
|
catalog.name,
|
|
216
305
|
" from the connected AI service? Other apps using that service will also lose access to this catalog."
|
|
217
306
|
] }),
|
|
307
|
+
/* @__PURE__ */ jsxs("div", { className: "db-settings-ai-knowledge-actions", children: [
|
|
308
|
+
/* @__PURE__ */ jsx(
|
|
309
|
+
"button",
|
|
310
|
+
{
|
|
311
|
+
type: "button",
|
|
312
|
+
className: "db-settings-action",
|
|
313
|
+
disabled: busy,
|
|
314
|
+
onClick: () => onAction({ action: "remove", catalogId: catalog.id }),
|
|
315
|
+
children: "Confirm removal"
|
|
316
|
+
}
|
|
317
|
+
),
|
|
318
|
+
/* @__PURE__ */ jsx(
|
|
319
|
+
"button",
|
|
320
|
+
{
|
|
321
|
+
type: "button",
|
|
322
|
+
className: "db-settings-action db-settings-action--secondary",
|
|
323
|
+
onClick: () => onRemoving(false),
|
|
324
|
+
children: "Keep catalog"
|
|
325
|
+
}
|
|
326
|
+
)
|
|
327
|
+
] })
|
|
328
|
+
] })
|
|
329
|
+
] })
|
|
330
|
+
] });
|
|
331
|
+
}
|
|
332
|
+
function AddCatalogDialog({
|
|
333
|
+
catalogs,
|
|
334
|
+
busy,
|
|
335
|
+
problem,
|
|
336
|
+
onAction,
|
|
337
|
+
onRefresh,
|
|
338
|
+
onClose
|
|
339
|
+
}) {
|
|
340
|
+
const [query, setQuery] = useState("");
|
|
341
|
+
const searchRef = useRef(null);
|
|
342
|
+
const [order] = useState(
|
|
343
|
+
() => [...catalogs].sort((a, b) => Number(a.installedVersion !== null) - Number(b.installedVersion !== null)).map((catalog) => catalog.id)
|
|
344
|
+
);
|
|
345
|
+
const rank = (catalog) => {
|
|
346
|
+
const index = order.indexOf(catalog.id);
|
|
347
|
+
return index < 0 ? order.length : index;
|
|
348
|
+
};
|
|
349
|
+
const needle = query.trim().toLowerCase();
|
|
350
|
+
const matches = catalogs.filter((catalog) => `${catalog.name} ${catalog.description}`.toLowerCase().includes(needle)).sort((a, b) => rank(a) - rank(b));
|
|
351
|
+
const dialog = /* @__PURE__ */ jsxs(
|
|
352
|
+
Dialog,
|
|
353
|
+
{
|
|
354
|
+
title: "Add knowledge catalog",
|
|
355
|
+
size: "wide",
|
|
356
|
+
onClose,
|
|
357
|
+
initialFocusRef: searchRef,
|
|
358
|
+
className: "db-knowledge-add-dialog",
|
|
359
|
+
bodyClassName: "db-knowledge-add-body",
|
|
360
|
+
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
218
361
|
/* @__PURE__ */ jsx(
|
|
219
362
|
"button",
|
|
220
363
|
{
|
|
221
364
|
type: "button",
|
|
222
|
-
className: "db-settings-action",
|
|
365
|
+
className: "db-settings-action db-settings-action--secondary",
|
|
223
366
|
disabled: busy,
|
|
224
|
-
onClick:
|
|
225
|
-
children: "
|
|
367
|
+
onClick: onRefresh,
|
|
368
|
+
children: "Refresh catalogs"
|
|
226
369
|
}
|
|
227
370
|
),
|
|
228
|
-
/* @__PURE__ */ jsx(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
371
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "db-settings-action", onClick: onClose, children: "Done" })
|
|
372
|
+
] }),
|
|
373
|
+
children: [
|
|
374
|
+
/* @__PURE__ */ jsx("p", { className: "db-settings-hint", children: "Catalogs come from the connected AI service. Once one is downloaded, relevant passages from it are included in AI writing, review, and chat." }),
|
|
375
|
+
problem && /* @__PURE__ */ jsx("p", { className: "db-settings-hint db-settings-ai-error", role: "alert", children: problem }),
|
|
376
|
+
/* @__PURE__ */ jsxs("label", { className: "db-settings-text db-knowledge-search", children: [
|
|
377
|
+
"Search catalogs",
|
|
378
|
+
/* @__PURE__ */ jsx(
|
|
379
|
+
"input",
|
|
380
|
+
{
|
|
381
|
+
ref: searchRef,
|
|
382
|
+
className: "db-settings-text-input",
|
|
383
|
+
type: "search",
|
|
384
|
+
value: query,
|
|
385
|
+
onChange: (event) => setQuery(event.currentTarget.value)
|
|
386
|
+
}
|
|
387
|
+
)
|
|
388
|
+
] }),
|
|
389
|
+
/* @__PURE__ */ jsx("p", { className: "db-settings-hint", role: "status", children: matches.length > 0 ? "" : catalogs.length === 0 ? "The connected AI service doesn\u2019t offer any catalogs right now." : `No catalogs match \u201C${query.trim()}\u201D.` }),
|
|
390
|
+
matches.length > 0 && /* @__PURE__ */ jsx("ul", { className: "db-knowledge-catalog-list", "aria-label": "Catalogs", children: matches.map((catalog) => /* @__PURE__ */ jsxs("li", { className: "db-knowledge-catalog", children: [
|
|
391
|
+
/* @__PURE__ */ jsxs("div", { className: "db-knowledge-catalog-text", children: [
|
|
392
|
+
/* @__PURE__ */ jsx("strong", { className: "db-knowledge-catalog-name", children: /* @__PURE__ */ jsx(HighlightedText, { text: catalog.name, ranges: matchRanges(catalog.name, needle) }) }),
|
|
393
|
+
/* @__PURE__ */ jsx("p", { className: "db-settings-hint", children: /* @__PURE__ */ jsx(
|
|
394
|
+
HighlightedText,
|
|
395
|
+
{
|
|
396
|
+
text: catalog.description,
|
|
397
|
+
ranges: matchRanges(catalog.description, needle)
|
|
398
|
+
}
|
|
399
|
+
) }),
|
|
400
|
+
/* @__PURE__ */ jsx("p", { className: "db-settings-hint", children: catalogFacts(catalog, catalog.version) }),
|
|
401
|
+
catalog.message && /* @__PURE__ */ jsx(
|
|
402
|
+
"p",
|
|
403
|
+
{
|
|
404
|
+
className: "db-settings-hint",
|
|
405
|
+
role: catalog.state === "error" ? "alert" : "status",
|
|
406
|
+
children: catalog.message
|
|
407
|
+
}
|
|
408
|
+
)
|
|
409
|
+
] }),
|
|
410
|
+
/* @__PURE__ */ jsx("div", { className: "db-knowledge-catalog-action", children: catalog.state === "downloading" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
411
|
+
/* @__PURE__ */ jsx(
|
|
412
|
+
"progress",
|
|
413
|
+
{
|
|
414
|
+
max: 100,
|
|
415
|
+
value: catalog.percent ?? void 0,
|
|
416
|
+
"aria-label": `${catalog.name} download progress`
|
|
417
|
+
}
|
|
418
|
+
),
|
|
419
|
+
/* @__PURE__ */ jsx(
|
|
420
|
+
"button",
|
|
421
|
+
{
|
|
422
|
+
type: "button",
|
|
423
|
+
className: "db-settings-action db-settings-action--secondary",
|
|
424
|
+
disabled: busy,
|
|
425
|
+
"aria-label": `Cancel ${catalog.name} download`,
|
|
426
|
+
onClick: () => onAction({ action: "cancel", catalogId: catalog.id }),
|
|
427
|
+
children: "Cancel"
|
|
428
|
+
}
|
|
429
|
+
)
|
|
430
|
+
] }) : catalog.installedVersion !== null ? /* @__PURE__ */ jsxs("span", { className: "db-knowledge-catalog-added", children: [
|
|
431
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2713 " }),
|
|
432
|
+
"Downloaded"
|
|
433
|
+
] }) : /* @__PURE__ */ jsx(
|
|
434
|
+
"button",
|
|
435
|
+
{
|
|
436
|
+
type: "button",
|
|
437
|
+
className: "db-settings-action",
|
|
438
|
+
disabled: busy,
|
|
439
|
+
"aria-label": `Download ${catalog.name}`,
|
|
440
|
+
onClick: () => onAction({ action: "install", catalogId: catalog.id }),
|
|
441
|
+
children: "Download"
|
|
442
|
+
}
|
|
443
|
+
) })
|
|
444
|
+
] }, catalog.id)) })
|
|
445
|
+
]
|
|
446
|
+
}
|
|
447
|
+
);
|
|
448
|
+
return typeof document === "undefined" ? dialog : createPortal(dialog, document.body);
|
|
240
449
|
}
|
|
241
450
|
|
|
242
451
|
// src/Settings/AiSettings.tsx
|
|
@@ -329,7 +538,7 @@ function AiSettingsControls({ ai }) {
|
|
|
329
538
|
const [failure, setFailure] = useState2(null);
|
|
330
539
|
const mounted = useRef2(true);
|
|
331
540
|
const installHandle = useRef2(null);
|
|
332
|
-
const modelSelectId =
|
|
541
|
+
const modelSelectId = useId2();
|
|
333
542
|
useEffect2(() => {
|
|
334
543
|
mounted.current = true;
|
|
335
544
|
setProviderInstalled(false);
|
|
@@ -637,7 +846,7 @@ function AiSettingsControls({ ai }) {
|
|
|
637
846
|
}
|
|
638
847
|
|
|
639
848
|
// src/Settings/WorkspaceSettingsControls.tsx
|
|
640
|
-
import { useEffect as useEffect3, useId as
|
|
849
|
+
import { useEffect as useEffect3, useId as useId3, useState as useState3 } from "react";
|
|
641
850
|
import {
|
|
642
851
|
DEFAULT_CATALOG_HTML_PATH,
|
|
643
852
|
DEFAULT_CATALOG_JSON_PATH,
|
|
@@ -690,7 +899,7 @@ function WorkspaceSettingsControls({
|
|
|
690
899
|
onRegenerate,
|
|
691
900
|
regenerating = false
|
|
692
901
|
}) {
|
|
693
|
-
const id =
|
|
902
|
+
const id = useId3();
|
|
694
903
|
const htmlEnabled = value.catalog?.html?.enabled === true;
|
|
695
904
|
const jsonEnabled = value.catalog?.json?.enabled === true;
|
|
696
905
|
const catalogEnabled = htmlEnabled || jsonEnabled;
|
|
@@ -992,7 +1201,7 @@ function WorkspaceSettingsControls({
|
|
|
992
1201
|
import {
|
|
993
1202
|
useCallback as useCallback2,
|
|
994
1203
|
useEffect as useEffect4,
|
|
995
|
-
useId as
|
|
1204
|
+
useId as useId4,
|
|
996
1205
|
useLayoutEffect,
|
|
997
1206
|
useRef as useRef3,
|
|
998
1207
|
useState as useState4
|
|
@@ -1430,8 +1639,8 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1430
1639
|
const triggerRef = useRef3(null);
|
|
1431
1640
|
const listboxRef = useRef3(null);
|
|
1432
1641
|
const optionRefs = useRef3([]);
|
|
1433
|
-
const labelId =
|
|
1434
|
-
const listboxId =
|
|
1642
|
+
const labelId = useId4();
|
|
1643
|
+
const listboxId = useId4();
|
|
1435
1644
|
const close = useCallback2((returnFocus) => {
|
|
1436
1645
|
setIsOpen(false);
|
|
1437
1646
|
setMenuPosition(null);
|
|
@@ -22,6 +22,9 @@ function abortable(promise, signal) {
|
|
|
22
22
|
);
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
+
function stripPauseEllipses(transcript) {
|
|
26
|
+
return transcript.replace(/(?:\.{3,}|…)+/gu, " ").replace(/\s+([,;:!?]|\.(?=\s|$))/gu, "$1").replace(/\s+/gu, " ").trim();
|
|
27
|
+
}
|
|
25
28
|
function createSpeechInputProvider(speech, options) {
|
|
26
29
|
const transcribe = speech.transcribe;
|
|
27
30
|
return {
|
|
@@ -51,7 +54,7 @@ function createSpeechInputProvider(speech, options) {
|
|
|
51
54
|
signal
|
|
52
55
|
);
|
|
53
56
|
if (!result.ok) throw new Error(result.error.message);
|
|
54
|
-
return { text: result.value.text };
|
|
57
|
+
return { text: stripPauseEllipses(result.value.text) };
|
|
55
58
|
}
|
|
56
59
|
};
|
|
57
60
|
}
|
|
@@ -57,6 +57,7 @@ var ProgressivePlayer = class _ProgressivePlayer {
|
|
|
57
57
|
this.playbackOffset = 0;
|
|
58
58
|
}
|
|
59
59
|
await this.context.resume();
|
|
60
|
+
if (this.playing || this.disposed) return this.playing;
|
|
60
61
|
this.stopSources();
|
|
61
62
|
this.playing = true;
|
|
62
63
|
this.playbackStartedAt = this.context.currentTime + 0.025;
|
|
@@ -82,6 +83,19 @@ var ProgressivePlayer = class _ProgressivePlayer {
|
|
|
82
83
|
if (wasPlaying) void this.play();
|
|
83
84
|
else this.emit();
|
|
84
85
|
}
|
|
86
|
+
/** Drop the whole timeline but keep the audio context, to start again from a new place. */
|
|
87
|
+
reset() {
|
|
88
|
+
if (this.disposed) return;
|
|
89
|
+
this.playing = false;
|
|
90
|
+
this.stopSources();
|
|
91
|
+
this.clearEndTimer();
|
|
92
|
+
this.chunks.length = 0;
|
|
93
|
+
this.pending.clear();
|
|
94
|
+
this.bufferedDuration = 0;
|
|
95
|
+
this.playbackOffset = 0;
|
|
96
|
+
this.complete = false;
|
|
97
|
+
this.emit();
|
|
98
|
+
}
|
|
85
99
|
/** No more chunks will arrive. */
|
|
86
100
|
finish() {
|
|
87
101
|
this.complete = true;
|
|
@@ -173,25 +187,54 @@ var ProgressivePlayer = class _ProgressivePlayer {
|
|
|
173
187
|
if (!this.disposed) this.onChange(this.snapshot());
|
|
174
188
|
}
|
|
175
189
|
};
|
|
190
|
+
var MIN_AHEAD_SECONDS = 3;
|
|
191
|
+
var LOOKAHEAD_SECONDS = 60;
|
|
176
192
|
var AutoPlayGate = class {
|
|
177
193
|
constructor() {
|
|
178
|
-
this.
|
|
179
|
-
this.
|
|
180
|
-
this.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
194
|
+
this.spokenCharacters = 0;
|
|
195
|
+
this.spokenSeconds = 0;
|
|
196
|
+
this.timedCharacters = 0;
|
|
197
|
+
this.busySeconds = 0;
|
|
198
|
+
this.lastAt = null;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Record a synthesized chunk. The first chunk after `restart()` only marks
|
|
202
|
+
* the clock, so model loading and skips are not counted against synthesis.
|
|
203
|
+
*/
|
|
204
|
+
record(characters, audioSeconds, nowMs) {
|
|
205
|
+
this.spokenCharacters += characters;
|
|
206
|
+
this.spokenSeconds += audioSeconds;
|
|
207
|
+
if (this.lastAt !== null) {
|
|
208
|
+
this.timedCharacters += characters;
|
|
209
|
+
this.busySeconds += (nowMs - this.lastAt) / 1e3;
|
|
210
|
+
}
|
|
211
|
+
this.lastAt = nowMs;
|
|
212
|
+
}
|
|
213
|
+
/** Synthesis stopped and starts again; the next gap is not a rate sample. */
|
|
214
|
+
restart() {
|
|
215
|
+
this.lastAt = null;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* True when `ahead` seconds of buffered audio should carry playback through
|
|
219
|
+
* the sentences still to be synthesized, given as character counts in order.
|
|
220
|
+
* The first of them has been synthesizing since the last recorded chunk.
|
|
221
|
+
*/
|
|
222
|
+
ready(ahead, upcoming, nowMs) {
|
|
223
|
+
if (this.busySeconds <= 0.25 || this.timedCharacters <= 0 || this.spokenCharacters <= 0) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
const charactersPerSecond = this.timedCharacters / this.busySeconds;
|
|
227
|
+
const secondsPerCharacter = this.spokenSeconds / this.spokenCharacters;
|
|
228
|
+
let arrives = this.lastAt === null ? 0 : -(nowMs - this.lastAt) / 1e3;
|
|
229
|
+
let startsAfter = 0;
|
|
230
|
+
let stall = 0;
|
|
231
|
+
for (const characters of upcoming) {
|
|
232
|
+
arrives = Math.max(0, arrives + characters / charactersPerSecond);
|
|
233
|
+
stall = Math.max(stall, arrives - startsAfter);
|
|
234
|
+
startsAfter += characters * secondsPerCharacter;
|
|
235
|
+
if (startsAfter >= LOOKAHEAD_SECONDS) break;
|
|
188
236
|
}
|
|
189
|
-
|
|
190
|
-
const audioRate = elapsed > 0.25 ? (snapshot.bufferedDuration - this.firstDuration) / elapsed : 0;
|
|
191
|
-
const characterRate = elapsed > 0.25 ? ((progress?.completedCharacters ?? 0) - this.firstCharacters) / elapsed : 0;
|
|
192
|
-
const remaining = progress && characterRate > 0 ? (progress.totalCharacters - progress.completedCharacters) / characterRate : Number.POSITIVE_INFINITY;
|
|
193
|
-
const ahead = snapshot.bufferedDuration - snapshot.currentTime;
|
|
194
|
-
return ahead >= 4 && (audioRate >= 1.15 || ahead >= remaining + 3);
|
|
237
|
+
return ahead >= Math.max(MIN_AHEAD_SECONDS, stall);
|
|
195
238
|
}
|
|
196
239
|
};
|
|
197
240
|
|
|
@@ -343,11 +343,14 @@ function ExportDialog({
|
|
|
343
343
|
}
|
|
344
344
|
)
|
|
345
345
|
] }),
|
|
346
|
-
/* @__PURE__ */ jsxs("
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
346
|
+
/* @__PURE__ */ jsxs("details", { className: "db-export-more-formats", children: [
|
|
347
|
+
/* @__PURE__ */ jsx("summary", { children: "More formats and automation" }),
|
|
348
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
349
|
+
"Need spreadsheets, portable bundles, or batch exports?",
|
|
350
|
+
" ",
|
|
351
|
+
/* @__PURE__ */ jsx("a", { href: "https://docblocks.com/cli/", target: "_blank", rel: "noopener noreferrer", children: "Explore the DocBlocks CLI" }),
|
|
352
|
+
"."
|
|
353
|
+
] })
|
|
351
354
|
] }),
|
|
352
355
|
error && /* @__PURE__ */ jsx("p", { className: "db-export-error", role: "alert", children: error })
|
|
353
356
|
]
|