@bendyline/docblocks-react 2.7.7 → 2.7.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/THIRD_PARTY_NOTICES.txt +205 -35
- package/dist/{AiDiagrams-7KBAOXPB.js → AiDiagrams-2IKKSBAU.js} +5 -3
- package/dist/{AiEditorAssistant-4B2PFFOT.js → AiEditorAssistant-ANYGVG7P.js} +46 -6
- package/dist/AiImagePanel-OXWEFOBC.js +314 -0
- package/dist/{AiStudyDialog-JPVFFZBB.js → AiStudyDialog-T3FY74HY.js} +2 -2
- package/dist/{AudioExportDialog-EICCBSSE.js → AudioExportDialog-CBMSLQBS.js} +1 -1
- package/dist/DocumentConflictDialog-4R4QMKBT.js +217 -0
- package/dist/{ExportDialog-EYDGTJ3S.js → ExportDialog-FNFD53SY.js} +2 -2
- package/dist/{ExportToolbarControls-2XY2CKGH.js → ExportToolbarControls-ZOYH4I36.js} +108 -71
- package/dist/{GitUI-F3CNBURE.js → GitUI-3FANM7I3.js} +88 -155
- package/dist/{KeyboardShortcutsDialog-HVKDFP5Z.js → KeyboardShortcutsDialog-7XJTDIX2.js} +1 -1
- package/dist/{PresentationMaker-VYQKNL3L.js → PresentationMaker-COLTVMTS.js} +3 -3
- package/dist/{QuickOpenDialog-3QEX7RZG.js → QuickOpenDialog-U2FWCEPA.js} +1 -1
- package/dist/{Settings-CfhY489G.d.ts → Settings-ButIB78y.d.ts} +20 -4
- package/dist/{ShareDialog-PF7D7ORP.js → ShareDialog-WOWHI6YI.js} +1 -1
- package/dist/{SpeechToolbarControl-E6OSJGHL.js → SpeechToolbarControl-BZW6IVZM.js} +1 -1
- package/dist/{TextFromNarration-ME6FAYWO.js → TextFromNarration-6BYTUKVZ.js} +2 -2
- package/dist/chunk-27E2OON2.js +90 -0
- package/dist/{chunk-5O5YTOXG.js → chunk-5YMULR6A.js} +13 -1
- package/dist/{chunk-5OIHB3SR.js → chunk-A7BK6QFL.js} +362 -25
- package/dist/{chunk-T2PA7QEF.js → chunk-BGA5UVKL.js} +58 -17
- package/dist/{chunk-N7AKLJPY.js → chunk-CXLXGFG2.js} +16 -8
- package/dist/{chunk-7CSBRAMT.js → chunk-F7TR5EKX.js} +8 -6
- package/dist/chunk-HIKMOKBQ.js +37 -0
- package/dist/chunk-OW6JWRAA.js +66 -0
- package/dist/{chunk-BNKIPCXO.js → chunk-QXBV3G6T.js} +5 -3
- package/dist/{chunk-7HBKKXRV.js → chunk-TN7BY5N3.js} +722 -281
- package/dist/{chunk-VJPGZCFS.js → chunk-UYJCL6OW.js} +4 -2
- package/dist/{chunk-G63YXKBC.js → chunk-WDNE5TI3.js} +13 -2
- package/dist/{chunk-KBUHWZCF.js → chunk-YX275NPE.js} +1 -1
- package/dist/editor.js +3 -3
- package/dist/export/index.d.ts +16 -162
- package/dist/export/index.js +6 -4
- package/dist/image-save-D18dJrUr.d.ts +182 -0
- package/dist/index.d.ts +15 -11
- package/dist/index.js +1154 -964
- package/dist/{run-export-SPNNH32M.js → run-export-C3PLLWLS.js} +2 -2
- package/dist/settings/index.d.ts +1 -1
- package/dist/settings/index.js +3 -2
- package/package.json +8 -8
- package/src/styles/docblocks.css +302 -10
- package/dist/DocumentConflictDialog-DZ2BV2IH.js +0 -111
|
@@ -1,17 +1,221 @@
|
|
|
1
|
+
import {
|
|
2
|
+
imageAccessSentence,
|
|
3
|
+
useImageAccess
|
|
4
|
+
} from "./chunk-OW6JWRAA.js";
|
|
1
5
|
import {
|
|
2
6
|
HighlightedText
|
|
3
7
|
} from "./chunk-TBLZBNQF.js";
|
|
4
8
|
import {
|
|
5
9
|
Dialog
|
|
6
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UYJCL6OW.js";
|
|
7
11
|
|
|
8
12
|
// src/Settings/AiSettings.tsx
|
|
9
|
-
import { useCallback, useEffect as
|
|
13
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useId as useId2, useRef as useRef3, useState as useState3 } from "react";
|
|
14
|
+
|
|
15
|
+
// src/Settings/AiImageSettings.tsx
|
|
16
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
17
|
+
|
|
18
|
+
// src/Speech/format.ts
|
|
19
|
+
function formatModelSize(bytes) {
|
|
20
|
+
const gigabytes = bytes / 1024 ** 3;
|
|
21
|
+
if (gigabytes >= 0.95) return `${gigabytes.toFixed(1)} GB`;
|
|
22
|
+
return `${Math.max(1, Math.round(bytes / 1024 ** 2))} MB`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/Settings/image-model-facts.ts
|
|
26
|
+
function imageModelFacts(model) {
|
|
27
|
+
const facts = [];
|
|
28
|
+
if (model.downloadBytes !== null) facts.push(formatModelSize(model.downloadBytes));
|
|
29
|
+
if (model.license) facts.push(model.license);
|
|
30
|
+
if (model.commercialUse === false) facts.push("Not for commercial use");
|
|
31
|
+
if (model.rendersText) facts.push("Draws legible text");
|
|
32
|
+
if (model.hardwareTier === "workstation") {
|
|
33
|
+
facts.push(
|
|
34
|
+
model.minRamGb !== null ? `Workstation \xB7 ${String(model.minRamGb)} GB+ memory` : "Workstation"
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
if (model.shared) facts.push("Shared with Gezel, no download needed");
|
|
38
|
+
if (model.fit && model.fit.verdict !== "fits" && model.fit.reason) facts.push(model.fit.reason);
|
|
39
|
+
return facts;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/Settings/AiImageSettings.tsx
|
|
43
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
44
|
+
function AiImageSettings({ images }) {
|
|
45
|
+
const access = useImageAccess(images);
|
|
46
|
+
const [models, setModels] = useState(null);
|
|
47
|
+
const [preferences, setPreferences] = useState(null);
|
|
48
|
+
const [failure, setFailure] = useState(null);
|
|
49
|
+
const [installing, setInstalling] = useState(
|
|
50
|
+
null
|
|
51
|
+
);
|
|
52
|
+
const [allowing, setAllowing] = useState(false);
|
|
53
|
+
const installHandle = useRef(null);
|
|
54
|
+
const mounted = useRef(true);
|
|
55
|
+
const ready = access?.kind === "ready";
|
|
56
|
+
const refresh = useCallback(async () => {
|
|
57
|
+
const result = await images.models();
|
|
58
|
+
if (!mounted.current) return;
|
|
59
|
+
if (result.ok) setModels(result.value);
|
|
60
|
+
else setFailure(result.error.message);
|
|
61
|
+
}, [images]);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
mounted.current = true;
|
|
64
|
+
void images.getPreferences().then(
|
|
65
|
+
(initial) => {
|
|
66
|
+
if (mounted.current) setPreferences(initial);
|
|
67
|
+
},
|
|
68
|
+
() => void 0
|
|
69
|
+
);
|
|
70
|
+
return () => {
|
|
71
|
+
mounted.current = false;
|
|
72
|
+
installHandle.current?.cancel();
|
|
73
|
+
};
|
|
74
|
+
}, [images]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (ready) void refresh();
|
|
77
|
+
}, [ready, refresh]);
|
|
78
|
+
const install = async (model) => {
|
|
79
|
+
setFailure(null);
|
|
80
|
+
setInstalling({ id: model.id, progress: null });
|
|
81
|
+
const handle = images.installModel(model.id, (progress) => {
|
|
82
|
+
if (mounted.current) setInstalling({ id: model.id, progress });
|
|
83
|
+
});
|
|
84
|
+
installHandle.current = handle;
|
|
85
|
+
try {
|
|
86
|
+
const result = await handle.done;
|
|
87
|
+
if (!mounted.current) return;
|
|
88
|
+
if (!result.ok && result.error.code !== "cancelled") setFailure(result.error.message);
|
|
89
|
+
await refresh();
|
|
90
|
+
} finally {
|
|
91
|
+
if (installHandle.current === handle) installHandle.current = null;
|
|
92
|
+
if (mounted.current) setInstalling(null);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const remove = async (model) => {
|
|
96
|
+
setFailure(null);
|
|
97
|
+
const result = await images.removeModel(model.id);
|
|
98
|
+
if (!mounted.current) return;
|
|
99
|
+
if (!result.ok) setFailure(result.error.message);
|
|
100
|
+
else setPreferences(await images.getPreferences());
|
|
101
|
+
await refresh();
|
|
102
|
+
};
|
|
103
|
+
const choose = async (patch) => {
|
|
104
|
+
setPreferences(await images.setPreferences(patch));
|
|
105
|
+
};
|
|
106
|
+
const allow = async () => {
|
|
107
|
+
setAllowing(true);
|
|
108
|
+
setFailure(null);
|
|
109
|
+
const result = await images.requestAccess();
|
|
110
|
+
if (!mounted.current) return;
|
|
111
|
+
setAllowing(false);
|
|
112
|
+
if (!result.ok) setFailure(result.error.message);
|
|
113
|
+
};
|
|
114
|
+
const installed = (models ?? []).filter((model) => model.state === "installed");
|
|
115
|
+
const designModels = installed.filter((model) => model.rendersText);
|
|
116
|
+
const blocked = imageAccessSentence(access);
|
|
117
|
+
const modelRow = (model) => {
|
|
118
|
+
const busy = installing?.id === model.id;
|
|
119
|
+
const percent = busy && installing.progress ? installing.progress.percent : null;
|
|
120
|
+
const wontRun = model.fit?.verdict === "wont-run";
|
|
121
|
+
return /* @__PURE__ */ jsxs("li", { className: "db-settings-speech-model", children: [
|
|
122
|
+
/* @__PURE__ */ jsxs("div", { className: "db-settings-speech-model-text", children: [
|
|
123
|
+
/* @__PURE__ */ jsx("span", { className: "db-settings-speech-model-name", children: model.label }),
|
|
124
|
+
/* @__PURE__ */ jsx("span", { className: "db-settings-hint", children: imageModelFacts(model).join(" \xB7 ") })
|
|
125
|
+
] }),
|
|
126
|
+
busy ? /* @__PURE__ */ jsxs("div", { className: "db-settings-ai-download-progress", role: "status", children: [
|
|
127
|
+
/* @__PURE__ */ jsx(
|
|
128
|
+
"progress",
|
|
129
|
+
{
|
|
130
|
+
max: 100,
|
|
131
|
+
value: percent ?? void 0,
|
|
132
|
+
"aria-label": `${model.label} download progress`
|
|
133
|
+
}
|
|
134
|
+
),
|
|
135
|
+
/* @__PURE__ */ jsx("span", { children: installing.progress?.phase === "verifying" ? "Verifying\u2026" : percent === null ? "Starting\u2026" : `${String(Math.round(percent))}%` }),
|
|
136
|
+
/* @__PURE__ */ jsx(
|
|
137
|
+
"button",
|
|
138
|
+
{
|
|
139
|
+
type: "button",
|
|
140
|
+
className: "db-settings-action db-settings-action--secondary",
|
|
141
|
+
onClick: () => installHandle.current?.cancel(),
|
|
142
|
+
children: "Cancel"
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
] }) : model.state === "installed" ? model.shared ? null : /* @__PURE__ */ jsx(
|
|
146
|
+
"button",
|
|
147
|
+
{
|
|
148
|
+
type: "button",
|
|
149
|
+
className: "db-settings-action db-settings-action--secondary",
|
|
150
|
+
disabled: installing !== null,
|
|
151
|
+
onClick: () => void remove(model),
|
|
152
|
+
children: "Remove"
|
|
153
|
+
}
|
|
154
|
+
) : /* @__PURE__ */ jsx(
|
|
155
|
+
"button",
|
|
156
|
+
{
|
|
157
|
+
type: "button",
|
|
158
|
+
className: "db-settings-action",
|
|
159
|
+
disabled: installing !== null || wontRun,
|
|
160
|
+
title: wontRun ? model.fit?.reason ?? void 0 : void 0,
|
|
161
|
+
onClick: () => void install(model),
|
|
162
|
+
children: model.state === "downloading" ? "Show download" : "Download"
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
] }, model.id);
|
|
166
|
+
};
|
|
167
|
+
return /* @__PURE__ */ jsxs("section", { className: "db-settings-ai-knowledge", "aria-label": "Image generation", children: [
|
|
168
|
+
/* @__PURE__ */ jsx("h3", { className: "db-settings-select-header", children: "Image generation" }),
|
|
169
|
+
blocked ? /* @__PURE__ */ jsx("p", { className: "db-settings-hint", role: "status", "aria-live": "polite", children: access?.kind === "awaiting-approval" && access.verificationCode ? `In Gezel, approve DocBlocks and enter the code ${access.verificationCode}.` : blocked }) : /* @__PURE__ */ jsx("p", { className: "db-settings-hint", children: "Images are generated on this computer. Models download only when you choose, and some are large." }),
|
|
170
|
+
access?.kind === "needs-approval" && /* @__PURE__ */ jsx(
|
|
171
|
+
"button",
|
|
172
|
+
{
|
|
173
|
+
type: "button",
|
|
174
|
+
className: "db-settings-action",
|
|
175
|
+
disabled: allowing,
|
|
176
|
+
onClick: () => void allow(),
|
|
177
|
+
children: "Allow image generation\u2026"
|
|
178
|
+
}
|
|
179
|
+
),
|
|
180
|
+
failure && /* @__PURE__ */ jsx("p", { className: "db-settings-hint db-settings-ai-error", role: "alert", children: failure }),
|
|
181
|
+
ready && preferences && installed.length > 0 && /* @__PURE__ */ jsxs("label", { className: "db-settings-select", children: [
|
|
182
|
+
/* @__PURE__ */ jsx("span", { className: "db-settings-select-header", children: "Model for Generate image" }),
|
|
183
|
+
/* @__PURE__ */ jsxs(
|
|
184
|
+
"select",
|
|
185
|
+
{
|
|
186
|
+
className: "db-settings-select-input",
|
|
187
|
+
value: preferences.model ?? "",
|
|
188
|
+
onChange: (event) => void choose({ model: event.currentTarget.value || null }),
|
|
189
|
+
children: [
|
|
190
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "First installed" }),
|
|
191
|
+
installed.map((model) => /* @__PURE__ */ jsx("option", { value: model.id, children: model.label }, model.id))
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
] }),
|
|
196
|
+
ready && preferences && designModels.length > 0 && /* @__PURE__ */ jsxs("label", { className: "db-settings-select", children: [
|
|
197
|
+
/* @__PURE__ */ jsx("span", { className: "db-settings-select-header", children: "Model for design graphics" }),
|
|
198
|
+
/* @__PURE__ */ jsxs(
|
|
199
|
+
"select",
|
|
200
|
+
{
|
|
201
|
+
className: "db-settings-select-input",
|
|
202
|
+
value: preferences.designModel ?? "",
|
|
203
|
+
onChange: (event) => void choose({ designModel: event.currentTarget.value || null }),
|
|
204
|
+
children: [
|
|
205
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "None" }),
|
|
206
|
+
designModels.map((model) => /* @__PURE__ */ jsx("option", { value: model.id, children: model.label }, model.id))
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
] }),
|
|
211
|
+
ready && models && /* @__PURE__ */ jsx("ul", { className: "db-settings-speech-models", children: models.map(modelRow) })
|
|
212
|
+
] });
|
|
213
|
+
}
|
|
10
214
|
|
|
11
215
|
// src/Settings/AiKnowledgeSettings.tsx
|
|
12
|
-
import { useEffect, useId, useRef, useState } from "react";
|
|
216
|
+
import { useEffect as useEffect2, useId, useRef as useRef2, useState as useState2 } from "react";
|
|
13
217
|
import { createPortal } from "react-dom";
|
|
14
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
218
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
15
219
|
function sizedArticle(bytes) {
|
|
16
220
|
const megabytes = String(Math.max(1, Math.round(bytes / 1024 ** 2)));
|
|
17
221
|
const an = megabytes.startsWith("8") || megabytes.length % 3 === 2 && (megabytes.startsWith("11") || megabytes.startsWith("18"));
|
|
@@ -40,24 +244,24 @@ function matchRanges(text, query) {
|
|
|
40
244
|
return ranges;
|
|
41
245
|
}
|
|
42
246
|
function AiKnowledgeSettings({ knowledge }) {
|
|
43
|
-
const [state, setState] =
|
|
44
|
-
const [error, setError] =
|
|
45
|
-
const [loadError, setLoadError] =
|
|
46
|
-
const [unsupported, setUnsupported] =
|
|
47
|
-
const [busy, setBusy] =
|
|
48
|
-
const [revision, setRevision] =
|
|
49
|
-
const [adding, setAdding] =
|
|
50
|
-
const [expanded, setExpanded] =
|
|
51
|
-
const [removing, setRemoving] =
|
|
247
|
+
const [state, setState] = useState2(null);
|
|
248
|
+
const [error, setError] = useState2(null);
|
|
249
|
+
const [loadError, setLoadError] = useState2(null);
|
|
250
|
+
const [unsupported, setUnsupported] = useState2(null);
|
|
251
|
+
const [busy, setBusy] = useState2(false);
|
|
252
|
+
const [revision, setRevision] = useState2(0);
|
|
253
|
+
const [adding, setAdding] = useState2(false);
|
|
254
|
+
const [expanded, setExpanded] = useState2(() => /* @__PURE__ */ new Set());
|
|
255
|
+
const [removing, setRemoving] = useState2(null);
|
|
52
256
|
const binHeadingId = useId();
|
|
53
|
-
const generation =
|
|
54
|
-
|
|
257
|
+
const generation = useRef2(0);
|
|
258
|
+
useEffect2(
|
|
55
259
|
() => () => {
|
|
56
260
|
generation.current++;
|
|
57
261
|
},
|
|
58
262
|
[knowledge]
|
|
59
263
|
);
|
|
60
|
-
|
|
264
|
+
useEffect2(() => {
|
|
61
265
|
let live = true;
|
|
62
266
|
let timer;
|
|
63
267
|
const refresh2 = async () => {
|
|
@@ -119,16 +323,16 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
119
323
|
) ?? [];
|
|
120
324
|
const problem = error ?? loadError;
|
|
121
325
|
if (unsupported)
|
|
122
|
-
return /* @__PURE__ */
|
|
123
|
-
/* @__PURE__ */
|
|
124
|
-
/* @__PURE__ */
|
|
326
|
+
return /* @__PURE__ */ jsxs2("section", { className: "db-settings-ai-knowledge", "aria-label": "Knowledge catalogs", children: [
|
|
327
|
+
/* @__PURE__ */ jsx2("h3", { className: "db-settings-select-header", children: "Knowledge catalogs" }),
|
|
328
|
+
/* @__PURE__ */ jsx2("p", { className: "db-settings-hint", children: unsupported })
|
|
125
329
|
] });
|
|
126
|
-
return /* @__PURE__ */
|
|
127
|
-
/* @__PURE__ */
|
|
128
|
-
/* @__PURE__ */
|
|
129
|
-
problem && !adding && /* @__PURE__ */
|
|
130
|
-
!state && !loadError && /* @__PURE__ */
|
|
131
|
-
!state && loadError && /* @__PURE__ */
|
|
330
|
+
return /* @__PURE__ */ jsxs2("section", { className: "db-settings-ai-knowledge", "aria-label": "Knowledge catalogs", children: [
|
|
331
|
+
/* @__PURE__ */ jsx2("h3", { className: "db-settings-select-header", children: "Knowledge catalogs" }),
|
|
332
|
+
/* @__PURE__ */ jsx2("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." }),
|
|
333
|
+
problem && !adding && /* @__PURE__ */ jsx2("p", { className: "db-settings-hint db-settings-ai-error", role: "alert", children: problem }),
|
|
334
|
+
!state && !loadError && /* @__PURE__ */ jsx2("p", { className: "db-settings-hint", role: "status", children: "Loading knowledge catalogs\u2026" }),
|
|
335
|
+
!state && loadError && /* @__PURE__ */ jsx2(
|
|
132
336
|
"button",
|
|
133
337
|
{
|
|
134
338
|
type: "button",
|
|
@@ -137,7 +341,7 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
137
341
|
children: "Try again"
|
|
138
342
|
}
|
|
139
343
|
),
|
|
140
|
-
state?.improvement && !state.improvement.downloading && /* @__PURE__ */
|
|
344
|
+
state?.improvement && !state.improvement.downloading && /* @__PURE__ */ jsx2("p", { className: "db-settings-hint", children: /* @__PURE__ */ jsxs2(
|
|
141
345
|
"button",
|
|
142
346
|
{
|
|
143
347
|
type: "button",
|
|
@@ -151,11 +355,11 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
151
355
|
]
|
|
152
356
|
}
|
|
153
357
|
) }),
|
|
154
|
-
state && /* @__PURE__ */
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
-
/* @__PURE__ */
|
|
157
|
-
/* @__PURE__ */
|
|
158
|
-
/* @__PURE__ */
|
|
358
|
+
state && /* @__PURE__ */ jsxs2("div", { className: "db-knowledge-bin", children: [
|
|
359
|
+
/* @__PURE__ */ jsxs2("div", { className: "db-knowledge-bin-header", children: [
|
|
360
|
+
/* @__PURE__ */ jsx2("h4", { id: binHeadingId, className: "db-knowledge-bin-title", children: "Downloaded catalogs" }),
|
|
361
|
+
/* @__PURE__ */ jsx2("span", { className: "db-knowledge-bin-count", "aria-hidden": "true", children: downloaded.length }),
|
|
362
|
+
/* @__PURE__ */ jsx2(
|
|
159
363
|
"button",
|
|
160
364
|
{
|
|
161
365
|
type: "button",
|
|
@@ -165,7 +369,7 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
165
369
|
}
|
|
166
370
|
)
|
|
167
371
|
] }),
|
|
168
|
-
downloaded.length === 0 ? /* @__PURE__ */
|
|
372
|
+
downloaded.length === 0 ? /* @__PURE__ */ jsx2("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__ */ jsx2("ul", { className: "db-knowledge-bin-list", "aria-labelledby": binHeadingId, children: downloaded.map((catalog) => /* @__PURE__ */ jsx2(
|
|
169
373
|
DownloadedCatalog,
|
|
170
374
|
{
|
|
171
375
|
catalog,
|
|
@@ -179,7 +383,7 @@ function AiKnowledgeSettings({ knowledge }) {
|
|
|
179
383
|
catalog.id
|
|
180
384
|
)) })
|
|
181
385
|
] }),
|
|
182
|
-
adding && state && /* @__PURE__ */
|
|
386
|
+
adding && state && /* @__PURE__ */ jsx2(
|
|
183
387
|
AddCatalogDialog,
|
|
184
388
|
{
|
|
185
389
|
catalogs: state.catalogs,
|
|
@@ -202,8 +406,8 @@ function DownloadedCatalog({
|
|
|
202
406
|
onAction
|
|
203
407
|
}) {
|
|
204
408
|
const bodyId = useId();
|
|
205
|
-
return /* @__PURE__ */
|
|
206
|
-
/* @__PURE__ */
|
|
409
|
+
return /* @__PURE__ */ jsxs2("li", { className: "db-knowledge-item", children: [
|
|
410
|
+
/* @__PURE__ */ jsxs2(
|
|
207
411
|
"button",
|
|
208
412
|
{
|
|
209
413
|
type: "button",
|
|
@@ -212,15 +416,15 @@ function DownloadedCatalog({
|
|
|
212
416
|
"aria-controls": expanded ? bodyId : void 0,
|
|
213
417
|
onClick: onToggle,
|
|
214
418
|
children: [
|
|
215
|
-
/* @__PURE__ */
|
|
419
|
+
/* @__PURE__ */ jsx2(
|
|
216
420
|
"span",
|
|
217
421
|
{
|
|
218
422
|
className: `db-knowledge-item-caret${expanded ? " db-knowledge-item-caret--open" : ""}`,
|
|
219
423
|
"aria-hidden": "true"
|
|
220
424
|
}
|
|
221
425
|
),
|
|
222
|
-
/* @__PURE__ */
|
|
223
|
-
/* @__PURE__ */
|
|
426
|
+
/* @__PURE__ */ jsx2("span", { className: "db-knowledge-item-name", children: catalog.name }),
|
|
427
|
+
/* @__PURE__ */ jsx2(
|
|
224
428
|
"span",
|
|
225
429
|
{
|
|
226
430
|
className: `db-knowledge-item-summary${catalog.state === "error" ? " db-knowledge-item-summary--error" : ""}`,
|
|
@@ -230,12 +434,12 @@ function DownloadedCatalog({
|
|
|
230
434
|
]
|
|
231
435
|
}
|
|
232
436
|
),
|
|
233
|
-
expanded && /* @__PURE__ */
|
|
234
|
-
/* @__PURE__ */
|
|
235
|
-
/* @__PURE__ */
|
|
236
|
-
catalog.message && /* @__PURE__ */
|
|
237
|
-
catalog.state === "downloading" ? /* @__PURE__ */
|
|
238
|
-
/* @__PURE__ */
|
|
437
|
+
expanded && /* @__PURE__ */ jsxs2("div", { id: bodyId, className: "db-knowledge-item-body", children: [
|
|
438
|
+
/* @__PURE__ */ jsx2("p", { className: "db-settings-hint", children: catalog.description }),
|
|
439
|
+
/* @__PURE__ */ jsx2("p", { className: "db-settings-hint", children: catalogFacts(catalog, catalog.installedVersion ?? catalog.version) }),
|
|
440
|
+
catalog.message && /* @__PURE__ */ jsx2("p", { className: "db-settings-hint", role: catalog.state === "error" ? "alert" : "status", children: catalog.message }),
|
|
441
|
+
catalog.state === "downloading" ? /* @__PURE__ */ jsxs2("div", { className: "db-settings-ai-knowledge-actions", children: [
|
|
442
|
+
/* @__PURE__ */ jsx2(
|
|
239
443
|
"progress",
|
|
240
444
|
{
|
|
241
445
|
max: 100,
|
|
@@ -243,7 +447,7 @@ function DownloadedCatalog({
|
|
|
243
447
|
"aria-label": `${catalog.name} download progress`
|
|
244
448
|
}
|
|
245
449
|
),
|
|
246
|
-
/* @__PURE__ */
|
|
450
|
+
/* @__PURE__ */ jsx2(
|
|
247
451
|
"button",
|
|
248
452
|
{
|
|
249
453
|
type: "button",
|
|
@@ -253,9 +457,9 @@ function DownloadedCatalog({
|
|
|
253
457
|
children: "Cancel download"
|
|
254
458
|
}
|
|
255
459
|
)
|
|
256
|
-
] }) : /* @__PURE__ */
|
|
257
|
-
/* @__PURE__ */
|
|
258
|
-
/* @__PURE__ */
|
|
460
|
+
] }) : /* @__PURE__ */ jsxs2("div", { className: "db-settings-ai-knowledge-actions", children: [
|
|
461
|
+
/* @__PURE__ */ jsxs2("label", { className: "db-settings-checkbox", children: [
|
|
462
|
+
/* @__PURE__ */ jsx2(
|
|
259
463
|
"input",
|
|
260
464
|
{
|
|
261
465
|
type: "checkbox",
|
|
@@ -270,7 +474,7 @@ function DownloadedCatalog({
|
|
|
270
474
|
"Use ",
|
|
271
475
|
catalog.name
|
|
272
476
|
] }),
|
|
273
|
-
catalog.updateAvailable && /* @__PURE__ */
|
|
477
|
+
catalog.updateAvailable && /* @__PURE__ */ jsxs2(
|
|
274
478
|
"button",
|
|
275
479
|
{
|
|
276
480
|
type: "button",
|
|
@@ -283,7 +487,7 @@ function DownloadedCatalog({
|
|
|
283
487
|
]
|
|
284
488
|
}
|
|
285
489
|
),
|
|
286
|
-
/* @__PURE__ */
|
|
490
|
+
/* @__PURE__ */ jsxs2(
|
|
287
491
|
"button",
|
|
288
492
|
{
|
|
289
493
|
type: "button",
|
|
@@ -298,14 +502,14 @@ function DownloadedCatalog({
|
|
|
298
502
|
}
|
|
299
503
|
)
|
|
300
504
|
] }),
|
|
301
|
-
removing && /* @__PURE__ */
|
|
302
|
-
/* @__PURE__ */
|
|
505
|
+
removing && /* @__PURE__ */ jsxs2("div", { role: "group", "aria-label": `Confirm removal of ${catalog.name}`, children: [
|
|
506
|
+
/* @__PURE__ */ jsxs2("p", { className: "db-settings-hint", children: [
|
|
303
507
|
"Remove ",
|
|
304
508
|
catalog.name,
|
|
305
509
|
" from the connected AI service? Other apps using that service will also lose access to this catalog."
|
|
306
510
|
] }),
|
|
307
|
-
/* @__PURE__ */
|
|
308
|
-
/* @__PURE__ */
|
|
511
|
+
/* @__PURE__ */ jsxs2("div", { className: "db-settings-ai-knowledge-actions", children: [
|
|
512
|
+
/* @__PURE__ */ jsx2(
|
|
309
513
|
"button",
|
|
310
514
|
{
|
|
311
515
|
type: "button",
|
|
@@ -315,7 +519,7 @@ function DownloadedCatalog({
|
|
|
315
519
|
children: "Confirm removal"
|
|
316
520
|
}
|
|
317
521
|
),
|
|
318
|
-
/* @__PURE__ */
|
|
522
|
+
/* @__PURE__ */ jsx2(
|
|
319
523
|
"button",
|
|
320
524
|
{
|
|
321
525
|
type: "button",
|
|
@@ -337,9 +541,9 @@ function AddCatalogDialog({
|
|
|
337
541
|
onRefresh,
|
|
338
542
|
onClose
|
|
339
543
|
}) {
|
|
340
|
-
const [query, setQuery] =
|
|
341
|
-
const searchRef =
|
|
342
|
-
const [order] =
|
|
544
|
+
const [query, setQuery] = useState2("");
|
|
545
|
+
const searchRef = useRef2(null);
|
|
546
|
+
const [order] = useState2(
|
|
343
547
|
() => [...catalogs].sort((a, b) => Number(a.installedVersion !== null) - Number(b.installedVersion !== null)).map((catalog) => catalog.id)
|
|
344
548
|
);
|
|
345
549
|
const rank = (catalog) => {
|
|
@@ -348,7 +552,7 @@ function AddCatalogDialog({
|
|
|
348
552
|
};
|
|
349
553
|
const needle = query.trim().toLowerCase();
|
|
350
554
|
const matches = catalogs.filter((catalog) => `${catalog.name} ${catalog.description}`.toLowerCase().includes(needle)).sort((a, b) => rank(a) - rank(b));
|
|
351
|
-
const dialog = /* @__PURE__ */
|
|
555
|
+
const dialog = /* @__PURE__ */ jsxs2(
|
|
352
556
|
Dialog,
|
|
353
557
|
{
|
|
354
558
|
title: "Add knowledge catalog",
|
|
@@ -357,8 +561,8 @@ function AddCatalogDialog({
|
|
|
357
561
|
initialFocusRef: searchRef,
|
|
358
562
|
className: "db-knowledge-add-dialog",
|
|
359
563
|
bodyClassName: "db-knowledge-add-body",
|
|
360
|
-
footer: /* @__PURE__ */
|
|
361
|
-
/* @__PURE__ */
|
|
564
|
+
footer: /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
565
|
+
/* @__PURE__ */ jsx2(
|
|
362
566
|
"button",
|
|
363
567
|
{
|
|
364
568
|
type: "button",
|
|
@@ -368,14 +572,14 @@ function AddCatalogDialog({
|
|
|
368
572
|
children: "Refresh catalogs"
|
|
369
573
|
}
|
|
370
574
|
),
|
|
371
|
-
/* @__PURE__ */
|
|
575
|
+
/* @__PURE__ */ jsx2("button", { type: "button", className: "db-settings-action", onClick: onClose, children: "Done" })
|
|
372
576
|
] }),
|
|
373
577
|
children: [
|
|
374
|
-
/* @__PURE__ */
|
|
375
|
-
problem && /* @__PURE__ */
|
|
376
|
-
/* @__PURE__ */
|
|
578
|
+
/* @__PURE__ */ jsx2("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." }),
|
|
579
|
+
problem && /* @__PURE__ */ jsx2("p", { className: "db-settings-hint db-settings-ai-error", role: "alert", children: problem }),
|
|
580
|
+
/* @__PURE__ */ jsxs2("label", { className: "db-settings-text db-knowledge-search", children: [
|
|
377
581
|
"Search catalogs",
|
|
378
|
-
/* @__PURE__ */
|
|
582
|
+
/* @__PURE__ */ jsx2(
|
|
379
583
|
"input",
|
|
380
584
|
{
|
|
381
585
|
ref: searchRef,
|
|
@@ -386,19 +590,19 @@ function AddCatalogDialog({
|
|
|
386
590
|
}
|
|
387
591
|
)
|
|
388
592
|
] }),
|
|
389
|
-
/* @__PURE__ */
|
|
390
|
-
matches.length > 0 && /* @__PURE__ */
|
|
391
|
-
/* @__PURE__ */
|
|
392
|
-
/* @__PURE__ */
|
|
393
|
-
/* @__PURE__ */
|
|
593
|
+
/* @__PURE__ */ jsx2("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.` }),
|
|
594
|
+
matches.length > 0 && /* @__PURE__ */ jsx2("ul", { className: "db-knowledge-catalog-list", "aria-label": "Catalogs", children: matches.map((catalog) => /* @__PURE__ */ jsxs2("li", { className: "db-knowledge-catalog", children: [
|
|
595
|
+
/* @__PURE__ */ jsxs2("div", { className: "db-knowledge-catalog-text", children: [
|
|
596
|
+
/* @__PURE__ */ jsx2("strong", { className: "db-knowledge-catalog-name", children: /* @__PURE__ */ jsx2(HighlightedText, { text: catalog.name, ranges: matchRanges(catalog.name, needle) }) }),
|
|
597
|
+
/* @__PURE__ */ jsx2("p", { className: "db-settings-hint", children: /* @__PURE__ */ jsx2(
|
|
394
598
|
HighlightedText,
|
|
395
599
|
{
|
|
396
600
|
text: catalog.description,
|
|
397
601
|
ranges: matchRanges(catalog.description, needle)
|
|
398
602
|
}
|
|
399
603
|
) }),
|
|
400
|
-
/* @__PURE__ */
|
|
401
|
-
catalog.message && /* @__PURE__ */
|
|
604
|
+
/* @__PURE__ */ jsx2("p", { className: "db-settings-hint", children: catalogFacts(catalog, catalog.version) }),
|
|
605
|
+
catalog.message && /* @__PURE__ */ jsx2(
|
|
402
606
|
"p",
|
|
403
607
|
{
|
|
404
608
|
className: "db-settings-hint",
|
|
@@ -407,8 +611,8 @@ function AddCatalogDialog({
|
|
|
407
611
|
}
|
|
408
612
|
)
|
|
409
613
|
] }),
|
|
410
|
-
/* @__PURE__ */
|
|
411
|
-
/* @__PURE__ */
|
|
614
|
+
/* @__PURE__ */ jsx2("div", { className: "db-knowledge-catalog-action", children: catalog.state === "downloading" ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
615
|
+
/* @__PURE__ */ jsx2(
|
|
412
616
|
"progress",
|
|
413
617
|
{
|
|
414
618
|
max: 100,
|
|
@@ -416,7 +620,7 @@ function AddCatalogDialog({
|
|
|
416
620
|
"aria-label": `${catalog.name} download progress`
|
|
417
621
|
}
|
|
418
622
|
),
|
|
419
|
-
/* @__PURE__ */
|
|
623
|
+
/* @__PURE__ */ jsx2(
|
|
420
624
|
"button",
|
|
421
625
|
{
|
|
422
626
|
type: "button",
|
|
@@ -427,10 +631,10 @@ function AddCatalogDialog({
|
|
|
427
631
|
children: "Cancel"
|
|
428
632
|
}
|
|
429
633
|
)
|
|
430
|
-
] }) : catalog.installedVersion !== null ? /* @__PURE__ */
|
|
431
|
-
/* @__PURE__ */
|
|
634
|
+
] }) : catalog.installedVersion !== null ? /* @__PURE__ */ jsxs2("span", { className: "db-knowledge-catalog-added", children: [
|
|
635
|
+
/* @__PURE__ */ jsx2("span", { "aria-hidden": "true", children: "\u2713 " }),
|
|
432
636
|
"Downloaded"
|
|
433
|
-
] }) : /* @__PURE__ */
|
|
637
|
+
] }) : /* @__PURE__ */ jsx2(
|
|
434
638
|
"button",
|
|
435
639
|
{
|
|
436
640
|
type: "button",
|
|
@@ -449,7 +653,7 @@ function AddCatalogDialog({
|
|
|
449
653
|
}
|
|
450
654
|
|
|
451
655
|
// src/Settings/AiSettings.tsx
|
|
452
|
-
import { Fragment as Fragment2, jsx as
|
|
656
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
453
657
|
function statusSentence(status) {
|
|
454
658
|
switch (status.kind) {
|
|
455
659
|
case "unavailable":
|
|
@@ -523,23 +727,23 @@ function downloadOptionLabel(model) {
|
|
|
523
727
|
return `${model.label}${size ? ` \u2014 ${size}` : ""}${rating}${slow}`;
|
|
524
728
|
}
|
|
525
729
|
function AiSettingsControls({ ai }) {
|
|
526
|
-
const [status, setStatus] =
|
|
527
|
-
const [preferences, setPreferences] =
|
|
528
|
-
const [providerInstalled, setProviderInstalled] =
|
|
529
|
-
const [models, setModels] =
|
|
530
|
-
const [availableModels, setAvailableModels] =
|
|
531
|
-
const [showModelDownloads, setShowModelDownloads] =
|
|
532
|
-
const [downloadModelId, setDownloadModelId] =
|
|
533
|
-
const [downloadProgress, setDownloadProgress] =
|
|
534
|
-
const [loadingAvailableModels, setLoadingAvailableModels] =
|
|
535
|
-
const [installingModel, setInstallingModel] =
|
|
536
|
-
const [busy, setBusy] =
|
|
537
|
-
const [saving, setSaving] =
|
|
538
|
-
const [failure, setFailure] =
|
|
539
|
-
const mounted =
|
|
540
|
-
const installHandle =
|
|
730
|
+
const [status, setStatus] = useState3(null);
|
|
731
|
+
const [preferences, setPreferences] = useState3(null);
|
|
732
|
+
const [providerInstalled, setProviderInstalled] = useState3(false);
|
|
733
|
+
const [models, setModels] = useState3([]);
|
|
734
|
+
const [availableModels, setAvailableModels] = useState3([]);
|
|
735
|
+
const [showModelDownloads, setShowModelDownloads] = useState3(false);
|
|
736
|
+
const [downloadModelId, setDownloadModelId] = useState3("");
|
|
737
|
+
const [downloadProgress, setDownloadProgress] = useState3(null);
|
|
738
|
+
const [loadingAvailableModels, setLoadingAvailableModels] = useState3(false);
|
|
739
|
+
const [installingModel, setInstallingModel] = useState3(false);
|
|
740
|
+
const [busy, setBusy] = useState3(false);
|
|
741
|
+
const [saving, setSaving] = useState3(false);
|
|
742
|
+
const [failure, setFailure] = useState3(null);
|
|
743
|
+
const mounted = useRef3(true);
|
|
744
|
+
const installHandle = useRef3(null);
|
|
541
745
|
const modelSelectId = useId2();
|
|
542
|
-
|
|
746
|
+
useEffect3(() => {
|
|
543
747
|
mounted.current = true;
|
|
544
748
|
setProviderInstalled(false);
|
|
545
749
|
const unsubscribe = ai.onStatus((next) => {
|
|
@@ -565,12 +769,12 @@ function AiSettingsControls({ ai }) {
|
|
|
565
769
|
};
|
|
566
770
|
}, [ai]);
|
|
567
771
|
const ready = status?.kind === "ready";
|
|
568
|
-
const refreshModels =
|
|
772
|
+
const refreshModels = useCallback2(async () => {
|
|
569
773
|
const result = await ai.models();
|
|
570
774
|
if (mounted.current && result.ok) setModels(result.value);
|
|
571
775
|
return result;
|
|
572
776
|
}, [ai]);
|
|
573
|
-
const refreshAvailableModels =
|
|
777
|
+
const refreshAvailableModels = useCallback2(async () => {
|
|
574
778
|
if (!ai.availableModels) return;
|
|
575
779
|
setLoadingAvailableModels(true);
|
|
576
780
|
try {
|
|
@@ -588,7 +792,7 @@ function AiSettingsControls({ ai }) {
|
|
|
588
792
|
if (mounted.current) setLoadingAvailableModels(false);
|
|
589
793
|
}
|
|
590
794
|
}, [ai]);
|
|
591
|
-
|
|
795
|
+
useEffect3(() => {
|
|
592
796
|
if (!ready) {
|
|
593
797
|
setModels([]);
|
|
594
798
|
setAvailableModels([]);
|
|
@@ -597,7 +801,7 @@ function AiSettingsControls({ ai }) {
|
|
|
597
801
|
}
|
|
598
802
|
void refreshModels();
|
|
599
803
|
}, [ready, refreshModels]);
|
|
600
|
-
const connect =
|
|
804
|
+
const connect = useCallback2(async () => {
|
|
601
805
|
setBusy(true);
|
|
602
806
|
setFailure(null);
|
|
603
807
|
try {
|
|
@@ -609,7 +813,7 @@ function AiSettingsControls({ ai }) {
|
|
|
609
813
|
if (mounted.current) setBusy(false);
|
|
610
814
|
}
|
|
611
815
|
}, [ai]);
|
|
612
|
-
const switchToBuiltIn =
|
|
816
|
+
const switchToBuiltIn = useCallback2(async () => {
|
|
613
817
|
setBusy(true);
|
|
614
818
|
setFailure(null);
|
|
615
819
|
try {
|
|
@@ -618,7 +822,7 @@ function AiSettingsControls({ ai }) {
|
|
|
618
822
|
if (mounted.current) setBusy(false);
|
|
619
823
|
}
|
|
620
824
|
}, [ai]);
|
|
621
|
-
const setEnabled =
|
|
825
|
+
const setEnabled = useCallback2(
|
|
622
826
|
async (enabled2) => {
|
|
623
827
|
const previous = preferences;
|
|
624
828
|
setFailure(null);
|
|
@@ -638,7 +842,7 @@ function AiSettingsControls({ ai }) {
|
|
|
638
842
|
},
|
|
639
843
|
[ai, preferences]
|
|
640
844
|
);
|
|
641
|
-
const retryBuiltIn =
|
|
845
|
+
const retryBuiltIn = useCallback2(async () => {
|
|
642
846
|
setBusy(true);
|
|
643
847
|
setFailure(null);
|
|
644
848
|
try {
|
|
@@ -647,14 +851,14 @@ function AiSettingsControls({ ai }) {
|
|
|
647
851
|
if (mounted.current) setBusy(false);
|
|
648
852
|
}
|
|
649
853
|
}, [ai]);
|
|
650
|
-
const setModel =
|
|
854
|
+
const setModel = useCallback2(
|
|
651
855
|
async (model) => {
|
|
652
856
|
const next = await ai.setPreferences({ model });
|
|
653
857
|
if (mounted.current) setPreferences(next);
|
|
654
858
|
},
|
|
655
859
|
[ai]
|
|
656
860
|
);
|
|
657
|
-
const addModel =
|
|
861
|
+
const addModel = useCallback2(async () => {
|
|
658
862
|
if (!downloadModelId || !ai.installModel) return;
|
|
659
863
|
setFailure(null);
|
|
660
864
|
setDownloadProgress({ phase: "starting", message: "Starting download\u2026", percent: null });
|
|
@@ -692,10 +896,10 @@ function AiSettingsControls({ ai }) {
|
|
|
692
896
|
const modelManagement = Boolean(ai.availableModels && ai.installModel);
|
|
693
897
|
const selectedDownload = availableModels.find((model) => model.id === downloadModelId) ?? null;
|
|
694
898
|
const failureMessage = failure && !(status.kind === "error" && status.error.message === failure.message) && !(status.kind === "unavailable" && failure.code === "provider-unavailable") ? failure.message : null;
|
|
695
|
-
return /* @__PURE__ */
|
|
696
|
-
/* @__PURE__ */
|
|
697
|
-
/* @__PURE__ */
|
|
698
|
-
/* @__PURE__ */
|
|
899
|
+
return /* @__PURE__ */ jsxs3("fieldset", { className: "db-settings-fieldset", children: [
|
|
900
|
+
/* @__PURE__ */ jsx3("legend", { className: "db-settings-legend", children: "AI assistance" }),
|
|
901
|
+
/* @__PURE__ */ jsxs3("label", { className: "db-settings-checkbox", children: [
|
|
902
|
+
/* @__PURE__ */ jsx3(
|
|
699
903
|
"input",
|
|
700
904
|
{
|
|
701
905
|
type: "checkbox",
|
|
@@ -706,19 +910,19 @@ function AiSettingsControls({ ai }) {
|
|
|
706
910
|
),
|
|
707
911
|
"Use AI features"
|
|
708
912
|
] }),
|
|
709
|
-
/* @__PURE__ */
|
|
710
|
-
enabled && /* @__PURE__ */
|
|
711
|
-
/* @__PURE__ */
|
|
712
|
-
code && /* @__PURE__ */
|
|
913
|
+
/* @__PURE__ */ jsx3("p", { className: "db-settings-hint", children: "DocBlocks can offer AI features that run entirely on this device \u2014 no account needed. Model downloads start only when you choose to add one." }),
|
|
914
|
+
enabled && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
915
|
+
/* @__PURE__ */ jsx3("p", { className: "db-settings-hint", role: "status", "aria-live": "polite", children: statusSentence(status) }),
|
|
916
|
+
code && /* @__PURE__ */ jsxs3("p", { className: "db-settings-hint", children: [
|
|
713
917
|
"Type this code in Gezel to approve DocBlocks:",
|
|
714
918
|
" ",
|
|
715
|
-
/* @__PURE__ */
|
|
919
|
+
/* @__PURE__ */ jsx3("strong", { className: "db-settings-ai-code", children: code })
|
|
716
920
|
] }),
|
|
717
|
-
failureMessage && /* @__PURE__ */
|
|
718
|
-
ready && /* @__PURE__ */
|
|
719
|
-
/* @__PURE__ */
|
|
720
|
-
/* @__PURE__ */
|
|
721
|
-
/* @__PURE__ */
|
|
921
|
+
failureMessage && /* @__PURE__ */ jsx3("p", { className: "db-settings-hint db-settings-ai-error", role: "alert", children: failureMessage }),
|
|
922
|
+
ready && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
923
|
+
/* @__PURE__ */ jsxs3("label", { className: "db-settings-select", htmlFor: modelSelectId, children: [
|
|
924
|
+
/* @__PURE__ */ jsx3("span", { className: "db-settings-select-header", children: "Model" }),
|
|
925
|
+
/* @__PURE__ */ jsxs3(
|
|
722
926
|
"select",
|
|
723
927
|
{
|
|
724
928
|
id: modelSelectId,
|
|
@@ -727,21 +931,21 @@ function AiSettingsControls({ ai }) {
|
|
|
727
931
|
disabled: !hasReadyModels || installingModel,
|
|
728
932
|
onChange: (event) => void setModel(event.currentTarget.value || null),
|
|
729
933
|
children: [
|
|
730
|
-
!hasReadyModels ? /* @__PURE__ */
|
|
731
|
-
preferences.model && !models.some((model) => model.id === preferences.model) && /* @__PURE__ */
|
|
732
|
-
models.map((model) => /* @__PURE__ */
|
|
934
|
+
!hasReadyModels ? /* @__PURE__ */ jsx3("option", { value: "", children: models.length ? "No models ready" : "No models installed" }) : /* @__PURE__ */ jsx3("option", { value: "", children: defaultModel ? `Default: ${modelLabel(defaultModel)}` : "Default" }),
|
|
935
|
+
preferences.model && !models.some((model) => model.id === preferences.model) && /* @__PURE__ */ jsx3("option", { value: preferences.model, disabled: true, children: "Previously selected model (not available)" }),
|
|
936
|
+
models.map((model) => /* @__PURE__ */ jsx3("option", { value: model.id, disabled: !modelReady(model), children: modelReady(model) ? modelLabel(model) : `${model.label} (${readinessLabel(model)})` }, model.id))
|
|
733
937
|
]
|
|
734
938
|
}
|
|
735
939
|
)
|
|
736
940
|
] }),
|
|
737
|
-
unavailableModels.map((model) => /* @__PURE__ */
|
|
941
|
+
unavailableModels.map((model) => /* @__PURE__ */ jsxs3("p", { className: "db-settings-hint", children: [
|
|
738
942
|
model.label,
|
|
739
943
|
":",
|
|
740
944
|
" ",
|
|
741
945
|
model.unavailableReason ?? "This model is not available right now."
|
|
742
946
|
] }, model.id)),
|
|
743
|
-
modelManagement && /* @__PURE__ */
|
|
744
|
-
/* @__PURE__ */
|
|
947
|
+
modelManagement && /* @__PURE__ */ jsxs3("div", { className: "db-settings-ai-models", children: [
|
|
948
|
+
/* @__PURE__ */ jsx3(
|
|
745
949
|
"button",
|
|
746
950
|
{
|
|
747
951
|
type: "button",
|
|
@@ -755,27 +959,27 @@ function AiSettingsControls({ ai }) {
|
|
|
755
959
|
children: showModelDownloads ? "Hide model downloads" : "Add model\u2026"
|
|
756
960
|
}
|
|
757
961
|
),
|
|
758
|
-
showModelDownloads && /* @__PURE__ */
|
|
759
|
-
loadingAvailableModels ? /* @__PURE__ */
|
|
760
|
-
/* @__PURE__ */
|
|
761
|
-
/* @__PURE__ */
|
|
762
|
-
/* @__PURE__ */
|
|
962
|
+
showModelDownloads && /* @__PURE__ */ jsxs3("div", { className: "db-settings-ai-model-downloads", children: [
|
|
963
|
+
loadingAvailableModels ? /* @__PURE__ */ jsx3("p", { className: "db-settings-hint", role: "status", children: "Looking for models\u2026" }) : availableModels.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "db-settings-hint", children: "No downloadable models are available for this device." }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
964
|
+
/* @__PURE__ */ jsxs3("label", { className: "db-settings-select", children: [
|
|
965
|
+
/* @__PURE__ */ jsx3("span", { className: "db-settings-select-header", children: "Model to download" }),
|
|
966
|
+
/* @__PURE__ */ jsx3(
|
|
763
967
|
"select",
|
|
764
968
|
{
|
|
765
969
|
className: "db-settings-select-input",
|
|
766
970
|
value: downloadModelId,
|
|
767
971
|
disabled: installingModel,
|
|
768
972
|
onChange: (event) => setDownloadModelId(event.currentTarget.value),
|
|
769
|
-
children: availableModels.map((model) => /* @__PURE__ */
|
|
973
|
+
children: availableModels.map((model) => /* @__PURE__ */ jsx3("option", { value: model.id, children: downloadOptionLabel(model) }, model.id))
|
|
770
974
|
}
|
|
771
975
|
)
|
|
772
976
|
] }),
|
|
773
|
-
selectedDownload && /* @__PURE__ */
|
|
977
|
+
selectedDownload && /* @__PURE__ */ jsxs3("p", { className: "db-settings-hint", title: selectedDownload.fit?.detail, children: [
|
|
774
978
|
selectedDownload.recommended ? "Recommended for this device" : "Downloads and runs on this device",
|
|
775
979
|
formatDownloadSize(selectedDownload.downloadBytes) ? ` \xB7 ${formatDownloadSize(selectedDownload.downloadBytes)}` : "",
|
|
776
980
|
selectedDownload.fit ? ` \xB7 ${selectedDownload.fit.label}` : ""
|
|
777
981
|
] }),
|
|
778
|
-
/* @__PURE__ */
|
|
982
|
+
/* @__PURE__ */ jsx3(
|
|
779
983
|
"button",
|
|
780
984
|
{
|
|
781
985
|
type: "button",
|
|
@@ -786,8 +990,8 @@ function AiSettingsControls({ ai }) {
|
|
|
786
990
|
}
|
|
787
991
|
)
|
|
788
992
|
] }),
|
|
789
|
-
installingModel && downloadProgress && /* @__PURE__ */
|
|
790
|
-
/* @__PURE__ */
|
|
993
|
+
installingModel && downloadProgress && /* @__PURE__ */ jsxs3("div", { className: "db-settings-ai-download-progress", role: "status", children: [
|
|
994
|
+
/* @__PURE__ */ jsx3(
|
|
791
995
|
"progress",
|
|
792
996
|
{
|
|
793
997
|
max: 100,
|
|
@@ -795,7 +999,7 @@ function AiSettingsControls({ ai }) {
|
|
|
795
999
|
"aria-label": "Model download progress"
|
|
796
1000
|
}
|
|
797
1001
|
),
|
|
798
|
-
/* @__PURE__ */
|
|
1002
|
+
/* @__PURE__ */ jsx3(
|
|
799
1003
|
"button",
|
|
800
1004
|
{
|
|
801
1005
|
type: "button",
|
|
@@ -804,7 +1008,7 @@ function AiSettingsControls({ ai }) {
|
|
|
804
1008
|
children: "Cancel download"
|
|
805
1009
|
}
|
|
806
1010
|
),
|
|
807
|
-
/* @__PURE__ */
|
|
1011
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
808
1012
|
downloadProgress.message,
|
|
809
1013
|
downloadProgress.percent === null ? "" : ` (${Math.round(downloadProgress.percent)}%)`
|
|
810
1014
|
] })
|
|
@@ -812,8 +1016,9 @@ function AiSettingsControls({ ai }) {
|
|
|
812
1016
|
] })
|
|
813
1017
|
] })
|
|
814
1018
|
] }),
|
|
815
|
-
ready && ai.knowledge && /* @__PURE__ */
|
|
816
|
-
ready &&
|
|
1019
|
+
ready && ai.knowledge && /* @__PURE__ */ jsx3(AiKnowledgeSettings, { knowledge: ai.knowledge }, status.provider.mode),
|
|
1020
|
+
ready && ai.images && /* @__PURE__ */ jsx3(AiImageSettings, { images: ai.images }, status.provider.mode),
|
|
1021
|
+
ready && status.provider.mode === "installed" ? /* @__PURE__ */ jsx3(
|
|
817
1022
|
"button",
|
|
818
1023
|
{
|
|
819
1024
|
type: "button",
|
|
@@ -822,7 +1027,7 @@ function AiSettingsControls({ ai }) {
|
|
|
822
1027
|
onClick: () => void switchToBuiltIn(),
|
|
823
1028
|
children: "Use built-in AI"
|
|
824
1029
|
}
|
|
825
|
-
) : ready && status.provider.mode === "hosted" && providerInstalled ? /* @__PURE__ */
|
|
1030
|
+
) : ready && status.provider.mode === "hosted" && providerInstalled ? /* @__PURE__ */ jsx3(
|
|
826
1031
|
"button",
|
|
827
1032
|
{
|
|
828
1033
|
type: "button",
|
|
@@ -831,7 +1036,7 @@ function AiSettingsControls({ ai }) {
|
|
|
831
1036
|
onClick: () => void connect(),
|
|
832
1037
|
children: "Connect Gezel app\u2026"
|
|
833
1038
|
}
|
|
834
|
-
) : status.kind === "error" && status.retryable ? /* @__PURE__ */
|
|
1039
|
+
) : status.kind === "error" && status.retryable ? /* @__PURE__ */ jsx3(
|
|
835
1040
|
"button",
|
|
836
1041
|
{
|
|
837
1042
|
type: "button",
|
|
@@ -846,13 +1051,13 @@ function AiSettingsControls({ ai }) {
|
|
|
846
1051
|
}
|
|
847
1052
|
|
|
848
1053
|
// src/Settings/WorkspaceSettingsControls.tsx
|
|
849
|
-
import { useEffect as
|
|
1054
|
+
import { useEffect as useEffect4, useId as useId3, useState as useState4 } from "react";
|
|
850
1055
|
import {
|
|
851
1056
|
DEFAULT_CATALOG_HTML_PATH,
|
|
852
1057
|
DEFAULT_CATALOG_JSON_PATH,
|
|
853
1058
|
DEFAULT_CATALOG_TITLE
|
|
854
1059
|
} from "@bendyline/docblocks/workspace-settings";
|
|
855
|
-
import { jsx as
|
|
1060
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
856
1061
|
function compactObject(value) {
|
|
857
1062
|
const entries = Object.entries(value).filter(([, field]) => field !== void 0);
|
|
858
1063
|
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
@@ -904,14 +1109,14 @@ function WorkspaceSettingsControls({
|
|
|
904
1109
|
const jsonEnabled = value.catalog?.json?.enabled === true;
|
|
905
1110
|
const catalogEnabled = htmlEnabled || jsonEnabled;
|
|
906
1111
|
const excludeText = (value.catalog?.exclude ?? []).join("\n");
|
|
907
|
-
const [excludeDraft, setExcludeDraft] =
|
|
908
|
-
|
|
1112
|
+
const [excludeDraft, setExcludeDraft] = useState4(excludeText);
|
|
1113
|
+
useEffect4(() => {
|
|
909
1114
|
setExcludeDraft(
|
|
910
1115
|
(current) => current.split("\n").map((line) => line.trim()).filter(Boolean).join("\n") === excludeText ? current : excludeText
|
|
911
1116
|
);
|
|
912
1117
|
}, [excludeText]);
|
|
913
1118
|
const versioning = value.versionHistory?.enabled === void 0 ? "inherit" : value.versionHistory.enabled ? "on" : "off";
|
|
914
|
-
const themeSelect = (selectId, selected, emptyLabel, onSelect) => /* @__PURE__ */
|
|
1119
|
+
const themeSelect = (selectId, selected, emptyLabel, onSelect) => /* @__PURE__ */ jsxs4(
|
|
915
1120
|
"select",
|
|
916
1121
|
{
|
|
917
1122
|
id: selectId,
|
|
@@ -920,20 +1125,20 @@ function WorkspaceSettingsControls({
|
|
|
920
1125
|
disabled,
|
|
921
1126
|
onChange: (event) => onSelect(event.currentTarget.value || void 0),
|
|
922
1127
|
children: [
|
|
923
|
-
/* @__PURE__ */
|
|
924
|
-
themes.map((theme) => /* @__PURE__ */
|
|
925
|
-
selected && !themes.some((theme) => theme.id === selected) && /* @__PURE__ */
|
|
1128
|
+
/* @__PURE__ */ jsx4("option", { value: "", children: emptyLabel }),
|
|
1129
|
+
themes.map((theme) => /* @__PURE__ */ jsx4("option", { value: theme.id, children: theme.name }, theme.id)),
|
|
1130
|
+
selected && !themes.some((theme) => theme.id === selected) && /* @__PURE__ */ jsxs4("option", { value: selected, children: [
|
|
926
1131
|
selected,
|
|
927
1132
|
" (not installed)"
|
|
928
1133
|
] })
|
|
929
1134
|
]
|
|
930
1135
|
}
|
|
931
1136
|
);
|
|
932
|
-
return /* @__PURE__ */
|
|
933
|
-
/* @__PURE__ */
|
|
934
|
-
/* @__PURE__ */
|
|
935
|
-
/* @__PURE__ */
|
|
936
|
-
/* @__PURE__ */
|
|
1137
|
+
return /* @__PURE__ */ jsxs4("div", { className: "db-workspace-settings", children: [
|
|
1138
|
+
/* @__PURE__ */ jsxs4("fieldset", { className: "db-settings-fieldset", disabled, children: [
|
|
1139
|
+
/* @__PURE__ */ jsx4("legend", { className: "db-settings-legend", children: "Documents" }),
|
|
1140
|
+
/* @__PURE__ */ jsxs4("div", { className: "db-settings-select", children: [
|
|
1141
|
+
/* @__PURE__ */ jsx4("label", { className: "db-settings-select-header", htmlFor: `${id}-theme`, children: "Default theme" }),
|
|
937
1142
|
themeSelect(
|
|
938
1143
|
`${id}-theme`,
|
|
939
1144
|
value.documents?.defaultTheme,
|
|
@@ -947,13 +1152,13 @@ function WorkspaceSettingsControls({
|
|
|
947
1152
|
)
|
|
948
1153
|
)
|
|
949
1154
|
] }),
|
|
950
|
-
/* @__PURE__ */
|
|
1155
|
+
/* @__PURE__ */ jsx4("p", { className: "db-settings-hint", children: "Used by documents in this folder that don\u2019t choose a theme of their own. Web pages pick up a change the next time they\u2019re saved." })
|
|
951
1156
|
] }),
|
|
952
|
-
/* @__PURE__ */
|
|
953
|
-
/* @__PURE__ */
|
|
954
|
-
/* @__PURE__ */
|
|
955
|
-
/* @__PURE__ */
|
|
956
|
-
/* @__PURE__ */
|
|
1157
|
+
/* @__PURE__ */ jsxs4("fieldset", { className: "db-settings-fieldset", disabled, children: [
|
|
1158
|
+
/* @__PURE__ */ jsx4("legend", { className: "db-settings-legend", children: "Catalog" }),
|
|
1159
|
+
/* @__PURE__ */ jsx4("p", { className: "db-settings-hint", children: "Keep a list of every document in this folder up to date as you save. DocBlocks only ever replaces files it created." }),
|
|
1160
|
+
/* @__PURE__ */ jsxs4("label", { className: "db-settings-checkbox", children: [
|
|
1161
|
+
/* @__PURE__ */ jsx4(
|
|
957
1162
|
"input",
|
|
958
1163
|
{
|
|
959
1164
|
type: "checkbox",
|
|
@@ -965,10 +1170,10 @@ function WorkspaceSettingsControls({
|
|
|
965
1170
|
),
|
|
966
1171
|
"Catalog page"
|
|
967
1172
|
] }),
|
|
968
|
-
htmlEnabled && /* @__PURE__ */
|
|
969
|
-
/* @__PURE__ */
|
|
970
|
-
/* @__PURE__ */
|
|
971
|
-
/* @__PURE__ */
|
|
1173
|
+
htmlEnabled && /* @__PURE__ */ jsxs4("div", { className: "db-settings-subfields", children: [
|
|
1174
|
+
/* @__PURE__ */ jsxs4("div", { className: "db-settings-text", children: [
|
|
1175
|
+
/* @__PURE__ */ jsx4("label", { htmlFor: `${id}-html-path`, children: "Page file" }),
|
|
1176
|
+
/* @__PURE__ */ jsx4(
|
|
972
1177
|
"input",
|
|
973
1178
|
{
|
|
974
1179
|
id: `${id}-html-path`,
|
|
@@ -983,8 +1188,8 @@ function WorkspaceSettingsControls({
|
|
|
983
1188
|
}
|
|
984
1189
|
)
|
|
985
1190
|
] }),
|
|
986
|
-
/* @__PURE__ */
|
|
987
|
-
/* @__PURE__ */
|
|
1191
|
+
/* @__PURE__ */ jsxs4("div", { className: "db-settings-text", children: [
|
|
1192
|
+
/* @__PURE__ */ jsx4("label", { htmlFor: `${id}-html-theme`, children: "Page theme" }),
|
|
988
1193
|
themeSelect(
|
|
989
1194
|
`${id}-html-theme`,
|
|
990
1195
|
value.catalog?.html?.theme,
|
|
@@ -993,8 +1198,8 @@ function WorkspaceSettingsControls({
|
|
|
993
1198
|
)
|
|
994
1199
|
] })
|
|
995
1200
|
] }),
|
|
996
|
-
/* @__PURE__ */
|
|
997
|
-
/* @__PURE__ */
|
|
1201
|
+
/* @__PURE__ */ jsxs4("label", { className: "db-settings-checkbox", children: [
|
|
1202
|
+
/* @__PURE__ */ jsx4(
|
|
998
1203
|
"input",
|
|
999
1204
|
{
|
|
1000
1205
|
type: "checkbox",
|
|
@@ -1006,10 +1211,10 @@ function WorkspaceSettingsControls({
|
|
|
1006
1211
|
),
|
|
1007
1212
|
"Catalog data (JSON)"
|
|
1008
1213
|
] }),
|
|
1009
|
-
jsonEnabled && /* @__PURE__ */
|
|
1010
|
-
/* @__PURE__ */
|
|
1011
|
-
/* @__PURE__ */
|
|
1012
|
-
/* @__PURE__ */
|
|
1214
|
+
jsonEnabled && /* @__PURE__ */ jsxs4("div", { className: "db-settings-subfields", children: [
|
|
1215
|
+
/* @__PURE__ */ jsxs4("div", { className: "db-settings-text", children: [
|
|
1216
|
+
/* @__PURE__ */ jsx4("label", { htmlFor: `${id}-json-path`, children: "Data file" }),
|
|
1217
|
+
/* @__PURE__ */ jsx4(
|
|
1013
1218
|
"input",
|
|
1014
1219
|
{
|
|
1015
1220
|
id: `${id}-json-path`,
|
|
@@ -1024,7 +1229,7 @@ function WorkspaceSettingsControls({
|
|
|
1024
1229
|
}
|
|
1025
1230
|
)
|
|
1026
1231
|
] }),
|
|
1027
|
-
/* @__PURE__ */
|
|
1232
|
+
/* @__PURE__ */ jsx4(
|
|
1028
1233
|
"div",
|
|
1029
1234
|
{
|
|
1030
1235
|
className: "db-settings-radio-row",
|
|
@@ -1033,8 +1238,8 @@ function WorkspaceSettingsControls({
|
|
|
1033
1238
|
children: [
|
|
1034
1239
|
["metadata", "Titles, descriptions and outlines"],
|
|
1035
1240
|
["markdown", "Also include each document\u2019s Markdown"]
|
|
1036
|
-
].map(([content, label]) => /* @__PURE__ */
|
|
1037
|
-
/* @__PURE__ */
|
|
1241
|
+
].map(([content, label]) => /* @__PURE__ */ jsxs4("label", { className: "db-settings-radio db-settings-radio--inline", children: [
|
|
1242
|
+
/* @__PURE__ */ jsx4(
|
|
1038
1243
|
"input",
|
|
1039
1244
|
{
|
|
1040
1245
|
type: "radio",
|
|
@@ -1052,10 +1257,10 @@ function WorkspaceSettingsControls({
|
|
|
1052
1257
|
}
|
|
1053
1258
|
)
|
|
1054
1259
|
] }),
|
|
1055
|
-
catalogEnabled && /* @__PURE__ */
|
|
1056
|
-
/* @__PURE__ */
|
|
1057
|
-
/* @__PURE__ */
|
|
1058
|
-
/* @__PURE__ */
|
|
1260
|
+
catalogEnabled && /* @__PURE__ */ jsxs4("div", { className: "db-settings-subfields", children: [
|
|
1261
|
+
/* @__PURE__ */ jsxs4("div", { className: "db-settings-text", children: [
|
|
1262
|
+
/* @__PURE__ */ jsx4("label", { htmlFor: `${id}-title`, children: "Title" }),
|
|
1263
|
+
/* @__PURE__ */ jsx4(
|
|
1059
1264
|
"input",
|
|
1060
1265
|
{
|
|
1061
1266
|
id: `${id}-title`,
|
|
@@ -1067,9 +1272,9 @@ function WorkspaceSettingsControls({
|
|
|
1067
1272
|
}
|
|
1068
1273
|
)
|
|
1069
1274
|
] }),
|
|
1070
|
-
/* @__PURE__ */
|
|
1071
|
-
/* @__PURE__ */
|
|
1072
|
-
/* @__PURE__ */
|
|
1275
|
+
/* @__PURE__ */ jsxs4("div", { className: "db-settings-text", children: [
|
|
1276
|
+
/* @__PURE__ */ jsx4("label", { htmlFor: `${id}-sort`, children: "Order" }),
|
|
1277
|
+
/* @__PURE__ */ jsxs4(
|
|
1073
1278
|
"select",
|
|
1074
1279
|
{
|
|
1075
1280
|
id: `${id}-sort`,
|
|
@@ -1080,16 +1285,16 @@ function WorkspaceSettingsControls({
|
|
|
1080
1285
|
onChange(withCatalog(value, { sort: sort === "title" ? void 0 : sort }));
|
|
1081
1286
|
},
|
|
1082
1287
|
children: [
|
|
1083
|
-
/* @__PURE__ */
|
|
1084
|
-
/* @__PURE__ */
|
|
1085
|
-
/* @__PURE__ */
|
|
1288
|
+
/* @__PURE__ */ jsx4("option", { value: "title", children: "By title" }),
|
|
1289
|
+
/* @__PURE__ */ jsx4("option", { value: "date", children: "Newest first (frontmatter date)" }),
|
|
1290
|
+
/* @__PURE__ */ jsx4("option", { value: "path", children: "By file path" })
|
|
1086
1291
|
]
|
|
1087
1292
|
}
|
|
1088
1293
|
)
|
|
1089
1294
|
] }),
|
|
1090
|
-
/* @__PURE__ */
|
|
1091
|
-
/* @__PURE__ */
|
|
1092
|
-
/* @__PURE__ */
|
|
1295
|
+
/* @__PURE__ */ jsxs4("div", { className: "db-settings-text", children: [
|
|
1296
|
+
/* @__PURE__ */ jsx4("label", { htmlFor: `${id}-exclude`, children: "Leave out" }),
|
|
1297
|
+
/* @__PURE__ */ jsx4(
|
|
1093
1298
|
"textarea",
|
|
1094
1299
|
{
|
|
1095
1300
|
id: `${id}-exclude`,
|
|
@@ -1109,9 +1314,9 @@ function WorkspaceSettingsControls({
|
|
|
1109
1314
|
}
|
|
1110
1315
|
)
|
|
1111
1316
|
] }),
|
|
1112
|
-
/* @__PURE__ */
|
|
1113
|
-
(catalogStatus || onRegenerate) && /* @__PURE__ */
|
|
1114
|
-
catalogStatus && /* @__PURE__ */
|
|
1317
|
+
/* @__PURE__ */ jsx4("p", { className: "db-settings-hint", children: "One folder or file per line." }),
|
|
1318
|
+
(catalogStatus || onRegenerate) && /* @__PURE__ */ jsxs4("div", { className: "db-settings-status-row", children: [
|
|
1319
|
+
catalogStatus && /* @__PURE__ */ jsx4(
|
|
1115
1320
|
"p",
|
|
1116
1321
|
{
|
|
1117
1322
|
className: `db-settings-status db-settings-status--${catalogStatus.tone}`,
|
|
@@ -1119,7 +1324,7 @@ function WorkspaceSettingsControls({
|
|
|
1119
1324
|
children: catalogStatus.message
|
|
1120
1325
|
}
|
|
1121
1326
|
),
|
|
1122
|
-
onRegenerate && /* @__PURE__ */
|
|
1327
|
+
onRegenerate && /* @__PURE__ */ jsx4(
|
|
1123
1328
|
"button",
|
|
1124
1329
|
{
|
|
1125
1330
|
type: "button",
|
|
@@ -1132,19 +1337,19 @@ function WorkspaceSettingsControls({
|
|
|
1132
1337
|
] })
|
|
1133
1338
|
] })
|
|
1134
1339
|
] }),
|
|
1135
|
-
versionHistory && /* @__PURE__ */
|
|
1136
|
-
/* @__PURE__ */
|
|
1137
|
-
/* @__PURE__ */
|
|
1340
|
+
versionHistory && /* @__PURE__ */ jsxs4("fieldset", { className: "db-settings-fieldset", disabled, children: [
|
|
1341
|
+
/* @__PURE__ */ jsx4("legend", { className: "db-settings-legend", children: "Version history" }),
|
|
1342
|
+
/* @__PURE__ */ jsxs4("p", { className: "db-settings-hint", children: [
|
|
1138
1343
|
"Keeps prior revisions in ",
|
|
1139
|
-
/* @__PURE__ */
|
|
1344
|
+
/* @__PURE__ */ jsx4("code", { children: "<name>_files/.versions/" }),
|
|
1140
1345
|
" for documents in this folder."
|
|
1141
1346
|
] }),
|
|
1142
1347
|
[
|
|
1143
1348
|
["inherit", versionHistory.inheritLabel],
|
|
1144
1349
|
["on", "On for this folder"],
|
|
1145
1350
|
["off", "Off for this folder"]
|
|
1146
|
-
].map(([option, label]) => /* @__PURE__ */
|
|
1147
|
-
/* @__PURE__ */
|
|
1351
|
+
].map(([option, label]) => /* @__PURE__ */ jsxs4("label", { className: "db-settings-radio", children: [
|
|
1352
|
+
/* @__PURE__ */ jsx4(
|
|
1148
1353
|
"input",
|
|
1149
1354
|
{
|
|
1150
1355
|
type: "radio",
|
|
@@ -1165,9 +1370,9 @@ function WorkspaceSettingsControls({
|
|
|
1165
1370
|
),
|
|
1166
1371
|
label
|
|
1167
1372
|
] }, option)),
|
|
1168
|
-
/* @__PURE__ */
|
|
1169
|
-
/* @__PURE__ */
|
|
1170
|
-
/* @__PURE__ */
|
|
1373
|
+
/* @__PURE__ */ jsxs4("div", { className: "db-settings-text", children: [
|
|
1374
|
+
/* @__PURE__ */ jsx4("label", { htmlFor: `${id}-keep`, children: "Revisions to keep per document" }),
|
|
1375
|
+
/* @__PURE__ */ jsx4(
|
|
1171
1376
|
"input",
|
|
1172
1377
|
{
|
|
1173
1378
|
id: `${id}-keep`,
|
|
@@ -1199,14 +1404,115 @@ function WorkspaceSettingsControls({
|
|
|
1199
1404
|
|
|
1200
1405
|
// src/Settings/Settings.tsx
|
|
1201
1406
|
import {
|
|
1202
|
-
useCallback as
|
|
1203
|
-
useEffect as
|
|
1407
|
+
useCallback as useCallback3,
|
|
1408
|
+
useEffect as useEffect6,
|
|
1204
1409
|
useId as useId4,
|
|
1205
1410
|
useLayoutEffect,
|
|
1206
|
-
useRef as
|
|
1207
|
-
useState as
|
|
1411
|
+
useRef as useRef4,
|
|
1412
|
+
useState as useState6
|
|
1208
1413
|
} from "react";
|
|
1209
1414
|
|
|
1415
|
+
// src/layout/form-factor.ts
|
|
1416
|
+
var DB_BREAKPOINTS = Object.freeze({
|
|
1417
|
+
/** Inclusive upper bound for phones and narrow slivers. */
|
|
1418
|
+
compactMax: 720,
|
|
1419
|
+
/** Inclusive upper bound for tablet-portrait and half-screen laptops. */
|
|
1420
|
+
mediumMax: 1023,
|
|
1421
|
+
/** Inclusive upper bound for tablet-landscape and laptops. */
|
|
1422
|
+
expandedMax: 1439,
|
|
1423
|
+
/**
|
|
1424
|
+
* Largest short edge still considered a phone. Orientation-independent on
|
|
1425
|
+
* purpose: a phone turned sideways is 844x390, which is `medium` by width but
|
|
1426
|
+
* is obviously not a tablet. The widest phone short edge in circulation is
|
|
1427
|
+
* around 430px; the narrowest tablet short edge is the iPad mini's 744px, so
|
|
1428
|
+
* 520 sits in open space between them.
|
|
1429
|
+
*/
|
|
1430
|
+
phoneMaxShortEdge: 520
|
|
1431
|
+
});
|
|
1432
|
+
var SIDEBAR_WIDTH_DEFAULT = 320;
|
|
1433
|
+
var SIDEBAR_WIDTH_MIN = 320;
|
|
1434
|
+
var SIDEBAR_WIDTH_MAX = 600;
|
|
1435
|
+
var SIDEBAR_COLLAPSE_THRESHOLD = SIDEBAR_WIDTH_MIN;
|
|
1436
|
+
var DB_LAYOUT_MINIMA = Object.freeze({
|
|
1437
|
+
/**
|
|
1438
|
+
* Narrower than this, an editor pane beside the sidebar is not worth the
|
|
1439
|
+
* split. Paired with `SIDEBAR_WIDTH_MIN` to derive `splitPaneAllowed`.
|
|
1440
|
+
*/
|
|
1441
|
+
editorMinWidth: 480
|
|
1442
|
+
});
|
|
1443
|
+
var SPLIT_PANE_MIN_WIDTH = SIDEBAR_WIDTH_MIN + DB_LAYOUT_MINIMA.editorMinWidth;
|
|
1444
|
+
function classifyWidth(width) {
|
|
1445
|
+
if (width <= DB_BREAKPOINTS.compactMax) return "compact";
|
|
1446
|
+
if (width <= DB_BREAKPOINTS.mediumMax) return "medium";
|
|
1447
|
+
if (width <= DB_BREAKPOINTS.expandedMax) return "expanded";
|
|
1448
|
+
return "wide";
|
|
1449
|
+
}
|
|
1450
|
+
function classifyFormFactor(input) {
|
|
1451
|
+
const widthClass = classifyWidth(input.width);
|
|
1452
|
+
const orientation = input.height >= input.width ? "portrait" : "landscape";
|
|
1453
|
+
let formFactor;
|
|
1454
|
+
if (input.pointer === "fine") {
|
|
1455
|
+
formFactor = "desktop";
|
|
1456
|
+
} else if (Math.min(input.width, input.height) <= DB_BREAKPOINTS.phoneMaxShortEdge) {
|
|
1457
|
+
formFactor = "phone";
|
|
1458
|
+
} else {
|
|
1459
|
+
formFactor = orientation === "portrait" ? "tablet-portrait" : "tablet-landscape";
|
|
1460
|
+
}
|
|
1461
|
+
return {
|
|
1462
|
+
...input,
|
|
1463
|
+
widthClass,
|
|
1464
|
+
orientation,
|
|
1465
|
+
formFactor,
|
|
1466
|
+
splitPaneAllowed: input.width >= SPLIT_PANE_MIN_WIDTH
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
function resolveLayoutMode(formFactor, preference) {
|
|
1470
|
+
if (!formFactor.splitPaneAllowed) return "single-pane";
|
|
1471
|
+
if (preference === "collapsed") return "single-pane";
|
|
1472
|
+
if (preference === "pinned") return "split-pane";
|
|
1473
|
+
if (formFactor.widthClass === "expanded" || formFactor.widthClass === "wide") {
|
|
1474
|
+
return "split-pane";
|
|
1475
|
+
}
|
|
1476
|
+
if (formFactor.pointer === "fine") return "split-pane";
|
|
1477
|
+
return "single-pane";
|
|
1478
|
+
}
|
|
1479
|
+
function formFactorDataAttributes(formFactor, layoutMode) {
|
|
1480
|
+
return Object.freeze({
|
|
1481
|
+
"data-db-width": formFactor.widthClass,
|
|
1482
|
+
"data-db-form-factor": formFactor.formFactor,
|
|
1483
|
+
"data-db-pointer": formFactor.pointer,
|
|
1484
|
+
"data-db-hover": formFactor.hover,
|
|
1485
|
+
"data-db-orientation": formFactor.orientation,
|
|
1486
|
+
"data-db-layout": layoutMode
|
|
1487
|
+
});
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
// src/layout/useMediaQuery.ts
|
|
1491
|
+
import { useEffect as useEffect5, useState as useState5 } from "react";
|
|
1492
|
+
var INSTALLED_DISPLAY_QUERIES = [
|
|
1493
|
+
"(display-mode: window-controls-overlay)",
|
|
1494
|
+
"(display-mode: standalone)"
|
|
1495
|
+
];
|
|
1496
|
+
function matchesMediaQuery(query) {
|
|
1497
|
+
if (typeof globalThis.matchMedia !== "function") return false;
|
|
1498
|
+
return globalThis.matchMedia(query).matches;
|
|
1499
|
+
}
|
|
1500
|
+
function isInstalledDisplayMode() {
|
|
1501
|
+
return INSTALLED_DISPLAY_QUERIES.some(matchesMediaQuery);
|
|
1502
|
+
}
|
|
1503
|
+
function useMediaQuery(query) {
|
|
1504
|
+
const [matches, setMatches] = useState5(() => matchesMediaQuery(query));
|
|
1505
|
+
useEffect5(() => {
|
|
1506
|
+
if (typeof globalThis.matchMedia !== "function") return;
|
|
1507
|
+
const list = globalThis.matchMedia(query);
|
|
1508
|
+
const update = () => setMatches(list.matches);
|
|
1509
|
+
update();
|
|
1510
|
+
list.addEventListener("change", update);
|
|
1511
|
+
return () => list.removeEventListener("change", update);
|
|
1512
|
+
}, [query]);
|
|
1513
|
+
return matches;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1210
1516
|
// src/preferences/theme.ts
|
|
1211
1517
|
var ACCENT_COLORS = [
|
|
1212
1518
|
"rust",
|
|
@@ -1408,7 +1714,7 @@ function isRecord(value) {
|
|
|
1408
1714
|
}
|
|
1409
1715
|
|
|
1410
1716
|
// src/Settings/Settings.tsx
|
|
1411
|
-
import { jsx as
|
|
1717
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1412
1718
|
var ACCENT_LABELS = {
|
|
1413
1719
|
rust: "Rust",
|
|
1414
1720
|
green: "Green",
|
|
@@ -1418,15 +1724,140 @@ var ACCENT_LABELS = {
|
|
|
1418
1724
|
orange: "Orange",
|
|
1419
1725
|
gray: "Gray"
|
|
1420
1726
|
};
|
|
1421
|
-
function SettingsDialog({
|
|
1422
|
-
|
|
1727
|
+
function SettingsDialog({
|
|
1728
|
+
title = "Settings",
|
|
1729
|
+
onClose,
|
|
1730
|
+
children,
|
|
1731
|
+
sections,
|
|
1732
|
+
section,
|
|
1733
|
+
onSectionChange
|
|
1734
|
+
}) {
|
|
1735
|
+
const sectioned = sections !== void 0 && sections.length > 1;
|
|
1736
|
+
return /* @__PURE__ */ jsx5(
|
|
1737
|
+
Dialog,
|
|
1738
|
+
{
|
|
1739
|
+
title,
|
|
1740
|
+
onClose,
|
|
1741
|
+
size: "wide",
|
|
1742
|
+
className: sectioned ? "db-settings-dialog--sectioned" : void 0,
|
|
1743
|
+
bodyClassName: sectioned ? "db-settings-dialog-body--sectioned" : void 0,
|
|
1744
|
+
children: sectioned ? /* @__PURE__ */ jsx5(SettingsSections, { sections, section, onSectionChange }) : sections?.[0]?.content ?? children
|
|
1745
|
+
}
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
var SECTION_DROPDOWN_QUERY = [
|
|
1749
|
+
`(max-width: ${DB_BREAKPOINTS.compactMax}px)`,
|
|
1750
|
+
"(pointer: coarse) and (orientation: portrait)",
|
|
1751
|
+
`(pointer: coarse) and (max-height: ${DB_BREAKPOINTS.phoneMaxShortEdge}px)`
|
|
1752
|
+
].join(", ");
|
|
1753
|
+
function SettingsSections({
|
|
1754
|
+
sections,
|
|
1755
|
+
section,
|
|
1756
|
+
onSectionChange
|
|
1757
|
+
}) {
|
|
1758
|
+
const [ownSection, setOwnSection] = useState6(sections[0].id);
|
|
1759
|
+
const active = sections.find((entry) => entry.id === (section ?? ownSection)) ?? sections[0];
|
|
1760
|
+
const dropdown = useMediaQuery(SECTION_DROPDOWN_QUERY);
|
|
1761
|
+
const baseId = useId4();
|
|
1762
|
+
const tabRefs = useRef4(/* @__PURE__ */ new Map());
|
|
1763
|
+
const tabId = (id) => `${baseId}-${id}-tab`;
|
|
1764
|
+
const panelId = (id) => `${baseId}-${id}-panel`;
|
|
1765
|
+
const select = (id) => {
|
|
1766
|
+
setOwnSection(id);
|
|
1767
|
+
onSectionChange?.(id);
|
|
1768
|
+
};
|
|
1769
|
+
const handleTabKeyDown = (event) => {
|
|
1770
|
+
const index = sections.indexOf(active);
|
|
1771
|
+
let next;
|
|
1772
|
+
switch (event.key) {
|
|
1773
|
+
case "ArrowDown":
|
|
1774
|
+
next = (index + 1) % sections.length;
|
|
1775
|
+
break;
|
|
1776
|
+
case "ArrowUp":
|
|
1777
|
+
next = (index - 1 + sections.length) % sections.length;
|
|
1778
|
+
break;
|
|
1779
|
+
case "Home":
|
|
1780
|
+
next = 0;
|
|
1781
|
+
break;
|
|
1782
|
+
case "End":
|
|
1783
|
+
next = sections.length - 1;
|
|
1784
|
+
break;
|
|
1785
|
+
default:
|
|
1786
|
+
return;
|
|
1787
|
+
}
|
|
1788
|
+
event.preventDefault();
|
|
1789
|
+
const target = sections[next];
|
|
1790
|
+
select(target.id);
|
|
1791
|
+
tabRefs.current.get(target.id)?.focus();
|
|
1792
|
+
};
|
|
1793
|
+
return /* @__PURE__ */ jsxs5("div", { className: `db-settings-sections db-settings-sections--${dropdown ? "dropdown" : "tabs"}`, children: [
|
|
1794
|
+
dropdown ? /* @__PURE__ */ jsx5("div", { className: "db-settings-section-picker", children: /* @__PURE__ */ jsx5(
|
|
1795
|
+
"select",
|
|
1796
|
+
{
|
|
1797
|
+
className: "db-settings-select-input db-settings-section-select",
|
|
1798
|
+
"aria-label": "Settings section",
|
|
1799
|
+
value: active.id,
|
|
1800
|
+
onChange: (event) => {
|
|
1801
|
+
const value = event.currentTarget.value;
|
|
1802
|
+
const next = sections.find((entry) => entry.id === value);
|
|
1803
|
+
if (next) select(next.id);
|
|
1804
|
+
},
|
|
1805
|
+
children: sections.map((entry) => /* @__PURE__ */ jsx5("option", { value: entry.id, children: entry.label }, entry.id))
|
|
1806
|
+
}
|
|
1807
|
+
) }) : /* @__PURE__ */ jsx5(
|
|
1808
|
+
"div",
|
|
1809
|
+
{
|
|
1810
|
+
className: "db-settings-tabs",
|
|
1811
|
+
role: "tablist",
|
|
1812
|
+
"aria-orientation": "vertical",
|
|
1813
|
+
"aria-label": "Settings sections",
|
|
1814
|
+
children: sections.map((entry) => {
|
|
1815
|
+
const selected = entry === active;
|
|
1816
|
+
return /* @__PURE__ */ jsx5(
|
|
1817
|
+
"button",
|
|
1818
|
+
{
|
|
1819
|
+
ref: (element) => {
|
|
1820
|
+
if (element) tabRefs.current.set(entry.id, element);
|
|
1821
|
+
else tabRefs.current.delete(entry.id);
|
|
1822
|
+
},
|
|
1823
|
+
type: "button",
|
|
1824
|
+
role: "tab",
|
|
1825
|
+
id: tabId(entry.id),
|
|
1826
|
+
className: `db-settings-tab${selected ? " db-settings-tab--selected" : ""}`,
|
|
1827
|
+
"aria-selected": selected,
|
|
1828
|
+
"aria-controls": panelId(entry.id),
|
|
1829
|
+
tabIndex: selected ? 0 : -1,
|
|
1830
|
+
onClick: () => select(entry.id),
|
|
1831
|
+
onKeyDown: handleTabKeyDown,
|
|
1832
|
+
children: entry.label
|
|
1833
|
+
},
|
|
1834
|
+
entry.id
|
|
1835
|
+
);
|
|
1836
|
+
})
|
|
1837
|
+
}
|
|
1838
|
+
),
|
|
1839
|
+
sections.map((entry) => /* @__PURE__ */ jsx5(
|
|
1840
|
+
"div",
|
|
1841
|
+
{
|
|
1842
|
+
id: panelId(entry.id),
|
|
1843
|
+
className: "db-settings-panel",
|
|
1844
|
+
role: dropdown ? "region" : "tabpanel",
|
|
1845
|
+
"aria-labelledby": dropdown ? void 0 : tabId(entry.id),
|
|
1846
|
+
"aria-label": dropdown ? entry.label : void 0,
|
|
1847
|
+
tabIndex: dropdown ? void 0 : 0,
|
|
1848
|
+
hidden: entry !== active,
|
|
1849
|
+
children: entry.content
|
|
1850
|
+
},
|
|
1851
|
+
entry.id
|
|
1852
|
+
))
|
|
1853
|
+
] });
|
|
1423
1854
|
}
|
|
1424
1855
|
function ThemeSettings({ value, onChange, name = "theme" }) {
|
|
1425
|
-
return /* @__PURE__ */
|
|
1426
|
-
/* @__PURE__ */
|
|
1427
|
-
/* @__PURE__ */
|
|
1428
|
-
/* @__PURE__ */
|
|
1429
|
-
/* @__PURE__ */
|
|
1856
|
+
return /* @__PURE__ */ jsxs5("fieldset", { className: "db-settings-fieldset", children: [
|
|
1857
|
+
/* @__PURE__ */ jsx5("legend", { className: "db-settings-legend", children: "Theme" }),
|
|
1858
|
+
/* @__PURE__ */ jsxs5("div", { className: "db-settings-radio-row", children: [
|
|
1859
|
+
/* @__PURE__ */ jsxs5("label", { className: "db-settings-radio db-settings-radio--inline", children: [
|
|
1860
|
+
/* @__PURE__ */ jsx5(
|
|
1430
1861
|
"input",
|
|
1431
1862
|
{
|
|
1432
1863
|
type: "radio",
|
|
@@ -1438,8 +1869,8 @@ function ThemeSettings({ value, onChange, name = "theme" }) {
|
|
|
1438
1869
|
),
|
|
1439
1870
|
"System default"
|
|
1440
1871
|
] }),
|
|
1441
|
-
/* @__PURE__ */
|
|
1442
|
-
/* @__PURE__ */
|
|
1872
|
+
/* @__PURE__ */ jsxs5("label", { className: "db-settings-radio db-settings-radio--inline", children: [
|
|
1873
|
+
/* @__PURE__ */ jsx5(
|
|
1443
1874
|
"input",
|
|
1444
1875
|
{
|
|
1445
1876
|
type: "radio",
|
|
@@ -1451,8 +1882,8 @@ function ThemeSettings({ value, onChange, name = "theme" }) {
|
|
|
1451
1882
|
),
|
|
1452
1883
|
"Light"
|
|
1453
1884
|
] }),
|
|
1454
|
-
/* @__PURE__ */
|
|
1455
|
-
/* @__PURE__ */
|
|
1885
|
+
/* @__PURE__ */ jsxs5("label", { className: "db-settings-radio db-settings-radio--inline", children: [
|
|
1886
|
+
/* @__PURE__ */ jsx5(
|
|
1456
1887
|
"input",
|
|
1457
1888
|
{
|
|
1458
1889
|
type: "radio",
|
|
@@ -1472,12 +1903,12 @@ function InterfaceFontSettings({
|
|
|
1472
1903
|
onChange,
|
|
1473
1904
|
name = "interface-font"
|
|
1474
1905
|
}) {
|
|
1475
|
-
return /* @__PURE__ */
|
|
1476
|
-
/* @__PURE__ */
|
|
1477
|
-
/* @__PURE__ */
|
|
1478
|
-
/* @__PURE__ */
|
|
1479
|
-
/* @__PURE__ */
|
|
1480
|
-
/* @__PURE__ */
|
|
1906
|
+
return /* @__PURE__ */ jsxs5("fieldset", { className: "db-settings-fieldset", children: [
|
|
1907
|
+
/* @__PURE__ */ jsx5("legend", { className: "db-settings-legend", children: "Interface font" }),
|
|
1908
|
+
/* @__PURE__ */ jsx5("p", { className: "db-settings-hint", children: "Applies to menus and panels, never to your documents." }),
|
|
1909
|
+
/* @__PURE__ */ jsxs5("div", { className: "db-settings-radio-row", children: [
|
|
1910
|
+
/* @__PURE__ */ jsxs5("label", { className: "db-settings-radio db-settings-radio--inline", children: [
|
|
1911
|
+
/* @__PURE__ */ jsx5(
|
|
1481
1912
|
"input",
|
|
1482
1913
|
{
|
|
1483
1914
|
type: "radio",
|
|
@@ -1489,8 +1920,8 @@ function InterfaceFontSettings({
|
|
|
1489
1920
|
),
|
|
1490
1921
|
"DocBlocks"
|
|
1491
1922
|
] }),
|
|
1492
|
-
/* @__PURE__ */
|
|
1493
|
-
/* @__PURE__ */
|
|
1923
|
+
/* @__PURE__ */ jsxs5("label", { className: "db-settings-radio db-settings-radio--inline", children: [
|
|
1924
|
+
/* @__PURE__ */ jsx5(
|
|
1494
1925
|
"input",
|
|
1495
1926
|
{
|
|
1496
1927
|
type: "radio",
|
|
@@ -1510,15 +1941,15 @@ function AccentColorSettings({
|
|
|
1510
1941
|
onChange,
|
|
1511
1942
|
name = "accent-color"
|
|
1512
1943
|
}) {
|
|
1513
|
-
return /* @__PURE__ */
|
|
1514
|
-
/* @__PURE__ */
|
|
1515
|
-
/* @__PURE__ */
|
|
1516
|
-
/* @__PURE__ */
|
|
1944
|
+
return /* @__PURE__ */ jsxs5("fieldset", { className: "db-settings-fieldset", children: [
|
|
1945
|
+
/* @__PURE__ */ jsx5("legend", { className: "db-settings-legend", children: "Accent color" }),
|
|
1946
|
+
/* @__PURE__ */ jsx5("p", { className: "db-settings-hint", children: "Used in both light and dark appearances." }),
|
|
1947
|
+
/* @__PURE__ */ jsx5("div", { className: "db-settings-accent-grid", children: ACCENT_COLORS.map((color) => /* @__PURE__ */ jsxs5(
|
|
1517
1948
|
"label",
|
|
1518
1949
|
{
|
|
1519
1950
|
className: `db-settings-accent${value === color ? " db-settings-accent--selected" : ""}`,
|
|
1520
1951
|
children: [
|
|
1521
|
-
/* @__PURE__ */
|
|
1952
|
+
/* @__PURE__ */ jsx5(
|
|
1522
1953
|
"input",
|
|
1523
1954
|
{
|
|
1524
1955
|
className: "db-settings-accent-input",
|
|
@@ -1529,14 +1960,14 @@ function AccentColorSettings({
|
|
|
1529
1960
|
onChange: () => onChange(color)
|
|
1530
1961
|
}
|
|
1531
1962
|
),
|
|
1532
|
-
/* @__PURE__ */
|
|
1963
|
+
/* @__PURE__ */ jsx5(
|
|
1533
1964
|
"span",
|
|
1534
1965
|
{
|
|
1535
1966
|
className: `db-settings-accent-swatch db-settings-accent-swatch--${color}`,
|
|
1536
1967
|
"aria-hidden": "true"
|
|
1537
1968
|
}
|
|
1538
1969
|
),
|
|
1539
|
-
/* @__PURE__ */
|
|
1970
|
+
/* @__PURE__ */ jsx5("span", { children: ACCENT_LABELS[color] })
|
|
1540
1971
|
]
|
|
1541
1972
|
},
|
|
1542
1973
|
color
|
|
@@ -1544,11 +1975,11 @@ function AccentColorSettings({
|
|
|
1544
1975
|
] });
|
|
1545
1976
|
}
|
|
1546
1977
|
function ProofingSettingsControls({ value, onChange }) {
|
|
1547
|
-
return /* @__PURE__ */
|
|
1548
|
-
/* @__PURE__ */
|
|
1549
|
-
/* @__PURE__ */
|
|
1550
|
-
/* @__PURE__ */
|
|
1551
|
-
/* @__PURE__ */
|
|
1978
|
+
return /* @__PURE__ */ jsxs5("fieldset", { className: "db-settings-fieldset", children: [
|
|
1979
|
+
/* @__PURE__ */ jsx5("legend", { className: "db-settings-legend", children: "Spelling and grammar" }),
|
|
1980
|
+
/* @__PURE__ */ jsx5("p", { className: "db-settings-hint", children: "Checking runs on this device \u2014 nothing you write is sent anywhere." }),
|
|
1981
|
+
/* @__PURE__ */ jsxs5("label", { className: "db-settings-checkbox", children: [
|
|
1982
|
+
/* @__PURE__ */ jsx5(
|
|
1552
1983
|
"input",
|
|
1553
1984
|
{
|
|
1554
1985
|
type: "checkbox",
|
|
@@ -1558,8 +1989,8 @@ function ProofingSettingsControls({ value, onChange }) {
|
|
|
1558
1989
|
),
|
|
1559
1990
|
"Show inline spell checking"
|
|
1560
1991
|
] }),
|
|
1561
|
-
/* @__PURE__ */
|
|
1562
|
-
/* @__PURE__ */
|
|
1992
|
+
/* @__PURE__ */ jsxs5("label", { className: "db-settings-checkbox", children: [
|
|
1993
|
+
/* @__PURE__ */ jsx5(
|
|
1563
1994
|
"input",
|
|
1564
1995
|
{
|
|
1565
1996
|
type: "checkbox",
|
|
@@ -1569,22 +2000,22 @@ function ProofingSettingsControls({ value, onChange }) {
|
|
|
1569
2000
|
),
|
|
1570
2001
|
"Show inline grammar checking"
|
|
1571
2002
|
] }),
|
|
1572
|
-
/* @__PURE__ */
|
|
2003
|
+
/* @__PURE__ */ jsx5("p", { className: "db-settings-hint", children: "(Grammar checking is currently only available for English)" })
|
|
1573
2004
|
] });
|
|
1574
2005
|
}
|
|
1575
2006
|
function WriteCanvasSettingsControls({ value, onChange }) {
|
|
1576
|
-
return /* @__PURE__ */
|
|
1577
|
-
/* @__PURE__ */
|
|
1578
|
-
/* @__PURE__ */
|
|
1579
|
-
/* @__PURE__ */
|
|
1580
|
-
/* @__PURE__ */
|
|
1581
|
-
/* @__PURE__ */
|
|
1582
|
-
/* @__PURE__ */
|
|
2007
|
+
return /* @__PURE__ */ jsxs5("fieldset", { className: "db-settings-fieldset", children: [
|
|
2008
|
+
/* @__PURE__ */ jsx5("legend", { className: "db-settings-legend", children: "Write canvas" }),
|
|
2009
|
+
/* @__PURE__ */ jsx5("p", { className: "db-settings-hint", children: "Adjust the writing view without changing the document or its exported text." }),
|
|
2010
|
+
/* @__PURE__ */ jsxs5("label", { className: "db-settings-slider", children: [
|
|
2011
|
+
/* @__PURE__ */ jsxs5("span", { className: "db-settings-slider-header", children: [
|
|
2012
|
+
/* @__PURE__ */ jsx5("span", { children: "Text size" }),
|
|
2013
|
+
/* @__PURE__ */ jsxs5("output", { className: "db-settings-slider-value", "aria-hidden": "true", children: [
|
|
1583
2014
|
value.textSize,
|
|
1584
2015
|
"px"
|
|
1585
2016
|
] })
|
|
1586
2017
|
] }),
|
|
1587
|
-
/* @__PURE__ */
|
|
2018
|
+
/* @__PURE__ */ jsx5(
|
|
1588
2019
|
"input",
|
|
1589
2020
|
{
|
|
1590
2021
|
type: "range",
|
|
@@ -1598,12 +2029,12 @@ function WriteCanvasSettingsControls({ value, onChange }) {
|
|
|
1598
2029
|
}
|
|
1599
2030
|
)
|
|
1600
2031
|
] }),
|
|
1601
|
-
/* @__PURE__ */
|
|
1602
|
-
/* @__PURE__ */
|
|
1603
|
-
/* @__PURE__ */
|
|
1604
|
-
/* @__PURE__ */
|
|
2032
|
+
/* @__PURE__ */ jsxs5("label", { className: "db-settings-slider", children: [
|
|
2033
|
+
/* @__PURE__ */ jsxs5("span", { className: "db-settings-slider-header", children: [
|
|
2034
|
+
/* @__PURE__ */ jsx5("span", { children: "Line spacing" }),
|
|
2035
|
+
/* @__PURE__ */ jsx5("output", { className: "db-settings-slider-value", "aria-hidden": "true", children: formatLineSpacing(value.lineSpacing) })
|
|
1605
2036
|
] }),
|
|
1606
|
-
/* @__PURE__ */
|
|
2037
|
+
/* @__PURE__ */ jsx5(
|
|
1607
2038
|
"input",
|
|
1608
2039
|
{
|
|
1609
2040
|
type: "range",
|
|
@@ -1617,7 +2048,7 @@ function WriteCanvasSettingsControls({ value, onChange }) {
|
|
|
1617
2048
|
}
|
|
1618
2049
|
)
|
|
1619
2050
|
] }),
|
|
1620
|
-
/* @__PURE__ */
|
|
2051
|
+
/* @__PURE__ */ jsx5(
|
|
1621
2052
|
FontSchemePicker,
|
|
1622
2053
|
{
|
|
1623
2054
|
value: value.fontScheme,
|
|
@@ -1632,21 +2063,21 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1632
2063
|
WRITE_CANVAS_FONT_SCHEMES.findIndex((scheme) => scheme.id === value)
|
|
1633
2064
|
);
|
|
1634
2065
|
const selectedScheme = WRITE_CANVAS_FONT_SCHEMES[selectedIndex];
|
|
1635
|
-
const [isOpen, setIsOpen] =
|
|
1636
|
-
const [activeIndex, setActiveIndex] =
|
|
1637
|
-
const [menuPosition, setMenuPosition] =
|
|
1638
|
-
const rootRef =
|
|
1639
|
-
const triggerRef =
|
|
1640
|
-
const listboxRef =
|
|
1641
|
-
const optionRefs =
|
|
2066
|
+
const [isOpen, setIsOpen] = useState6(false);
|
|
2067
|
+
const [activeIndex, setActiveIndex] = useState6(selectedIndex);
|
|
2068
|
+
const [menuPosition, setMenuPosition] = useState6(null);
|
|
2069
|
+
const rootRef = useRef4(null);
|
|
2070
|
+
const triggerRef = useRef4(null);
|
|
2071
|
+
const listboxRef = useRef4(null);
|
|
2072
|
+
const optionRefs = useRef4([]);
|
|
1642
2073
|
const labelId = useId4();
|
|
1643
2074
|
const listboxId = useId4();
|
|
1644
|
-
const close =
|
|
2075
|
+
const close = useCallback3((returnFocus) => {
|
|
1645
2076
|
setIsOpen(false);
|
|
1646
2077
|
setMenuPosition(null);
|
|
1647
2078
|
if (returnFocus) triggerRef.current?.focus({ preventScroll: true });
|
|
1648
2079
|
}, []);
|
|
1649
|
-
const updateMenuPosition =
|
|
2080
|
+
const updateMenuPosition = useCallback3(() => {
|
|
1650
2081
|
const trigger = triggerRef.current;
|
|
1651
2082
|
if (!trigger) return;
|
|
1652
2083
|
const rect = trigger.getBoundingClientRect();
|
|
@@ -1675,7 +2106,7 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1675
2106
|
}
|
|
1676
2107
|
);
|
|
1677
2108
|
}, []);
|
|
1678
|
-
const open =
|
|
2109
|
+
const open = useCallback3(
|
|
1679
2110
|
(index) => {
|
|
1680
2111
|
setActiveIndex(index);
|
|
1681
2112
|
updateMenuPosition();
|
|
@@ -1683,7 +2114,7 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1683
2114
|
},
|
|
1684
2115
|
[updateMenuPosition]
|
|
1685
2116
|
);
|
|
1686
|
-
|
|
2117
|
+
useEffect6(() => {
|
|
1687
2118
|
if (!isOpen) setActiveIndex(selectedIndex);
|
|
1688
2119
|
}, [isOpen, selectedIndex]);
|
|
1689
2120
|
useLayoutEffect(() => {
|
|
@@ -1692,7 +2123,7 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1692
2123
|
listboxRef.current?.focus({ preventScroll: true });
|
|
1693
2124
|
optionRefs.current[activeIndex]?.scrollIntoView?.({ block: "nearest" });
|
|
1694
2125
|
}, [activeIndex, isOpen, updateMenuPosition]);
|
|
1695
|
-
|
|
2126
|
+
useEffect6(() => {
|
|
1696
2127
|
if (!isOpen) return;
|
|
1697
2128
|
const handleOutsidePointer = (event) => {
|
|
1698
2129
|
if (!rootRef.current?.contains(event.target)) close(false);
|
|
@@ -1707,7 +2138,7 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1707
2138
|
window.removeEventListener("scroll", handleViewportChange, true);
|
|
1708
2139
|
};
|
|
1709
2140
|
}, [close, isOpen, updateMenuPosition]);
|
|
1710
|
-
const select =
|
|
2141
|
+
const select = useCallback3(
|
|
1711
2142
|
(index) => {
|
|
1712
2143
|
const scheme = WRITE_CANVAS_FONT_SCHEMES[index];
|
|
1713
2144
|
if (!scheme) return;
|
|
@@ -1764,9 +2195,9 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1764
2195
|
width: `${menuPosition.width}px`,
|
|
1765
2196
|
maxHeight: `${menuPosition.maxHeight}px`
|
|
1766
2197
|
} : void 0;
|
|
1767
|
-
return /* @__PURE__ */
|
|
1768
|
-
/* @__PURE__ */
|
|
1769
|
-
/* @__PURE__ */
|
|
2198
|
+
return /* @__PURE__ */ jsxs5("div", { ref: rootRef, className: "db-settings-select db-font-picker", children: [
|
|
2199
|
+
/* @__PURE__ */ jsx5("span", { className: "db-settings-select-header", children: /* @__PURE__ */ jsx5("span", { id: labelId, children: "Font" }) }),
|
|
2200
|
+
/* @__PURE__ */ jsxs5(
|
|
1770
2201
|
"button",
|
|
1771
2202
|
{
|
|
1772
2203
|
ref: triggerRef,
|
|
@@ -1779,8 +2210,8 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1779
2210
|
onClick: () => isOpen ? close(false) : open(selectedIndex),
|
|
1780
2211
|
onKeyDown: handleTriggerKeyDown,
|
|
1781
2212
|
children: [
|
|
1782
|
-
/* @__PURE__ */
|
|
1783
|
-
/* @__PURE__ */
|
|
2213
|
+
/* @__PURE__ */ jsx5(FontSchemePreview, { scheme: selectedScheme, compact: true }),
|
|
2214
|
+
/* @__PURE__ */ jsx5(
|
|
1784
2215
|
"span",
|
|
1785
2216
|
{
|
|
1786
2217
|
className: `db-font-picker-caret${isOpen ? " db-font-picker-caret--open" : ""}`,
|
|
@@ -1790,7 +2221,7 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1790
2221
|
]
|
|
1791
2222
|
}
|
|
1792
2223
|
),
|
|
1793
|
-
isOpen && /* @__PURE__ */
|
|
2224
|
+
isOpen && /* @__PURE__ */ jsxs5(
|
|
1794
2225
|
"div",
|
|
1795
2226
|
{
|
|
1796
2227
|
ref: listboxRef,
|
|
@@ -1806,8 +2237,8 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1806
2237
|
WRITE_CANVAS_FONT_SCHEMES.filter((scheme) => scheme.group === "theme").map(
|
|
1807
2238
|
(scheme) => renderFontSchemeOption(scheme)
|
|
1808
2239
|
),
|
|
1809
|
-
FONT_SCHEME_GROUPS.map(({ group, label }) => /* @__PURE__ */
|
|
1810
|
-
/* @__PURE__ */
|
|
2240
|
+
FONT_SCHEME_GROUPS.map(({ group, label }) => /* @__PURE__ */ jsxs5("div", { role: "group", "aria-label": label, children: [
|
|
2241
|
+
/* @__PURE__ */ jsx5("div", { className: "db-font-picker-group", "aria-hidden": "true", children: label }),
|
|
1811
2242
|
WRITE_CANVAS_FONT_SCHEMES.filter((scheme) => scheme.group === group).map(
|
|
1812
2243
|
(scheme) => renderFontSchemeOption(scheme)
|
|
1813
2244
|
)
|
|
@@ -1820,7 +2251,7 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1820
2251
|
const index = WRITE_CANVAS_FONT_SCHEMES.indexOf(scheme);
|
|
1821
2252
|
const selected = scheme.id === value;
|
|
1822
2253
|
const active = index === activeIndex;
|
|
1823
|
-
return /* @__PURE__ */
|
|
2254
|
+
return /* @__PURE__ */ jsxs5(
|
|
1824
2255
|
"div",
|
|
1825
2256
|
{
|
|
1826
2257
|
ref: (element) => {
|
|
@@ -1834,8 +2265,8 @@ function FontSchemePicker({ value, onChange }) {
|
|
|
1834
2265
|
onMouseMove: () => setActiveIndex(index),
|
|
1835
2266
|
onClick: () => select(index),
|
|
1836
2267
|
children: [
|
|
1837
|
-
/* @__PURE__ */
|
|
1838
|
-
/* @__PURE__ */
|
|
2268
|
+
/* @__PURE__ */ jsx5(FontSchemePreview, { scheme }),
|
|
2269
|
+
/* @__PURE__ */ jsx5("span", { className: "db-font-picker-check", "aria-hidden": "true", children: selected ? "\u2713" : "" })
|
|
1839
2270
|
]
|
|
1840
2271
|
},
|
|
1841
2272
|
scheme.id
|
|
@@ -1849,8 +2280,8 @@ function FontSchemePreview({
|
|
|
1849
2280
|
const labels = scheme.label.split(/\s*\u00b7\s*/u);
|
|
1850
2281
|
const headingLabel = labels[0] ?? scheme.label;
|
|
1851
2282
|
const bodyLabel = labels[1] ?? (scheme.id === "theme" ? "Use the active theme" : "Headings & body");
|
|
1852
|
-
return /* @__PURE__ */
|
|
1853
|
-
/* @__PURE__ */
|
|
2283
|
+
return /* @__PURE__ */ jsxs5("span", { className: `db-font-picker-preview${compact ? " db-font-picker-preview--compact" : ""}`, children: [
|
|
2284
|
+
/* @__PURE__ */ jsx5(
|
|
1854
2285
|
"span",
|
|
1855
2286
|
{
|
|
1856
2287
|
className: "db-font-picker-heading",
|
|
@@ -1858,7 +2289,7 @@ function FontSchemePreview({
|
|
|
1858
2289
|
children: headingLabel
|
|
1859
2290
|
}
|
|
1860
2291
|
),
|
|
1861
|
-
/* @__PURE__ */
|
|
2292
|
+
/* @__PURE__ */ jsx5(
|
|
1862
2293
|
"span",
|
|
1863
2294
|
{
|
|
1864
2295
|
className: "db-font-picker-body",
|
|
@@ -1916,6 +2347,15 @@ export {
|
|
|
1916
2347
|
DEFAULT_PROOFING_PREFERENCES,
|
|
1917
2348
|
loadProofingPreferences,
|
|
1918
2349
|
saveProofingPreferences,
|
|
2350
|
+
SIDEBAR_WIDTH_DEFAULT,
|
|
2351
|
+
SIDEBAR_WIDTH_MIN,
|
|
2352
|
+
SIDEBAR_WIDTH_MAX,
|
|
2353
|
+
SIDEBAR_COLLAPSE_THRESHOLD,
|
|
2354
|
+
classifyFormFactor,
|
|
2355
|
+
resolveLayoutMode,
|
|
2356
|
+
formFactorDataAttributes,
|
|
2357
|
+
isInstalledDisplayMode,
|
|
2358
|
+
useMediaQuery,
|
|
1919
2359
|
DB_CHROME_COLORS,
|
|
1920
2360
|
DEFAULT_INTERFACE_FONT,
|
|
1921
2361
|
loadThemePreference,
|
|
@@ -1930,6 +2370,7 @@ export {
|
|
|
1930
2370
|
AccentColorSettings,
|
|
1931
2371
|
ProofingSettingsControls,
|
|
1932
2372
|
WriteCanvasSettingsControls,
|
|
2373
|
+
formatModelSize,
|
|
1933
2374
|
AiSettingsControls,
|
|
1934
2375
|
WorkspaceSettingsControls
|
|
1935
2376
|
};
|