dsh-plugin-subscriptions 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -1
- package/README.zh.md +42 -1
- package/lib/auth/device-flow.d.ts +0 -9
- package/lib/auth/device-flow.js +2 -1
- package/lib/auth/rpc.d.ts +44 -13
- package/lib/auth/rpc.js +127 -9
- package/lib/auth/store.d.ts +75 -17
- package/lib/auth/store.js +148 -27
- package/lib/client/SubscriptionsSection.d.ts +26 -3
- package/lib/client/SubscriptionsSection.js +263 -67
- package/lib/client/index.js +11 -0
- package/lib/client/locales.d.ts +82 -10
- package/lib/client/locales.js +82 -10
- package/lib/client.js +837 -223
- package/lib/client.js.map +1 -1
- package/lib/http.d.ts +114 -0
- package/lib/http.js +402 -0
- package/lib/index.d.ts +21 -0
- package/lib/index.js +1938 -208
- package/lib/providers/accounts.d.ts +102 -0
- package/lib/providers/accounts.js +123 -0
- package/lib/providers/antigravity.d.ts +90 -0
- package/lib/providers/antigravity.js +392 -0
- package/lib/providers/claude.d.ts +22 -4
- package/lib/providers/claude.js +97 -16
- package/lib/providers/codex.d.ts +24 -3
- package/lib/providers/codex.js +121 -21
- package/lib/providers/common.d.ts +17 -0
- package/lib/providers/common.js +67 -3
- package/lib/providers/copilot.d.ts +23 -4
- package/lib/providers/copilot.js +99 -19
- package/lib/providers/grok.d.ts +24 -4
- package/lib/providers/grok.js +106 -19
- package/lib/providers/pool-family.d.ts +56 -0
- package/lib/providers/pool-family.js +45 -0
- package/lib/providers/pool-health.d.ts +74 -0
- package/lib/providers/pool-health.js +148 -0
- package/lib/providers/pool-usage.d.ts +57 -0
- package/lib/providers/pool-usage.js +130 -0
- package/lib/providers/pool.d.ts +107 -0
- package/lib/providers/pool.js +371 -0
- package/lib/tools/image-generate.d.ts +3 -3
- package/lib/tools/image-generate.js +4 -2
- package/lib/tools/video-generate.d.ts +2 -2
- package/lib/tools/video-generate.js +4 -2
- package/lib/tools/x-search.d.ts +2 -2
- package/lib/tools/x-search.js +4 -2
- package/lib/translate/antigravity.d.ts +110 -0
- package/lib/translate/antigravity.js +303 -0
- package/package.json +14 -9
package/lib/client.js
CHANGED
|
@@ -39,15 +39,19 @@ const en = {
|
|
|
39
39
|
unavailable: "Connection unavailable; subscription status cannot be loaded.",
|
|
40
40
|
checking: "Checking…",
|
|
41
41
|
loginInProgress: "Login in progress…",
|
|
42
|
-
loggedIn: "Logged in",
|
|
43
|
-
loggedInAccount: "Logged in as {account}",
|
|
44
|
-
loggedInExpires: "Logged in · expires {date}",
|
|
45
|
-
loggedInAccountExpires: "Logged in as {account} · expires {date}",
|
|
46
42
|
notLoggedIn: "Not logged in",
|
|
43
|
+
loggedInCount: "{count} account(s) connected",
|
|
44
|
+
accountExpires: "expires {date}",
|
|
45
|
+
defaultBadge: "Default",
|
|
46
|
+
setDefault: "Set as default",
|
|
47
|
+
addAccount: "Add account",
|
|
48
|
+
addAccountOAuth: "Browser authorization",
|
|
49
|
+
addAccountKeychain: "Import Claude Code",
|
|
50
|
+
addAccountHint: "Browser authorization signs in whichever account the browser currently uses — switch accounts there first (or use an incognito window with the manual code below) to add a different one.",
|
|
47
51
|
login: "Log in",
|
|
48
52
|
cancel: "Cancel",
|
|
49
53
|
logout: "Log out",
|
|
50
|
-
|
|
54
|
+
logoutAccountConfirm: "Log out {account} of {provider}?",
|
|
51
55
|
manualSummary: "Browser flow not working? Paste the callback URL or code",
|
|
52
56
|
manualPlaceholder: "Paste the callback URL or code",
|
|
53
57
|
submit: "Submit",
|
|
@@ -83,7 +87,39 @@ const en = {
|
|
|
83
87
|
speedFast: "Fast",
|
|
84
88
|
speedFastDescription: "1.5x speed, more usage",
|
|
85
89
|
commandFast: "Switch the Codex speed tier (Standard/Fast)",
|
|
86
|
-
commandFastUnavailable: "The current model has no fast tier; /fast only works on Codex models whose catalog advertises one"
|
|
90
|
+
commandFastUnavailable: "The current model has no fast tier; /fast only works on Codex models whose catalog advertises one",
|
|
91
|
+
proxyTitle: "Proxy",
|
|
92
|
+
proxyStatusNone: "Not configured — subscription requests go direct.",
|
|
93
|
+
proxyStatusEnabled: "Enabled · {url}",
|
|
94
|
+
proxyStatusError: "Config error: {message}",
|
|
95
|
+
proxyConfigure: "Configure…",
|
|
96
|
+
proxyDialogTitle: "Proxy settings",
|
|
97
|
+
proxyDialogClose: "Close",
|
|
98
|
+
proxyEnabled: "Route subscription requests through a proxy",
|
|
99
|
+
proxyUrl: "Proxy URL",
|
|
100
|
+
proxyUrlPlaceholder: "http://localhost:7890",
|
|
101
|
+
proxyUrlHint: "HTTP or HTTPS proxy only (Clash/mihomo, v2rayN…); socks is not supported.",
|
|
102
|
+
proxyUsername: "Username (optional)",
|
|
103
|
+
proxyUsernamePlaceholder: "Proxy username",
|
|
104
|
+
proxyPassword: "Password",
|
|
105
|
+
proxyPasswordPlaceholder: "Leave blank to keep the saved password",
|
|
106
|
+
proxyClearPassword: "Clear the saved password",
|
|
107
|
+
proxyBypass: "Bypass hosts",
|
|
108
|
+
proxyBypassPlaceholder: "127.0.0.1, localhost, *.example.com",
|
|
109
|
+
proxyBypassHint: "Comma-separated hostnames that keep going direct.",
|
|
110
|
+
proxyTest: "Test",
|
|
111
|
+
proxyTesting: "Testing…",
|
|
112
|
+
proxyTestOk: "OK · HTTP {status} · {ms} ms",
|
|
113
|
+
proxyTestOkDirect: "OK (direct, bypassed) · HTTP {status} · {ms} ms",
|
|
114
|
+
proxyTestFail: "Failed: {message}",
|
|
115
|
+
proxySave: "Save",
|
|
116
|
+
proxyCancel: "Cancel",
|
|
117
|
+
proxySaving: "Saving…",
|
|
118
|
+
proxyLoading: "Loading proxy settings…",
|
|
119
|
+
proxyLoadFailed: "Failed to load proxy settings: {message}",
|
|
120
|
+
proxySaved: "Saved — new requests use the proxy.",
|
|
121
|
+
proxySaveFailed: "Save failed: {message}",
|
|
122
|
+
proxyNote: "Applies to token exchange, model APIs, usage lookups, image/video generation and x_search. The OAuth authorization page opens in your browser and follows the browser/system proxy, not this setting."
|
|
87
123
|
};
|
|
88
124
|
/** zh strings, one per {@link en} key. */
|
|
89
125
|
const zh = {
|
|
@@ -92,15 +128,19 @@ const zh = {
|
|
|
92
128
|
unavailable: "连接不可用,无法加载订阅状态。",
|
|
93
129
|
checking: "查询中…",
|
|
94
130
|
loginInProgress: "登录中…",
|
|
95
|
-
loggedIn: "已登录",
|
|
96
|
-
loggedInAccount: "已登录:{account}",
|
|
97
|
-
loggedInExpires: "已登录 · 过期时间 {date}",
|
|
98
|
-
loggedInAccountExpires: "已登录:{account} · 过期时间 {date}",
|
|
99
131
|
notLoggedIn: "未登录",
|
|
132
|
+
loggedInCount: "已连接 {count} 个账号",
|
|
133
|
+
accountExpires: "过期时间 {date}",
|
|
134
|
+
defaultBadge: "默认",
|
|
135
|
+
setDefault: "设为默认",
|
|
136
|
+
addAccount: "添加账号",
|
|
137
|
+
addAccountOAuth: "浏览器授权",
|
|
138
|
+
addAccountKeychain: "导入 Claude Code",
|
|
139
|
+
addAccountHint: "浏览器授权以浏览器当前登录的账号为准;要添加不同账号,请先在浏览器里切换账号,或用无痕窗口走下方手动授权码。",
|
|
100
140
|
login: "登录",
|
|
101
141
|
cancel: "取消",
|
|
102
142
|
logout: "退出登录",
|
|
103
|
-
|
|
143
|
+
logoutAccountConfirm: "确定退出 {provider} 的账号 {account} 吗?",
|
|
104
144
|
manualSummary: "浏览器流程无法完成?粘贴回调 URL 或授权码",
|
|
105
145
|
manualPlaceholder: "粘贴回调 URL 或授权码",
|
|
106
146
|
submit: "提交",
|
|
@@ -136,7 +176,39 @@ const zh = {
|
|
|
136
176
|
speedFast: "快速",
|
|
137
177
|
speedFastDescription: "约 1.5 倍速度,消耗更多用量",
|
|
138
178
|
commandFast: "切换 Codex 速度档(标准/快速)",
|
|
139
|
-
commandFastUnavailable: "当前模型不支持快速档;/fast 仅对目录声明了 fast tier 的 Codex 模型可用"
|
|
179
|
+
commandFastUnavailable: "当前模型不支持快速档;/fast 仅对目录声明了 fast tier 的 Codex 模型可用",
|
|
180
|
+
proxyTitle: "代理",
|
|
181
|
+
proxyStatusNone: "未配置 —— 订阅请求直连。",
|
|
182
|
+
proxyStatusEnabled: "已启用 · {url}",
|
|
183
|
+
proxyStatusError: "配置错误:{message}",
|
|
184
|
+
proxyConfigure: "配置…",
|
|
185
|
+
proxyDialogTitle: "代理设置",
|
|
186
|
+
proxyDialogClose: "关闭",
|
|
187
|
+
proxyEnabled: "让订阅相关请求走代理",
|
|
188
|
+
proxyUrl: "代理地址",
|
|
189
|
+
proxyUrlPlaceholder: "http://localhost:7890",
|
|
190
|
+
proxyUrlHint: "仅支持 HTTP/HTTPS 代理(Clash/mihomo、v2rayN 等);不支持 socks。",
|
|
191
|
+
proxyUsername: "用户名(可选)",
|
|
192
|
+
proxyUsernamePlaceholder: "代理用户名",
|
|
193
|
+
proxyPassword: "密码",
|
|
194
|
+
proxyPasswordPlaceholder: "留空则保留已保存的密码",
|
|
195
|
+
proxyClearPassword: "清除已保存的密码",
|
|
196
|
+
proxyBypass: "绕过主机",
|
|
197
|
+
proxyBypassPlaceholder: "127.0.0.1, localhost, *.example.com",
|
|
198
|
+
proxyBypassHint: "逗号分隔的主机名,这些主机保持直连。",
|
|
199
|
+
proxyTest: "测试",
|
|
200
|
+
proxyTesting: "测试中…",
|
|
201
|
+
proxyTestOk: "成功 · HTTP {status} · {ms} ms",
|
|
202
|
+
proxyTestOkDirect: "成功(直连,已绕过)· HTTP {status} · {ms} ms",
|
|
203
|
+
proxyTestFail: "失败:{message}",
|
|
204
|
+
proxySave: "保存",
|
|
205
|
+
proxyCancel: "取消",
|
|
206
|
+
proxySaving: "保存中…",
|
|
207
|
+
proxyLoading: "代理设置加载中…",
|
|
208
|
+
proxyLoadFailed: "代理设置加载失败:{message}",
|
|
209
|
+
proxySaved: "已保存 —— 后续请求将走代理。",
|
|
210
|
+
proxySaveFailed: "保存失败:{message}",
|
|
211
|
+
proxyNote: "作用于 token 交换、模型 API、用量查询、图片/视频生成与 x_search。OAuth 授权页在浏览器中打开,走的是浏览器/系统代理,不受此设置影响。"
|
|
140
212
|
};
|
|
141
213
|
|
|
142
214
|
//#endregion
|
|
@@ -188,6 +260,14 @@ async function callSubscriptionsAuth(rpc, endpoint, payload) {
|
|
|
188
260
|
function messageOf(error) {
|
|
189
261
|
return error instanceof Error ? error.message : String(error);
|
|
190
262
|
}
|
|
263
|
+
/** Copy a keyed map without the entries whose key is not in `live`. */
|
|
264
|
+
function dropStale(map, live) {
|
|
265
|
+
const stale = Object.keys(map).filter((key) => !live.has(key));
|
|
266
|
+
if (stale.length === 0) return map;
|
|
267
|
+
const next = { ...map };
|
|
268
|
+
for (const key of stale) delete next[key];
|
|
269
|
+
return next;
|
|
270
|
+
}
|
|
191
271
|
/**
|
|
192
272
|
* English-dictionary fallback for a missing inject `t` (standalone renders);
|
|
193
273
|
* the slot inject always supplies the locale-bound one.
|
|
@@ -222,6 +302,13 @@ const styles$4 = {
|
|
|
222
302
|
flexDirection: "column",
|
|
223
303
|
gap: 6
|
|
224
304
|
},
|
|
305
|
+
proxyCard: {
|
|
306
|
+
padding: "12px 14px",
|
|
307
|
+
display: "flex",
|
|
308
|
+
flexDirection: "column",
|
|
309
|
+
gap: 6
|
|
310
|
+
},
|
|
311
|
+
separator: { borderTop: "1px solid var(--dsw-alias-border-l2)" },
|
|
225
312
|
cardHeader: {
|
|
226
313
|
display: "flex",
|
|
227
314
|
alignItems: "center",
|
|
@@ -328,6 +415,36 @@ const styles$4 = {
|
|
|
328
415
|
lineHeight: "18px",
|
|
329
416
|
color: "var(--dsw-alias-label-tertiary)"
|
|
330
417
|
},
|
|
418
|
+
accountRow: {
|
|
419
|
+
display: "flex",
|
|
420
|
+
flexDirection: "column",
|
|
421
|
+
gap: 6,
|
|
422
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
423
|
+
borderRadius: 8,
|
|
424
|
+
padding: "8px 10px",
|
|
425
|
+
marginTop: 4
|
|
426
|
+
},
|
|
427
|
+
accountHeader: {
|
|
428
|
+
display: "flex",
|
|
429
|
+
alignItems: "center",
|
|
430
|
+
gap: 8
|
|
431
|
+
},
|
|
432
|
+
accountName: {
|
|
433
|
+
fontSize: 13,
|
|
434
|
+
lineHeight: "20px",
|
|
435
|
+
color: "var(--dsw-alias-label-primary)",
|
|
436
|
+
userSelect: "all"
|
|
437
|
+
},
|
|
438
|
+
starButton: {
|
|
439
|
+
border: "none",
|
|
440
|
+
background: "transparent",
|
|
441
|
+
padding: 0,
|
|
442
|
+
font: "inherit",
|
|
443
|
+
fontSize: 14,
|
|
444
|
+
lineHeight: "20px",
|
|
445
|
+
cursor: "pointer",
|
|
446
|
+
color: "var(--dsw-alias-state-warn-label)"
|
|
447
|
+
},
|
|
331
448
|
usageTrack: {
|
|
332
449
|
height: 6,
|
|
333
450
|
borderRadius: 3,
|
|
@@ -380,12 +497,97 @@ const styles$4 = {
|
|
|
380
497
|
letterSpacing: 2,
|
|
381
498
|
color: "var(--dsw-alias-label-primary)",
|
|
382
499
|
userSelect: "all"
|
|
500
|
+
},
|
|
501
|
+
proxyField: {
|
|
502
|
+
display: "flex",
|
|
503
|
+
flexDirection: "column",
|
|
504
|
+
gap: 4
|
|
505
|
+
},
|
|
506
|
+
proxyLabel: {
|
|
507
|
+
fontSize: 12,
|
|
508
|
+
lineHeight: "18px",
|
|
509
|
+
color: "var(--dsw-alias-label-secondary)"
|
|
510
|
+
},
|
|
511
|
+
proxyInput: {
|
|
512
|
+
height: 32,
|
|
513
|
+
width: "100%",
|
|
514
|
+
boxSizing: "border-box",
|
|
515
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
516
|
+
borderRadius: 8,
|
|
517
|
+
padding: "0 10px",
|
|
518
|
+
font: "inherit",
|
|
519
|
+
fontSize: 14,
|
|
520
|
+
lineHeight: "22px",
|
|
521
|
+
background: "var(--dsw-alias-bg-layer-1)",
|
|
522
|
+
color: "var(--dsw-alias-label-primary)"
|
|
523
|
+
},
|
|
524
|
+
proxyHint: {
|
|
525
|
+
margin: 0,
|
|
526
|
+
fontSize: 12,
|
|
527
|
+
lineHeight: "18px",
|
|
528
|
+
color: "var(--dsw-alias-label-tertiary)"
|
|
529
|
+
},
|
|
530
|
+
proxyCheck: {
|
|
531
|
+
display: "flex",
|
|
532
|
+
alignItems: "center",
|
|
533
|
+
gap: 8,
|
|
534
|
+
fontSize: 13,
|
|
535
|
+
lineHeight: "20px",
|
|
536
|
+
color: "var(--dsw-alias-label-primary)",
|
|
537
|
+
cursor: "pointer"
|
|
538
|
+
},
|
|
539
|
+
proxyMessage: {
|
|
540
|
+
margin: 0,
|
|
541
|
+
fontSize: 12,
|
|
542
|
+
lineHeight: "18px"
|
|
543
|
+
},
|
|
544
|
+
proxyActions: {
|
|
545
|
+
display: "flex",
|
|
546
|
+
gap: 8,
|
|
547
|
+
alignItems: "center",
|
|
548
|
+
justifyContent: "flex-end",
|
|
549
|
+
marginTop: 2
|
|
550
|
+
},
|
|
551
|
+
modalOverlay: {
|
|
552
|
+
position: "fixed",
|
|
553
|
+
inset: 0,
|
|
554
|
+
zIndex: 1e3,
|
|
555
|
+
display: "flex",
|
|
556
|
+
alignItems: "center",
|
|
557
|
+
justifyContent: "center",
|
|
558
|
+
padding: 16,
|
|
559
|
+
background: "rgba(0, 0, 0, 0.45)"
|
|
560
|
+
},
|
|
561
|
+
modal: {
|
|
562
|
+
width: 460,
|
|
563
|
+
maxWidth: "100%",
|
|
564
|
+
maxHeight: "90vh",
|
|
565
|
+
overflowY: "auto",
|
|
566
|
+
boxSizing: "border-box",
|
|
567
|
+
display: "flex",
|
|
568
|
+
flexDirection: "column",
|
|
569
|
+
gap: 12,
|
|
570
|
+
padding: "16px 18px",
|
|
571
|
+
borderRadius: 12,
|
|
572
|
+
background: "var(--dsw-alias-bg-layer-1)",
|
|
573
|
+
border: "1px solid var(--dsw-alias-border-l2)"
|
|
574
|
+
},
|
|
575
|
+
modalHeader: {
|
|
576
|
+
display: "flex",
|
|
577
|
+
alignItems: "center",
|
|
578
|
+
gap: 8
|
|
579
|
+
},
|
|
580
|
+
modalTitle: {
|
|
581
|
+
fontWeight: 600,
|
|
582
|
+
fontSize: 15,
|
|
583
|
+
lineHeight: "22px",
|
|
584
|
+
color: "var(--dsw-alias-label-primary)"
|
|
383
585
|
}
|
|
384
586
|
};
|
|
385
587
|
/** Status dot color for one provider state. */
|
|
386
588
|
function dotColor(status) {
|
|
387
589
|
if (status?.busy === true) return "var(--dsw-alias-state-warn-label)";
|
|
388
|
-
if (status?.
|
|
590
|
+
if ((status?.accounts.length ?? 0) > 0) return "var(--dsw-alias-state-success-primary)";
|
|
389
591
|
return "var(--dsw-alias-label-dimmed)";
|
|
390
592
|
}
|
|
391
593
|
/**
|
|
@@ -397,15 +599,7 @@ function dotColor(status) {
|
|
|
397
599
|
function statusText(t, status) {
|
|
398
600
|
if (status === void 0) return t("checking");
|
|
399
601
|
if (status.busy) return t("loginInProgress");
|
|
400
|
-
if (status.
|
|
401
|
-
const params = {};
|
|
402
|
-
if (status.account !== void 0) params.account = status.account;
|
|
403
|
-
if (status.expiresAt !== void 0) params.date = new Date(status.expiresAt).toLocaleString();
|
|
404
|
-
if (params.account !== void 0 && params.date !== void 0) return t("loggedInAccountExpires", params);
|
|
405
|
-
if (params.account !== void 0) return t("loggedInAccount", params);
|
|
406
|
-
if (params.date !== void 0) return t("loggedInExpires", params);
|
|
407
|
-
return t("loggedIn");
|
|
408
|
-
}
|
|
602
|
+
if (status.accounts.length > 0) return t("loggedInCount", { count: status.accounts.length });
|
|
409
603
|
return t("notLoggedIn");
|
|
410
604
|
}
|
|
411
605
|
/**
|
|
@@ -424,6 +618,18 @@ function usageBarColor(usedPercent) {
|
|
|
424
618
|
if (usedPercent >= 80) return "var(--dsw-alias-state-warn-label)";
|
|
425
619
|
return "var(--dsw-alias-state-success-primary)";
|
|
426
620
|
}
|
|
621
|
+
/** One-line status text of the proxy config card. */
|
|
622
|
+
function proxyStatusText(t, proxy, loadError) {
|
|
623
|
+
if (loadError !== void 0) return t("proxyLoadFailed", { message: loadError });
|
|
624
|
+
if (proxy === void 0) return t("proxyLoading");
|
|
625
|
+
if (proxy.error !== void 0) return t("proxyStatusError", { message: proxy.error });
|
|
626
|
+
if (proxy.enabled) return t("proxyStatusEnabled", { url: proxy.url });
|
|
627
|
+
return t("proxyStatusNone");
|
|
628
|
+
}
|
|
629
|
+
/** Feedback-line color of the proxy dialog. */
|
|
630
|
+
function messageColor(tone) {
|
|
631
|
+
return tone === "error" ? "var(--dsw-alias-state-error-primary)" : "var(--dsw-alias-state-success-primary)";
|
|
632
|
+
}
|
|
427
633
|
/**
|
|
428
634
|
* The Subscriptions settings page component.
|
|
429
635
|
* @param props - the slot inject face ({@link SubscriptionsSectionInjected}).
|
|
@@ -443,13 +649,29 @@ function SubscriptionsSection(props) {
|
|
|
443
649
|
/** Pending device-flow codes (copilot), shown while the attempt polls. */
|
|
444
650
|
const [deviceCodes, setDeviceCodes] = (0, react.useState)({});
|
|
445
651
|
const [copiedCode, setCopiedCode] = (0, react.useState)(void 0);
|
|
652
|
+
/** Usage snapshots keyed `${provider}:${accountKey}` — every account tracks its own windows. */
|
|
446
653
|
const [usages, setUsages] = (0, react.useState)({});
|
|
447
654
|
const [usageErrors, setUsageErrors] = (0, react.useState)({});
|
|
448
655
|
const [usageLoading, setUsageLoading] = (0, react.useState)({});
|
|
449
656
|
const mountedRef = (0, react.useRef)(true);
|
|
450
657
|
const pollersRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
451
|
-
/**
|
|
658
|
+
/** Accounts with a `usage` call in flight; guards the auto-fetch effect against re-entry. */
|
|
452
659
|
const usageInflightRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
660
|
+
/** Proxy config as last answered by `proxyGet`/`proxySet`. */
|
|
661
|
+
const [proxy, setProxy] = (0, react.useState)(void 0);
|
|
662
|
+
const [proxyLoadError, setProxyLoadError] = (0, react.useState)(void 0);
|
|
663
|
+
/** Proxy dialog state (draft fields; the password never pre-fills). */
|
|
664
|
+
const [proxyOpen, setProxyOpen] = (0, react.useState)(false);
|
|
665
|
+
const [proxyEnabled, setProxyEnabled] = (0, react.useState)(false);
|
|
666
|
+
const [proxyUrl, setProxyUrl] = (0, react.useState)("");
|
|
667
|
+
const [proxyUsername, setProxyUsername] = (0, react.useState)("");
|
|
668
|
+
const [proxyPassword, setProxyPassword] = (0, react.useState)("");
|
|
669
|
+
const [proxyClearPassword, setProxyClearPassword] = (0, react.useState)(false);
|
|
670
|
+
const [proxyBypass, setProxyBypass] = (0, react.useState)("");
|
|
671
|
+
const [proxySaving, setProxySaving] = (0, react.useState)(false);
|
|
672
|
+
const [proxyTesting, setProxyTesting] = (0, react.useState)(false);
|
|
673
|
+
const [proxyMessage, setProxyMessage] = (0, react.useState)(void 0);
|
|
674
|
+
const [proxyTestResult, setProxyTestResult] = (0, react.useState)(void 0);
|
|
453
675
|
const setProviderError = (0, react.useCallback)((provider, message) => {
|
|
454
676
|
if (!mountedRef.current) return;
|
|
455
677
|
setErrors((prev) => {
|
|
@@ -479,7 +701,7 @@ function SubscriptionsSection(props) {
|
|
|
479
701
|
setStatuses(response.providers);
|
|
480
702
|
for (const { id } of PROVIDERS) {
|
|
481
703
|
const status = response.providers[id];
|
|
482
|
-
if (status.
|
|
704
|
+
if (status.accounts.length > 0 || !status.busy) {
|
|
483
705
|
stopPolling(id);
|
|
484
706
|
setDeviceCodes((prev) => {
|
|
485
707
|
if (prev[id] === void 0) return prev;
|
|
@@ -511,68 +733,65 @@ function SubscriptionsSection(props) {
|
|
|
511
733
|
pollersRef.current.clear();
|
|
512
734
|
};
|
|
513
735
|
}, [refresh, startPolling]);
|
|
514
|
-
const loadUsage = (0, react.useCallback)(async (provider) => {
|
|
515
|
-
|
|
516
|
-
usageInflightRef.current.
|
|
736
|
+
const loadUsage = (0, react.useCallback)(async (provider, account) => {
|
|
737
|
+
const key = `${provider}:${account}`;
|
|
738
|
+
if (rpc === void 0 || usageInflightRef.current.has(key)) return;
|
|
739
|
+
usageInflightRef.current.add(key);
|
|
517
740
|
setUsageLoading((prev) => ({
|
|
518
741
|
...prev,
|
|
519
|
-
[
|
|
742
|
+
[key]: true
|
|
520
743
|
}));
|
|
521
744
|
try {
|
|
522
|
-
const usage = await callSubscriptionsAuth(rpc, "usage", {
|
|
745
|
+
const usage = await callSubscriptionsAuth(rpc, "usage", {
|
|
746
|
+
provider,
|
|
747
|
+
account
|
|
748
|
+
});
|
|
523
749
|
if (!mountedRef.current) return;
|
|
524
750
|
setUsages((prev) => ({
|
|
525
751
|
...prev,
|
|
526
|
-
[
|
|
752
|
+
[key]: usage
|
|
527
753
|
}));
|
|
528
754
|
setUsageErrors((prev) => {
|
|
529
755
|
const next = { ...prev };
|
|
530
|
-
delete next[
|
|
756
|
+
delete next[key];
|
|
531
757
|
return next;
|
|
532
758
|
});
|
|
533
759
|
} catch (error) {
|
|
534
760
|
if (mountedRef.current) setUsageErrors((prev) => ({
|
|
535
761
|
...prev,
|
|
536
|
-
[
|
|
762
|
+
[key]: messageOf(error)
|
|
537
763
|
}));
|
|
538
764
|
} finally {
|
|
539
|
-
usageInflightRef.current.delete(
|
|
765
|
+
usageInflightRef.current.delete(key);
|
|
540
766
|
if (mountedRef.current) setUsageLoading((prev) => ({
|
|
541
767
|
...prev,
|
|
542
|
-
[
|
|
768
|
+
[key]: false
|
|
543
769
|
}));
|
|
544
770
|
}
|
|
545
771
|
}, [rpc]);
|
|
546
772
|
(0, react.useEffect)(() => {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
} else if (usages[id] !== void 0 || usageErrors[id] !== void 0) {
|
|
553
|
-
setUsages((prev) => {
|
|
554
|
-
const next = { ...prev };
|
|
555
|
-
delete next[id];
|
|
556
|
-
return next;
|
|
557
|
-
});
|
|
558
|
-
setUsageErrors((prev) => {
|
|
559
|
-
const next = { ...prev };
|
|
560
|
-
delete next[id];
|
|
561
|
-
return next;
|
|
562
|
-
});
|
|
563
|
-
}
|
|
773
|
+
const live = /* @__PURE__ */ new Set();
|
|
774
|
+
for (const { id } of PROVIDERS) for (const account of statuses[id]?.accounts ?? []) {
|
|
775
|
+
const key = `${id}:${account.key}`;
|
|
776
|
+
live.add(key);
|
|
777
|
+
if (usages[key] === void 0 && usageErrors[key] === void 0) loadUsage(id, account.key);
|
|
564
778
|
}
|
|
779
|
+
setUsages((prev) => dropStale(prev, live));
|
|
780
|
+
setUsageErrors((prev) => dropStale(prev, live));
|
|
565
781
|
}, [
|
|
566
782
|
statuses,
|
|
567
783
|
usages,
|
|
568
784
|
usageErrors,
|
|
569
785
|
loadUsage
|
|
570
786
|
]);
|
|
571
|
-
const login = (0, react.useCallback)(async (provider) => {
|
|
787
|
+
const login = (0, react.useCallback)(async (provider, method) => {
|
|
572
788
|
if (rpc === void 0) return;
|
|
573
789
|
setProviderError(provider, void 0);
|
|
574
790
|
try {
|
|
575
|
-
const response = await callSubscriptionsAuth(rpc, "login", {
|
|
791
|
+
const response = await callSubscriptionsAuth(rpc, "login", {
|
|
792
|
+
provider,
|
|
793
|
+
...method === void 0 ? {} : { method }
|
|
794
|
+
});
|
|
576
795
|
if (typeof response.authorizeUrl === "string" && response.authorizeUrl === "") {
|
|
577
796
|
await refresh();
|
|
578
797
|
return;
|
|
@@ -582,9 +801,9 @@ function SubscriptionsSection(props) {
|
|
|
582
801
|
setStatuses((prev) => ({
|
|
583
802
|
...prev,
|
|
584
803
|
[provider]: {
|
|
804
|
+
accounts: prev[provider]?.accounts ?? [],
|
|
585
805
|
...prev[provider],
|
|
586
|
-
busy: true
|
|
587
|
-
loggedIn: false
|
|
806
|
+
busy: true
|
|
588
807
|
}
|
|
589
808
|
}));
|
|
590
809
|
if (typeof response.userCode === "string" && response.userCode.length > 0) setDeviceCodes((prev) => ({
|
|
@@ -644,12 +863,18 @@ function SubscriptionsSection(props) {
|
|
|
644
863
|
setProviderError,
|
|
645
864
|
refresh
|
|
646
865
|
]);
|
|
647
|
-
const logout = (0, react.useCallback)(async (provider, name) => {
|
|
866
|
+
const logout = (0, react.useCallback)(async (provider, account, display, name) => {
|
|
648
867
|
if (rpc === void 0) return;
|
|
649
|
-
if (!window.confirm(t("
|
|
868
|
+
if (!window.confirm(t("logoutAccountConfirm", {
|
|
869
|
+
provider: name,
|
|
870
|
+
account: display
|
|
871
|
+
}))) return;
|
|
650
872
|
setProviderError(provider, void 0);
|
|
651
873
|
try {
|
|
652
|
-
await callSubscriptionsAuth(rpc, "logout", {
|
|
874
|
+
await callSubscriptionsAuth(rpc, "logout", {
|
|
875
|
+
provider,
|
|
876
|
+
account
|
|
877
|
+
});
|
|
653
878
|
} catch (error) {
|
|
654
879
|
setProviderError(provider, messageOf(error));
|
|
655
880
|
}
|
|
@@ -660,6 +885,23 @@ function SubscriptionsSection(props) {
|
|
|
660
885
|
setProviderError,
|
|
661
886
|
refresh
|
|
662
887
|
]);
|
|
888
|
+
const setDefault = (0, react.useCallback)(async (provider, account) => {
|
|
889
|
+
if (rpc === void 0) return;
|
|
890
|
+
setProviderError(provider, void 0);
|
|
891
|
+
try {
|
|
892
|
+
await callSubscriptionsAuth(rpc, "setDefault", {
|
|
893
|
+
provider,
|
|
894
|
+
account
|
|
895
|
+
});
|
|
896
|
+
} catch (error) {
|
|
897
|
+
setProviderError(provider, messageOf(error));
|
|
898
|
+
}
|
|
899
|
+
await refresh();
|
|
900
|
+
}, [
|
|
901
|
+
rpc,
|
|
902
|
+
setProviderError,
|
|
903
|
+
refresh
|
|
904
|
+
]);
|
|
663
905
|
const copyDeviceCode = (0, react.useCallback)((provider, userCode) => {
|
|
664
906
|
navigator.clipboard?.writeText(userCode).then(() => {
|
|
665
907
|
if (!mountedRef.current) return;
|
|
@@ -669,194 +911,559 @@ function SubscriptionsSection(props) {
|
|
|
669
911
|
}, 1500);
|
|
670
912
|
}).catch(() => void 0);
|
|
671
913
|
}, []);
|
|
914
|
+
(0, react.useEffect)(() => {
|
|
915
|
+
if (rpc === void 0) return;
|
|
916
|
+
let alive = true;
|
|
917
|
+
callSubscriptionsAuth(rpc, "proxyGet", {}).then((view) => {
|
|
918
|
+
if (!alive) return;
|
|
919
|
+
setProxy(view);
|
|
920
|
+
setProxyLoadError(void 0);
|
|
921
|
+
}).catch((error) => {
|
|
922
|
+
if (alive) setProxyLoadError(messageOf(error));
|
|
923
|
+
});
|
|
924
|
+
return () => {
|
|
925
|
+
alive = false;
|
|
926
|
+
};
|
|
927
|
+
}, [rpc]);
|
|
928
|
+
(0, react.useEffect)(() => {
|
|
929
|
+
if (!proxyOpen) return;
|
|
930
|
+
const onKey = (event) => {
|
|
931
|
+
if (event.key === "Escape") setProxyOpen(false);
|
|
932
|
+
};
|
|
933
|
+
window.addEventListener("keydown", onKey);
|
|
934
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
935
|
+
}, [proxyOpen]);
|
|
936
|
+
const openProxyDialog = (0, react.useCallback)(() => {
|
|
937
|
+
if (proxy === void 0) return;
|
|
938
|
+
setProxyEnabled(proxy.enabled);
|
|
939
|
+
setProxyUrl(proxy.url);
|
|
940
|
+
setProxyUsername(proxy.username ?? "");
|
|
941
|
+
setProxyPassword("");
|
|
942
|
+
setProxyClearPassword(false);
|
|
943
|
+
setProxyBypass(proxy.bypass.join(", "));
|
|
944
|
+
setProxyMessage(void 0);
|
|
945
|
+
setProxyTestResult(void 0);
|
|
946
|
+
setProxyOpen(true);
|
|
947
|
+
}, [proxy]);
|
|
948
|
+
const saveProxy = (0, react.useCallback)(async () => {
|
|
949
|
+
if (rpc === void 0) return;
|
|
950
|
+
setProxySaving(true);
|
|
951
|
+
setProxyMessage(void 0);
|
|
952
|
+
try {
|
|
953
|
+
setProxy(await callSubscriptionsAuth(rpc, "proxySet", {
|
|
954
|
+
enabled: proxyEnabled,
|
|
955
|
+
url: proxyUrl.trim(),
|
|
956
|
+
username: proxyUsername,
|
|
957
|
+
...proxyClearPassword ? { password: null } : proxyPassword !== "" ? { password: proxyPassword } : {},
|
|
958
|
+
bypass: proxyBypass.split(/[,\n]/).map((entry) => entry.trim()).filter((entry) => entry !== "")
|
|
959
|
+
}));
|
|
960
|
+
setProxyLoadError(void 0);
|
|
961
|
+
setProxyMessage({
|
|
962
|
+
tone: "success",
|
|
963
|
+
text: t("proxySaved")
|
|
964
|
+
});
|
|
965
|
+
setProxyOpen(false);
|
|
966
|
+
} catch (error) {
|
|
967
|
+
setProxyMessage({
|
|
968
|
+
tone: "error",
|
|
969
|
+
text: t("proxySaveFailed", { message: messageOf(error) })
|
|
970
|
+
});
|
|
971
|
+
} finally {
|
|
972
|
+
setProxySaving(false);
|
|
973
|
+
}
|
|
974
|
+
}, [
|
|
975
|
+
rpc,
|
|
976
|
+
proxyEnabled,
|
|
977
|
+
proxyUrl,
|
|
978
|
+
proxyUsername,
|
|
979
|
+
proxyPassword,
|
|
980
|
+
proxyClearPassword,
|
|
981
|
+
proxyBypass,
|
|
982
|
+
t
|
|
983
|
+
]);
|
|
984
|
+
const testProxy = (0, react.useCallback)(async () => {
|
|
985
|
+
if (rpc === void 0 || proxyTesting) return;
|
|
986
|
+
setProxyTesting(true);
|
|
987
|
+
setProxyTestResult(void 0);
|
|
988
|
+
try {
|
|
989
|
+
setProxyTestResult(await callSubscriptionsAuth(rpc, "proxyTest", { proxy: {
|
|
990
|
+
url: proxyUrl.trim(),
|
|
991
|
+
...proxyUsername.trim() !== "" ? { username: proxyUsername.trim() } : {},
|
|
992
|
+
...proxyPassword !== "" ? { password: proxyPassword } : {}
|
|
993
|
+
} }));
|
|
994
|
+
} catch (error) {
|
|
995
|
+
setProxyTestResult({
|
|
996
|
+
ok: false,
|
|
997
|
+
viaProxy: false,
|
|
998
|
+
error: messageOf(error)
|
|
999
|
+
});
|
|
1000
|
+
} finally {
|
|
1001
|
+
setProxyTesting(false);
|
|
1002
|
+
}
|
|
1003
|
+
}, [
|
|
1004
|
+
rpc,
|
|
1005
|
+
proxyTesting,
|
|
1006
|
+
proxyUrl,
|
|
1007
|
+
proxyUsername,
|
|
1008
|
+
proxyPassword
|
|
1009
|
+
]);
|
|
672
1010
|
if (rpc === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
673
1011
|
style: styles$4.intro,
|
|
674
1012
|
children: t("unavailable")
|
|
675
1013
|
});
|
|
676
1014
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
677
1015
|
style: styles$4.section,
|
|
678
|
-
children: [
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
style: styles$4.card,
|
|
690
|
-
children: [
|
|
691
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
692
|
-
style: styles$4.cardHeader,
|
|
693
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
|
|
1016
|
+
children: [
|
|
1017
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1018
|
+
style: styles$4.intro,
|
|
1019
|
+
children: t("intro")
|
|
1020
|
+
}),
|
|
1021
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1022
|
+
style: styles$4.proxyCard,
|
|
1023
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1024
|
+
style: styles$4.cardHeader,
|
|
1025
|
+
children: [
|
|
1026
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
|
|
694
1027
|
...styles$4.dot,
|
|
695
|
-
background:
|
|
696
|
-
} }),
|
|
1028
|
+
background: proxy?.enabled === true ? "var(--dsw-alias-state-success-primary)" : "var(--dsw-alias-label-dimmed)"
|
|
1029
|
+
} }),
|
|
1030
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
697
1031
|
style: styles$4.name,
|
|
698
|
-
children:
|
|
699
|
-
})
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
1032
|
+
children: t("proxyTitle")
|
|
1033
|
+
}),
|
|
1034
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1035
|
+
type: "button",
|
|
1036
|
+
style: {
|
|
1037
|
+
...styles$4.button,
|
|
1038
|
+
marginLeft: "auto",
|
|
1039
|
+
flexShrink: 0
|
|
1040
|
+
},
|
|
1041
|
+
onClick: openProxyDialog,
|
|
1042
|
+
children: t("proxyConfigure")
|
|
1043
|
+
})
|
|
1044
|
+
]
|
|
1045
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1046
|
+
style: styles$4.statusLine,
|
|
1047
|
+
children: proxyStatusText(t, proxy, proxyLoadError)
|
|
1048
|
+
})]
|
|
1049
|
+
}),
|
|
1050
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: styles$4.separator }),
|
|
1051
|
+
PROVIDERS.map(({ id, name }) => {
|
|
1052
|
+
const status = statuses[id];
|
|
1053
|
+
const busy = status?.busy === true;
|
|
1054
|
+
const deviceCode = deviceCodes[id];
|
|
1055
|
+
const accounts = status?.accounts ?? [];
|
|
1056
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1057
|
+
style: styles$4.card,
|
|
1058
|
+
children: [
|
|
1059
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1060
|
+
style: styles$4.cardHeader,
|
|
1061
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
|
|
1062
|
+
...styles$4.dot,
|
|
1063
|
+
background: dotColor(status)
|
|
1064
|
+
} }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1065
|
+
style: styles$4.name,
|
|
1066
|
+
children: name
|
|
1067
|
+
})]
|
|
1068
|
+
}),
|
|
1069
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1070
|
+
style: styles$4.statusLine,
|
|
1071
|
+
children: statusText(t, status)
|
|
1072
|
+
}),
|
|
1073
|
+
status?.detail !== void 0 && status.detail !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1074
|
+
style: styles$4.statusLine,
|
|
1075
|
+
children: status.detail
|
|
1076
|
+
}),
|
|
1077
|
+
errors[id] !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1078
|
+
style: styles$4.errorLine,
|
|
1079
|
+
children: errors[id]
|
|
1080
|
+
}),
|
|
1081
|
+
accounts.map((account) => {
|
|
1082
|
+
const usageKey = `${id}:${account.key}`;
|
|
1083
|
+
const usage = usages[usageKey];
|
|
1084
|
+
const usageError = usageErrors[usageKey];
|
|
1085
|
+
const display = account.account ?? account.key;
|
|
1086
|
+
const showUsage = usage?.supported !== false && (usage !== void 0 || usageError !== void 0 || usageLoading[usageKey] === true);
|
|
1087
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1088
|
+
style: styles$4.accountRow,
|
|
1089
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1090
|
+
style: styles$4.accountHeader,
|
|
1091
|
+
children: [
|
|
1092
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1093
|
+
type: "button",
|
|
1094
|
+
style: styles$4.starButton,
|
|
1095
|
+
title: account.isDefault ? t("defaultBadge") : t("setDefault"),
|
|
1096
|
+
onClick: () => {
|
|
1097
|
+
if (!account.isDefault) setDefault(id, account.key);
|
|
1098
|
+
},
|
|
1099
|
+
children: account.isDefault ? "★" : "☆"
|
|
1100
|
+
}),
|
|
1101
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1102
|
+
style: styles$4.accountName,
|
|
1103
|
+
children: display
|
|
1104
|
+
}),
|
|
1105
|
+
account.plan !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1106
|
+
style: styles$4.usagePlan,
|
|
1107
|
+
children: account.plan
|
|
1108
|
+
}),
|
|
1109
|
+
account.expiresAt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1110
|
+
style: styles$4.statusLine,
|
|
1111
|
+
children: t("accountExpires", { date: new Date(account.expiresAt).toLocaleString() })
|
|
1112
|
+
}),
|
|
1113
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1114
|
+
type: "button",
|
|
1115
|
+
style: {
|
|
1116
|
+
...styles$4.button,
|
|
1117
|
+
marginLeft: "auto",
|
|
1118
|
+
flexShrink: 0
|
|
1119
|
+
},
|
|
1120
|
+
onClick: () => {
|
|
1121
|
+
logout(id, account.key, display, name);
|
|
1122
|
+
},
|
|
1123
|
+
children: t("logout")
|
|
1124
|
+
})
|
|
1125
|
+
]
|
|
1126
|
+
}), showUsage && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1127
|
+
style: styles$4.usage,
|
|
1128
|
+
children: [
|
|
1129
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1130
|
+
style: styles$4.usageHeader,
|
|
1131
|
+
children: [
|
|
1132
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1133
|
+
style: styles$4.usageTitle,
|
|
1134
|
+
children: t("usageTitle")
|
|
1135
|
+
}),
|
|
1136
|
+
usage?.plan !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1137
|
+
style: styles$4.usagePlan,
|
|
1138
|
+
children: t("usagePlan", { plan: usage.plan })
|
|
1139
|
+
}),
|
|
1140
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1141
|
+
type: "button",
|
|
1142
|
+
style: {
|
|
1143
|
+
...styles$4.usageRefresh,
|
|
1144
|
+
...usageLoading[usageKey] === true ? {
|
|
1145
|
+
opacity: .5,
|
|
1146
|
+
cursor: "default"
|
|
1147
|
+
} : {}
|
|
1148
|
+
},
|
|
1149
|
+
disabled: usageLoading[usageKey] === true,
|
|
1150
|
+
onClick: () => {
|
|
1151
|
+
loadUsage(id, account.key);
|
|
1152
|
+
},
|
|
1153
|
+
children: t("usageRefresh")
|
|
1154
|
+
})
|
|
1155
|
+
]
|
|
1156
|
+
}),
|
|
1157
|
+
usage === void 0 && usageError === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1158
|
+
style: styles$4.statusLine,
|
|
1159
|
+
children: t("usageLoading")
|
|
1160
|
+
}),
|
|
1161
|
+
usageError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1162
|
+
style: styles$4.errorLine,
|
|
1163
|
+
children: t("usageError", { message: usageError })
|
|
1164
|
+
}),
|
|
1165
|
+
usage?.windows !== void 0 && usage.windows.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1166
|
+
style: styles$4.statusLine,
|
|
1167
|
+
children: t("usageEmpty")
|
|
1168
|
+
}),
|
|
1169
|
+
(usage?.windows ?? []).map((window$1, index) => {
|
|
1170
|
+
const percent = Math.min(100, Math.max(0, window$1.usedPercent));
|
|
1171
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1172
|
+
style: styles$4.usageRow,
|
|
1173
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1174
|
+
style: styles$4.usageMeta,
|
|
1175
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: usageWindowLabel(t, window$1) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [`${String(Math.round(percent))}%`, window$1.resetsAt !== void 0 && ` · ${t("usageResets", { date: new Date(window$1.resetsAt).toLocaleString() })}`] })]
|
|
1176
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1177
|
+
style: styles$4.usageTrack,
|
|
1178
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
1179
|
+
...styles$4.usageFill,
|
|
1180
|
+
width: `${String(percent)}%`,
|
|
1181
|
+
background: usageBarColor(percent)
|
|
1182
|
+
} })
|
|
1183
|
+
})]
|
|
1184
|
+
}, index);
|
|
1185
|
+
})
|
|
1186
|
+
]
|
|
1187
|
+
})]
|
|
1188
|
+
}, account.key);
|
|
1189
|
+
}),
|
|
1190
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1191
|
+
style: styles$4.actions,
|
|
1192
|
+
children: [
|
|
1193
|
+
!busy && accounts.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1194
|
+
type: "button",
|
|
1195
|
+
style: styles$4.button,
|
|
1196
|
+
onClick: () => {
|
|
1197
|
+
login(id);
|
|
1198
|
+
},
|
|
1199
|
+
children: t("login")
|
|
1200
|
+
}),
|
|
1201
|
+
!busy && accounts.length > 0 && id === "claude" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1202
|
+
type: "button",
|
|
1203
|
+
style: styles$4.button,
|
|
1204
|
+
onClick: () => {
|
|
1205
|
+
login(id, "oauth");
|
|
1206
|
+
},
|
|
1207
|
+
children: t("addAccountOAuth")
|
|
1208
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1209
|
+
type: "button",
|
|
1210
|
+
style: styles$4.button,
|
|
1211
|
+
onClick: () => {
|
|
1212
|
+
login(id, "keychain");
|
|
1213
|
+
},
|
|
1214
|
+
children: t("addAccountKeychain")
|
|
1215
|
+
})] }),
|
|
1216
|
+
!busy && accounts.length > 0 && id !== "claude" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1217
|
+
type: "button",
|
|
1218
|
+
style: styles$4.button,
|
|
1219
|
+
onClick: () => {
|
|
1220
|
+
login(id);
|
|
1221
|
+
},
|
|
1222
|
+
children: t("addAccount")
|
|
1223
|
+
}),
|
|
1224
|
+
busy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1225
|
+
type: "button",
|
|
1226
|
+
style: styles$4.button,
|
|
1227
|
+
onClick: () => {
|
|
1228
|
+
cancel(id);
|
|
1229
|
+
},
|
|
1230
|
+
children: t("cancel")
|
|
1231
|
+
})
|
|
1232
|
+
]
|
|
1233
|
+
}),
|
|
1234
|
+
!busy && accounts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1235
|
+
style: styles$4.statusLine,
|
|
1236
|
+
children: t("addAccountHint")
|
|
1237
|
+
}),
|
|
1238
|
+
busy && deviceCode !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1239
|
+
style: styles$4.deviceCode,
|
|
1240
|
+
children: [
|
|
1241
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1242
|
+
style: styles$4.statusLine,
|
|
1243
|
+
children: t("deviceCodePrompt")
|
|
1244
|
+
}),
|
|
1245
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1246
|
+
style: styles$4.deviceCodeText,
|
|
1247
|
+
children: deviceCode.userCode
|
|
1248
|
+
}),
|
|
1249
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1250
|
+
style: styles$4.actions,
|
|
1251
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
757
1252
|
type: "button",
|
|
758
|
-
style:
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
opacity: .5,
|
|
762
|
-
cursor: "default"
|
|
763
|
-
} : {}
|
|
1253
|
+
style: styles$4.button,
|
|
1254
|
+
onClick: () => {
|
|
1255
|
+
copyDeviceCode(id, deviceCode.userCode);
|
|
764
1256
|
},
|
|
765
|
-
|
|
1257
|
+
children: copiedCode === id ? t("deviceCodeCopied") : t("deviceCodeCopy")
|
|
1258
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1259
|
+
type: "button",
|
|
1260
|
+
style: styles$4.button,
|
|
766
1261
|
onClick: () => {
|
|
767
|
-
|
|
1262
|
+
window.open(deviceCode.verificationUrl, "_blank", "noopener");
|
|
768
1263
|
},
|
|
769
|
-
children: t("
|
|
770
|
-
})
|
|
771
|
-
]
|
|
772
|
-
}),
|
|
773
|
-
usage === void 0 && usageError === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
774
|
-
style: styles$4.statusLine,
|
|
775
|
-
children: t("usageLoading")
|
|
776
|
-
}),
|
|
777
|
-
usageError !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
778
|
-
style: styles$4.errorLine,
|
|
779
|
-
children: t("usageError", { message: usageError })
|
|
780
|
-
}),
|
|
781
|
-
usage?.windows !== void 0 && usage.windows.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
782
|
-
style: styles$4.statusLine,
|
|
783
|
-
children: t("usageEmpty")
|
|
784
|
-
}),
|
|
785
|
-
(usage?.windows ?? []).map((window$1, index) => {
|
|
786
|
-
const percent = Math.min(100, Math.max(0, window$1.usedPercent));
|
|
787
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
788
|
-
style: styles$4.usageRow,
|
|
789
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
790
|
-
style: styles$4.usageMeta,
|
|
791
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: usageWindowLabel(t, window$1) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [`${String(Math.round(percent))}%`, window$1.resetsAt !== void 0 && ` · ${t("usageResets", { date: new Date(window$1.resetsAt).toLocaleString() })}`] })]
|
|
792
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
793
|
-
style: styles$4.usageTrack,
|
|
794
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
795
|
-
...styles$4.usageFill,
|
|
796
|
-
width: `${String(percent)}%`,
|
|
797
|
-
background: usageBarColor(percent)
|
|
798
|
-
} })
|
|
1264
|
+
children: t("deviceCodeOpenPage")
|
|
799
1265
|
})]
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
816
|
-
style: styles$4.actions,
|
|
817
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
818
|
-
type: "button",
|
|
819
|
-
style: styles$4.button,
|
|
820
|
-
onClick: () => {
|
|
821
|
-
copyDeviceCode(id, deviceCode.userCode);
|
|
822
|
-
},
|
|
823
|
-
children: copiedCode === id ? t("deviceCodeCopied") : t("deviceCodeCopy")
|
|
1266
|
+
})
|
|
1267
|
+
]
|
|
1268
|
+
}),
|
|
1269
|
+
busy && deviceCode === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
1270
|
+
style: styles$4.manual,
|
|
1271
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t("manualSummary") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1272
|
+
style: styles$4.manualRow,
|
|
1273
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1274
|
+
style: styles$4.manualInput,
|
|
1275
|
+
value: manualDrafts[id],
|
|
1276
|
+
placeholder: t("manualPlaceholder"),
|
|
1277
|
+
onChange: (event) => setManualDrafts((prev) => ({
|
|
1278
|
+
...prev,
|
|
1279
|
+
[id]: event.target.value
|
|
1280
|
+
}))
|
|
824
1281
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
825
1282
|
type: "button",
|
|
826
1283
|
style: styles$4.button,
|
|
827
1284
|
onClick: () => {
|
|
828
|
-
|
|
1285
|
+
submitManual(id);
|
|
829
1286
|
},
|
|
830
|
-
children: t("
|
|
1287
|
+
children: t("submit")
|
|
831
1288
|
})]
|
|
832
|
-
})
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
1289
|
+
})]
|
|
1290
|
+
})
|
|
1291
|
+
]
|
|
1292
|
+
}, id);
|
|
1293
|
+
}),
|
|
1294
|
+
proxyOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1295
|
+
style: styles$4.modalOverlay,
|
|
1296
|
+
onClick: () => setProxyOpen(false),
|
|
1297
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1298
|
+
style: styles$4.modal,
|
|
1299
|
+
onClick: (event) => event.stopPropagation(),
|
|
1300
|
+
children: [
|
|
1301
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1302
|
+
style: styles$4.modalHeader,
|
|
1303
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1304
|
+
style: styles$4.modalTitle,
|
|
1305
|
+
children: t("proxyDialogTitle")
|
|
847
1306
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
848
1307
|
type: "button",
|
|
849
|
-
style:
|
|
850
|
-
|
|
851
|
-
|
|
1308
|
+
style: {
|
|
1309
|
+
...styles$4.button,
|
|
1310
|
+
marginLeft: "auto"
|
|
852
1311
|
},
|
|
853
|
-
|
|
1312
|
+
onClick: () => setProxyOpen(false),
|
|
1313
|
+
children: t("proxyDialogClose")
|
|
854
1314
|
})]
|
|
855
|
-
})
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1315
|
+
}),
|
|
1316
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1317
|
+
style: styles$4.proxyCheck,
|
|
1318
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1319
|
+
type: "checkbox",
|
|
1320
|
+
checked: proxyEnabled,
|
|
1321
|
+
onChange: (event) => setProxyEnabled(event.target.checked)
|
|
1322
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("proxyEnabled") })]
|
|
1323
|
+
}),
|
|
1324
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1325
|
+
style: styles$4.proxyField,
|
|
1326
|
+
children: [
|
|
1327
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1328
|
+
style: styles$4.proxyLabel,
|
|
1329
|
+
children: t("proxyUrl")
|
|
1330
|
+
}),
|
|
1331
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1332
|
+
style: styles$4.proxyInput,
|
|
1333
|
+
value: proxyUrl,
|
|
1334
|
+
placeholder: t("proxyUrlPlaceholder"),
|
|
1335
|
+
onChange: (event) => setProxyUrl(event.target.value)
|
|
1336
|
+
}),
|
|
1337
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1338
|
+
style: styles$4.proxyHint,
|
|
1339
|
+
children: t("proxyUrlHint")
|
|
1340
|
+
})
|
|
1341
|
+
]
|
|
1342
|
+
}),
|
|
1343
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1344
|
+
style: styles$4.proxyField,
|
|
1345
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1346
|
+
style: styles$4.proxyLabel,
|
|
1347
|
+
children: t("proxyUsername")
|
|
1348
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1349
|
+
style: styles$4.proxyInput,
|
|
1350
|
+
value: proxyUsername,
|
|
1351
|
+
placeholder: t("proxyUsernamePlaceholder"),
|
|
1352
|
+
onChange: (event) => setProxyUsername(event.target.value)
|
|
1353
|
+
})]
|
|
1354
|
+
}),
|
|
1355
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1356
|
+
style: styles$4.proxyField,
|
|
1357
|
+
children: [
|
|
1358
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1359
|
+
style: styles$4.proxyLabel,
|
|
1360
|
+
children: t("proxyPassword")
|
|
1361
|
+
}),
|
|
1362
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1363
|
+
type: "password",
|
|
1364
|
+
style: styles$4.proxyInput,
|
|
1365
|
+
value: proxyPassword,
|
|
1366
|
+
placeholder: t("proxyPasswordPlaceholder"),
|
|
1367
|
+
onChange: (event) => setProxyPassword(event.target.value)
|
|
1368
|
+
}),
|
|
1369
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1370
|
+
style: styles$4.proxyCheck,
|
|
1371
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1372
|
+
type: "checkbox",
|
|
1373
|
+
checked: proxyClearPassword,
|
|
1374
|
+
onChange: (event) => setProxyClearPassword(event.target.checked)
|
|
1375
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("proxyClearPassword") })]
|
|
1376
|
+
})
|
|
1377
|
+
]
|
|
1378
|
+
}),
|
|
1379
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1380
|
+
style: styles$4.proxyField,
|
|
1381
|
+
children: [
|
|
1382
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1383
|
+
style: styles$4.proxyLabel,
|
|
1384
|
+
children: t("proxyBypass")
|
|
1385
|
+
}),
|
|
1386
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1387
|
+
style: styles$4.proxyInput,
|
|
1388
|
+
value: proxyBypass,
|
|
1389
|
+
placeholder: t("proxyBypassPlaceholder"),
|
|
1390
|
+
onChange: (event) => setProxyBypass(event.target.value)
|
|
1391
|
+
}),
|
|
1392
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1393
|
+
style: styles$4.proxyHint,
|
|
1394
|
+
children: t("proxyBypassHint")
|
|
1395
|
+
})
|
|
1396
|
+
]
|
|
1397
|
+
}),
|
|
1398
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1399
|
+
style: styles$4.proxyHint,
|
|
1400
|
+
children: t("proxyNote")
|
|
1401
|
+
}),
|
|
1402
|
+
proxyMessage !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1403
|
+
style: {
|
|
1404
|
+
...styles$4.proxyMessage,
|
|
1405
|
+
color: messageColor(proxyMessage.tone)
|
|
1406
|
+
},
|
|
1407
|
+
children: proxyMessage.text
|
|
1408
|
+
}),
|
|
1409
|
+
proxyTestResult !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1410
|
+
style: {
|
|
1411
|
+
...styles$4.proxyMessage,
|
|
1412
|
+
color: proxyTestResult.ok ? "var(--dsw-alias-state-success-primary)" : "var(--dsw-alias-state-error-primary)"
|
|
1413
|
+
},
|
|
1414
|
+
children: proxyTestResult.ok ? proxyTestResult.viaProxy ? t("proxyTestOk", {
|
|
1415
|
+
status: String(proxyTestResult.status),
|
|
1416
|
+
ms: String(proxyTestResult.latencyMs)
|
|
1417
|
+
}) : t("proxyTestOkDirect", {
|
|
1418
|
+
status: String(proxyTestResult.status),
|
|
1419
|
+
ms: String(proxyTestResult.latencyMs)
|
|
1420
|
+
}) : t("proxyTestFail", { message: proxyTestResult.error ?? "" })
|
|
1421
|
+
}),
|
|
1422
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1423
|
+
style: styles$4.proxyActions,
|
|
1424
|
+
children: [
|
|
1425
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1426
|
+
type: "button",
|
|
1427
|
+
style: {
|
|
1428
|
+
...styles$4.button,
|
|
1429
|
+
...proxyTesting ? {
|
|
1430
|
+
opacity: .5,
|
|
1431
|
+
cursor: "default"
|
|
1432
|
+
} : {}
|
|
1433
|
+
},
|
|
1434
|
+
disabled: proxyTesting,
|
|
1435
|
+
onClick: () => {
|
|
1436
|
+
testProxy();
|
|
1437
|
+
},
|
|
1438
|
+
children: proxyTesting ? t("proxyTesting") : t("proxyTest")
|
|
1439
|
+
}),
|
|
1440
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1441
|
+
type: "button",
|
|
1442
|
+
style: {
|
|
1443
|
+
...styles$4.button,
|
|
1444
|
+
...proxySaving ? {
|
|
1445
|
+
opacity: .5,
|
|
1446
|
+
cursor: "default"
|
|
1447
|
+
} : {}
|
|
1448
|
+
},
|
|
1449
|
+
disabled: proxySaving,
|
|
1450
|
+
onClick: () => {
|
|
1451
|
+
saveProxy();
|
|
1452
|
+
},
|
|
1453
|
+
children: proxySaving ? t("proxySaving") : t("proxySave")
|
|
1454
|
+
}),
|
|
1455
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1456
|
+
type: "button",
|
|
1457
|
+
style: styles$4.button,
|
|
1458
|
+
onClick: () => setProxyOpen(false),
|
|
1459
|
+
children: t("proxyCancel")
|
|
1460
|
+
})
|
|
1461
|
+
]
|
|
1462
|
+
})
|
|
1463
|
+
]
|
|
1464
|
+
})
|
|
1465
|
+
})
|
|
1466
|
+
]
|
|
860
1467
|
});
|
|
861
1468
|
}
|
|
862
1469
|
|
|
@@ -1738,6 +2345,13 @@ function apply(ctx) {
|
|
|
1738
2345
|
zh,
|
|
1739
2346
|
en
|
|
1740
2347
|
}), "dsh-plugin-subscriptions: copy dictionaries");
|
|
2348
|
+
ctx.effect(() => {
|
|
2349
|
+
const style = document.createElement("style");
|
|
2350
|
+
style.setAttribute("data-plugin", "dsh-plugin-subscriptions");
|
|
2351
|
+
style.textContent = "div[role=\"dialog\"][aria-modal=\"true\"]:has(> nav) { padding-top: 14px; }";
|
|
2352
|
+
document.head.appendChild(style);
|
|
2353
|
+
return () => style.remove();
|
|
2354
|
+
}, "dsh-plugin-subscriptions: settings panel breathing room");
|
|
1741
2355
|
const connection = ctx.get("connection");
|
|
1742
2356
|
const t = ctx.locale.bind(NS);
|
|
1743
2357
|
const injected = () => ({
|