@1e0zj/dsh-plugin-mall 0.1.0 → 0.1.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/cordis.patch.yml +1 -1
- package/package.json +1 -1
- package/src/client.js +57 -29
package/cordis.patch.yml
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Mounted at the host plane (profile bundle layer), so its tools land in the
|
|
3
3
|
# tools registry's global layer and every session sees them.
|
|
4
4
|
- insert:
|
|
5
|
-
- id: dsh-
|
|
5
|
+
- id: dsh-plugin-mall
|
|
6
6
|
name: '@1e0zj/dsh-plugin-mall'
|
|
7
7
|
config:
|
|
8
8
|
# The profile market_install targets when the caller names none.
|
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -44,6 +44,10 @@ window.__ModuleLoader__.load({
|
|
|
44
44
|
".mkt_ok{color:var(--dsw-alias-state-success-primary,#2f855a)}",
|
|
45
45
|
".mkt_badge{display:inline-block;border-radius:999px;padding:1px 8px;font-size:11px;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary)}",
|
|
46
46
|
".mkt_link{color:var(--dsw-alias-state-business-primary);font-size:12px;text-decoration:none;cursor:pointer}",
|
|
47
|
+
".mkt_installedHead{display:flex;align-items:center;gap:8px;width:100%;background:none;border:0;padding:0;margin:0;cursor:pointer;font:inherit;text-align:left}",
|
|
48
|
+
".mkt_installedHead:hover .mkt_panelTitle{color:var(--dsw-alias-state-business-primary)}",
|
|
49
|
+
".mkt_depList{display:flex;flex-direction:column;gap:6px;margin-top:8px}",
|
|
50
|
+
".mkt_depRow{display:flex;justify-content:space-between;align-items:center;gap:8px}",
|
|
47
51
|
].join("\n");
|
|
48
52
|
var tagId = "@1e0zj/dsh-plugin-mall/market-tab.css";
|
|
49
53
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
@@ -78,7 +82,7 @@ window.__ModuleLoader__.load({
|
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
// ── job polling ─────────────────────────────────────────────────────────
|
|
81
|
-
function useJobPolling(call) {
|
|
85
|
+
function useJobPolling(call, onSettled) {
|
|
82
86
|
var jobsRef = useRef({});
|
|
83
87
|
var _jobs = useState({});
|
|
84
88
|
var jobs = _jobs[0];
|
|
@@ -94,20 +98,24 @@ window.__ModuleLoader__.load({
|
|
|
94
98
|
running.forEach(function (id) {
|
|
95
99
|
call("job", { jobId: id }).then(function (value) {
|
|
96
100
|
var snapshot = value.snapshot || {};
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
var old = jobsRef.current[id] || {};
|
|
102
|
+
var wasTerminal = old.status === "completed" || old.status === "failed" || old.status === "killed";
|
|
103
|
+
var nowTerminal = snapshot.status === "completed" || snapshot.status === "failed" || snapshot.status === "killed";
|
|
104
|
+
if (!wasTerminal && nowTerminal && onSettled) {
|
|
105
|
+
try { onSettled(id); } catch (e) { /* best effort */ }
|
|
106
|
+
}
|
|
107
|
+
var output = (old.output || "") + (value.output || "");
|
|
108
|
+
jobsRef.current = Object.assign({}, jobsRef.current, { [id]: Object.assign({}, old, {
|
|
109
|
+
status: snapshot.status,
|
|
110
|
+
detail: snapshot.detail,
|
|
111
|
+
output: output,
|
|
112
|
+
}) });
|
|
113
|
+
setJobs(Object.assign({}, jobsRef.current));
|
|
106
114
|
}).catch(function () { /* keep polling */ });
|
|
107
115
|
});
|
|
108
116
|
}, 1200);
|
|
109
117
|
return function () { clearInterval(timer); };
|
|
110
|
-
}, [call]);
|
|
118
|
+
}, [call, onSettled]);
|
|
111
119
|
var track = useCallback(function (id, spec) {
|
|
112
120
|
jobsRef.current = Object.assign({}, jobsRef.current, { [id]: { status: "running", spec: spec, output: "" } });
|
|
113
121
|
setJobs(Object.assign({}, jobsRef.current));
|
|
@@ -191,21 +199,35 @@ window.__ModuleLoader__.load({
|
|
|
191
199
|
);
|
|
192
200
|
}
|
|
193
201
|
|
|
194
|
-
// ── installed panel
|
|
202
|
+
// ── installed panel (collapsible summary) ───────────────────────────────
|
|
195
203
|
function InstalledPanel(props) {
|
|
196
204
|
var installed = props.installed;
|
|
205
|
+
var _open = useState(false);
|
|
206
|
+
var open = _open[0];
|
|
207
|
+
var setOpen = _open[1];
|
|
197
208
|
if (!installed) return null;
|
|
209
|
+
var count = installed.error ? 0 : (installed.deps || []).length;
|
|
198
210
|
return h("div", { className: "mkt_card" },
|
|
199
|
-
h("
|
|
211
|
+
h("button", {
|
|
212
|
+
type: "button",
|
|
213
|
+
className: "mkt_installedHead",
|
|
214
|
+
onClick: function () { setOpen(!open); },
|
|
215
|
+
"aria-expanded": open ? "true" : "false",
|
|
216
|
+
},
|
|
217
|
+
h("span", { className: "mkt_panelTitle" }, "已装插件"),
|
|
218
|
+
h("span", { className: "mkt_badge" }, count + " 个"),
|
|
219
|
+
h("span", { className: "mkt_meta" }, open ? "收起 ▲" : "展开 ▼")
|
|
220
|
+
),
|
|
200
221
|
installed.error
|
|
201
222
|
? h("div", { className: "mkt_error" }, installed.error)
|
|
202
|
-
:
|
|
223
|
+
: !open ? null
|
|
224
|
+
: (installed.deps || []).length === 0
|
|
203
225
|
? h("div", { className: "mkt_meta" }, "还没有装过插件")
|
|
204
|
-
: (installed.deps || []).map(function (dep) {
|
|
205
|
-
return h("div", { key: dep.name,
|
|
226
|
+
: h("div", { className: "mkt_depList" }, (installed.deps || []).map(function (dep) {
|
|
227
|
+
return h("div", { key: dep.name, className: "mkt_depRow" },
|
|
206
228
|
h("span", { className: "mkt_desc" }, dep.name + "@" + dep.version),
|
|
207
229
|
h("span", { className: "mkt_badge" }, kindLabel(dep.kind)));
|
|
208
|
-
})
|
|
230
|
+
}))
|
|
209
231
|
);
|
|
210
232
|
}
|
|
211
233
|
|
|
@@ -265,10 +287,24 @@ window.__ModuleLoader__.load({
|
|
|
265
287
|
});
|
|
266
288
|
}, [call]);
|
|
267
289
|
|
|
268
|
-
var
|
|
290
|
+
var refreshInstalled = useCallback(function () {
|
|
291
|
+
call("installed", {}).then(function (value) {
|
|
292
|
+
setInstalled(value);
|
|
293
|
+
}).catch(function (e) {
|
|
294
|
+
setInstalled({ error: errorText(e) });
|
|
295
|
+
});
|
|
296
|
+
}, [call]);
|
|
297
|
+
|
|
298
|
+
// 点开即自动搜索(空关键词 = 最热插件),安装任务结束自动刷新已装列表。
|
|
299
|
+
var polling = useJobPolling(call, refreshInstalled);
|
|
269
300
|
var track = polling.track;
|
|
270
301
|
var jobs = polling.jobs;
|
|
271
302
|
|
|
303
|
+
useEffect(function () {
|
|
304
|
+
doSearch();
|
|
305
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
306
|
+
}, []);
|
|
307
|
+
|
|
272
308
|
var doInstall = useCallback(function (repo) {
|
|
273
309
|
var spec = "github:" + repo;
|
|
274
310
|
setInstalling(function (prev) {
|
|
@@ -289,14 +325,6 @@ window.__ModuleLoader__.load({
|
|
|
289
325
|
});
|
|
290
326
|
}, [call, track]);
|
|
291
327
|
|
|
292
|
-
var refreshInstalled = useCallback(function () {
|
|
293
|
-
call("installed", {}).then(function (value) {
|
|
294
|
-
setInstalled(value);
|
|
295
|
-
}).catch(function (e) {
|
|
296
|
-
setInstalled({ error: errorText(e) });
|
|
297
|
-
});
|
|
298
|
-
}, [call]);
|
|
299
|
-
|
|
300
328
|
useEffect(function () {
|
|
301
329
|
refreshInstalled();
|
|
302
330
|
}, [refreshInstalled]);
|
|
@@ -330,7 +358,7 @@ window.__ModuleLoader__.load({
|
|
|
330
358
|
h("div", { className: "mkt_columns" },
|
|
331
359
|
h("div", { className: "mkt_list" },
|
|
332
360
|
results == null
|
|
333
|
-
? h("div", { className: "mkt_meta" }, "
|
|
361
|
+
? h("div", { className: "mkt_meta" }, loading ? "正在加载最热插件…" : "—")
|
|
334
362
|
: results.items.length === 0
|
|
335
363
|
? h("div", { className: "mkt_meta" }, "没有匹配的仓库。")
|
|
336
364
|
: h(React.Fragment, null,
|
|
@@ -347,9 +375,9 @@ window.__ModuleLoader__.load({
|
|
|
347
375
|
)
|
|
348
376
|
),
|
|
349
377
|
h("div", { className: "mkt_rail" },
|
|
378
|
+
h(InstalledPanel, { installed: installed }),
|
|
350
379
|
h(InfoPanel, { info: info, onInstall: doInstall }),
|
|
351
|
-
h(JobsPanel, { jobs: jobs })
|
|
352
|
-
h(InstalledPanel, { installed: installed })
|
|
380
|
+
h(JobsPanel, { jobs: jobs })
|
|
353
381
|
)
|
|
354
382
|
)
|
|
355
383
|
);
|