@weniatall/dsh-file-viewer 0.3.17 → 0.3.18
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 +2 -0
- package/lib/client.js +55 -14
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -94,6 +94,8 @@ dsh plugin --profile web add <release-tgz-url>
|
|
|
94
94
|
|
|
95
95
|
桌面端(Windows)抽屉会自动避让窗口右上角的原生标题栏按钮(最小化 / 最大化 / 关闭):宿主在 `<html>` 上标记 `data-windows-titlebar` 并给出 `--dsh-windows-titlebar-height`,抽屉顶部从其下方开始,因此标题栏里的图标不会再压在窗口按钮下面;窗口进入全屏后该条带消失,抽屉相应贴到顶边。
|
|
96
96
|
|
|
97
|
+
这条偏移带 `!important`:抽屉为退出宿主"居中卡片化"而声明的 `inset:0!important` 会展开出同样重要的 `top:0`,普通声明赢不过它——这正是该问题在 v0.3.6 之后复发的原因。现已由测试锁死层叠结果,规范见仓库根目录 `AGENTS.md` 的「桌面版兼容」一节。
|
|
98
|
+
|
|
97
99
|
## Git 面板
|
|
98
100
|
|
|
99
101
|
左侧栏顶部有两个页签:**文件**(目录树)与 **Git**(源代码管理)。Git 页签按 VSCode 源代码管理面板的方式组织:仓库 → 分支 → 提交记录 → 该提交的改动文件。
|
package/lib/client.js
CHANGED
|
@@ -443,8 +443,22 @@ window.__ModuleLoader__.load({
|
|
|
443
443
|
header controls could never be clicked. Start the drawer below the
|
|
444
444
|
strip instead, which also leaves the strip free to drag the window.
|
|
445
445
|
The host sets data-fullscreen while the window is fullscreen and the
|
|
446
|
-
strip is hidden, so the offset has to drop then.
|
|
447
|
-
|
|
446
|
+
strip is hidden, so the offset has to drop then.
|
|
447
|
+
|
|
448
|
+
The declaration carries !important on purpose. It is not defensive
|
|
449
|
+
padding: the drawer's own opt-out above neutralises the host's
|
|
450
|
+
modal-card treatment with an important inset, and the longhand top that
|
|
451
|
+
shorthand expands to outranks any normal declaration — including this
|
|
452
|
+
one. Without !important the strip wins and the drawer slides back under
|
|
453
|
+
the caption buttons, which is exactly the regression this rule was
|
|
454
|
+
written for (fixed in 0.2.8, broken again once 0.3.6 added the
|
|
455
|
+
important inset, because the guard test only checked that the rule
|
|
456
|
+
exists rather than that it wins the cascade).
|
|
457
|
+
|
|
458
|
+
The role="dialog" qualifier keeps this at least as specific as the inset
|
|
459
|
+
rule it has to beat, so the outcome is decided by the important flag and
|
|
460
|
+
the attribute count rather than by sheet order. */
|
|
461
|
+
html[data-windows-titlebar]:not([data-fullscreen]) .fv-scrim[role="dialog"]{top:var(--dsh-windows-titlebar-height,40px)!important}
|
|
448
462
|
@keyframes fv-fade{from{opacity:0}to{opacity:1}}
|
|
449
463
|
@keyframes fv-slide{from{transform:translateX(100%)}to{transform:translateX(0)}}
|
|
450
464
|
@media(prefers-reduced-motion:reduce){.fv-scrim,.fv-shell{animation:none}}
|
|
@@ -5656,18 +5670,16 @@ window.__ModuleLoader__.load({
|
|
|
5656
5670
|
treeGeneration.current += 1;
|
|
5657
5671
|
setNodes(new Map());
|
|
5658
5672
|
if (rootChanged) {
|
|
5659
|
-
//
|
|
5660
|
-
//
|
|
5661
|
-
// the
|
|
5662
|
-
//
|
|
5663
|
-
//
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
setTabMenu(null);
|
|
5673
|
+
// Only the tree is rebuilt here. Tabs are deliberately NOT touched:
|
|
5674
|
+
// this effect re-runs on the very commit that resolved `root`, i.e.
|
|
5675
|
+
// *after* the roots effect above has already cleared the previous
|
|
5676
|
+
// visit's tabs and opened the one the arrival path asked for.
|
|
5677
|
+
// Clearing them here wiped that brand-new tab, so the first click on
|
|
5678
|
+
// a file in a conversation (a path or a changes card) opened an empty
|
|
5679
|
+
// pane and only the second click — now that `treeBuiltForRef` and
|
|
5680
|
+
// `visitContextRef` both already name this root — loaded anything.
|
|
5681
|
+
// A root switched from the picker resets tabs in `chooseRoot`.
|
|
5669
5682
|
setExpanded(new Set());
|
|
5670
|
-
setPane("tree");
|
|
5671
5683
|
}
|
|
5672
5684
|
const chain = revealChanged && reveal !== "" ? [...ancestorsOf(reveal), reveal] : [];
|
|
5673
5685
|
if (chain.length > 0) {
|
|
@@ -5820,6 +5832,35 @@ window.__ModuleLoader__.load({
|
|
|
5820
5832
|
}
|
|
5821
5833
|
};
|
|
5822
5834
|
|
|
5835
|
+
/**
|
|
5836
|
+
* Switch the root from the header picker.
|
|
5837
|
+
*
|
|
5838
|
+
* A root switch is the one thing that invalidates every open tab: their
|
|
5839
|
+
* ids and paths only mean something inside the root that opened them, so
|
|
5840
|
+
* carrying them over would point at a different file with the same name.
|
|
5841
|
+
* The reset lives here, on the reader's own action, rather than in the
|
|
5842
|
+
* tree-building effect — that effect also re-runs on the commit that
|
|
5843
|
+
* resolves `root` for an arrival, and clearing there wiped the tab the
|
|
5844
|
+
* arrival had just opened (first click on a file did nothing, second one
|
|
5845
|
+
* worked because the guards had caught up by then).
|
|
5846
|
+
*/
|
|
5847
|
+
const chooseRoot = (next) => {
|
|
5848
|
+
const resolved = typeof next === "string" ? next : "";
|
|
5849
|
+
if (resolved === "" || resolved === root) return;
|
|
5850
|
+
tabsRef.current = null;
|
|
5851
|
+
setTabs(null);
|
|
5852
|
+
activeTabIdRef.current = "";
|
|
5853
|
+
setActiveTabId("");
|
|
5854
|
+
setTabMenu(null);
|
|
5855
|
+
setPane("tree");
|
|
5856
|
+
setExpanded(new Set());
|
|
5857
|
+
// The arrival context belongs to the root that is being left; naming it
|
|
5858
|
+
// here keeps the next roots response from treating the switch as an
|
|
5859
|
+
// arrival that has to be reset all over again.
|
|
5860
|
+
visitContextRef.current = resolved;
|
|
5861
|
+
setRoot(resolved);
|
|
5862
|
+
};
|
|
5863
|
+
|
|
5823
5864
|
/** Patch one tab by id. Used by asynchronous reads that outlive a switch. */
|
|
5824
5865
|
const patchTab = (id, mutator) => {
|
|
5825
5866
|
const current = tabList();
|
|
@@ -6332,7 +6373,7 @@ window.__ModuleLoader__.load({
|
|
|
6332
6373
|
className: "fv-root-select",
|
|
6333
6374
|
value: root,
|
|
6334
6375
|
"aria-label": "工作区与安全路径",
|
|
6335
|
-
onChange: (event) =>
|
|
6376
|
+
onChange: (event) => chooseRoot(event.target.value),
|
|
6336
6377
|
}, ...renderRootOptions(roots))
|
|
6337
6378
|
: react.createElement("span", { className: "fv-crumbs" }, activeRoot ? activeRoot.label : ""),
|
|
6338
6379
|
// The tree shows structure, so the header carries the selected
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weniatall/dsh-file-viewer",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.18",
|
|
4
4
|
"description": "Workspace file viewer and Git panel for DeepSeek Harness: file tree, syntax-highlighted code, images, PDF, Excel and Word, plus local/remote branches, paged commit history, commit diffs, working-tree changes and changed-file navigation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -70,6 +70,11 @@
|
|
|
70
70
|
"engines": {
|
|
71
71
|
"node": ">=20.3"
|
|
72
72
|
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"jsdom": "29.1.1",
|
|
75
|
+
"react": "18.3.1",
|
|
76
|
+
"react-dom": "18.3.1"
|
|
77
|
+
},
|
|
73
78
|
"scripts": {
|
|
74
79
|
"test": "node --test test/*.test.mjs && node ../../scripts/check-host-settings.mjs plugins/dsh-file-viewer file-viewer"
|
|
75
80
|
}
|