dsh-life-pack 0.3.60 → 0.3.61

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/dist/client.js CHANGED
@@ -10488,32 +10488,38 @@ ${body}`;
10488
10488
  *
10489
10489
  * 上游首查回包里的 `manual`(精确手工命令)读出来交 `onManual`:带精确版本号与 registry,
10490
10490
  * 调用方拿它画自己的命令行+复制按钮(单一定位,不复述上游 details 里的同一条)。
10491
- * 只读、不重查:读两次(800/2600ms,覆盖默认 1000ms 轮询的首查落定),读不到就只剩双包命令。 */
10491
+ * 只读、不重查:每秒读一次、读到为止、最多 10 次(0.3.60 现场:固定两次读不到,首查落定比预期晚)。 */
10492
10492
  function TabInstallSlot(props) {
10493
10493
  const slotRef = react.useRef(null);
10494
10494
  const callReady = props.getCall() !== null;
10495
10495
  const onManualRef = react.useRef(props.onManual);
10496
- onManualRef.current = props.onManual;
10496
+ react.useEffect(() => {
10497
+ onManualRef.current = props.onManual;
10498
+ }, [props.onManual]);
10497
10499
  react.useEffect(() => {
10498
10500
  const mount = slotRef.current;
10499
10501
  if (mount === null || !callReady) return;
10500
10502
  const button = mountLifeInstallButton(mount, managerCallAdapter(props.getCall()), props.tab);
10501
10503
  if (button === null) return;
10502
10504
  let alive = true;
10503
- const timers = [];
10504
- for (const ms of [800, 2600]) {
10505
- if (typeof setTimeout !== "function") break;
10506
- timers.push(setTimeout(() => {
10507
- if (!alive) return;
10508
- try {
10509
- const manual = button.state().manual;
10510
- if (typeof manual === "string" && manual.length > 0) onManualRef.current?.(manual);
10511
- } catch {}
10512
- }, ms));
10513
- }
10505
+ let attempts = 0;
10506
+ const readOnce = () => {
10507
+ if (!alive) return;
10508
+ attempts += 1;
10509
+ try {
10510
+ const manual = button.state().manual;
10511
+ if (typeof manual === "string" && manual.length > 0) {
10512
+ onManualRef.current?.(manual);
10513
+ return;
10514
+ }
10515
+ } catch {}
10516
+ if (attempts < 10 && typeof setTimeout === "function") timer = setTimeout(readOnce, 1e3);
10517
+ };
10518
+ let timer = null;
10519
+ if (typeof setTimeout === "function") timer = setTimeout(readOnce, 800);
10514
10520
  return () => {
10515
10521
  alive = false;
10516
- for (const t of timers) clearTimeout(t);
10522
+ if (timer !== null) clearTimeout(timer);
10517
10523
  button.unmount();
10518
10524
  };
10519
10525
  }, [callReady, props.tab]);
@@ -10528,10 +10534,13 @@ ${body}`;
10528
10534
  * 全收敛在 `[data-ilife-absent]` 作用域下;容器 `S.reco` 与子顺序一字不动。
10529
10535
  * 上游主按钮换色用容器覆盖(`button[data-primary="1"]` 特异度压上游缺省;上游自带 CSS 无 hover
10530
10536
  * 规则,见 update-dialog.ts 注释——themeTokens 对安装控件无视觉效果,故悬停也收在这里)。
10531
- * 悬停取深橙+白字+投影(用户 verdict:8% 提亮看不见);颜色原型定稿 hex,见 v4 原型。 */
10537
+ * 悬停取深橙+白字+投影(用户 verdict:8% 提亮看不见);颜色原型定稿 hex,见 v4 原型。
10538
+ * 常态橙底(0.3.61 补上:首版只写了 hover 没写常态,线上按钮常态掉回宿主灰——原型 L33 整条)。
10539
+ * 上游自带折叠手工行(0.3.60 现场:②里贴着按钮又冒出一条“手工命令”):默认不动,
10540
+ * 只有当③的精确命令取到了(`data-manual="ready"`)才藏它——取不到时它仍是兜底。 */
10532
10541
  const ABSENT_TOAST_MS = 1500;
