@wenbin_wb/dsh-bridge 2.2.4 → 2.2.6
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 +70 -6
- package/README.zh-CN.md +70 -6
- package/client/client.js +542 -183
- package/client/index.js +475 -165
- package/docs/qq-usage.md +385 -0
- package/lib/bridge-rpc-constants.js +1 -0
- package/lib/bridge-rpc.js +5 -0
- package/lib/index.js +88 -8
- package/lib/platform/conversation-bridge.js +5 -3
- package/lib/qq/index.js +2 -0
- package/lib/tunnel-client.mjs +0 -3
- package/lib/wechat/node.js +42 -16
- package/package.json +3 -2
package/client/client.js
CHANGED
|
@@ -42,6 +42,7 @@ var BRIDGE_ENDPOINTS = {
|
|
|
42
42
|
resetCloudflared: "resetCloudflared",
|
|
43
43
|
saveCustomTunnelConfig: "saveCustomTunnelConfig",
|
|
44
44
|
checkVersion: "checkVersion",
|
|
45
|
+
upgradePlugin: "upgradePlugin",
|
|
45
46
|
// 平台管理器(多 IM 平台统一接口)
|
|
46
47
|
listPlatforms: "listPlatforms",
|
|
47
48
|
platformLogin: "platformLogin",
|
|
@@ -89,20 +90,73 @@ function semverGt(a, b) {
|
|
|
89
90
|
return av.pre > bv.pre;
|
|
90
91
|
}
|
|
91
92
|
var s = {
|
|
92
|
-
card: { background: "var(--dsw-alias-bg-layer-
|
|
93
|
+
card: { background: "var(--dsw-alias-bg-layer-2,#f9fafb)", border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", borderRadius: 12, padding: "16px 20px", marginBottom: 16 },
|
|
93
94
|
block: { borderTop: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", marginTop: 12, paddingTop: 12 },
|
|
94
95
|
muted: { color: "var(--dsw-alias-label-tertiary,#8b93a1)", fontSize: 12, lineHeight: 1.5 },
|
|
95
96
|
label: { color: "var(--dsw-alias-label-primary,currentColor)", fontSize: 13, fontWeight: 500 },
|
|
96
97
|
code: { fontFamily: "ui-monospace,Menlo,monospace", fontSize: 12, wordBreak: "break-all", color: "var(--dsw-alias-label-primary,currentColor)" },
|
|
97
98
|
btnPri: { font: "inherit", cursor: "pointer", border: "none", background: "var(--dsw-alias-brand-primary,#4f6ef7)", color: "var(--dsw-alias-label-primary-foreground,#fff)", height: 32, padding: "0 14px", borderRadius: 999, fontSize: 13, fontWeight: 500, display: "inline-flex", alignItems: "center", gap: 4 },
|
|
98
|
-
btnGhost: { font: "inherit", cursor: "pointer", border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", background: "var(--dsw-alias-bg-layer-
|
|
99
|
+
btnGhost: { font: "inherit", cursor: "pointer", border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", background: "var(--dsw-alias-bg-layer-2,#f9fafb)", color: "var(--dsw-alias-label-primary,currentColor)", height: 32, padding: "0 14px", borderRadius: 999, fontSize: 13, display: "inline-flex", alignItems: "center", gap: 4, textDecoration: "none" },
|
|
99
100
|
btnLink: { font: "inherit", cursor: "pointer", border: "none", background: "none", color: "var(--dsw-alias-brand-primary,#4f6ef7)", fontSize: 12, padding: 0, display: "inline-flex", alignItems: "center", gap: 3, textDecoration: "none" },
|
|
100
|
-
qr: { width: 200, height: 200, borderRadius: 10, border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", margin: "8px 0", display: "block" },
|
|
101
|
+
qr: { width: 200, height: 200, borderRadius: 10, border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)", margin: "8px 0", display: "block", background: "#ffffff", padding: 6, boxSizing: "border-box" },
|
|
101
102
|
tag: { display: "inline-flex", alignItems: "center", padding: "2px 8px", borderRadius: 999, fontSize: 12, fontWeight: 500 },
|
|
102
|
-
input: { width: "100%", font: "inherit", fontSize: 13, padding: "7px 10px", borderRadius: 8, border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", background: "var(--dsw-alias-bg-layer-
|
|
103
|
+
input: { width: "100%", font: "inherit", fontSize: 13, padding: "7px 10px", borderRadius: 8, border: "1px solid var(--dsw-alias-border-l2,#d1d5db)", background: "var(--dsw-alias-bg-layer-2,#f9fafb)", color: "var(--dsw-alias-label-primary,currentColor)", outline: "none", boxSizing: "border-box" },
|
|
103
104
|
warn: { background: "var(--dsw-alias-state-warn-bg,#fffbeb)", border: "1px solid var(--dsw-alias-state-warn-border,#fde68a)", borderRadius: 8, padding: "10px 14px", fontSize: 12, color: "var(--dsw-alias-state-warn-primary,#92400e)", lineHeight: 1.6 },
|
|
104
105
|
tip: { background: "var(--dsw-alias-bg-layer-2,#f9fafb)", borderRadius: 8, padding: "10px 14px", fontSize: 12, color: "var(--dsw-alias-label-secondary,#6b7280)", lineHeight: 1.6 }
|
|
105
106
|
};
|
|
107
|
+
var Icons = {
|
|
108
|
+
wechat: (props) => React.createElement(
|
|
109
|
+
"svg",
|
|
110
|
+
{ viewBox: "0 0 24 24", width: 18, height: 18, fill: "currentColor", ...props },
|
|
111
|
+
React.createElement("path", { d: "M8.5 2C4.36 2 1 4.91 1 8.5c0 2.01 1.05 3.81 2.69 4.97l-.69 2.06 2.45-1.22c.94.43 1.98.69 3.05.69.21 0 .42-.01.62-.03-.23-.62-.37-1.28-.37-1.97 0-3.59 3.36-6.5 7.5-6.5.21 0 .41.01.62.03C15.87 4.54 12.44 2 8.5 2zM6 6.5a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5zm5 0a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5zm7.5 3.5c-3.59 0-6.5 2.46-6.5 5.5 0 1.66.86 3.14 2.21 4.1l-.56 1.69 2.01-1c.78.36 1.64.57 2.54.57 3.59 0 6.5-2.46 6.5-5.5s-2.91-5.5-6.5-5.5zm-2 4a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2z" })
|
|
112
|
+
),
|
|
113
|
+
qq: (props) => React.createElement(
|
|
114
|
+
"svg",
|
|
115
|
+
{ viewBox: "0 0 24 24", width: 18, height: 18, fill: "currentColor", ...props },
|
|
116
|
+
React.createElement("path", { d: "M12 2C7.58 2 4 5.37 4 9.53c0 1.95.78 3.73 2.07 5.07-.37 1.15-.99 2.19-1.8 3.08-.18.2-.04.52.23.52 2.22 0 3.99-1.07 4.9-1.86.8.25 1.66.39 2.6.39 4.42 0 8-3.37 8-7.53S16.42 2 12 2zm-3 8a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5zm6 0a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5z" })
|
|
117
|
+
),
|
|
118
|
+
feishu: (props) => React.createElement(
|
|
119
|
+
"svg",
|
|
120
|
+
{ viewBox: "0 0 24 24", width: 18, height: 18, fill: "currentColor", ...props },
|
|
121
|
+
React.createElement("path", { d: "M12 2.5L3.5 11.2l6.8 1.8 2.2 6.5 1.8-4.7 5.2-1.4L12 2.5zm-.8 11.1l-4.1-1.1 6.5-6.6-4.2 8.3 1.8-.6z" })
|
|
122
|
+
),
|
|
123
|
+
telegram: (props) => React.createElement(
|
|
124
|
+
"svg",
|
|
125
|
+
{ viewBox: "0 0 24 24", width: 18, height: 18, fill: "currentColor", ...props },
|
|
126
|
+
React.createElement("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.64 6.8c-.15 1.58-.8 5.42-1.13 7.19-.14.75-.42 1-.68 1.03-.58.05-1.02-.38-1.58-.75-.88-.58-1.38-.94-2.23-1.5-.99-.65-.35-1.01.22-1.59.15-.15 2.71-2.48 2.76-2.69a.2.2 0 0 0-.05-.18c-.06-.05-.14-.03-.21-.02-.09.02-1.49.95-4.22 2.79-.4.27-.76.41-1.08.4-.36-.01-1.04-.2-1.55-.37-.63-.2-1.12-.31-1.08-.66.02-.18.27-.36.74-.55 2.92-1.27 4.86-2.11 5.83-2.51 2.78-1.16 3.35-1.36 3.73-1.36.08 0 .27.02.39.12.1.08.13.19.14.27-.01.06.01.24 0 .38z" })
|
|
127
|
+
),
|
|
128
|
+
lan: (props) => React.createElement(
|
|
129
|
+
"svg",
|
|
130
|
+
{ viewBox: "0 0 24 24", width: 16, height: 16, fill: "currentColor", ...props },
|
|
131
|
+
React.createElement("path", { d: "M12 3c-4.97 0-9 4.03-9 9 0 2.12.74 4.07 1.97 5.61L4.29 19.3a1 1 0 0 0 1.41 1.41l1.7-1.7C9.02 19.64 10.46 20 12 20c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 15c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zm0-9a3 3 0 1 0 0 6 3 3 0 0 0 0-6z" })
|
|
132
|
+
),
|
|
133
|
+
tunnel: (props) => React.createElement(
|
|
134
|
+
"svg",
|
|
135
|
+
{ viewBox: "0 0 24 24", width: 16, height: 16, fill: "currentColor", ...props },
|
|
136
|
+
React.createElement("path", { d: "M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4 0-2.05 1.53-3.76 3.56-3.97l1.07-.11.5-.95C8.08 7.14 9.94 6 12 6c2.62 0 4.88 1.86 5.39 4.43l.3 1.5 1.53.11c1.56.1 2.78 1.41 2.78 2.96 0 1.65-1.35 3-3 3z" })
|
|
137
|
+
),
|
|
138
|
+
bot: (props) => React.createElement(
|
|
139
|
+
"svg",
|
|
140
|
+
{ viewBox: "0 0 24 24", width: 16, height: 16, fill: "currentColor", ...props },
|
|
141
|
+
React.createElement("path", { d: "M20 9V7c0-1.1-.9-2-2-2h-3c0-1.66-1.34-3-3-3S9 3.34 9 5H6c-1.1 0-2 .9-2 2v2c-1.66 0-3 1.34-3 3s1.34 3 3 3v4c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4c1.66 0 3-1.34 3-3s-1.34-3-3-3zm-2 10H6V7h12v12zm-9-6c-.83 0-1.5-.67-1.5-1.5S8.17 10 9 10s1.5.67 1.5 1.5S9.83 13 9 13zm6 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" })
|
|
142
|
+
),
|
|
143
|
+
github: (props) => React.createElement(
|
|
144
|
+
"svg",
|
|
145
|
+
{ viewBox: "0 0 24 24", width: 13, height: 13, fill: "currentColor", ...props },
|
|
146
|
+
React.createElement("path", { d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.53 1.032 1.53 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" })
|
|
147
|
+
),
|
|
148
|
+
refresh: (props) => React.createElement(
|
|
149
|
+
"svg",
|
|
150
|
+
{ viewBox: "0 0 24 24", width: 12, height: 12, fill: "none", stroke: "currentColor", strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", ...props },
|
|
151
|
+
React.createElement("path", { d: "M23 4v6h-6M1 20v-6h6" }),
|
|
152
|
+
React.createElement("path", { d: "M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" })
|
|
153
|
+
),
|
|
154
|
+
check: (props) => React.createElement(
|
|
155
|
+
"svg",
|
|
156
|
+
{ viewBox: "0 0 24 24", width: 12, height: 12, fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", ...props },
|
|
157
|
+
React.createElement("polyline", { points: "20 6 9 17 4 12" })
|
|
158
|
+
)
|
|
159
|
+
};
|
|
106
160
|
function useCopy() {
|
|
107
161
|
const [copied, setCopied] = React.useState(false);
|
|
108
162
|
const copy = React.useCallback((text) => {
|
|
@@ -129,14 +183,38 @@ function useCopy() {
|
|
|
129
183
|
}, []);
|
|
130
184
|
return [copied, copy];
|
|
131
185
|
}
|
|
132
|
-
function StatusTag({ running }) {
|
|
186
|
+
function StatusTag({ running, status }) {
|
|
187
|
+
let bg = "var(--dsw-alias-bg-layer-2,#f3f4f6)";
|
|
188
|
+
let color = "var(--dsw-alias-label-secondary,#6b7280)";
|
|
189
|
+
let text = running ? "\u8FD0\u884C\u4E2D" : "\u672A\u542F\u52A8";
|
|
190
|
+
if (status === "connected") {
|
|
191
|
+
bg = "var(--dsw-alias-state-success-bg,#ecfdf5)";
|
|
192
|
+
color = "var(--dsw-alias-state-success-primary,#059669)";
|
|
193
|
+
text = "\u5DF2\u8FDE\u63A5";
|
|
194
|
+
} else if (status === "starting") {
|
|
195
|
+
bg = "var(--dsw-alias-state-info-bg,#eff6ff)";
|
|
196
|
+
color = "var(--dsw-alias-state-info-primary,#3b82f6)";
|
|
197
|
+
text = "\u8FDE\u63A5\u4E2D\u2026";
|
|
198
|
+
} else if (status === "reconnecting") {
|
|
199
|
+
bg = "var(--dsw-alias-state-warn-bg,#fffbeb)";
|
|
200
|
+
color = "var(--dsw-alias-state-warn-primary,#d97706)";
|
|
201
|
+
text = "\u91CD\u8FDE\u4E2D\u2026";
|
|
202
|
+
} else if (status === "paused") {
|
|
203
|
+
bg = "var(--dsw-alias-state-warn-bg,#fffbeb)";
|
|
204
|
+
color = "var(--dsw-alias-state-warn-primary,#d97706)";
|
|
205
|
+
text = "\u6682\u505C\u4E2D";
|
|
206
|
+
} else if (status === "error") {
|
|
207
|
+
bg = "var(--dsw-alias-state-error-bg,#fef2f2)";
|
|
208
|
+
color = "var(--dsw-alias-state-error-primary,#dc2626)";
|
|
209
|
+
text = "\u5F02\u5E38";
|
|
210
|
+
} else if (running) {
|
|
211
|
+
bg = "var(--dsw-alias-state-success-bg,#ecfdf5)";
|
|
212
|
+
color = "var(--dsw-alias-state-success-primary,#059669)";
|
|
213
|
+
text = "\u8FD0\u884C\u4E2D";
|
|
214
|
+
}
|
|
133
215
|
return React.createElement("span", {
|
|
134
|
-
style: {
|
|
135
|
-
|
|
136
|
-
background: running ? "var(--dsw-alias-state-success-bg,#ecfdf5)" : "var(--dsw-alias-bg-layer-2,#f3f4f6)",
|
|
137
|
-
color: running ? "var(--dsw-alias-state-success-primary,#059669)" : "var(--dsw-alias-label-secondary,#6b7280)"
|
|
138
|
-
}
|
|
139
|
-
}, running ? "\u8FD0\u884C\u4E2D" : "\u672A\u542F\u52A8");
|
|
216
|
+
style: { ...s.tag, background: bg, color }
|
|
217
|
+
}, text);
|
|
140
218
|
}
|
|
141
219
|
function QrBlock({ url, qr, onReset }) {
|
|
142
220
|
const [copied, setCopied] = React.useState(false);
|
|
@@ -220,6 +298,7 @@ var CustomTunnelConfigForm = React.memo(function CustomTunnelConfigForm2({ serve
|
|
|
220
298
|
const [serverUrl, setServerUrl] = React.useState(initUrl ?? "");
|
|
221
299
|
const [accessToken, setAccessToken] = React.useState(initToken ?? "");
|
|
222
300
|
const [saving, setSaving] = React.useState(false);
|
|
301
|
+
const [saveSuccess, setSaveSuccess] = React.useState(false);
|
|
223
302
|
const syncedRef = React.useRef(false);
|
|
224
303
|
React.useEffect(() => {
|
|
225
304
|
if (!syncedRef.current && (initUrl || initToken)) {
|
|
@@ -231,14 +310,23 @@ var CustomTunnelConfigForm = React.memo(function CustomTunnelConfigForm2({ serve
|
|
|
231
310
|
const dirty = serverUrl !== (initUrl ?? "") || accessToken !== (initToken ?? "");
|
|
232
311
|
const handleSave = React.useCallback(async () => {
|
|
233
312
|
setSaving(true);
|
|
313
|
+
setSaveSuccess(false);
|
|
234
314
|
try {
|
|
235
315
|
await onSave(serverUrl, accessToken);
|
|
316
|
+
setSaveSuccess(true);
|
|
317
|
+
setTimeout(() => setSaveSuccess(false), 2500);
|
|
236
318
|
} finally {
|
|
237
319
|
setSaving(false);
|
|
238
320
|
}
|
|
239
321
|
}, [onSave, serverUrl, accessToken]);
|
|
240
|
-
const handleUrlChange = React.useCallback((e) =>
|
|
241
|
-
|
|
322
|
+
const handleUrlChange = React.useCallback((e) => {
|
|
323
|
+
setServerUrl(e.target.value);
|
|
324
|
+
setSaveSuccess(false);
|
|
325
|
+
}, []);
|
|
326
|
+
const handleTokenChange = React.useCallback((e) => {
|
|
327
|
+
setAccessToken(e.target.value);
|
|
328
|
+
setSaveSuccess(false);
|
|
329
|
+
}, []);
|
|
242
330
|
return React.createElement(
|
|
243
331
|
"div",
|
|
244
332
|
{ style: s.block },
|
|
@@ -251,6 +339,9 @@ var CustomTunnelConfigForm = React.memo(function CustomTunnelConfigForm2({ serve
|
|
|
251
339
|
placeholder: "WebSocket \u5730\u5740\uFF0C\u4F8B\u5982 wss://tunnel.example.com/connect",
|
|
252
340
|
value: serverUrl,
|
|
253
341
|
onChange: handleUrlChange,
|
|
342
|
+
onKeyDown: (e) => {
|
|
343
|
+
if (e.key === "Enter" && dirty && !saving) handleSave();
|
|
344
|
+
},
|
|
254
345
|
disabled: saving
|
|
255
346
|
}),
|
|
256
347
|
React.createElement("input", {
|
|
@@ -259,13 +350,21 @@ var CustomTunnelConfigForm = React.memo(function CustomTunnelConfigForm2({ serve
|
|
|
259
350
|
placeholder: "\u8BBF\u95EE\u4EE4\u724C\uFF08Access Token\uFF09",
|
|
260
351
|
value: accessToken,
|
|
261
352
|
onChange: handleTokenChange,
|
|
353
|
+
onKeyDown: (e) => {
|
|
354
|
+
if (e.key === "Enter" && dirty && !saving) handleSave();
|
|
355
|
+
},
|
|
262
356
|
disabled: saving
|
|
263
357
|
}),
|
|
264
358
|
React.createElement("button", {
|
|
265
|
-
style: {
|
|
266
|
-
|
|
359
|
+
style: {
|
|
360
|
+
...s.btnPri,
|
|
361
|
+
alignSelf: "flex-start",
|
|
362
|
+
opacity: !dirty || saving ? saveSuccess ? 1 : 0.5 : 1,
|
|
363
|
+
background: saveSuccess ? "var(--dsw-alias-state-success-primary,#059669)" : void 0
|
|
364
|
+
},
|
|
365
|
+
disabled: !dirty && !saveSuccess || saving,
|
|
267
366
|
onClick: handleSave
|
|
268
|
-
}, saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u914D\u7F6E")
|
|
367
|
+
}, saving ? "\u4FDD\u5B58\u4E2D\u2026" : saveSuccess ? "\u2713 \u5DF2\u4FDD\u5B58" : "\u4FDD\u5B58\u914D\u7F6E")
|
|
269
368
|
)
|
|
270
369
|
);
|
|
271
370
|
});
|
|
@@ -381,6 +480,16 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
381
480
|
await act(BRIDGE_ENDPOINTS.platformSetAllowFrom, { allowFrom: list });
|
|
382
481
|
}, [act, platform?.allowFrom]);
|
|
383
482
|
const handleNewId = React.useCallback((e) => setNewId(e.target.value), []);
|
|
483
|
+
const [showSecret, setShowSecret] = React.useState(false);
|
|
484
|
+
const resetDefaults = React.useCallback(() => {
|
|
485
|
+
setCfgDraft((d) => ({
|
|
486
|
+
...d,
|
|
487
|
+
digestIntervalSec: "300",
|
|
488
|
+
approvalTimeoutSec: "600",
|
|
489
|
+
maxMessageChars: "2000",
|
|
490
|
+
sendChunkDelayMs: "1500"
|
|
491
|
+
}));
|
|
492
|
+
}, []);
|
|
384
493
|
const saveConfig = React.useCallback(async () => {
|
|
385
494
|
if (!cfgDraft) return;
|
|
386
495
|
const payload = {
|
|
@@ -417,12 +526,20 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
417
526
|
React.createElement(
|
|
418
527
|
"div",
|
|
419
528
|
null,
|
|
420
|
-
React.createElement(
|
|
529
|
+
React.createElement(
|
|
530
|
+
"div",
|
|
531
|
+
{ style: { ...s.label, display: "flex", alignItems: "center", gap: 7 } },
|
|
532
|
+
platformId === "wechat" && React.createElement(Icons.wechat, { style: { color: "#07C160", width: 20, height: 20 } }),
|
|
533
|
+
platformId === "qq" && React.createElement(Icons.qq, { style: { color: "#12B7F5", width: 20, height: 20 } }),
|
|
534
|
+
platformId === "feishu" && React.createElement(Icons.feishu, { style: { color: "#00D6B9", width: 20, height: 20 } }),
|
|
535
|
+
platformId === "telegram" && React.createElement(Icons.telegram, { style: { color: "#24A1DE", width: 20, height: 20 } }),
|
|
536
|
+
platformName
|
|
537
|
+
),
|
|
421
538
|
React.createElement("div", { style: { ...s.muted, marginTop: 2 } }, platformDesc)
|
|
422
539
|
),
|
|
423
|
-
React.createElement(StatusTag, { running: connected })
|
|
540
|
+
React.createElement(StatusTag, { status: platform?.status, running: connected })
|
|
424
541
|
),
|
|
425
|
-
// 快捷入口:使用说明 /
|
|
542
|
+
// 快捷入口:使用说明 / 开放平台 / 命令速查
|
|
426
543
|
React.createElement(
|
|
427
544
|
"div",
|
|
428
545
|
{ style: { display: "flex", gap: 8, marginTop: 10, flexWrap: "wrap", alignItems: "center" } },
|
|
@@ -431,7 +548,19 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
431
548
|
target: "_blank",
|
|
432
549
|
rel: "noopener noreferrer",
|
|
433
550
|
style: s.btnGhost
|
|
434
|
-
}, "\u{1F4D6} \u4F7F\u7528\u8BF4\u660E"),
|
|
551
|
+
}, "\u{1F4D6} \u5FAE\u4FE1\u4F7F\u7528\u8BF4\u660E"),
|
|
552
|
+
platformId === "qq" && React.createElement("a", {
|
|
553
|
+
href: "https://github.com/wenbin-wb/dsh-bridge/blob/main/docs/qq-usage.md",
|
|
554
|
+
target: "_blank",
|
|
555
|
+
rel: "noopener noreferrer",
|
|
556
|
+
style: s.btnGhost
|
|
557
|
+
}, "\u{1F4D6} QQ \u4F7F\u7528\u8BF4\u660E"),
|
|
558
|
+
platformId === "qq" && React.createElement("a", {
|
|
559
|
+
href: "https://bot.q.qq.com/wiki/develop/api-v2/",
|
|
560
|
+
target: "_blank",
|
|
561
|
+
rel: "noopener noreferrer",
|
|
562
|
+
style: s.btnGhost
|
|
563
|
+
}, "\u{1F310} QQ \u5F00\u653E\u5E73\u53F0"),
|
|
435
564
|
React.createElement("button", {
|
|
436
565
|
style: s.btnGhost,
|
|
437
566
|
onClick: () => setShowHelp((v) => !v)
|
|
@@ -441,32 +570,89 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
441
570
|
showHelp && React.createElement(
|
|
442
571
|
"div",
|
|
443
572
|
{ style: { ...s.block, fontSize: 12, lineHeight: 1.8, fontFamily: "monospace" } },
|
|
444
|
-
React.createElement("div", null, "/new <\u63D0\u793A\u8BCD> \u2014 \u65B0\u5EFA\u4F1A\u8BDD\uFF08\u5F53\u524D\u5DE5\u4F5C\u533A\uFF09"),
|
|
445
|
-
React.createElement("div", null, "/new <\u63D0\u793A\u8BCD> @N \u2014 \u5728\u6307\u5B9A\u5DE5\u4F5C\u533A\u65B0\u5EFA"),
|
|
446
|
-
React.createElement("div", null, "/sessions \u2014 \u6309\u5DE5\u4F5C\u533A\u5206\u7EC4\
|
|
447
|
-
React.createElement("div", null, "/use N \u2014 \u5207\u6362\u5230\u4F1A\u8BDD N"),
|
|
448
|
-
React.createElement("div", null, "/workspaces \u2014 \u5217\u51FA\u5DE5\u4F5C\u533A"),
|
|
449
|
-
React.createElement("div", null, "/
|
|
450
|
-
React.createElement("div", null, "/
|
|
451
|
-
React.createElement("div", null, "/
|
|
452
|
-
React.createElement("div", null, "/
|
|
573
|
+
React.createElement("div", null, "/new <\u63D0\u793A\u8BCD> \u2014 \u65B0\u5EFA\u4F1A\u8BDD\u5E76\u5F00\u59CB\uFF08\u5F53\u524D\u5DE5\u4F5C\u533A\uFF09"),
|
|
574
|
+
React.createElement("div", null, "/new <\u63D0\u793A\u8BCD> @N \u2014 \u5728\u6307\u5B9A\u5DE5\u4F5C\u533A\u65B0\u5EFA\u4F1A\u8BDD"),
|
|
575
|
+
React.createElement("div", null, "/sessions\uFF08\u6216 /list\uFF09\u2014 \u5217\u51FA\u4F1A\u8BDD\uFF08\u6309\u5DE5\u4F5C\u533A\u5206\u7EC4\uFF0C\u5E26\u6807\u9898\uFF09"),
|
|
576
|
+
React.createElement("div", null, "/use N\uFF08\u6216 /resume N\uFF09\u2014 \u5207\u6362\u5230\u4F1A\u8BDD N"),
|
|
577
|
+
React.createElement("div", null, "/workspaces \u2014 \u5217\u51FA\u6240\u6709\u53EF\u7528\u5DE5\u4F5C\u533A"),
|
|
578
|
+
React.createElement("div", null, "/end \u2014 \u7ED3\u675F\u5F53\u524D\u4F1A\u8BDD\uFF08\u56DE\u5230\u65E0\u6D3B\u52A8\u4F1A\u8BDD\u72B6\u6001\uFF09"),
|
|
579
|
+
React.createElement("div", null, "/stop \u2014 \u505C\u6B62\u5F53\u524D\u4EFB\u52A1"),
|
|
580
|
+
React.createElement("div", null, "/status \u2014 \u67E5\u770B Agent \u72B6\u6001\u4E0E\u4F1A\u8BDD\u6458\u8981"),
|
|
581
|
+
React.createElement("div", null, "/yes \u6216 /no\uFF08\u6216 1/2\uFF09\u2014 \u56DE\u5E94\u6743\u9650\u5BA1\u6279\u8BF7\u6C42"),
|
|
582
|
+
React.createElement("div", null, "/help \u2014 \u663E\u793A\u5B8C\u6574\u547D\u4EE4\u5E2E\u52A9")
|
|
453
583
|
),
|
|
454
584
|
err && React.createElement("div", { style: { ...s.warn, marginTop: 10 } }, err),
|
|
455
|
-
//
|
|
585
|
+
// 已配置:结构化状态看板 + 白名单
|
|
456
586
|
platform?.configured && React.createElement(
|
|
457
587
|
"div",
|
|
458
588
|
{ style: s.block },
|
|
589
|
+
// 结构化状态卡片看板
|
|
459
590
|
React.createElement(
|
|
460
591
|
"div",
|
|
461
|
-
{
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
592
|
+
{
|
|
593
|
+
style: {
|
|
594
|
+
display: "grid",
|
|
595
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(140px, 1fr))",
|
|
596
|
+
gap: 8,
|
|
597
|
+
marginBottom: 12
|
|
598
|
+
}
|
|
599
|
+
},
|
|
600
|
+
React.createElement(
|
|
601
|
+
"div",
|
|
602
|
+
{
|
|
603
|
+
style: {
|
|
604
|
+
background: "var(--dsw-alias-bg-layer-1,#fff)",
|
|
605
|
+
border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)",
|
|
606
|
+
borderRadius: 8,
|
|
607
|
+
padding: "8px 12px"
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
React.createElement("div", { style: { ...s.muted, fontSize: 11 } }, "\u8FDE\u63A5\u72B6\u6001"),
|
|
611
|
+
React.createElement(
|
|
612
|
+
"div",
|
|
613
|
+
{ style: { ...s.label, fontSize: 13, marginTop: 2, display: "flex", alignItems: "center", gap: 6 } },
|
|
614
|
+
React.createElement("span", {
|
|
615
|
+
style: {
|
|
616
|
+
width: 6,
|
|
617
|
+
height: 6,
|
|
618
|
+
borderRadius: "50%",
|
|
619
|
+
background: connected ? "var(--dsw-alias-state-success-primary,#10b981)" : "var(--dsw-alias-label-tertiary,#9ca3af)"
|
|
620
|
+
}
|
|
621
|
+
}),
|
|
622
|
+
statusLabel
|
|
623
|
+
)
|
|
624
|
+
),
|
|
625
|
+
platform.accountId && React.createElement(
|
|
626
|
+
"div",
|
|
627
|
+
{
|
|
628
|
+
style: {
|
|
629
|
+
background: "var(--dsw-alias-bg-layer-1,#fff)",
|
|
630
|
+
border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)",
|
|
631
|
+
borderRadius: 8,
|
|
632
|
+
padding: "8px 12px"
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
React.createElement("div", { style: { ...s.muted, fontSize: 11 } }, "\u767B\u5F55\u8D26\u53F7"),
|
|
636
|
+
React.createElement("div", { style: { ...s.code, fontSize: 12, marginTop: 2, fontWeight: 500 } }, platform.accountId)
|
|
637
|
+
),
|
|
638
|
+
platform.sessionId && React.createElement(
|
|
639
|
+
"div",
|
|
640
|
+
{
|
|
641
|
+
style: {
|
|
642
|
+
background: "var(--dsw-alias-bg-layer-1,#fff)",
|
|
643
|
+
border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)",
|
|
644
|
+
borderRadius: 8,
|
|
645
|
+
padding: "8px 12px"
|
|
646
|
+
}
|
|
647
|
+
},
|
|
648
|
+
React.createElement("div", { style: { ...s.muted, fontSize: 11 } }, "\u6D3B\u52A8\u4F1A\u8BDD"),
|
|
649
|
+
React.createElement("div", { style: { ...s.code, fontSize: 12, marginTop: 2 } }, platform.sessionId)
|
|
650
|
+
)
|
|
465
651
|
),
|
|
466
652
|
React.createElement(
|
|
467
653
|
"div",
|
|
468
654
|
{ style: { ...s.muted, fontSize: 12, marginTop: 8, lineHeight: 1.6 } },
|
|
469
|
-
|
|
655
|
+
`\u767D\u540D\u5355 (\u5DF2\u6388\u6743 ${platform.allowFrom?.length || 0} \u4E2A\u8D26\u53F7/\u7FA4):`
|
|
470
656
|
),
|
|
471
657
|
React.createElement(
|
|
472
658
|
"div",
|
|
@@ -493,9 +679,12 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
493
679
|
{ style: { display: "flex", gap: 8, marginTop: 8, alignItems: "center" } },
|
|
494
680
|
React.createElement("input", {
|
|
495
681
|
style: { ...s.input, flex: 1 },
|
|
496
|
-
placeholder: platformId === "wechat" ? "\u6DFB\u52A0\u5141\u8BB8\u7684\u5FAE\u4FE1 ID\uFF08\u5982 xxx@im.wechat\uFF09" : "\u6DFB\u52A0\u5141\u8BB8\u7684\u7528\u6237 ID",
|
|
682
|
+
placeholder: platformId === "wechat" ? "\u6DFB\u52A0\u5141\u8BB8\u7684\u5FAE\u4FE1 ID\uFF08\u5982 xxx@im.wechat\uFF09\uFF0C\u6309 Enter \u6DFB\u52A0" : "\u6DFB\u52A0\u5141\u8BB8\u7684\u7528\u6237/\u7FA4 ID\uFF0C\u6309 Enter \u6DFB\u52A0",
|
|
497
683
|
value: newId,
|
|
498
|
-
onChange: handleNewId
|
|
684
|
+
onChange: handleNewId,
|
|
685
|
+
onKeyDown: (e) => {
|
|
686
|
+
if (e.key === "Enter" && newId.trim() && !busy) addAllow();
|
|
687
|
+
}
|
|
499
688
|
}),
|
|
500
689
|
React.createElement("button", {
|
|
501
690
|
style: { ...s.btnGhost, whiteSpace: "nowrap", opacity: newId.trim() && !busy ? 1 : 0.5 },
|
|
@@ -543,19 +732,36 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
543
732
|
style: { ...s.input, width: "100%" },
|
|
544
733
|
placeholder: "\u8BF7\u8F93\u5165 AppID",
|
|
545
734
|
value: cfgDraft?.appId ?? "",
|
|
546
|
-
onChange: (e) => setCfgDraft((d) => ({ ...d, appId: e.target.value }))
|
|
735
|
+
onChange: (e) => setCfgDraft((d) => ({ ...d, appId: e.target.value })),
|
|
736
|
+
onKeyDown: (e) => {
|
|
737
|
+
if (e.key === "Enter" && cfgDraft?.appId?.trim() && cfgDraft?.clientSecret?.trim() && !busy) saveConfig();
|
|
738
|
+
}
|
|
547
739
|
})
|
|
548
740
|
),
|
|
549
741
|
React.createElement(
|
|
550
742
|
"div",
|
|
551
743
|
null,
|
|
552
744
|
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "ClientSecret \u2014 QQ \u5F00\u653E\u5E73\u53F0\u673A\u5668\u4EBA\u5BC6\u94A5"),
|
|
553
|
-
React.createElement(
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
745
|
+
React.createElement(
|
|
746
|
+
"div",
|
|
747
|
+
{ style: { display: "flex", gap: 6, alignItems: "center" } },
|
|
748
|
+
React.createElement("input", {
|
|
749
|
+
style: { ...s.input, flex: 1 },
|
|
750
|
+
type: showSecret ? "text" : "password",
|
|
751
|
+
placeholder: "\u8BF7\u8F93\u5165 ClientSecret",
|
|
752
|
+
value: cfgDraft?.clientSecret ?? "",
|
|
753
|
+
onChange: (e) => setCfgDraft((d) => ({ ...d, clientSecret: e.target.value })),
|
|
754
|
+
onKeyDown: (e) => {
|
|
755
|
+
if (e.key === "Enter" && cfgDraft?.appId?.trim() && cfgDraft?.clientSecret?.trim() && !busy) saveConfig();
|
|
756
|
+
}
|
|
757
|
+
}),
|
|
758
|
+
React.createElement("button", {
|
|
759
|
+
style: { ...s.btnGhost, height: 32, padding: "0 10px", fontSize: 13, flexShrink: 0 },
|
|
760
|
+
onClick: () => setShowSecret((v) => !v),
|
|
761
|
+
type: "button",
|
|
762
|
+
title: showSecret ? "\u9690\u85CF\u5BC6\u94A5" : "\u663E\u793A\u660E\u6587"
|
|
763
|
+
}, showSecret ? "\u{1F648} \u9690\u85CF" : "\u{1F441}\uFE0F \u663E\u793A")
|
|
764
|
+
)
|
|
559
765
|
),
|
|
560
766
|
React.createElement(
|
|
561
767
|
"div",
|
|
@@ -588,7 +794,7 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
588
794
|
login.phase === "error" && React.createElement("div", { style: { ...s.muted, fontSize: 12 } }, login.error ?? "\u767B\u5F55\u5931\u8D25")
|
|
589
795
|
)
|
|
590
796
|
),
|
|
591
|
-
//
|
|
797
|
+
// 高级设置(紧凑 2x2 网格 + 恢复默认值)
|
|
592
798
|
cfgDraft && React.createElement(
|
|
593
799
|
"div",
|
|
594
800
|
{ style: s.block },
|
|
@@ -599,72 +805,83 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
599
805
|
showAdvanced && React.createElement(
|
|
600
806
|
"div",
|
|
601
807
|
{ style: { display: "flex", flexDirection: "column", gap: 10 } },
|
|
602
|
-
//
|
|
603
|
-
React.createElement(
|
|
604
|
-
"div",
|
|
605
|
-
null,
|
|
606
|
-
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "\u5FC3\u8DF3\u95F4\u9694\uFF08\u79D2\uFF09\u2014 \u957F\u4EFB\u52A1\u5904\u7406\u4E2D\u6BCF\u9694\u591A\u4E45\u53D1\u4E00\u6B21\u8FDB\u5EA6\u63D0\u793A"),
|
|
607
|
-
React.createElement("input", {
|
|
608
|
-
style: { ...s.input, width: 120 },
|
|
609
|
-
type: "number",
|
|
610
|
-
min: 30,
|
|
611
|
-
max: 3600,
|
|
612
|
-
value: cfgDraft.digestIntervalSec,
|
|
613
|
-
onChange: (e) => setCfgDraft((d) => ({ ...d, digestIntervalSec: e.target.value }))
|
|
614
|
-
})
|
|
615
|
-
),
|
|
616
|
-
// 审批超时
|
|
617
|
-
React.createElement(
|
|
618
|
-
"div",
|
|
619
|
-
null,
|
|
620
|
-
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "\u5BA1\u6279\u8D85\u65F6\uFF08\u79D2\uFF09\u2014 \u5DE5\u5177\u8C03\u7528\u5BA1\u6279\u65E0\u54CD\u5E94\u540E\u81EA\u52A8\u62D2\u7EDD"),
|
|
621
|
-
React.createElement("input", {
|
|
622
|
-
style: { ...s.input, width: 120 },
|
|
623
|
-
type: "number",
|
|
624
|
-
min: 30,
|
|
625
|
-
max: 86400,
|
|
626
|
-
value: cfgDraft.approvalTimeoutSec,
|
|
627
|
-
onChange: (e) => setCfgDraft((d) => ({ ...d, approvalTimeoutSec: e.target.value }))
|
|
628
|
-
})
|
|
629
|
-
),
|
|
630
|
-
// 每气泡字数
|
|
631
|
-
React.createElement(
|
|
632
|
-
"div",
|
|
633
|
-
null,
|
|
634
|
-
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "\u6BCF\u6761\u6D88\u606F\u6700\u5927\u5B57\u6570 \u2014 \u8D85\u51FA\u65F6\u81EA\u52A8\u5206\u591A\u6761\u53D1\u9001"),
|
|
635
|
-
React.createElement("input", {
|
|
636
|
-
style: { ...s.input, width: 120 },
|
|
637
|
-
type: "number",
|
|
638
|
-
min: 100,
|
|
639
|
-
max: 1e4,
|
|
640
|
-
value: cfgDraft.maxMessageChars,
|
|
641
|
-
onChange: (e) => setCfgDraft((d) => ({ ...d, maxMessageChars: e.target.value }))
|
|
642
|
-
})
|
|
643
|
-
),
|
|
644
|
-
// 分块延迟
|
|
808
|
+
// 2x2 参数网格
|
|
645
809
|
React.createElement(
|
|
646
810
|
"div",
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
811
|
+
{
|
|
812
|
+
style: {
|
|
813
|
+
display: "grid",
|
|
814
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
|
|
815
|
+
gap: 10
|
|
816
|
+
}
|
|
817
|
+
},
|
|
818
|
+
// 心跳间隔
|
|
819
|
+
React.createElement(
|
|
820
|
+
"div",
|
|
821
|
+
null,
|
|
822
|
+
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "\u5FC3\u8DF3\u8FDB\u5EA6\u95F4\u9694 (\u79D2)"),
|
|
823
|
+
React.createElement("input", {
|
|
824
|
+
style: { ...s.input, width: "100%" },
|
|
825
|
+
type: "number",
|
|
826
|
+
min: 30,
|
|
827
|
+
max: 3600,
|
|
828
|
+
value: cfgDraft.digestIntervalSec,
|
|
829
|
+
onChange: (e) => setCfgDraft((d) => ({ ...d, digestIntervalSec: e.target.value }))
|
|
830
|
+
})
|
|
831
|
+
),
|
|
832
|
+
// 审批超时
|
|
833
|
+
React.createElement(
|
|
834
|
+
"div",
|
|
835
|
+
null,
|
|
836
|
+
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "\u5BA1\u6279\u8D85\u65F6\u81EA\u52A8\u62D2\u7EDD (\u79D2)"),
|
|
837
|
+
React.createElement("input", {
|
|
838
|
+
style: { ...s.input, width: "100%" },
|
|
839
|
+
type: "number",
|
|
840
|
+
min: 30,
|
|
841
|
+
max: 86400,
|
|
842
|
+
value: cfgDraft.approvalTimeoutSec,
|
|
843
|
+
onChange: (e) => setCfgDraft((d) => ({ ...d, approvalTimeoutSec: e.target.value }))
|
|
844
|
+
})
|
|
845
|
+
),
|
|
846
|
+
// 每气泡字数
|
|
847
|
+
React.createElement(
|
|
848
|
+
"div",
|
|
849
|
+
null,
|
|
850
|
+
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "\u5355\u6761\u6700\u5927\u5B57\u6570\u9650\u5236 (\u5B57)"),
|
|
851
|
+
React.createElement("input", {
|
|
852
|
+
style: { ...s.input, width: "100%" },
|
|
853
|
+
type: "number",
|
|
854
|
+
min: 100,
|
|
855
|
+
max: 1e4,
|
|
856
|
+
value: cfgDraft.maxMessageChars,
|
|
857
|
+
onChange: (e) => setCfgDraft((d) => ({ ...d, maxMessageChars: e.target.value }))
|
|
858
|
+
})
|
|
859
|
+
),
|
|
860
|
+
// 分块延迟
|
|
861
|
+
React.createElement(
|
|
862
|
+
"div",
|
|
863
|
+
null,
|
|
864
|
+
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "\u5206\u5757\u53D1\u9001\u5EF6\u8FDF (\u6BEB\u79D2)"),
|
|
865
|
+
React.createElement("input", {
|
|
866
|
+
style: { ...s.input, width: "100%" },
|
|
867
|
+
type: "number",
|
|
868
|
+
min: 0,
|
|
869
|
+
max: 1e4,
|
|
870
|
+
value: cfgDraft.sendChunkDelayMs,
|
|
871
|
+
onChange: (e) => setCfgDraft((d) => ({ ...d, sendChunkDelayMs: e.target.value }))
|
|
872
|
+
})
|
|
873
|
+
)
|
|
657
874
|
),
|
|
658
875
|
// QQ 平台凭证
|
|
659
876
|
platformId === "qq" && React.createElement(
|
|
660
877
|
"div",
|
|
661
|
-
{ style: { display: "flex", flexDirection: "column", gap: 10 } },
|
|
878
|
+
{ style: { display: "flex", flexDirection: "column", gap: 10, marginTop: 4 } },
|
|
662
879
|
React.createElement(
|
|
663
880
|
"div",
|
|
664
881
|
null,
|
|
665
882
|
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "AppID \u2014 QQ \u5F00\u653E\u5E73\u53F0\u673A\u5668\u4EBA\u5E94\u7528 ID"),
|
|
666
883
|
React.createElement("input", {
|
|
667
|
-
style: { ...s.input, width:
|
|
884
|
+
style: { ...s.input, width: "100%" },
|
|
668
885
|
placeholder: "\u8BF7\u8F93\u5165 AppID",
|
|
669
886
|
value: cfgDraft.appId,
|
|
670
887
|
onChange: (e) => setCfgDraft((d) => ({ ...d, appId: e.target.value }))
|
|
@@ -673,20 +890,40 @@ function PlatformCard({ platformId, platformName, platformDesc, rpcCall, onStatu
|
|
|
673
890
|
React.createElement(
|
|
674
891
|
"div",
|
|
675
892
|
null,
|
|
676
|
-
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "ClientSecret \u2014 QQ \u5F00\u653E\u5E73\u53F0\u673A\u5668\u4EBA\u5BC6\u94A5"),
|
|
677
|
-
React.createElement(
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
893
|
+
React.createElement("div", { style: { ...s.muted, marginBottom: 4 } }, "ClientSecret \u2014 QQ \u5F00\u653E\u5E73\u53F0\u673A\u5668\u4EBA\u5BC6\u94A5\uFF08\u7559\u7A7A\u5219\u4FDD\u6301\u5DF2\u4FDD\u5B58\u5BC6\u94A5\uFF09"),
|
|
894
|
+
React.createElement(
|
|
895
|
+
"div",
|
|
896
|
+
{ style: { display: "flex", gap: 6, alignItems: "center" } },
|
|
897
|
+
React.createElement("input", {
|
|
898
|
+
style: { ...s.input, flex: 1 },
|
|
899
|
+
type: showSecret ? "text" : "password",
|
|
900
|
+
placeholder: "\u7559\u7A7A\u4FDD\u6301\u5DF2\u4FDD\u5B58\u5BC6\u94A5",
|
|
901
|
+
value: cfgDraft.clientSecret,
|
|
902
|
+
onChange: (e) => setCfgDraft((d) => ({ ...d, clientSecret: e.target.value }))
|
|
903
|
+
}),
|
|
904
|
+
React.createElement("button", {
|
|
905
|
+
style: { ...s.btnGhost, height: 32, padding: "0 10px", fontSize: 13, flexShrink: 0 },
|
|
906
|
+
onClick: () => setShowSecret((v) => !v),
|
|
907
|
+
type: "button",
|
|
908
|
+
title: showSecret ? "\u9690\u85CF\u5BC6\u94A5" : "\u663E\u793A\u660E\u6587"
|
|
909
|
+
}, showSecret ? "\u{1F648} \u9690\u85CF" : "\u{1F441}\uFE0F \u663E\u793A")
|
|
910
|
+
)
|
|
683
911
|
)
|
|
684
912
|
),
|
|
685
|
-
React.createElement(
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
913
|
+
React.createElement(
|
|
914
|
+
"div",
|
|
915
|
+
{ style: { display: "flex", gap: 8, alignItems: "center", marginTop: 4 } },
|
|
916
|
+
React.createElement("button", {
|
|
917
|
+
style: { ...s.btnPri, opacity: cfgDirty && !busy ? 1 : 0.5 },
|
|
918
|
+
disabled: !cfgDirty || busy,
|
|
919
|
+
onClick: saveConfig
|
|
920
|
+
}, busy ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u8BBE\u7F6E"),
|
|
921
|
+
React.createElement("button", {
|
|
922
|
+
style: { ...s.btnGhost, height: 32, fontSize: 12 },
|
|
923
|
+
onClick: resetDefaults,
|
|
924
|
+
title: "\u6062\u590D\u63A8\u8350\u9ED8\u8BA4\u914D\u7F6E"
|
|
925
|
+
}, "\u21BA \u6062\u590D\u63A8\u8350\u9ED8\u8BA4")
|
|
926
|
+
)
|
|
690
927
|
)
|
|
691
928
|
),
|
|
692
929
|
React.createElement(
|
|
@@ -712,7 +949,11 @@ function UpgradeCommandRow({ cmd }) {
|
|
|
712
949
|
color: "var(--dsw-alias-label-secondary,#6b7280)",
|
|
713
950
|
flex: 1,
|
|
714
951
|
minWidth: 0,
|
|
715
|
-
wordBreak: "break-all"
|
|
952
|
+
wordBreak: "break-all",
|
|
953
|
+
background: "var(--dsw-alias-bg-layer-1,#ffffff)",
|
|
954
|
+
padding: "4px 8px",
|
|
955
|
+
borderRadius: 6,
|
|
956
|
+
border: "1px solid var(--dsw-alias-border-l2,#e5e7eb)"
|
|
716
957
|
}
|
|
717
958
|
}, cmd),
|
|
718
959
|
React.createElement("button", {
|
|
@@ -725,6 +966,9 @@ function UpgradeCommandRow({ cmd }) {
|
|
|
725
966
|
function VersionBanner({ rpcCall }) {
|
|
726
967
|
const [info, setInfo] = React.useState(null);
|
|
727
968
|
const [loading, setLoading] = React.useState(false);
|
|
969
|
+
const [upgrading, setUpgrading] = React.useState(false);
|
|
970
|
+
const [upgradeResult, setUpgradeResult] = React.useState(null);
|
|
971
|
+
const [showManual, setShowManual] = React.useState(false);
|
|
728
972
|
const check = React.useCallback(async () => {
|
|
729
973
|
setLoading(true);
|
|
730
974
|
try {
|
|
@@ -738,6 +982,27 @@ function VersionBanner({ rpcCall }) {
|
|
|
738
982
|
check();
|
|
739
983
|
}, [check]);
|
|
740
984
|
const hasUpdate = info?.latest && info?.current && !info.error && semverGt(info.latest, info.current);
|
|
985
|
+
const isLatest = info?.latest && info?.current && !info.error && !semverGt(info.latest, info.current);
|
|
986
|
+
const handleUpgrade = React.useCallback(async () => {
|
|
987
|
+
if (!info?.latest || upgrading) return;
|
|
988
|
+
setUpgrading(true);
|
|
989
|
+
setUpgradeResult(null);
|
|
990
|
+
try {
|
|
991
|
+
const r = await rpcCall(BRIDGE_ENDPOINTS.upgradePlugin, { version: info.latest });
|
|
992
|
+
if (r?.ok && r.value?.ok) {
|
|
993
|
+
setUpgradeResult({ ok: true, message: `\u5DF2\u6210\u529F\u5347\u7EA7\u5230 v${info.latest}\uFF01\u8BF7\u91CD\u542F DSH \u670D\u52A1\u4F7F\u65B0\u7248\u672C\u751F\u6548\u3002` });
|
|
994
|
+
setTimeout(() => check(), 3e3);
|
|
995
|
+
} else {
|
|
996
|
+
setUpgradeResult({ ok: false, message: r?.value?.error || r?.error?.message || "\u5347\u7EA7\u5931\u8D25" });
|
|
997
|
+
setShowManual(true);
|
|
998
|
+
}
|
|
999
|
+
} catch (e) {
|
|
1000
|
+
setUpgradeResult({ ok: false, message: e.message || "\u5347\u7EA7\u8BF7\u6C42\u5931\u8D25" });
|
|
1001
|
+
setShowManual(true);
|
|
1002
|
+
} finally {
|
|
1003
|
+
setUpgrading(false);
|
|
1004
|
+
}
|
|
1005
|
+
}, [info?.latest, upgrading, rpcCall, check]);
|
|
741
1006
|
const links = React.createElement(
|
|
742
1007
|
"div",
|
|
743
1008
|
{ style: { display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" } },
|
|
@@ -746,95 +1011,174 @@ function VersionBanner({ rpcCall }) {
|
|
|
746
1011
|
target: "_blank",
|
|
747
1012
|
rel: "noreferrer",
|
|
748
1013
|
style: s.btnLink
|
|
749
|
-
}, "
|
|
1014
|
+
}, React.createElement(Icons.github), "GitHub"),
|
|
750
1015
|
React.createElement("a", {
|
|
751
1016
|
href: RELEASES_URL,
|
|
752
1017
|
target: "_blank",
|
|
753
1018
|
rel: "noreferrer",
|
|
754
1019
|
style: s.btnLink
|
|
755
|
-
}, "\
|
|
1020
|
+
}, "\u66F4\u65B0\u65E5\u5FD7"),
|
|
756
1021
|
React.createElement("a", {
|
|
757
1022
|
href: ISSUES_URL,
|
|
758
1023
|
target: "_blank",
|
|
759
1024
|
rel: "noreferrer",
|
|
760
1025
|
style: s.btnLink
|
|
761
|
-
}, "\
|
|
1026
|
+
}, "\u53CD\u9988 Issue")
|
|
762
1027
|
);
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
1028
|
+
return React.createElement(
|
|
1029
|
+
"div",
|
|
1030
|
+
{ style: { marginBottom: 16 } },
|
|
1031
|
+
// 顶部状态行:版本徽标 + 刷新按钮 + 链接组
|
|
1032
|
+
React.createElement(
|
|
766
1033
|
"div",
|
|
767
|
-
{
|
|
1034
|
+
{
|
|
1035
|
+
style: {
|
|
1036
|
+
display: "flex",
|
|
1037
|
+
alignItems: "center",
|
|
1038
|
+
justifyContent: "space-between",
|
|
1039
|
+
flexWrap: "wrap",
|
|
1040
|
+
gap: 8
|
|
1041
|
+
}
|
|
1042
|
+
},
|
|
768
1043
|
React.createElement(
|
|
769
1044
|
"div",
|
|
770
|
-
{
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
1045
|
+
{ style: { display: "flex", alignItems: "center", gap: 8 } },
|
|
1046
|
+
// 版本状态徽标
|
|
1047
|
+
React.createElement(
|
|
1048
|
+
"span",
|
|
1049
|
+
{
|
|
1050
|
+
style: {
|
|
1051
|
+
...s.tag,
|
|
1052
|
+
background: hasUpdate ? "var(--dsw-alias-state-info-bg,#eff6ff)" : isLatest ? "var(--dsw-alias-state-success-bg,#ecfdf5)" : "var(--dsw-alias-bg-layer-2,#f3f4f6)",
|
|
1053
|
+
color: hasUpdate ? "var(--dsw-alias-state-info-primary,#2563eb)" : isLatest ? "var(--dsw-alias-state-success-primary,#059669)" : "var(--dsw-alias-label-secondary,#6b7280)",
|
|
1054
|
+
padding: "3px 10px",
|
|
1055
|
+
fontSize: 12,
|
|
1056
|
+
fontWeight: 500,
|
|
1057
|
+
display: "inline-flex",
|
|
1058
|
+
alignItems: "center",
|
|
1059
|
+
gap: 5
|
|
1060
|
+
}
|
|
1061
|
+
},
|
|
1062
|
+
loading ? React.createElement("span", {
|
|
1063
|
+
style: { display: "inline-flex", alignItems: "center" }
|
|
1064
|
+
}, React.createElement(Icons.refresh)) : isLatest ? React.createElement(Icons.check) : null,
|
|
1065
|
+
info ? `v${info.current}` : "\u7248\u672C\u68C0\u67E5\u4E2D\u2026",
|
|
1066
|
+
isLatest && React.createElement("span", { style: { opacity: 0.85, fontSize: 11, fontWeight: 400 } }, "\xB7 \u5DF2\u662F\u6700\u65B0"),
|
|
1067
|
+
hasUpdate && React.createElement("span", { style: { fontWeight: 600, fontSize: 11 } }, `\u2794 v${info.latest}`),
|
|
1068
|
+
info?.error && React.createElement("span", { style: { color: "var(--dsw-alias-state-warn-primary,#d97706)", fontSize: 11 } }, "(\u7F51\u7EDC\u8D85\u65F6)")
|
|
1069
|
+
),
|
|
1070
|
+
// 刷新检查按钮
|
|
1071
|
+
React.createElement(
|
|
1072
|
+
"button",
|
|
1073
|
+
{
|
|
1074
|
+
style: {
|
|
1075
|
+
...s.btnGhost,
|
|
1076
|
+
height: 24,
|
|
1077
|
+
padding: "0 8px",
|
|
1078
|
+
fontSize: 11,
|
|
1079
|
+
opacity: loading ? 0.5 : 1,
|
|
1080
|
+
gap: 4
|
|
1081
|
+
},
|
|
1082
|
+
onClick: check,
|
|
1083
|
+
disabled: loading || upgrading,
|
|
1084
|
+
title: "\u91CD\u65B0\u68C0\u67E5 npm \u7EBF\u4E0A\u7248\u672C"
|
|
1085
|
+
},
|
|
1086
|
+
React.createElement(Icons.refresh),
|
|
1087
|
+
loading ? "\u68C0\u67E5\u4E2D\u2026" : "\u68C0\u67E5\u66F4\u65B0"
|
|
1088
|
+
)
|
|
1089
|
+
),
|
|
1090
|
+
links
|
|
1091
|
+
),
|
|
1092
|
+
// 发现新版本高亮卡片(支持一键直接升级)
|
|
1093
|
+
hasUpdate && React.createElement(
|
|
1094
|
+
"div",
|
|
1095
|
+
{
|
|
1096
|
+
style: {
|
|
1097
|
+
...s.card,
|
|
1098
|
+
background: "var(--dsw-alias-state-info-bg,#eff6ff)",
|
|
1099
|
+
border: "1px solid var(--dsw-alias-state-info-border,#bfdbfe)",
|
|
1100
|
+
padding: "14px 16px",
|
|
1101
|
+
marginTop: 10,
|
|
1102
|
+
marginBottom: 0
|
|
1103
|
+
}
|
|
1104
|
+
},
|
|
1105
|
+
React.createElement(
|
|
1106
|
+
"div",
|
|
1107
|
+
{ style: { display: "flex", alignItems: "flex-start", gap: 12 } },
|
|
1108
|
+
React.createElement("span", { style: { fontSize: 22 } }, "\u{1F680}"),
|
|
779
1109
|
React.createElement(
|
|
780
1110
|
"div",
|
|
781
|
-
{ style: {
|
|
782
|
-
React.createElement("span", { style: { fontSize: 20 } }, "\u{1F389}"),
|
|
1111
|
+
{ style: { flex: 1, minWidth: 0 } },
|
|
783
1112
|
React.createElement(
|
|
784
1113
|
"div",
|
|
785
|
-
{ style: { flex:
|
|
1114
|
+
{ style: { display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 8, marginBottom: 8 } },
|
|
786
1115
|
React.createElement("div", {
|
|
787
1116
|
style: {
|
|
788
1117
|
fontSize: 13,
|
|
789
1118
|
fontWeight: 600,
|
|
790
|
-
color: "var(--dsw-alias-state-info-primary,#1e40af)"
|
|
791
|
-
marginBottom: 8
|
|
1119
|
+
color: "var(--dsw-alias-state-info-primary,#1e40af)"
|
|
792
1120
|
}
|
|
793
1121
|
}, `\u53D1\u73B0\u65B0\u7248\u672C v${info.latest}\uFF08\u5F53\u524D v${info.current}\uFF09`),
|
|
794
|
-
// 升级命令:dsh plugin 与 npx 两种,均带复制按钮
|
|
795
1122
|
React.createElement(
|
|
796
|
-
"
|
|
797
|
-
{
|
|
798
|
-
|
|
1123
|
+
"button",
|
|
1124
|
+
{
|
|
1125
|
+
style: {
|
|
1126
|
+
...s.btnPri,
|
|
1127
|
+
height: 28,
|
|
1128
|
+
fontSize: 12,
|
|
1129
|
+
padding: "0 14px",
|
|
1130
|
+
background: upgradeResult?.ok ? "var(--dsw-alias-state-success-primary,#059669)" : "var(--dsw-alias-brand-primary,#4f6ef7)",
|
|
1131
|
+
opacity: upgrading ? 0.6 : 1
|
|
1132
|
+
},
|
|
1133
|
+
onClick: handleUpgrade,
|
|
1134
|
+
disabled: upgrading || upgradeResult?.ok
|
|
1135
|
+
},
|
|
1136
|
+
upgrading ? React.createElement(
|
|
1137
|
+
"span",
|
|
1138
|
+
{ style: { display: "inline-flex", alignItems: "center", gap: 6 } },
|
|
1139
|
+
React.createElement("span", { style: { animation: "spin 1s linear infinite", display: "inline-flex" } }, React.createElement(Icons.refresh)),
|
|
1140
|
+
"\u6B63\u5728\u81EA\u52A8\u5347\u7EA7\u2026"
|
|
1141
|
+
) : upgradeResult?.ok ? "\u2713 \u5DF2\u5B8C\u6210\u5347\u7EA7" : `\u4E00\u952E\u5347\u7EA7\u5230 v${info.latest}`
|
|
799
1142
|
)
|
|
800
1143
|
),
|
|
801
|
-
React.createElement("
|
|
1144
|
+
upgradeResult && React.createElement("div", {
|
|
802
1145
|
style: {
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
1146
|
+
background: upgradeResult.ok ? "var(--dsw-alias-state-success-bg,#ecfdf5)" : "var(--dsw-alias-state-error-bg,#fef2f2)",
|
|
1147
|
+
border: `1px solid ${upgradeResult.ok ? "var(--dsw-alias-state-success-border,#a7f3d0)" : "var(--dsw-alias-state-error-border,#fecaca)"}`,
|
|
1148
|
+
color: upgradeResult.ok ? "var(--dsw-alias-state-success-primary,#065f46)" : "var(--dsw-alias-state-error-primary,#991b1b)",
|
|
1149
|
+
padding: "8px 12px",
|
|
1150
|
+
borderRadius: 6,
|
|
806
1151
|
fontSize: 12,
|
|
807
|
-
|
|
808
|
-
|
|
1152
|
+
marginBottom: 8,
|
|
1153
|
+
lineHeight: 1.5
|
|
1154
|
+
}
|
|
1155
|
+
}, upgradeResult.message),
|
|
1156
|
+
React.createElement(
|
|
1157
|
+
"div",
|
|
1158
|
+
{ style: { marginTop: 4 } },
|
|
1159
|
+
React.createElement("button", {
|
|
1160
|
+
style: { ...s.btnLink, fontSize: 11, color: "var(--dsw-alias-label-secondary,#6b7280)" },
|
|
1161
|
+
onClick: () => setShowManual((v) => !v)
|
|
1162
|
+
}, showManual ? "\u25B4 \u6298\u53E0\u624B\u52A8\u547D\u4EE4\u884C" : "\u25BE \u67E5\u770B\u624B\u52A8\u5347\u7EA7\u547D\u4EE4 (\u5982\u9700)")
|
|
1163
|
+
),
|
|
1164
|
+
showManual && React.createElement(
|
|
1165
|
+
"div",
|
|
1166
|
+
{
|
|
1167
|
+
style: { display: "flex", flexDirection: "column", gap: 6, marginTop: 8 }
|
|
809
1168
|
},
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
1169
|
+
upgradeCommands(info.latest).map(
|
|
1170
|
+
({ id, cmd }) => React.createElement(UpgradeCommandRow, { key: id, cmd })
|
|
1171
|
+
)
|
|
1172
|
+
)
|
|
813
1173
|
)
|
|
814
|
-
)
|
|
815
|
-
|
|
816
|
-
);
|
|
817
|
-
}
|
|
818
|
-
return React.createElement(
|
|
819
|
-
"div",
|
|
820
|
-
{ style: { marginBottom: 14, display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 8 } },
|
|
821
|
-
React.createElement(
|
|
822
|
-
"div",
|
|
823
|
-
{ style: { ...s.muted, display: "flex", alignItems: "center", gap: 8 } },
|
|
824
|
-
loading && !info ? React.createElement("span", null, "\u68C0\u67E5\u66F4\u65B0\u4E2D\u2026") : info ? React.createElement("span", null, `v${info.current}${info.latest && !info.error ? " \xB7 \u5DF2\u662F\u6700\u65B0" : info.error ? " \xB7 \u68C0\u67E5\u5931\u8D25" : ""}`) : null,
|
|
825
|
-
info && React.createElement("button", {
|
|
826
|
-
style: { ...s.btnGhost, height: 22, padding: "0 8px", fontSize: 11, opacity: loading ? 0.5 : 1 },
|
|
827
|
-
onClick: check,
|
|
828
|
-
disabled: loading
|
|
829
|
-
}, loading ? "\u2026" : "\u91CD\u65B0\u68C0\u67E5")
|
|
830
|
-
),
|
|
831
|
-
links
|
|
1174
|
+
)
|
|
1175
|
+
)
|
|
832
1176
|
);
|
|
833
1177
|
}
|
|
834
1178
|
var TABS = [
|
|
835
|
-
{ id: "lan", label: "\u5C40\u57DF\u7F51" },
|
|
836
|
-
{ id: "tunnel", label: "\u516C\u7F51\u96A7\u9053" },
|
|
837
|
-
{ id: "im", label: "IM \u673A\u5668\u4EBA" }
|
|
1179
|
+
{ id: "lan", label: "\u5C40\u57DF\u7F51", icon: Icons.lan },
|
|
1180
|
+
{ id: "tunnel", label: "\u516C\u7F51\u96A7\u9053", icon: Icons.tunnel },
|
|
1181
|
+
{ id: "im", label: "IM \u673A\u5668\u4EBA", icon: Icons.bot }
|
|
838
1182
|
];
|
|
839
1183
|
function TabBar({ active, onChange, dots }) {
|
|
840
1184
|
return React.createElement(
|
|
@@ -842,12 +1186,12 @@ function TabBar({ active, onChange, dots }) {
|
|
|
842
1186
|
{
|
|
843
1187
|
style: {
|
|
844
1188
|
display: "flex",
|
|
845
|
-
gap:
|
|
1189
|
+
gap: 4,
|
|
846
1190
|
marginBottom: 20,
|
|
847
1191
|
borderBottom: "1px solid var(--dsw-alias-border-l2,#e5e7eb)"
|
|
848
1192
|
}
|
|
849
1193
|
},
|
|
850
|
-
TABS.map(({ id, label }) => {
|
|
1194
|
+
TABS.map(({ id, label, icon: TabIcon }) => {
|
|
851
1195
|
const isActive = active === id;
|
|
852
1196
|
const hasDot = dots?.[id];
|
|
853
1197
|
return React.createElement(
|
|
@@ -868,11 +1212,19 @@ function TabBar({ active, onChange, dots }) {
|
|
|
868
1212
|
marginBottom: -1,
|
|
869
1213
|
display: "inline-flex",
|
|
870
1214
|
alignItems: "center",
|
|
871
|
-
gap:
|
|
1215
|
+
gap: 7,
|
|
872
1216
|
transition: "color .15s, border-color .15s",
|
|
873
1217
|
whiteSpace: "nowrap"
|
|
874
1218
|
}
|
|
875
1219
|
},
|
|
1220
|
+
TabIcon && React.createElement(TabIcon, {
|
|
1221
|
+
style: {
|
|
1222
|
+
color: isActive ? "var(--dsw-alias-brand-primary,#4f6ef7)" : "var(--dsw-alias-label-tertiary,#9ca3af)",
|
|
1223
|
+
width: 16,
|
|
1224
|
+
height: 16,
|
|
1225
|
+
flexShrink: 0
|
|
1226
|
+
}
|
|
1227
|
+
}),
|
|
876
1228
|
label,
|
|
877
1229
|
hasDot && React.createElement("span", {
|
|
878
1230
|
style: {
|
|
@@ -1011,9 +1363,10 @@ function BridgePanel({ rpcCall }) {
|
|
|
1011
1363
|
);
|
|
1012
1364
|
} else if (activeTab === "im") {
|
|
1013
1365
|
const IM_PLATFORMS = [
|
|
1014
|
-
{ id: "wechat", label: "\u5FAE\u4FE1", desc: "
|
|
1015
|
-
{ id: "qq", label: "QQ",
|
|
1016
|
-
{ id: "feishu", label: "\u98DE\u4E66", desc: "\u5B98\u65B9\u4E8B\u4EF6\u56DE\u8C03 API" }
|
|
1366
|
+
{ id: "wechat", label: "\u5FAE\u4FE1", icon: Icons.wechat, brandColor: "#07C160", desc: "ClawBot \u626B\u7801\u76F4\u8FDE \xB7 \u65E0\u9700\u516C\u7F51" },
|
|
1367
|
+
{ id: "qq", label: "QQ", icon: Icons.qq, brandColor: "#12B7F5", desc: "\u5B98\u65B9\u673A\u5668\u4EBA \xB7 \u79C1\u804A/\u7FA4\u804A/\u6309\u94AE" },
|
|
1368
|
+
{ id: "feishu", label: "\u98DE\u4E66", icon: Icons.feishu, brandColor: "#00D6B9", desc: "\u5B98\u65B9\u4E8B\u4EF6\u56DE\u8C03 API" },
|
|
1369
|
+
{ id: "telegram", label: "Telegram", icon: Icons.telegram, brandColor: "#24A1DE", desc: "\u5B98\u65B9 Bot API" }
|
|
1017
1370
|
];
|
|
1018
1371
|
tabContent = React.createElement(
|
|
1019
1372
|
"div",
|
|
@@ -1024,7 +1377,7 @@ function BridgePanel({ rpcCall }) {
|
|
|
1024
1377
|
{
|
|
1025
1378
|
style: { display: "flex", gap: 10, marginBottom: 16, flexWrap: "wrap" }
|
|
1026
1379
|
},
|
|
1027
|
-
IM_PLATFORMS.map(({ id, label, desc }) => {
|
|
1380
|
+
IM_PLATFORMS.map(({ id, label, icon: IconComponent, brandColor, desc }) => {
|
|
1028
1381
|
const platformData = platforms?.[id];
|
|
1029
1382
|
const available = !!platformData;
|
|
1030
1383
|
const active = platformData?.status === "connected" || platformData?.status === "starting" || platformData?.status === "reconnecting";
|
|
@@ -1033,21 +1386,27 @@ function BridgePanel({ rpcCall }) {
|
|
|
1033
1386
|
{
|
|
1034
1387
|
key: id,
|
|
1035
1388
|
style: {
|
|
1036
|
-
flex: "1 1
|
|
1037
|
-
border: `1px solid ${selectedPlatform === id ? "var(--dsw-alias-
|
|
1389
|
+
flex: "1 1 135px",
|
|
1390
|
+
border: `1px solid ${selectedPlatform === id ? "var(--dsw-alias-brand-primary,#4f6ef7)" : active ? "var(--dsw-alias-state-success-primary,#10b981)" : "var(--dsw-alias-border-l2,#e5e7eb)"}`,
|
|
1038
1391
|
borderRadius: 10,
|
|
1039
1392
|
padding: "12px 14px",
|
|
1040
|
-
opacity: available ? 1 : 0.
|
|
1393
|
+
opacity: available ? 1 : 0.5,
|
|
1041
1394
|
cursor: available ? "pointer" : "not-allowed",
|
|
1042
|
-
background: selectedPlatform === id ? "var(--dsw-alias-state-info-bg,#eff6ff)" : active ? "var(--dsw-alias-state-success-bg,#ecfdf5)" :
|
|
1395
|
+
background: selectedPlatform === id ? "var(--dsw-alias-state-info-bg,#eff6ff)" : active ? "var(--dsw-alias-state-success-bg,#ecfdf5)" : "var(--dsw-alias-bg-layer-2,#f9fafb)",
|
|
1396
|
+
boxShadow: selectedPlatform === id ? "0 0 0 1px var(--dsw-alias-brand-primary,#4f6ef7)" : "none",
|
|
1043
1397
|
transition: "all 0.15s ease"
|
|
1044
1398
|
},
|
|
1045
1399
|
onClick: available ? () => setSelectedPlatform(id) : void 0
|
|
1046
1400
|
},
|
|
1047
1401
|
React.createElement(
|
|
1048
1402
|
"div",
|
|
1049
|
-
{ style: { ...s.label, fontSize: 13, display: "flex", alignItems: "center",
|
|
1050
|
-
|
|
1403
|
+
{ style: { ...s.label, fontSize: 13, display: "flex", alignItems: "center", justifyContent: "space-between" } },
|
|
1404
|
+
React.createElement(
|
|
1405
|
+
"span",
|
|
1406
|
+
{ style: { display: "flex", alignItems: "center", gap: 7 } },
|
|
1407
|
+
IconComponent && React.createElement(IconComponent, { style: { color: brandColor, width: 18, height: 18, flexShrink: 0 } }),
|
|
1408
|
+
label
|
|
1409
|
+
),
|
|
1051
1410
|
active && React.createElement("span", {
|
|
1052
1411
|
style: { width: 6, height: 6, borderRadius: "50%", background: "var(--dsw-alias-state-success-primary,#10b981)", flexShrink: 0 }
|
|
1053
1412
|
}),
|
|
@@ -1058,7 +1417,7 @@ function BridgePanel({ rpcCall }) {
|
|
|
1058
1417
|
style: { fontSize: 11, color: "var(--dsw-alias-label-tertiary,#9ca3af)", fontWeight: 400 }
|
|
1059
1418
|
}, "\u5373\u5C06\u652F\u6301")
|
|
1060
1419
|
),
|
|
1061
|
-
React.createElement("div", { style: { ...s.muted, marginTop:
|
|
1420
|
+
React.createElement("div", { style: { ...s.muted, marginTop: 4, fontSize: 11 } }, desc)
|
|
1062
1421
|
);
|
|
1063
1422
|
})
|
|
1064
1423
|
),
|
|
@@ -1076,7 +1435,7 @@ function BridgePanel({ rpcCall }) {
|
|
|
1076
1435
|
}
|
|
1077
1436
|
return React.createElement(
|
|
1078
1437
|
"div",
|
|
1079
|
-
{ style: { maxWidth:
|
|
1438
|
+
{ style: { maxWidth: 620 } },
|
|
1080
1439
|
err && React.createElement("div", {
|
|
1081
1440
|
style: { ...s.card, background: "var(--dsw-alias-state-error-bg,#fef2f2)", color: "var(--dsw-alias-state-error-primary,#dc2626)", fontSize: 13, marginBottom: 16 }
|
|
1082
1441
|
}, err),
|