dsh-prompt-history 1.2.0 → 1.2.2
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 +27 -4
- package/lib/types/client/index.js +3 -3
- package/package.json +1 -1
- package/src/client/ChatToc.tsx +28 -2
- package/src/client/index.ts +3 -3
package/lib/client.js
CHANGED
|
@@ -351,6 +351,29 @@ window.__ModuleLoader__.load({
|
|
|
351
351
|
};
|
|
352
352
|
const gripLeft = pos?.left ?? origin.left + 6;
|
|
353
353
|
const gripTop = pos?.top ?? gripY() - 26;
|
|
354
|
+
const [panelStyle, setPanelStyle] = (0, react.useState)(null);
|
|
355
|
+
(0, react.useLayoutEffect)(() => {
|
|
356
|
+
if (!open || entries.length === 0) return;
|
|
357
|
+
const panel = panelRef.current;
|
|
358
|
+
if (panel === null) return;
|
|
359
|
+
const gap = 8;
|
|
360
|
+
const gripRight = gripLeft + 20;
|
|
361
|
+
const gripCenterY = gripTop + 26;
|
|
362
|
+
const natural = Math.min(panel.getBoundingClientRect().height, 480);
|
|
363
|
+
const maxHeight = Math.min(natural, window.innerHeight - 8);
|
|
364
|
+
const left = Math.max(4, Math.min(gripRight + gap, window.innerWidth - 230 - 4));
|
|
365
|
+
const next = {
|
|
366
|
+
top: Math.max(4, Math.min(gripCenterY - maxHeight / 2, window.innerHeight - maxHeight - 4)),
|
|
367
|
+
left,
|
|
368
|
+
maxHeight
|
|
369
|
+
};
|
|
370
|
+
setPanelStyle((prev) => prev !== null && prev.top === next.top && prev.left === next.left && prev.maxHeight === next.maxHeight ? prev : next);
|
|
371
|
+
}, [
|
|
372
|
+
open,
|
|
373
|
+
entries.length,
|
|
374
|
+
gripLeft,
|
|
375
|
+
gripTop
|
|
376
|
+
]);
|
|
354
377
|
return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
355
378
|
type: "button",
|
|
356
379
|
className: "dsh-ph-toc-grip",
|
|
@@ -374,7 +397,7 @@ window.__ModuleLoader__.load({
|
|
|
374
397
|
}), open && entries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
375
398
|
ref: panelRef,
|
|
376
399
|
className: "dsh-ph-toc",
|
|
377
|
-
style: {
|
|
400
|
+
style: panelStyle ?? {
|
|
378
401
|
top: Math.max(4, gripTop - 8),
|
|
379
402
|
left: Math.min(gripLeft + 30, window.innerWidth - 230)
|
|
380
403
|
},
|
|
@@ -1115,10 +1138,10 @@ window.__ModuleLoader__.load({
|
|
|
1115
1138
|
".dsh-ph-group{margin:8px 0 4px;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);}",
|
|
1116
1139
|
".dsh-ph-toc-grip{position:fixed;z-index:2147483000;width:20px;height:52px;border:1px solid var(--dsw-alias-border-l1);border-radius:9px;background:var(--dsw-specific-menu);background:color-mix(in srgb,var(--dsw-specific-menu) 88%,#000);box-shadow:0 1px 4px rgba(0,0,0,.18);color:var(--dsw-alias-label-primary);font-size:14px;line-height:1;cursor:pointer;opacity:.65;transition:opacity .15s;display:flex;align-items:center;justify-content:center;padding:0;}",
|
|
1117
1140
|
".dsh-ph-toc-grip:hover{opacity:1;background:var(--dsw-alias-bg-layer-2);}",
|
|
1118
|
-
".dsh-ph-toc{position:fixed;z-index:2147483000;width:220px;max-height:min(60vh,480px);display:flex;flex-direction:column;padding:8px;border-radius:12px;background:var(--dsw-specific-menu);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 28px rgba(0,0,0,.25);}",
|
|
1141
|
+
".dsh-ph-toc{position:fixed;z-index:2147483000;width:220px;max-height:min(60vh,480px);display:flex;flex-direction:column;padding:8px;border-radius:12px;background:var(--dsw-specific-menu);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 28px rgba(0,0,0,.25);box-sizing:border-box;}",
|
|
1119
1142
|
".dsh-ph-toc-title{margin:0 4px 6px;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);}",
|
|
1120
|
-
".dsh-ph-toc-list{overflow-y:auto;display:flex;flex-direction:column;gap:2px;}",
|
|
1121
|
-
".dsh-ph-toc-item{display:block;width:100%;text-align:left;padding:5px 8px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);font-size:12px;line-height:1.4;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}",
|
|
1143
|
+
".dsh-ph-toc-list{overflow-y:auto;display:flex;flex-direction:column;gap:2px;box-sizing:border-box;}",
|
|
1144
|
+
".dsh-ph-toc-item{display:block;width:100%;text-align:left;padding:5px 8px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);font-size:12px;line-height:1.4;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-sizing:border-box;}",
|
|
1122
1145
|
".dsh-ph-toc-item:hover{background:var(--dsw-alias-bg-layer-2);}"
|
|
1123
1146
|
].join("");
|
|
1124
1147
|
/**
|
|
@@ -15,10 +15,10 @@ const SETTINGS_CSS = [
|
|
|
15
15
|
'.dsh-ph-group{margin:8px 0 4px;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);}',
|
|
16
16
|
'.dsh-ph-toc-grip{position:fixed;z-index:2147483000;width:20px;height:52px;border:1px solid var(--dsw-alias-border-l1);border-radius:9px;background:var(--dsw-specific-menu);background:color-mix(in srgb,var(--dsw-specific-menu) 88%,#000);box-shadow:0 1px 4px rgba(0,0,0,.18);color:var(--dsw-alias-label-primary);font-size:14px;line-height:1;cursor:pointer;opacity:.65;transition:opacity .15s;display:flex;align-items:center;justify-content:center;padding:0;}',
|
|
17
17
|
'.dsh-ph-toc-grip:hover{opacity:1;background:var(--dsw-alias-bg-layer-2);}',
|
|
18
|
-
'.dsh-ph-toc{position:fixed;z-index:2147483000;width:220px;max-height:min(60vh,480px);display:flex;flex-direction:column;padding:8px;border-radius:12px;background:var(--dsw-specific-menu);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 28px rgba(0,0,0,.25);}',
|
|
18
|
+
'.dsh-ph-toc{position:fixed;z-index:2147483000;width:220px;max-height:min(60vh,480px);display:flex;flex-direction:column;padding:8px;border-radius:12px;background:var(--dsw-specific-menu);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 28px rgba(0,0,0,.25);box-sizing:border-box;}',
|
|
19
19
|
'.dsh-ph-toc-title{margin:0 4px 6px;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);}',
|
|
20
|
-
'.dsh-ph-toc-list{overflow-y:auto;display:flex;flex-direction:column;gap:2px;}',
|
|
21
|
-
'.dsh-ph-toc-item{display:block;width:100%;text-align:left;padding:5px 8px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);font-size:12px;line-height:1.4;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}',
|
|
20
|
+
'.dsh-ph-toc-list{overflow-y:auto;display:flex;flex-direction:column;gap:2px;box-sizing:border-box;}',
|
|
21
|
+
'.dsh-ph-toc-item{display:block;width:100%;text-align:left;padding:5px 8px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);font-size:12px;line-height:1.4;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-sizing:border-box;}',
|
|
22
22
|
'.dsh-ph-toc-item:hover{background:var(--dsw-alias-bg-layer-2);}',
|
|
23
23
|
].join('');
|
|
24
24
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-prompt-history",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "DSH web plugin: terminal-style input for the composer — bash-like Up/Down prompt history with prefix search and Ctrl+R, selection toolbar with copy and quote (Codex-style > blockquote), right-click paste, toggleable draggable chat TOC, fully internationalized (zh/en), with copy modes in Settings (history sourced from the session's own message log; zero config required).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
package/src/client/ChatToc.tsx
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* message. Rendered via a portal to document.body so the fixed positioning is
|
|
6
6
|
* viewport-relative, and lives off the conversation snapshot's user nodes.
|
|
7
7
|
*/
|
|
8
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
8
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
|
|
9
9
|
import type { MouseEvent as ReactMouseEvent } from 'react'
|
|
10
10
|
import { createPortal } from 'react-dom'
|
|
11
11
|
import type { ConversationNode } from '@deepseek-ai/dsh-client-runtime/client'
|
|
@@ -146,6 +146,32 @@ export function ChatToc({ nodes }: ChatTocProps): JSX.Element {
|
|
|
146
146
|
|
|
147
147
|
const gripLeft = pos?.left ?? origin.left + 6
|
|
148
148
|
const gripTop = pos?.top ?? gripY() - 26
|
|
149
|
+
|
|
150
|
+
// The panel is anchored to the grip like a context menu: it sits to the
|
|
151
|
+
// grip's right, vertically centered on it, and is clamped so the box always
|
|
152
|
+
// fits the viewport — dragging the grip to the bottom edge shifts the panel
|
|
153
|
+
// up just enough (never clipping the directory).
|
|
154
|
+
const [panelStyle, setPanelStyle] = useState<{ top: number; left: number; maxHeight: number } | null>(null)
|
|
155
|
+
useLayoutEffect(() => {
|
|
156
|
+
if (!open || entries.length === 0) return
|
|
157
|
+
const panel = panelRef.current
|
|
158
|
+
if (panel === null) return
|
|
159
|
+
const gap = 8
|
|
160
|
+
const gripRight = gripLeft + 20 // grip width from .dsh-ph-toc-grip
|
|
161
|
+
const gripCenterY = gripTop + 26 // grip height 52 → vertical center
|
|
162
|
+
const natural = Math.min(panel.getBoundingClientRect().height, 480)
|
|
163
|
+
const maxHeight = Math.min(natural, window.innerHeight - 8)
|
|
164
|
+
const left = Math.max(4, Math.min(gripRight + gap, window.innerWidth - 230 - 4))
|
|
165
|
+
// Prefer centering on the grip; clamp so both edges stay inside the viewport.
|
|
166
|
+
const top = Math.max(4, Math.min(gripCenterY - maxHeight / 2, window.innerHeight - maxHeight - 4))
|
|
167
|
+
const next = { top, left, maxHeight }
|
|
168
|
+
setPanelStyle((prev) => (
|
|
169
|
+
prev !== null && prev.top === next.top && prev.left === next.left && prev.maxHeight === next.maxHeight
|
|
170
|
+
? prev
|
|
171
|
+
: next
|
|
172
|
+
))
|
|
173
|
+
}, [open, entries.length, gripLeft, gripTop])
|
|
174
|
+
|
|
149
175
|
return createPortal(
|
|
150
176
|
<>
|
|
151
177
|
<button
|
|
@@ -167,7 +193,7 @@ export function ChatToc({ nodes }: ChatTocProps): JSX.Element {
|
|
|
167
193
|
<div
|
|
168
194
|
ref={panelRef}
|
|
169
195
|
className="dsh-ph-toc"
|
|
170
|
-
style={{ top: Math.max(4, gripTop - 8), left: Math.min(gripLeft + 30, window.innerWidth - 230) }}
|
|
196
|
+
style={panelStyle ?? { top: Math.max(4, gripTop - 8), left: Math.min(gripLeft + 30, window.innerWidth - 230) }}
|
|
171
197
|
>
|
|
172
198
|
<div className="dsh-ph-toc-title">{T('toc.title')}</div>
|
|
173
199
|
<div className="dsh-ph-toc-list">
|
package/src/client/index.ts
CHANGED
|
@@ -31,10 +31,10 @@ const SETTINGS_CSS = [
|
|
|
31
31
|
'.dsh-ph-group{margin:8px 0 4px;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);}',
|
|
32
32
|
'.dsh-ph-toc-grip{position:fixed;z-index:2147483000;width:20px;height:52px;border:1px solid var(--dsw-alias-border-l1);border-radius:9px;background:var(--dsw-specific-menu);background:color-mix(in srgb,var(--dsw-specific-menu) 88%,#000);box-shadow:0 1px 4px rgba(0,0,0,.18);color:var(--dsw-alias-label-primary);font-size:14px;line-height:1;cursor:pointer;opacity:.65;transition:opacity .15s;display:flex;align-items:center;justify-content:center;padding:0;}',
|
|
33
33
|
'.dsh-ph-toc-grip:hover{opacity:1;background:var(--dsw-alias-bg-layer-2);}',
|
|
34
|
-
'.dsh-ph-toc{position:fixed;z-index:2147483000;width:220px;max-height:min(60vh,480px);display:flex;flex-direction:column;padding:8px;border-radius:12px;background:var(--dsw-specific-menu);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 28px rgba(0,0,0,.25);}',
|
|
34
|
+
'.dsh-ph-toc{position:fixed;z-index:2147483000;width:220px;max-height:min(60vh,480px);display:flex;flex-direction:column;padding:8px;border-radius:12px;background:var(--dsw-specific-menu);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 28px rgba(0,0,0,.25);box-sizing:border-box;}',
|
|
35
35
|
'.dsh-ph-toc-title{margin:0 4px 6px;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);}',
|
|
36
|
-
'.dsh-ph-toc-list{overflow-y:auto;display:flex;flex-direction:column;gap:2px;}',
|
|
37
|
-
'.dsh-ph-toc-item{display:block;width:100%;text-align:left;padding:5px 8px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);font-size:12px;line-height:1.4;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}',
|
|
36
|
+
'.dsh-ph-toc-list{overflow-y:auto;display:flex;flex-direction:column;gap:2px;box-sizing:border-box;}',
|
|
37
|
+
'.dsh-ph-toc-item{display:block;width:100%;text-align:left;padding:5px 8px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);font-size:12px;line-height:1.4;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-sizing:border-box;}',
|
|
38
38
|
'.dsh-ph-toc-item:hover{background:var(--dsw-alias-bg-layer-2);}',
|
|
39
39
|
].join('')
|
|
40
40
|
|