dsh-sidenote 0.8.4 → 0.8.5
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/lib/client.js +134 -90
- package/lib/index.js +1 -0
- package/lib/types/client/annotate/overlay.d.ts +1 -0
- package/lib/types/client/locales.d.ts +2 -0
- package/lib/types/client/preferences.d.ts +6 -3
- package/lib/types/settings.d.ts +2 -0
- package/package.json +1 -1
- package/src/client/annotate/overlay.tsx +55 -38
- package/src/client/locales.ts +4 -0
- package/src/client/preferences.ts +19 -14
- package/src/client/settings.tsx +9 -0
- package/src/settings.ts +1 -0
package/lib/client.js
CHANGED
|
@@ -766,7 +766,7 @@ window.__ModuleLoader__.load({
|
|
|
766
766
|
let dockRegistered = false;
|
|
767
767
|
let report = {
|
|
768
768
|
versions: {
|
|
769
|
-
sidenote: "0.8.
|
|
769
|
+
sidenote: "0.8.5",
|
|
770
770
|
dsh: "unknown",
|
|
771
771
|
betterSidebar: null
|
|
772
772
|
},
|
|
@@ -966,6 +966,8 @@ window.__ModuleLoader__.load({
|
|
|
966
966
|
settingsDescription: "Choose the actions available when you select conversation text.",
|
|
967
967
|
hideNativeQuote: "Hide native quote",
|
|
968
968
|
hideNativeQuoteHint: "Hide the Quote action in main and side chats.",
|
|
969
|
+
showSideChatNote: "Add a note before asking in side chat",
|
|
970
|
+
showSideChatNoteHint: "Turn off to add selected text directly to side chat and write your question there.",
|
|
969
971
|
settingsSaving: "Saving…",
|
|
970
972
|
settingsLoading: "Loading preferences…",
|
|
971
973
|
settingsUnavailable: "Preferences are unavailable. Reload the page to reconnect.",
|
|
@@ -1141,6 +1143,8 @@ window.__ModuleLoader__.load({
|
|
|
1141
1143
|
settingsDescription: "调整划选对话文字时显示的操作。",
|
|
1142
1144
|
hideNativeQuote: "隐藏原生引用",
|
|
1143
1145
|
hideNativeQuoteHint: "在主对话和侧边聊天中隐藏“引用”按钮。",
|
|
1146
|
+
showSideChatNote: "侧边提问前填写注解",
|
|
1147
|
+
showSideChatNoteHint: "关闭后,划选内容直接添加到侧边聊天,可在侧聊输入框中继续提问。",
|
|
1144
1148
|
settingsSaving: "正在保存…",
|
|
1145
1149
|
settingsLoading: "正在加载偏好设置…",
|
|
1146
1150
|
settingsUnavailable: "暂时无法读取设置,请刷新页面重新连接。",
|
|
@@ -1420,13 +1424,13 @@ window.__ModuleLoader__.load({
|
|
|
1420
1424
|
document.head.appendChild(tag);
|
|
1421
1425
|
}
|
|
1422
1426
|
var diagnostics_module_css_default = {
|
|
1423
|
-
"
|
|
1427
|
+
"trigger": "tGe0LW_trigger",
|
|
1428
|
+
"list": "tGe0LW_list",
|
|
1424
1429
|
"header": "tGe0LW_header",
|
|
1425
1430
|
"panel": "tGe0LW_panel",
|
|
1426
|
-
"trigger": "tGe0LW_trigger",
|
|
1427
1431
|
"actions": "tGe0LW_actions",
|
|
1428
|
-
"
|
|
1429
|
-
"
|
|
1432
|
+
"description": "tGe0LW_description",
|
|
1433
|
+
"versions": "tGe0LW_versions"
|
|
1430
1434
|
};
|
|
1431
1435
|
//#endregion
|
|
1432
1436
|
//#region src/client/diagnostics/index.tsx
|
|
@@ -2349,32 +2353,32 @@ window.__ModuleLoader__.load({
|
|
|
2349
2353
|
}
|
|
2350
2354
|
var annotations_module_css_default = {
|
|
2351
2355
|
"contextNumber": "SVnebq_contextNumber",
|
|
2352
|
-
"
|
|
2353
|
-
"
|
|
2354
|
-
"sentChips": "SVnebq_sentChips",
|
|
2355
|
-
"contextText": "SVnebq_contextText",
|
|
2356
|
-
"chipWrap": "SVnebq_chipWrap",
|
|
2357
|
-
"contextFooter": "SVnebq_contextFooter",
|
|
2358
|
-
"userContextHost": "SVnebq_userContextHost",
|
|
2359
|
-
"chip": "SVnebq_chip",
|
|
2356
|
+
"contextLabel": "SVnebq_contextLabel",
|
|
2357
|
+
"contextEditor": "SVnebq_contextEditor",
|
|
2360
2358
|
"sentChipGroup": "SVnebq_sentChipGroup",
|
|
2361
|
-
"sentChevron": "SVnebq_sentChevron",
|
|
2362
|
-
"sentPreview": "SVnebq_sentPreview",
|
|
2363
|
-
"contextList": "SVnebq_contextList",
|
|
2364
|
-
"chipDismissShade": "SVnebq_chipDismissShade",
|
|
2365
|
-
"chipDismiss": "SVnebq_chipDismiss",
|
|
2366
2359
|
"sentChip": "SVnebq_sentChip",
|
|
2360
|
+
"chipMain": "SVnebq_chipMain",
|
|
2361
|
+
"contextText": "SVnebq_contextText",
|
|
2362
|
+
"chipClearAll": "SVnebq_chipClearAll",
|
|
2367
2363
|
"storageNotice": "SVnebq_storageNotice",
|
|
2368
|
-
"
|
|
2364
|
+
"contextContent": "SVnebq_contextContent",
|
|
2365
|
+
"sentChevron": "SVnebq_sentChevron",
|
|
2366
|
+
"sentChevronOpen": "SVnebq_sentChevronOpen",
|
|
2367
|
+
"userContextHost": "SVnebq_userContextHost",
|
|
2368
|
+
"sentPreview": "SVnebq_sentPreview",
|
|
2369
|
+
"contextActions": "SVnebq_contextActions",
|
|
2370
|
+
"contextFooter": "SVnebq_contextFooter",
|
|
2369
2371
|
"contextAppear": "SVnebq_contextAppear",
|
|
2372
|
+
"contextList": "SVnebq_contextList",
|
|
2370
2373
|
"contextPanel": "SVnebq_contextPanel",
|
|
2371
|
-
"
|
|
2374
|
+
"chip": "SVnebq_chip",
|
|
2372
2375
|
"contextAction": "SVnebq_contextAction",
|
|
2373
|
-
"
|
|
2374
|
-
"
|
|
2376
|
+
"sentChips": "SVnebq_sentChips",
|
|
2377
|
+
"chipWrap": "SVnebq_chipWrap",
|
|
2378
|
+
"chipDismiss": "SVnebq_chipDismiss",
|
|
2375
2379
|
"contextSource": "SVnebq_contextSource",
|
|
2376
|
-
"
|
|
2377
|
-
"
|
|
2380
|
+
"contextItem": "SVnebq_contextItem",
|
|
2381
|
+
"chipDismissShade": "SVnebq_chipDismissShade"
|
|
2378
2382
|
};
|
|
2379
2383
|
//#endregion
|
|
2380
2384
|
//#region src/client/annotations/NativeUserContext.tsx
|
|
@@ -2848,38 +2852,38 @@ window.__ModuleLoader__.load({
|
|
|
2848
2852
|
document.head.appendChild(tag);
|
|
2849
2853
|
}
|
|
2850
2854
|
var sidechat_module_css_default = {
|
|
2851
|
-
"
|
|
2852
|
-
"progressDetail": "_5KEEsG_progressDetail",
|
|
2853
|
-
"progressPreview": "_5KEEsG_progressPreview",
|
|
2854
|
-
"headerSide": "_5KEEsG_headerSide",
|
|
2855
|
-
"emptyTitle": "_5KEEsG_emptyTitle",
|
|
2856
|
-
"progressContent": "_5KEEsG_progressContent",
|
|
2857
|
-
"nativeToolbar": "_5KEEsG_nativeToolbar",
|
|
2858
|
-
"contextUserRow": "_5KEEsG_contextUserRow",
|
|
2855
|
+
"root": "_5KEEsG_root",
|
|
2859
2856
|
"progress": "_5KEEsG_progress",
|
|
2860
|
-
"chatView": "_5KEEsG_chatView",
|
|
2861
|
-
"contextChevron": "_5KEEsG_contextChevron",
|
|
2862
|
-
"nativeConversation": "_5KEEsG_nativeConversation",
|
|
2863
|
-
"contextBubble": "_5KEEsG_contextBubble",
|
|
2864
|
-
"nativeHost": "_5KEEsG_nativeHost",
|
|
2865
2857
|
"progressProcess": "_5KEEsG_progressProcess",
|
|
2866
|
-
"emptyIcon": "_5KEEsG_emptyIcon",
|
|
2867
|
-
"root": "_5KEEsG_root",
|
|
2868
|
-
"emptyText": "_5KEEsG_emptyText",
|
|
2869
|
-
"contextImage": "_5KEEsG_contextImage",
|
|
2870
2858
|
"nativeToolbarActions": "_5KEEsG_nativeToolbarActions",
|
|
2871
|
-
"
|
|
2872
|
-
"mainContext": "_5KEEsG_mainContext",
|
|
2873
|
-
"contextChevronOpen": "_5KEEsG_contextChevronOpen",
|
|
2874
|
-
"progressEntry": "_5KEEsG_progressEntry",
|
|
2859
|
+
"nativeToolbar": "_5KEEsG_nativeToolbar",
|
|
2875
2860
|
"stateDetail": "_5KEEsG_stateDetail",
|
|
2876
|
-
"
|
|
2861
|
+
"headerSide": "_5KEEsG_headerSide",
|
|
2862
|
+
"nativeConversation": "_5KEEsG_nativeConversation",
|
|
2863
|
+
"emptyText": "_5KEEsG_emptyText",
|
|
2864
|
+
"contextChevron": "_5KEEsG_contextChevron",
|
|
2865
|
+
"contextHint": "_5KEEsG_contextHint",
|
|
2866
|
+
"progressEntry": "_5KEEsG_progressEntry",
|
|
2867
|
+
"progressPreview": "_5KEEsG_progressPreview",
|
|
2877
2868
|
"nativeAction": "_5KEEsG_nativeAction",
|
|
2869
|
+
"reflowAction": "_5KEEsG_reflowAction",
|
|
2870
|
+
"chatView": "_5KEEsG_chatView",
|
|
2871
|
+
"contextColumn": "_5KEEsG_contextColumn",
|
|
2872
|
+
"contextChevronOpen": "_5KEEsG_contextChevronOpen",
|
|
2873
|
+
"mainContext": "_5KEEsG_mainContext",
|
|
2874
|
+
"emptyTitle": "_5KEEsG_emptyTitle",
|
|
2878
2875
|
"errorRow": "_5KEEsG_errorRow",
|
|
2879
|
-
"
|
|
2876
|
+
"progressDetail": "_5KEEsG_progressDetail",
|
|
2880
2877
|
"historyToggle": "_5KEEsG_historyToggle",
|
|
2878
|
+
"nativeHost": "_5KEEsG_nativeHost",
|
|
2879
|
+
"progressEntries": "_5KEEsG_progressEntries",
|
|
2880
|
+
"progressLatest": "_5KEEsG_progressLatest",
|
|
2881
|
+
"progressContent": "_5KEEsG_progressContent",
|
|
2881
2882
|
"stateScreen": "_5KEEsG_stateScreen",
|
|
2882
|
-
"
|
|
2883
|
+
"contextImage": "_5KEEsG_contextImage",
|
|
2884
|
+
"contextBubble": "_5KEEsG_contextBubble",
|
|
2885
|
+
"emptyIcon": "_5KEEsG_emptyIcon",
|
|
2886
|
+
"contextUserRow": "_5KEEsG_contextUserRow"
|
|
2883
2887
|
};
|
|
2884
2888
|
//#endregion
|
|
2885
2889
|
//#region src/client/sidechat/ContextProgress.tsx
|
|
@@ -6684,35 +6688,35 @@ ${body}
|
|
|
6684
6688
|
document.head.appendChild(tag);
|
|
6685
6689
|
}
|
|
6686
6690
|
var annotate_module_css_default = {
|
|
6687
|
-
"
|
|
6688
|
-
"
|
|
6689
|
-
"
|
|
6690
|
-
"deleteButton": "_SVViG_deleteButton",
|
|
6691
|
-
"highlight": "_SVViG_highlight",
|
|
6691
|
+
"badge": "_SVViG_badge",
|
|
6692
|
+
"editorEdit": "_SVViG_editorEdit",
|
|
6693
|
+
"sentCardQuote": "_SVViG_sentCardQuote",
|
|
6692
6694
|
"confirmButton": "_SVViG_confirmButton",
|
|
6693
|
-
"
|
|
6694
|
-
"editorAskRow": "_SVViG_editorAskRow",
|
|
6695
|
-
"sentCardNote": "_SVViG_sentCardNote",
|
|
6695
|
+
"saveButton": "_SVViG_saveButton",
|
|
6696
6696
|
"cancelButton": "_SVViG_cancelButton",
|
|
6697
|
+
"sentCardNote": "_SVViG_sentCardNote",
|
|
6697
6698
|
"toolbarBelow": "_SVViG_toolbarBelow",
|
|
6698
|
-
"
|
|
6699
|
+
"sentCardTitle": "_SVViG_sentCardTitle",
|
|
6700
|
+
"editorError": "_SVViG_editorError",
|
|
6701
|
+
"sentChip": "_SVViG_sentChip",
|
|
6702
|
+
"highlight": "_SVViG_highlight",
|
|
6703
|
+
"editorTarget": "_SVViG_editorTarget",
|
|
6704
|
+
"toolbarStatus": "_SVViG_toolbarStatus",
|
|
6705
|
+
"dshSidenoteHintIn": "_SVViG_dshSidenoteHintIn",
|
|
6706
|
+
"toolbarButton": "_SVViG_toolbarButton",
|
|
6707
|
+
"editorAskRow": "_SVViG_editorAskRow",
|
|
6699
6708
|
"editorInput": "_SVViG_editorInput",
|
|
6709
|
+
"deleteButton": "_SVViG_deleteButton",
|
|
6710
|
+
"hintClose": "_SVViG_hintClose",
|
|
6700
6711
|
"toolbar": "_SVViG_toolbar",
|
|
6701
6712
|
"editorAsk": "_SVViG_editorAsk",
|
|
6702
|
-
"editorError": "_SVViG_editorError",
|
|
6703
|
-
"sentCardTitle": "_SVViG_sentCardTitle",
|
|
6704
|
-
"editorTextarea": "_SVViG_editorTextarea",
|
|
6705
|
-
"dshSidenoteHintIn": "_SVViG_dshSidenoteHintIn",
|
|
6706
|
-
"editorTarget": "_SVViG_editorTarget",
|
|
6707
|
-
"sentChip": "_SVViG_sentChip",
|
|
6708
|
-
"sentCardQuote": "_SVViG_sentCardQuote",
|
|
6709
|
-
"editorEdit": "_SVViG_editorEdit",
|
|
6710
6713
|
"editorSpacer": "_SVViG_editorSpacer",
|
|
6714
|
+
"badgeSent": "_SVViG_badgeSent",
|
|
6715
|
+
"editorFooter": "_SVViG_editorFooter",
|
|
6711
6716
|
"hint": "_SVViG_hint",
|
|
6712
|
-
"toolbarStatus": "_SVViG_toolbarStatus",
|
|
6713
6717
|
"editorNew": "_SVViG_editorNew",
|
|
6714
|
-
"
|
|
6715
|
-
"
|
|
6718
|
+
"sentChipRow": "_SVViG_sentChipRow",
|
|
6719
|
+
"editorTextarea": "_SVViG_editorTextarea"
|
|
6716
6720
|
};
|
|
6717
6721
|
//#endregion
|
|
6718
6722
|
//#region src/client/annotate/hint.tsx
|
|
@@ -7025,6 +7029,7 @@ ${body}
|
|
|
7025
7029
|
y: anchor.y,
|
|
7026
7030
|
abort: new AbortController(),
|
|
7027
7031
|
target,
|
|
7032
|
+
skipNote: !preference.showSideChatNote,
|
|
7028
7033
|
...targetTitle !== void 0 ? { targetTitle } : {}
|
|
7029
7034
|
});
|
|
7030
7035
|
controller.clear();
|
|
@@ -7053,6 +7058,10 @@ ${body}
|
|
|
7053
7058
|
view: snapshot.source.view
|
|
7054
7059
|
});
|
|
7055
7060
|
setSideDraft((current) => current === sideDraft ? null : current);
|
|
7061
|
+
if (sideDraft.skipNote) {
|
|
7062
|
+
const view = [...document.querySelectorAll("[data-sidenote-chat-session]")].find((element) => element.dataset.sidenoteChatSession === target.childId);
|
|
7063
|
+
if (view) focusSideComposer(view);
|
|
7064
|
+
}
|
|
7056
7065
|
return true;
|
|
7057
7066
|
} catch {
|
|
7058
7067
|
return false;
|
|
@@ -7136,6 +7145,7 @@ ${body}
|
|
|
7136
7145
|
x: sideDraft.x,
|
|
7137
7146
|
y: sideDraft.y,
|
|
7138
7147
|
targetTitle: sideDraft.targetTitle,
|
|
7148
|
+
skipNote: sideDraft.skipNote,
|
|
7139
7149
|
bounds: sourceClip(sideDraft.snapshot.source),
|
|
7140
7150
|
onSave: commitSideDraft,
|
|
7141
7151
|
onCancel: () => {
|
|
@@ -7232,6 +7242,7 @@ ${body}
|
|
|
7232
7242
|
function SideChatNoteEditor(props) {
|
|
7233
7243
|
useLocaleTick();
|
|
7234
7244
|
const [note, setNote] = (0, react.useState)("");
|
|
7245
|
+
const [showNote, setShowNote] = (0, react.useState)(!props.skipNote);
|
|
7235
7246
|
const noteInputRef = useAutoGrowingNote(note);
|
|
7236
7247
|
const [failed, setFailed] = (0, react.useState)(false);
|
|
7237
7248
|
const [pending, setPending] = (0, react.useState)(false);
|
|
@@ -7262,6 +7273,7 @@ ${body}
|
|
|
7262
7273
|
if (cancelled.current) return;
|
|
7263
7274
|
saved.current = ok;
|
|
7264
7275
|
failedRef.current = !ok;
|
|
7276
|
+
if (!ok) setShowNote(true);
|
|
7265
7277
|
setFailed(!ok);
|
|
7266
7278
|
setPending(false);
|
|
7267
7279
|
};
|
|
@@ -7280,6 +7292,9 @@ ${body}
|
|
|
7280
7292
|
};
|
|
7281
7293
|
const saveRef = (0, react.useRef)(save);
|
|
7282
7294
|
saveRef.current = save;
|
|
7295
|
+
(0, react.useEffect)(() => {
|
|
7296
|
+
if (props.skipNote) saveRef.current();
|
|
7297
|
+
}, [props.skipNote]);
|
|
7283
7298
|
(0, react.useEffect)(() => {
|
|
7284
7299
|
const onKeyDown = (event) => {
|
|
7285
7300
|
if (event.key === "Escape") {
|
|
@@ -7320,7 +7335,7 @@ ${body}
|
|
|
7320
7335
|
className: annotate_module_css_default.editorTarget,
|
|
7321
7336
|
children: t("sendToTarget", { title: props.targetTitle })
|
|
7322
7337
|
}),
|
|
7323
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7338
|
+
showNote && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7324
7339
|
className: annotate_module_css_default.editorAskRow,
|
|
7325
7340
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
7326
7341
|
ref: noteInputRef,
|
|
@@ -8339,7 +8354,7 @@ ${body}
|
|
|
8339
8354
|
}
|
|
8340
8355
|
//#endregion
|
|
8341
8356
|
//#region src/client/preferences.ts
|
|
8342
|
-
/** Share
|
|
8357
|
+
/** Share host-backed preferences between every main and side conversation. */
|
|
8343
8358
|
function createSidenotePreferences(form) {
|
|
8344
8359
|
const listeners = /* @__PURE__ */ new Set();
|
|
8345
8360
|
let saving = false;
|
|
@@ -8348,6 +8363,7 @@ ${body}
|
|
|
8348
8363
|
const state = form.getSnapshot();
|
|
8349
8364
|
return {
|
|
8350
8365
|
hidden: state.value?.hideNativeQuote ?? true,
|
|
8366
|
+
showSideChatNote: state.value?.showSideChatNote ?? true,
|
|
8351
8367
|
status: state.status,
|
|
8352
8368
|
writable: state.writable,
|
|
8353
8369
|
saving,
|
|
@@ -8360,6 +8376,20 @@ ${body}
|
|
|
8360
8376
|
for (const listener of listeners) listener();
|
|
8361
8377
|
};
|
|
8362
8378
|
const unsubscribe = form.subscribe(publish);
|
|
8379
|
+
const set = async (field, value) => {
|
|
8380
|
+
if (saving || snapshot.status !== "ready" || !snapshot.writable) return;
|
|
8381
|
+
saving = true;
|
|
8382
|
+
failed = false;
|
|
8383
|
+
publish();
|
|
8384
|
+
try {
|
|
8385
|
+
failed = !await form.set(field, value);
|
|
8386
|
+
} catch {
|
|
8387
|
+
failed = true;
|
|
8388
|
+
} finally {
|
|
8389
|
+
saving = false;
|
|
8390
|
+
publish();
|
|
8391
|
+
}
|
|
8392
|
+
};
|
|
8363
8393
|
return {
|
|
8364
8394
|
getSnapshot: () => snapshot,
|
|
8365
8395
|
subscribe(listener) {
|
|
@@ -8368,20 +8398,8 @@ ${body}
|
|
|
8368
8398
|
listeners.delete(listener);
|
|
8369
8399
|
};
|
|
8370
8400
|
},
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
saving = true;
|
|
8374
|
-
failed = false;
|
|
8375
|
-
publish();
|
|
8376
|
-
try {
|
|
8377
|
-
failed = !await form.set("hideNativeQuote", hidden);
|
|
8378
|
-
} catch {
|
|
8379
|
-
failed = true;
|
|
8380
|
-
} finally {
|
|
8381
|
-
saving = false;
|
|
8382
|
-
publish();
|
|
8383
|
-
}
|
|
8384
|
-
},
|
|
8401
|
+
setHidden: (hidden) => set("hideNativeQuote", hidden),
|
|
8402
|
+
setShowSideChatNote: (show) => set("showSideChatNote", show),
|
|
8385
8403
|
dispose() {
|
|
8386
8404
|
unsubscribe();
|
|
8387
8405
|
listeners.clear();
|
|
@@ -8400,15 +8418,15 @@ ${body}
|
|
|
8400
8418
|
document.head.appendChild(tag);
|
|
8401
8419
|
}
|
|
8402
8420
|
var settings_module_css_default = {
|
|
8403
|
-
"description": "_2xJwMG_description",
|
|
8404
|
-
"error": "_2xJwMG_error",
|
|
8405
8421
|
"hint": "_2xJwMG_hint",
|
|
8406
|
-
"
|
|
8407
|
-
"title": "_2xJwMG_title",
|
|
8408
|
-
"copy": "_2xJwMG_copy",
|
|
8422
|
+
"description": "_2xJwMG_description",
|
|
8409
8423
|
"status": "_2xJwMG_status",
|
|
8410
8424
|
"row": "_2xJwMG_row",
|
|
8411
|
-
"page": "_2xJwMG_page"
|
|
8425
|
+
"page": "_2xJwMG_page",
|
|
8426
|
+
"copy": "_2xJwMG_copy",
|
|
8427
|
+
"title": "_2xJwMG_title",
|
|
8428
|
+
"label": "_2xJwMG_label",
|
|
8429
|
+
"error": "_2xJwMG_error"
|
|
8412
8430
|
};
|
|
8413
8431
|
//#endregion
|
|
8414
8432
|
//#region src/client/settings.tsx
|
|
@@ -8455,6 +8473,32 @@ ${body}
|
|
|
8455
8473
|
}
|
|
8456
8474
|
})]
|
|
8457
8475
|
}),
|
|
8476
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8477
|
+
className: settings_module_css_default.row,
|
|
8478
|
+
role: "group",
|
|
8479
|
+
"aria-labelledby": `${id}-side-note-label`,
|
|
8480
|
+
"aria-describedby": `${id}-side-note-description`,
|
|
8481
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8482
|
+
className: settings_module_css_default.copy,
|
|
8483
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8484
|
+
id: `${id}-side-note-label`,
|
|
8485
|
+
className: settings_module_css_default.label,
|
|
8486
|
+
children: t("showSideChatNote")
|
|
8487
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
8488
|
+
id: `${id}-side-note-description`,
|
|
8489
|
+
className: settings_module_css_default.hint,
|
|
8490
|
+
children: t("showSideChatNoteHint")
|
|
8491
|
+
})]
|
|
8492
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
8493
|
+
checked: state.showSideChatNote,
|
|
8494
|
+
label: t("showSideChatNote"),
|
|
8495
|
+
title: t("showSideChatNoteHint"),
|
|
8496
|
+
disabled: state.status !== "ready" || !state.writable || state.saving,
|
|
8497
|
+
onChange: (show) => {
|
|
8498
|
+
preferences.setShowSideChatNote(show);
|
|
8499
|
+
}
|
|
8500
|
+
})]
|
|
8501
|
+
}),
|
|
8458
8502
|
state.saving && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
8459
8503
|
className: settings_module_css_default.status,
|
|
8460
8504
|
role: "status",
|
package/lib/index.js
CHANGED
|
@@ -1094,6 +1094,7 @@ defineMethod("transform", [
|
|
|
1094
1094
|
/** Live presentation preference stored in the host's profile document. */
|
|
1095
1095
|
const Config = Schema.object({
|
|
1096
1096
|
hideNativeQuote: Schema.boolean().default(true).volatile(),
|
|
1097
|
+
showSideChatNote: Schema.boolean().default(true).volatile(),
|
|
1097
1098
|
finalRepliesDefaultAttempted: Schema.boolean().default(false).volatile()
|
|
1098
1099
|
});
|
|
1099
1100
|
//#endregion
|
|
@@ -69,6 +69,8 @@ export declare const en: {
|
|
|
69
69
|
settingsDescription: string;
|
|
70
70
|
hideNativeQuote: string;
|
|
71
71
|
hideNativeQuoteHint: string;
|
|
72
|
+
showSideChatNote: string;
|
|
73
|
+
showSideChatNoteHint: string;
|
|
72
74
|
settingsSaving: string;
|
|
73
75
|
settingsLoading: string;
|
|
74
76
|
settingsUnavailable: string;
|
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import type { ObservableSnapshot } from './host/contracts.ts';
|
|
2
|
-
/** The host ConfigForm subset used by
|
|
2
|
+
/** The host ConfigForm subset used by Sidenote preferences. */
|
|
3
3
|
export interface SidenoteConfigForm extends ObservableSnapshot<{
|
|
4
4
|
status: 'loading' | 'ready' | 'unavailable';
|
|
5
5
|
value: {
|
|
6
6
|
hideNativeQuote: boolean;
|
|
7
|
+
showSideChatNote?: boolean;
|
|
7
8
|
} | undefined;
|
|
8
9
|
writable: boolean;
|
|
9
10
|
}> {
|
|
10
|
-
set(field: 'hideNativeQuote', value: boolean): Promise<boolean>;
|
|
11
|
+
set(field: 'hideNativeQuote' | 'showSideChatNote', value: boolean): Promise<boolean>;
|
|
11
12
|
}
|
|
12
13
|
export interface SidenotePreferences extends ObservableSnapshot<{
|
|
13
14
|
hidden: boolean;
|
|
15
|
+
showSideChatNote: boolean;
|
|
14
16
|
status: 'loading' | 'ready' | 'unavailable';
|
|
15
17
|
writable: boolean;
|
|
16
18
|
saving: boolean;
|
|
17
19
|
failed: boolean;
|
|
18
20
|
}> {
|
|
19
21
|
setHidden(hidden: boolean): Promise<void>;
|
|
22
|
+
setShowSideChatNote(show: boolean): Promise<void>;
|
|
20
23
|
dispose(): void;
|
|
21
24
|
}
|
|
22
|
-
/** Share
|
|
25
|
+
/** Share host-backed preferences between every main and side conversation. */
|
|
23
26
|
export declare function createSidenotePreferences(form: SidenoteConfigForm): SidenotePreferences;
|
package/lib/types/settings.d.ts
CHANGED
|
@@ -2,8 +2,10 @@ import z from '@deepseek-ai/schemastery';
|
|
|
2
2
|
/** Live presentation preference stored in the host's profile document. */
|
|
3
3
|
export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
4
4
|
hideNativeQuote: z<boolean, boolean, "volatile-defined">;
|
|
5
|
+
showSideChatNote: z<boolean, boolean, "volatile-defined">;
|
|
5
6
|
finalRepliesDefaultAttempted: z<boolean, boolean, "volatile-defined">;
|
|
6
7
|
}>>, Schemastery.ObjectT<NoInfer<{
|
|
7
8
|
hideNativeQuote: z<boolean, boolean, "volatile-defined">;
|
|
9
|
+
showSideChatNote: z<boolean, boolean, "volatile-defined">;
|
|
8
10
|
finalRepliesDefaultAttempted: z<boolean, boolean, "volatile-defined">;
|
|
9
11
|
}>>, "plain">;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-sidenote",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"description": "Follow the tangent. Keep the thread. Annotate, explore on the side, and bring answers back to DeepSeek Harness. / 思路可以分岔,主线始终向前。划选注释、侧边追问,再把结论带回正在推进的任务。",
|
|
5
5
|
"icon": "docs/assets/logo.svg",
|
|
6
6
|
"type": "module",
|
|
@@ -17,6 +17,7 @@ import type { ReactNode } from 'react'
|
|
|
17
17
|
import { IconCheckOutline16, IconTrashOutline16 } from '../host/icons.ts'
|
|
18
18
|
import type { Context } from '../host/contracts.ts'
|
|
19
19
|
import { currentSessionIdOf } from '../host/currentSession.ts'
|
|
20
|
+
import { focusSideComposer } from '../host/dom.ts'
|
|
20
21
|
import { hostDiagnostics } from '../host/probes.ts'
|
|
21
22
|
import { insertNativeQuote, probeInput, resolveInput } from '../host/input.ts'
|
|
22
23
|
import { sideChatBridge, type SideChatBridge } from '../bridge.ts'
|
|
@@ -56,8 +57,8 @@ function useAutoGrowingNote(note: string) {
|
|
|
56
57
|
return input
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
/** 「Ask in side chat
|
|
60
|
-
*
|
|
60
|
+
/** 「Ask in side chat」的投递草稿:按偏好填写或跳过注解,
|
|
61
|
+
* 经 bridge 等待真实子会话后创建共享注释对象;正文保持干净。 */
|
|
61
62
|
interface SideDraftState {
|
|
62
63
|
readonly snapshot: SelectionSnapshot
|
|
63
64
|
readonly x: number
|
|
@@ -66,6 +67,7 @@ interface SideDraftState {
|
|
|
66
67
|
readonly targetTitle?: string
|
|
67
68
|
readonly abort: AbortController
|
|
68
69
|
readonly target: ReturnType<SideChatBridge['captureTarget']> | undefined
|
|
70
|
+
readonly skipNote: boolean
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
interface OverlayProps {
|
|
@@ -188,11 +190,12 @@ function AnnotateOverlayInner({ ctx, store, controller, preferences }: OverlayPr
|
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
const askInSideChat = (snapshot: SelectionSnapshot): void => {
|
|
191
|
-
//
|
|
193
|
+
// 按偏好收集注解,等选定的实际目标就绪后递交共享对象。
|
|
192
194
|
const anchor = selectionBadgePoint(snapshot)
|
|
193
195
|
const target = sideChatBridge.current?.captureTarget(snapshot.sessionId)
|
|
194
196
|
const targetTitle = target?.title
|
|
195
|
-
setSideDraft({ snapshot, x: anchor.x, y: anchor.y, abort: new AbortController(), target,
|
|
197
|
+
setSideDraft({ snapshot, x: anchor.x, y: anchor.y, abort: new AbortController(), target, skipNote: !preference.showSideChatNote,
|
|
198
|
+
...(targetTitle !== undefined ? { targetTitle } : {}) })
|
|
196
199
|
controller.clear()
|
|
197
200
|
window.getSelection()?.removeAllRanges()
|
|
198
201
|
}
|
|
@@ -211,6 +214,11 @@ function AnnotateOverlayInner({ ctx, store, controller, preferences }: OverlayPr
|
|
|
211
214
|
})
|
|
212
215
|
rangeCache.current.set(annotation.id, { ranges: snapshot.ranges.map(range => range.cloneRange()), view: snapshot.source.view })
|
|
213
216
|
setSideDraft(current => current === sideDraft ? null : current)
|
|
217
|
+
if (sideDraft.skipNote) {
|
|
218
|
+
const view = [...document.querySelectorAll<HTMLElement>('[data-sidenote-chat-session]')]
|
|
219
|
+
.find(element => element.dataset.sidenoteChatSession === target.childId)
|
|
220
|
+
if (view) focusSideComposer(view)
|
|
221
|
+
}
|
|
214
222
|
return true
|
|
215
223
|
} catch { return false }
|
|
216
224
|
}
|
|
@@ -298,6 +306,7 @@ function AnnotateOverlayInner({ ctx, store, controller, preferences }: OverlayPr
|
|
|
298
306
|
x={sideDraft.x}
|
|
299
307
|
y={sideDraft.y}
|
|
300
308
|
targetTitle={sideDraft.targetTitle}
|
|
309
|
+
skipNote={sideDraft.skipNote}
|
|
301
310
|
bounds={sourceClip(sideDraft.snapshot.source)}
|
|
302
311
|
onSave={commitSideDraft}
|
|
303
312
|
onCancel={() => { sideDraft.abort.abort(); setSideDraft(null) }}
|
|
@@ -392,11 +401,13 @@ export function SideChatNoteEditor(props: {
|
|
|
392
401
|
y: number
|
|
393
402
|
targetTitle?: string
|
|
394
403
|
bounds?: Bounds
|
|
404
|
+
skipNote?: boolean
|
|
395
405
|
onSave: (note: string) => boolean | Promise<boolean>
|
|
396
406
|
onCancel: () => void
|
|
397
407
|
}): ReactNode {
|
|
398
408
|
useLocaleTick()
|
|
399
409
|
const [note, setNote] = useState('')
|
|
410
|
+
const [showNote, setShowNote] = useState(!props.skipNote)
|
|
400
411
|
const noteInputRef = useAutoGrowingNote(note)
|
|
401
412
|
const [failed, setFailed] = useState(false)
|
|
402
413
|
const [pending, setPending] = useState(false)
|
|
@@ -415,6 +426,7 @@ export function SideChatNoteEditor(props: {
|
|
|
415
426
|
if (cancelled.current) return
|
|
416
427
|
saved.current = ok
|
|
417
428
|
failedRef.current = !ok
|
|
429
|
+
if (!ok) setShowNote(true)
|
|
418
430
|
setFailed(!ok)
|
|
419
431
|
setPending(false)
|
|
420
432
|
}
|
|
@@ -426,6 +438,9 @@ export function SideChatNoteEditor(props: {
|
|
|
426
438
|
}
|
|
427
439
|
const saveRef = useRef(save)
|
|
428
440
|
saveRef.current = save
|
|
441
|
+
useEffect(() => {
|
|
442
|
+
if (props.skipNote) saveRef.current()
|
|
443
|
+
}, [props.skipNote])
|
|
429
444
|
|
|
430
445
|
useEffect(() => {
|
|
431
446
|
const onKeyDown = (event: KeyboardEvent): void => {
|
|
@@ -460,40 +475,42 @@ export function SideChatNoteEditor(props: {
|
|
|
460
475
|
{props.targetTitle !== undefined && props.targetTitle !== '' && (
|
|
461
476
|
<div className={css.editorTarget}>{t('sendToTarget', { title: props.targetTitle })}</div>
|
|
462
477
|
)}
|
|
463
|
-
|
|
464
|
-
<
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
478
|
+
{showNote && (
|
|
479
|
+
<div className={css.editorAskRow}>
|
|
480
|
+
<textarea
|
|
481
|
+
ref={noteInputRef}
|
|
482
|
+
rows={1}
|
|
483
|
+
className={css.editorInput}
|
|
484
|
+
value={note}
|
|
485
|
+
placeholder={t('sideNotePlaceholder')}
|
|
486
|
+
aria-label={t('sideNoteAria')}
|
|
487
|
+
autoFocus
|
|
488
|
+
disabled={pending}
|
|
489
|
+
onChange={(event) => {
|
|
490
|
+
setNote(event.target.value)
|
|
491
|
+
failedRef.current = false
|
|
492
|
+
setFailed(false)
|
|
493
|
+
}}
|
|
494
|
+
onKeyDown={(event) => {
|
|
495
|
+
if (event.key !== 'Enter' || event.shiftKey) return
|
|
496
|
+
// IME 保护:组合中(候选窗未提交)的 Enter 属于输入法,不能算确认。
|
|
497
|
+
if (event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229) return
|
|
498
|
+
event.preventDefault()
|
|
499
|
+
save()
|
|
500
|
+
}}
|
|
501
|
+
/>
|
|
502
|
+
<button
|
|
503
|
+
type="button"
|
|
504
|
+
className={css.confirmButton}
|
|
505
|
+
title={t('confirmTitle')}
|
|
506
|
+
aria-label={t('confirmAskAria')}
|
|
507
|
+
onClick={() => { save() }}
|
|
508
|
+
disabled={pending}
|
|
509
|
+
>
|
|
510
|
+
<IconCheckOutline16 size={14} />
|
|
511
|
+
</button>
|
|
512
|
+
</div>
|
|
513
|
+
)}
|
|
497
514
|
{failed && <div className={css.editorError}>{t('openSideFailed')}</div>}
|
|
498
515
|
{pending && <div className={css.editorTarget} role="status">{t('sideTargetWaiting')}</div>}
|
|
499
516
|
</div>
|
package/src/client/locales.ts
CHANGED
|
@@ -62,6 +62,8 @@ export const en = {
|
|
|
62
62
|
settingsDescription: 'Choose the actions available when you select conversation text.',
|
|
63
63
|
hideNativeQuote: 'Hide native quote',
|
|
64
64
|
hideNativeQuoteHint: 'Hide the Quote action in main and side chats.',
|
|
65
|
+
showSideChatNote: 'Add a note before asking in side chat',
|
|
66
|
+
showSideChatNoteHint: 'Turn off to add selected text directly to side chat and write your question there.',
|
|
65
67
|
settingsSaving: 'Saving…',
|
|
66
68
|
settingsLoading: 'Loading preferences…',
|
|
67
69
|
settingsUnavailable: 'Preferences are unavailable. Reload the page to reconnect.',
|
|
@@ -271,6 +273,8 @@ export const zh: Record<CopyKey, string> = {
|
|
|
271
273
|
settingsDescription: '调整划选对话文字时显示的操作。',
|
|
272
274
|
hideNativeQuote: '隐藏原生引用',
|
|
273
275
|
hideNativeQuoteHint: '在主对话和侧边聊天中隐藏“引用”按钮。',
|
|
276
|
+
showSideChatNote: '侧边提问前填写注解',
|
|
277
|
+
showSideChatNoteHint: '关闭后,划选内容直接添加到侧边聊天,可在侧聊输入框中继续提问。',
|
|
274
278
|
settingsSaving: '正在保存…',
|
|
275
279
|
settingsLoading: '正在加载偏好设置…',
|
|
276
280
|
settingsUnavailable: '暂时无法读取设置,请刷新页面重新连接。',
|
|
@@ -1,33 +1,36 @@
|
|
|
1
1
|
import type { ObservableSnapshot } from './host/contracts.ts'
|
|
2
2
|
|
|
3
|
-
/** The host ConfigForm subset used by
|
|
3
|
+
/** The host ConfigForm subset used by Sidenote preferences. */
|
|
4
4
|
export interface SidenoteConfigForm extends ObservableSnapshot<{
|
|
5
5
|
status: 'loading' | 'ready' | 'unavailable'
|
|
6
|
-
value: { hideNativeQuote: boolean } | undefined
|
|
6
|
+
value: { hideNativeQuote: boolean; showSideChatNote?: boolean } | undefined
|
|
7
7
|
writable: boolean
|
|
8
8
|
}> {
|
|
9
|
-
set(field: 'hideNativeQuote', value: boolean): Promise<boolean>
|
|
9
|
+
set(field: 'hideNativeQuote' | 'showSideChatNote', value: boolean): Promise<boolean>
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface SidenotePreferences extends ObservableSnapshot<{
|
|
13
13
|
hidden: boolean
|
|
14
|
+
showSideChatNote: boolean
|
|
14
15
|
status: 'loading' | 'ready' | 'unavailable'
|
|
15
16
|
writable: boolean
|
|
16
17
|
saving: boolean
|
|
17
18
|
failed: boolean
|
|
18
19
|
}> {
|
|
19
20
|
setHidden(hidden: boolean): Promise<void>
|
|
21
|
+
setShowSideChatNote(show: boolean): Promise<void>
|
|
20
22
|
dispose(): void
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
/** Share
|
|
25
|
+
/** Share host-backed preferences between every main and side conversation. */
|
|
24
26
|
export function createSidenotePreferences(form: SidenoteConfigForm): SidenotePreferences {
|
|
25
27
|
const listeners = new Set<() => void>()
|
|
26
28
|
let saving = false
|
|
27
29
|
let failed = false
|
|
28
30
|
const read = () => {
|
|
29
31
|
const state = form.getSnapshot()
|
|
30
|
-
return { hidden: state.value?.hideNativeQuote ?? true,
|
|
32
|
+
return { hidden: state.value?.hideNativeQuote ?? true, showSideChatNote: state.value?.showSideChatNote ?? true,
|
|
33
|
+
status: state.status, writable: state.writable, saving, failed }
|
|
31
34
|
}
|
|
32
35
|
let snapshot = read()
|
|
33
36
|
const publish = (): void => {
|
|
@@ -35,18 +38,20 @@ export function createSidenotePreferences(form: SidenoteConfigForm): SidenotePre
|
|
|
35
38
|
for (const listener of listeners) listener()
|
|
36
39
|
}
|
|
37
40
|
const unsubscribe = form.subscribe(publish)
|
|
41
|
+
const set = async (field: 'hideNativeQuote' | 'showSideChatNote', value: boolean): Promise<void> => {
|
|
42
|
+
if (saving || snapshot.status !== 'ready' || !snapshot.writable) return
|
|
43
|
+
saving = true
|
|
44
|
+
failed = false
|
|
45
|
+
publish()
|
|
46
|
+
try { failed = !await form.set(field, value) }
|
|
47
|
+
catch { failed = true }
|
|
48
|
+
finally { saving = false; publish() }
|
|
49
|
+
}
|
|
38
50
|
return {
|
|
39
51
|
getSnapshot: () => snapshot,
|
|
40
52
|
subscribe(listener) { listeners.add(listener); return () => { listeners.delete(listener) } },
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
saving = true
|
|
44
|
-
failed = false
|
|
45
|
-
publish()
|
|
46
|
-
try { failed = !await form.set('hideNativeQuote', hidden) }
|
|
47
|
-
catch { failed = true }
|
|
48
|
-
finally { saving = false; publish() }
|
|
49
|
-
},
|
|
53
|
+
setHidden: hidden => set('hideNativeQuote', hidden),
|
|
54
|
+
setShowSideChatNote: show => set('showSideChatNote', show),
|
|
50
55
|
dispose() { unsubscribe(); listeners.clear() },
|
|
51
56
|
}
|
|
52
57
|
}
|
package/src/client/settings.tsx
CHANGED
|
@@ -24,6 +24,15 @@ function SidenoteSettings({ preferences }: { preferences: SidenotePreferences })
|
|
|
24
24
|
disabled={state.status !== 'ready' || !state.writable || state.saving}
|
|
25
25
|
onChange={hidden => { void preferences.setHidden(hidden) }} />
|
|
26
26
|
</div>
|
|
27
|
+
<div className={css.row} role="group" aria-labelledby={`${id}-side-note-label`} aria-describedby={`${id}-side-note-description`}>
|
|
28
|
+
<div className={css.copy}>
|
|
29
|
+
<span id={`${id}-side-note-label`} className={css.label}>{t('showSideChatNote')}</span>
|
|
30
|
+
<p id={`${id}-side-note-description`} className={css.hint}>{t('showSideChatNoteHint')}</p>
|
|
31
|
+
</div>
|
|
32
|
+
<Switch checked={state.showSideChatNote} label={t('showSideChatNote')} title={t('showSideChatNoteHint')}
|
|
33
|
+
disabled={state.status !== 'ready' || !state.writable || state.saving}
|
|
34
|
+
onChange={show => { void preferences.setShowSideChatNote(show) }} />
|
|
35
|
+
</div>
|
|
27
36
|
{state.saving && <p className={css.status} role="status">{t('settingsSaving')}</p>}
|
|
28
37
|
{state.status === 'loading' && <p className={css.status} role="status">{t('settingsLoading')}</p>}
|
|
29
38
|
{state.status === 'unavailable' && <p className={css.error} role="alert">{t('settingsUnavailable')}</p>}
|
package/src/settings.ts
CHANGED
|
@@ -3,5 +3,6 @@ import z from '@deepseek-ai/schemastery'
|
|
|
3
3
|
/** Live presentation preference stored in the host's profile document. */
|
|
4
4
|
export const Config = z.object({
|
|
5
5
|
hideNativeQuote: z.boolean().default(true).volatile(),
|
|
6
|
+
showSideChatNote: z.boolean().default(true).volatile(),
|
|
6
7
|
finalRepliesDefaultAttempted: z.boolean().default(false).volatile(),
|
|
7
8
|
})
|