@civilization/dsh-workspace-files 0.3.2 → 0.3.4
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/README.md +8 -0
- package/icon.svg +4 -0
- package/lib/client.js +612 -541
- package/lib/client.js.map +1 -1
- package/lib/index.js +15 -1
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +8 -4
- package/src/client/icons.tsx +39 -0
- package/src/client/index.tsx +549 -554
- package/src/files.ts +14 -0
package/lib/client.js
CHANGED
|
@@ -4,7 +4,30 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
//#region \0rolldown/runtime.js
|
|
8
|
+
var __create = Object.create;
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
16
|
+
key = keys[i];
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
18
|
+
get: ((k) => from[k]).bind(null, key),
|
|
19
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
25
|
+
value: mod,
|
|
26
|
+
enumerable: true
|
|
27
|
+
}) : target, mod));
|
|
28
|
+
//#endregion
|
|
7
29
|
let react = require("react");
|
|
30
|
+
react = __toESM(react, 1);
|
|
8
31
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
32
|
//#region src/client/icons.tsx
|
|
10
33
|
function IconFolder({ size = 15, open = false }) {
|
|
@@ -204,6 +227,30 @@ window.__ModuleLoader__.load({
|
|
|
204
227
|
} else if (ext === "yml" || ext === "yaml") {
|
|
205
228
|
color = "#cb171e";
|
|
206
229
|
badge = "Y";
|
|
230
|
+
} else if (ext === "rs") {
|
|
231
|
+
color = "#dea584";
|
|
232
|
+
badge = "RS";
|
|
233
|
+
} else if (ext === "go") {
|
|
234
|
+
color = "#00add8";
|
|
235
|
+
badge = "GO";
|
|
236
|
+
} else if (ext === "vue") {
|
|
237
|
+
color = "#41b883";
|
|
238
|
+
badge = "V";
|
|
239
|
+
} else if (ext === "svelte") {
|
|
240
|
+
color = "#ff3e00";
|
|
241
|
+
badge = "S";
|
|
242
|
+
} else if (ext === "toml") {
|
|
243
|
+
color = "#9c4121";
|
|
244
|
+
badge = "T";
|
|
245
|
+
} else if (ext === "sql") {
|
|
246
|
+
color = "#e38c00";
|
|
247
|
+
badge = "SQL";
|
|
248
|
+
} else if (ext === "sh" || ext === "bash" || ext === "zsh" || ext === "ps1" || ext === "bat" || ext === "cmd") {
|
|
249
|
+
color = "#4eaa25";
|
|
250
|
+
badge = ">_";
|
|
251
|
+
} else if (ext === "lock") {
|
|
252
|
+
color = "var(--dsw-alias-label-tertiary, #8c9ba5)";
|
|
253
|
+
badge = "🔒";
|
|
207
254
|
}
|
|
208
255
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
209
256
|
style: {
|
|
@@ -247,22 +294,23 @@ window.__ModuleLoader__.load({
|
|
|
247
294
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2 3h4v4H2zM10 9h4v4h-4zM4 7v6h6" })
|
|
248
295
|
});
|
|
249
296
|
}
|
|
250
|
-
function
|
|
297
|
+
function IconChevronRight({ size = 11, className, style }) {
|
|
251
298
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
252
299
|
width: size,
|
|
253
300
|
height: size,
|
|
254
301
|
viewBox: "0 0 16 16",
|
|
255
|
-
fill: "
|
|
256
|
-
|
|
257
|
-
strokeWidth: "1.5",
|
|
258
|
-
strokeLinecap: "round",
|
|
259
|
-
strokeLinejoin: "round",
|
|
302
|
+
fill: "currentColor",
|
|
303
|
+
className,
|
|
260
304
|
style: {
|
|
261
305
|
display: "inline-block",
|
|
262
306
|
verticalAlign: "middle",
|
|
263
|
-
flexShrink: 0
|
|
307
|
+
flexShrink: 0,
|
|
308
|
+
...style
|
|
264
309
|
},
|
|
265
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
310
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
311
|
+
fillRule: "evenodd",
|
|
312
|
+
d: "M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06z"
|
|
313
|
+
})
|
|
266
314
|
});
|
|
267
315
|
}
|
|
268
316
|
function IconExplorer({ size = 12 }) {
|
|
@@ -411,16 +459,16 @@ window.__ModuleLoader__.load({
|
|
|
411
459
|
style.id = id;
|
|
412
460
|
style.textContent = `
|
|
413
461
|
.dsh-wf-card {
|
|
414
|
-
border:
|
|
415
|
-
background: var(--dsw-alias-
|
|
416
|
-
border-radius:
|
|
462
|
+
border: 0.5px solid var(--dsw-alias-border-l1);
|
|
463
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
464
|
+
border-radius: var(--dsw-radius-md, 8px);
|
|
417
465
|
list-style: none;
|
|
418
|
-
transition: border-color .16s, background .16s;
|
|
466
|
+
transition: border-color 0.16s, background 0.16s;
|
|
419
467
|
box-sizing: border-box;
|
|
420
468
|
}
|
|
421
469
|
.dsh-wf-card-open {
|
|
422
|
-
background: var(--dsw-alias-
|
|
423
|
-
border-color: var(--dsw-alias-
|
|
470
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
471
|
+
border-color: var(--dsw-alias-state-business-primary);
|
|
424
472
|
}
|
|
425
473
|
.dsh-wf-header {
|
|
426
474
|
-webkit-appearance: none;
|
|
@@ -430,24 +478,24 @@ window.__ModuleLoader__.load({
|
|
|
430
478
|
color: inherit;
|
|
431
479
|
text-align: left;
|
|
432
480
|
cursor: pointer;
|
|
433
|
-
background:
|
|
481
|
+
background: transparent;
|
|
434
482
|
border: 0;
|
|
435
|
-
border-radius:
|
|
483
|
+
border-radius: var(--dsw-radius-md, 8px);
|
|
436
484
|
align-items: center;
|
|
437
485
|
gap: 12px;
|
|
438
|
-
padding: 14px
|
|
486
|
+
padding: 12px 14px;
|
|
439
487
|
display: flex;
|
|
440
488
|
}
|
|
441
489
|
.dsh-wf-head-text {
|
|
442
490
|
flex-direction: column;
|
|
443
491
|
flex: 1;
|
|
444
|
-
gap:
|
|
492
|
+
gap: 3px;
|
|
445
493
|
min-width: 0;
|
|
446
494
|
display: flex;
|
|
447
495
|
}
|
|
448
496
|
.dsh-wf-name {
|
|
449
|
-
color: var(--dsw-alias-label-primary
|
|
450
|
-
font-size:
|
|
497
|
+
color: var(--dsw-alias-label-primary);
|
|
498
|
+
font-size: 14px;
|
|
451
499
|
font-weight: 600;
|
|
452
500
|
line-height: 1.4;
|
|
453
501
|
display: flex;
|
|
@@ -455,38 +503,38 @@ window.__ModuleLoader__.load({
|
|
|
455
503
|
gap: 8px;
|
|
456
504
|
}
|
|
457
505
|
.dsh-wf-version {
|
|
458
|
-
font-size:
|
|
506
|
+
font-size: 11px;
|
|
459
507
|
font-weight: 400;
|
|
460
|
-
color: var(--dsw-alias-label-tertiary
|
|
508
|
+
color: var(--dsw-alias-label-tertiary);
|
|
461
509
|
}
|
|
462
510
|
.dsh-wf-desc {
|
|
463
|
-
color: var(--dsw-alias-label-
|
|
464
|
-
font-size:
|
|
511
|
+
color: var(--dsw-alias-label-secondary);
|
|
512
|
+
font-size: 12px;
|
|
465
513
|
line-height: 1.5;
|
|
466
514
|
}
|
|
467
515
|
.dsh-wf-chevron {
|
|
468
|
-
color: var(--dsw-alias-label-tertiary
|
|
516
|
+
color: var(--dsw-alias-label-tertiary);
|
|
469
517
|
flex: none;
|
|
470
|
-
transition: transform .
|
|
518
|
+
transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
|
|
471
519
|
display: inline-flex;
|
|
472
520
|
}
|
|
473
521
|
.dsh-wf-chevron-open {
|
|
474
522
|
transform: rotate(180deg);
|
|
475
523
|
}
|
|
476
524
|
.dsh-wf-body {
|
|
477
|
-
border-top:
|
|
478
|
-
margin: 0
|
|
525
|
+
border-top: 0.5px solid var(--dsw-alias-border-l2);
|
|
526
|
+
margin: 0 14px;
|
|
479
527
|
padding: 8px 0 12px;
|
|
480
528
|
}
|
|
481
529
|
.dsh-wf-row {
|
|
482
530
|
align-items: center;
|
|
483
531
|
gap: 16px;
|
|
484
|
-
padding:
|
|
532
|
+
padding: 10px 0;
|
|
485
533
|
display: flex;
|
|
486
534
|
justify-content: space-between;
|
|
487
535
|
}
|
|
488
536
|
.dsh-wf-row + .dsh-wf-row {
|
|
489
|
-
border-top:
|
|
537
|
+
border-top: 0.5px solid var(--dsw-alias-border-l2);
|
|
490
538
|
}
|
|
491
539
|
.dsh-wf-label-box {
|
|
492
540
|
flex-direction: column;
|
|
@@ -496,14 +544,14 @@ window.__ModuleLoader__.load({
|
|
|
496
544
|
display: flex;
|
|
497
545
|
}
|
|
498
546
|
.dsh-wf-label {
|
|
499
|
-
font-size:
|
|
547
|
+
font-size: 13px;
|
|
500
548
|
font-weight: 550;
|
|
501
|
-
color: var(--dsw-alias-label-primary
|
|
549
|
+
color: var(--dsw-alias-label-primary);
|
|
502
550
|
}
|
|
503
551
|
.dsh-wf-hint {
|
|
504
|
-
color: var(--dsw-alias-label-tertiary
|
|
505
|
-
font-size:
|
|
506
|
-
line-height:
|
|
552
|
+
color: var(--dsw-alias-label-tertiary);
|
|
553
|
+
font-size: 11.5px;
|
|
554
|
+
line-height: 16px;
|
|
507
555
|
}
|
|
508
556
|
.dsh-wf-ctrl {
|
|
509
557
|
flex-shrink: 0;
|
|
@@ -512,56 +560,56 @@ window.__ModuleLoader__.load({
|
|
|
512
560
|
gap: 8px;
|
|
513
561
|
}
|
|
514
562
|
.dsh-wf-seg {
|
|
515
|
-
border:
|
|
516
|
-
border-radius:
|
|
563
|
+
border: 0.5px solid var(--dsw-alias-border-l1);
|
|
564
|
+
border-radius: var(--dsw-radius-sm, 6px);
|
|
517
565
|
gap: 2px;
|
|
518
566
|
padding: 2px;
|
|
519
567
|
display: inline-flex;
|
|
520
|
-
background: var(--dsw-alias-
|
|
568
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
521
569
|
}
|
|
522
570
|
.dsh-wf-seg-btn {
|
|
523
571
|
font: inherit;
|
|
524
|
-
color: var(--dsw-alias-label-secondary
|
|
572
|
+
color: var(--dsw-alias-label-secondary);
|
|
525
573
|
cursor: pointer;
|
|
526
|
-
background:
|
|
574
|
+
background: transparent;
|
|
527
575
|
border: none;
|
|
528
|
-
border-radius:
|
|
529
|
-
padding:
|
|
530
|
-
font-size:
|
|
531
|
-
|
|
532
|
-
transition: all 0.15s;
|
|
576
|
+
border-radius: 4px;
|
|
577
|
+
padding: 3px 8px;
|
|
578
|
+
font-size: 11.5px;
|
|
579
|
+
transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
|
|
533
580
|
}
|
|
534
581
|
.dsh-wf-seg-btn:hover {
|
|
535
|
-
color: var(--dsw-alias-label-primary
|
|
582
|
+
color: var(--dsw-alias-label-primary);
|
|
583
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
536
584
|
}
|
|
537
585
|
.dsh-wf-seg-active {
|
|
538
|
-
background: var(--dsw-alias-
|
|
539
|
-
color: var(--dsw-alias-
|
|
586
|
+
background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);
|
|
587
|
+
color: var(--dsw-alias-state-business-primary);
|
|
540
588
|
font-weight: 600;
|
|
541
|
-
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
|
|
542
589
|
}
|
|
543
590
|
.dsh-wf-input {
|
|
544
591
|
box-sizing: border-box;
|
|
545
|
-
border:
|
|
546
|
-
background: var(--dsw-alias-
|
|
547
|
-
width:
|
|
592
|
+
border: 0.5px solid var(--dsw-alias-border-l1);
|
|
593
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
594
|
+
width: 58px;
|
|
548
595
|
text-align: center;
|
|
549
|
-
color: var(--dsw-alias-label-primary
|
|
596
|
+
color: var(--dsw-alias-label-primary);
|
|
550
597
|
font: inherit;
|
|
551
|
-
border-radius:
|
|
552
|
-
padding:
|
|
553
|
-
font-size:
|
|
554
|
-
|
|
598
|
+
border-radius: 6px;
|
|
599
|
+
padding: 3px 6px;
|
|
600
|
+
font-size: 12px;
|
|
601
|
+
outline: none;
|
|
602
|
+
transition: border-color 0.15s, box-shadow 0.15s;
|
|
555
603
|
}
|
|
556
604
|
.dsh-wf-input:focus {
|
|
557
|
-
border-color: var(--dsw-alias-
|
|
558
|
-
|
|
605
|
+
border-color: var(--dsw-alias-state-business-primary);
|
|
606
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary) 18%, transparent);
|
|
559
607
|
}
|
|
560
608
|
.dsh-wf-toggle {
|
|
561
609
|
position: relative;
|
|
562
610
|
display: inline-block;
|
|
563
|
-
width:
|
|
564
|
-
height:
|
|
611
|
+
width: 36px;
|
|
612
|
+
height: 20px;
|
|
565
613
|
cursor: pointer;
|
|
566
614
|
}
|
|
567
615
|
.dsh-wf-toggle input {
|
|
@@ -573,55 +621,55 @@ window.__ModuleLoader__.load({
|
|
|
573
621
|
.dsh-wf-toggle-track {
|
|
574
622
|
position: absolute;
|
|
575
623
|
top: 0; left: 0; right: 0; bottom: 0;
|
|
576
|
-
background-color: var(--dsw-alias-border-
|
|
577
|
-
transition: .
|
|
578
|
-
border-radius:
|
|
624
|
+
background-color: var(--dsw-alias-border-l1);
|
|
625
|
+
transition: 0.18s cubic-bezier(0.16, 1, 0.3, 1);
|
|
626
|
+
border-radius: 20px;
|
|
579
627
|
}
|
|
580
628
|
.dsh-wf-toggle input:checked + .dsh-wf-toggle-track {
|
|
581
|
-
background-color: var(--dsw-alias-
|
|
629
|
+
background-color: var(--dsw-alias-state-business-primary);
|
|
582
630
|
}
|
|
583
631
|
.dsh-wf-toggle-thumb {
|
|
584
632
|
position: absolute;
|
|
585
|
-
height:
|
|
586
|
-
width:
|
|
633
|
+
height: 14px;
|
|
634
|
+
width: 14px;
|
|
587
635
|
left: 3px;
|
|
588
636
|
bottom: 3px;
|
|
589
|
-
background-color:
|
|
590
|
-
transition: .
|
|
637
|
+
background-color: #ffffff;
|
|
638
|
+
transition: 0.18s cubic-bezier(0.16, 1, 0.3, 1);
|
|
591
639
|
border-radius: 50%;
|
|
592
|
-
box-shadow: 0 1px
|
|
640
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.18);
|
|
593
641
|
}
|
|
594
642
|
.dsh-wf-toggle input:checked + .dsh-wf-toggle-track .dsh-wf-toggle-thumb {
|
|
595
|
-
transform: translateX(
|
|
643
|
+
transform: translateX(16px);
|
|
596
644
|
}
|
|
597
645
|
.dsh-wf-footer {
|
|
598
|
-
margin-top:
|
|
599
|
-
padding-top:
|
|
600
|
-
border-top:
|
|
646
|
+
margin-top: 6px;
|
|
647
|
+
padding-top: 8px;
|
|
648
|
+
border-top: 0.5px solid var(--dsw-alias-border-l2);
|
|
601
649
|
display: flex;
|
|
602
650
|
align-items: center;
|
|
603
651
|
justify-content: space-between;
|
|
604
652
|
}
|
|
605
653
|
.dsh-wf-saved-hint {
|
|
606
|
-
font-size:
|
|
607
|
-
color: var(--dsw-alias-state-
|
|
654
|
+
font-size: 11px;
|
|
655
|
+
color: var(--dsw-alias-state-business-primary);
|
|
608
656
|
display: flex;
|
|
609
657
|
align-items: center;
|
|
610
658
|
gap: 4px;
|
|
611
659
|
}
|
|
612
660
|
.dsh-wf-btn-reset {
|
|
613
661
|
background: transparent;
|
|
614
|
-
border:
|
|
615
|
-
border-radius:
|
|
616
|
-
padding: 3px
|
|
617
|
-
font-size:
|
|
618
|
-
color: var(--dsw-alias-label-secondary
|
|
662
|
+
border: 0.5px solid var(--dsw-alias-border-l1);
|
|
663
|
+
border-radius: 4px;
|
|
664
|
+
padding: 3px 8px;
|
|
665
|
+
font-size: 11px;
|
|
666
|
+
color: var(--dsw-alias-label-secondary);
|
|
619
667
|
cursor: pointer;
|
|
620
|
-
transition: all 0.
|
|
668
|
+
transition: all 0.12s;
|
|
621
669
|
}
|
|
622
670
|
.dsh-wf-btn-reset:hover {
|
|
623
|
-
background: var(--dsw-alias-bg-
|
|
624
|
-
color: var(--dsw-alias-label-primary
|
|
671
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
672
|
+
color: var(--dsw-alias-label-primary);
|
|
625
673
|
}
|
|
626
674
|
`;
|
|
627
675
|
document.head.appendChild(style);
|
|
@@ -660,32 +708,39 @@ window.__ModuleLoader__.load({
|
|
|
660
708
|
};
|
|
661
709
|
setConfig(def);
|
|
662
710
|
saveWorkspaceFilesConfig(def);
|
|
663
|
-
setSavedTick(true);
|
|
664
|
-
setTimeout(() => setSavedTick(false), 2e3);
|
|
665
711
|
};
|
|
666
712
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
667
|
-
className:
|
|
713
|
+
className: `dsh-wf-card ${open ? "dsh-wf-card-open" : ""}`,
|
|
668
714
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
669
715
|
type: "button",
|
|
670
716
|
className: "dsh-wf-header",
|
|
671
|
-
"aria-expanded": open,
|
|
672
717
|
onClick: () => setOpen(!open),
|
|
673
|
-
children: [
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
className: "dsh-wf-
|
|
677
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
678
|
-
className: "dsh-wf-
|
|
679
|
-
children: ["
|
|
718
|
+
children: [
|
|
719
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FolderGuideGlyph, { size: 22 }),
|
|
720
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
721
|
+
className: "dsh-wf-head-text",
|
|
722
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
723
|
+
className: "dsh-wf-name",
|
|
724
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "工作区文件" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
725
|
+
className: "dsh-wf-version",
|
|
726
|
+
children: ["v", "0.3.4"]
|
|
727
|
+
})]
|
|
728
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
729
|
+
className: "dsh-wf-desc",
|
|
730
|
+
children: "全量项目文件树浏览、即时检索与 @-mention 会话一键引用。"
|
|
680
731
|
})]
|
|
681
|
-
}),
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
732
|
+
}),
|
|
733
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
734
|
+
className: `dsh-wf-chevron ${open ? "dsh-wf-chevron-open" : ""}`,
|
|
735
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronRight, {
|
|
736
|
+
size: 14,
|
|
737
|
+
style: {
|
|
738
|
+
transform: open ? "rotate(90deg)" : "rotate(0deg)",
|
|
739
|
+
transition: "transform 0.16s"
|
|
740
|
+
}
|
|
741
|
+
})
|
|
742
|
+
})
|
|
743
|
+
]
|
|
689
744
|
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
690
745
|
className: "dsh-wf-body",
|
|
691
746
|
children: [
|
|
@@ -693,12 +748,12 @@ window.__ModuleLoader__.load({
|
|
|
693
748
|
className: "dsh-wf-row",
|
|
694
749
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
695
750
|
className: "dsh-wf-label-box",
|
|
696
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
751
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
697
752
|
className: "dsh-wf-label",
|
|
698
|
-
children: "
|
|
699
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
753
|
+
children: "扫描最大深度 (层级)"
|
|
754
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
700
755
|
className: "dsh-wf-hint",
|
|
701
|
-
children: "
|
|
756
|
+
children: "控制文件树深入遍历的最大文件夹嵌套层级,防止庞大项目深度过大产生卡顿。"
|
|
702
757
|
})]
|
|
703
758
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
704
759
|
className: "dsh-wf-ctrl",
|
|
@@ -707,22 +762,22 @@ window.__ModuleLoader__.load({
|
|
|
707
762
|
children: [
|
|
708
763
|
8,
|
|
709
764
|
16,
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
].map((d) => /* @__PURE__ */ (0, react_jsx_runtime.
|
|
765
|
+
24,
|
|
766
|
+
32
|
|
767
|
+
].map((d) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
713
768
|
type: "button",
|
|
714
|
-
className: config.maxDepth === d ? "dsh-wf-seg-
|
|
769
|
+
className: `dsh-wf-seg-btn ${config.maxDepth === d ? "dsh-wf-seg-active" : ""}`,
|
|
715
770
|
onClick: () => handleDepthSelect(d),
|
|
716
|
-
children: d
|
|
771
|
+
children: [d, " 层"]
|
|
717
772
|
}, d))
|
|
718
773
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
719
774
|
type: "number",
|
|
720
|
-
min:
|
|
721
|
-
max:
|
|
775
|
+
min: 1,
|
|
776
|
+
max: 100,
|
|
722
777
|
className: "dsh-wf-input",
|
|
723
778
|
value: config.maxDepth,
|
|
724
779
|
onChange: handleDepthInput,
|
|
725
|
-
title: "
|
|
780
|
+
title: "手动输入层级深度 (1-100)"
|
|
726
781
|
})]
|
|
727
782
|
})]
|
|
728
783
|
}),
|
|
@@ -730,12 +785,12 @@ window.__ModuleLoader__.load({
|
|
|
730
785
|
className: "dsh-wf-row",
|
|
731
786
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
732
787
|
className: "dsh-wf-label-box",
|
|
733
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
788
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
734
789
|
className: "dsh-wf-label",
|
|
735
|
-
children: "
|
|
736
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
790
|
+
children: "显示以点开头的隐藏文件"
|
|
791
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
737
792
|
className: "dsh-wf-hint",
|
|
738
|
-
children: "
|
|
793
|
+
children: "开启后,文件树中将展现如 .env, .editorconfig 等以点开头的配置文件(.git 等缓存黑名单除外)。"
|
|
739
794
|
})]
|
|
740
795
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
741
796
|
className: "dsh-wf-ctrl",
|
|
@@ -754,15 +809,9 @@ window.__ModuleLoader__.load({
|
|
|
754
809
|
}),
|
|
755
810
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
756
811
|
className: "dsh-wf-footer",
|
|
757
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: savedTick
|
|
812
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: savedTick && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
758
813
|
className: "dsh-wf-saved-hint",
|
|
759
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCheck, { size: 12 }),
|
|
760
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
761
|
-
style: {
|
|
762
|
-
fontSize: 11,
|
|
763
|
-
color: "var(--dsw-alias-label-tertiary, #8b93a1)"
|
|
764
|
-
},
|
|
765
|
-
children: "设置改动即时生效并同步至工作区文件树"
|
|
814
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCheck, { size: 12 }), "配置已自动保存并实时同步"]
|
|
766
815
|
}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
767
816
|
type: "button",
|
|
768
817
|
className: "dsh-wf-btn-reset",
|
|
@@ -774,21 +823,85 @@ window.__ModuleLoader__.load({
|
|
|
774
823
|
})]
|
|
775
824
|
});
|
|
776
825
|
}
|
|
826
|
+
/**
|
|
827
|
+
* 线性遍历计算可视行。未展开目录的子节点绝不遍历,彻底解决 DOM 节点爆炸问题。
|
|
828
|
+
*/
|
|
829
|
+
function flattenVisibleTree(items, expandedPaths, depth = 0, out = []) {
|
|
830
|
+
for (const it of items) {
|
|
831
|
+
const isDir = it.isDirectory;
|
|
832
|
+
const hasChildren = isDir && Array.isArray(it.children) && it.children.length > 0;
|
|
833
|
+
const isExpanded = isDir && expandedPaths.has(it.path);
|
|
834
|
+
const childCount = hasChildren ? it.children.length : 0;
|
|
835
|
+
out.push({
|
|
836
|
+
id: it.path,
|
|
837
|
+
name: it.name,
|
|
838
|
+
path: it.path,
|
|
839
|
+
isDirectory: isDir,
|
|
840
|
+
depth,
|
|
841
|
+
isExpanded,
|
|
842
|
+
hasChildren,
|
|
843
|
+
childCount,
|
|
844
|
+
size: it.size,
|
|
845
|
+
item: it
|
|
846
|
+
});
|
|
847
|
+
if (isDir && isExpanded && hasChildren) flattenVisibleTree(it.children, expandedPaths, depth + 1, out);
|
|
848
|
+
}
|
|
849
|
+
return out;
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* 树形过滤模式:仅保留包含匹配项的分支并保持展开
|
|
853
|
+
*/
|
|
854
|
+
function filterTreeWithAutoExpand(nodes, q) {
|
|
855
|
+
const autoExpand = /* @__PURE__ */ new Set();
|
|
856
|
+
function filterNode(node) {
|
|
857
|
+
const matchSelf = node.name.toLowerCase().includes(q) || node.path.toLowerCase().includes(q);
|
|
858
|
+
if (node.isDirectory) {
|
|
859
|
+
const children = [];
|
|
860
|
+
for (const child of node.children || []) {
|
|
861
|
+
const c = filterNode(child);
|
|
862
|
+
if (c) children.push(c);
|
|
863
|
+
}
|
|
864
|
+
if (matchSelf || children.length > 0) {
|
|
865
|
+
autoExpand.add(node.path);
|
|
866
|
+
return {
|
|
867
|
+
...node,
|
|
868
|
+
children
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
return null;
|
|
872
|
+
}
|
|
873
|
+
return matchSelf ? node : null;
|
|
874
|
+
}
|
|
875
|
+
const result = [];
|
|
876
|
+
for (const it of nodes) {
|
|
877
|
+
const f = filterNode(it);
|
|
878
|
+
if (f) result.push(f);
|
|
879
|
+
}
|
|
880
|
+
return {
|
|
881
|
+
filteredItems: result,
|
|
882
|
+
autoExpandPaths: autoExpand
|
|
883
|
+
};
|
|
884
|
+
}
|
|
777
885
|
function WorkspaceFilesView({ sessionId, cwd, onOpenFile }) {
|
|
778
886
|
const [data, setData] = (0, react.useState)(null);
|
|
779
887
|
const [loading, setLoading] = (0, react.useState)(true);
|
|
780
888
|
const [error, setError] = (0, react.useState)(null);
|
|
781
|
-
const [
|
|
889
|
+
const [inputQuery, setInputQuery] = (0, react.useState)("");
|
|
782
890
|
const [toast, setToast] = (0, react.useState)(null);
|
|
783
891
|
const [expandedPaths, setExpandedPaths] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
784
892
|
const [activeConfig, setActiveConfig] = (0, react.useState)(() => loadWorkspaceFilesConfig());
|
|
785
893
|
const [showHidden, setShowHidden] = (0, react.useState)(() => loadWorkspaceFilesConfig().showHidden);
|
|
894
|
+
const [searchViewMode, setSearchViewMode] = (0, react.useState)("flat");
|
|
895
|
+
const deferredQuery = (0, react.useDeferredValue)(inputQuery.trim().toLowerCase());
|
|
786
896
|
const toastTimer = (0, react.useRef)(null);
|
|
787
897
|
const showToastMsg = (0, react.useCallback)((msg) => {
|
|
788
898
|
setToast(msg);
|
|
789
899
|
if (toastTimer.current) window.clearTimeout(toastTimer.current);
|
|
790
900
|
toastTimer.current = window.setTimeout(() => setToast(null), 2e3);
|
|
791
901
|
}, []);
|
|
902
|
+
(0, react.useEffect)(() => {
|
|
903
|
+
ensureFilesStyle();
|
|
904
|
+
}, []);
|
|
792
905
|
(0, react.useEffect)(() => {
|
|
793
906
|
const handleCfgChange = (e) => {
|
|
794
907
|
if (e.detail) {
|
|
@@ -831,7 +944,7 @@ window.__ModuleLoader__.load({
|
|
|
831
944
|
(0, react.useEffect)(() => {
|
|
832
945
|
loadTree();
|
|
833
946
|
}, [loadTree]);
|
|
834
|
-
const handleToggleExpand = (path) => {
|
|
947
|
+
const handleToggleExpand = (0, react.useCallback)((path) => {
|
|
835
948
|
setExpandedPaths((prev) => {
|
|
836
949
|
const next = new Set(prev);
|
|
837
950
|
if (next.has(path)) next.delete(path);
|
|
@@ -839,8 +952,8 @@ window.__ModuleLoader__.load({
|
|
|
839
952
|
saveStoredExpandedPaths(data?.root || cwd, next);
|
|
840
953
|
return next;
|
|
841
954
|
});
|
|
842
|
-
};
|
|
843
|
-
const handleExpandAll = () => {
|
|
955
|
+
}, [data?.root, cwd]);
|
|
956
|
+
const handleExpandAll = (0, react.useCallback)(() => {
|
|
844
957
|
if (!data) return;
|
|
845
958
|
const all = /* @__PURE__ */ new Set();
|
|
846
959
|
function collect(items) {
|
|
@@ -852,13 +965,13 @@ window.__ModuleLoader__.load({
|
|
|
852
965
|
collect(data.items);
|
|
853
966
|
setExpandedPaths(all);
|
|
854
967
|
saveStoredExpandedPaths(data.root || cwd, all);
|
|
855
|
-
};
|
|
856
|
-
const handleCollapseAll = () => {
|
|
968
|
+
}, [data, cwd]);
|
|
969
|
+
const handleCollapseAll = (0, react.useCallback)(() => {
|
|
857
970
|
const empty = /* @__PURE__ */ new Set();
|
|
858
971
|
setExpandedPaths(empty);
|
|
859
972
|
saveStoredExpandedPaths(data?.root || cwd, empty);
|
|
860
|
-
};
|
|
861
|
-
const handleJumpToFolderInTree = (dirPath) => {
|
|
973
|
+
}, [data?.root, cwd]);
|
|
974
|
+
const handleJumpToFolderInTree = (0, react.useCallback)((dirPath) => {
|
|
862
975
|
const parts = dirPath.split("/");
|
|
863
976
|
const toExpand = [];
|
|
864
977
|
let acc = "";
|
|
@@ -873,7 +986,7 @@ window.__ModuleLoader__.load({
|
|
|
873
986
|
saveStoredExpandedPaths(data?.root || cwd, next);
|
|
874
987
|
return next;
|
|
875
988
|
});
|
|
876
|
-
|
|
989
|
+
setInputQuery("");
|
|
877
990
|
showToastMsg(`已定位并展开目录: ${dirPath}/`);
|
|
878
991
|
setTimeout(() => {
|
|
879
992
|
try {
|
|
@@ -884,14 +997,18 @@ window.__ModuleLoader__.load({
|
|
|
884
997
|
});
|
|
885
998
|
} catch {}
|
|
886
999
|
}, 60);
|
|
887
|
-
}
|
|
888
|
-
|
|
1000
|
+
}, [
|
|
1001
|
+
data?.root,
|
|
1002
|
+
cwd,
|
|
1003
|
+
showToastMsg
|
|
1004
|
+
]);
|
|
1005
|
+
const handleCopyPath = (0, react.useCallback)((e, path) => {
|
|
889
1006
|
e.stopPropagation();
|
|
890
1007
|
navigator.clipboard.writeText(path).then(() => {
|
|
891
1008
|
showToastMsg(`已复制路径: ${path}`);
|
|
892
1009
|
});
|
|
893
|
-
};
|
|
894
|
-
const handleMention = (e, itemOrPath) => {
|
|
1010
|
+
}, [showToastMsg]);
|
|
1011
|
+
const handleMention = (0, react.useCallback)((e, itemOrPath) => {
|
|
895
1012
|
e.stopPropagation();
|
|
896
1013
|
const itemObj = typeof itemOrPath === "string" ? {
|
|
897
1014
|
name: itemOrPath.split("/").pop() || itemOrPath,
|
|
@@ -902,21 +1019,17 @@ window.__ModuleLoader__.load({
|
|
|
902
1019
|
let inserted = false;
|
|
903
1020
|
try {
|
|
904
1021
|
inserted = tryInsertNativeReferenceChip(globalCtx, sessionId, itemObj);
|
|
905
|
-
} catch
|
|
906
|
-
console.warn("[dsh-workspace-files] 原生 Chip 插入失败:", err);
|
|
907
|
-
}
|
|
1022
|
+
} catch {}
|
|
908
1023
|
if (!inserted) try {
|
|
909
1024
|
inserted = insertMentionToComposer(mentionText);
|
|
910
|
-
} catch
|
|
911
|
-
console.warn("[dsh-workspace-files] 降级纯文本插入失败:", err);
|
|
912
|
-
}
|
|
1025
|
+
} catch {}
|
|
913
1026
|
const displayName = itemObj.isDirectory ? `${itemObj.name}/` : itemObj.name;
|
|
914
1027
|
navigator.clipboard.writeText(mentionText.trim()).then(() => {
|
|
915
1028
|
if (inserted) showToastMsg(`已引用${itemObj.isDirectory ? "目录" : "文件"}: ${displayName}`);
|
|
916
1029
|
else showToastMsg(`已复制引用: ${mentionText.trim()}`);
|
|
917
1030
|
});
|
|
918
|
-
};
|
|
919
|
-
const handleRevealInExplorer = (e, item) => {
|
|
1031
|
+
}, [sessionId, showToastMsg]);
|
|
1032
|
+
const handleRevealInExplorer = (0, react.useCallback)((e, item) => {
|
|
920
1033
|
e.stopPropagation();
|
|
921
1034
|
fetch("/dsh-workspace-files/api/files.open", {
|
|
922
1035
|
method: "POST",
|
|
@@ -934,8 +1047,12 @@ window.__ModuleLoader__.load({
|
|
|
934
1047
|
}).catch((err) => {
|
|
935
1048
|
showToastMsg(`请求失败: ${err?.message || String(err)}`);
|
|
936
1049
|
});
|
|
937
|
-
}
|
|
938
|
-
|
|
1050
|
+
}, [
|
|
1051
|
+
sessionId,
|
|
1052
|
+
cwd,
|
|
1053
|
+
showToastMsg
|
|
1054
|
+
]);
|
|
1055
|
+
const handleOpenDefaultApp = (0, react.useCallback)((e, item) => {
|
|
939
1056
|
e.stopPropagation();
|
|
940
1057
|
fetch("/dsh-workspace-files/api/files.open", {
|
|
941
1058
|
method: "POST",
|
|
@@ -953,76 +1070,51 @@ window.__ModuleLoader__.load({
|
|
|
953
1070
|
}).catch((err) => {
|
|
954
1071
|
showToastMsg(`请求失败: ${err?.message || String(err)}`);
|
|
955
1072
|
});
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
const
|
|
965
|
-
|
|
966
|
-
filteredTreeItems: data.items,
|
|
967
|
-
flatSearchResults: []
|
|
968
|
-
};
|
|
969
|
-
const flat = [];
|
|
970
|
-
function traverseFlat(items, parentDir) {
|
|
1073
|
+
}, [
|
|
1074
|
+
sessionId,
|
|
1075
|
+
cwd,
|
|
1076
|
+
showToastMsg
|
|
1077
|
+
]);
|
|
1078
|
+
const isSearchActive = Boolean(deferredQuery);
|
|
1079
|
+
const flatSearchResults = (0, react.useMemo)(() => {
|
|
1080
|
+
if (!data || !isSearchActive) return [];
|
|
1081
|
+
const results = [];
|
|
1082
|
+
function traverse(items, parentDir) {
|
|
971
1083
|
for (const it of items) {
|
|
972
|
-
if (it.name.toLowerCase().includes(
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
if (node.isDirectory) {
|
|
983
|
-
const filteredChildren = [];
|
|
984
|
-
for (const child of node.children || []) {
|
|
985
|
-
const matchedChild = filterNode(child);
|
|
986
|
-
if (matchedChild) filteredChildren.push(matchedChild);
|
|
1084
|
+
if (it.name.toLowerCase().includes(deferredQuery) || it.path.toLowerCase().includes(deferredQuery)) {
|
|
1085
|
+
results.push({
|
|
1086
|
+
item: it,
|
|
1087
|
+
parentDir
|
|
1088
|
+
});
|
|
1089
|
+
if (results.length >= 300) return;
|
|
1090
|
+
}
|
|
1091
|
+
if (it.isDirectory && it.children) {
|
|
1092
|
+
traverse(it.children, it.path);
|
|
1093
|
+
if (results.length >= 300) return;
|
|
987
1094
|
}
|
|
988
|
-
if (selfMatch || filteredChildren.length > 0) return {
|
|
989
|
-
...node,
|
|
990
|
-
children: filteredChildren
|
|
991
|
-
};
|
|
992
|
-
return null;
|
|
993
|
-
}
|
|
994
|
-
return selfMatch ? node : null;
|
|
995
|
-
}
|
|
996
|
-
const tree = [];
|
|
997
|
-
for (const rootNode of data.items) {
|
|
998
|
-
const matched = filterNode(rootNode);
|
|
999
|
-
if (matched) tree.push(matched);
|
|
1000
|
-
}
|
|
1001
|
-
return {
|
|
1002
|
-
filteredTreeItems: tree,
|
|
1003
|
-
flatSearchResults: flat
|
|
1004
|
-
};
|
|
1005
|
-
}, [data, query]);
|
|
1006
|
-
(0, react.useEffect)(() => {
|
|
1007
|
-
if (!query.trim() || !data) return;
|
|
1008
|
-
const q = query.trim().toLowerCase();
|
|
1009
|
-
const autoExpand = /* @__PURE__ */ new Set();
|
|
1010
|
-
function collect(items) {
|
|
1011
|
-
for (const it of items) if (it.isDirectory) {
|
|
1012
|
-
const selfMatch = it.name.toLowerCase().includes(q) || it.path.toLowerCase().includes(q);
|
|
1013
|
-
const childMatch = it.children?.some((c) => c.name.toLowerCase().includes(q) || c.path.toLowerCase().includes(q));
|
|
1014
|
-
if (selfMatch || childMatch) autoExpand.add(it.path);
|
|
1015
|
-
if (it.children) collect(it.children);
|
|
1016
1095
|
}
|
|
1017
1096
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
}, [
|
|
1021
|
-
|
|
1097
|
+
traverse(data.items, "");
|
|
1098
|
+
return results;
|
|
1099
|
+
}, [
|
|
1100
|
+
data,
|
|
1101
|
+
deferredQuery,
|
|
1102
|
+
isSearchActive
|
|
1103
|
+
]);
|
|
1104
|
+
const visibleFlatRows = (0, react.useMemo)(() => {
|
|
1105
|
+
if (!data) return [];
|
|
1106
|
+
if (!isSearchActive) return flattenVisibleTree(data.items, expandedPaths);
|
|
1107
|
+
const { filteredItems, autoExpandPaths } = filterTreeWithAutoExpand(data.items, deferredQuery);
|
|
1108
|
+
return flattenVisibleTree(filteredItems, autoExpandPaths);
|
|
1109
|
+
}, [
|
|
1110
|
+
data,
|
|
1111
|
+
isSearchActive,
|
|
1112
|
+
deferredQuery,
|
|
1113
|
+
expandedPaths
|
|
1114
|
+
]);
|
|
1022
1115
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1023
1116
|
className: "dsh-files-root",
|
|
1024
1117
|
children: [
|
|
1025
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalFilesStyle, {}),
|
|
1026
1118
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("header", {
|
|
1027
1119
|
className: "dsh-files-header",
|
|
1028
1120
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1031,7 +1123,7 @@ window.__ModuleLoader__.load({
|
|
|
1031
1123
|
className: "dsh-files-title-row",
|
|
1032
1124
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1033
1125
|
className: "dsh-files-title",
|
|
1034
|
-
children: "
|
|
1126
|
+
children: "工作区文件"
|
|
1035
1127
|
}), data && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1036
1128
|
className: "dsh-files-stats-badge",
|
|
1037
1129
|
children: [
|
|
@@ -1060,18 +1152,18 @@ window.__ModuleLoader__.load({
|
|
|
1060
1152
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1061
1153
|
type: "text",
|
|
1062
1154
|
className: "dsh-files-search-input",
|
|
1063
|
-
placeholder: "
|
|
1064
|
-
value:
|
|
1065
|
-
onChange: (e) =>
|
|
1155
|
+
placeholder: "搜索文件或路径 (Esc 清空)...",
|
|
1156
|
+
value: inputQuery,
|
|
1157
|
+
onChange: (e) => setInputQuery(e.target.value),
|
|
1066
1158
|
onKeyDown: (e) => {
|
|
1067
|
-
if (e.key === "Escape")
|
|
1159
|
+
if (e.key === "Escape") setInputQuery("");
|
|
1068
1160
|
}
|
|
1069
1161
|
}),
|
|
1070
|
-
|
|
1162
|
+
inputQuery && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1071
1163
|
type: "button",
|
|
1072
1164
|
className: "dsh-files-clear-btn",
|
|
1073
|
-
onClick: () =>
|
|
1074
|
-
title: "
|
|
1165
|
+
onClick: () => setInputQuery(""),
|
|
1166
|
+
title: "清空搜索",
|
|
1075
1167
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconClose, { size: 12 })
|
|
1076
1168
|
})
|
|
1077
1169
|
]
|
|
@@ -1082,29 +1174,29 @@ window.__ModuleLoader__.load({
|
|
|
1082
1174
|
type: "button",
|
|
1083
1175
|
className: "dsh-files-tool-btn is-active",
|
|
1084
1176
|
onClick: () => setSearchViewMode(searchViewMode === "flat" ? "tree" : "flat"),
|
|
1085
|
-
title: searchViewMode === "flat" ? "
|
|
1177
|
+
title: searchViewMode === "flat" ? "切为树形匹配视图" : "切为扁平列表视图",
|
|
1086
1178
|
children: searchViewMode === "flat" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconTree, { size: 13 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconList, { size: 13 })
|
|
1087
1179
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1088
1180
|
type: "button",
|
|
1089
1181
|
className: "dsh-files-tool-btn",
|
|
1090
1182
|
onClick: handleExpandAll,
|
|
1091
|
-
title: "
|
|
1183
|
+
title: "展开全部目录",
|
|
1092
1184
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconExpandAll, { size: 13 })
|
|
1093
1185
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1094
1186
|
type: "button",
|
|
1095
1187
|
className: "dsh-files-tool-btn",
|
|
1096
1188
|
onClick: handleCollapseAll,
|
|
1097
|
-
title: "
|
|
1189
|
+
title: "折叠全部目录",
|
|
1098
1190
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCollapseAll, { size: 13 })
|
|
1099
1191
|
})] }),
|
|
1100
1192
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1101
1193
|
type: "button",
|
|
1102
1194
|
className: `dsh-files-tool-btn ${showHidden ? "is-active" : ""}`,
|
|
1103
1195
|
onClick: () => setShowHidden(!showHidden),
|
|
1104
|
-
title: showHidden ? "
|
|
1196
|
+
title: showHidden ? "隐藏以点开头的文件" : "显示以点开头的文件",
|
|
1105
1197
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1106
1198
|
style: {
|
|
1107
|
-
fontSize:
|
|
1199
|
+
fontSize: 10.5,
|
|
1108
1200
|
fontWeight: 700
|
|
1109
1201
|
},
|
|
1110
1202
|
children: ".*"
|
|
@@ -1134,21 +1226,21 @@ window.__ModuleLoader__.load({
|
|
|
1134
1226
|
className: "dsh-files-body",
|
|
1135
1227
|
children: loading && !data ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1136
1228
|
className: "dsh-files-centered",
|
|
1137
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "dsh-files-spinner" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "
|
|
1229
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "dsh-files-spinner" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "正在索引工作区文件…" })]
|
|
1138
1230
|
}) : isSearchActive && flatSearchResults.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1139
1231
|
className: "dsh-files-empty",
|
|
1140
1232
|
children: [
|
|
1141
1233
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1142
1234
|
className: "dsh-files-empty-icon",
|
|
1143
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconFolder, { size:
|
|
1235
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconFolder, { size: 28 })
|
|
1144
1236
|
}),
|
|
1145
1237
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1146
1238
|
className: "dsh-files-empty-title",
|
|
1147
|
-
children: "
|
|
1239
|
+
children: "未匹配到相关文件"
|
|
1148
1240
|
}),
|
|
1149
1241
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1150
1242
|
className: "dsh-files-empty-detail",
|
|
1151
|
-
children: "
|
|
1243
|
+
children: "请尝试更换关键字或按 Esc 恢复完整目录树。"
|
|
1152
1244
|
})
|
|
1153
1245
|
]
|
|
1154
1246
|
}) : !isSearchActive && (!data || data.items.length === 0) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1156,7 +1248,7 @@ window.__ModuleLoader__.load({
|
|
|
1156
1248
|
children: [
|
|
1157
1249
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1158
1250
|
className: "dsh-files-empty-icon",
|
|
1159
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconFolder, { size:
|
|
1251
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconFolder, { size: 28 })
|
|
1160
1252
|
}),
|
|
1161
1253
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1162
1254
|
className: "dsh-files-empty-title",
|
|
@@ -1164,7 +1256,7 @@ window.__ModuleLoader__.load({
|
|
|
1164
1256
|
}),
|
|
1165
1257
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1166
1258
|
className: "dsh-files-empty-detail",
|
|
1167
|
-
children: "
|
|
1259
|
+
children: "当前工作目录下暂无可展示的文件。"
|
|
1168
1260
|
})
|
|
1169
1261
|
]
|
|
1170
1262
|
}) : isSearchActive && searchViewMode === "flat" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1177,24 +1269,24 @@ window.__ModuleLoader__.load({
|
|
|
1177
1269
|
"找到 ",
|
|
1178
1270
|
flatSearchResults.length,
|
|
1179
1271
|
" 个匹配项",
|
|
1180
|
-
flatSearchResults.length > 150 ? "
|
|
1272
|
+
flatSearchResults.length > 150 ? "(已展示前 150 项)" : ""
|
|
1181
1273
|
]
|
|
1182
1274
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1183
1275
|
type: "button",
|
|
1184
1276
|
className: "dsh-files-view-toggle-btn",
|
|
1185
1277
|
onClick: () => setSearchViewMode("tree"),
|
|
1186
|
-
title: "
|
|
1278
|
+
title: "切换为树形视图",
|
|
1187
1279
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconTree, { size: 12 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "切为树形" })]
|
|
1188
1280
|
})]
|
|
1189
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1281
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1190
1282
|
className: "dsh-files-flat-list",
|
|
1191
|
-
children:
|
|
1283
|
+
children: flatSearchResults.slice(0, 150).map(({ item, parentDir }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1192
1284
|
className: `dsh-files-flat-row ${item.isDirectory ? "is-directory" : ""}`,
|
|
1193
1285
|
onClick: () => {
|
|
1194
1286
|
if (item.isDirectory) handleJumpToFolderInTree(item.path);
|
|
1195
1287
|
else onOpenFile(item.path);
|
|
1196
1288
|
},
|
|
1197
|
-
title: item.isDirectory ?
|
|
1289
|
+
title: item.isDirectory ? `点击定位并展开目录: ${item.path}/` : `点击预览打开: ${item.path}`,
|
|
1198
1290
|
children: [
|
|
1199
1291
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1200
1292
|
className: "dsh-files-flat-icon",
|
|
@@ -1212,7 +1304,7 @@ window.__ModuleLoader__.load({
|
|
|
1212
1304
|
className: "dsh-files-flat-name",
|
|
1213
1305
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HighlightText, {
|
|
1214
1306
|
text: item.name,
|
|
1215
|
-
query
|
|
1307
|
+
query: deferredQuery
|
|
1216
1308
|
}), item.isDirectory && "/"]
|
|
1217
1309
|
}),
|
|
1218
1310
|
item.size !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -1237,8 +1329,8 @@ window.__ModuleLoader__.load({
|
|
|
1237
1329
|
type: "button",
|
|
1238
1330
|
className: "dsh-files-action-btn dsh-files-action-at",
|
|
1239
1331
|
onClick: (e) => handleMention(e, item),
|
|
1240
|
-
title:
|
|
1241
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconAt, { size:
|
|
1332
|
+
title: `@ 引用${item.isDirectory ? "目录" : "文件"}到会话`,
|
|
1333
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconAt, { size: 12 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1242
1334
|
className: "dsh-files-action-at-text",
|
|
1243
1335
|
children: "@引用"
|
|
1244
1336
|
})]
|
|
@@ -1247,14 +1339,14 @@ window.__ModuleLoader__.load({
|
|
|
1247
1339
|
type: "button",
|
|
1248
1340
|
className: "dsh-files-action-btn",
|
|
1249
1341
|
onClick: (e) => handleRevealInExplorer(e, item),
|
|
1250
|
-
title:
|
|
1342
|
+
title: "在文件资源管理器中显示",
|
|
1251
1343
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconExplorer, { size: 12 })
|
|
1252
1344
|
}),
|
|
1253
1345
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1254
1346
|
type: "button",
|
|
1255
1347
|
className: "dsh-files-action-btn",
|
|
1256
1348
|
onClick: (e) => handleOpenDefaultApp(e, item),
|
|
1257
|
-
title:
|
|
1349
|
+
title: "用系统默认应用打开",
|
|
1258
1350
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconExternalApp, { size: 12 })
|
|
1259
1351
|
}),
|
|
1260
1352
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -1267,24 +1359,19 @@ window.__ModuleLoader__.load({
|
|
|
1267
1359
|
]
|
|
1268
1360
|
})
|
|
1269
1361
|
]
|
|
1270
|
-
}, item.path))
|
|
1271
|
-
style: {
|
|
1272
|
-
padding: "10px 14px",
|
|
1273
|
-
fontSize: 11,
|
|
1274
|
-
textAlign: "center",
|
|
1275
|
-
color: "var(--dsw-alias-label-tertiary, #8b93a1)",
|
|
1276
|
-
borderTop: "1px dashed var(--dsw-alias-border-l2, #e5e7eb)"
|
|
1277
|
-
},
|
|
1278
|
-
children: "匹配项较多,已限制展示前 150 项以保证流畅度,请输入更详细关键字"
|
|
1279
|
-
})]
|
|
1362
|
+
}, item.path))
|
|
1280
1363
|
})]
|
|
1281
1364
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1282
1365
|
className: "dsh-files-tree",
|
|
1283
1366
|
children: [isSearchActive && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1284
1367
|
className: "dsh-files-search-header",
|
|
1285
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1368
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1286
1369
|
className: "dsh-files-search-count",
|
|
1287
|
-
children:
|
|
1370
|
+
children: [
|
|
1371
|
+
"树形匹配(共 ",
|
|
1372
|
+
visibleFlatRows.length,
|
|
1373
|
+
" 项)"
|
|
1374
|
+
]
|
|
1288
1375
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1289
1376
|
type: "button",
|
|
1290
1377
|
className: "dsh-files-view-toggle-btn",
|
|
@@ -1292,27 +1379,16 @@ window.__ModuleLoader__.load({
|
|
|
1292
1379
|
title: "切换为扁平搜索结果列表",
|
|
1293
1380
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconList, { size: 12 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "切为列表" })]
|
|
1294
1381
|
})]
|
|
1295
|
-
}),
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
isSearchMode: isSearchActive,
|
|
1300
|
-
expandedPaths: isSearchActive ? searchExpandedPaths : expandedPaths,
|
|
1301
|
-
onToggleExpand: (path) => {
|
|
1302
|
-
if (isSearchActive) setSearchExpandedPaths((prev) => {
|
|
1303
|
-
const next = new Set(prev);
|
|
1304
|
-
if (next.has(path)) next.delete(path);
|
|
1305
|
-
else next.add(path);
|
|
1306
|
-
return next;
|
|
1307
|
-
});
|
|
1308
|
-
else handleToggleExpand(path);
|
|
1309
|
-
},
|
|
1382
|
+
}), visibleFlatRows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FileTreeRow, {
|
|
1383
|
+
row,
|
|
1384
|
+
query: deferredQuery,
|
|
1385
|
+
onToggleExpand: handleToggleExpand,
|
|
1310
1386
|
onOpenFile,
|
|
1311
1387
|
onMention: handleMention,
|
|
1312
|
-
onCopyPath: handleCopyPath,
|
|
1313
1388
|
onRevealInExplorer: handleRevealInExplorer,
|
|
1314
|
-
onOpenDefaultApp: handleOpenDefaultApp
|
|
1315
|
-
|
|
1389
|
+
onOpenDefaultApp: handleOpenDefaultApp,
|
|
1390
|
+
onCopyPath: handleCopyPath
|
|
1391
|
+
}, row.id))]
|
|
1316
1392
|
})
|
|
1317
1393
|
}),
|
|
1318
1394
|
toast && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1322,120 +1398,101 @@ window.__ModuleLoader__.load({
|
|
|
1322
1398
|
]
|
|
1323
1399
|
});
|
|
1324
1400
|
}
|
|
1325
|
-
function
|
|
1326
|
-
const {
|
|
1327
|
-
const
|
|
1328
|
-
if (
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1401
|
+
const FileTreeRow = (0, react.memo)(function FileTreeRow(props) {
|
|
1402
|
+
const { row, query, onToggleExpand, onOpenFile, onMention, onRevealInExplorer, onOpenDefaultApp, onCopyPath } = props;
|
|
1403
|
+
const indentPx = row.depth * 14 + 8;
|
|
1404
|
+
if (row.isDirectory) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1405
|
+
className: "dsh-files-dir-row",
|
|
1406
|
+
"data-tree-path": row.path,
|
|
1407
|
+
style: { paddingLeft: `${indentPx}px` },
|
|
1408
|
+
onClick: () => onToggleExpand(row.path),
|
|
1409
|
+
children: [
|
|
1410
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1411
|
+
className: `dsh-files-chevron-wrap ${row.isExpanded ? "is-expanded" : ""}`,
|
|
1412
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronRight, { size: 11 })
|
|
1413
|
+
}),
|
|
1414
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1415
|
+
className: "dsh-files-folder-icon",
|
|
1416
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconFolder, {
|
|
1417
|
+
size: 14,
|
|
1418
|
+
open: row.isExpanded
|
|
1419
|
+
})
|
|
1420
|
+
}),
|
|
1421
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1422
|
+
className: "dsh-files-folder-name",
|
|
1423
|
+
title: row.path,
|
|
1424
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HighlightText, {
|
|
1425
|
+
text: row.name,
|
|
1426
|
+
query
|
|
1427
|
+
})
|
|
1428
|
+
}),
|
|
1429
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1430
|
+
className: "dsh-files-count-badge",
|
|
1431
|
+
children: row.childCount
|
|
1432
|
+
}),
|
|
1433
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1434
|
+
className: "dsh-files-row-actions",
|
|
1337
1435
|
children: [
|
|
1338
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1339
|
-
|
|
1340
|
-
"
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
open: isExpanded
|
|
1348
|
-
})
|
|
1436
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1437
|
+
type: "button",
|
|
1438
|
+
className: "dsh-files-action-btn dsh-files-action-at",
|
|
1439
|
+
onClick: (e) => onMention(e, row.item),
|
|
1440
|
+
title: "一键 @ 引用此目录到会话",
|
|
1441
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconAt, { size: 12 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1442
|
+
className: "dsh-files-action-at-text",
|
|
1443
|
+
children: "@引用"
|
|
1444
|
+
})]
|
|
1349
1445
|
}),
|
|
1350
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
})
|
|
1446
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1447
|
+
type: "button",
|
|
1448
|
+
className: "dsh-files-action-btn",
|
|
1449
|
+
onClick: (e) => onRevealInExplorer(e, row.item),
|
|
1450
|
+
title: "在文件资源管理器中打开此目录",
|
|
1451
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconExplorer, { size: 12 })
|
|
1357
1452
|
}),
|
|
1358
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
1359
|
-
|
|
1360
|
-
|
|
1453
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1454
|
+
type: "button",
|
|
1455
|
+
className: "dsh-files-action-btn",
|
|
1456
|
+
onClick: (e) => onOpenDefaultApp(e, row.item),
|
|
1457
|
+
title: "用系统默认应用打开此目录",
|
|
1458
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconExternalApp, { size: 12 })
|
|
1361
1459
|
}),
|
|
1362
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
onClick: (e) => onMention(e, item),
|
|
1369
|
-
title: "一键 @ 引用此目录到当前会话",
|
|
1370
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconAt, { size: 13 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1371
|
-
className: "dsh-files-action-at-text",
|
|
1372
|
-
children: "@引用"
|
|
1373
|
-
})]
|
|
1374
|
-
}),
|
|
1375
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1376
|
-
type: "button",
|
|
1377
|
-
className: "dsh-files-action-btn",
|
|
1378
|
-
onClick: (e) => onRevealInExplorer(e, item),
|
|
1379
|
-
title: "在文件资源管理器中打开此目录",
|
|
1380
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconExplorer, { size: 12 })
|
|
1381
|
-
}),
|
|
1382
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1383
|
-
type: "button",
|
|
1384
|
-
className: "dsh-files-action-btn",
|
|
1385
|
-
onClick: (e) => onOpenDefaultApp(e, item),
|
|
1386
|
-
title: "用系统默认应用打开此目录",
|
|
1387
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconExternalApp, { size: 12 })
|
|
1388
|
-
}),
|
|
1389
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1390
|
-
type: "button",
|
|
1391
|
-
className: "dsh-files-action-btn",
|
|
1392
|
-
onClick: (e) => onCopyPath(e, item.path),
|
|
1393
|
-
title: "复制目录路径",
|
|
1394
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCopy, { size: 12 })
|
|
1395
|
-
})
|
|
1396
|
-
]
|
|
1460
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1461
|
+
type: "button",
|
|
1462
|
+
className: "dsh-files-action-btn",
|
|
1463
|
+
onClick: (e) => onCopyPath(e, row.path),
|
|
1464
|
+
title: "复制目录路径",
|
|
1465
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCopy, { size: 12 })
|
|
1397
1466
|
})
|
|
1398
1467
|
]
|
|
1399
|
-
})
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
item: child,
|
|
1403
|
-
depth: depth + 1,
|
|
1404
|
-
query,
|
|
1405
|
-
isSearchMode,
|
|
1406
|
-
expandedPaths,
|
|
1407
|
-
onToggleExpand,
|
|
1408
|
-
onOpenFile,
|
|
1409
|
-
onMention,
|
|
1410
|
-
onCopyPath,
|
|
1411
|
-
onRevealInExplorer,
|
|
1412
|
-
onOpenDefaultApp
|
|
1413
|
-
}, child.path))
|
|
1414
|
-
})]
|
|
1415
|
-
});
|
|
1416
|
-
}
|
|
1468
|
+
})
|
|
1469
|
+
]
|
|
1470
|
+
});
|
|
1417
1471
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1418
1472
|
className: "dsh-files-row",
|
|
1419
|
-
"data-tree-path":
|
|
1420
|
-
style: { paddingLeft: `${
|
|
1421
|
-
onClick: () => onOpenFile(
|
|
1422
|
-
title:
|
|
1473
|
+
"data-tree-path": row.path,
|
|
1474
|
+
style: { paddingLeft: `${indentPx}px` },
|
|
1475
|
+
onClick: () => onOpenFile(row.path),
|
|
1476
|
+
title: `点击打开文件: ${row.path}`,
|
|
1423
1477
|
children: [
|
|
1424
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1425
|
-
|
|
1426
|
-
|
|
1478
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1479
|
+
className: "dsh-files-file-glyph",
|
|
1480
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FileGlyphIcon, {
|
|
1481
|
+
filename: row.name,
|
|
1482
|
+
size: 14
|
|
1483
|
+
})
|
|
1427
1484
|
}),
|
|
1428
1485
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1429
1486
|
className: "dsh-files-name",
|
|
1430
1487
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HighlightText, {
|
|
1431
|
-
text:
|
|
1488
|
+
text: row.name,
|
|
1432
1489
|
query
|
|
1433
1490
|
})
|
|
1434
1491
|
}),
|
|
1435
|
-
|
|
1492
|
+
row.size !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1436
1493
|
className: "dsh-files-size",
|
|
1437
|
-
title: `大小: ${
|
|
1438
|
-
children: formatFileSize(
|
|
1494
|
+
title: `大小: ${row.size} 字节`,
|
|
1495
|
+
children: formatFileSize(row.size)
|
|
1439
1496
|
}),
|
|
1440
1497
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1441
1498
|
className: "dsh-files-row-actions",
|
|
@@ -1443,9 +1500,9 @@ window.__ModuleLoader__.load({
|
|
|
1443
1500
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1444
1501
|
type: "button",
|
|
1445
1502
|
className: "dsh-files-action-btn dsh-files-action-at",
|
|
1446
|
-
onClick: (e) => onMention(e, item),
|
|
1447
|
-
title: "一键 @
|
|
1448
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconAt, { size:
|
|
1503
|
+
onClick: (e) => onMention(e, row.item),
|
|
1504
|
+
title: "一键 @ 引用此文件到会话",
|
|
1505
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconAt, { size: 12 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1449
1506
|
className: "dsh-files-action-at-text",
|
|
1450
1507
|
children: "@引用"
|
|
1451
1508
|
})]
|
|
@@ -1453,21 +1510,21 @@ window.__ModuleLoader__.load({
|
|
|
1453
1510
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1454
1511
|
type: "button",
|
|
1455
1512
|
className: "dsh-files-action-btn",
|
|
1456
|
-
onClick: (e) => onRevealInExplorer(e, item),
|
|
1457
|
-
title: "
|
|
1513
|
+
onClick: (e) => onRevealInExplorer(e, row.item),
|
|
1514
|
+
title: "在文件资源管理器中定位",
|
|
1458
1515
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconExplorer, { size: 12 })
|
|
1459
1516
|
}),
|
|
1460
1517
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1461
1518
|
type: "button",
|
|
1462
1519
|
className: "dsh-files-action-btn",
|
|
1463
|
-
onClick: (e) => onOpenDefaultApp(e, item),
|
|
1464
|
-
title: "
|
|
1520
|
+
onClick: (e) => onOpenDefaultApp(e, row.item),
|
|
1521
|
+
title: "用系统默认应用打开",
|
|
1465
1522
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconExternalApp, { size: 12 })
|
|
1466
1523
|
}),
|
|
1467
1524
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1468
1525
|
type: "button",
|
|
1469
1526
|
className: "dsh-files-action-btn",
|
|
1470
|
-
onClick: (e) => onCopyPath(e,
|
|
1527
|
+
onClick: (e) => onCopyPath(e, row.path),
|
|
1471
1528
|
title: "复制相对路径",
|
|
1472
1529
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCopy, { size: 12 })
|
|
1473
1530
|
})
|
|
@@ -1475,15 +1532,16 @@ window.__ModuleLoader__.load({
|
|
|
1475
1532
|
})
|
|
1476
1533
|
]
|
|
1477
1534
|
});
|
|
1478
|
-
}
|
|
1535
|
+
}, (prev, next) => {
|
|
1536
|
+
return prev.row.id === next.row.id && prev.row.isExpanded === next.row.isExpanded && prev.row.depth === next.row.depth && prev.row.childCount === next.row.childCount && prev.query === next.query;
|
|
1537
|
+
});
|
|
1479
1538
|
function HighlightText({ text, query }) {
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
const index = text.toLowerCase().indexOf(q);
|
|
1539
|
+
if (!query) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: text });
|
|
1540
|
+
const index = text.toLowerCase().indexOf(query);
|
|
1483
1541
|
if (index === -1) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: text });
|
|
1484
1542
|
const before = text.slice(0, index);
|
|
1485
|
-
const match = text.slice(index, index +
|
|
1486
|
-
const after = text.slice(index +
|
|
1543
|
+
const match = text.slice(index, index + query.length);
|
|
1544
|
+
const after = text.slice(index + query.length);
|
|
1487
1545
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
1488
1546
|
before,
|
|
1489
1547
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("mark", {
|
|
@@ -1499,12 +1557,6 @@ window.__ModuleLoader__.load({
|
|
|
1499
1557
|
if (kb < 1024) return `${kb.toFixed(1)} KB`;
|
|
1500
1558
|
return `${(kb / 1024).toFixed(1)} MB`;
|
|
1501
1559
|
}
|
|
1502
|
-
/**
|
|
1503
|
-
* 按照 DSH 官方规范格式化引用路径:
|
|
1504
|
-
* - 纯路径无空格:@path
|
|
1505
|
-
* - 路径含空格:@"path"
|
|
1506
|
-
* - 目录末尾保留斜杠:@folder/ 或 @"folder/"
|
|
1507
|
-
*/
|
|
1508
1560
|
function formatMentionText(path, isDirectory = false) {
|
|
1509
1561
|
const cleanPath = path.replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
1510
1562
|
const finalPath = isDirectory ? cleanPath.endsWith("/") ? cleanPath : `${cleanPath}/` : cleanPath;
|
|
@@ -1530,9 +1582,6 @@ window.__ModuleLoader__.load({
|
|
|
1530
1582
|
window.localStorage.setItem(getStorageKey(workspaceRoot), JSON.stringify(Array.from(paths)));
|
|
1531
1583
|
} catch {}
|
|
1532
1584
|
}
|
|
1533
|
-
/**
|
|
1534
|
-
* 从当前 DOM 的 React Fiber 树或 Cordis RootContext 中提取当前活跃输入框的 SessionInputShell 实例
|
|
1535
|
-
*/
|
|
1536
1585
|
function findComposerShell(ctx, sessionId) {
|
|
1537
1586
|
try {
|
|
1538
1587
|
const composerDom = document.querySelector("[data-composer-input=\"true\"], [data-composer-input], [data-composer-card], div[role=\"textbox\"][contenteditable=\"true\"]");
|
|
@@ -1552,9 +1601,7 @@ window.__ModuleLoader__.load({
|
|
|
1552
1601
|
}
|
|
1553
1602
|
}
|
|
1554
1603
|
}
|
|
1555
|
-
} catch
|
|
1556
|
-
console.debug("[dsh-workspace-files] 从 Fiber 查找 keyboard 失败:", e);
|
|
1557
|
-
}
|
|
1604
|
+
} catch {}
|
|
1558
1605
|
if (ctx) try {
|
|
1559
1606
|
const root = ctx.root || ctx;
|
|
1560
1607
|
const inputService = (root.conversation || root.get?.("conversation") || window.__dsh_conversation)?.input || root["conversation.input"] || root.get?.("conversation.input");
|
|
@@ -1568,14 +1615,9 @@ window.__ModuleLoader__.load({
|
|
|
1568
1615
|
return values[values.length - 1];
|
|
1569
1616
|
}
|
|
1570
1617
|
}
|
|
1571
|
-
} catch
|
|
1572
|
-
console.debug("[dsh-workspace-files] 从 RootContext 查找 shell 失败:", e);
|
|
1573
|
-
}
|
|
1618
|
+
} catch {}
|
|
1574
1619
|
return null;
|
|
1575
1620
|
}
|
|
1576
|
-
/**
|
|
1577
|
-
* 尝试向会话输入框插入原生的 ReferenceChipNode(官方胶囊 Tag 卡片)
|
|
1578
|
-
*/
|
|
1579
1621
|
function tryInsertNativeReferenceChip(ctx, sessionId, item) {
|
|
1580
1622
|
if (typeof document === "undefined") return false;
|
|
1581
1623
|
try {
|
|
@@ -1612,16 +1654,9 @@ window.__ModuleLoader__.load({
|
|
|
1612
1654
|
span
|
|
1613
1655
|
}) === true) return true;
|
|
1614
1656
|
}
|
|
1615
|
-
} catch
|
|
1616
|
-
console.debug("[dsh-workspace-files] 插入原生 Chip 异常:", err);
|
|
1617
|
-
}
|
|
1657
|
+
} catch {}
|
|
1618
1658
|
return false;
|
|
1619
1659
|
}
|
|
1620
|
-
/**
|
|
1621
|
-
* 将引用文本注入到 DSH 当前会话的主输入框。
|
|
1622
|
-
* 兼容 DSH 官方基于 Lexical 的 ComposerContentEditable (div[data-composer-input])
|
|
1623
|
-
* 以及传统的 textarea / input,并自动消除用户手动输入的冗余 '@'。
|
|
1624
|
-
*/
|
|
1625
1660
|
function insertMentionToComposer(mentionText) {
|
|
1626
1661
|
if (typeof document === "undefined") return false;
|
|
1627
1662
|
const target = [
|
|
@@ -1722,16 +1757,21 @@ window.__ModuleLoader__.load({
|
|
|
1722
1757
|
if (!response.ok || envelope?.ok !== true || envelope.value === void 0) throw new Error(envelope?.error?.message ?? `HTTP ${response.status}`);
|
|
1723
1758
|
return envelope.value;
|
|
1724
1759
|
}
|
|
1725
|
-
function
|
|
1726
|
-
|
|
1760
|
+
function ensureFilesStyle() {
|
|
1761
|
+
if (typeof document === "undefined") return;
|
|
1762
|
+
const id = "dsh-workspace-files-core-style";
|
|
1763
|
+
if (document.getElementById(id)) return;
|
|
1764
|
+
const style = document.createElement("style");
|
|
1765
|
+
style.id = id;
|
|
1766
|
+
style.textContent = `
|
|
1727
1767
|
.dsh-files-root {
|
|
1728
1768
|
display: flex;
|
|
1729
1769
|
flex-direction: column;
|
|
1730
1770
|
height: 100%;
|
|
1731
1771
|
min-height: 0;
|
|
1732
1772
|
box-sizing: border-box;
|
|
1733
|
-
background: var(--dsw-alias-
|
|
1734
|
-
color: var(--dsw-alias-label-primary
|
|
1773
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
1774
|
+
color: var(--dsw-alias-label-primary);
|
|
1735
1775
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
1736
1776
|
font-size: 12px;
|
|
1737
1777
|
line-height: 1.4;
|
|
@@ -1747,7 +1787,8 @@ window.__ModuleLoader__.load({
|
|
|
1747
1787
|
justify-content: space-between;
|
|
1748
1788
|
gap: 8px;
|
|
1749
1789
|
padding: 8px 12px;
|
|
1750
|
-
border-bottom:
|
|
1790
|
+
border-bottom: 0.5px solid var(--dsw-alias-border-l1);
|
|
1791
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
1751
1792
|
}
|
|
1752
1793
|
.dsh-files-header-info {
|
|
1753
1794
|
flex: 1;
|
|
@@ -1761,33 +1802,34 @@ window.__ModuleLoader__.load({
|
|
|
1761
1802
|
.dsh-files-title {
|
|
1762
1803
|
font-weight: 600;
|
|
1763
1804
|
font-size: 13px;
|
|
1764
|
-
color: var(--dsw-alias-label-primary
|
|
1805
|
+
color: var(--dsw-alias-label-primary);
|
|
1765
1806
|
}
|
|
1766
1807
|
.dsh-files-stats-badge {
|
|
1767
1808
|
font-size: 10px;
|
|
1768
1809
|
font-weight: 500;
|
|
1769
|
-
color: var(--dsw-alias-label-tertiary
|
|
1770
|
-
background: var(--dsw-alias-
|
|
1771
|
-
padding: 1px
|
|
1810
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1811
|
+
background: color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);
|
|
1812
|
+
padding: 1px 7px;
|
|
1772
1813
|
border-radius: 99px;
|
|
1773
1814
|
}
|
|
1774
1815
|
.dsh-files-root-path {
|
|
1775
1816
|
font-size: 11px;
|
|
1776
|
-
color: var(--dsw-alias-label-tertiary
|
|
1817
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1777
1818
|
overflow: hidden;
|
|
1778
1819
|
text-overflow: ellipsis;
|
|
1779
1820
|
white-space: nowrap;
|
|
1780
|
-
margin-top:
|
|
1821
|
+
margin-top: 2px;
|
|
1781
1822
|
}
|
|
1782
1823
|
|
|
1783
|
-
/* ── Toolbar &
|
|
1824
|
+
/* ── Toolbar & Pure White Input ── */
|
|
1784
1825
|
.dsh-files-toolbar {
|
|
1785
1826
|
display: flex;
|
|
1786
1827
|
align-items: center;
|
|
1787
1828
|
gap: 6px;
|
|
1788
|
-
padding: 6px
|
|
1789
|
-
border-bottom:
|
|
1790
|
-
background: var(--dsw-alias-
|
|
1829
|
+
padding: 6px 10px;
|
|
1830
|
+
border-bottom: 0.5px solid var(--dsw-alias-border-l2);
|
|
1831
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
1832
|
+
flex-shrink: 0;
|
|
1791
1833
|
}
|
|
1792
1834
|
.dsh-files-search-wrap {
|
|
1793
1835
|
position: relative;
|
|
@@ -1798,70 +1840,77 @@ window.__ModuleLoader__.load({
|
|
|
1798
1840
|
}
|
|
1799
1841
|
.dsh-files-search-icon {
|
|
1800
1842
|
position: absolute;
|
|
1801
|
-
left:
|
|
1802
|
-
color: var(--dsw-alias-label-tertiary
|
|
1843
|
+
left: 8px;
|
|
1844
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1803
1845
|
pointer-events: none;
|
|
1804
1846
|
display: flex;
|
|
1805
1847
|
}
|
|
1806
1848
|
.dsh-files-search-input {
|
|
1807
1849
|
box-sizing: border-box;
|
|
1808
1850
|
width: 100%;
|
|
1809
|
-
height:
|
|
1810
|
-
padding: 0
|
|
1811
|
-
border:
|
|
1812
|
-
border-radius:
|
|
1813
|
-
background: var(--dsw-alias-
|
|
1814
|
-
color:
|
|
1815
|
-
font-size:
|
|
1851
|
+
height: 28px;
|
|
1852
|
+
padding: 0 24px 0 28px;
|
|
1853
|
+
border: 0.5px solid var(--dsw-alias-border-l1);
|
|
1854
|
+
border-radius: var(--dsw-radius-sm, 6px);
|
|
1855
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
1856
|
+
color: var(--dsw-alias-label-primary);
|
|
1857
|
+
font-size: 11px;
|
|
1816
1858
|
outline: none;
|
|
1817
|
-
transition:
|
|
1859
|
+
transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
|
|
1818
1860
|
}
|
|
1819
1861
|
.dsh-files-search-input:focus {
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-
|
|
1862
|
+
border-color: var(--dsw-alias-state-business-primary);
|
|
1863
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
1864
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary) 18%, transparent);
|
|
1823
1865
|
}
|
|
1824
1866
|
.dsh-files-clear-btn {
|
|
1825
1867
|
position: absolute;
|
|
1826
|
-
right:
|
|
1868
|
+
right: 6px;
|
|
1827
1869
|
border: none;
|
|
1828
1870
|
background: transparent;
|
|
1829
|
-
color: var(--dsw-alias-label-tertiary
|
|
1871
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1830
1872
|
cursor: pointer;
|
|
1831
1873
|
padding: 2px;
|
|
1832
1874
|
display: flex;
|
|
1875
|
+
border-radius: 50%;
|
|
1876
|
+
transition: all 0.12s ease;
|
|
1833
1877
|
}
|
|
1834
1878
|
.dsh-files-clear-btn:hover {
|
|
1835
|
-
color: var(--dsw-alias-label-primary
|
|
1879
|
+
color: var(--dsw-alias-label-primary);
|
|
1880
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
1836
1881
|
}
|
|
1837
1882
|
.dsh-files-toolbar-btns {
|
|
1838
1883
|
display: flex;
|
|
1839
1884
|
align-items: center;
|
|
1840
1885
|
gap: 2px;
|
|
1886
|
+
flex-shrink: 0;
|
|
1841
1887
|
}
|
|
1842
1888
|
.dsh-files-tool-btn {
|
|
1843
1889
|
display: inline-flex;
|
|
1844
1890
|
align-items: center;
|
|
1845
1891
|
justify-content: center;
|
|
1846
|
-
width:
|
|
1847
|
-
height:
|
|
1892
|
+
width: 26px;
|
|
1893
|
+
height: 26px;
|
|
1848
1894
|
border: none;
|
|
1849
|
-
border-radius: 4px;
|
|
1895
|
+
border-radius: var(--dsw-radius-xs, 4px);
|
|
1850
1896
|
background: transparent;
|
|
1851
|
-
color: var(--dsw-alias-label-secondary
|
|
1897
|
+
color: var(--dsw-alias-label-secondary);
|
|
1852
1898
|
cursor: pointer;
|
|
1853
|
-
transition: all 0.
|
|
1899
|
+
transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
|
|
1854
1900
|
}
|
|
1855
1901
|
.dsh-files-tool-btn:hover:not(:disabled) {
|
|
1856
|
-
color: var(--dsw-alias-label-primary
|
|
1857
|
-
background: var(--dsw-alias-interactive-bg-hover
|
|
1902
|
+
color: var(--dsw-alias-label-primary);
|
|
1903
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
1904
|
+
}
|
|
1905
|
+
.dsh-files-tool-btn:active:not(:disabled) {
|
|
1906
|
+
transform: scale(0.94);
|
|
1858
1907
|
}
|
|
1859
1908
|
.dsh-files-tool-btn.is-active {
|
|
1860
|
-
color: var(--dsw-alias-
|
|
1861
|
-
background: var(--dsw-alias-
|
|
1909
|
+
color: var(--dsw-alias-state-business-primary);
|
|
1910
|
+
background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 14%, transparent);
|
|
1862
1911
|
}
|
|
1863
1912
|
.dsh-files-tool-btn:disabled {
|
|
1864
|
-
opacity: 0.
|
|
1913
|
+
opacity: 0.35;
|
|
1865
1914
|
cursor: not-allowed;
|
|
1866
1915
|
}
|
|
1867
1916
|
|
|
@@ -1873,10 +1922,8 @@ window.__ModuleLoader__.load({
|
|
|
1873
1922
|
overflow-x: hidden;
|
|
1874
1923
|
padding: 4px 0;
|
|
1875
1924
|
}
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
flex-direction: column;
|
|
1879
|
-
}
|
|
1925
|
+
|
|
1926
|
+
/* ── Directory Row (with Motion Chevron) ── */
|
|
1880
1927
|
.dsh-files-dir-row {
|
|
1881
1928
|
display: flex;
|
|
1882
1929
|
align-items: center;
|
|
@@ -1886,29 +1933,35 @@ window.__ModuleLoader__.load({
|
|
|
1886
1933
|
cursor: pointer;
|
|
1887
1934
|
user-select: none;
|
|
1888
1935
|
position: relative;
|
|
1889
|
-
color: var(--dsw-alias-label-
|
|
1936
|
+
color: var(--dsw-alias-label-primary);
|
|
1937
|
+
border-radius: var(--dsw-radius-xs, 4px);
|
|
1938
|
+
margin: 0 4px;
|
|
1890
1939
|
transition: background 0.12s ease;
|
|
1891
1940
|
}
|
|
1892
1941
|
.dsh-files-dir-row:hover {
|
|
1893
|
-
background: var(--dsw-alias-interactive-bg-hover
|
|
1894
|
-
color: var(--dsw-alias-label-primary, inherit);
|
|
1942
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
1895
1943
|
}
|
|
1896
|
-
.dsh-files-chevron {
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
display: inline-
|
|
1900
|
-
|
|
1944
|
+
.dsh-files-chevron-wrap {
|
|
1945
|
+
width: 12px;
|
|
1946
|
+
height: 12px;
|
|
1947
|
+
display: inline-flex;
|
|
1948
|
+
align-items: center;
|
|
1949
|
+
justify-content: center;
|
|
1950
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1951
|
+
transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
|
|
1952
|
+
flex-shrink: 0;
|
|
1901
1953
|
}
|
|
1902
|
-
.dsh-files-chevron
|
|
1903
|
-
transform: rotate(
|
|
1954
|
+
.dsh-files-chevron-wrap.is-expanded {
|
|
1955
|
+
transform: rotate(90deg);
|
|
1904
1956
|
}
|
|
1905
1957
|
.dsh-files-folder-icon {
|
|
1906
1958
|
display: flex;
|
|
1959
|
+
flex-shrink: 0;
|
|
1907
1960
|
}
|
|
1908
1961
|
.dsh-files-folder-name {
|
|
1909
1962
|
flex: 1;
|
|
1910
1963
|
min-width: 0;
|
|
1911
|
-
font-weight:
|
|
1964
|
+
font-weight: 550;
|
|
1912
1965
|
font-size: 12px;
|
|
1913
1966
|
overflow: hidden;
|
|
1914
1967
|
text-overflow: ellipsis;
|
|
@@ -1919,8 +1972,8 @@ window.__ModuleLoader__.load({
|
|
|
1919
1972
|
font-weight: 600;
|
|
1920
1973
|
padding: 0 5px;
|
|
1921
1974
|
border-radius: 99px;
|
|
1922
|
-
background: var(--dsw-alias-
|
|
1923
|
-
color: var(--dsw-alias-label-tertiary
|
|
1975
|
+
background: color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);
|
|
1976
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1924
1977
|
}
|
|
1925
1978
|
|
|
1926
1979
|
/* ── File Row ── */
|
|
@@ -1933,44 +1986,95 @@ window.__ModuleLoader__.load({
|
|
|
1933
1986
|
cursor: pointer;
|
|
1934
1987
|
user-select: none;
|
|
1935
1988
|
position: relative;
|
|
1989
|
+
border-radius: var(--dsw-radius-xs, 4px);
|
|
1990
|
+
margin: 0 4px;
|
|
1936
1991
|
transition: background 0.12s ease;
|
|
1937
1992
|
}
|
|
1938
1993
|
.dsh-files-row:hover {
|
|
1939
|
-
background: var(--dsw-alias-interactive-bg-hover
|
|
1994
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
1995
|
+
}
|
|
1996
|
+
.dsh-files-file-glyph {
|
|
1997
|
+
margin-left: 12px;
|
|
1998
|
+
display: inline-flex;
|
|
1999
|
+
align-items: center;
|
|
2000
|
+
justify-content: center;
|
|
1940
2001
|
}
|
|
1941
2002
|
.dsh-files-name {
|
|
1942
2003
|
flex: 1;
|
|
1943
2004
|
min-width: 0;
|
|
1944
2005
|
font-size: 12px;
|
|
1945
|
-
color: var(--dsw-alias-label-primary
|
|
2006
|
+
color: var(--dsw-alias-label-primary);
|
|
1946
2007
|
overflow: hidden;
|
|
1947
2008
|
text-overflow: ellipsis;
|
|
1948
2009
|
white-space: nowrap;
|
|
1949
2010
|
}
|
|
1950
2011
|
.dsh-files-size {
|
|
1951
2012
|
font-size: 10px;
|
|
1952
|
-
color: var(--dsw-alias-label-tertiary
|
|
2013
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1953
2014
|
flex-shrink: 0;
|
|
1954
2015
|
margin-right: 4px;
|
|
1955
2016
|
}
|
|
1956
2017
|
|
|
1957
|
-
/* ── Hover
|
|
2018
|
+
/* ── Micro-Interaction Hover Action Pills ── */
|
|
1958
2019
|
.dsh-files-row-actions {
|
|
1959
|
-
display:
|
|
2020
|
+
display: flex;
|
|
1960
2021
|
align-items: center;
|
|
1961
|
-
gap:
|
|
2022
|
+
gap: 2px;
|
|
1962
2023
|
flex-shrink: 0;
|
|
2024
|
+
opacity: 0;
|
|
2025
|
+
transform: translateX(4px);
|
|
2026
|
+
pointer-events: none;
|
|
2027
|
+
transition: opacity 0.15s cubic-bezier(0.16, 1, 0.3, 1), transform 0.15s cubic-bezier(0.16, 1, 0.3, 1);
|
|
2028
|
+
margin-left: auto;
|
|
1963
2029
|
}
|
|
1964
2030
|
.dsh-files-row:hover .dsh-files-row-actions,
|
|
1965
2031
|
.dsh-files-dir-row:hover .dsh-files-row-actions,
|
|
1966
2032
|
.dsh-files-flat-row:hover .dsh-files-row-actions {
|
|
1967
|
-
|
|
2033
|
+
opacity: 1;
|
|
2034
|
+
transform: translateX(0);
|
|
2035
|
+
pointer-events: auto;
|
|
1968
2036
|
}
|
|
1969
2037
|
.dsh-files-row:hover .dsh-files-size,
|
|
1970
2038
|
.dsh-files-dir-row:hover .dsh-files-count-badge,
|
|
1971
2039
|
.dsh-files-flat-row:hover .dsh-files-size {
|
|
1972
2040
|
display: none;
|
|
1973
2041
|
}
|
|
2042
|
+
.dsh-files-action-btn {
|
|
2043
|
+
display: inline-flex;
|
|
2044
|
+
align-items: center;
|
|
2045
|
+
justify-content: center;
|
|
2046
|
+
gap: 3px;
|
|
2047
|
+
height: 20px;
|
|
2048
|
+
padding: 0 5px;
|
|
2049
|
+
border: 0.5px solid var(--dsw-alias-border-l1);
|
|
2050
|
+
border-radius: var(--dsw-radius-xs, 3px);
|
|
2051
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
2052
|
+
color: var(--dsw-alias-label-secondary);
|
|
2053
|
+
cursor: pointer;
|
|
2054
|
+
transition: all 0.12s cubic-bezier(0.16, 1, 0.3, 1);
|
|
2055
|
+
}
|
|
2056
|
+
.dsh-files-action-btn:hover {
|
|
2057
|
+
color: var(--dsw-alias-label-primary);
|
|
2058
|
+
border-color: var(--dsw-alias-state-business-primary);
|
|
2059
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
2060
|
+
}
|
|
2061
|
+
.dsh-files-action-btn:active {
|
|
2062
|
+
transform: scale(0.92);
|
|
2063
|
+
}
|
|
2064
|
+
.dsh-files-action-at {
|
|
2065
|
+
color: var(--dsw-alias-state-business-primary);
|
|
2066
|
+
border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary) 35%, transparent);
|
|
2067
|
+
background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 8%, transparent);
|
|
2068
|
+
}
|
|
2069
|
+
.dsh-files-action-at:hover {
|
|
2070
|
+
color: var(--dsw-alias-label-primary-inverted, #ffffff);
|
|
2071
|
+
background: var(--dsw-alias-state-business-primary);
|
|
2072
|
+
border-color: var(--dsw-alias-state-business-primary);
|
|
2073
|
+
}
|
|
2074
|
+
.dsh-files-action-at-text {
|
|
2075
|
+
font-size: 10px;
|
|
2076
|
+
font-weight: 600;
|
|
2077
|
+
}
|
|
1974
2078
|
|
|
1975
2079
|
/* ── Flat Search Result List ── */
|
|
1976
2080
|
.dsh-files-search-container {
|
|
@@ -1983,9 +2087,9 @@ window.__ModuleLoader__.load({
|
|
|
1983
2087
|
justify-content: space-between;
|
|
1984
2088
|
padding: 6px 12px;
|
|
1985
2089
|
font-size: 11px;
|
|
1986
|
-
color: var(--dsw-alias-label-tertiary
|
|
1987
|
-
background: color-mix(in srgb, var(--dsw-alias-
|
|
1988
|
-
border-bottom:
|
|
2090
|
+
color: var(--dsw-alias-label-tertiary);
|
|
2091
|
+
background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 4%, transparent);
|
|
2092
|
+
border-bottom: 0.5px solid var(--dsw-alias-border-l2);
|
|
1989
2093
|
}
|
|
1990
2094
|
.dsh-files-search-count {
|
|
1991
2095
|
font-weight: 500;
|
|
@@ -1994,20 +2098,20 @@ window.__ModuleLoader__.load({
|
|
|
1994
2098
|
display: inline-flex;
|
|
1995
2099
|
align-items: center;
|
|
1996
2100
|
gap: 4px;
|
|
1997
|
-
border:
|
|
1998
|
-
background: var(--dsw-alias-
|
|
1999
|
-
color: var(--dsw-alias-
|
|
2101
|
+
border: 0.5px solid var(--dsw-alias-border-l1);
|
|
2102
|
+
background: var(--dsw-alias-fill-base, #ffffff);
|
|
2103
|
+
color: var(--dsw-alias-state-business-primary);
|
|
2000
2104
|
cursor: pointer;
|
|
2001
2105
|
font-size: 10.5px;
|
|
2002
2106
|
font-weight: 500;
|
|
2003
2107
|
padding: 2px 7px;
|
|
2004
|
-
border-radius: 4px;
|
|
2005
|
-
transition: all 0.12s
|
|
2108
|
+
border-radius: var(--dsw-radius-xs, 4px);
|
|
2109
|
+
transition: all 0.12s cubic-bezier(0.16, 1, 0.3, 1);
|
|
2006
2110
|
}
|
|
2007
2111
|
.dsh-files-view-toggle-btn:hover {
|
|
2008
|
-
background: var(--dsw-alias-
|
|
2009
|
-
color: #ffffff;
|
|
2010
|
-
border-color: var(--dsw-alias-
|
|
2112
|
+
background: var(--dsw-alias-state-business-primary);
|
|
2113
|
+
color: var(--dsw-alias-label-primary-inverted, #ffffff);
|
|
2114
|
+
border-color: var(--dsw-alias-state-business-primary);
|
|
2011
2115
|
}
|
|
2012
2116
|
.dsh-files-flat-list {
|
|
2013
2117
|
padding: 4px 0;
|
|
@@ -2016,7 +2120,7 @@ window.__ModuleLoader__.load({
|
|
|
2016
2120
|
display: flex;
|
|
2017
2121
|
align-items: center;
|
|
2018
2122
|
gap: 8px;
|
|
2019
|
-
padding:
|
|
2123
|
+
padding: 5px 12px;
|
|
2020
2124
|
cursor: pointer;
|
|
2021
2125
|
user-select: none;
|
|
2022
2126
|
position: relative;
|
|
@@ -2024,7 +2128,7 @@ window.__ModuleLoader__.load({
|
|
|
2024
2128
|
min-height: 32px;
|
|
2025
2129
|
}
|
|
2026
2130
|
.dsh-files-flat-row:hover {
|
|
2027
|
-
background: var(--dsw-alias-interactive-bg-hover
|
|
2131
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
2028
2132
|
}
|
|
2029
2133
|
.dsh-files-flat-icon {
|
|
2030
2134
|
display: flex;
|
|
@@ -2048,22 +2152,21 @@ window.__ModuleLoader__.load({
|
|
|
2048
2152
|
.dsh-files-flat-name {
|
|
2049
2153
|
font-size: 12px;
|
|
2050
2154
|
font-weight: 500;
|
|
2051
|
-
color: var(--dsw-alias-label-primary
|
|
2155
|
+
color: var(--dsw-alias-label-primary);
|
|
2052
2156
|
overflow: hidden;
|
|
2053
2157
|
text-overflow: ellipsis;
|
|
2054
2158
|
white-space: nowrap;
|
|
2055
2159
|
}
|
|
2056
2160
|
.dsh-files-flat-parent {
|
|
2057
2161
|
font-size: 10.5px;
|
|
2058
|
-
color: var(--dsw-alias-label-tertiary
|
|
2162
|
+
color: var(--dsw-alias-label-tertiary);
|
|
2059
2163
|
overflow: hidden;
|
|
2060
2164
|
text-overflow: ellipsis;
|
|
2061
2165
|
white-space: nowrap;
|
|
2062
|
-
opacity: 0.8;
|
|
2063
2166
|
}
|
|
2064
2167
|
.dsh-files-jump-hint {
|
|
2065
2168
|
font-size: 10px;
|
|
2066
|
-
color: var(--dsw-alias-
|
|
2169
|
+
color: var(--dsw-alias-state-business-primary);
|
|
2067
2170
|
opacity: 0;
|
|
2068
2171
|
transition: opacity 0.12s ease;
|
|
2069
2172
|
margin-right: 6px;
|
|
@@ -2071,49 +2174,16 @@ window.__ModuleLoader__.load({
|
|
|
2071
2174
|
white-space: nowrap;
|
|
2072
2175
|
}
|
|
2073
2176
|
.dsh-files-flat-row:hover .dsh-files-jump-hint {
|
|
2074
|
-
opacity: 0.
|
|
2177
|
+
opacity: 0.9;
|
|
2075
2178
|
}
|
|
2076
2179
|
.dsh-files-flat-row.is-directory:hover {
|
|
2077
|
-
background: color-mix(in srgb, var(--dsw-alias-
|
|
2078
|
-
}
|
|
2079
|
-
.dsh-files-action-btn {
|
|
2080
|
-
display: inline-flex;
|
|
2081
|
-
align-items: center;
|
|
2082
|
-
justify-content: center;
|
|
2083
|
-
gap: 3px;
|
|
2084
|
-
height: 20px;
|
|
2085
|
-
padding: 0 5px;
|
|
2086
|
-
border: 1px solid var(--dsw-alias-border-l2, rgba(118,137,166,.25));
|
|
2087
|
-
border-radius: 3px;
|
|
2088
|
-
background: var(--dsw-alias-container-bg, var(--dsw-alias-bg-base, #ffffff));
|
|
2089
|
-
color: var(--dsw-alias-label-secondary, #6f7f9b);
|
|
2090
|
-
cursor: pointer;
|
|
2091
|
-
transition: all 0.12s ease;
|
|
2092
|
-
}
|
|
2093
|
-
.dsh-files-action-btn:hover {
|
|
2094
|
-
color: var(--dsw-alias-label-primary, inherit);
|
|
2095
|
-
border-color: var(--dsw-alias-border-l3, rgba(118,137,166,.4));
|
|
2096
|
-
background: var(--dsw-alias-interactive-bg-hover, rgba(100,120,150,.12));
|
|
2097
|
-
}
|
|
2098
|
-
.dsh-files-action-at {
|
|
2099
|
-
color: var(--dsw-alias-brand-primary, #4b70e2);
|
|
2100
|
-
border-color: color-mix(in srgb, var(--dsw-alias-brand-primary, #4b70e2) 30%, transparent);
|
|
2101
|
-
background: color-mix(in srgb, var(--dsw-alias-brand-primary, #4b70e2) 8%, transparent);
|
|
2102
|
-
}
|
|
2103
|
-
.dsh-files-action-at:hover {
|
|
2104
|
-
color: #ffffff;
|
|
2105
|
-
background: var(--dsw-alias-brand-primary, #4b70e2);
|
|
2106
|
-
border-color: var(--dsw-alias-brand-primary, #4b70e2);
|
|
2107
|
-
}
|
|
2108
|
-
.dsh-files-action-at-text {
|
|
2109
|
-
font-size: 10px;
|
|
2110
|
-
font-weight: 600;
|
|
2180
|
+
background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 8%, transparent);
|
|
2111
2181
|
}
|
|
2112
2182
|
|
|
2113
2183
|
/* ── Highlight & Toast ── */
|
|
2114
2184
|
.dsh-files-highlight {
|
|
2115
|
-
background: color-mix(in srgb, var(--dsw-alias-
|
|
2116
|
-
color: var(--dsw-alias-
|
|
2185
|
+
background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 22%, transparent);
|
|
2186
|
+
color: var(--dsw-alias-state-business-primary);
|
|
2117
2187
|
font-weight: 600;
|
|
2118
2188
|
border-radius: 2px;
|
|
2119
2189
|
padding: 0 1px;
|
|
@@ -2127,12 +2197,12 @@ window.__ModuleLoader__.load({
|
|
|
2127
2197
|
align-items: center;
|
|
2128
2198
|
gap: 6px;
|
|
2129
2199
|
padding: 6px 12px;
|
|
2130
|
-
background: var(--dsw-alias-label-primary
|
|
2131
|
-
color: var(--dsw-alias-
|
|
2200
|
+
background: var(--dsw-alias-label-primary);
|
|
2201
|
+
color: var(--dsw-alias-fill-base, #ffffff);
|
|
2132
2202
|
font-size: 11px;
|
|
2133
2203
|
border-radius: 99px;
|
|
2134
|
-
box-shadow: 0 4px 16px rgba(0,0,0
|
|
2135
|
-
animation: dsh-files-fade-in 0.
|
|
2204
|
+
box-shadow: 0 4px 16px rgba(0,0,0,0.22);
|
|
2205
|
+
animation: dsh-files-fade-in 0.16s cubic-bezier(0.16, 1, 0.3, 1);
|
|
2136
2206
|
z-index: 100;
|
|
2137
2207
|
pointer-events: none;
|
|
2138
2208
|
white-space: nowrap;
|
|
@@ -2150,13 +2220,13 @@ window.__ModuleLoader__.load({
|
|
|
2150
2220
|
justify-content: center;
|
|
2151
2221
|
height: 180px;
|
|
2152
2222
|
gap: 10px;
|
|
2153
|
-
color: var(--dsw-alias-label-secondary
|
|
2223
|
+
color: var(--dsw-alias-label-secondary);
|
|
2154
2224
|
}
|
|
2155
2225
|
.dsh-files-spinner {
|
|
2156
2226
|
width: 18px;
|
|
2157
2227
|
height: 18px;
|
|
2158
|
-
border: 2px solid var(--dsw-alias-border-
|
|
2159
|
-
border-top-color: var(--dsw-alias-
|
|
2228
|
+
border: 2px solid var(--dsw-alias-border-l1);
|
|
2229
|
+
border-top-color: var(--dsw-alias-state-business-primary);
|
|
2160
2230
|
border-radius: 50%;
|
|
2161
2231
|
animation: dsh-files-spin 0.8s linear infinite;
|
|
2162
2232
|
}
|
|
@@ -2170,7 +2240,7 @@ window.__ModuleLoader__.load({
|
|
|
2170
2240
|
justify-content: center;
|
|
2171
2241
|
padding: 36px 16px;
|
|
2172
2242
|
text-align: center;
|
|
2173
|
-
color: var(--dsw-alias-label-secondary
|
|
2243
|
+
color: var(--dsw-alias-label-secondary);
|
|
2174
2244
|
}
|
|
2175
2245
|
.dsh-files-empty-icon {
|
|
2176
2246
|
margin-bottom: 8px;
|
|
@@ -2183,7 +2253,7 @@ window.__ModuleLoader__.load({
|
|
|
2183
2253
|
}
|
|
2184
2254
|
.dsh-files-empty-detail {
|
|
2185
2255
|
font-size: 11.5px;
|
|
2186
|
-
color: var(--dsw-alias-label-tertiary
|
|
2256
|
+
color: var(--dsw-alias-label-tertiary);
|
|
2187
2257
|
}
|
|
2188
2258
|
.dsh-files-banner-error {
|
|
2189
2259
|
display: flex;
|
|
@@ -2192,9 +2262,9 @@ window.__ModuleLoader__.load({
|
|
|
2192
2262
|
gap: 8px;
|
|
2193
2263
|
padding: 6px 12px;
|
|
2194
2264
|
font-size: 11.5px;
|
|
2195
|
-
color: var(--dsw-alias-state-
|
|
2196
|
-
background: color-mix(in srgb, var(--dsw-alias-state-
|
|
2197
|
-
border-bottom:
|
|
2265
|
+
color: var(--dsw-alias-state-danger-primary, #e34c59);
|
|
2266
|
+
background: color-mix(in srgb, var(--dsw-alias-state-danger-primary, #e34c59) 10%, transparent);
|
|
2267
|
+
border-bottom: 0.5px solid var(--dsw-alias-border-l1);
|
|
2198
2268
|
}
|
|
2199
2269
|
.dsh-files-banner-close {
|
|
2200
2270
|
border: none;
|
|
@@ -2202,7 +2272,8 @@ window.__ModuleLoader__.load({
|
|
|
2202
2272
|
color: inherit;
|
|
2203
2273
|
cursor: pointer;
|
|
2204
2274
|
}
|
|
2205
|
-
|
|
2275
|
+
`;
|
|
2276
|
+
document.head.appendChild(style);
|
|
2206
2277
|
}
|
|
2207
2278
|
//#endregion
|
|
2208
2279
|
exports.WorkspaceFilesSettingsCard = WorkspaceFilesSettingsCard;
|