@morehao/dsh-github-trending 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +2 -2
- package/client.js +192 -93
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -40,11 +40,11 @@ dsh plugin --profile <profile> add @morehao/dsh-github-trending
|
|
|
40
40
|
- `GET /preview?id=<runId>` 只接受历史里出现过的 id、不接路径参数;返回 `{ text, truncated }`。客户端渲染 Markdown 子集(标题 / 段落 / 列表 / 引用 / 代码块 / 表格(GFM 管道表,含列对齐)/ 粗体 / 行内代码 / 链接 / 分隔线),**只生成 React 文本节点**,链接仅放行 http(s),不渲染图片或原始 HTML;也可以切「原文」。
|
|
41
41
|
- 日报只列最近 30 天**有记录**的日期,每天一条;默认打开最近一期有预览的日报。失败 / 无变更 / 试跑 / 旧记录 / 副本被清理都有各自的空状态,不用示例内容兜底。
|
|
42
42
|
- 预览是运行结束时的派生副本:你在仓库里事后编辑 canonical 文件,不会改变这次记录。
|
|
43
|
-
-
|
|
43
|
+
- 工作台顶部第一行是插件身份条:名称 / 版本 / 完整包名(点击复制)/ GitHub 外链 / 检查更新(就地状态);第二行是横向 tab(概览 / 日报 / 运行记录 / 设置),右侧常驻下次运行与就绪 N/4。点版本号可打开「关于」弹层。包名 / 版本 / GitHub 来自 `/state.plugin`(`repository` 由 `package.json` 规范化),仓库缺失时隐藏外链。
|
|
44
44
|
|
|
45
45
|
## 插件更新
|
|
46
46
|
|
|
47
|
-
-
|
|
47
|
+
- 顶部身份条的「检查更新」与「关于」弹层都会显示当前版本与 npm 上的最新版:首次挂载静默检查一次(Host 侧缓存 5 分钟),也可以点「检查更新」强制重查;有新版时身份条就地显示「有新版本 vX」+「更新到 vX」。只跟随 npm 的 `latest` 稳定版。
|
|
48
48
|
- 确认后由宿主 `pluginManager` 重装本插件(`installBundle`;已装同 spec 时走 `removeBundle → installBundle`,失败会尝试装回原版本),完成后需要重启 DSH 生效。
|
|
49
49
|
- 本地安装(`link:` / `file:` / `workspace:`)**不提供一键更新**:那会把开发链接换成 npm 版。此时只显示 `dsh plugin --profile <name> add @morehao/dsh-github-trending@latest` 供复制。
|
|
50
50
|
- 更新引擎来自共享包 [`@morehao/dsh-plugin-kit`](https://www.npmjs.com/package/@morehao/dsh-plugin-kit)(`./update` + `./update/client`),本仓只做上下文与 `execCapture` 接线;`GET /update` / `POST /update` 与其它路由一样要求自定义头、`no-store`,业务失败返回 409 + `UPDATE_FAILED` + `updateCode`。
|
package/client.js
CHANGED
|
@@ -241,6 +241,22 @@ var DICT = {
|
|
|
241
241
|
"shell.ready": "就绪 {ready} / {total}",
|
|
242
242
|
"shell.github": "GitHub",
|
|
243
243
|
"shell.package.copy": "复制完整包名",
|
|
244
|
+
"shell.update.check": "检查更新",
|
|
245
|
+
"shell.update.checking": "正在检查…",
|
|
246
|
+
"shell.update.applying": "正在更新到 v{version}…",
|
|
247
|
+
"shell.update.applyingShort": "更新中…",
|
|
248
|
+
"shell.update.done": "已更新,重启 DSH 生效",
|
|
249
|
+
"shell.update.failed": "更新失败",
|
|
250
|
+
"shell.update.checkFailed": "检查失败,可稍后重试",
|
|
251
|
+
"shell.update.available": "有新版本 v{latest}",
|
|
252
|
+
"shell.update.latest": "已是最新 v{version}",
|
|
253
|
+
"shell.update.apply": "更新到 v{version}",
|
|
254
|
+
"shell.update.confirmHint": "更新会重装插件,需重启 DSH 生效",
|
|
255
|
+
"shell.update.confirmYes": "确认更新",
|
|
256
|
+
"shell.update.cancel": "取消",
|
|
257
|
+
"shell.update.copyCmd": "复制更新命令",
|
|
258
|
+
"shell.update.copied": "已复制",
|
|
259
|
+
"shell.update.manual": "本地安装,需手动更新",
|
|
244
260
|
"time.in.minutes": "{minutes} 分钟后",
|
|
245
261
|
"time.in.hours": "{hours} 小时 {minutes} 分后",
|
|
246
262
|
"time.in.days": "{days} 天后",
|
|
@@ -558,6 +574,22 @@ var DICT = {
|
|
|
558
574
|
"shell.ready": "Ready {ready} / {total}",
|
|
559
575
|
"shell.github": "GitHub",
|
|
560
576
|
"shell.package.copy": "Copy full package name",
|
|
577
|
+
"shell.update.check": "Check for updates",
|
|
578
|
+
"shell.update.checking": "Checking…",
|
|
579
|
+
"shell.update.applying": "Updating to v{version}…",
|
|
580
|
+
"shell.update.applyingShort": "Updating…",
|
|
581
|
+
"shell.update.done": "Updated · restart DSH",
|
|
582
|
+
"shell.update.failed": "Update failed",
|
|
583
|
+
"shell.update.checkFailed": "Check failed, try again later",
|
|
584
|
+
"shell.update.available": "v{latest} available",
|
|
585
|
+
"shell.update.latest": "Up to date · v{version}",
|
|
586
|
+
"shell.update.apply": "Update to v{version}",
|
|
587
|
+
"shell.update.confirmHint": "Reinstalls the plugin; restart DSH to apply",
|
|
588
|
+
"shell.update.confirmYes": "Confirm",
|
|
589
|
+
"shell.update.cancel": "Cancel",
|
|
590
|
+
"shell.update.copyCmd": "Copy update command",
|
|
591
|
+
"shell.update.copied": "Copied",
|
|
592
|
+
"shell.update.manual": "Local install · update manually",
|
|
561
593
|
"time.in.minutes": "in {minutes} min",
|
|
562
594
|
"time.in.hours": "in {hours} h {minutes} min",
|
|
563
595
|
"time.in.days": "in {days} d",
|
|
@@ -768,7 +800,7 @@ var CSS = `
|
|
|
768
800
|
|
|
769
801
|
/* ——— 01 工作台外壳 ——— */
|
|
770
802
|
.dshgt-shell{gap:0;height:100%;min-height:0;overflow:hidden;}
|
|
771
|
-
.dshgt-app{flex:1;min-height:0;display:
|
|
803
|
+
.dshgt-app{flex:1;min-height:0;display:flex;flex-direction:column;background:var(--gt-bg);}
|
|
772
804
|
.dshgt-rail{background:color-mix(in srgb,var(--gt-fg) 3%,var(--gt-bg));border-right:1px solid var(--gt-border);display:flex;flex-direction:column;padding:14px 10px 12px;min-height:0;overflow:hidden;}
|
|
773
805
|
.dshgt-brand{display:flex;align-items:center;gap:9px;padding:2px 6px 16px;}
|
|
774
806
|
.dshgt-brand svg{flex:none;border-radius:8px;}
|
|
@@ -797,7 +829,7 @@ var CSS = `
|
|
|
797
829
|
.dshgt-pkg-copy{width:22px;height:22px;margin-left:auto;display:grid;place-items:center;border:0;background:none;border-radius:4px;color:var(--gt-muted);cursor:pointer;}
|
|
798
830
|
.dshgt-pkg-copy:hover{background:color-mix(in srgb,var(--gt-fg) 7%,var(--gt-bg));color:var(--gt-fg);}
|
|
799
831
|
.dshgt-pkg-copy:disabled{opacity:.4;cursor:not-allowed;}
|
|
800
|
-
.dshgt-main{display:flex;flex-direction:column;min-width:0;min-height:0;background:var(--gt-bg);}
|
|
832
|
+
.dshgt-main{flex:1;display:flex;flex-direction:column;min-width:0;min-height:0;background:var(--gt-bg);}
|
|
801
833
|
.dshgt-page-head{display:flex;align-items:flex-start;gap:16px;padding:20px 30px 14px;border-bottom:1px solid color-mix(in srgb,var(--gt-border) 70%,transparent);flex:none;}
|
|
802
834
|
.dshgt-page-heading{min-width:0;}
|
|
803
835
|
.dshgt-page-head h1{margin:0;font-size:21px;line-height:1.25;font-weight:650;letter-spacing:-.012em;}
|
|
@@ -813,6 +845,43 @@ var CSS = `
|
|
|
813
845
|
.dshgt-tag{display:inline-flex;align-items:center;height:20px;padding:0 7px;border:1px solid var(--gt-border);border-radius:999px;font-size:11px;color:var(--gt-muted);background:var(--gt-bg);white-space:nowrap;}
|
|
814
846
|
.dshgt-inline-tag{margin-left:6px;vertical-align:1px;}
|
|
815
847
|
|
|
848
|
+
/* ——— 顶部身份条(第一行):名称 / 版本 / 完整包名 / GitHub / 检查更新 ——— */
|
|
849
|
+
.dshgt-idbar{display:flex;align-items:center;gap:10px;height:48px;padding:0 18px;border-bottom:1px solid var(--gt-border);flex:none;background:var(--gt-bg);}
|
|
850
|
+
.dshgt-idbar .dshgt-brand{display:flex;align-items:center;gap:9px;padding:0;flex:none;}
|
|
851
|
+
.dshgt-idbar .dshgt-brand svg{width:22px;height:22px;flex:none;border-radius:6px;}
|
|
852
|
+
.dshgt-brand-name{font-size:13.5px;font-weight:650;letter-spacing:-.01em;white-space:nowrap;line-height:1.3;}
|
|
853
|
+
.dshgt-id-ver{appearance:none;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;color:var(--gt-fg);background:var(--gt-card);border:1px solid var(--gt-border);border-radius:999px;padding:1px 7px;line-height:16px;cursor:pointer;flex:none;}
|
|
854
|
+
.dshgt-id-ver:hover{border-color:color-mix(in srgb,var(--gt-accent) 45%,var(--gt-border));}
|
|
855
|
+
.dshgt-id-sep{width:1px;height:16px;background:var(--gt-border);flex:none;}
|
|
856
|
+
.dshgt-id-pkg{appearance:none;border:0;background:none;padding:2px 4px;border-radius:5px;color:var(--gt-muted);cursor:pointer;font-size:12px;max-width:44vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:none;}
|
|
857
|
+
.dshgt-id-pkg:hover{color:var(--gt-fg);background:color-mix(in srgb,var(--gt-fg) 5%,var(--gt-bg));}
|
|
858
|
+
.dshgt-idbar-right{margin-left:auto;display:flex;align-items:center;gap:10px;flex:none;}
|
|
859
|
+
.dshgt-id-gh{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:7px;color:var(--gt-muted);border:1px solid transparent;}
|
|
860
|
+
.dshgt-id-gh:hover{color:var(--gt-fg);background:color-mix(in srgb,var(--gt-fg) 6%,var(--gt-bg));border-color:var(--gt-border);}
|
|
861
|
+
.dshgt-id-upd{display:flex;align-items:center;gap:10px;}
|
|
862
|
+
.dshgt-id-status{font-size:12px;color:var(--gt-muted);white-space:nowrap;display:inline-flex;align-items:center;gap:6px;}
|
|
863
|
+
.dshgt-id-status.ok{color:var(--gt-ok);}
|
|
864
|
+
.dshgt-id-status.new{color:var(--gt-warn);}
|
|
865
|
+
.dshgt-id-status.err{color:var(--gt-err);}
|
|
866
|
+
.dshgt-id-actions{display:flex;align-items:center;gap:8px;}
|
|
867
|
+
|
|
868
|
+
/* ——— 横向 tab(第二行)+ 右侧状态 ——— */
|
|
869
|
+
.dshgt-tabsbar{display:flex;align-items:stretch;gap:16px;height:46px;padding:0 24px;border-bottom:1px solid var(--gt-border);flex:none;background:var(--gt-bg);}
|
|
870
|
+
.dshgt-tabnav{display:flex;align-items:stretch;gap:2px;height:100%;}
|
|
871
|
+
.dshgt-tab{display:flex;align-items:center;gap:7px;padding:0 12px;border:0;background:none;color:var(--gt-muted);cursor:pointer;font:inherit;font-size:13.5px;position:relative;border-bottom:2px solid transparent;margin-bottom:-1px;}
|
|
872
|
+
.dshgt-tab svg{opacity:.8;}
|
|
873
|
+
.dshgt-tab:hover{color:var(--gt-fg);}
|
|
874
|
+
.dshgt-tab.on{color:var(--gt-fg);font-weight:600;border-bottom-color:var(--gt-accent);}
|
|
875
|
+
.dshgt-tab.on svg{opacity:1;color:var(--gt-accent);}
|
|
876
|
+
.dshgt-tab-tail{font-size:10.5px;color:var(--gt-muted);background:var(--gt-card);border:1px solid var(--gt-border);border-radius:999px;padding:0 5px;line-height:15px;}
|
|
877
|
+
.dshgt-tabsbar-status{margin-left:auto;display:flex;align-items:center;gap:16px;flex:none;}
|
|
878
|
+
.dshgt-status-item{display:inline-flex;align-items:center;gap:7px;font-size:12px;color:var(--gt-muted);white-space:nowrap;}
|
|
879
|
+
.dshgt-status-key{color:var(--gt-muted);}
|
|
880
|
+
.dshgt-status-val{color:var(--gt-fg);font-weight:600;}
|
|
881
|
+
.dshgt-status-sub{color:var(--gt-muted);}
|
|
882
|
+
@media (max-width:1100px){ .dshgt-id-pkg{max-width:26vw;} }
|
|
883
|
+
@media (max-width:860px){ .dshgt-id-pkg{display:none;} .dshgt-status-item.dshgt-next{display:none;} }
|
|
884
|
+
|
|
816
885
|
/* ——— 概览 ——— */
|
|
817
886
|
.dshgt-delivery{border:1px solid var(--gt-border);border-radius:12px;padding:18px 20px 16px;background:var(--gt-card);display:flex;flex-direction:column;gap:6px;}
|
|
818
887
|
.dshgt-delivery-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
|
|
@@ -2129,11 +2198,6 @@ function usePluginUpdate() {
|
|
|
2129
2198
|
}, [controller]);
|
|
2130
2199
|
return [state, controller];
|
|
2131
2200
|
}
|
|
2132
|
-
function UpdateDot(props) {
|
|
2133
|
-
const [state] = usePluginUpdate();
|
|
2134
|
-
if (state.view?.updateAvailable !== true) return null;
|
|
2135
|
-
return h("span", { className: "dshgt-update-dot", title: props.t("update.badge") });
|
|
2136
|
-
}
|
|
2137
2201
|
function PluginUpdateSection(props) {
|
|
2138
2202
|
const { t } = props;
|
|
2139
2203
|
const [state, controller] = usePluginUpdate();
|
|
@@ -3462,6 +3526,109 @@ function AboutDialog(props) {
|
|
|
3462
3526
|
return h("div", { className: "dshgt-root" }, dialog);
|
|
3463
3527
|
}
|
|
3464
3528
|
|
|
3529
|
+
// client/identity-bar.ts
|
|
3530
|
+
function logo() {
|
|
3531
|
+
return h(
|
|
3532
|
+
"svg",
|
|
3533
|
+
{ width: 22, height: 22, viewBox: "0 0 64 64", "aria-hidden": "true" },
|
|
3534
|
+
h("rect", { x: 4, y: 4, width: 56, height: 56, rx: 14, fill: "#0d1117" }),
|
|
3535
|
+
h("path", { d: "M18 46V22l14 12 14-12v24", fill: "none", stroke: "#58a6ff", strokeWidth: 4, strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
3536
|
+
h("circle", { cx: 32, cy: 45, r: 3, fill: "#3fb950" })
|
|
3537
|
+
);
|
|
3538
|
+
}
|
|
3539
|
+
function githubIcon() {
|
|
3540
|
+
return h("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true" }, h("path", {
|
|
3541
|
+
d: "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"
|
|
3542
|
+
}));
|
|
3543
|
+
}
|
|
3544
|
+
function IdentityBar(props) {
|
|
3545
|
+
const { t, plugin } = props;
|
|
3546
|
+
const [copied, setCopied] = import_react.default.useState(false);
|
|
3547
|
+
const [confirming, setConfirming] = import_react.default.useState(false);
|
|
3548
|
+
const [cmdCopied, setCmdCopied] = import_react.default.useState(false);
|
|
3549
|
+
const [updateState, controller] = usePluginUpdate();
|
|
3550
|
+
const view = updateState.view;
|
|
3551
|
+
const status = updateState.status;
|
|
3552
|
+
import_react.default.useEffect(() => {
|
|
3553
|
+
if (status === "applying" || status === "restart-required" || status === "applied") setConfirming(false);
|
|
3554
|
+
}, [status]);
|
|
3555
|
+
const copyPkg = () => {
|
|
3556
|
+
void copyText(plugin.name).then((ok) => {
|
|
3557
|
+
if (!ok) return;
|
|
3558
|
+
setCopied(true);
|
|
3559
|
+
setTimeout(() => setCopied(false), 1400);
|
|
3560
|
+
});
|
|
3561
|
+
};
|
|
3562
|
+
const busy = status === "checking" || status === "applying";
|
|
3563
|
+
const settled = status === "restart-required" || status === "applied";
|
|
3564
|
+
const latestVersion = view === null ? "" : view.latestVersion ?? "";
|
|
3565
|
+
const updateAvailable = view !== null && view.updateAvailable;
|
|
3566
|
+
const actionable = updateAvailable && view !== null && view.canApply && !settled && !busy;
|
|
3567
|
+
const manual = view !== null && (!view.canApply || view.checkFailed) ? view.manualCommand ?? null : null;
|
|
3568
|
+
const currentVersion = view === null ? plugin.version : view.currentVersion ?? plugin.version;
|
|
3569
|
+
const copyCmd = () => {
|
|
3570
|
+
if (manual === void 0 || manual === null) return;
|
|
3571
|
+
void copyText(manual).then((ok) => {
|
|
3572
|
+
if (!ok) return;
|
|
3573
|
+
setCmdCopied(true);
|
|
3574
|
+
setTimeout(() => setCmdCopied(false), 1400);
|
|
3575
|
+
});
|
|
3576
|
+
};
|
|
3577
|
+
function statusLine() {
|
|
3578
|
+
if (status === "checking" || view === null) return { text: t("shell.update.checking"), kind: "muted" };
|
|
3579
|
+
if (status === "applying") return { text: t("shell.update.applying", { version: latestVersion }), kind: "muted" };
|
|
3580
|
+
if (status === "restart-required" || status === "applied") return { text: t("shell.update.done", { version: latestVersion }), kind: "ok" };
|
|
3581
|
+
if (status === "failed") return { text: updateState.error?.code === "CHECK_FAILED" ? t("shell.update.checkFailed") : t("shell.update.failed"), kind: "err" };
|
|
3582
|
+
if (view.checkFailed) return { text: t("shell.update.checkFailed"), kind: "err" };
|
|
3583
|
+
if (view.updateAvailable) return { text: t("shell.update.available", { latest: view.latestVersion ?? "" }), kind: "new" };
|
|
3584
|
+
return { text: t("shell.update.latest", { version: currentVersion }), kind: "ok" };
|
|
3585
|
+
}
|
|
3586
|
+
function action() {
|
|
3587
|
+
if (status === "applying") return h(Btn, { small: true, disabled: true }, t("shell.update.applyingShort"));
|
|
3588
|
+
if (actionable) {
|
|
3589
|
+
if (confirming) {
|
|
3590
|
+
return [
|
|
3591
|
+
h(Btn, { key: "yes", small: true, variant: "danger", onClick: () => {
|
|
3592
|
+
setConfirming(false);
|
|
3593
|
+
void controller.apply();
|
|
3594
|
+
} }, t("shell.update.confirmYes")),
|
|
3595
|
+
h(Btn, { key: "no", small: true, onClick: () => setConfirming(false) }, t("shell.update.cancel"))
|
|
3596
|
+
];
|
|
3597
|
+
}
|
|
3598
|
+
return h(Btn, { small: true, variant: "primary", onClick: () => setConfirming(true) }, t("shell.update.apply", { version: latestVersion }));
|
|
3599
|
+
}
|
|
3600
|
+
if (manual !== null) return h(Btn, { small: true, onClick: copyCmd }, cmdCopied ? t("shell.update.copied") : t("shell.update.copyCmd"));
|
|
3601
|
+
return h(Btn, { small: true, disabled: busy, onClick: () => void controller.check({ fresh: true }) }, t("shell.update.check"));
|
|
3602
|
+
}
|
|
3603
|
+
const line = statusLine();
|
|
3604
|
+
return h(
|
|
3605
|
+
"div",
|
|
3606
|
+
{ className: "dshgt-idbar" },
|
|
3607
|
+
h("div", { className: "dshgt-brand" }, logo(), h("span", { className: "dshgt-brand-name" }, t("section.title"))),
|
|
3608
|
+
h("button", { type: "button", className: "dshgt-id-ver", title: t("about.title"), onClick: () => props.onOpenAbout() }, `v${plugin.version}`),
|
|
3609
|
+
h("span", { className: "dshgt-id-sep" }),
|
|
3610
|
+
h(
|
|
3611
|
+
"button",
|
|
3612
|
+
{ type: "button", className: "dshgt-id-pkg dshgt-mono", title: updatedCopyTitle(t, copied), onClick: copyPkg },
|
|
3613
|
+
copied ? t("about.copied") : plugin.name
|
|
3614
|
+
),
|
|
3615
|
+
h(
|
|
3616
|
+
"div",
|
|
3617
|
+
{ className: "dshgt-idbar-right" },
|
|
3618
|
+
plugin.repository === void 0 ? null : h("a", { className: "dshgt-id-gh", href: plugin.repository, target: "_blank", rel: "noreferrer", title: t("about.repo"), "aria-label": t("about.repo") }, githubIcon()),
|
|
3619
|
+
h(
|
|
3620
|
+
"span",
|
|
3621
|
+
{ className: "dshgt-id-upd" },
|
|
3622
|
+
confirming ? h("span", { className: "dshgt-id-status new" }, t("shell.update.confirmHint")) : h("span", { className: `dshgt-id-status ${line.kind}` }, line.text),
|
|
3623
|
+
h("span", { className: "dshgt-id-actions" }, action())
|
|
3624
|
+
)
|
|
3625
|
+
)
|
|
3626
|
+
);
|
|
3627
|
+
}
|
|
3628
|
+
function updatedCopyTitle(t, copied) {
|
|
3629
|
+
return copied ? t("about.copied") : t("about.copy");
|
|
3630
|
+
}
|
|
3631
|
+
|
|
3465
3632
|
// client/panel-icon.ts
|
|
3466
3633
|
var TREND_LINE = "3 16.5 9 10.5 13 14.5 21 6.5";
|
|
3467
3634
|
var TREND_ARROW = "15.5 6.5 21 6.5 21 12";
|
|
@@ -3542,22 +3709,6 @@ function navIcon(name, size = 16) {
|
|
|
3542
3709
|
h("circle", { cx: 10, cy: 17, r: 2.2 })
|
|
3543
3710
|
);
|
|
3544
3711
|
}
|
|
3545
|
-
function brandLogo() {
|
|
3546
|
-
return h(
|
|
3547
|
-
"svg",
|
|
3548
|
-
{ width: 28, height: 28, viewBox: "0 0 64 64", "aria-hidden": "true" },
|
|
3549
|
-
h("rect", { x: 3, y: 3, width: 58, height: 58, rx: 15, fill: "#0d1117", stroke: "rgba(255,255,255,.14)", strokeWidth: 1 }),
|
|
3550
|
-
h("path", {
|
|
3551
|
-
d: "M18 46V22l14 12 14-12v24",
|
|
3552
|
-
fill: "none",
|
|
3553
|
-
stroke: "#58a6ff",
|
|
3554
|
-
strokeWidth: 4,
|
|
3555
|
-
strokeLinecap: "round",
|
|
3556
|
-
strokeLinejoin: "round"
|
|
3557
|
-
}),
|
|
3558
|
-
h("circle", { cx: 32, cy: 45, r: 3, fill: "#3fb950" })
|
|
3559
|
-
);
|
|
3560
|
-
}
|
|
3561
3712
|
function relativeFuture(iso, t) {
|
|
3562
3713
|
if (iso === void 0) return void 0;
|
|
3563
3714
|
const target = new Date(iso).getTime();
|
|
@@ -3603,6 +3754,7 @@ function apply(ctx) {
|
|
|
3603
3754
|
}, []);
|
|
3604
3755
|
const openRuns = import_react.default.useCallback(() => setView("runs"), []);
|
|
3605
3756
|
const openSettings = import_react.default.useCallback(() => setView("settings"), []);
|
|
3757
|
+
const openAbout = import_react.default.useCallback(() => setAboutOpen(true), []);
|
|
3606
3758
|
const state = value.state;
|
|
3607
3759
|
const plugin = state?.plugin;
|
|
3608
3760
|
const history = state?.status.history ?? [];
|
|
@@ -3613,9 +3765,10 @@ function apply(ctx) {
|
|
|
3613
3765
|
state.settings.repo.path.trim() !== "",
|
|
3614
3766
|
state.github.configured
|
|
3615
3767
|
].filter(Boolean).length;
|
|
3616
|
-
const fullName = plugin === void 0 ? void 0 : `${plugin.name}@v${plugin.version}`;
|
|
3617
3768
|
const digestTail = digestDate ?? state?.status.lastResult?.date ?? state?.status.history[0]?.date;
|
|
3618
3769
|
const showActions = view === "overview" || view === "runs";
|
|
3770
|
+
const nextRun = schedule === void 0 || !schedule.enabled ? t("shell.scheduleOff") : schedule.nextRunAt === void 0 ? `${schedule.time} · ${schedule.timezone}` : nextRunText(schedule.nextRunAt);
|
|
3771
|
+
const relNext = schedule !== void 0 && schedule.enabled && schedule.nextRunAt !== void 0 ? relativeFuture(schedule.nextRunAt, t) : void 0;
|
|
3619
3772
|
const viewNode = view === "overview" ? h(OverviewView, {
|
|
3620
3773
|
t,
|
|
3621
3774
|
lang,
|
|
@@ -3638,103 +3791,49 @@ function apply(ctx) {
|
|
|
3638
3791
|
h(
|
|
3639
3792
|
"div",
|
|
3640
3793
|
{ className: "dshgt-app" },
|
|
3794
|
+
plugin === void 0 ? null : h(IdentityBar, { t, plugin, onOpenAbout: openAbout }),
|
|
3641
3795
|
h(
|
|
3642
|
-
"
|
|
3643
|
-
{ className: "dshgt-
|
|
3644
|
-
h(
|
|
3645
|
-
"div",
|
|
3646
|
-
{ className: "dshgt-brand" },
|
|
3647
|
-
brandLogo(),
|
|
3648
|
-
h(
|
|
3649
|
-
"div",
|
|
3650
|
-
null,
|
|
3651
|
-
h("div", { className: "dshgt-brand-name" }, t("section.title")),
|
|
3652
|
-
h("div", { className: "dshgt-brand-ver" }, plugin === void 0 ? "" : `v${plugin.version}`)
|
|
3653
|
-
)
|
|
3654
|
-
),
|
|
3796
|
+
"div",
|
|
3797
|
+
{ className: "dshgt-tabsbar" },
|
|
3655
3798
|
h(
|
|
3656
3799
|
"nav",
|
|
3657
|
-
{ className: "dshgt-
|
|
3800
|
+
{ className: "dshgt-tabnav", "aria-label": t("shell.nav") },
|
|
3658
3801
|
NAV.map(
|
|
3659
3802
|
(item) => h(
|
|
3660
3803
|
"button",
|
|
3661
3804
|
{
|
|
3662
3805
|
key: item.id,
|
|
3663
3806
|
type: "button",
|
|
3664
|
-
className: `dshgt-
|
|
3807
|
+
className: `dshgt-tab${view === item.id ? " on" : ""}`,
|
|
3665
3808
|
"aria-current": view === item.id ? "page" : void 0,
|
|
3666
3809
|
onClick: () => setView(item.id)
|
|
3667
3810
|
},
|
|
3668
3811
|
navIcon(item.icon),
|
|
3669
3812
|
h("span", null, t(item.label)),
|
|
3670
|
-
item.id === "digest" && digestTail !== void 0 ? h("span", { className: "dshgt-
|
|
3813
|
+
item.id === "digest" && digestTail !== void 0 ? h("span", { className: "dshgt-tab-tail dshgt-mono" }, digestTail.slice(5)) : item.id === "runs" && history.length > 0 ? h("span", { className: "dshgt-tab-tail dshgt-mono" }, String(history.length)) : null
|
|
3671
3814
|
)
|
|
3672
3815
|
)
|
|
3673
3816
|
),
|
|
3674
|
-
h("div", { className: "dshgt-rail-spacer" }),
|
|
3675
3817
|
h(
|
|
3676
3818
|
"div",
|
|
3677
|
-
{ className: "dshgt-
|
|
3678
|
-
h("div", { className: "dshgt-rail-cap" }, t("shell.nextRun")),
|
|
3679
|
-
h(
|
|
3680
|
-
"div",
|
|
3681
|
-
{ className: "dshgt-rail-time" },
|
|
3682
|
-
schedule === void 0 || !schedule.enabled ? t("shell.scheduleOff") : schedule.nextRunAt === void 0 ? `${schedule.time} · ${schedule.timezone}` : nextRunText(schedule.nextRunAt)
|
|
3683
|
-
),
|
|
3684
|
-
h(
|
|
3685
|
-
"div",
|
|
3686
|
-
{ className: "dshgt-rail-count" },
|
|
3687
|
-
schedule !== void 0 && schedule.enabled && schedule.nextRunAt !== void 0 ? relativeFuture(schedule.nextRunAt, t) ?? "" : schedule === void 0 ? "" : `${schedule.time} · ${schedule.timezone}`
|
|
3688
|
-
),
|
|
3819
|
+
{ className: "dshgt-tabsbar-status" },
|
|
3689
3820
|
h(
|
|
3690
|
-
"
|
|
3691
|
-
{ className: "dshgt-
|
|
3821
|
+
"span",
|
|
3822
|
+
{ className: "dshgt-status-item" },
|
|
3692
3823
|
h("span", { className: `dshgt-lamp ${ready === 4 ? "ok" : ready > 0 ? "warn" : "err"}` }),
|
|
3693
3824
|
t("shell.ready", { ready, total: 4 })
|
|
3694
|
-
)
|
|
3695
|
-
),
|
|
3696
|
-
h(
|
|
3697
|
-
"div",
|
|
3698
|
-
{ className: "dshgt-rail-pkg" },
|
|
3699
|
-
h(
|
|
3700
|
-
"button",
|
|
3701
|
-
{
|
|
3702
|
-
type: "button",
|
|
3703
|
-
className: "dshgt-pkg-name",
|
|
3704
|
-
onClick: () => setAboutOpen(true),
|
|
3705
|
-
title: plugin === void 0 ? "" : fullName
|
|
3706
|
-
},
|
|
3707
|
-
plugin?.name ?? t("section.title"),
|
|
3708
|
-
h(UpdateDot, { t })
|
|
3709
3825
|
),
|
|
3710
3826
|
h(
|
|
3711
|
-
"
|
|
3712
|
-
{ className: "dshgt-
|
|
3713
|
-
h("span", { className: "dshgt-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
{ href: plugin.repository, target: "_blank", rel: "noreferrer" },
|
|
3717
|
-
`${t("shell.github")} ↗`
|
|
3718
|
-
),
|
|
3719
|
-
h(
|
|
3720
|
-
"button",
|
|
3721
|
-
{
|
|
3722
|
-
type: "button",
|
|
3723
|
-
className: "dshgt-pkg-copy",
|
|
3724
|
-
title: t("shell.package.copy"),
|
|
3725
|
-
"aria-label": t("shell.package.copy"),
|
|
3726
|
-
disabled: fullName === void 0,
|
|
3727
|
-
onClick: () => {
|
|
3728
|
-
if (fullName !== void 0) void copyText(fullName);
|
|
3729
|
-
}
|
|
3730
|
-
},
|
|
3731
|
-
navIcon("doc", 13)
|
|
3732
|
-
)
|
|
3827
|
+
"span",
|
|
3828
|
+
{ className: "dshgt-status-item dshgt-next" },
|
|
3829
|
+
h("span", { className: "dshgt-status-key" }, t("shell.nextRun")),
|
|
3830
|
+
h("span", { className: "dshgt-status-val dshgt-mono" }, nextRun),
|
|
3831
|
+
relNext === void 0 ? null : h("span", { className: "dshgt-status-sub" }, relNext)
|
|
3733
3832
|
)
|
|
3734
3833
|
)
|
|
3735
3834
|
),
|
|
3736
3835
|
h(
|
|
3737
|
-
"
|
|
3836
|
+
"div",
|
|
3738
3837
|
{ className: "dshgt-main" },
|
|
3739
3838
|
h(
|
|
3740
3839
|
"header",
|