@ottttto/dsh-scheduled-send 0.3.1 → 0.3.3

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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "@ottttto/dsh-scheduled-send",
3
- "version": "0.2.3",
3
+ "version": "0.3.3",
4
4
  "main": "./src/index.js",
5
5
  "description": "定时发送:到点以你的身份把消息作为正常用户气泡发进当前会话,无人值守、会话隔离、断电补发。Scheduled send for DSH — fires as a normal user bubble into the bound conversation, unattended, per-session isolated, restart-safe.",
6
6
  "engines": {
package/lib/client.js CHANGED
@@ -499,6 +499,7 @@ function createClientPluginBody(React) {
499
499
  const core = props.panelCore;
500
500
  const [open, setOpen] = React.useState(false);
501
501
  const [tick, setTick] = React.useState(0);
502
+ const [hover, setHover] = React.useState(false);
502
503
  const mobile = isMobile();
503
504
 
504
505
  // keep the badge alive even while the panel is closed: poll the FULL
@@ -523,11 +524,28 @@ function createClientPluginBody(React) {
523
524
  const overflow = Math.max(0, all.length - annotated.length);
524
525
 
525
526
  const isDark = typeof window !== "undefined" && window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
527
+ // mirrors usage-stats' footer trigger: same metrics + theme variables as
528
+ // the system sidebar rows (hover comes from the injected var-only rule)
529
+ const layerStyle = {
530
+ flex: "none", alignItems: "center", width: "100%", height: 49,
531
+ margin: "8px 0 0", display: "flex", position: "relative",
532
+ ...(mobile ? { height: 44 } : {}),
533
+ };
526
534
  const entryBtn = {
527
- cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 6,
528
- border: "none", background: "transparent", color: "inherit",
529
- fontSize: 12, fontWeight: 600, padding: "4px 8px", borderRadius: 8, whiteSpace: "nowrap",
530
- ...(mobile ? { minHeight: TOUCH_MIN } : {}),
535
+ width: "100%", height: mobile ? 44 : 49, color: "var(--dsw-alias-label-primary)",
536
+ cursor: "pointer", background: "0 0", border: "none", borderRadius: 12,
537
+ alignItems: "center", gap: 8, padding: "0 8px 0 6px", fontFamily: "inherit",
538
+ fontSize: 14, display: "inline-flex", overflow: "hidden",
539
+ };
540
+ const iconBox = { display: "inline-flex", width: mobile ? 18 : 16, justifyContent: "center", flexShrink: 0 };
541
+ const labelStyle = { textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0, overflow: "hidden" };
542
+ const amountStyle = {
543
+ color: "var(--dsw-alias-label-secondary)", fontVariantNumeric: "tabular-nums",
544
+ flex: "none", fontSize: 12, fontWeight: 600, lineHeight: "16px",
545
+ };
546
+ const countStyle = {
547
+ color: "var(--dsw-alias-label-tertiary)", fontVariantNumeric: "tabular-nums",
548
+ flex: "none", marginLeft: "auto", fontSize: 12, lineHeight: "16px",
531
549
  };
532
550
  const badge = (n) => h("span", {
533
551
  key: "b", "data-badge": n,
@@ -623,14 +641,17 @@ function createClientPluginBody(React) {
623
641
  ])
624
642
  : null;
625
643
 
626
- return h("div", { "data-plugin": "dsh-scheduled-send-sidebar", style: { display: "inline-flex", alignItems: "center" } }, [
644
+ return h("div", { "data-plugin": "dsh-scheduled-send-sidebar", style: layerStyle }, [
645
+ h("style", { key: "css" }, '.ssb_badge:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}'),
627
646
  h("button", {
628
647
  key: "btn", type: "button",
648
+ className: "ssb_badge",
629
649
  onClick: () => { setOpen(!open); setTick((n) => n + 1); },
630
650
  title: "定时任务", "aria-label": "定时任务", style: entryBtn,
631
651
  }, [
632
- h("span", { key: "l" }, "⏰ 定时任务"),
633
- all.length ? badge(all.length) : null,
652
+ h("span", { key: "i", style: iconBox }, "⏰"),
653
+ h("span", { key: "l", style: labelStyle }, "定时任务"),
654
+ all.length ? h("span", { key: "bs", style: countStyle }, String(all.length)) : null,
634
655
  ]),
635
656
  footer,
636
657
  ]);
@@ -690,6 +711,9 @@ function createClientPluginBody(React) {
690
711
 
691
712
  const inject = ["slots", "sessions"]; // sessions: sidebar panel jump (0.3.0)
692
713
  function apply(ctx) {
714
+ // due-time delivery: refresh the sidebar panel the moment a task fires
715
+ ctx.on?.('guard/scheduled-due', () => { void panelCore.refresh(); });
716
+ ctx.on?.('guard/scheduled-dropped', () => { void panelCore.refresh(); });
693
717
  ctx.inject(inject, (scope) => {
694
718
  // 0.3.0 session navigation, sourced from the sessions service:
695
719
  // - open(id) selects a session as current (unknown ids throw → false)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ottttto/dsh-scheduled-send",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "DSH plugin: scheduled sending (⏰ composer button, dock list of pending tasks, sidebar 定时任务 panel with cross-session cancel, due-time delivery as a normal user bubble)",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -52,4 +52,4 @@
52
52
  "engines": {
53
53
  "node": ">=18"
54
54
  }
55
- }
55
+ }
@@ -235,6 +235,7 @@ function createClientPluginBody(React) {
235
235
  const core = props.panelCore;
236
236
  const [open, setOpen] = React.useState(false);
237
237
  const [tick, setTick] = React.useState(0);
238
+ const [hover, setHover] = React.useState(false);
238
239
  const mobile = isMobile();
239
240
 
240
241
  // keep the badge alive even while the panel is closed: poll the FULL
@@ -259,11 +260,28 @@ function createClientPluginBody(React) {
259
260
  const overflow = Math.max(0, all.length - annotated.length);
260
261
 
261
262
  const isDark = typeof window !== "undefined" && window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
263
+ // mirrors usage-stats' footer trigger: same metrics + theme variables as
264
+ // the system sidebar rows (hover comes from the injected var-only rule)
265
+ const layerStyle = {
266
+ flex: "none", alignItems: "center", width: "100%", height: 49,
267
+ margin: "8px 0 0", display: "flex", position: "relative",
268
+ ...(mobile ? { height: 44 } : {}),
269
+ };
262
270
  const entryBtn = {
263
- cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 6,
264
- border: "none", background: "transparent", color: "inherit",
265
- fontSize: 12, fontWeight: 600, padding: "4px 8px", borderRadius: 8, whiteSpace: "nowrap",
266
- ...(mobile ? { minHeight: TOUCH_MIN } : {}),
271
+ width: "100%", height: mobile ? 44 : 49, color: "var(--dsw-alias-label-primary)",
272
+ cursor: "pointer", background: "0 0", border: "none", borderRadius: 12,
273
+ alignItems: "center", gap: 8, padding: "0 8px 0 6px", fontFamily: "inherit",
274
+ fontSize: 14, display: "inline-flex", overflow: "hidden",
275
+ };
276
+ const iconBox = { display: "inline-flex", width: mobile ? 18 : 16, justifyContent: "center", flexShrink: 0 };
277
+ const labelStyle = { textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0, overflow: "hidden" };
278
+ const amountStyle = {
279
+ color: "var(--dsw-alias-label-secondary)", fontVariantNumeric: "tabular-nums",
280
+ flex: "none", fontSize: 12, fontWeight: 600, lineHeight: "16px",
281
+ };
282
+ const countStyle = {
283
+ color: "var(--dsw-alias-label-tertiary)", fontVariantNumeric: "tabular-nums",
284
+ flex: "none", marginLeft: "auto", fontSize: 12, lineHeight: "16px",
267
285
  };
268
286
  const badge = (n) => h("span", {
269
287
  key: "b", "data-badge": n,
@@ -359,14 +377,17 @@ function createClientPluginBody(React) {
359
377
  ])
360
378
  : null;
361
379
 
362
- return h("div", { "data-plugin": "dsh-scheduled-send-sidebar", style: { display: "inline-flex", alignItems: "center" } }, [
380
+ return h("div", { "data-plugin": "dsh-scheduled-send-sidebar", style: layerStyle }, [
381
+ h("style", { key: "css" }, '.ssb_badge:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}'),
363
382
  h("button", {
364
383
  key: "btn", type: "button",
384
+ className: "ssb_badge",
365
385
  onClick: () => { setOpen(!open); setTick((n) => n + 1); },
366
386
  title: "定时任务", "aria-label": "定时任务", style: entryBtn,
367
387
  }, [
368
- h("span", { key: "l" }, "⏰ 定时任务"),
369
- all.length ? badge(all.length) : null,
388
+ h("span", { key: "i", style: iconBox }, "⏰"),
389
+ h("span", { key: "l", style: labelStyle }, "定时任务"),
390
+ all.length ? h("span", { key: "bs", style: countStyle }, String(all.length)) : null,
370
391
  ]),
371
392
  footer,
372
393
  ]);
@@ -426,6 +447,9 @@ function createClientPluginBody(React) {
426
447
 
427
448
  const inject = ["slots", "sessions"]; // sessions: sidebar panel jump (0.3.0)
428
449
  function apply(ctx) {
450
+ // due-time delivery: refresh the sidebar panel the moment a task fires
451
+ ctx.on?.('guard/scheduled-due', () => { void panelCore.refresh(); });
452
+ ctx.on?.('guard/scheduled-dropped', () => { void panelCore.refresh(); });
429
453
  ctx.inject(inject, (scope) => {
430
454
  // 0.3.0 session navigation, sourced from the sessions service:
431
455
  // - open(id) selects a session as current (unknown ids throw → false)