@jxgame2020/dsh-token-quota 0.1.15 → 0.1.17
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/lib/client.js +154 -81
- package/lib/index.js +5 -2
- package/lib/types/client/TokenQuotaPanel.d.ts +3 -1
- package/lib/types/client/TokenQuotaPanel.js +58 -6
- package/lib/types/client/index.js +12 -2
- package/lib/types/client/locales.d.ts +6 -0
- package/lib/types/client/locales.js +6 -0
- package/lib/types/client/store.d.ts +3 -0
- package/lib/types/client/store.js +13 -2
- package/lib/types/index.js +4 -1
- package/lib/types/types.d.ts +6 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -36,6 +36,7 @@ window.__ModuleLoader__.load({
|
|
|
36
36
|
monitored: null,
|
|
37
37
|
onFull: "stop",
|
|
38
38
|
checkUpdates: true,
|
|
39
|
+
dimWhenIdle: false,
|
|
39
40
|
upgrade: null,
|
|
40
41
|
upgradeDismissed: false,
|
|
41
42
|
checkingUpdates: false,
|
|
@@ -74,9 +75,13 @@ window.__ModuleLoader__.load({
|
|
|
74
75
|
setCheckUpdates: (d, checkUpdates) => {
|
|
75
76
|
d.checkUpdates = checkUpdates;
|
|
76
77
|
},
|
|
78
|
+
setDimWhenIdle: (d, dimWhenIdle) => {
|
|
79
|
+
d.dimWhenIdle = dimWhenIdle;
|
|
80
|
+
},
|
|
77
81
|
setUpgrade: (d, upgrade) => {
|
|
78
|
-
|
|
79
|
-
d.upgrade =
|
|
82
|
+
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.17" ? upgrade : null;
|
|
83
|
+
if (d.upgrade === null || d.upgrade.latestVersion !== normalized?.latestVersion) d.upgradeDismissed = false;
|
|
84
|
+
d.upgrade = normalized;
|
|
80
85
|
},
|
|
81
86
|
setUpgradeDismissed: (d, dismissed) => {
|
|
82
87
|
d.upgradeDismissed = dismissed;
|
|
@@ -170,7 +175,7 @@ window.__ModuleLoader__.load({
|
|
|
170
175
|
}
|
|
171
176
|
//#endregion
|
|
172
177
|
//#region \0dsh-css:/Users/jxgame/Desktop/works/deepseek-harness-package/dsh-token-quota/packages/token-quota/src/client/TokenQuotaPanel.module.css.mjs
|
|
173
|
-
const css = ".NPLLIq_panel{box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);pointer-events:auto;z-index:40;opacity:1;border-radius:12px;flex-direction:column;width:320px;max-height:min(72vh,560px);transition:opacity .18s;display:flex;position:fixed;top:56px;right:12px;overflow:hidden;box-shadow:0 8px 28px #0000002e}.NPLLIq_panelDim{opacity:.55}.NPLLIq_panelDimStrong{opacity:.3}.NPLLIq_header{border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:flex-start;gap:8px;padding:10px 12px;display:flex}.NPLLIq_header:active{cursor:grabbing}.NPLLIq_headerText{flex-direction:column;gap:2px;min-width:0;display:flex}.NPLLIq_title{color:var(--dsw-alias-label-primary);align-items:baseline;gap:6px;font-size:13px;font-weight:600;display:flex}.NPLLIq_version{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:10px;font-weight:500}.NPLLIq_versionNew{color:var(--dsw-alias-status-warning-foreground,#b56900);background:var(--dsw-alias-status-warning-background,#fff6d7);cursor:default;border-radius:4px;padding:1px 6px}.NPLLIq_subtitle{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_collapse{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_collapse:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_body{padding:4px 0;overflow-y:auto}.NPLLIq_row{border-bottom:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:6px;padding:8px 12px;display:flex}.NPLLIq_rowHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.NPLLIq_rowName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:6px;font-size:12px;font-weight:500;display:inline-flex;overflow:hidden}.NPLLIq_currentBadge{color:var(--dsw-alias-state-success-primary);border:1px solid var(--dsw-alias-state-success-primary);border-radius:8px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_rowMeta{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.NPLLIq_bar{background:var(--dsw-alias-bg-layer-1);border-radius:3px;height:6px;overflow:hidden}.NPLLIq_fillIdle{background:var(--dsw-alias-brand-primary);height:100%;transition:width .2s}.NPLLIq_fillWarn{background:var(--dsw-alias-state-warn-primary);height:100%;transition:width .2s}.NPLLIq_fillOver{background:var(--dsw-alias-state-error-primary);height:100%;transition:width .2s}.NPLLIq_controls{align-items:center;gap:6px;display:flex}.NPLLIq_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;color:var(--dsw-alias-label-primary);border-radius:6px;flex:1;padding:4px 8px;font-size:11px}.NPLLIq_input::placeholder{color:var(--dsw-alias-label-secondary)}.NPLLIq_save,.NPLLIq_switch{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px;font-size:11px}.NPLLIq_save:hover,.NPLLIq_switch:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2)}.NPLLIq_switch:disabled{opacity:.5;cursor:default}.NPLLIq_notice,.NPLLIq_noticeError{color:var(--dsw-alias-label-secondary);padding:10px 12px;font-size:12px}.NPLLIq_noticeError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_tab{background:var(--dsw-alias-brand-primary);border:1px solid var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay);pointer-events:auto;cursor:pointer;z-index:90;border-radius:10px;align-items:center;gap:6px;padding:9px 14px;font-size:12px;font-weight:600;display:inline-flex;position:fixed;top:56px;right:12px;box-shadow:0 6px 20px #00000040}.NPLLIq_tab:hover{filter:brightness(1.08)}.NPLLIq_tabIcon{font-size:12px;line-height:1}.NPLLIq_tabLabel{white-space:nowrap}.NPLLIq_headerActions{flex:none;align-items:center;gap:4px;display:flex}.NPLLIq_settingsBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_settingsBtn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_selectBtn{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_selectBtn:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_gearBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;flex:none;margin-left:6px;padding:0 2px;font-size:12px;line-height:1}.NPLLIq_gearBtn:hover{color:var(--dsw-alias-label-primary)}.NPLLIq_fullNotice{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;margin:6px 12px;padding:8px 10px;font-size:12px}.NPLLIq_upgradeBanner{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-divider-1,#0000001a);border-radius:8px;margin:6px 12px;padding:10px 30px 10px 10px;font-size:12px;position:relative}.NPLLIq_upgradeBannerText{margin-bottom:6px;font-weight:600}.NPLLIq_upgradeCommands{flex-direction:column;gap:4px;display:flex}.NPLLIq_upgradeCommandRow{align-items:center;gap:6px;display:flex}.NPLLIq_upgradeCommand{background:var(--dsw-alias-bg-layer-2,#0000000a);white-space:nowrap;border-radius:4px;flex:1;min-width:0;padding:4px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;overflow-x:auto}.NPLLIq_copyBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_copyBtn:hover{background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_upgradeHint{color:var(--dsw-alias-label-secondary);margin-top:6px;font-size:11px}.NPLLIq_upgradeClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;font-size:16px;line-height:1;position:absolute;top:4px;right:6px}.NPLLIq_upgradeClose:hover{background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary)}.NPLLIq_checkUpdatesRow{justify-content:space-between;align-items:center;gap:12px;display:flex}.NPLLIq_checkUpdatesLabel{color:var(--dsw-alias-label-primary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.NPLLIq_checkUpdatesLabel input{margin:0}.NPLLIq_checkBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;text-align:center;border-radius:4px;flex:none;min-width:72px;padding:4px 10px;font-size:12px}.NPLLIq_checkBtn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_checkBtn:disabled{opacity:.6;cursor:default}.NPLLIq_checkErrorHint{color:var(--dsw-alias-state-error-primary,#c00);background:var(--dsw-alias-state-error-background,#ff00000f);border:1px solid var(--dsw-alias-state-error-border,#b4000040);word-break:break-all;border-radius:6px;margin-top:8px;padding:6px 8px;font-size:11px;line-height:1.4}.NPLLIq_dialog{z-index:100;box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;gap:12px;width:280px;max-height:80vh;padding:14px;display:flex;position:fixed;top:50%;left:50%;overflow-y:auto;transform:translate(-50%,-50%);box-shadow:0 8px 28px #00000040}.NPLLIq_dialogTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.NPLLIq_dialogSection{flex-direction:column;gap:6px;display:flex}.NPLLIq_dialogLabel{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500}.NPLLIq_monitorHint{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_monitorList{flex-direction:column;gap:2px;max-height:180px;display:flex;overflow-y:auto}.NPLLIq_monitorRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:2px 4px;font-size:12px;display:flex}.NPLLIq_monitorRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_monitorName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.NPLLIq_radioRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:3px 4px;font-size:12px;display:flex}.NPLLIq_radioRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_dialogActions{justify-content:flex-end;gap:6px;display:flex}.NPLLIq_dialogBtn,.NPLLIq_dialogBtnPrimary{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;border-radius:6px;padding:4px 12px;font-size:11px}.NPLLIq_dialogBtn{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.NPLLIq_dialogBtnPrimary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay)}.NPLLIq_dialogHeader{z-index:2;background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:center;gap:8px;margin:-14px -14px 0;padding:14px 14px 8px;display:flex;position:sticky;top:-14px}.NPLLIq_dialogHeader:active{cursor:grabbing}.NPLLIq_dialogClose{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;font-size:18px;line-height:1;display:flex}.NPLLIq_dialogClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_resetRow{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.NPLLIq_resetSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:6px;padding:3px 6px;font-size:12px}.NPLLIq_logTable{border-collapse:collapse;width:100%;font-size:11px}.NPLLIq_logTable th{text-align:left;color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);padding:4px 6px;font-weight:500}.NPLLIq_logTable td{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);font-variant-numeric:tabular-nums;padding:4px 6px}.NPLLIq_logDayCol{white-space:nowrap;color:var(--dsw-alias-label-secondary)}.NPLLIq_logModelCol{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}.NPLLIq_logUsedCol{text-align:right}.NPLLIq_logDialog{gap:0;width:380px;max-height:min(72vh,480px);padding:0}.NPLLIq_logHeader{background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;flex:none;justify-content:space-between;align-items:center;gap:8px;padding:14px 14px 8px;display:flex}.NPLLIq_logHeader:active{cursor:grabbing}.NPLLIq_logScroll{flex:1;min-height:0;padding:0 14px 14px;overflow:auto}.NPLLIq_logToolbar{flex:1;align-items:center;gap:6px;display:flex}.NPLLIq_logSearch{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);min-width:0;color:var(--dsw-alias-label-primary);border-radius:4px;flex:1;padding:3px 6px;font-size:11px}.NPLLIq_logSearch:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}.NPLLIq_logClearBtn{border:1px solid var(--dsw-alias-state-error-border,#b400004d);color:var(--dsw-alias-state-error-primary,#c00);cursor:pointer;white-space:nowrap;background:0 0;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_logClearBtn:hover{background:var(--dsw-alias-state-error-background,#ff00000f)}.NPLLIq_logPager{border-top:1px solid var(--dsw-alias-divider-1,#00000014);background:var(--dsw-alias-bg-overlay);color:var(--dsw-alias-label-secondary);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:6px 14px;font-size:11px;display:flex}.NPLLIq_logPagerInfo{white-space:nowrap}.NPLLIq_logPagerControls{align-items:center;gap:4px;display:flex}.NPLLIq_logPagerBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:24px;height:24px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;font-size:13px;line-height:1}.NPLLIq_logPagerBtn:disabled{opacity:.4;cursor:default}.NPLLIq_logPagerPages{text-align:center;min-width:50px;color:var(--dsw-alias-label-secondary)}.NPLLIq_logPageSizeSelect{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;padding:2px 4px;font-size:11px}.NPLLIq_dialogOverlay{z-index:100001;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.NPLLIq_logClearDialog{gap:0;width:320px;padding:16px}.NPLLIq_dialogBody{color:var(--dsw-alias-label-secondary);margin:6px 0 10px;font-size:12px;line-height:1.5}.NPLLIq_logClearDate{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:100%;color:var(--dsw-alias-label-primary);border-radius:6px;margin-bottom:12px;padding:6px 8px;font-size:13px}.NPLLIq_logClearDate:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}";
|
|
178
|
+
const css = ".NPLLIq_panel{box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);pointer-events:auto;z-index:40;opacity:1;border-radius:12px;flex-direction:column;width:320px;max-height:min(72vh,560px);transition:opacity .18s;display:flex;position:fixed;top:56px;right:12px;overflow:hidden;box-shadow:0 8px 28px #0000002e}.NPLLIq_panelDim{opacity:.55}.NPLLIq_panelDimStrong{opacity:.3}.NPLLIq_header{border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:flex-start;gap:8px;padding:10px 12px;display:flex}.NPLLIq_header:active{cursor:grabbing}.NPLLIq_headerText{flex-direction:column;gap:2px;min-width:0;display:flex}.NPLLIq_title{color:var(--dsw-alias-label-primary);align-items:baseline;gap:6px;font-size:13px;font-weight:600;display:flex}.NPLLIq_version{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:10px;font-weight:500}.NPLLIq_versionNew{color:var(--dsw-alias-status-warning-foreground,#b56900);background:var(--dsw-alias-status-warning-background,#fff6d7);cursor:default;border-radius:4px;padding:1px 6px}.NPLLIq_subtitle{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_collapse{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_collapse:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_body{padding:4px 0;overflow-y:auto}.NPLLIq_row{border-bottom:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:6px;padding:8px 12px;display:flex}.NPLLIq_rowHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.NPLLIq_rowName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:6px;font-size:12px;font-weight:500;display:inline-flex;overflow:hidden}.NPLLIq_currentBadge{color:var(--dsw-alias-state-success-primary);border:1px solid var(--dsw-alias-state-success-primary);border-radius:8px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_rowMeta{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.NPLLIq_bar{background:var(--dsw-alias-bg-layer-1);border-radius:3px;height:6px;overflow:hidden}.NPLLIq_fillIdle{background:var(--dsw-alias-brand-primary);height:100%;transition:width .2s}.NPLLIq_fillWarn{background:var(--dsw-alias-state-warn-primary);height:100%;transition:width .2s}.NPLLIq_fillOver{background:var(--dsw-alias-state-error-primary);height:100%;transition:width .2s}.NPLLIq_controls{align-items:center;gap:6px;display:flex}.NPLLIq_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;color:var(--dsw-alias-label-primary);border-radius:6px;flex:1;padding:4px 8px;font-size:11px}.NPLLIq_input::placeholder{color:var(--dsw-alias-label-secondary)}.NPLLIq_save,.NPLLIq_switch{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px;font-size:11px}.NPLLIq_save:hover,.NPLLIq_switch:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2)}.NPLLIq_switch:disabled{opacity:.5;cursor:default}.NPLLIq_notice,.NPLLIq_noticeError{color:var(--dsw-alias-label-secondary);padding:10px 12px;font-size:12px}.NPLLIq_noticeError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_tab{background:var(--dsw-alias-brand-primary);border:1px solid var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay);pointer-events:auto;cursor:pointer;z-index:90;border-radius:10px;align-items:center;gap:6px;padding:9px 14px;font-size:12px;font-weight:600;display:inline-flex;position:fixed;top:56px;right:12px;box-shadow:0 6px 20px #00000040}.NPLLIq_tab:hover{filter:brightness(1.08)}.NPLLIq_tabIcon{font-size:12px;line-height:1}.NPLLIq_tabLabel{white-space:nowrap}.NPLLIq_headerActions{flex:none;align-items:center;gap:4px;display:flex}.NPLLIq_settingsBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_settingsBtn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_selectBtn{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_selectBtn:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_gearBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;flex:none;margin-left:6px;padding:0 2px;font-size:12px;line-height:1}.NPLLIq_gearBtn:hover{color:var(--dsw-alias-label-primary)}.NPLLIq_fullNotice{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;margin:6px 12px;padding:8px 10px;font-size:12px}.NPLLIq_upgradeBanner{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-divider-1,#0000001a);border-radius:8px;margin:6px 12px;padding:10px 30px 10px 10px;font-size:12px;position:relative}@keyframes NPLLIq_upgradeBannerFlash{0%,to{border-color:var(--dsw-alias-divider-1,#0000001a);box-shadow:0 0 #f0a02000}50%{border-color:var(--dsw-alias-status-warning-foreground,#b56900);box-shadow:0 0 0 5px #f0a02073}}.NPLLIq_upgradeBannerFlash{border-color:var(--dsw-alias-status-warning-foreground,#b56900);animation:.6s ease-in-out 4 NPLLIq_upgradeBannerFlash}.NPLLIq_upgradeBannerText{margin-bottom:6px;font-weight:600}.NPLLIq_upgradeCommands{flex-direction:column;gap:4px;display:flex}.NPLLIq_upgradeCommandRow{align-items:center;gap:6px;display:flex}.NPLLIq_upgradeCommand{background:var(--dsw-alias-bg-layer-2,#0000000a);white-space:nowrap;border-radius:4px;flex:1;min-width:0;padding:4px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;overflow-x:auto}.NPLLIq_copyBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;flex:none;padding:3px 8px;font-size:11px;transition:transform 80ms,background .12s,color .12s}.NPLLIq_copyBtn:hover{background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_copyBtn:active{transform:scale(.92)}.NPLLIq_copyBtnDone{background:var(--dsw-alias-status-success-background,#14963c1f);border-color:var(--dsw-alias-status-success-foreground,#0a7d32);color:var(--dsw-alias-status-success-foreground,#0a7d32);font-weight:600}.NPLLIq_upgradeHint{color:var(--dsw-alias-label-secondary);margin-top:6px;font-size:11px}.NPLLIq_upgradeClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;font-size:16px;line-height:1;position:absolute;top:4px;right:6px}.NPLLIq_upgradeClose:hover{background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary)}.NPLLIq_checkUpdatesRow{justify-content:space-between;align-items:center;gap:12px;display:flex}.NPLLIq_checkUpdatesLabel{color:var(--dsw-alias-label-primary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.NPLLIq_checkUpdatesLabel input{margin:0}.NPLLIq_checkBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;text-align:center;border-radius:4px;flex:none;min-width:72px;padding:4px 10px;font-size:12px}.NPLLIq_checkBtn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_checkBtn:disabled{opacity:.6;cursor:default}.NPLLIq_checkErrorHint{color:var(--dsw-alias-state-error-primary,#c00);background:var(--dsw-alias-state-error-background,#ff00000f);border:1px solid var(--dsw-alias-state-error-border,#b4000040);word-break:break-all;border-radius:6px;margin-top:8px;padding:6px 8px;font-size:11px;line-height:1.4}.NPLLIq_dialog{z-index:100;box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;gap:12px;width:280px;max-height:80vh;padding:14px;display:flex;position:fixed;top:50%;left:50%;overflow-y:auto;transform:translate(-50%,-50%);box-shadow:0 8px 28px #00000040}.NPLLIq_dialogTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.NPLLIq_dialogSection{flex-direction:column;gap:6px;display:flex}.NPLLIq_dialogLabel{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500}.NPLLIq_monitorHint{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_dialogHint{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:11px;line-height:1.4}.NPLLIq_monitorList{flex-direction:column;gap:2px;max-height:180px;display:flex;overflow-y:auto}.NPLLIq_monitorRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:2px 4px;font-size:12px;display:flex}.NPLLIq_monitorRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_monitorName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.NPLLIq_radioRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:3px 4px;font-size:12px;display:flex}.NPLLIq_radioRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_dialogActions{justify-content:flex-end;gap:6px;display:flex}.NPLLIq_dialogBtn,.NPLLIq_dialogBtnPrimary{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;border-radius:6px;padding:4px 12px;font-size:11px}.NPLLIq_dialogBtn{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.NPLLIq_dialogBtnPrimary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay)}.NPLLIq_dialogHeader{z-index:2;background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:center;gap:8px;margin:-14px -14px 0;padding:14px 14px 8px;display:flex;position:sticky;top:-14px}.NPLLIq_dialogHeader:active{cursor:grabbing}.NPLLIq_dialogClose{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;font-size:18px;line-height:1;display:flex}.NPLLIq_dialogClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_resetRow{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.NPLLIq_resetSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:6px;padding:3px 6px;font-size:12px}.NPLLIq_logTable{border-collapse:collapse;width:100%;font-size:11px}.NPLLIq_logTable th{text-align:left;color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);padding:4px 6px;font-weight:500}.NPLLIq_logTable td{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);font-variant-numeric:tabular-nums;padding:4px 6px}.NPLLIq_logDayCol{white-space:nowrap;color:var(--dsw-alias-label-secondary)}.NPLLIq_logModelCol{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}.NPLLIq_logUsedCol{text-align:right}.NPLLIq_logDialog{gap:0;width:380px;max-height:min(72vh,480px);padding:0}.NPLLIq_logHeader{background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;flex:none;justify-content:space-between;align-items:center;gap:8px;padding:14px 14px 8px;display:flex}.NPLLIq_logHeader:active{cursor:grabbing}.NPLLIq_logScroll{flex:1;min-height:0;padding:0 14px 14px;overflow:auto}.NPLLIq_logToolbar{flex:1;align-items:center;gap:6px;display:flex}.NPLLIq_logSearch{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);min-width:0;color:var(--dsw-alias-label-primary);border-radius:4px;flex:1;padding:3px 6px;font-size:11px}.NPLLIq_logSearch:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}.NPLLIq_logClearBtn{border:1px solid var(--dsw-alias-state-error-border,#b400004d);color:var(--dsw-alias-state-error-primary,#c00);cursor:pointer;white-space:nowrap;background:0 0;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_logClearBtn:hover{background:var(--dsw-alias-state-error-background,#ff00000f)}.NPLLIq_logPager{border-top:1px solid var(--dsw-alias-divider-1,#00000014);background:var(--dsw-alias-bg-overlay);color:var(--dsw-alias-label-secondary);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:6px 14px;font-size:11px;display:flex}.NPLLIq_logPagerInfo{white-space:nowrap}.NPLLIq_logPagerControls{align-items:center;gap:4px;display:flex}.NPLLIq_logPagerBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:24px;height:24px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;font-size:13px;line-height:1}.NPLLIq_logPagerBtn:disabled{opacity:.4;cursor:default}.NPLLIq_logPagerPages{text-align:center;min-width:50px;color:var(--dsw-alias-label-secondary)}.NPLLIq_logPageSizeSelect{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;padding:2px 4px;font-size:11px}.NPLLIq_dialogOverlay{z-index:100001;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.NPLLIq_logClearDialog{gap:0;width:320px;padding:16px}.NPLLIq_dialogBody{color:var(--dsw-alias-label-secondary);margin:6px 0 10px;font-size:12px;line-height:1.5}.NPLLIq_logClearDate{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:100%;color:var(--dsw-alias-label-primary);border-radius:6px;margin-bottom:12px;padding:6px 8px;font-size:13px}.NPLLIq_logClearDate:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}";
|
|
174
179
|
const tagId = "@jxgame2020/dsh-token-quota/TokenQuotaPanel.module.css";
|
|
175
180
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
176
181
|
const tag = document.createElement("style");
|
|
@@ -180,88 +185,91 @@ window.__ModuleLoader__.load({
|
|
|
180
185
|
document.head.appendChild(tag);
|
|
181
186
|
}
|
|
182
187
|
var TokenQuotaPanel_module_css_default = {
|
|
183
|
-
"
|
|
184
|
-
"
|
|
185
|
-
"
|
|
186
|
-
"
|
|
187
|
-
"rowHeader": "NPLLIq_rowHeader",
|
|
188
|
-
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
189
|
-
"settingsBtn": "NPLLIq_settingsBtn",
|
|
190
|
-
"version": "NPLLIq_version",
|
|
191
|
-
"headerText": "NPLLIq_headerText",
|
|
188
|
+
"logPager": "NPLLIq_logPager",
|
|
189
|
+
"logToolbar": "NPLLIq_logToolbar",
|
|
190
|
+
"radioRow": "NPLLIq_radioRow",
|
|
191
|
+
"dialogClose": "NPLLIq_dialogClose",
|
|
192
192
|
"gearBtn": "NPLLIq_gearBtn",
|
|
193
|
+
"panelDim": "NPLLIq_panelDim",
|
|
194
|
+
"fillIdle": "NPLLIq_fillIdle",
|
|
195
|
+
"monitorHint": "NPLLIq_monitorHint",
|
|
196
|
+
"logPagerControls": "NPLLIq_logPagerControls",
|
|
197
|
+
"currentBadge": "NPLLIq_currentBadge",
|
|
198
|
+
"tabLabel": "NPLLIq_tabLabel",
|
|
199
|
+
"dialogTitle": "NPLLIq_dialogTitle",
|
|
200
|
+
"logClearDialog": "NPLLIq_logClearDialog",
|
|
201
|
+
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
202
|
+
"settingsBtn": "NPLLIq_settingsBtn",
|
|
203
|
+
"dialogActions": "NPLLIq_dialogActions",
|
|
204
|
+
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
205
|
+
"rowName": "NPLLIq_rowName",
|
|
206
|
+
"logHeader": "NPLLIq_logHeader",
|
|
207
|
+
"row": "NPLLIq_row",
|
|
193
208
|
"checkUpdatesRow": "NPLLIq_checkUpdatesRow",
|
|
194
|
-
"
|
|
195
|
-
"switch": "NPLLIq_switch",
|
|
196
|
-
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
197
|
-
"checkBtn": "NPLLIq_checkBtn",
|
|
198
|
-
"monitorName": "NPLLIq_monitorName",
|
|
209
|
+
"panel": "NPLLIq_panel",
|
|
199
210
|
"copyBtn": "NPLLIq_copyBtn",
|
|
200
|
-
"
|
|
201
|
-
"
|
|
202
|
-
"
|
|
203
|
-
"
|
|
204
|
-
"
|
|
205
|
-
"logPagerBtn": "NPLLIq_logPagerBtn",
|
|
206
|
-
"fillWarn": "NPLLIq_fillWarn",
|
|
211
|
+
"dialogLabel": "NPLLIq_dialogLabel",
|
|
212
|
+
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
213
|
+
"logSearch": "NPLLIq_logSearch",
|
|
214
|
+
"version": "NPLLIq_version",
|
|
215
|
+
"logDialog": "NPLLIq_logDialog",
|
|
207
216
|
"rowMeta": "NPLLIq_rowMeta",
|
|
208
|
-
"subtitle": "NPLLIq_subtitle",
|
|
209
|
-
"dialogBody": "NPLLIq_dialogBody",
|
|
210
|
-
"fillIdle": "NPLLIq_fillIdle",
|
|
211
217
|
"selectBtn": "NPLLIq_selectBtn",
|
|
218
|
+
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
212
219
|
"controls": "NPLLIq_controls",
|
|
213
|
-
"
|
|
220
|
+
"fullNotice": "NPLLIq_fullNotice",
|
|
221
|
+
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
|
|
222
|
+
"dialog": "NPLLIq_dialog",
|
|
214
223
|
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
"row": "NPLLIq_row",
|
|
218
|
-
"upgradeHint": "NPLLIq_upgradeHint",
|
|
219
|
-
"monitorHint": "NPLLIq_monitorHint",
|
|
220
|
-
"logPagerControls": "NPLLIq_logPagerControls",
|
|
221
|
-
"logClearDialog": "NPLLIq_logClearDialog",
|
|
222
|
-
"currentBadge": "NPLLIq_currentBadge",
|
|
223
|
-
"dialogSection": "NPLLIq_dialogSection",
|
|
224
|
-
"bar": "NPLLIq_bar",
|
|
225
|
-
"panelDim": "NPLLIq_panelDim",
|
|
226
|
-
"headerActions": "NPLLIq_headerActions",
|
|
227
|
-
"upgradeClose": "NPLLIq_upgradeClose",
|
|
224
|
+
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
225
|
+
"input": "NPLLIq_input",
|
|
228
226
|
"header": "NPLLIq_header",
|
|
229
|
-
"dialogLabel": "NPLLIq_dialogLabel",
|
|
230
|
-
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
231
|
-
"noticeError": "NPLLIq_noticeError",
|
|
232
|
-
"notice": "NPLLIq_notice",
|
|
233
|
-
"dialogBtn": "NPLLIq_dialogBtn",
|
|
234
|
-
"logToolbar": "NPLLIq_logToolbar",
|
|
235
|
-
"tab": "NPLLIq_tab",
|
|
236
227
|
"tabIcon": "NPLLIq_tabIcon",
|
|
237
|
-
"
|
|
238
|
-
"
|
|
239
|
-
"
|
|
240
|
-
"
|
|
241
|
-
"
|
|
242
|
-
"
|
|
243
|
-
"
|
|
228
|
+
"monitorName": "NPLLIq_monitorName",
|
|
229
|
+
"checkBtn": "NPLLIq_checkBtn",
|
|
230
|
+
"rowHeader": "NPLLIq_rowHeader",
|
|
231
|
+
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
232
|
+
"bar": "NPLLIq_bar",
|
|
233
|
+
"save": "NPLLIq_save",
|
|
234
|
+
"upgradeClose": "NPLLIq_upgradeClose",
|
|
244
235
|
"dialogHeader": "NPLLIq_dialogHeader",
|
|
245
|
-
"
|
|
236
|
+
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
237
|
+
"resetRow": "NPLLIq_resetRow",
|
|
238
|
+
"notice": "NPLLIq_notice",
|
|
239
|
+
"logClearDate": "NPLLIq_logClearDate",
|
|
240
|
+
"switch": "NPLLIq_switch",
|
|
241
|
+
"headerActions": "NPLLIq_headerActions",
|
|
246
242
|
"logModelCol": "NPLLIq_logModelCol",
|
|
247
|
-
"
|
|
248
|
-
"logPagerPages": "NPLLIq_logPagerPages",
|
|
249
|
-
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
250
|
-
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
251
|
-
"upgradeCommandRow": "NPLLIq_upgradeCommandRow",
|
|
252
|
-
"dialogClose": "NPLLIq_dialogClose",
|
|
243
|
+
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
253
244
|
"checkErrorHint": "NPLLIq_checkErrorHint",
|
|
254
|
-
"
|
|
255
|
-
"
|
|
256
|
-
"logSearch": "NPLLIq_logSearch",
|
|
257
|
-
"dialogActions": "NPLLIq_dialogActions",
|
|
245
|
+
"logPagerPages": "NPLLIq_logPagerPages",
|
|
246
|
+
"dialogSection": "NPLLIq_dialogSection",
|
|
258
247
|
"monitorRow": "NPLLIq_monitorRow",
|
|
259
|
-
"save": "NPLLIq_save",
|
|
260
|
-
"logUsedCol": "NPLLIq_logUsedCol",
|
|
261
|
-
"logDialog": "NPLLIq_logDialog",
|
|
262
248
|
"logScroll": "NPLLIq_logScroll",
|
|
263
|
-
"
|
|
264
|
-
"
|
|
249
|
+
"logTable": "NPLLIq_logTable",
|
|
250
|
+
"logClearBtn": "NPLLIq_logClearBtn",
|
|
251
|
+
"headerText": "NPLLIq_headerText",
|
|
252
|
+
"fillWarn": "NPLLIq_fillWarn",
|
|
253
|
+
"logDayCol": "NPLLIq_logDayCol",
|
|
254
|
+
"logPagerBtn": "NPLLIq_logPagerBtn",
|
|
255
|
+
"collapse": "NPLLIq_collapse",
|
|
256
|
+
"dialogHint": "NPLLIq_dialogHint",
|
|
257
|
+
"monitorList": "NPLLIq_monitorList",
|
|
258
|
+
"logPagerInfo": "NPLLIq_logPagerInfo",
|
|
259
|
+
"title": "NPLLIq_title",
|
|
260
|
+
"subtitle": "NPLLIq_subtitle",
|
|
261
|
+
"logUsedCol": "NPLLIq_logUsedCol",
|
|
262
|
+
"noticeError": "NPLLIq_noticeError",
|
|
263
|
+
"dialogBody": "NPLLIq_dialogBody",
|
|
264
|
+
"body": "NPLLIq_body",
|
|
265
|
+
"dialogBtn": "NPLLIq_dialogBtn",
|
|
266
|
+
"fillOver": "NPLLIq_fillOver",
|
|
267
|
+
"upgradeCommandRow": "NPLLIq_upgradeCommandRow",
|
|
268
|
+
"upgradeHint": "NPLLIq_upgradeHint",
|
|
269
|
+
"tab": "NPLLIq_tab",
|
|
270
|
+
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
271
|
+
"resetSelect": "NPLLIq_resetSelect",
|
|
272
|
+
"versionNew": "NPLLIq_versionNew"
|
|
265
273
|
};
|
|
266
274
|
//#endregion
|
|
267
275
|
//#region lib/types/client/TokenQuotaPanel.js
|
|
@@ -348,12 +356,17 @@ window.__ModuleLoader__.load({
|
|
|
348
356
|
* @param props - composed slot props.
|
|
349
357
|
* @returns the panel element tree.
|
|
350
358
|
*/
|
|
351
|
-
function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, useStore, actions, useSessions }) {
|
|
359
|
+
function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, useStore, actions, useSessions }) {
|
|
352
360
|
const [collapsed, setCollapsed] = (0, react.useState)(false);
|
|
353
361
|
const [drafts, setDrafts] = (0, react.useState)({});
|
|
354
362
|
const [editingKey, setEditingKey] = (0, react.useState)(null);
|
|
355
363
|
const [hovered, setHovered] = (0, react.useState)(false);
|
|
356
364
|
const [inputActive, setInputActive] = (0, react.useState)(false);
|
|
365
|
+
const [copiedCmd, setCopiedCmd] = (0, react.useState)(null);
|
|
366
|
+
const copyTimerRef = (0, react.useRef)(null);
|
|
367
|
+
const [upgradeFlash, setUpgradeFlash] = (0, react.useState)(false);
|
|
368
|
+
const flashTimerRef = (0, react.useRef)(null);
|
|
369
|
+
const prevUpgradeRef = (0, react.useRef)(null);
|
|
357
370
|
const [panelPos, setPanelPos] = (0, react.useState)(loadPanelPos);
|
|
358
371
|
const [settingsPos, setSettingsPos] = (0, react.useState)(null);
|
|
359
372
|
const [logPos, setLogPos] = (0, react.useState)(null);
|
|
@@ -373,6 +386,7 @@ window.__ModuleLoader__.load({
|
|
|
373
386
|
const monitored = useStore((s) => s.monitored);
|
|
374
387
|
const onFull = useStore((s) => s.onFull);
|
|
375
388
|
const checkUpdates = useStore((s) => s.checkUpdates);
|
|
389
|
+
const dimWhenIdle = useStore((s) => s.dimWhenIdle);
|
|
376
390
|
const upgrade = useStore((s) => s.upgrade);
|
|
377
391
|
const upgradeDismissed = useStore((s) => s.upgradeDismissed);
|
|
378
392
|
const checkingUpdates = useStore((s) => s.checkingUpdates);
|
|
@@ -405,6 +419,26 @@ window.__ModuleLoader__.load({
|
|
|
405
419
|
window.removeEventListener("focusin", onFocusIn);
|
|
406
420
|
};
|
|
407
421
|
}, []);
|
|
422
|
+
(0, react.useEffect)(() => {
|
|
423
|
+
const latest = upgrade?.latestVersion ?? null;
|
|
424
|
+
if (latest !== null && prevUpgradeRef.current !== latest) {
|
|
425
|
+
setCollapsed(false);
|
|
426
|
+
setUpgradeFlash(true);
|
|
427
|
+
if (flashTimerRef.current !== null) clearTimeout(flashTimerRef.current);
|
|
428
|
+
flashTimerRef.current = window.setTimeout(() => {
|
|
429
|
+
setUpgradeFlash(false);
|
|
430
|
+
flashTimerRef.current = null;
|
|
431
|
+
}, 2500);
|
|
432
|
+
}
|
|
433
|
+
prevUpgradeRef.current = latest;
|
|
434
|
+
return () => {};
|
|
435
|
+
}, [upgrade]);
|
|
436
|
+
(0, react.useEffect)(() => {
|
|
437
|
+
return () => {
|
|
438
|
+
if (flashTimerRef.current !== null) clearTimeout(flashTimerRef.current);
|
|
439
|
+
if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
|
|
440
|
+
};
|
|
441
|
+
}, []);
|
|
408
442
|
const rows = (0, react.useMemo)(() => mergeModelRows(groups, snapshot, current), [
|
|
409
443
|
groups,
|
|
410
444
|
snapshot,
|
|
@@ -448,6 +482,16 @@ window.__ModuleLoader__.load({
|
|
|
448
482
|
document.body.removeChild(el);
|
|
449
483
|
}
|
|
450
484
|
};
|
|
485
|
+
/** Copy an upgrade command and show per-button success feedback. */
|
|
486
|
+
const copyUpgradeCommand = (cmd) => {
|
|
487
|
+
copyToClipboard(cmd);
|
|
488
|
+
setCopiedCmd(cmd);
|
|
489
|
+
if (copyTimerRef.current !== null) clearTimeout(copyTimerRef.current);
|
|
490
|
+
copyTimerRef.current = window.setTimeout(() => {
|
|
491
|
+
setCopiedCmd(null);
|
|
492
|
+
copyTimerRef.current = null;
|
|
493
|
+
}, 1600);
|
|
494
|
+
};
|
|
451
495
|
(0, react.useEffect)(() => {
|
|
452
496
|
if (!logOpen) return;
|
|
453
497
|
let cancelled = false;
|
|
@@ -498,7 +542,7 @@ window.__ModuleLoader__.load({
|
|
|
498
542
|
setLimit(row.key, parsed);
|
|
499
543
|
};
|
|
500
544
|
const visibleRows = rows.filter((row) => isMonitoredKey(row.key) || row.current);
|
|
501
|
-
const panelDimClass = hovered ? "" : inputActive ? TokenQuotaPanel_module_css_default.panelDimStrong : TokenQuotaPanel_module_css_default.panelDim;
|
|
545
|
+
const panelDimClass = dimWhenIdle ? hovered || upgradeFlash ? "" : inputActive ? TokenQuotaPanel_module_css_default.panelDimStrong : TokenQuotaPanel_module_css_default.panelDim : "";
|
|
502
546
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
503
547
|
ref: panelRef,
|
|
504
548
|
className: `${TokenQuotaPanel_module_css_default.panel}${panelDimClass !== "" ? ` ${panelDimClass}` : ""}`,
|
|
@@ -528,13 +572,13 @@ window.__ModuleLoader__.load({
|
|
|
528
572
|
title: t("upgradeAvailableHint"),
|
|
529
573
|
children: [
|
|
530
574
|
"v",
|
|
531
|
-
"0.1.
|
|
575
|
+
"0.1.17",
|
|
532
576
|
" → v",
|
|
533
577
|
upgrade.latestVersion
|
|
534
578
|
]
|
|
535
579
|
}) : (0, react_jsx_runtime.jsxs)("span", {
|
|
536
580
|
className: TokenQuotaPanel_module_css_default.version,
|
|
537
|
-
children: ["v", "0.1.
|
|
581
|
+
children: ["v", "0.1.17"]
|
|
538
582
|
})]
|
|
539
583
|
}), (0, react_jsx_runtime.jsx)("div", {
|
|
540
584
|
className: TokenQuotaPanel_module_css_default.subtitle,
|
|
@@ -588,7 +632,7 @@ window.__ModuleLoader__.load({
|
|
|
588
632
|
children: fullNotice
|
|
589
633
|
}),
|
|
590
634
|
upgrade !== null && !upgradeDismissed && (0, react_jsx_runtime.jsxs)("div", {
|
|
591
|
-
className: TokenQuotaPanel_module_css_default.upgradeBanner
|
|
635
|
+
className: `${TokenQuotaPanel_module_css_default.upgradeBanner}${upgradeFlash ? ` ${TokenQuotaPanel_module_css_default.upgradeBannerFlash}` : ""}`,
|
|
592
636
|
role: "alert",
|
|
593
637
|
children: [
|
|
594
638
|
(0, react_jsx_runtime.jsx)("div", {
|
|
@@ -604,11 +648,11 @@ window.__ModuleLoader__.load({
|
|
|
604
648
|
children: cmd
|
|
605
649
|
}), (0, react_jsx_runtime.jsx)("button", {
|
|
606
650
|
type: "button",
|
|
607
|
-
className: TokenQuotaPanel_module_css_default.copyBtn
|
|
651
|
+
className: `${TokenQuotaPanel_module_css_default.copyBtn}${copiedCmd === cmd ? ` ${TokenQuotaPanel_module_css_default.copyBtnDone}` : ""}`,
|
|
608
652
|
onClick: () => {
|
|
609
|
-
|
|
653
|
+
copyUpgradeCommand(cmd);
|
|
610
654
|
},
|
|
611
|
-
children: t("copy")
|
|
655
|
+
children: copiedCmd === cmd ? t("copied") : t("copy")
|
|
612
656
|
})]
|
|
613
657
|
}, cmd))
|
|
614
658
|
}),
|
|
@@ -855,6 +899,22 @@ window.__ModuleLoader__.load({
|
|
|
855
899
|
})
|
|
856
900
|
]
|
|
857
901
|
}),
|
|
902
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
903
|
+
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
904
|
+
children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
905
|
+
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
906
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
907
|
+
type: "checkbox",
|
|
908
|
+
checked: dimWhenIdle,
|
|
909
|
+
onChange: (event) => {
|
|
910
|
+
setDimWhenIdle(event.target.checked);
|
|
911
|
+
}
|
|
912
|
+
}), (0, react_jsx_runtime.jsx)("span", { children: t("dimWhenIdleLabel") })]
|
|
913
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
914
|
+
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
915
|
+
children: t("dimWhenIdleHint")
|
|
916
|
+
})]
|
|
917
|
+
}),
|
|
858
918
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
859
919
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
860
920
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1134,8 +1194,11 @@ window.__ModuleLoader__.load({
|
|
|
1134
1194
|
upgradeAvailableHint: "有新版本可用",
|
|
1135
1195
|
upgradeAvailable: "发现新版本 v{version},请在终端执行以下命令升级:",
|
|
1136
1196
|
copy: "复制",
|
|
1197
|
+
copied: "已复制 ✓",
|
|
1137
1198
|
upgradeHint: "升级后请重启 dsh web 并刷新浏览器页面",
|
|
1138
1199
|
checkUpdatesLabel: "自动检查更新",
|
|
1200
|
+
dimWhenIdleLabel: "失焦时窗口透明",
|
|
1201
|
+
dimWhenIdleHint: "鼠标移开面板时降低不透明度,输入文字时更透明;鼠标悬停恢复",
|
|
1139
1202
|
checkUpdatesNow: "立即检查",
|
|
1140
1203
|
checkingUpdates: "检查中…",
|
|
1141
1204
|
checkUpToDate: "已是最新",
|
|
@@ -1198,8 +1261,11 @@ window.__ModuleLoader__.load({
|
|
|
1198
1261
|
upgradeAvailableHint: "A new version is available",
|
|
1199
1262
|
upgradeAvailable: "A new version v{version} is available. Run one of the following commands in your terminal to upgrade:",
|
|
1200
1263
|
copy: "Copy",
|
|
1264
|
+
copied: "Copied ✓",
|
|
1201
1265
|
upgradeHint: "After upgrading, restart dsh web and refresh the browser",
|
|
1202
1266
|
checkUpdatesLabel: "Check for updates automatically",
|
|
1267
|
+
dimWhenIdleLabel: "Dim panel when unfocused",
|
|
1268
|
+
dimWhenIdleHint: "Fade the panel out when the pointer is away (more while typing); hover to restore",
|
|
1203
1269
|
checkUpdatesNow: "Check now",
|
|
1204
1270
|
checkingUpdates: "Checking…",
|
|
1205
1271
|
checkUpToDate: "Up to date",
|
|
@@ -1341,6 +1407,7 @@ window.__ModuleLoader__.load({
|
|
|
1341
1407
|
lastReset = doc?.reset !== void 0 && doc.reset !== null && typeof doc.reset === "object" && typeof doc.reset.offsetHours === "number" ? doc.reset : null;
|
|
1342
1408
|
bound?.setSettings(lastMonitored, lastOnFull);
|
|
1343
1409
|
bound?.setCheckUpdates(doc?.checkUpdates ?? true);
|
|
1410
|
+
bound?.setDimWhenIdle(doc?.dimWhenIdle ?? false);
|
|
1344
1411
|
bound?.setReset(lastReset);
|
|
1345
1412
|
fetch("/token-quota", { headers: { accept: "application/json" } }).then((response) => {
|
|
1346
1413
|
if (!response.ok) {
|
|
@@ -1406,6 +1473,10 @@ window.__ModuleLoader__.load({
|
|
|
1406
1473
|
bound?.setCheckUpdates(enabled);
|
|
1407
1474
|
scope.set("checkUpdates", enabled);
|
|
1408
1475
|
};
|
|
1476
|
+
const setDimWhenIdle = (enabled) => {
|
|
1477
|
+
bound?.setDimWhenIdle(enabled);
|
|
1478
|
+
scope.set("dimWhenIdle", enabled);
|
|
1479
|
+
};
|
|
1409
1480
|
/** Ask the Host to check the registry right now, then refresh the snapshot. */
|
|
1410
1481
|
const checkUpdatesNow = () => {
|
|
1411
1482
|
bound?.setCheckingUpdates(true);
|
|
@@ -1426,7 +1497,8 @@ window.__ModuleLoader__.load({
|
|
|
1426
1497
|
bound?.setUpgrade(snapshot.upgrade ?? null);
|
|
1427
1498
|
bound?.setUpgradeError(snapshot.upgradeError ?? null);
|
|
1428
1499
|
actOnFull(snapshot);
|
|
1429
|
-
if (snapshot.upgrade
|
|
1500
|
+
if (snapshot.upgrade !== null) bound?.setDialogOpen(false);
|
|
1501
|
+
else bound?.setLastCheckResult(snapshot.upgradeError !== null ? "error" : "up-to-date");
|
|
1430
1502
|
}
|
|
1431
1503
|
bound?.setCheckingUpdates(false);
|
|
1432
1504
|
setTimeout(() => {
|
|
@@ -1487,7 +1559,8 @@ window.__ModuleLoader__.load({
|
|
|
1487
1559
|
setReset,
|
|
1488
1560
|
setCheckUpdates,
|
|
1489
1561
|
checkUpdatesNow,
|
|
1490
|
-
clearLogBefore
|
|
1562
|
+
clearLogBefore,
|
|
1563
|
+
setDimWhenIdle
|
|
1491
1564
|
};
|
|
1492
1565
|
};
|
|
1493
1566
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
package/lib/index.js
CHANGED
|
@@ -163,6 +163,7 @@ const TOKEN_QUOTA_SETTINGS_SCHEMA = z.object({
|
|
|
163
163
|
"switchPriority"
|
|
164
164
|
]).default("stop"),
|
|
165
165
|
checkUpdates: z.boolean().default(true),
|
|
166
|
+
dimWhenIdle: z.boolean().default(false),
|
|
166
167
|
reset: z.any().default(null)
|
|
167
168
|
});
|
|
168
169
|
/** Two-digit zero-pad helper. */
|
|
@@ -219,7 +220,8 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
219
220
|
limits: {},
|
|
220
221
|
monitored: [],
|
|
221
222
|
onFull: "stop",
|
|
222
|
-
checkUpdates: true
|
|
223
|
+
checkUpdates: true,
|
|
224
|
+
dimWhenIdle: false
|
|
223
225
|
});
|
|
224
226
|
/** Whether update checks are enabled (mirrors the settings document). */
|
|
225
227
|
checkUpdates = true;
|
|
@@ -266,6 +268,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
266
268
|
monitored: doc.monitored ?? [],
|
|
267
269
|
onFull: doc.onFull === "switchPriority" ? "switchAll" : doc.onFull ?? "stop",
|
|
268
270
|
checkUpdates: doc.checkUpdates ?? true,
|
|
271
|
+
dimWhenIdle: doc.dimWhenIdle ?? false,
|
|
269
272
|
reset: doc.reset ?? void 0
|
|
270
273
|
};
|
|
271
274
|
};
|
|
@@ -406,7 +409,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
406
409
|
return this.upgradeCheck;
|
|
407
410
|
}
|
|
408
411
|
async doRefreshUpgrade() {
|
|
409
|
-
const current = "0.1.
|
|
412
|
+
const current = "0.1.17";
|
|
410
413
|
let latest;
|
|
411
414
|
try {
|
|
412
415
|
const response = await fetch(REGISTRY_LATEST_URL, {
|
|
@@ -18,6 +18,8 @@ export interface TokenQuotaPanelInjected {
|
|
|
18
18
|
setReset: (reset: TokenQuotaReset | null) => void;
|
|
19
19
|
/** Persist whether the Host may check npm for newer versions. */
|
|
20
20
|
setCheckUpdates: (enabled: boolean) => void;
|
|
21
|
+
/** Persist whether the panel dims while the pointer is away / typing. */
|
|
22
|
+
setDimWhenIdle: (enabled: boolean) => void;
|
|
21
23
|
/** Ask the Host to check the registry right now, then refresh the snapshot. */
|
|
22
24
|
checkUpdatesNow: () => void;
|
|
23
25
|
/** Ask the Host to clear log entries before a date, then refresh the log. */
|
|
@@ -30,5 +32,5 @@ export type TokenQuotaPanelComponentProps = PropsRuntime<'shell.overlay'> & Prop
|
|
|
30
32
|
* @param props - composed slot props.
|
|
31
33
|
* @returns the panel element tree.
|
|
32
34
|
*/
|
|
33
|
-
export declare function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, useStore, actions, useSessions, }: TokenQuotaPanelComponentProps): import("react").JSX.Element;
|
|
35
|
+
export declare function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, useStore, actions, useSessions, }: TokenQuotaPanelComponentProps): import("react").JSX.Element;
|
|
34
36
|
//# sourceMappingURL=TokenQuotaPanel.d.ts.map
|
|
@@ -86,7 +86,7 @@ function loadPanelPos() {
|
|
|
86
86
|
* @param props - composed slot props.
|
|
87
87
|
* @returns the panel element tree.
|
|
88
88
|
*/
|
|
89
|
-
export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, useStore, actions, useSessions, }) {
|
|
89
|
+
export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, useStore, actions, useSessions, }) {
|
|
90
90
|
const [collapsed, setCollapsed] = useState(false);
|
|
91
91
|
const [drafts, setDrafts] = useState({});
|
|
92
92
|
const [editingKey, setEditingKey] = useState(null);
|
|
@@ -95,6 +95,15 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
95
95
|
// so the chat content behind it stays readable; hovering restores it.
|
|
96
96
|
const [hovered, setHovered] = useState(false);
|
|
97
97
|
const [inputActive, setInputActive] = useState(false);
|
|
98
|
+
// Copy-button feedback: which command was just copied (label flips to
|
|
99
|
+
// 「已复制」for a moment so the click is perceivable).
|
|
100
|
+
const [copiedCmd, setCopiedCmd] = useState(null);
|
|
101
|
+
const copyTimerRef = useRef(null);
|
|
102
|
+
// Flash state for the upgrade banner: armed when a NEW latest version shows
|
|
103
|
+
// up (either from a manual check or a periodic poll).
|
|
104
|
+
const [upgradeFlash, setUpgradeFlash] = useState(false);
|
|
105
|
+
const flashTimerRef = useRef(null);
|
|
106
|
+
const prevUpgradeRef = useRef(null);
|
|
98
107
|
// Draggable placements: the panel persists across reloads; the dialogs
|
|
99
108
|
// start centered (null) and remember where they were dragged to.
|
|
100
109
|
const [panelPos, setPanelPos] = useState(loadPanelPos);
|
|
@@ -119,6 +128,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
119
128
|
const monitored = useStore(s => s.monitored);
|
|
120
129
|
const onFull = useStore(s => s.onFull);
|
|
121
130
|
const checkUpdates = useStore(s => s.checkUpdates);
|
|
131
|
+
const dimWhenIdle = useStore(s => s.dimWhenIdle);
|
|
122
132
|
const upgrade = useStore(s => s.upgrade);
|
|
123
133
|
const upgradeDismissed = useStore(s => s.upgradeDismissed);
|
|
124
134
|
const checkingUpdates = useStore(s => s.checkingUpdates);
|
|
@@ -154,6 +164,34 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
154
164
|
window.addEventListener('focusin', onFocusIn);
|
|
155
165
|
return () => { window.removeEventListener('focusin', onFocusIn); };
|
|
156
166
|
}, []);
|
|
167
|
+
// When a NEW latest version appears (manual check or periodic poll):
|
|
168
|
+
// expand the panel (it may be collapsed), force it opaque, and flash the
|
|
169
|
+
// upgrade banner a few times so the discovery is unmissable.
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
const latest = upgrade?.latestVersion ?? null;
|
|
172
|
+
if (latest !== null && prevUpgradeRef.current !== latest) {
|
|
173
|
+
setCollapsed(false);
|
|
174
|
+
setUpgradeFlash(true);
|
|
175
|
+
if (flashTimerRef.current !== null)
|
|
176
|
+
clearTimeout(flashTimerRef.current);
|
|
177
|
+
flashTimerRef.current = window.setTimeout(() => {
|
|
178
|
+
setUpgradeFlash(false);
|
|
179
|
+
flashTimerRef.current = null;
|
|
180
|
+
}, 2500);
|
|
181
|
+
}
|
|
182
|
+
prevUpgradeRef.current = latest;
|
|
183
|
+
return () => {
|
|
184
|
+
// Keep the timer across re-renders; cleared only on unmount.
|
|
185
|
+
};
|
|
186
|
+
}, [upgrade]);
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
return () => {
|
|
189
|
+
if (flashTimerRef.current !== null)
|
|
190
|
+
clearTimeout(flashTimerRef.current);
|
|
191
|
+
if (copyTimerRef.current !== null)
|
|
192
|
+
clearTimeout(copyTimerRef.current);
|
|
193
|
+
};
|
|
194
|
+
}, []);
|
|
157
195
|
const rows = useMemo(() => mergeModelRows(groups, snapshot, current), [groups, snapshot, current]);
|
|
158
196
|
// All directory models, flattened for the monitoring picker.
|
|
159
197
|
const allModels = useMemo(() => groups.flatMap(group => group.models.map((model) => ({
|
|
@@ -197,6 +235,17 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
197
235
|
document.body.removeChild(el);
|
|
198
236
|
}
|
|
199
237
|
};
|
|
238
|
+
/** Copy an upgrade command and show per-button success feedback. */
|
|
239
|
+
const copyUpgradeCommand = (cmd) => {
|
|
240
|
+
void copyToClipboard(cmd);
|
|
241
|
+
setCopiedCmd(cmd);
|
|
242
|
+
if (copyTimerRef.current !== null)
|
|
243
|
+
clearTimeout(copyTimerRef.current);
|
|
244
|
+
copyTimerRef.current = window.setTimeout(() => {
|
|
245
|
+
setCopiedCmd(null);
|
|
246
|
+
copyTimerRef.current = null;
|
|
247
|
+
}, 1600);
|
|
248
|
+
};
|
|
200
249
|
// Fetch the usage log whenever the log dialog opens. Kept ABOVE the
|
|
201
250
|
// collapsed early-return: every hook must run on every render, otherwise
|
|
202
251
|
// React unmounts the component the moment the panel collapses (the old
|
|
@@ -237,12 +286,15 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
237
286
|
setLimit(row.key, parsed);
|
|
238
287
|
};
|
|
239
288
|
const visibleRows = rows.filter(row => isMonitoredKey(row.key) || row.current);
|
|
240
|
-
// The panel dims when the pointer is away
|
|
241
|
-
//
|
|
242
|
-
|
|
289
|
+
// The panel dims when the pointer is away ONLY when the user opted in
|
|
290
|
+
// (settings → 失焦窗口透明). While the upgrade banner flashes, the panel
|
|
291
|
+
// is forced opaque regardless.
|
|
292
|
+
const panelDimClass = dimWhenIdle
|
|
293
|
+
? (hovered || upgradeFlash ? '' : inputActive ? css.panelDimStrong : css.panelDim)
|
|
294
|
+
: '';
|
|
243
295
|
return (_jsxs("div", { ref: panelRef, className: `${css.panel}${panelDimClass !== '' ? ` ${panelDimClass}` : ''}`, style: panelPos !== null ? { left: panelPos.x, top: panelPos.y, right: 'auto' } : undefined, onPointerEnter: () => { setHovered(true); }, onPointerLeave: () => { setHovered(false); }, children: [_jsxs("div", { className: css.header, onPointerDown: (event) => { beginDrag(event, panelRef.current, applyPanelPos); }, children: [_jsxs("div", { className: css.headerText, children: [_jsxs("div", { className: css.title, children: [t('title'), __TOKEN_QUOTA_VERSION__ !== undefined && __TOKEN_QUOTA_VERSION__ !== '' && (upgrade !== null
|
|
244
296
|
? (_jsxs("span", { className: `${css.version} ${css.versionNew}`, title: t('upgradeAvailableHint'), children: ["v", __TOKEN_QUOTA_VERSION__, " \u2192 v", upgrade.latestVersion] }))
|
|
245
|
-
: (_jsxs("span", { className: css.version, children: ["v", __TOKEN_QUOTA_VERSION__] })))] }), _jsx("div", { className: css.subtitle, children: t('subtitle') })] }), _jsxs("div", { className: css.headerActions, onPointerDown: (event) => { event.stopPropagation(); }, children: [_jsx("button", { type: "button", className: css.settingsBtn, onClick: () => { actions.setLogOpen(true); }, children: t('logs') }), _jsx("button", { type: "button", className: css.settingsBtn, onClick: openSettings, children: t('settings') }), _jsx("button", { type: "button", className: css.collapse, onClick: () => { setCollapsed(true); }, children: t('collapse') })] })] }), _jsxs("div", { className: css.body, children: [loading && _jsx("div", { className: css.notice, children: t('loading') }), error !== null && _jsx("div", { className: css.noticeError, children: error }), fullNotice !== null && (_jsx("div", { className: css.fullNotice, role: "alert", children: fullNotice })), upgrade !== null && !upgradeDismissed && (_jsxs("div", { className: css.upgradeBanner
|
|
297
|
+
: (_jsxs("span", { className: css.version, children: ["v", __TOKEN_QUOTA_VERSION__] })))] }), _jsx("div", { className: css.subtitle, children: t('subtitle') })] }), _jsxs("div", { className: css.headerActions, onPointerDown: (event) => { event.stopPropagation(); }, children: [_jsx("button", { type: "button", className: css.settingsBtn, onClick: () => { actions.setLogOpen(true); }, children: t('logs') }), _jsx("button", { type: "button", className: css.settingsBtn, onClick: openSettings, children: t('settings') }), _jsx("button", { type: "button", className: css.collapse, onClick: () => { setCollapsed(true); }, children: t('collapse') })] })] }), _jsxs("div", { className: css.body, children: [loading && _jsx("div", { className: css.notice, children: t('loading') }), error !== null && _jsx("div", { className: css.noticeError, children: error }), fullNotice !== null && (_jsx("div", { className: css.fullNotice, role: "alert", children: fullNotice })), upgrade !== null && !upgradeDismissed && (_jsxs("div", { className: `${css.upgradeBanner}${upgradeFlash ? ` ${css.upgradeBannerFlash}` : ''}`, role: "alert", children: [_jsx("div", { className: css.upgradeBannerText, children: t('upgradeAvailable').replace('{version}', upgrade.latestVersion) }), _jsx("div", { className: css.upgradeCommands, children: upgrade.commands.map(cmd => (_jsxs("div", { className: css.upgradeCommandRow, children: [_jsx("code", { className: css.upgradeCommand, children: cmd }), _jsx("button", { type: "button", className: `${css.copyBtn}${copiedCmd === cmd ? ` ${css.copyBtnDone}` : ''}`, onClick: () => { copyUpgradeCommand(cmd); }, children: copiedCmd === cmd ? t('copied') : t('copy') })] }, cmd))) }), _jsx("div", { className: css.upgradeHint, children: t('upgradeHint') }), _jsx("button", { type: "button", className: css.upgradeClose, onClick: () => { actions.setUpgradeDismissed(true); }, "aria-label": t('close'), children: "\u00D7" })] })), !loading && error === null && visibleRows.length === 0 && (_jsx("div", { className: css.notice, children: monitored !== null && monitored.length === 0 ? t('noMonitored') : t('waiting') })), visibleRows.map((row) => {
|
|
246
298
|
const state = barStateOf(row);
|
|
247
299
|
const pct = row.limit > 0 ? Math.min(100, Math.round((row.used / row.limit) * 100)) : 0;
|
|
248
300
|
const barClass = state === 'over'
|
|
@@ -282,7 +334,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
282
334
|
hour: reset?.hour ?? 0,
|
|
283
335
|
minute: Number(event.target.value),
|
|
284
336
|
});
|
|
285
|
-
}, children: Array.from({ length: 12 }, (_, i) => i * 5).map(minute => (_jsxs("option", { value: minute, children: [String(minute).padStart(2, '0'), " \u5206"] }, minute))) })] })] }), _jsxs("div", { className: css.dialogSection, children: [_jsxs("div", { className: css.checkUpdatesRow, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: checkUpdates, onChange: (event) => { setCheckUpdates(event.target.checked); } }), _jsx("span", { children: t('checkUpdatesLabel') })] }), _jsx("button", { type: "button", className: css.checkBtn, disabled: checkingUpdates, onClick: checkUpdatesNow, children: checkingUpdates
|
|
337
|
+
}, children: Array.from({ length: 12 }, (_, i) => i * 5).map(minute => (_jsxs("option", { value: minute, children: [String(minute).padStart(2, '0'), " \u5206"] }, minute))) })] })] }), _jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: dimWhenIdle, onChange: (event) => { setDimWhenIdle(event.target.checked); } }), _jsx("span", { children: t('dimWhenIdleLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('dimWhenIdleHint') })] }), _jsxs("div", { className: css.dialogSection, children: [_jsxs("div", { className: css.checkUpdatesRow, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: checkUpdates, onChange: (event) => { setCheckUpdates(event.target.checked); } }), _jsx("span", { children: t('checkUpdatesLabel') })] }), _jsx("button", { type: "button", className: css.checkBtn, disabled: checkingUpdates, onClick: checkUpdatesNow, children: checkingUpdates
|
|
286
338
|
? t('checkingUpdates')
|
|
287
339
|
: lastCheckResult === 'up-to-date'
|
|
288
340
|
? t('checkUpToDate')
|
|
@@ -171,6 +171,7 @@ export function apply(ctx) {
|
|
|
171
171
|
: null;
|
|
172
172
|
bound?.setSettings(lastMonitored, lastOnFull);
|
|
173
173
|
bound?.setCheckUpdates(doc?.checkUpdates ?? true);
|
|
174
|
+
bound?.setDimWhenIdle(doc?.dimWhenIdle ?? false);
|
|
174
175
|
bound?.setReset(lastReset);
|
|
175
176
|
void fetch('/token-quota', { headers: { accept: 'application/json' } }).then((response) => {
|
|
176
177
|
if (!response.ok) {
|
|
@@ -234,6 +235,10 @@ export function apply(ctx) {
|
|
|
234
235
|
bound?.setCheckUpdates(enabled);
|
|
235
236
|
void scope.set('checkUpdates', enabled);
|
|
236
237
|
};
|
|
238
|
+
const setDimWhenIdle = (enabled) => {
|
|
239
|
+
bound?.setDimWhenIdle(enabled);
|
|
240
|
+
void scope.set('dimWhenIdle', enabled);
|
|
241
|
+
};
|
|
237
242
|
/** Ask the Host to check the registry right now, then refresh the snapshot. */
|
|
238
243
|
const checkUpdatesNow = () => {
|
|
239
244
|
bound?.setCheckingUpdates(true);
|
|
@@ -254,7 +259,12 @@ export function apply(ctx) {
|
|
|
254
259
|
bound?.setUpgrade(snapshot.upgrade ?? null);
|
|
255
260
|
bound?.setUpgradeError(snapshot.upgradeError ?? null);
|
|
256
261
|
actOnFull(snapshot);
|
|
257
|
-
if (snapshot.upgrade
|
|
262
|
+
if (snapshot.upgrade !== null) {
|
|
263
|
+
// A new version was found: close the settings dialog so the
|
|
264
|
+
// flashing upgrade banner in the panel is immediately visible.
|
|
265
|
+
bound?.setDialogOpen(false);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
258
268
|
// No newer version known: distinguish "checked OK, up to date"
|
|
259
269
|
// from "check failed" via the host-provided error message.
|
|
260
270
|
bound?.setLastCheckResult(snapshot.upgradeError !== null ? 'error' : 'up-to-date');
|
|
@@ -315,7 +325,7 @@ export function apply(ctx) {
|
|
|
315
325
|
bound = actions;
|
|
316
326
|
return {
|
|
317
327
|
load, setLimit, selectModel, setMonitored, setOnFull, setReset,
|
|
318
|
-
setCheckUpdates, checkUpdatesNow, clearLogBefore,
|
|
328
|
+
setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle,
|
|
319
329
|
};
|
|
320
330
|
};
|
|
321
331
|
ctx.slots.inject('shell.overlay', () => ctx.slots.register({
|
|
@@ -61,8 +61,11 @@ export declare const zh: {
|
|
|
61
61
|
upgradeAvailableHint: string;
|
|
62
62
|
upgradeAvailable: string;
|
|
63
63
|
copy: string;
|
|
64
|
+
copied: string;
|
|
64
65
|
upgradeHint: string;
|
|
65
66
|
checkUpdatesLabel: string;
|
|
67
|
+
dimWhenIdleLabel: string;
|
|
68
|
+
dimWhenIdleHint: string;
|
|
66
69
|
checkUpdatesNow: string;
|
|
67
70
|
checkingUpdates: string;
|
|
68
71
|
checkUpToDate: string;
|
|
@@ -127,8 +130,11 @@ export declare const en: {
|
|
|
127
130
|
upgradeAvailableHint: string;
|
|
128
131
|
upgradeAvailable: string;
|
|
129
132
|
copy: string;
|
|
133
|
+
copied: string;
|
|
130
134
|
upgradeHint: string;
|
|
131
135
|
checkUpdatesLabel: string;
|
|
136
|
+
dimWhenIdleLabel: string;
|
|
137
|
+
dimWhenIdleHint: string;
|
|
132
138
|
checkUpdatesNow: string;
|
|
133
139
|
checkingUpdates: string;
|
|
134
140
|
checkUpToDate: string;
|
|
@@ -61,8 +61,11 @@ export const zh = {
|
|
|
61
61
|
upgradeAvailableHint: '有新版本可用',
|
|
62
62
|
upgradeAvailable: '发现新版本 v{version},请在终端执行以下命令升级:',
|
|
63
63
|
copy: '复制',
|
|
64
|
+
copied: '已复制 ✓',
|
|
64
65
|
upgradeHint: '升级后请重启 dsh web 并刷新浏览器页面',
|
|
65
66
|
checkUpdatesLabel: '自动检查更新',
|
|
67
|
+
dimWhenIdleLabel: '失焦时窗口透明',
|
|
68
|
+
dimWhenIdleHint: '鼠标移开面板时降低不透明度,输入文字时更透明;鼠标悬停恢复',
|
|
66
69
|
checkUpdatesNow: '立即检查',
|
|
67
70
|
checkingUpdates: '检查中…',
|
|
68
71
|
checkUpToDate: '已是最新',
|
|
@@ -125,8 +128,11 @@ export const en = {
|
|
|
125
128
|
upgradeAvailableHint: 'A new version is available',
|
|
126
129
|
upgradeAvailable: 'A new version v{version} is available. Run one of the following commands in your terminal to upgrade:',
|
|
127
130
|
copy: 'Copy',
|
|
131
|
+
copied: 'Copied ✓',
|
|
128
132
|
upgradeHint: 'After upgrading, restart dsh web and refresh the browser',
|
|
129
133
|
checkUpdatesLabel: 'Check for updates automatically',
|
|
134
|
+
dimWhenIdleLabel: 'Dim panel when unfocused',
|
|
135
|
+
dimWhenIdleHint: 'Fade the panel out when the pointer is away (more while typing); hover to restore',
|
|
130
136
|
checkUpdatesNow: 'Check now',
|
|
131
137
|
checkingUpdates: 'Checking…',
|
|
132
138
|
checkUpToDate: 'Up to date',
|
|
@@ -48,6 +48,8 @@ export interface TokenQuotaPanelState {
|
|
|
48
48
|
onFull: TokenQuotaFullAction;
|
|
49
49
|
/** Whether the Host is allowed to check npm for newer versions. */
|
|
50
50
|
checkUpdates: boolean;
|
|
51
|
+
/** Whether the panel dims while the pointer is away / while typing. */
|
|
52
|
+
dimWhenIdle: boolean;
|
|
51
53
|
/** Latest upgrade availability from the Host; null = up to date or unknown. */
|
|
52
54
|
upgrade: TokenQuotaUpgrade | null;
|
|
53
55
|
/** Whether the one-shot upgrade banner was dismissed for the current latest version. */
|
|
@@ -89,6 +91,7 @@ export type TokenQuotaPanelActions = {
|
|
|
89
91
|
setError: (d: TokenQuotaPanelState, error: string | null) => void;
|
|
90
92
|
setSettings: (d: TokenQuotaPanelState, monitored: string[] | null, onFull: TokenQuotaFullAction) => void;
|
|
91
93
|
setCheckUpdates: (d: TokenQuotaPanelState, checkUpdates: boolean) => void;
|
|
94
|
+
setDimWhenIdle: (d: TokenQuotaPanelState, dimWhenIdle: boolean) => void;
|
|
92
95
|
setUpgrade: (d: TokenQuotaPanelState, upgrade: TokenQuotaUpgrade | null) => void;
|
|
93
96
|
setUpgradeDismissed: (d: TokenQuotaPanelState, dismissed: boolean) => void;
|
|
94
97
|
setCheckingUpdates: (d: TokenQuotaPanelState, checking: boolean) => void;
|
|
@@ -27,6 +27,7 @@ export function createTokenQuotaPanelStore() {
|
|
|
27
27
|
monitored: null,
|
|
28
28
|
onFull: 'stop',
|
|
29
29
|
checkUpdates: true,
|
|
30
|
+
dimWhenIdle: false,
|
|
30
31
|
upgrade: null,
|
|
31
32
|
upgradeDismissed: false,
|
|
32
33
|
checkingUpdates: false,
|
|
@@ -51,13 +52,23 @@ export function createTokenQuotaPanelStore() {
|
|
|
51
52
|
setError: (d, error) => { d.error = error; },
|
|
52
53
|
setSettings: (d, monitored, onFull) => { d.monitored = monitored; d.onFull = onFull; },
|
|
53
54
|
setCheckUpdates: (d, checkUpdates) => { d.checkUpdates = checkUpdates; },
|
|
55
|
+
setDimWhenIdle: (d, dimWhenIdle) => { d.dimWhenIdle = dimWhenIdle; },
|
|
54
56
|
setUpgrade: (d, upgrade) => {
|
|
57
|
+
// Guard against host/client version skew (e.g. the host process still
|
|
58
|
+
// runs an older bundle after an upgrade): when the reported "latest"
|
|
59
|
+
// equals the client's own version, there is nothing to upgrade to.
|
|
60
|
+
// This prevents a confusing `v0.1.16 → v0.1.16` banner.
|
|
61
|
+
const normalized = upgrade !== null
|
|
62
|
+
&& upgrade.latestVersion !== ''
|
|
63
|
+
&& upgrade.latestVersion !== __TOKEN_QUOTA_VERSION__
|
|
64
|
+
? upgrade
|
|
65
|
+
: null;
|
|
55
66
|
// A new latest version re-arms the one-shot banner; the same version
|
|
56
67
|
// stays dismissed until the user dismisses it again (or it changes).
|
|
57
|
-
if (d.upgrade === null || d.upgrade.latestVersion !==
|
|
68
|
+
if (d.upgrade === null || d.upgrade.latestVersion !== normalized?.latestVersion) {
|
|
58
69
|
d.upgradeDismissed = false;
|
|
59
70
|
}
|
|
60
|
-
d.upgrade =
|
|
71
|
+
d.upgrade = normalized;
|
|
61
72
|
},
|
|
62
73
|
setUpgradeDismissed: (d, dismissed) => { d.upgradeDismissed = dismissed; },
|
|
63
74
|
setCheckingUpdates: (d, checking) => { d.checkingUpdates = checking; },
|
package/lib/types/index.js
CHANGED
|
@@ -156,6 +156,8 @@ const TOKEN_QUOTA_SETTINGS_SCHEMA = z.object({
|
|
|
156
156
|
// without reconfiguring.
|
|
157
157
|
onFull: z.union(['stop', 'switchQuota', 'switchAll', 'switchPriority']).default('stop'),
|
|
158
158
|
checkUpdates: z.boolean().default(true),
|
|
159
|
+
// Client-side appearance preference; the host only stores it.
|
|
160
|
+
dimWhenIdle: z.boolean().default(false),
|
|
159
161
|
// `reset` is a user-facing preference outside the validated surface: the
|
|
160
162
|
// panel writes it and the host validates the shape at runtime. `z.any` with
|
|
161
163
|
// a null default keeps it out of the strict fields above.
|
|
@@ -220,7 +222,7 @@ export class TokenQuotaService extends Service {
|
|
|
220
222
|
history = {};
|
|
221
223
|
limits = {};
|
|
222
224
|
monitored = undefined;
|
|
223
|
-
settingsSource = () => ({ limits: {}, monitored: [], onFull: 'stop', checkUpdates: true });
|
|
225
|
+
settingsSource = () => ({ limits: {}, monitored: [], onFull: 'stop', checkUpdates: true, dimWhenIdle: false });
|
|
224
226
|
/** Whether update checks are enabled (mirrors the settings document). */
|
|
225
227
|
checkUpdates = true;
|
|
226
228
|
/** Cached upgrade availability; recomputed by {@link refreshUpgrade}. */
|
|
@@ -275,6 +277,7 @@ export class TokenQuotaService extends Service {
|
|
|
275
277
|
// capped models first, then uncapped — both monitored-only.
|
|
276
278
|
onFull: doc.onFull === 'switchPriority' ? 'switchAll' : (doc.onFull ?? 'stop'),
|
|
277
279
|
checkUpdates: doc.checkUpdates ?? true,
|
|
280
|
+
dimWhenIdle: doc.dimWhenIdle ?? false,
|
|
278
281
|
reset: doc.reset ?? undefined,
|
|
279
282
|
};
|
|
280
283
|
};
|
package/lib/types/types.d.ts
CHANGED
|
@@ -68,6 +68,12 @@ export interface TokenQuotaSettings {
|
|
|
68
68
|
* and surfaces an update notice in the panel. `true` by default.
|
|
69
69
|
*/
|
|
70
70
|
checkUpdates: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Client-side appearance preference: dim the floating panel while the
|
|
73
|
+
* pointer is away (and more while typing) so the content behind stays
|
|
74
|
+
* readable. `false` by default — the panel stays fully opaque.
|
|
75
|
+
*/
|
|
76
|
+
dimWhenIdle: boolean;
|
|
71
77
|
/**
|
|
72
78
|
* Daily reset moment (timezone + clock time). Absent = machine-local
|
|
73
79
|
* midnight (the historical behaviour).
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxgame2020/dsh-token-quota",
|
|
3
3
|
"description": "Daily per-model token quota accounting, enforcement, and a floating quota panel for the DeepSeek Harness — a fully self-contained plugin (no core-Harness wiring, no generated RPC contract)",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.17",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|