dsh-better-workspace 0.7.0 → 0.7.1

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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-better-workspace",
3
- "version": "0.6.0",
3
+ "version": "0.7.1",
4
4
  "main": "./src/index.js",
5
5
  "description": "侧边栏工作区层级树:名称中的 / 即虚拟分组(web/前端 · web/后端),添加工作区的目录流附所属分组弹窗,重命名即时重排层级,可新建空分组。Hierarchy tree for the DSH sidebar workspace list.",
6
6
  "engines": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-better-workspace",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "DSH web plugin: a hierarchical workspace tree for the sidebar. Workspace titles containing \"/\" group into virtual folders (web/前端 · web/后端); the add-workspace directory flow gains a parent-group popup; renames re-derive the tree; a new-folder button creates empty levels.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -43,7 +43,8 @@
43
43
  "LICENSE"
44
44
  ],
45
45
  "scripts": {
46
- "test": "node --test tests/smoke.mjs"
46
+ "test": "node --test tests/smoke.mjs",
47
+ "version": "node -e \"const fs=require('fs');const m=JSON.parse(fs.readFileSync('dsh.plugin.json','utf8'));const v=JSON.parse(fs.readFileSync('package.json','utf8')).version;m.version=v;fs.writeFileSync('dsh.plugin.json',JSON.stringify(m,null,2)+'\\n')\" && git add dsh.plugin.json"
47
48
  },
48
49
  "keywords": [
49
50
  "dsh",
package/src/client.js CHANGED
@@ -1157,6 +1157,12 @@ window.__ModuleLoader__.load({
1157
1157
  const [customize, setCustomize] = React.useState(null) // { kind, entryKey, name }
1158
1158
  const [errorText, setErrorText] = React.useState(null)
1159
1159
  const [drag, setDrag] = React.useState(null) // { kind: 'workspace'|'session', source, over } | null
1160
+ // Workspace drags arm their state one frame LATE (see workspaceDragEvents):
1161
+ // arming synchronously re-renders during the dragstart dispatch, the chain
1162
+ // expansion inserts rows above the drag source, the cursor leaves the
1163
+ // source element, and Chromium cancels the whole gesture. dragEnd clears
1164
+ // the timer so a same-tick cancel never leaves a ghost drag behind.
1165
+ const wsDragArmTimer = React.useRef(null)
1160
1166
  const normalizedQuery = query.trim().toLowerCase()
1161
1167
  const now = Date.now()
1162
1168
 
@@ -1332,9 +1338,20 @@ window.__ModuleLoader__.load({
1332
1338
  const segs = splitTitleSegs(workspace.title)
1333
1339
  const sourceLeaf = segs.length > 0 ? segs[segs.length - 1] : (workspace.leaf || String(workspace.workspaceId))
1334
1340
  const sourceFolder = segs.length > 1 ? segs.slice(0, -1).join('/') : ''
1335
- setDrag({ kind: 'workspace', source: { workspaceId: workspace.workspaceId, leaf: sourceLeaf, folderPath: sourceFolder }, over: null })
1341
+ // Deferred by one frame on purpose (Chromium cancels a just-started
1342
+ // drag whose source element is moved out from under the cursor; see
1343
+ // wsDragArmTimer above). By the next frame the gesture has settled
1344
+ // and the chain expansion is an ordinary mid-drag update.
1345
+ if (wsDragArmTimer.current !== null) clearTimeout(wsDragArmTimer.current)
1346
+ wsDragArmTimer.current = setTimeout(() => {
1347
+ wsDragArmTimer.current = null
1348
+ setDrag({ kind: 'workspace', source: { workspaceId: workspace.workspaceId, leaf: sourceLeaf, folderPath: sourceFolder }, over: null })
1349
+ }, 0)
1350
+ },
1351
+ onDragEnd: () => {
1352
+ if (wsDragArmTimer.current !== null) { clearTimeout(wsDragArmTimer.current); wsDragArmTimer.current = null }
1353
+ setDrag(null)
1336
1354
  },
1337
- onDragEnd: () => setDrag(null),
1338
1355
  onDragOver: (event) => {
1339
1356
  if (!dragMatches('workspace')) return
1340
1357
  event.preventDefault()