@rooode/dsh-plugin-preview 0.1.0 → 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 +75 -4
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -8,9 +8,8 @@
8
8
  * without popping up Windows Notepad.
9
9
  */
10
10
 
11
- window.__ModuleLoader__.load({
12
- id: "@deepseek-ai/dsh-client-ui-preview",
13
- factory: (require) => {
11
+ (function() {
12
+ function previewFactory(require) {
14
13
  var module = { exports: {} };
15
14
  var exports = module.exports;
16
15
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
@@ -41,6 +40,7 @@ window.__ModuleLoader__.load({
41
40
  let globalActiveTabId = null;
42
41
  let globalIsPanelOpen = false;
43
42
  let globalPanelWidth = DEFAULT_PANEL_WIDTH;
43
+ let globalLastOpenTime = 0;
44
44
  const stateListeners = new Set();
45
45
 
46
46
  try {
@@ -86,6 +86,9 @@ window.__ModuleLoader__.load({
86
86
 
87
87
  function setPanelOpen(open) {
88
88
  globalIsPanelOpen = open;
89
+ if (open) {
90
+ globalLastOpenTime = Date.now();
91
+ }
89
92
  notifyStateChange();
90
93
  }
91
94
 
@@ -180,6 +183,7 @@ window.__ModuleLoader__.load({
180
183
  globalTabs = [newTab, ...globalTabs];
181
184
  globalActiveTabId = tabId;
182
185
  }
186
+ globalLastOpenTime = Date.now();
183
187
  globalIsPanelOpen = true;
184
188
  saveTabsToStorage();
185
189
  notifyStateChange();
@@ -1001,6 +1005,57 @@ window.__ModuleLoader__.load({
1001
1005
  }
1002
1006
  }, [isDragging]);
1003
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
+
1004
1059
  // Hotkey: Esc closes preview
1005
1060
  useEffect(() => {
1006
1061
  const onKeyDown = (e) => {
@@ -1033,6 +1088,7 @@ window.__ModuleLoader__.load({
1033
1088
 
1034
1089
  // Right-Side Slide Drawer
1035
1090
  isOpen ? h('div', {
1091
+ ref: drawerRef,
1036
1092
  className: `dsh-preview-drawer-container ${isDragging ? 'dragging' : ''}`,
1037
1093
  style: { width: `${width}px` },
1038
1094
  },
@@ -2197,4 +2253,19 @@ window.__ModuleLoader__.load({
2197
2253
 
2198
2254
  return module.exports;
2199
2255
  }
2200
- });
2256
+
2257
+ if (typeof window !== 'undefined' && window.__ModuleLoader__) {
2258
+ const ids = [
2259
+ '@rooode/dsh-plugin-preview',
2260
+ '@deepseek-ai/dsh-client-ui-preview'
2261
+ ];
2262
+ for (const id of ids) {
2263
+ try {
2264
+ window.__ModuleLoader__.load({
2265
+ id: id,
2266
+ factory: previewFactory
2267
+ });
2268
+ } catch (e) {}
2269
+ }
2270
+ }
2271
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rooode/dsh-plugin-preview",
3
- "version": "0.1.0",
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",