dsh-vidi 0.4.0 → 0.4.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 +69 -6
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -656,6 +656,42 @@ function ChatPanel(props) {
656
656
  });
657
657
  }
658
658
 
659
+ // src/client/Guard.tsx
660
+ /**
661
+ * Keeps a companion plugin's part of the page (a tab, a player menu, a
662
+ * workbench) from taking the whole video page down: if it fails, only its
663
+ * own area says so, with a way out, and the video keeps playing.
664
+ */
665
+ var Guard = class extends react.Component {
666
+ state = {};
667
+ static getDerivedStateFromError(error) {
668
+ return { error };
669
+ }
670
+ componentDidCatch(error) {
671
+ console.error(`[dsh-vidi] ${this.props.name} failed`, error);
672
+ }
673
+ render() {
674
+ if (!this.state.error) return this.props.children;
675
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
676
+ className: "dshl-guard",
677
+ role: "alert",
678
+ children: [
679
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: this.props.message }),
680
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: this.state.error.message }),
681
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
682
+ className: "dshl-btn small",
683
+ onClick: () => this.setState({ error: void 0 }),
684
+ children: "↻"
685
+ }), this.props.onClose && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
686
+ className: "dshl-btn small",
687
+ onClick: this.props.onClose,
688
+ children: this.props.closeLabel
689
+ })] })
690
+ ]
691
+ });
692
+ }
693
+ };
694
+
659
695
  // src/client/langs.ts
660
696
  /** Language names for the UI, by interface language. */
661
697
  const NAMES = {
@@ -35250,7 +35286,11 @@ function LiveView(props) {
35250
35286
  }),
35251
35287
  job && view && extPanels.filter((p) => p.id === tab).map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
35252
35288
  className: "dshl-panel dshl-ext",
35253
- children: p.render(view)
35289
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Guard, {
35290
+ name: `tab ${p.id}`,
35291
+ message: t("ext.failed"),
35292
+ children: p.render(view)
35293
+ })
35254
35294
  }, p.id)),
35255
35295
  tab === "glossary" && job && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlossaryPanel, {
35256
35296
  jobId: job.id,
@@ -35479,7 +35519,11 @@ function LiveView(props) {
35479
35519
  id: `ext:${m.id}`,
35480
35520
  icon: m.icon,
35481
35521
  title: m.title(ui),
35482
- content: view ? m.render(view, () => player.current?.closeMenu()) : null
35522
+ content: view ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Guard, {
35523
+ name: `menu ${m.id}`,
35524
+ message: t("ext.failed"),
35525
+ children: m.render(view, () => player.current?.closeMenu())
35526
+ }) : null
35483
35527
  })),