10533
10542
  function absentStepsCss() {
10534
- return "[data-ilife-absent=\"panel\"]>.ilife-step{display:block;position:relative;padding:10px 4px 10px 40px;border-bottom:1px solid rgba(255,255,255,.07)}[data-ilife-absent=\"panel\"]>.ilife-step:last-child{border-bottom:0}[data-ilife-absent=\"panel\"]>.ilife-step::before{content:attr(data-step);position:absolute;left:4px;top:10px;width:24px;height:24px;border-radius:50%;background:#2b2b2b;color:#9a9a9a;font-size:12px;display:flex;align-items:center;justify-content:center;font-weight:700}[data-ilife-absent=\"panel\"]>.ilife-step[data-step=\"1\"]::before{background:#e5534b;color:#fff}[data-ilife-absent=\"panel\"]>.ilife-step[data-step=\"2\"]::before{background:#f2a65a;color:#1a1206}[data-ilife-absent=\"panel\"] .ilife-step-t{display:block;color:#fff;font-weight:700;font-size:14px;margin-bottom:2px}[data-ilife-absent=\"panel\"] .ilife-tray{background:rgba(242,166,90,.08);border-radius:8px;padding:10px 12px}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]{transition:background .15s,color .15s,transform .06s,box-shadow .15s}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]:hover{background:#cf6f1f;color:#fff;transform:translateY(-1px);box-shadow:0 4px 14px rgba(207,111,31,.45)}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]:active{transform:translateY(1px);box-shadow:none;background:#a8561a;color:#fff}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]:disabled{opacity:.55;cursor:default;transform:none;box-shadow:none}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]:focus-visible{outline:2px solid #f2a65a;outline-offset:2px}[data-ilife-absent=\"panel\"] .ilife-cmdrow{display:flex;gap:8px;align-items:stretch;margin-top:8px}[data-ilife-absent=\"panel\"] .ilife-cmdrow>code{flex:1;padding:8px 10px;border-radius:8px;background:rgba(128,128,128,.12);color:#57b883;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;user-select:all;white-space:pre-wrap;overflow-wrap:anywhere}[data-ilife-absent=\"panel\"] .ilife-cmdrow>code.plain{color:inherit}[data-ilife-absent=\"panel\"] .ilife-copycmd{flex:0 0 auto;align-self:center;background:#2b2b2b;color:inherit;border:1px solid rgba(255,255,255,.12);border-radius:8px;padding:6px 14px;font-size:12.5px;cursor:pointer;transition:background .15s,border-color .15s,color .15s,transform .06s,box-shadow .15s}[data-ilife-absent=\"panel\"] .ilife-copycmd:hover{border-color:#f2a65a;color:#f2a65a;background:#353535;transform:translateY(-1px);box-shadow:0 2px 8px rgba(242,166,90,.25)}[data-ilife-absent=\"panel\"] .ilife-copycmd:active{transform:translateY(1px);box-shadow:none;background:#242424}[data-ilife-absent=\"panel\"] .ilife-copycmd:focus-visible{outline:2px solid #f2a65a;outline-offset:2px}[data-ilife-absent=\"toast\"]{position:fixed;left:50%;bottom:48px;transform:translateX(-50%) translateY(" + String(8) + "px);background:#1f1f1f;color:#fff;border:1px solid rgba(87,184,131,.6);border-radius:999px;padding:6px 18px;font-size:13px;z-index:99;animation:absentToastIn " + String(180 / 1e3) + "s ease}@keyframes absentToastIn{from{opacity:0;transform:translateX(-50%) translateY(" + String(8) + "px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}";
10543
+ return "[data-ilife-absent=\"panel\"]>.ilife-step{display:block;position:relative;padding:10px 4px 10px 40px;border-bottom:1px solid rgba(255,255,255,.07)}[data-ilife-absent=\"panel\"]>.ilife-step:last-child{border-bottom:0}[data-ilife-absent=\"panel\"]>.ilife-step::before{content:attr(data-step);position:absolute;left:4px;top:10px;width:24px;height:24px;border-radius:50%;background:#2b2b2b;color:#9a9a9a;font-size:12px;display:flex;align-items:center;justify-content:center;font-weight:700}[data-ilife-absent=\"panel\"]>.ilife-step[data-step=\"1\"]::before{background:#e5534b;color:#fff}[data-ilife-absent=\"panel\"]>.ilife-step[data-step=\"2\"]::before{background:#f2a65a;color:#1a1206}[data-ilife-absent=\"panel\"] .ilife-step-t{display:block;color:#fff;font-weight:700;font-size:14px;margin-bottom:2px}[data-ilife-absent=\"panel\"] .ilife-tray{background:rgba(242,166,90,.14);border-radius:8px;padding:10px 12px}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]{background:#f2a65a;color:#1a1206;border:0;border-radius:8px;padding:9px 24px;font-size:14px;font-weight:700;cursor:pointer;transition:background .15s,color .15s,transform .06s,box-shadow .15s}[data-ilife-absent=\"panel\"][data-manual=\"ready\"] .dsh-upd-ib-manual{display:none}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]:hover{background:#cf6f1f;color:#fff;transform:translateY(-1px);box-shadow:0 4px 14px rgba(207,111,31,.45)}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]:active{transform:translateY(1px);box-shadow:none;background:#a8561a;color:#fff}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]:disabled{opacity:.55;cursor:default;transform:none;box-shadow:none}[data-ilife-absent=\"panel\"] .dsh-upd-ib button[data-primary=\"1\"]:focus-visible{outline:2px solid #f2a65a;outline-offset:2px}[data-ilife-absent=\"panel\"] .ilife-cmdrow{display:flex;gap:8px;align-items:stretch;margin-top:8px}[data-ilife-absent=\"panel\"] .ilife-cmdrow>code{flex:1;padding:8px 10px;border-radius:8px;background:rgba(128,128,128,.12);color:#57b883;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;user-select:all;white-space:pre-wrap;overflow-wrap:anywhere}[data-ilife-absent=\"panel\"] .ilife-cmdrow>code.plain{color:#e8e8e8}[data-ilife-absent=\"panel\"] .ilife-copycmd{flex:0 0 auto;align-self:center;background:#2b2b2b;color:#e8e8e8;border:1px solid rgba(255,255,255,.12);border-radius:8px;padding:6px 14px;font-size:12.5px;cursor:pointer;transition:background .15s,border-color .15s,color .15s,transform .06s,box-shadow .15s}[data-ilife-absent=\"panel\"] .ilife-copycmd:hover{border-color:#f2a65a;color:#f2a65a;background:#353535;transform:translateY(-1px);box-shadow:0 2px 8px rgba(242,166,90,.25)}[data-ilife-absent=\"panel\"] .ilife-copycmd:active{transform:translateY(1px);box-shadow:none;background:#242424}[data-ilife-absent=\"panel\"] .ilife-copycmd:focus-visible{outline:2px solid #f2a65a;outline-offset:2px}[data-ilife-absent=\"toast\"]{position:fixed;left:50%;bottom:48px;transform:translateX(-50%) translateY(" + String(8) + "px);background:#1f1f1f;color:#fff;border:1px solid rgba(87,184,131,.6);border-radius:999px;padding:6px 18px;font-size:13px;z-index:99;animation:absentToastIn " + String(180 / 1e3) + "s ease}@keyframes absentToastIn{from{opacity:0;transform:translateX(-50%) translateY(" + String(8) + "px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}";
10535
10544
  }
