dsh-workbuddy-xdpool 1.0.0 → 1.1.0
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 +96 -0
- package/lib/bin.js +614 -8
- package/lib/client.js +303 -123
- package/lib/index.d.ts +377 -0
- package/lib/index.js +697 -16
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -28,8 +28,6 @@ window.__ModuleLoader__.load({
|
|
|
28
28
|
const POOL_RESET_COOLDOWN_PATH = "/plugins/dsh-workbuddy-xdpool/cooldowns/reset";
|
|
29
29
|
/** Plugin-owned daily check-in action endpoint (claim today's reward). */
|
|
30
30
|
const POOL_CHECKIN_PATH = "/plugins/dsh-workbuddy-xdpool/checkin";
|
|
31
|
-
/** Switch one account in or out of the pool (card toggle). */
|
|
32
|
-
const POOL_ACCOUNT_DISABLE_PATH = "/plugins/dsh-workbuddy-xdpool/accounts/disabled";
|
|
33
31
|
//#endregion
|
|
34
32
|
//#region src/client/icon.ts
|
|
35
33
|
/**
|
|
@@ -130,18 +128,32 @@ window.__ModuleLoader__.load({
|
|
|
130
128
|
/* Account list (each account = a labeled subpanel, same as dingminhua). */
|
|
131
129
|
.dsm-workbuddy-xdpool-accounts{display:flex;flex-direction:column;gap:14px;border-top:1px solid var(--dsw-alias-border-l2,#36373b);padding-top:14px}
|
|
132
130
|
.dsm-workbuddy-xdpool-accounts-head{display:flex;align-items:center;justify-content:space-between;gap:12px}
|
|
131
|
+
/* "In use now": answers which account is serving without scanning every row. */
|
|
132
|
+
/* A hairline + tint reads as status; a filled bar would read as a call to action. */
|
|
133
|
+
.dsm-workbuddy-xdpool-current{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin:10px 0 0;padding:9px 13px;border:1px solid color-mix(in oklab, var(--dsw-alias-state-success-primary,#22a06b) 32%, transparent);border-radius:12px;background:color-mix(in oklab, var(--dsw-alias-state-success-primary,#22a06b) 9%, transparent)}
|
|
134
|
+
.dsm-workbuddy-xdpool-current-dot{width:7px;height:7px;border-radius:50%;flex:none;background:var(--dsw-alias-state-success-primary,#22a06b);box-shadow:0 0 0 3px color-mix(in oklab, var(--dsw-alias-state-success-primary,#22a06b) 18%, transparent)}
|
|
135
|
+
.dsm-workbuddy-xdpool-current-label{color:var(--dsw-alias-state-success-primary,#22a06b);font-size:11.5px;line-height:18px;font-weight:600;letter-spacing:.02em;flex:none}
|
|
136
|
+
.dsm-workbuddy-xdpool-current-name{color:var(--dsw-alias-label-primary,#e6e6e6);font-size:13px;line-height:18px;font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
137
|
+
.dsm-workbuddy-xdpool-current-note{color:var(--dsw-alias-state-warning-primary,#d97706);font-size:11px;line-height:16px}
|
|
133
138
|
.dsm-workbuddy-xdpool-accounts-title{margin:0;color:var(--dsw-alias-label-primary,#e6e6e6);font-size:14px;font-weight:600;line-height:20px}
|
|
134
139
|
.dsm-workbuddy-xdpool-accounts-summary{margin:2px 0 0;color:var(--dsw-alias-label-tertiary,#999);font-size:12px;line-height:18px}
|
|
135
|
-
.dsm-workbuddy-xdpool-account{display:flex;
|
|
136
|
-
.
|
|
140
|
+
.dsm-workbuddy-xdpool-account{display:flex;flex-direction:column;gap:0;padding:0;border:1px solid color-mix(in oklab, var(--dsw-alias-border-l2,#3a3d45) 55%, transparent);border-radius:16px;background:var(--dsw-alias-bg-layer-2,#24262c);box-shadow:0 1px 3px rgba(0,0,0,.04);overflow:hidden}
|
|
141
|
+
/* Body row inside a card: identity on the left, credit panels on the right. */
|
|
142
|
+
/* flex-wrap lets the panels drop below on a narrow card instead of squeezing both. */
|
|
143
|
+
.dsm-workbuddy-xdpool-account-body{display:flex;align-items:stretch;gap:0;flex-wrap:wrap}
|
|
144
|
+
.dsm-workbuddy-xdpool-account-copy{display:flex;flex-direction:column;align-items:flex-start;gap:6px;flex:1 1 200px;min-width:0;padding:14px 16px;justify-content:center}
|
|
137
145
|
.dsm-workbuddy-xdpool-account-label{color:var(--dsw-alias-label-primary,#e6e6e6);font-size:14px;font-weight:600;line-height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
138
|
-
.dsm-workbuddy-xdpool-account-head{
|
|
146
|
+
.dsm-workbuddy-xdpool-account-head .dsm-workbuddy-xdpool-account-toggle{margin-left:auto}
|
|
147
|
+
.dsm-workbuddy-xdpool-account-head{display:flex;align-items:center;gap:10px;min-width:0;padding:12px 16px;border-bottom:1px solid color-mix(in oklab, var(--dsw-alias-border-l2,#3a3d45) 45%, transparent)}
|
|
139
148
|
/* Account switched off on the card: still listed (so it can be turned back on) but visually muted. */
|
|
140
149
|
.dsm-workbuddy-xdpool-account-off{opacity:.55}
|
|
141
150
|
/* Small pill switch: "in rotation" vs "off". Native checkbox styled by the label. */
|
|
142
|
-
.dsm-workbuddy-xdpool-account-toggle{display:inline-flex;align-items:center;gap:5px;flex:none;
|
|
143
|
-
.dsm-workbuddy-xdpool-account-toggle
|
|
144
|
-
.dsm-workbuddy-xdpool-account-toggle:
|
|
151
|
+
.dsm-workbuddy-xdpool-account-toggle{appearance:none;font:inherit;display:inline-flex;align-items:center;gap:5px;cursor:pointer;flex:none;border:1px solid color-mix(in oklab, var(--dsw-alias-border-l2,#3a3d45) 70%, transparent);border-radius:999px;padding:3px 10px;font-size:11px;line-height:17px;background:transparent;color:var(--dsw-alias-label-tertiary,#9aa0a8);transition:color .16s,border-color .16s,background .16s}
|
|
152
|
+
.dsm-workbuddy-xdpool-account-toggle:hover:not(:disabled){color:var(--dsw-alias-label-primary,#e6e6e6);border-color:var(--dsw-alias-label-dimmed,#777)}
|
|
153
|
+
.dsm-workbuddy-xdpool-account-toggle:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#5686fe);outline-offset:1px}
|
|
154
|
+
.dsm-workbuddy-xdpool-account-toggle:disabled{cursor:default;opacity:.6}
|
|
155
|
+
.dsm-workbuddy-xdpool-account-toggle-on{background:color-mix(in oklab, var(--dsw-alias-state-success-primary,#22a06b) 14%, transparent);border-color:color-mix(in oklab, var(--dsw-alias-state-success-primary,#22a06b) 55%, transparent);color:var(--dsw-alias-state-success-primary,#22a06b);font-weight:600}
|
|
156
|
+
.dsm-workbuddy-xdpool-account-toggle-dot{width:6px;height:6px;border-radius:50%;flex:none;background:currentColor;opacity:.9}
|
|
145
157
|
.dsm-workbuddy-xdpool-account-tags{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
|
|
146
158
|
.dsm-workbuddy-xdpool-account-tag{padding:1px 8px;border-radius:999px;font-size:11px;line-height:18px;background:var(--dsw-alias-state-success-subtle,rgba(34,160,107,.12));color:var(--dsw-alias-state-success-primary,#22a06b)}
|
|
147
159
|
.dsm-workbuddy-xdpool-account-tag-cooling{background:var(--dsw-alias-state-warning-subtle,rgba(217,119,6,.15));color:var(--dsw-alias-state-warning-primary,#d97706)}
|
|
@@ -152,9 +164,9 @@ window.__ModuleLoader__.load({
|
|
|
152
164
|
.dsm-workbuddy-xdpool-account-error{margin:0;color:var(--dsw-alias-state-error-primary,#ef4444);font-size:13px;line-height:20px}
|
|
153
165
|
|
|
154
166
|
/* Two-column stats: packages on the left, total + check-in on the right. */
|
|
155
|
-
.dsm-workbuddy-xdpool-stats{display:grid;grid-template-columns:minmax(0,1.
|
|
156
|
-
.dsm-workbuddy-xdpool-panel{display:flex;flex-direction:column;min-width:0;gap:7px;padding:14px
|
|
157
|
-
.dsm-workbuddy-xdpool-panel-title{color:var(--dsw-alias-label-tertiary,#999);font-size:
|
|
167
|
+
.dsm-workbuddy-xdpool-stats{display:grid;grid-template-columns:minmax(0,1.45fr) minmax(168px,.85fr);gap:0;flex:1 1 420px;min-width:0;max-width:660px;border-left:1px solid color-mix(in oklab, var(--dsw-alias-border-l2,#3a3d45) 45%, transparent)}
|
|
168
|
+
.dsm-workbuddy-xdpool-panel{display:flex;flex-direction:column;min-width:0;gap:7px;padding:14px 16px}
|
|
169
|
+
.dsm-workbuddy-xdpool-panel-title{color:var(--dsw-alias-label-tertiary,#999);font-size:11px;line-height:16px;letter-spacing:.03em;text-transform:uppercase;font-weight:600}
|
|
158
170
|
.dsm-workbuddy-xdpool-panel-empty{color:var(--dsw-alias-label-tertiary,#999);font-size:14px;line-height:20px}
|
|
159
171
|
.dsm-workbuddy-xdpool-panel-error{color:var(--dsw-alias-state-error-primary,#ef4444);font-size:12px;line-height:18px;word-break:break-word}
|
|
160
172
|
.dsm-workbuddy-xdpool-panel-foot{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-top:9px;padding-top:9px;border-top:1px solid var(--dsw-alias-border-l2,#36373b);color:var(--dsw-alias-label-secondary,#c6c9d0);font-size:12px;line-height:18px}
|
|
@@ -172,9 +184,9 @@ window.__ModuleLoader__.load({
|
|
|
172
184
|
fold onto their own line so a long package name cannot squeeze them out. */
|
|
173
185
|
.dsm-workbuddy-xdpool-packages-when{grid-column:1/-1;color:var(--dsw-alias-label-tertiary,#9aa0a8);font-size:11px;line-height:15px;font-variant-numeric:tabular-nums}
|
|
174
186
|
.dsm-workbuddy-xdpool-packages-when-soon{color:var(--dsw-alias-state-warning-primary,#d97706)}
|
|
175
|
-
.dsm-workbuddy-xdpool-panel-total{position:relative;align-items:center;text-align:center;overflow:hidden}
|
|
187
|
+
.dsm-workbuddy-xdpool-panel-total{position:relative;align-items:center;text-align:center;justify-content:center;overflow:hidden;background:color-mix(in oklab, var(--dsw-alias-state-success-primary,#22a06b) 5%, transparent)}
|
|
176
188
|
.dsm-workbuddy-xdpool-panel-total::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;opacity:.9;background:var(--dsw-alias-state-success-primary,#22a06b)}
|
|
177
|
-
.dsm-workbuddy-xdpool-total-value{color:var(--dsw-alias-state-success-primary,#22a06b);font-size:
|
|
189
|
+
.dsm-workbuddy-xdpool-total-value{color:var(--dsw-alias-state-success-primary,#22a06b);font-size:28px;line-height:32px;font-weight:800;letter-spacing:-.02em;white-space:nowrap;font-variant-numeric:tabular-nums}
|
|
178
190
|
|
|
179
191
|
/* Model directory list. */
|
|
180
192
|
.dsm-workbuddy-xdpool-models{display:flex;flex-direction:column;gap:10px;border-top:1px solid var(--dsw-alias-border-l2,#36373b);padding-top:14px}
|
|
@@ -231,6 +243,21 @@ window.__ModuleLoader__.load({
|
|
|
231
243
|
.dsm-workbuddy-xdpool-checkin-meta{align-items:flex-start}
|
|
232
244
|
.dsm-workbuddy-xdpool-checkin-bonus{text-align:left}
|
|
233
245
|
}
|
|
246
|
+
|
|
247
|
+
/* Automation panel: schedule and last-run summary, collapsed behind a switch. */
|
|
248
|
+
.dsm-workbuddy-xdpool-auto{margin-top:12px;padding:10px 12px;border:1px solid var(--dsw-alias-border-l2,#36373b);border-radius:10px;background:var(--dsw-alias-bg-module-platform,#202126)}
|
|
249
|
+
.dsm-workbuddy-xdpool-auto-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
|
|
250
|
+
.dsm-workbuddy-xdpool-auto-title{color:var(--dsw-alias-label-primary,#e8e8ea);font-size:12px;font-weight:600}
|
|
251
|
+
.dsm-workbuddy-xdpool-auto-switch{padding:3px 12px;border:1px solid var(--dsw-alias-border-l2,#36373b);border-radius:999px;background:transparent;color:var(--dsw-alias-label-dimmed,#8a97b5);font-size:11px;cursor:pointer;transition:color .16s,border-color .16s,background .16s}
|
|
252
|
+
.dsm-workbuddy-xdpool-auto-switch:hover:not(:disabled){border-color:var(--dsw-alias-label-dimmed,#777);color:var(--dsw-alias-label-primary,#e8e8ea)}
|
|
253
|
+
.dsm-workbuddy-xdpool-auto-switch:disabled{opacity:.5;cursor:not-allowed}
|
|
254
|
+
.dsm-workbuddy-xdpool-auto-switch-on{border-color:#28c8b4;color:#28c8b4;background:rgba(40,200,180,.12)}
|
|
255
|
+
.dsm-workbuddy-xdpool-auto-hint{margin:6px 0 0;color:var(--dsw-alias-label-dimmed,#8a97b5);font-size:11px;line-height:1.5}
|
|
256
|
+
.dsm-workbuddy-xdpool-auto-jobs{margin-top:8px;display:flex;flex-direction:column;gap:4px}
|
|
257
|
+
.dsm-workbuddy-xdpool-auto-job{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--dsw-alias-label-dimmed,#8a97b5)}
|
|
258
|
+
.dsm-workbuddy-xdpool-auto-job-name{flex:0 0 72px;color:var(--dsw-alias-label-primary,#e8e8ea)}
|
|
259
|
+
.dsm-workbuddy-xdpool-auto-job-when{flex:1 1 auto;font-variant-numeric:tabular-nums}
|
|
260
|
+
.dsm-workbuddy-xdpool-auto-job-last{flex:0 0 auto;text-align:right;font-variant-numeric:tabular-nums}
|
|
234
261
|
`.trim();
|
|
235
262
|
//#endregion
|
|
236
263
|
//#region src/client/PoolCard.tsx
|
|
@@ -291,6 +318,35 @@ window.__ModuleLoader__.load({
|
|
|
291
318
|
minute: "2-digit"
|
|
292
319
|
}).format(new Date(ms));
|
|
293
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* The automation jobs, in the order they run.
|
|
323
|
+
*
|
|
324
|
+
* The order is the contract: the report has to land before the task pass, or
|
|
325
|
+
* the task pass reads progress the report would have lit. `hoursOf` reads the
|
|
326
|
+
* matching hour list off the status document so the panel stays in step with
|
|
327
|
+
* whatever schedule the scheduler is actually running on.
|
|
328
|
+
*/
|
|
329
|
+
const AUTOMATION_JOBS = [
|
|
330
|
+
"report",
|
|
331
|
+
"tasks",
|
|
332
|
+
"checkin",
|
|
333
|
+
"streak"
|
|
334
|
+
];
|
|
335
|
+
/** Read one job's configured hours off the status document. */
|
|
336
|
+
function automationHours(status, kind) {
|
|
337
|
+
const automation = status.automation;
|
|
338
|
+
if (automation === void 0) return [];
|
|
339
|
+
switch (kind) {
|
|
340
|
+
case "report": return automation.reportHours;
|
|
341
|
+
case "tasks": return automation.taskHours;
|
|
342
|
+
case "checkin": return automation.checkinHours;
|
|
343
|
+
case "streak": return automation.streakHours;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/** Read one job's last-run record off the status document. */
|
|
347
|
+
function automationJob(status, kind) {
|
|
348
|
+
return status.automation?.jobs[kind];
|
|
349
|
+
}
|
|
294
350
|
function dotColor(status) {
|
|
295
351
|
return status === "ok" ? "var(--dsw-alias-state-success-primary, #22a06b)" : status === "error" ? "var(--dsw-alias-state-error-primary, #ef4444)" : "var(--dsw-alias-label-dimmed, #9aa0a6)";
|
|
296
352
|
}
|
|
@@ -380,6 +436,7 @@ window.__ModuleLoader__.load({
|
|
|
380
436
|
const [error, setError] = (0, react.useState)(void 0);
|
|
381
437
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
382
438
|
const [cooldownBusy, setCooldownBusy] = (0, react.useState)(false);
|
|
439
|
+
const [automationBusy, setAutomationBusy] = (0, react.useState)(false);
|
|
383
440
|
const [flash, setFlash] = (0, react.useState)(void 0);
|
|
384
441
|
/** Account id whose daily claim is currently in flight. */
|
|
385
442
|
const [checkinBusyId, setCheckinBusyId] = (0, react.useState)(void 0);
|
|
@@ -530,27 +587,21 @@ window.__ModuleLoader__.load({
|
|
|
530
587
|
* restart and is re-applied after every re-scan.
|
|
531
588
|
*/
|
|
532
589
|
const toggleAccountDisabled = async (accountId, disabled) => {
|
|
590
|
+
const write = settingsScope?.set;
|
|
591
|
+
if (write === void 0) {
|
|
592
|
+
setError(t?.("row.modelsSaveError", { message: "settings scope is read-only" }) ?? "settings scope is read-only");
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
533
595
|
setAccountBusyId(accountId);
|
|
534
596
|
setFlash(void 0);
|
|
535
597
|
try {
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
accept: "application/json",
|
|
540
|
-
"content-type": "application/json"
|
|
541
|
-
},
|
|
542
|
-
credentials: "same-origin",
|
|
543
|
-
body: JSON.stringify({
|
|
544
|
-
accountId,
|
|
545
|
-
disabled
|
|
546
|
-
})
|
|
547
|
-
});
|
|
548
|
-
const body = await response.json().catch(() => void 0);
|
|
549
|
-
if (!response.ok) throw new Error(body?.error ?? `HTTP ${response.status}`);
|
|
598
|
+
const current = (status?.accounts ?? []).filter((account) => account.disabled === true).map((account) => account.id);
|
|
599
|
+
const next = disabled ? current.includes(accountId) ? current : [...current, accountId] : current.filter((id) => id !== accountId);
|
|
600
|
+
await write.call(settingsScope, "disabledAccountIds", next);
|
|
550
601
|
await refresh(activeRegion);
|
|
551
602
|
} catch (cause) {
|
|
552
603
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
553
|
-
if (mounted.current) setError(t?.("row.accountToggleError", { message }) ??
|
|
604
|
+
if (mounted.current) setError(t?.("row.accountToggleError", { message }) ?? "Could not switch the account: " + message);
|
|
554
605
|
} finally {
|
|
555
606
|
if (mounted.current) setAccountBusyId(void 0);
|
|
556
607
|
}
|
|
@@ -640,6 +691,39 @@ window.__ModuleLoader__.load({
|
|
|
640
691
|
if (mounted.current) setError(String(cause));
|
|
641
692
|
}
|
|
642
693
|
};
|
|
694
|
+
/**
|
|
695
|
+
* Switch the daily-points automation on or off.
|
|
696
|
+
*
|
|
697
|
+
* The whole `automation` object is written as one key, because that is how the
|
|
698
|
+
* settings document stores it: the schedule fields must be carried along, or a
|
|
699
|
+
* save would drop the hour lists the scheduler is running on.
|
|
700
|
+
*/
|
|
701
|
+
const setAutomationEnabled = async (enabled) => {
|
|
702
|
+
const write = settingsScope?.set;
|
|
703
|
+
if (write === void 0) {
|
|
704
|
+
setError(t?.("row.modelsSaveError", { message: "settings scope is read-only" }) ?? "settings scope is read-only");
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
const existing = status?.automation;
|
|
708
|
+
setAutomationBusy(true);
|
|
709
|
+
setFlash(void 0);
|
|
710
|
+
try {
|
|
711
|
+
await write.call(settingsScope, "automation", {
|
|
712
|
+
...existing === void 0 ? {} : {
|
|
713
|
+
checkinHours: [...existing.checkinHours],
|
|
714
|
+
reportHours: [...existing.reportHours],
|
|
715
|
+
taskHours: [...existing.taskHours],
|
|
716
|
+
streakHours: [...existing.streakHours]
|
|
717
|
+
},
|
|
718
|
+
enabled
|
|
719
|
+
});
|
|
720
|
+
await refresh(activeRegion);
|
|
721
|
+
} catch (cause) {
|
|
722
|
+
if (mounted.current) setError(String(cause));
|
|
723
|
+
} finally {
|
|
724
|
+
if (mounted.current) setAutomationBusy(false);
|
|
725
|
+
}
|
|
726
|
+
};
|
|
643
727
|
const saveModels = async () => {
|
|
644
728
|
if (draft === void 0 || status === void 0) return;
|
|
645
729
|
if (enabledCount === 0) {
|
|
@@ -812,6 +896,58 @@ window.__ModuleLoader__.load({
|
|
|
812
896
|
}) : null]
|
|
813
897
|
})]
|
|
814
898
|
}),
|
|
899
|
+
status?.automation === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
900
|
+
className: "dsm-workbuddy-xdpool-auto",
|
|
901
|
+
"aria-label": t?.("row.autoTitle") ?? "Automation",
|
|
902
|
+
children: [
|
|
903
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
904
|
+
className: "dsm-workbuddy-xdpool-auto-head",
|
|
905
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
906
|
+
className: "dsm-workbuddy-xdpool-auto-title",
|
|
907
|
+
children: t?.("row.autoTitle") ?? "Automation"
|
|
908
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
909
|
+
type: "button",
|
|
910
|
+
role: "switch",
|
|
911
|
+
"aria-checked": status.automation.enabled,
|
|
912
|
+
disabled: !settingsWritable || automationBusy,
|
|
913
|
+
className: `dsm-workbuddy-xdpool-auto-switch${status.automation.enabled ? " dsm-workbuddy-xdpool-auto-switch-on" : ""}`,
|
|
914
|
+
onClick: () => {
|
|
915
|
+
setAutomationEnabled(!status.automation.enabled);
|
|
916
|
+
},
|
|
917
|
+
children: automationBusy ? t?.("row.autoBusy") ?? "Saving…" : status.automation.enabled ? t?.("row.autoOn") ?? "On" : t?.("row.autoOff") ?? "Off"
|
|
918
|
+
})]
|
|
919
|
+
}),
|
|
920
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
921
|
+
className: "dsm-workbuddy-xdpool-auto-hint",
|
|
922
|
+
children: status.automation.enabled ? t?.("row.autoHintOn") ?? "Reports activity, claims task rewards and checks in once a day." : t?.("row.autoHintOff") ?? "Off: no background requests are made for you."
|
|
923
|
+
}),
|
|
924
|
+
status.automation.enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
925
|
+
className: "dsm-workbuddy-xdpool-auto-jobs",
|
|
926
|
+
children: AUTOMATION_JOBS.map((kind) => {
|
|
927
|
+
const job = automationJob(status, kind);
|
|
928
|
+
const hours = automationHours(status, kind);
|
|
929
|
+
const label = t?.(`row.autoJob_${kind}`) ?? kind;
|
|
930
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
931
|
+
className: "dsm-workbuddy-xdpool-auto-job",
|
|
932
|
+
children: [
|
|
933
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
934
|
+
className: "dsm-workbuddy-xdpool-auto-job-name",
|
|
935
|
+
children: label
|
|
936
|
+
}),
|
|
937
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
938
|
+
className: "dsm-workbuddy-xdpool-auto-job-when",
|
|
939
|
+
children: hours.length === 0 ? t?.("row.autoHourNone") ?? "not scheduled" : hours.map((hour) => `${String(hour).padStart(2, "0")}:00`).join(" · ")
|
|
940
|
+
}),
|
|
941
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
942
|
+
className: "dsm-workbuddy-xdpool-auto-job-last",
|
|
943
|
+
children: job?.lastRunDate === void 0 ? t?.("row.autoNever") ?? "not run yet" : `${job.lastRunDate} · ${job.ok}${job.failed > 0 ? `/${job.failed}` : ""}`
|
|
944
|
+
})
|
|
945
|
+
]
|
|
946
|
+
}, kind);
|
|
947
|
+
})
|
|
948
|
+
}) : null
|
|
949
|
+
]
|
|
950
|
+
}),
|
|
815
951
|
flash === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
816
952
|
className: "dsm-workbuddy-xdpool-note",
|
|
817
953
|
children: flash
|
|
@@ -851,31 +987,55 @@ window.__ModuleLoader__.load({
|
|
|
851
987
|
accountCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
852
988
|
className: "dsm-workbuddy-xdpool-accounts",
|
|
853
989
|
"aria-label": t?.("row.accountsTitle") ?? "Accounts",
|
|
854
|
-
children: [
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
990
|
+
children: [
|
|
991
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
992
|
+
className: "dsm-workbuddy-xdpool-accounts-head",
|
|
993
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
994
|
+
className: "dsm-workbuddy-xdpool-accounts-title",
|
|
995
|
+
children: t?.("row.accountsTitle") ?? "Accounts in the pool"
|
|
996
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
997
|
+
className: "dsm-workbuddy-xdpool-accounts-summary",
|
|
998
|
+
children: t?.("row.accountsSummary", {
|
|
999
|
+
count: accountCount,
|
|
1000
|
+
cooling
|
|
1001
|
+
}) ?? `${accountCount} account(s) · ${cooling} cooling`
|
|
1002
|
+
})]
|
|
1003
|
+
}),
|
|
1004
|
+
(() => {
|
|
1005
|
+
const active = status?.activeAccountId === void 0 ? void 0 : status.accounts.find((account) => account.id === status.activeAccountId);
|
|
1006
|
+
if (active === void 0) return null;
|
|
1007
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1008
|
+
className: "dsm-workbuddy-xdpool-current",
|
|
1009
|
+
children: [
|
|
1010
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "dsm-workbuddy-xdpool-current-dot" }),
|
|
1011
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1012
|
+
className: "dsm-workbuddy-xdpool-current-label",
|
|
1013
|
+
children: t?.("row.currentAccount") ?? "In use now"
|
|
1014
|
+
}),
|
|
1015
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1016
|
+
className: "dsm-workbuddy-xdpool-current-name",
|
|
1017
|
+
children: active.label
|
|
1018
|
+
}),
|
|
1019
|
+
active.disabled === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1020
|
+
className: "dsm-workbuddy-xdpool-current-note",
|
|
1021
|
+
children: t?.("row.currentAccountDisabled") ?? "disabled — will switch on the next request"
|
|
1022
|
+
}) : null
|
|
1023
|
+
]
|
|
1024
|
+
});
|
|
1025
|
+
})(),
|
|
1026
|
+
status?.accounts.map((account) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountBlock, {
|
|
1027
|
+
account,
|
|
1028
|
+
...checkinBusyId === void 0 ? {} : { checkinBusyId },
|
|
1029
|
+
onClaimCheckin: (accountId) => {
|
|
1030
|
+
claimCheckin(accountId);
|
|
1031
|
+
},
|
|
1032
|
+
onToggleDisabled: (accountId, disabled) => {
|
|
1033
|
+
toggleAccountDisabled(accountId, disabled);
|
|
1034
|
+
},
|
|
1035
|
+
...accountBusyId === void 0 ? {} : { accountBusyId },
|
|
1036
|
+
t
|
|
1037
|
+
}, account.id))
|
|
1038
|
+
]
|
|
879
1039
|
}) : null,
|
|
880
1040
|
(status?.models.length ?? 0) > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
881
1041
|
className: "dsm-workbuddy-xdpool-models",
|
|
@@ -934,81 +1094,75 @@ window.__ModuleLoader__.load({
|
|
|
934
1094
|
});
|
|
935
1095
|
}
|
|
936
1096
|
/** One account block: label + status tag + meta + optional credit panels. */
|
|
937
|
-
function AccountBlock({ account,
|
|
938
|
-
const isActive = account.id === activeAccountId;
|
|
1097
|
+
function AccountBlock({ account, t, checkinBusyId, onClaimCheckin, accountBusyId, onToggleDisabled }) {
|
|
939
1098
|
const isDisabled = account.disabled === true;
|
|
940
1099
|
const isCooling = account.cooling === true;
|
|
941
1100
|
const cooldownUntil = account.cooldownUntil !== void 0 ? Date.parse(account.cooldownUntil) : void 0;
|
|
942
1101
|
const modelCooldowns = account.modelCooldowns ?? [];
|
|
943
|
-
const tag =
|
|
944
|
-
text: t?.("row.accountNext") ?? "Next up",
|
|
945
|
-
cls: "dsm-workbuddy-xdpool-account-tag"
|
|
946
|
-
} : isCooling ? {
|
|
1102
|
+
const tag = isCooling ? {
|
|
947
1103
|
text: t?.("row.cooling") ?? "Cooling",
|
|
948
1104
|
cls: "dsm-workbuddy-xdpool-account-tag dsm-workbuddy-xdpool-account-tag-cooling"
|
|
949
1105
|
} : null;
|
|
950
1106
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
951
1107
|
className: isDisabled ? "dsm-workbuddy-xdpool-account dsm-workbuddy-xdpool-account-off" : "dsm-workbuddy-xdpool-account",
|
|
952
1108
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
953
|
-
className: "dsm-workbuddy-xdpool-account-
|
|
1109
|
+
className: "dsm-workbuddy-xdpool-account-head",
|
|
954
1110
|
children: [
|
|
955
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
956
|
-
className: "dsm-workbuddy-xdpool-account-
|
|
957
|
-
children:
|
|
958
|
-
className: "dsm-workbuddy-xdpool-account-label",
|
|
959
|
-
children: account.label
|
|
960
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
961
|
-
className: "dsm-workbuddy-xdpool-account-toggle",
|
|
962
|
-
title: t?.("row.accountToggleHint") ?? "Include this account in the pool",
|
|
963
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
964
|
-
type: "checkbox",
|
|
965
|
-
checked: !isDisabled,
|
|
966
|
-
disabled: accountBusyId === account.id,
|
|
967
|
-
onChange: (event) => {
|
|
968
|
-
onToggleDisabled(account.id, !event.target.checked);
|
|
969
|
-
}
|
|
970
|
-
}), isDisabled ? t?.("row.accountOff") ?? "Off" : t?.("row.accountInRotation") ?? "In rotation"]
|
|
971
|
-
})]
|
|
972
|
-
}),
|
|
973
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
974
|
-
className: "dsm-workbuddy-xdpool-account-tags",
|
|
975
|
-
children: tag === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
976
|
-
className: tag.cls,
|
|
977
|
-
children: tag.text
|
|
978
|
-
})
|
|
1111
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1112
|
+
className: "dsm-workbuddy-xdpool-account-label",
|
|
1113
|
+
children: account.label
|
|
979
1114
|
}),
|
|
980
|
-
|
|
981
|
-
className:
|
|
982
|
-
children:
|
|
1115
|
+
tag === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1116
|
+
className: tag.cls,
|
|
1117
|
+
children: tag.text
|
|
983
1118
|
}),
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
]
|
|
995
|
-
})
|
|
996
|
-
modelCooldowns.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
997
|
-
className: "dsm-workbuddy-xdpool-account-modelcool",
|
|
998
|
-
children: modelCooldowns.map((mc) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
999
|
-
className: "dsm-workbuddy-xdpool-account-modelcool-chip",
|
|
1000
|
-
children: t?.("row.modelCooling", {
|
|
1001
|
-
model: mc.modelId,
|
|
1002
|
-
time: formatDateTime(mc.until)
|
|
1003
|
-
}) ?? `${mc.modelId} cooling to ${formatDateTime(mc.until)}`
|
|
1004
|
-
}, mc.modelId))
|
|
1005
|
-
}) : null
|
|
1119
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1120
|
+
type: "button",
|
|
1121
|
+
role: "switch",
|
|
1122
|
+
"aria-checked": !isDisabled,
|
|
1123
|
+
className: isDisabled ? "dsm-workbuddy-xdpool-account-toggle" : "dsm-workbuddy-xdpool-account-toggle dsm-workbuddy-xdpool-account-toggle-on",
|
|
1124
|
+
title: t?.("row.accountToggleHint") ?? "Enable this account (uncheck to keep it out of the pool)",
|
|
1125
|
+
disabled: accountBusyId === account.id,
|
|
1126
|
+
onClick: () => {
|
|
1127
|
+
onToggleDisabled(account.id, !isDisabled);
|
|
1128
|
+
},
|
|
1129
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "dsm-workbuddy-xdpool-account-toggle-dot" }), isDisabled ? t?.("row.accountOff") ?? "Disabled" : t?.("row.accountInRotation") ?? "Enabled"]
|
|
1130
|
+
})
|
|
1006
1131
|
]
|
|
1007
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1008
|
-
account,
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1132
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1133
|
+
className: "dsm-workbuddy-xdpool-account-body",
|
|
1134
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1135
|
+
className: "dsm-workbuddy-xdpool-account-copy",
|
|
1136
|
+
children: [
|
|
1137
|
+
account.expiresAt !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1138
|
+
className: "dsm-workbuddy-xdpool-account-meta",
|
|
1139
|
+
children: t?.("row.tokenExpiry", { time: formatDateTime(account.expiresAt) }) ?? `token ${formatDateTime(account.expiresAt)}`
|
|
1140
|
+
}) : null,
|
|
1141
|
+
isCooling && cooldownUntil !== void 0 && !Number.isNaN(cooldownUntil) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1142
|
+
className: "dsm-workbuddy-xdpool-account-meta",
|
|
1143
|
+
children: [
|
|
1144
|
+
t?.("row.cooldownUntil", { time: formatTime(cooldownUntil) }) ?? `until ${formatTime(cooldownUntil)}`,
|
|
1145
|
+
" · ",
|
|
1146
|
+
t?.("row.cooldownHits", { hits: account.rateLimitHits ?? 0 }) ?? `${account.rateLimitHits ?? 0} hit(s)`
|
|
1147
|
+
]
|
|
1148
|
+
}) : null,
|
|
1149
|
+
modelCooldowns.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1150
|
+
className: "dsm-workbuddy-xdpool-account-modelcool",
|
|
1151
|
+
children: modelCooldowns.map((mc) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1152
|
+
className: "dsm-workbuddy-xdpool-account-modelcool-chip",
|
|
1153
|
+
children: t?.("row.modelCooling", {
|
|
1154
|
+
model: mc.modelId,
|
|
1155
|
+
time: formatDateTime(mc.until)
|
|
1156
|
+
}) ?? `${mc.modelId} cooling to ${formatDateTime(mc.until)}`
|
|
1157
|
+
}, mc.modelId))
|
|
1158
|
+
}) : null
|
|
1159
|
+
]
|
|
1160
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountStats, {
|
|
1161
|
+
account,
|
|
1162
|
+
t,
|
|
1163
|
+
checkinBusy: checkinBusyId === account.id,
|
|
1164
|
+
onClaim: onClaimCheckin
|
|
1165
|
+
})]
|
|
1012
1166
|
})]
|
|
1013
1167
|
});
|
|
1014
1168
|
}
|
|
@@ -1254,11 +1408,12 @@ window.__ModuleLoader__.load({
|
|
|
1254
1408
|
"row.accountsSummary": "{count} account(s) · {cooling} cooling",
|
|
1255
1409
|
"row.ok": "Healthy — requests auto-rotate across accounts",
|
|
1256
1410
|
"row.allCooling": "Every account is rate-limited right now; requests pause until a cooldown lifts.",
|
|
1257
|
-
"row.
|
|
1258
|
-
"row.
|
|
1259
|
-
"row.
|
|
1260
|
-
"row.accountToggleHint": "Include this account in the pool",
|
|
1411
|
+
"row.accountInRotation": "Enabled",
|
|
1412
|
+
"row.accountOff": "Disabled",
|
|
1413
|
+
"row.accountToggleHint": "Enable this account (uncheck to keep it out of the pool)",
|
|
1261
1414
|
"row.accountToggleError": "Could not switch the account: {message}",
|
|
1415
|
+
"row.currentAccount": "In use now",
|
|
1416
|
+
"row.currentAccountDisabled": "switched off — the next request moves on",
|
|
1262
1417
|
"row.cooling": "Cooling (rate-limited)",
|
|
1263
1418
|
"row.cooldownHits": "{hits} hit(s)",
|
|
1264
1419
|
"row.cooldownUntil": "until {time}",
|
|
@@ -1318,7 +1473,19 @@ window.__ModuleLoader__.load({
|
|
|
1318
1473
|
"row.resetCooldownsBusy": "Clearing…",
|
|
1319
1474
|
"row.resetCooldownsDone": "Cooldowns cleared",
|
|
1320
1475
|
"row.accountsRescanned": "Detected {count} account(s)",
|
|
1321
|
-
"row.error": "Pool status unavailable: {message}"
|
|
1476
|
+
"row.error": "Pool status unavailable: {message}",
|
|
1477
|
+
"row.autoTitle": "Automation",
|
|
1478
|
+
"row.autoOn": "On",
|
|
1479
|
+
"row.autoOff": "Off",
|
|
1480
|
+
"row.autoBusy": "Saving…",
|
|
1481
|
+
"row.autoHintOn": "Reports activity, claims task rewards and checks in once a day.",
|
|
1482
|
+
"row.autoHintOff": "Off: no background requests are made for you.",
|
|
1483
|
+
"row.autoJob_report": "Activity report",
|
|
1484
|
+
"row.autoJob_tasks": "Task rewards",
|
|
1485
|
+
"row.autoJob_checkin": "Daily check-in",
|
|
1486
|
+
"row.autoJob_streak": "Streak bonus",
|
|
1487
|
+
"row.autoHourNone": "not scheduled",
|
|
1488
|
+
"row.autoNever": "not run yet"
|
|
1322
1489
|
};
|
|
1323
1490
|
const zh = {
|
|
1324
1491
|
"row.title": "WorkBuddy 池(dsh-workbuddy-xdpool)",
|
|
@@ -1346,11 +1513,12 @@ window.__ModuleLoader__.load({
|
|
|
1346
1513
|
"row.accountsSummary": "{count} 个账号 · {cooling} 个冷却中",
|
|
1347
1514
|
"row.ok": "运行健康 —— 请求会在各账号间自动轮换",
|
|
1348
1515
|
"row.allCooling": "当前所有账号都处于限流冷却,请求会暂停直到某个冷却结束。",
|
|
1349
|
-
"row.
|
|
1350
|
-
"row.accountInRotation": "参与轮换",
|
|
1516
|
+
"row.accountInRotation": "已启用",
|
|
1351
1517
|
"row.accountOff": "已停用",
|
|
1352
|
-
"row.accountToggleHint": "
|
|
1518
|
+
"row.accountToggleHint": "启用该账号(取消勾选则不参与池子)",
|
|
1353
1519
|
"row.accountToggleError": "切换账号失败:{message}",
|
|
1520
|
+
"row.currentAccount": "当前使用",
|
|
1521
|
+
"row.currentAccountDisabled": "已停用 —— 下次请求会换号",
|
|
1354
1522
|
"row.cooling": "冷却中(被限流)",
|
|
1355
1523
|
"row.cooldownHits": "触发 {hits} 次",
|
|
1356
1524
|
"row.cooldownUntil": "至 {time}",
|
|
@@ -1410,7 +1578,19 @@ window.__ModuleLoader__.load({
|
|
|
1410
1578
|
"row.resetCooldownsBusy": "正在清除…",
|
|
1411
1579
|
"row.resetCooldownsDone": "冷却已清除",
|
|
1412
1580
|
"row.accountsRescanned": "检测到 {count} 个账号",
|
|
1413
|
-
"row.error": "池状态不可用:{message}"
|
|
1581
|
+
"row.error": "池状态不可用:{message}",
|
|
1582
|
+
"row.autoTitle": "积分自动化",
|
|
1583
|
+
"row.autoOn": "已开启",
|
|
1584
|
+
"row.autoOff": "已关闭",
|
|
1585
|
+
"row.autoBusy": "保存中…",
|
|
1586
|
+
"row.autoHintOn": "每天自动活跃上报、领取任务奖励并签到。",
|
|
1587
|
+
"row.autoHintOff": "已关闭:不会替你发起任何后台请求。",
|
|
1588
|
+
"row.autoJob_report": "活跃上报",
|
|
1589
|
+
"row.autoJob_tasks": "任务奖励",
|
|
1590
|
+
"row.autoJob_checkin": "每日签到",
|
|
1591
|
+
"row.autoJob_streak": "连登奖励",
|
|
1592
|
+
"row.autoHourNone": "未排程",
|
|
1593
|
+
"row.autoNever": "尚未执行"
|
|
1414
1594
|
};
|
|
1415
1595
|
//#endregion
|
|
1416
1596
|
//#region src/client/index.tsx
|