35484
35528
  {
35485
35529
  id: "download",
@@ -35535,7 +35579,13 @@ function LiveView(props) {
35535
35579
  className: "dshl-side",
35536
35580
  children: activeBench && view ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
35537
35581
  className: "dshl-benchbox",
35538
- children: activeBench.render(view)
35582
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Guard, {
35583
+ name: `workbench ${activeBench.id}`,
35584
+ message: t("ext.failed"),
35585
+ onClose: () => setBench(null),
35586
+ closeLabel: t("ext.close"),
35587
+ children: activeBench.render(view)
35588
+ }, activeBench.id)
35539
35589
  }) : pageMode ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChatPanel, {
35540
35590
  face: chatFace,
35541
35591
  source: chatSource,
@@ -36292,6 +36342,8 @@ const en = {
36292
36342
  "player.polished": "This line is polished",
36293
36343
  "page.open": "Vidi video",
36294
36344
  "page.failed": "The video page could not open: {e}",
36345
+ "ext.failed": "This part (from another plugin) ran into an error. The video keeps playing; restarting DSH usually fixes it after an update.",
36346
+ "ext.close": "Back to chat",
36295
36347
  "side.subs": "Subtitles {p}%",
36296
36348
  "side.subsLive": "Subtitling",
36297
36349
  "side.recording": "Recording",
@@ -36614,6 +36666,8 @@ const zh = {
36614
36666
  "player.polished": "这句字幕已精修",
36615
36667
  "page.open": "Vidi 视频",
36616
36668
  "page.failed": "视频页打不开:{e}",
36669
+ "ext.failed": "这一块(来自其他插件)出错了。视频照常播放;刚更新过插件的话,重启一下 DSH 一般就好。",
36670
+ "ext.close": "回到对话",
36617
36671
  "side.subs": "字幕 {p}%",
36618
36672
  "side.subsLive": "生成字幕中",
36619
36673
  "side.recording": "录制中",
@@ -36879,9 +36933,13 @@ html[data-platform='darwin']:not([data-fullscreen]) .dshl-pagewrap .dshl.page .d
36879
36933
  publishes how much room they take: the top bar starts after them. */
36880
36934
  .dshl-panelwrap { height: 100%; min-height: 0; background: var(--dsw-alias-bg-base, #fff); }
36881
36935
  .dshl-panelwrap .dshl.page .dshl-top { padding-left: max(20px, var(--dsh-frame-leading-clearance, 0px)); }
36882
- /* Narrow windows (sidebar as a drawer): the app gives its opener a row of its own above the page. */
36883
- [data-sidebar-drawer] .dshl-panelwrap .dshl.page .dshl-top { padding-left: 12px; }
36884
- html[data-platform='darwin']:not([data-fullscreen]) .dshl-panelwrap .dshl.page .dshl-top { padding-top: 4px; padding-bottom: 8px; }
36936
+ /* Web page in a narrow window (sidebar as a drawer): the app gives its opener a row of its own above
36937
+ the page, so the bar starts at the edge. The desktop app keeps the opener on the bar's row instead
36938
+ (beside the traffic lights on macOS), and the clearance above leaves room for it. */
36939
+ html:not([data-platform]) [data-sidebar-drawer] .dshl-panelwrap .dshl.page .dshl-top { padding-left: 12px; }
36940
+ /* macOS: the app's window controls (traffic lights, sidebar toggle, new chat) are centred at y 25 in
36941
+ every state, full screen included; the bar's 40px row is centred on the same line. */
36942
+ html[data-platform='darwin'] .dshl-panelwrap .dshl.page .dshl-top { padding-top: 5px; padding-bottom: 8px; }
36885
36943
  html[data-platform='darwin'] .dshl.page .dshl-top { -webkit-app-region: drag; app-region: drag; }
36886
36944
  html[data-platform='darwin'] .dshl.page .dshl-top :is(button, input, label, a, select, .dshl-pick) { -webkit-app-region: no-drag; app-region: no-drag; }
36887
36945
  .dshl.page { display: flex; flex-direction: column; height: 100%; overflow: hidden; }
@@ -36893,6 +36951,10 @@ html[data-platform='darwin'] .dshl.page .dshl-top :is(button, input, label, a, s
36893
36951
  .dshl.page .dshl-side { position: static; height: 100%; max-height: none; }
36894
36952
  /* Workbench open: the video and its subtitles keep a column on the left; the bench takes the rest. */
36895
36953
  .dshl.page.bench .dshl-main { grid-template-columns: clamp(340px, 32vw, 520px) minmax(0, 1fr); }
36954
+ .dshl-guard { display: grid; gap: 8px; margin: 12px; padding: 12px 14px; border: 1px solid color-mix(in srgb, #d1434b 35%, var(--line)); border-radius: 10px; color: var(--ink); font-size: 13px; }
36955
+ .dshl-guard p { margin: 0; line-height: 1.6; }
36956
+ .dshl-guard code { color: var(--muted); font-size: 12px; white-space: pre-wrap; word-break: break-word; }
36957
+ .dshl-guard div { display: flex; gap: 8px; }
36896
36958
  .dshl-benchbox { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; }
36897
36959
  .dshl-under { display: flex; flex-direction: column; flex: 1; min-height: 210px; overflow: hidden; border: 1px solid var(--line); border-radius: 12px; background: var(--l1); }
36898
36960
  .dshl-under .dshl-sidetabs { align-items: center; padding: 0 12px 0 10px; }
@@ -37332,6 +37394,7 @@ let done = false;
37332
37394
  function ensureStyles() {
37333
37395
  if (done || typeof document === "undefined") return;
37334
37396
  done = true;
37397
+ for (const old of document.querySelectorAll("style[data-dsh-live]")) old.remove();
37335
37398
  const el = document.createElement("style");
37336
37399
  el.dataset.dshLive = "";
37337
37400
  el.textContent = CSS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-vidi",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "A video tool for DeepSeek Harness: watch live streams, videos and podcasts with real-time subtitles in any language, then clip and download",
5
5
  "type": "module",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",