@rooode/dsh-plugin-preview 0.1.1 → 0.1.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.
Files changed (2) hide show
  1. package/lib/client.js +57 -0
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -40,6 +40,7 @@
40
40
  let globalActiveTabId = null;
41
41
  let globalIsPanelOpen = false;
42
42
  let globalPanelWidth = DEFAULT_PANEL_WIDTH;
43
+ let globalLastOpenTime = 0;
43
44
  const stateListeners = new Set();
44
45
 
45
46
  try {
@@ -85,6 +86,9 @@
85
86
 
86
87
  function setPanelOpen(open) {
87
88
  globalIsPanelOpen = open;
89
+ if (open) {
90
+ globalLastOpenTime = Date.now();
91
+ }
88
92
  notifyStateChange();
89
93
  }
90
94
 
@@ -179,6 +183,7 @@
179
183
  globalTabs = [newTab, ...globalTabs];
180
184
  globalActiveTabId = tabId;
181
185
  }
186
+ globalLastOpenTime = Date.now();
182
187
  globalIsPanelOpen = true;
183
188
  saveTabsToStorage();
184
189
  notifyStateChange();
@@ -1000,6 +1005,57 @@
1000
1005
  }
1001
1006
  }, [isDragging]);
1002
1007
 
1008
+ const drawerRef = useRef(null);
1009
+
1010
+ // Outside Click Listener: Click on the chat conversation / dialog box outside the drawer to auto close/hide it
1011
+ useEffect(() => {
1012
+ if (!isOpen) return;
1013
+
1014
+ const handleOutsidePointerDown = (e) => {
1015
+ // 1. Ignore if just opened within 250ms
1016
+ if (Date.now() - globalLastOpenTime < 250) return;
1017
+ // 2. Ignore during dragging resize handle
1018
+ if (isDragging) return;
1019
+
1020
+ const target = e.target;
1021
+ if (!target) return;
1022
+
1023
+ // 3. If clicking inside the preview drawer, do not close
1024
+ const drawerEl = drawerRef.current || document.querySelector('.dsh-preview-drawer-container');
1025
+ if (drawerEl && (drawerEl === target || drawerEl.contains(target))) {
1026
+ return;
1027
+ }
1028
+
1029
+ // 4. If clicking on the floating pill, do not close
1030
+ const floatPill = document.querySelector('.dsh-preview-float-pill');
1031
+ if (floatPill && (floatPill === target || floatPill.contains(target))) {
1032
+ return;
1033
+ }
1034
+
1035
+ // 5. If clicking on a file link or button that opens a file preview, do not close (let interceptor open it)
1036
+ if (target.closest) {
1037
+ const btn = target.closest('button');
1038
+ if (btn) {
1039
+ const candidate = btn.getAttribute('title') || btn.getAttribute('aria-label') || btn.textContent || '';
1040
+ if (isPreviewableFile(candidate.trim())) return;
1041
+ }
1042
+ const anchor = target.closest('a');
1043
+ if (anchor) {
1044
+ const href = anchor.getAttribute('href') || '';
1045
+ if (isPreviewableFile(href)) return;
1046
+ }
1047
+ }
1048
+
1049
+ // 6. Outside click in dialog/conversation/background: Auto hide the preview drawer!
1050
+ setPanelOpen(false);
1051
+ };
1052
+
1053
+ window.addEventListener('pointerdown', handleOutsidePointerDown, true);
1054
+ return () => {
1055
+ window.removeEventListener('pointerdown', handleOutsidePointerDown, true);
1056
+ };
1057
+ }, [isOpen, isDragging]);
1058
+
1003
1059
  // Hotkey: Esc closes preview
1004
1060
  useEffect(() => {
1005
1061
  const onKeyDown = (e) => {
@@ -1032,6 +1088,7 @@
1032
1088
 
1033
1089
  // Right-Side Slide Drawer
1034
1090
  isOpen ? h('div', {
1091
+ ref: drawerRef,
1035
1092
  className: `dsh-preview-drawer-container ${isDragging ? 'dragging' : ''}`,
1036
1093
  style: { width: `${width}px` },
1037
1094
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rooode/dsh-plugin-preview",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "DeepSeek Harness Markdown 文档右侧预览插件 (参考 WorkBuddy FileTabs 实现,支持多标签、GFM 渲染、TOC 大纲、源码分栏)",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",