@weniatall/dsh-file-viewer 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/client.js +111 -7
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -378,6 +378,10 @@ window.__ModuleLoader__.load({
378
378
  .fv-crumb:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
379
379
  .fv-crumb-sep{flex:none;opacity:.5}
380
380
  .fv-icon-button{display:inline-grid;flex:none;place-items:center;width:30px;height:30px;padding:0;border:none;border-radius:8px;background:none;color:var(--dsw-alias-label-secondary);cursor:pointer;transition:color .12s,background .12s;line-height:1}
381
+ /* A control with nowhere to go must look unavailable, not merely behave
382
+ that way — otherwise a disabled back button reads as broken. */
383
+ .fv-icon-button:disabled{opacity:.35;cursor:default}
384
+ .fv-icon-button:disabled:hover{background:none;color:var(--dsw-alias-label-secondary)}
381
385
  .fv-icon-button svg{display:block;flex:none}
382
386
  .fv-icon-button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
383
387
  .fv-icon-button[aria-pressed="true"]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
@@ -4032,6 +4036,22 @@ window.__ModuleLoader__.load({
4032
4036
  const [previewCommit, setPreviewCommit] = react.useState("");
4033
4037
  // Which half of the commit pane is showing: the file list or the patch.
4034
4038
  const [commitView, setCommitView] = react.useState("files");
4039
+ /**
4040
+ * What the main pane was showing before the current file preview.
4041
+ *
4042
+ * The back control has to undo exactly one step. Opening a file from a
4043
+ * commit's changed-file list must return to that list — not to the file
4044
+ * tree, which is a different place entirely — so the origin is recorded
4045
+ * when the file is opened rather than guessed when back is pressed.
4046
+ *
4047
+ * `null` means there is nowhere to go back to.
4048
+ * @type {"commit" | "changes" | null}
4049
+ */
4050
+ const [previewOrigin, setPreviewOrigin] = react.useState(null);
4051
+ // The working-tree change shown in the main pane. It cannot ride on the
4052
+ // commit detail, which is keyed by hash, and `meta` belongs to the file
4053
+ // preview — so the row the reader clicked is kept here.
4054
+ const [previewChangePath, setPreviewChangePath] = react.useState("");
4035
4055
  const gitState = useStore(git.store);
4036
4056
 
4037
4057
  react.useEffect(() => {
@@ -4189,6 +4209,19 @@ window.__ModuleLoader__.load({
4189
4209
  react.useEffect(() => {
4190
4210
  if (request_ === null) return undefined;
4191
4211
  let live = true;
4212
+ // The drawer stays mounted while closed (`open` only gates rendering),
4213
+ // so every view state survives from the previous visit. Opening a
4214
+ // plain file after browsing Git used to inherit the old commit hash
4215
+ // and the Git sidebar, and the file rendered as "history preview"
4216
+ // instead of its content. A new open is a new session: clear it all.
4217
+ setSide("files");
4218
+ setShowCommit(false);
4219
+ setCommitView("files");
4220
+ setPreviewCommit("");
4221
+ setPreviewOrigin(null);
4222
+ setPreviewChangePath("");
4223
+ setMeta(null);
4224
+ setError(null);
4192
4225
  const payload = {
4193
4226
  ...(request_.sessionId !== undefined ? { sessionId: request_.sessionId } : {}),
4194
4227
  ...(request_.filePath !== undefined ? { filePath: request_.filePath } : {}),
@@ -4402,6 +4435,9 @@ window.__ModuleLoader__.load({
4402
4435
  setShowCommit(false);
4403
4436
  setPane("content");
4404
4437
  setPreviewCommit(readSha);
4438
+ // Back must return to the changed-file list this row came from,
4439
+ // not to the file tree, which is somewhere else entirely.
4440
+ setPreviewOrigin("commit");
4405
4441
  setLangChoice("auto");
4406
4442
  const ticket = metaTicket.current + 1;
4407
4443
  metaTicket.current = ticket;
@@ -4413,6 +4449,9 @@ window.__ModuleLoader__.load({
4413
4449
  // The blob path is what the host reads; the display path keeps the
4414
4450
  // row the reader clicked.
4415
4451
  path: blobPath,
4452
+ // A rename is read from its old path but highlighted as the row
4453
+ // the reader actually clicked.
4454
+ rowPath: file.path,
4416
4455
  name: baseNameOf(blobPath),
4417
4456
  displayPath: baseNameOf(blobPath) + " @ " + readSha.slice(0, 7),
4418
4457
  kind: component,
@@ -4431,6 +4470,44 @@ window.__ModuleLoader__.load({
4431
4470
  selectFile({ path: file.path, name: baseNameOf(file.path), type: "file" });
4432
4471
  };
4433
4472
 
4473
+ /**
4474
+ * Step back one place from the main pane.
4475
+ *
4476
+ * Three destinations, in the order the reader arrived from: a commit's
4477
+ * changed-file list, the working-tree change list, or the file tree.
4478
+ * Each step clears the state that belonged to the place being left, so
4479
+ * a stale hash or blob path cannot leak into the next preview.
4480
+ */
4481
+ const goBack = () => {
4482
+ if (previewOrigin === "commit") {
4483
+ // Re-open the changed-file view of the commit still in `detail`;
4484
+ // its hash is what the sidebar is highlighting.
4485
+ setShowCommit(true);
4486
+ setCommitView("files");
4487
+ setPreviewCommit("");
4488
+ setPreviewOrigin(null);
4489
+ setPane("content");
4490
+ return;
4491
+ }
4492
+ if (previewOrigin === "changes") {
4493
+ setShowCommit(true);
4494
+ setCommitView("changes");
4495
+ setPreviewCommit("");
4496
+ setPreviewOrigin(null);
4497
+ setPane("content");
4498
+ return;
4499
+ }
4500
+ // Nothing to undo inside the pane: hand control back to the sidebar.
4501
+ // On a phone that actually swaps panes; on desktop the tree is
4502
+ // already alongside, so the selection is cleared instead of the
4503
+ // button doing nothing at all.
4504
+ setPreviewCommit("");
4505
+ setPreviewOrigin(null);
4506
+ setMeta(null);
4507
+ setError(null);
4508
+ setPane("tree");
4509
+ };
4510
+
4434
4511
  /**
4435
4512
  * Open one working-tree change as a diff.
4436
4513
  *
@@ -4443,7 +4520,10 @@ window.__ModuleLoader__.load({
4443
4520
  setPane("content");
4444
4521
  setCommitView("changes");
4445
4522
  setPreviewCommit("");
4446
- void row;
4523
+ setPreviewOrigin(null);
4524
+ // The pane diffs exactly this path; ignoring the row left it reading
4525
+ // whatever file happened to be selected before.
4526
+ setPreviewChangePath(row.path);
4447
4527
  };
4448
4528
 
4449
4529
  // Clicking two files quickly must not let the slower answer win: only
@@ -4451,8 +4531,11 @@ window.__ModuleLoader__.load({
4451
4531
  const selectFile = (entry) => {
4452
4532
  setPane("content");
4453
4533
  // Selecting from the file tree is always the working tree, so any
4454
- // commit a preview was read from is dropped here.
4534
+ // commit a preview was read from is dropped here — and there is no
4535
+ // intermediate pane to return to.
4455
4536
  setPreviewCommit("");
4537
+ setPreviewOrigin(null);
4538
+ setPreviewChangePath("");
4456
4539
  // The remembered choice for this file takes effect immediately, so
4457
4540
  // the read that follows is already resolved with it.
4458
4541
  setLangChoice(readLangOverride(root, entry.path));
@@ -4712,9 +4795,28 @@ window.__ModuleLoader__.load({
4712
4795
  }),
4713
4796
  react.createElement("div", { className: "fv-main" },
4714
4797
  react.createElement("div", { className: "fv-main-head" },
4715
- react.createElement("button", {
4716
- type: "button", className: "fv-icon-button", "aria-label": "返回文件列表", onClick: () => setPane("tree"),
4717
- }, react.createElement("span", { "aria-hidden": "true" }, "‹")),
4798
+ (() => {
4799
+ // The control returns one step, so it names that step and
4800
+ // is disabled when there is nowhere to go — a button that
4801
+ // silently does nothing reads as broken.
4802
+ const backTarget = previewOrigin === "commit"
4803
+ ? "返回变更文件列表"
4804
+ : (previewOrigin === "changes" ? "返回工作区改动列表" : "返回文件列表");
4805
+ // On a phone the panes are exclusive, so leaving the content
4806
+ // pane is always meaningful; on desktop the sidebar is
4807
+ // already visible and only an origin is worth returning to.
4808
+ const canGoBack = isMobile || pane === "content"
4809
+ ? (previewOrigin !== null || meta !== null || showCommit)
4810
+ : false;
4811
+ return react.createElement("button", {
4812
+ type: "button",
4813
+ className: "fv-icon-button fv-btn-back",
4814
+ "aria-label": backTarget,
4815
+ title: backTarget,
4816
+ disabled: !canGoBack,
4817
+ onClick: goBack,
4818
+ }, react.createElement("span", { "aria-hidden": "true" }, "‹"));
4819
+ })(),
4718
4820
  react.createElement("span", { className: "fv-main-name" },
4719
4821
  commitHeadline !== ""
4720
4822
  ? commitHeadline
@@ -4755,13 +4857,15 @@ window.__ModuleLoader__.load({
4755
4857
  }, commitView === "changes"
4756
4858
  ? react.createElement(WorkspaceChangeDetail, {
4757
4859
  state: gitState,
4758
- path: meta === null ? "" : meta.path,
4860
+ path: previewChangePath,
4759
4861
  request,
4760
4862
  repo: gitState.repoId,
4761
4863
  })
4762
4864
  : react.createElement(CommitDetail, {
4763
4865
  state: gitState,
4764
- selectedPath: meta === null ? "" : meta.path,
4866
+ // A rename is read from its old path but highlighted as
4867
+ // the row that was clicked, so the two stay in step.
4868
+ selectedPath: meta === null ? "" : (meta.rowPath || meta.path),
4765
4869
  onSelectFile: openCommitFile,
4766
4870
  view: commitView,
4767
4871
  onSwitchView: setCommitView,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weniatall/dsh-file-viewer",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
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",