10536
10545
  /** 命令行文本进剪贴板:先走 Clipboard API,摸不到(老宿主/非安全上下文)就地降级为隐藏 textarea。
10537
10546
  * 文案保持「复制」二字不动(用户口径):成功只弹 Toast,不改按钮字。 */
@@ -10603,7 +10612,8 @@ ${body}`;
10603
10612
  });
10604
10613
  return react.createElement("div", {
10605
10614
  style: S.reco,
10606
- "data-ilife-absent": "panel"
10615
+ "data-ilife-absent": "panel",
10616
+ "data-manual": manual !== null ? "ready" : "pending"
10607
10617
  }, react.createElement("style", { "data-ilife-absent": "steps-css" }, absentStepsCss()), react.createElement("span", {
10608
10618
  className: "ilife-step",
10609
10619
  "data-step": "1"
@@ -10642,7 +10652,7 @@ ${body}`;
10642
10652
  }, react.createElement("span", { style: S.morePkg }, row.pkg), react.createElement("span", { style: S.moreDesc }, row.desc), react.createElement("span", { style: S.moreIcon }, react.createElement(ExternalIcon, null)))));
10643
10653
  }
10644
10654
  /** 版本胶囊那一行字:只在这里拼一次,屏上与用例读的是同一串。 */
10645
- const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.60";
10655
+ const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.61";
10646
10656
  /** 右下角那本书离面板两沿的距离:用户口径「一直处于面板右下角、不随列表滑动消失」
10647
10657
  * ⇒ sticky 吸附(面板相对,视口多大都落在面板角上);INSET=右沿,BOTTOM=底沿。 */
10648
10658
  const MANUAL_ENTRY_INSET = 16;