cicy-desktop 2.1.49 → 2.1.51
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/package.json +1 -1
- package/src/backends/homepage-react/assets/{index-BowhPJHl.css → index-BN_rniiJ.css} +1 -1
- package/src/backends/homepage-react/assets/index-BPk6QOob.js +49 -0
- package/src/backends/homepage-react/index.html +2 -2
- package/workers/render/src/App.css +6 -0
- package/workers/render/src/App.jsx +37 -33
- package/src/backends/homepage-react/assets/index-CLpXv2cd.js +0 -49
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>CiCy Desktop</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-BPk6QOob.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-BN_rniiJ.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
|
@@ -671,6 +671,12 @@ body {
|
|
|
671
671
|
.bcard__menu-item.is-accent:hover { background: rgba(245,158,11,.15); color: #fcd34d; }
|
|
672
672
|
.bcard__menu-item.is-danger { color: #f7a3a3; }
|
|
673
673
|
.bcard__menu-item.is-danger:hover { background: rgba(239,68,68,.16); color: #fff; }
|
|
674
|
+
/* version from /api/health 探活 */
|
|
675
|
+
.bcard__ver {
|
|
676
|
+
font-size: 11px;
|
|
677
|
+
color: #8b949e;
|
|
678
|
+
font-variant-numeric: tabular-nums;
|
|
679
|
+
}
|
|
674
680
|
/* "新版 vX.Y.Z" chip on the card face */
|
|
675
681
|
.bcard__chip--new {
|
|
676
682
|
color: #fbbf24;
|
|
@@ -320,9 +320,16 @@ export default function App() {
|
|
|
320
320
|
|
|
321
321
|
// Logged in: unified tabs + cards grid on the left, full-height webview
|
|
322
322
|
// drawer on the right.
|
|
323
|
-
|
|
323
|
+
// Split the cicyDesktopNodes list into 本地 (the localhost:8008 sidecar the
|
|
324
|
+
// desktop owns — full lifecycle) vs 自定义 (deeplink-added nodes, usually
|
|
325
|
+
// remote — probe-only, no restart/stop/update, just 打开).
|
|
326
|
+
const localList = (localTeams || []).filter((t) => isLocalSidecar(t.base_url));
|
|
327
|
+
const customList = (localTeams || []).filter((t) => !isLocalSidecar(t.base_url));
|
|
328
|
+
const localCount = localList.length;
|
|
329
|
+
const customCount = customList.length;
|
|
324
330
|
const cloudCount = (teams || []).length;
|
|
325
331
|
const showLocal = tab === "all" || tab === "local";
|
|
332
|
+
const showCustom = tab === "all" || tab === "custom";
|
|
326
333
|
const showCloud = tab === "all" || tab === "cloud";
|
|
327
334
|
|
|
328
335
|
return (
|
|
@@ -333,9 +340,10 @@ export default function App() {
|
|
|
333
340
|
<main className="main">
|
|
334
341
|
<div className="app__tabs">
|
|
335
342
|
{[
|
|
336
|
-
{ k: "all",
|
|
337
|
-
{ k: "local",
|
|
338
|
-
{ k: "cloud",
|
|
343
|
+
{ k: "all", label: "全部", n: localCount + customCount + cloudCount },
|
|
344
|
+
{ k: "local", label: "本地", n: localCount },
|
|
345
|
+
{ k: "cloud", label: "云端", n: cloudCount },
|
|
346
|
+
{ k: "custom", label: "自定义", n: customCount },
|
|
339
347
|
].map(({ k, label, n }) => (
|
|
340
348
|
<button
|
|
341
349
|
key={k}
|
|
@@ -359,9 +367,12 @@ export default function App() {
|
|
|
359
367
|
)}
|
|
360
368
|
|
|
361
369
|
<div className="app__grid">
|
|
362
|
-
{showLocal &&
|
|
370
|
+
{showLocal && localList.map((t) => (
|
|
363
371
|
<LocalTeamCard key={"local:" + t.id} team={t} onOpen={() => openLocalTeam(t.id)} onRename={renameLocalTeam} onRefresh={fetchLocalTeams} />
|
|
364
372
|
))}
|
|
373
|
+
{showCustom && customList.map((t) => (
|
|
374
|
+
<LocalTeamCard key={"custom:" + t.id} team={t} onOpen={() => openLocalTeam(t.id)} onRename={renameLocalTeam} onRefresh={fetchLocalTeams} />
|
|
375
|
+
))}
|
|
365
376
|
{showCloud && teams && teams.map((t) => (
|
|
366
377
|
<TeamCard
|
|
367
378
|
key={"cloud:" + t.id}
|
|
@@ -439,11 +450,13 @@ function LocalTeamCard({ team, onOpen, onRename, onRefresh }) {
|
|
|
439
450
|
if (onRename && next && next !== team.name) await onRename(team.id, next);
|
|
440
451
|
};
|
|
441
452
|
|
|
442
|
-
//
|
|
443
|
-
//
|
|
444
|
-
//
|
|
445
|
-
//
|
|
446
|
-
|
|
453
|
+
// Lifecycle (启动 / 重启 / 更新 / 停止) acts on the daemon the desktop OWNS —
|
|
454
|
+
// localhost on the sidecar port (:8008). A remote node or a non-8008 port
|
|
455
|
+
// can't be controlled from here (sidecar.* would hit the wrong, local :8008),
|
|
456
|
+
// so those cards get 打开 only — no ⋯ menu, no update prompt. 打开 stays the
|
|
457
|
+
// one primary action; maintenance lives in the ⋯ menu.
|
|
458
|
+
const hasBridge = !!window.cicy?.sidecar?.restart;
|
|
459
|
+
const local = hasBridge && isLocalSidecar(team.base_url);
|
|
447
460
|
const running = team.status === "running";
|
|
448
461
|
const [busy, setBusy] = useState(""); // "" | start | restart | update | stop
|
|
449
462
|
const [opMsg, setOpMsg] = useState("");
|
|
@@ -455,17 +468,17 @@ function LocalTeamCard({ team, onOpen, onRename, onRefresh }) {
|
|
|
455
468
|
// exists (no nagging when current). Renderer-side via cloud.fetch — main
|
|
456
469
|
// proxies it, dodging CORS; no extra IPC needed.
|
|
457
470
|
useEffect(() => {
|
|
458
|
-
if (!
|
|
471
|
+
if (!local || !window.cicy?.cloud?.fetch) return;
|
|
459
472
|
let alive = true;
|
|
460
473
|
window.cicy.cloud
|
|
461
474
|
.fetch("https://registry.npmmirror.com/cicy-code/latest")
|
|
462
475
|
.then((r) => { if (alive && r?.ok) { try { setLatest(JSON.parse(r.body)?.version || null); } catch {} } })
|
|
463
476
|
.catch(() => {});
|
|
464
477
|
return () => { alive = false; };
|
|
465
|
-
}, [
|
|
478
|
+
}, [local]);
|
|
466
479
|
|
|
467
|
-
const updateAvailable = !!(latest && team.version && cmpVer(latest, team.version) > 0);
|
|
468
|
-
const showMenu =
|
|
480
|
+
const updateAvailable = !!(local && latest && team.version && cmpVer(latest, team.version) > 0);
|
|
481
|
+
const showMenu = local && (running || updateAvailable);
|
|
469
482
|
|
|
470
483
|
useEffect(() => {
|
|
471
484
|
if (!menuOpen) return;
|
|
@@ -492,18 +505,13 @@ function LocalTeamCard({ team, onOpen, onRename, onRefresh }) {
|
|
|
492
505
|
};
|
|
493
506
|
const BUSY_LABEL = { start: "启动中…", restart: "重启中…", update: "更新中…", stop: "停止中…" };
|
|
494
507
|
|
|
495
|
-
// Can we bring this daemon up locally? Only the 127.0.0.1:8008 team is the
|
|
496
|
-
// sidecar we own — a remote node (or a non-8008 local port) can't be started
|
|
497
|
-
// from the desktop, so for those 打开 just opens the window and lets the
|
|
498
|
-
// loaded page show its own connecting/login/error UI.
|
|
499
|
-
const localSidecar = hasOps && isLocalSidecar(team.base_url);
|
|
500
|
-
|
|
501
508
|
// 打开 is NEVER gated on /api/health — openTeam() in main doesn't check it,
|
|
502
|
-
// it just opens the window. health is an indicator, not a gate. When
|
|
503
|
-
// daemon is down we start it first;
|
|
509
|
+
// it just opens the window. health is an indicator, not a gate. When the
|
|
510
|
+
// LOCAL daemon is down we start it first; remote/other-port teams just open
|
|
511
|
+
// and let the loaded page show its own connecting/login/error UI.
|
|
504
512
|
const handleOpen = async () => {
|
|
505
513
|
if (busy) return;
|
|
506
|
-
if (!running &&
|
|
514
|
+
if (!running && local && window.cicy?.sidecar?.start) {
|
|
507
515
|
setBusy("start"); setOpMsg("");
|
|
508
516
|
const r = await window.cicy.sidecar.start().catch((e) => ({ ok: false, error: e?.message || String(e) }));
|
|
509
517
|
setBusy(""); onRefresh?.();
|
|
@@ -516,9 +524,9 @@ function LocalTeamCard({ team, onOpen, onRename, onRefresh }) {
|
|
|
516
524
|
};
|
|
517
525
|
const openLabel = running
|
|
518
526
|
? tr("localTeams.open", "打开")
|
|
519
|
-
:
|
|
520
|
-
? tr("localTeams.startOpen", "启动并打开")
|
|
521
|
-
: tr("localTeams.open", "打开");
|
|
527
|
+
: local
|
|
528
|
+
? tr("localTeams.startOpen", "启动并打开") // only the local sidecar can be started from here
|
|
529
|
+
: tr("localTeams.open", "打开"); // custom/remote: 探活-only, just open
|
|
522
530
|
return (
|
|
523
531
|
<div data-id="LocalTeamCard" className={`bcard bcard--local${tone === "ok" ? " bcard--online" : ""}`}>
|
|
524
532
|
<div className="bcard__accent" />
|
|
@@ -604,8 +612,9 @@ function LocalTeamCard({ team, onOpen, onRename, onRefresh }) {
|
|
|
604
612
|
{team.base_url || "—"}
|
|
605
613
|
</div>
|
|
606
614
|
<div className="bcard__meta">
|
|
607
|
-
|
|
608
|
-
|
|
615
|
+
{team.version && (
|
|
616
|
+
<span className="bcard__ver" data-id="LocalTeamCard-version">v{team.version}</span>
|
|
617
|
+
)}
|
|
609
618
|
{updateAvailable && (
|
|
610
619
|
<span
|
|
611
620
|
className="bcard__chip bcard__chip--new"
|
|
@@ -616,11 +625,6 @@ function LocalTeamCard({ team, onOpen, onRename, onRefresh }) {
|
|
|
616
625
|
</span>
|
|
617
626
|
)}
|
|
618
627
|
</div>
|
|
619
|
-
{(busy || opMsg) && (
|
|
620
|
-
<div className="bcard__opmsg" data-id="LocalTeamCard-opmsg">
|
|
621
|
-
{busy ? <><Spinner />{BUSY_LABEL[busy] || tr("sidecar.working", "处理中…")}</> : opMsg}
|
|
622
|
-
</div>
|
|
623
|
-
)}
|
|
624
628
|
</div>
|
|
625
629
|
<button
|
|
626
630
|
type="button"
|