@xmanrui/dsh-im 4.28.0 → 4.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +9 -7
- package/README.md +9 -7
- package/lib/client.js +370 -115
- package/lib/index.js +298 -298
- package/package.json +5 -1
- package/plugin-src/client/channels/feishu/api.js +3 -0
- package/plugin-src/client/channels/feishu/voice-editor.js +115 -0
- package/plugin-src/client/channels/feishu/voice-settings.js +71 -0
- package/plugin-src/client/delivery-settings.js +8 -0
- package/plugin-src/client/i18n.js +16 -0
- package/plugin-src/client/styles.js +11 -0
- package/plugin-src/host/channels/dingtalk/production.mjs +1 -1
- package/plugin-src/host/channels/feishu/production.mjs +12 -1
- package/plugin-src/host/channels/feishu/rpc.mjs +21 -0
- package/plugin-src/host/channels/qq/production.mjs +1 -1
- package/plugin-src/host/channels/shared/production.mjs +1 -1
- package/plugin-src/host/channels/slack/production.mjs +1 -1
- package/plugin-src/host/channels/wecom/production.mjs +1 -1
- package/plugin-src/host/channels/wecom-app/production.mjs +1 -1
- package/plugin-src/host/channels/weixin/production.mjs +22 -5
- package/plugin-src/host/channels/whatsapp/production.mjs +1 -1
- package/src/channels/feishu/bridge.mjs +165 -12
- package/src/channels/feishu/feishu-cards.mjs +4 -2
- package/src/channels/feishu/feishu-runtime.mjs +16 -0
- package/src/channels/feishu/multi-bot-controller.mjs +22 -0
- package/src/channels/feishu/plugin-config-store.mjs +2 -0
- package/src/channels/feishu/voice-config.mjs +34 -0
- package/src/channels/feishu/voice.mjs +134 -0
- package/src/channels/shared/bot-workspace-store.mjs +30 -10
- package/src/channels/shared/default-workspace.mjs +6 -3
- package/src/channels/shared/harness-approval.mjs +24 -17
- package/src/channels/shared/harness-session-binding.mjs +4 -0
- package/src/channels/weixin/weixin-api.mjs +3 -2
package/lib/client.js
CHANGED
|
@@ -590,12 +590,12 @@ async function callManagementRpc(connection, channel7, method, payload, signal)
|
|
|
590
590
|
}
|
|
591
591
|
|
|
592
592
|
// plugin-src/client/index.js
|
|
593
|
-
var
|
|
593
|
+
var React36 = __toESM(require("react"), 1);
|
|
594
594
|
|
|
595
595
|
// package.json
|
|
596
596
|
var package_default = {
|
|
597
597
|
name: "@xmanrui/dsh-im",
|
|
598
|
-
version: "4.
|
|
598
|
+
version: "4.29.0",
|
|
599
599
|
description: "\u628A\u5341\u4E8C\u79CD IM \u6E20\u9053\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect twelve IM channels and a public AI Office to a local DeepSeek Harness.",
|
|
600
600
|
keywords: [
|
|
601
601
|
"deepseek-harness",
|
|
@@ -680,6 +680,10 @@ var package_default = {
|
|
|
680
680
|
{
|
|
681
681
|
name: "Zhe (Phil) Yang",
|
|
682
682
|
url: "https://github.com/yangzhe1991"
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
name: "Biertolovisk",
|
|
686
|
+
url: "https://github.com/rosalynthompson32-a11y"
|
|
683
687
|
}
|
|
684
688
|
],
|
|
685
689
|
license: "MIT",
|
|
@@ -1486,6 +1490,22 @@ var EN = Object.freeze({
|
|
|
1486
1490
|
"\u63A8\u8350\u957F\u4EFB\u52A1\u4F7F\u7528\uFF1A\u8FC7\u7A0B\u4E0E\u6700\u7EC8\u7B54\u6848\u90FD\u5728\u540C\u4E00\u5F20\u5361\u7247\u91CC\u5B9E\u65F6\u66F4\u65B0\uFF0C\u4E0D\u5237\u5C4F": "Recommended for long tasks: the process and the final answer update live in one card without flooding the chat",
|
|
1487
1491
|
"\u6BCF\u4E00\u6B65\u90FD\u5355\u72EC\u53D1\u4E00\u6761\u6D88\u606F\uFF08\u542B\u5DE5\u5177\u8C03\u7528\u548C\u8FC7\u7A0B\u8BF4\u660E\uFF09\uFF1B\u6CE8\u610F\u957F\u4EFB\u52A1\u4F1A\u8FDE\u7EED\u53D1\u9001\u8F83\u591A\u6D88\u606F": "Every step is sent as its own message (including tool calls and notes); long tasks may send many messages in a row",
|
|
1488
1492
|
"\u5206\u6B65\u76F4\u63A8\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not save the step push setting. Try again.",
|
|
1493
|
+
"\u8BED\u97F3\u4EA4\u4E92": "Voice",
|
|
1494
|
+
"\u6B63\u5728\u8BFB\u53D6\u8BED\u97F3\u8BBE\u7F6E\u2026": "Loading voice settings\u2026",
|
|
1495
|
+
"\u98DE\u4E66\u8BED\u97F3\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002": "Feishu voice settings are unavailable.",
|
|
1496
|
+
"\u672A\u627E\u5230\u5F53\u524D\u98DE\u4E66\u673A\u5668\u4EBA\uFF0C\u8BF7\u8FD4\u56DE\u5217\u8868\u540E\u91CD\u8BD5\u3002": "This Feishu bot was not found. Return to the bot list and try again.",
|
|
1497
|
+
"\u67E5\u770B\u8BED\u97F3\u4EA4\u4E92\u8BF4\u660E": "View voice help",
|
|
1498
|
+
"\u8BED\u97F3\u4EA4\u4E92\u5F00\u5173": "Voice on/off",
|
|
1499
|
+
"\u5F00\u542F(\u8BED\u97F3\u63D0\u95EE\u4E0E\u8BED\u97F3\u56DE\u590D)": "On (voice questions and voice replies)",
|
|
1500
|
+
"\u6536\u5230\u8BED\u97F3\u6D88\u606F\u65F6\u8F6C\u5199\u4E3A\u6587\u5B57\u5E76\u6309\u6587\u5B57\u6D41\u6C34\u7EBF\u5904\u7406,\u7B54\u6848\u540C\u65F6\u4EE5\u8BED\u97F3\u56DE\u590D;\u8F6C\u5199\u5931\u8D25\u65F6\u964D\u7EA7\u4E3A\u4EC5\u652F\u6301\u6587\u5B57/\u56FE\u7247/\u6587\u4EF6\u7684\u63D0\u793A\u3002\u51ED\u636E\u503C\u5728\u63D2\u4EF6\u51ED\u636E\u5E93\u91CC\u7BA1\u7406,\u8FD9\u91CC\u53EA\u5F15\u7528\u73AF\u5883\u53D8\u91CF\u540D\u3002": "Voice messages are transcribed to text and processed by the normal text pipeline; the answer is also sent as a voice reply. If transcription fails, the bot falls back to the text/image/file-only notice. The credential value lives in the plugin credential store; only the environment variable name is referenced here.",
|
|
1501
|
+
"\u51ED\u636E\u5F15\u7528(\u73AF\u5883\u53D8\u91CF\u540D)": "Credential reference (environment variable name)",
|
|
1502
|
+
"\u8F6C\u5199\u6A21\u578B(ASR)": "Transcription model (ASR)",
|
|
1503
|
+
"\u5408\u6210\u6A21\u578B(TTS)": "Synthesis model (TTS)",
|
|
1504
|
+
"\u56DE\u590D\u97F3\u8272": "Reply voice",
|
|
1505
|
+
'\u9700\u8981 DashScope \u5BC6\u94A5(\u51ED\u636E\u5E93\u4E2D\u4EE5"\u51ED\u636E\u5F15\u7528"\u4E3A\u540D\u7684\u73AF\u5883\u53D8\u91CF)\u4E0E\u53EF\u7528 ffmpeg;\u97F3\u8272\u652F\u6301 Cherry/Serena/Bella/Chelsie/Momo/Katerina \u7B49 qwen3-tts-flash \u5B98\u65B9\u97F3\u8272\u3002': "Requires a DashScope API key (the credential-store environment variable named by the credential reference above) and a working ffmpeg. Supported voices include the official qwen3-tts-flash voices Cherry/Serena/Bella/Chelsie/Momo/Katerina.",
|
|
1506
|
+
"\u4FDD\u5B58\u8BED\u97F3\u8BBE\u7F6E": "Save voice settings",
|
|
1507
|
+
"\u9ED8\u8BA4\u5173\u95ED;\u5F00\u542F\u540E\u673A\u5668\u4EBA\u53EF\u542C\u61C2\u8BED\u97F3\u6D88\u606F\u5E76\u4EE5\u8BED\u97F3\u56DE\u590D\u3002": "Off by default. When enabled, the bot understands voice messages and replies by voice.",
|
|
1508
|
+
"\u8BED\u97F3\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not save the voice settings. Try again.",
|
|
1489
1509
|
"zcode\u8FC7\u7A0B\u5361\u6A21\u5F0F": "ZCode process-card mode",
|
|
1490
1510
|
"\u8FC7\u7A0B\u8BF4\u660E\u3001\u5DE5\u5177\u6458\u8981\u4E0E\u6700\u7EC8\u7B54\u6848\u90FD\u5728\u540C\u4E00\u5F20\u5361\u7247\u4E2D\u539F\u5730\u5237\u65B0": "Process notes, the tool summary, and the final answer refresh in place inside one card",
|
|
1491
1511
|
"\u601D\u8003\u4E0E\u5DE5\u5177\u6458\u8981\u6298\u53E0\u5C55\u793A\uFF0C\u6700\u7EC8\u7B54\u6848\u5728\u540C\u4E00\u5F20\u5361\u7247\u4E2D\u539F\u5730\u5237\u65B0": "Thinking and the tool summary stay folded; the final answer refreshes in place inside one card",
|
|
@@ -7198,6 +7218,29 @@ function normalizeFeishuStepPushMode(value) {
|
|
|
7198
7218
|
return FEISHU_STEP_PUSH_MODES.POST;
|
|
7199
7219
|
}
|
|
7200
7220
|
|
|
7221
|
+
// src/channels/feishu/voice-config.mjs
|
|
7222
|
+
var DEFAULT_ASR_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
|
|
7223
|
+
var DEFAULT_ASR_MODEL = "qwen3-asr-flash";
|
|
7224
|
+
var DEFAULT_TTS_MODEL = "qwen3-tts-flash";
|
|
7225
|
+
var DEFAULT_TTS_VOICE = "Momo";
|
|
7226
|
+
function cleanString(value) {
|
|
7227
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
7228
|
+
}
|
|
7229
|
+
function normalizeFeishuVoiceConfig(value) {
|
|
7230
|
+
if (value == null || typeof value !== "object" || value.enabled !== true) return null;
|
|
7231
|
+
const secretRef = cleanString(value.secretRef);
|
|
7232
|
+
if (!secretRef || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(secretRef)) return null;
|
|
7233
|
+
return Object.freeze({
|
|
7234
|
+
enabled: true,
|
|
7235
|
+
secretRef,
|
|
7236
|
+
asrModel: cleanString(value.asrModel) ?? DEFAULT_ASR_MODEL,
|
|
7237
|
+
ttsModel: cleanString(value.ttsModel) ?? DEFAULT_TTS_MODEL,
|
|
7238
|
+
ttsVoice: cleanString(value.ttsVoice) ?? DEFAULT_TTS_VOICE,
|
|
7239
|
+
asrBaseUrl: cleanString(value.asrBaseUrl) ?? DEFAULT_ASR_BASE_URL,
|
|
7240
|
+
ffmpeg: cleanString(value.ffmpeg)
|
|
7241
|
+
});
|
|
7242
|
+
}
|
|
7243
|
+
|
|
7201
7244
|
// plugin-src/client/channels/feishu/api.js
|
|
7202
7245
|
var FEISHU_RPC_CHANNEL = "/feishu";
|
|
7203
7246
|
var FEISHU_ENDPOINTS = Object.freeze({
|
|
@@ -7221,6 +7264,7 @@ var FEISHU_ENDPOINTS = Object.freeze({
|
|
|
7221
7264
|
setGroupTopicReply: "bot.group-topic-reply.set",
|
|
7222
7265
|
setStepPush: "bot.step-push.set",
|
|
7223
7266
|
setStepPushMode: "bot.step-push-mode.set",
|
|
7267
|
+
setVoice: "bot.voice.set",
|
|
7224
7268
|
// Kept for rolling upgrades. The multi-bot UI never calls these endpoints.
|
|
7225
7269
|
testConnection: "connection.test",
|
|
7226
7270
|
disconnect: "connection.disconnect"
|
|
@@ -7377,6 +7421,7 @@ function normalizeBotConnection(value, fallbackBotId) {
|
|
|
7377
7421
|
groupTopicReply: value.groupTopicReply === true,
|
|
7378
7422
|
stepPush: value.stepPush === true,
|
|
7379
7423
|
stepPushMode: normalizeFeishuStepPushMode(value.stepPushMode),
|
|
7424
|
+
voice: normalizeFeishuVoiceConfig(value.voice),
|
|
7380
7425
|
groupMessagePermissionGranted: value.groupMessagePermissionGranted === true,
|
|
7381
7426
|
bot: normalizeBot2(value.bot),
|
|
7382
7427
|
health: normalizeHealth(value.health, connected),
|
|
@@ -16075,7 +16120,7 @@ function installInterfaceLanguageMirror(ctx, {
|
|
|
16075
16120
|
}
|
|
16076
16121
|
|
|
16077
16122
|
// plugin-src/client/delivery-settings.js
|
|
16078
|
-
var
|
|
16123
|
+
var React32 = __toESM(require("react"), 1);
|
|
16079
16124
|
|
|
16080
16125
|
// plugin-src/client/access-policy-settings.js
|
|
16081
16126
|
var React28 = __toESM(require("react"), 1);
|
|
@@ -17078,6 +17123,200 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
|
|
|
17078
17123
|
);
|
|
17079
17124
|
}
|
|
17080
17125
|
|
|
17126
|
+
// plugin-src/client/channels/feishu/voice-settings.js
|
|
17127
|
+
var React31 = __toESM(require("react"), 1);
|
|
17128
|
+
|
|
17129
|
+
// plugin-src/client/channels/feishu/voice-editor.js
|
|
17130
|
+
var React30 = __toESM(require("react"), 1);
|
|
17131
|
+
function VoiceEditor({ value = null, disabled = false, onSave }) {
|
|
17132
|
+
const [enabled, setEnabled] = React30.useState(value != null);
|
|
17133
|
+
const [secretRef, setSecretRef] = React30.useState(value?.secretRef ?? "DASHSCOPE_API_KEY");
|
|
17134
|
+
const [asrModel, setAsrModel] = React30.useState(value?.asrModel ?? "qwen3-asr-flash");
|
|
17135
|
+
const [ttsModel, setTtsModel] = React30.useState(value?.ttsModel ?? "qwen3-tts-flash");
|
|
17136
|
+
const [ttsVoice, setTtsVoice] = React30.useState(value?.ttsVoice ?? "Momo");
|
|
17137
|
+
const [saving, setSaving] = React30.useState(false);
|
|
17138
|
+
const [error, setError] = React30.useState(null);
|
|
17139
|
+
const titleId = React30.useId();
|
|
17140
|
+
const helpId = `${titleId}-help`;
|
|
17141
|
+
React30.useEffect(() => {
|
|
17142
|
+
setEnabled(value != null);
|
|
17143
|
+
if (value) {
|
|
17144
|
+
setSecretRef(value.secretRef ?? "DASHSCOPE_API_KEY");
|
|
17145
|
+
setAsrModel(value.asrModel ?? "qwen3-asr-flash");
|
|
17146
|
+
setTtsModel(value.ttsModel ?? "qwen3-tts-flash");
|
|
17147
|
+
setTtsVoice(value.ttsVoice ?? "Momo");
|
|
17148
|
+
}
|
|
17149
|
+
}, [value]);
|
|
17150
|
+
const persist = async (payload) => {
|
|
17151
|
+
if (saving || disabled) return;
|
|
17152
|
+
setSaving(true);
|
|
17153
|
+
setError(null);
|
|
17154
|
+
try {
|
|
17155
|
+
await onSave?.(payload);
|
|
17156
|
+
} catch (cause) {
|
|
17157
|
+
setError(cause?.message ?? "\u8BED\u97F3\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
17158
|
+
} finally {
|
|
17159
|
+
setSaving(false);
|
|
17160
|
+
}
|
|
17161
|
+
};
|
|
17162
|
+
const save = () => persist(enabled ? { enabled: true, secretRef, asrModel, ttsModel, ttsVoice } : null);
|
|
17163
|
+
const toggle = (next) => {
|
|
17164
|
+
setEnabled(next);
|
|
17165
|
+
if (!next) void persist(null);
|
|
17166
|
+
};
|
|
17167
|
+
const input = (label, state, setState, placeholder) => h2(
|
|
17168
|
+
"label",
|
|
17169
|
+
{ className: "dim-feishuVoiceField" },
|
|
17170
|
+
h2("span", { className: "dim-feishuVoiceLabel" }, label),
|
|
17171
|
+
h2("input", {
|
|
17172
|
+
type: "text",
|
|
17173
|
+
className: "dim-feishuVoiceInput",
|
|
17174
|
+
value: state,
|
|
17175
|
+
placeholder,
|
|
17176
|
+
disabled: disabled || saving,
|
|
17177
|
+
onChange: (event) => setState(event.target.value)
|
|
17178
|
+
})
|
|
17179
|
+
);
|
|
17180
|
+
return h2(
|
|
17181
|
+
"section",
|
|
17182
|
+
{
|
|
17183
|
+
className: "dim-feishuGroupControl",
|
|
17184
|
+
"aria-labelledby": titleId
|
|
17185
|
+
},
|
|
17186
|
+
h2(
|
|
17187
|
+
"div",
|
|
17188
|
+
{ className: "dim-feishuGroupControlHeader" },
|
|
17189
|
+
h2(
|
|
17190
|
+
"div",
|
|
17191
|
+
{ className: "dim-presetTitle" },
|
|
17192
|
+
h2("h3", { id: titleId }, "\u8BED\u97F3\u4EA4\u4E92"),
|
|
17193
|
+
h2(
|
|
17194
|
+
"span",
|
|
17195
|
+
{ className: "dim-presetHelp" },
|
|
17196
|
+
h2("button", {
|
|
17197
|
+
type: "button",
|
|
17198
|
+
className: "dim-presetHelpButton",
|
|
17199
|
+
"aria-label": "\u67E5\u770B\u8BED\u97F3\u4EA4\u4E92\u8BF4\u660E",
|
|
17200
|
+
"aria-describedby": helpId
|
|
17201
|
+
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
17202
|
+
h2("span", {
|
|
17203
|
+
id: helpId,
|
|
17204
|
+
className: "dim-presetTooltip",
|
|
17205
|
+
role: "tooltip"
|
|
17206
|
+
}, "\u6536\u5230\u8BED\u97F3\u6D88\u606F\u65F6\u8F6C\u5199\u4E3A\u6587\u5B57\u5E76\u6309\u6587\u5B57\u6D41\u6C34\u7EBF\u5904\u7406,\u7B54\u6848\u540C\u65F6\u4EE5\u8BED\u97F3\u56DE\u590D;\u8F6C\u5199\u5931\u8D25\u65F6\u964D\u7EA7\u4E3A\u4EC5\u652F\u6301\u6587\u5B57/\u56FE\u7247/\u6587\u4EF6\u7684\u63D0\u793A\u3002\u51ED\u636E\u503C\u5728\u63D2\u4EF6\u51ED\u636E\u5E93\u91CC\u7BA1\u7406,\u8FD9\u91CC\u53EA\u5F15\u7528\u73AF\u5883\u53D8\u91CF\u540D\u3002")
|
|
17207
|
+
)
|
|
17208
|
+
),
|
|
17209
|
+
saving ? h2("span", { className: "dim-feishuGroupControlStatus", role: "status" }, "\u4FDD\u5B58\u4E2D\u2026") : null
|
|
17210
|
+
),
|
|
17211
|
+
h2(
|
|
17212
|
+
"select",
|
|
17213
|
+
{
|
|
17214
|
+
className: "dim-feishuGroupSelect",
|
|
17215
|
+
value: enabled ? "on" : "off",
|
|
17216
|
+
disabled: disabled || saving,
|
|
17217
|
+
"aria-label": "\u8BED\u97F3\u4EA4\u4E92\u5F00\u5173",
|
|
17218
|
+
onChange: (event) => toggle(event.target.value === "on")
|
|
17219
|
+
},
|
|
17220
|
+
h2("option", { value: "off" }, "\u5173\u95ED"),
|
|
17221
|
+
h2("option", { value: "on" }, "\u5F00\u542F(\u8BED\u97F3\u63D0\u95EE\u4E0E\u8BED\u97F3\u56DE\u590D)")
|
|
17222
|
+
),
|
|
17223
|
+
enabled ? h2(
|
|
17224
|
+
"div",
|
|
17225
|
+
{ className: "dim-feishuVoiceForm" },
|
|
17226
|
+
input("\u51ED\u636E\u5F15\u7528(\u73AF\u5883\u53D8\u91CF\u540D)", secretRef, setSecretRef, "DASHSCOPE_API_KEY"),
|
|
17227
|
+
input("\u8F6C\u5199\u6A21\u578B(ASR)", asrModel, setAsrModel, "qwen3-asr-flash"),
|
|
17228
|
+
input("\u5408\u6210\u6A21\u578B(TTS)", ttsModel, setTtsModel, "qwen3-tts-flash"),
|
|
17229
|
+
input("\u56DE\u590D\u97F3\u8272", ttsVoice, setTtsVoice, "Momo"),
|
|
17230
|
+
h2(
|
|
17231
|
+
"p",
|
|
17232
|
+
{ className: "dim-feishuGroupHelp" },
|
|
17233
|
+
'\u9700\u8981 DashScope \u5BC6\u94A5(\u51ED\u636E\u5E93\u4E2D\u4EE5"\u51ED\u636E\u5F15\u7528"\u4E3A\u540D\u7684\u73AF\u5883\u53D8\u91CF)\u4E0E\u53EF\u7528 ffmpeg;\u97F3\u8272\u652F\u6301 Cherry/Serena/Bella/Chelsie/Momo/Katerina \u7B49 qwen3-tts-flash \u5B98\u65B9\u97F3\u8272\u3002'
|
|
17234
|
+
),
|
|
17235
|
+
h2(
|
|
17236
|
+
"div",
|
|
17237
|
+
{ className: "dim-feishuVoiceActions" },
|
|
17238
|
+
h2("button", {
|
|
17239
|
+
type: "button",
|
|
17240
|
+
className: "dim-feishuVoiceSave",
|
|
17241
|
+
onClick: () => void save(),
|
|
17242
|
+
disabled: disabled || saving || !secretRef.trim()
|
|
17243
|
+
}, "\u4FDD\u5B58\u8BED\u97F3\u8BBE\u7F6E")
|
|
17244
|
+
)
|
|
17245
|
+
) : h2("p", { className: "dim-feishuGroupHelp" }, "\u9ED8\u8BA4\u5173\u95ED;\u5F00\u542F\u540E\u673A\u5668\u4EBA\u53EF\u542C\u61C2\u8BED\u97F3\u6D88\u606F\u5E76\u4EE5\u8BED\u97F3\u56DE\u590D\u3002"),
|
|
17246
|
+
error ? h2("p", {
|
|
17247
|
+
className: "dim-feishuGroupError",
|
|
17248
|
+
role: "alert"
|
|
17249
|
+
}, error) : null
|
|
17250
|
+
);
|
|
17251
|
+
}
|
|
17252
|
+
|
|
17253
|
+
// plugin-src/client/channels/feishu/voice-settings.js
|
|
17254
|
+
function FeishuVoiceSettingsPage({ account, rpcCall }) {
|
|
17255
|
+
const [voice, setVoice] = React31.useState(null);
|
|
17256
|
+
const [phase, setPhase] = React31.useState("loading");
|
|
17257
|
+
const [error, setError] = React31.useState(null);
|
|
17258
|
+
const mounted = React31.useRef(true);
|
|
17259
|
+
const invoke = React31.useCallback(async (endpoint, payload, signal) => {
|
|
17260
|
+
if (typeof rpcCall !== "function") throw new Error("\u98DE\u4E66\u8BED\u97F3\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
17261
|
+
return unwrapRpcResult3(await rpcCall(endpoint, payload, signal));
|
|
17262
|
+
}, [rpcCall]);
|
|
17263
|
+
const applySnapshot = React31.useCallback((value) => {
|
|
17264
|
+
const bot = normalizeBotsSnapshot(value).bots.find((entry) => entry.botId === account.botId);
|
|
17265
|
+
if (!bot) throw new Error("\u672A\u627E\u5230\u5F53\u524D\u98DE\u4E66\u673A\u5668\u4EBA\uFF0C\u8BF7\u8FD4\u56DE\u5217\u8868\u540E\u91CD\u8BD5\u3002");
|
|
17266
|
+
if (mounted.current) setVoice(bot.voice);
|
|
17267
|
+
}, [account.botId]);
|
|
17268
|
+
const loadSettings = React31.useCallback(async (signal) => {
|
|
17269
|
+
setPhase("loading");
|
|
17270
|
+
setError(null);
|
|
17271
|
+
try {
|
|
17272
|
+
const value = await invoke(FEISHU_ENDPOINTS.status, {}, signal);
|
|
17273
|
+
if (signal?.aborted || !mounted.current) return;
|
|
17274
|
+
applySnapshot(value);
|
|
17275
|
+
setPhase("ready");
|
|
17276
|
+
} catch (cause) {
|
|
17277
|
+
if (signal?.aborted || !mounted.current) return;
|
|
17278
|
+
setError(cause?.message ?? "\u98DE\u4E66\u8BED\u97F3\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
17279
|
+
setPhase("error");
|
|
17280
|
+
}
|
|
17281
|
+
}, [applySnapshot, invoke]);
|
|
17282
|
+
React31.useEffect(() => {
|
|
17283
|
+
mounted.current = true;
|
|
17284
|
+
const controller = new AbortController();
|
|
17285
|
+
void loadSettings(controller.signal);
|
|
17286
|
+
return () => {
|
|
17287
|
+
mounted.current = false;
|
|
17288
|
+
controller.abort();
|
|
17289
|
+
};
|
|
17290
|
+
}, [loadSettings]);
|
|
17291
|
+
const saveVoice = async (settings) => {
|
|
17292
|
+
const value = await invoke(FEISHU_ENDPOINTS.setVoice, {
|
|
17293
|
+
botId: account.botId,
|
|
17294
|
+
voice: settings === null ? null : { ...voice, ...settings }
|
|
17295
|
+
});
|
|
17296
|
+
if (mounted.current) applySnapshot(value);
|
|
17297
|
+
};
|
|
17298
|
+
if (phase === "loading") {
|
|
17299
|
+
return h2(
|
|
17300
|
+
"div",
|
|
17301
|
+
{ className: "dim-deliveryState", role: "status", "aria-busy": "true" },
|
|
17302
|
+
"\u6B63\u5728\u8BFB\u53D6\u8BED\u97F3\u8BBE\u7F6E\u2026"
|
|
17303
|
+
);
|
|
17304
|
+
}
|
|
17305
|
+
if (phase === "error") {
|
|
17306
|
+
return h2(
|
|
17307
|
+
"div",
|
|
17308
|
+
{ className: "dim-deliveryState", role: "alert" },
|
|
17309
|
+
h2("p", null, error),
|
|
17310
|
+
h2("button", {
|
|
17311
|
+
type: "button",
|
|
17312
|
+
className: "dim-deliveryButton",
|
|
17313
|
+
onClick: () => void loadSettings()
|
|
17314
|
+
}, "\u91CD\u65B0\u8BFB\u53D6")
|
|
17315
|
+
);
|
|
17316
|
+
}
|
|
17317
|
+
return h2(VoiceEditor, { value: voice, onSave: saveVoice });
|
|
17318
|
+
}
|
|
17319
|
+
|
|
17081
17320
|
// plugin-src/client/delivery-settings.js
|
|
17082
17321
|
var DELIVERY_RPC_CHANNEL = "/dsh-im-delivery";
|
|
17083
17322
|
var DELIVERY_DOCS_URL = Object.freeze({
|
|
@@ -17099,7 +17338,8 @@ var BOT_SETTINGS_TABS = Object.freeze([
|
|
|
17099
17338
|
]);
|
|
17100
17339
|
var FEISHU_BOT_SETTINGS_TABS = Object.freeze([
|
|
17101
17340
|
...BOT_SETTINGS_TABS,
|
|
17102
|
-
Object.freeze({ id: "group", label: "\u7FA4\u804A" })
|
|
17341
|
+
Object.freeze({ id: "group", label: "\u7FA4\u804A" }),
|
|
17342
|
+
Object.freeze({ id: "voice", label: "\u8BED\u97F3\u4EA4\u4E92" })
|
|
17103
17343
|
]);
|
|
17104
17344
|
function botSettingsTabsForChannel(channel7) {
|
|
17105
17345
|
return channel7 === "feishu" ? FEISHU_BOT_SETTINGS_TABS : BOT_SETTINGS_TABS;
|
|
@@ -17311,13 +17551,13 @@ function TargetForm({
|
|
|
17311
17551
|
}) {
|
|
17312
17552
|
const editing = mode === "edit";
|
|
17313
17553
|
const initialKind = initialValue?.kind && definition.fields[initialValue.kind] ? initialValue.kind : definition.kinds[0].value;
|
|
17314
|
-
const [targetId, setTargetId] =
|
|
17315
|
-
const [name2, setName] =
|
|
17316
|
-
const [kind, setKind] =
|
|
17317
|
-
const [route, setRoute] =
|
|
17318
|
-
const [error, setError] =
|
|
17319
|
-
const [testing, setTesting] =
|
|
17320
|
-
const [testState, setTestState] =
|
|
17554
|
+
const [targetId, setTargetId] = React32.useState(initialValue?.targetId ?? "");
|
|
17555
|
+
const [name2, setName] = React32.useState(initialValue?.name ?? "");
|
|
17556
|
+
const [kind, setKind] = React32.useState(initialKind);
|
|
17557
|
+
const [route, setRoute] = React32.useState(initialValue?.route ?? {});
|
|
17558
|
+
const [error, setError] = React32.useState(null);
|
|
17559
|
+
const [testing, setTesting] = React32.useState(false);
|
|
17560
|
+
const [testState, setTestState] = React32.useState(null);
|
|
17321
17561
|
const currentTarget = () => {
|
|
17322
17562
|
const normalizedRoute = Object.fromEntries(fieldsFor(definition, kind).map((field2) => {
|
|
17323
17563
|
const raw = String(route[field2.key] ?? "").trim();
|
|
@@ -17534,7 +17774,7 @@ function TargetSuggestionPicker({
|
|
|
17534
17774
|
suggestions.map((suggestion, index) => {
|
|
17535
17775
|
const identity = routeIdentity(definition, suggestion);
|
|
17536
17776
|
const added = configured.has(identity);
|
|
17537
|
-
return
|
|
17777
|
+
return React32.createElement("option", {
|
|
17538
17778
|
key: suggestion.id ?? suggestion.suggestionId ?? `${identity}:${index}`,
|
|
17539
17779
|
value: String(index),
|
|
17540
17780
|
disabled: added
|
|
@@ -17551,11 +17791,11 @@ function TargetSuggestionPicker({
|
|
|
17551
17791
|
);
|
|
17552
17792
|
}
|
|
17553
17793
|
function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, onEdit }) {
|
|
17554
|
-
const [action, setAction] =
|
|
17555
|
-
const [testState, setTestState] =
|
|
17556
|
-
const [syncFeedback, setSyncFeedback] =
|
|
17557
|
-
const [copyState, setCopyState] =
|
|
17558
|
-
const [confirmDelete, setConfirmDelete] =
|
|
17794
|
+
const [action, setAction] = React32.useState(null);
|
|
17795
|
+
const [testState, setTestState] = React32.useState(null);
|
|
17796
|
+
const [syncFeedback, setSyncFeedback] = React32.useState(null);
|
|
17797
|
+
const [copyState, setCopyState] = React32.useState(null);
|
|
17798
|
+
const [confirmDelete, setConfirmDelete] = React32.useState(false);
|
|
17559
17799
|
const sessionSync = target.sessionSync ?? { enabled: false, state: "unavailable" };
|
|
17560
17800
|
const syncDescription = sessionSync.state === "active" ? "\u81EA\u52A8\u8DDF\u968F\u8BE5\u79C1\u804A\u7684\u5F53\u524D\u4F1A\u8BDD" : sessionSync.state === "waiting" ? "\u7B49\u5F85\u8BE5\u79C1\u804A\u5EFA\u7ACB\u65B0\u4F1A\u8BDD" : sessionSync.state === "unavailable" ? "\u4EC5\u652F\u6301\u5DF2\u7ECF\u804A\u8FC7\u3001\u5DF2\u5EFA\u7ACB\u5F53\u524D\u4F1A\u8BDD\u4E14\u4F7F\u7528\u5F53\u524D Host Harness \u7684\u79C1\u804A\u76EE\u6807" : "\u5173\u95ED\u65F6\u4E0D\u53D1\u9001 DSH \u4F1A\u8BDD\u6D88\u606F";
|
|
17561
17801
|
const testTarget = async () => {
|
|
@@ -17618,7 +17858,7 @@ function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, o
|
|
|
17618
17858
|
h2(
|
|
17619
17859
|
"div",
|
|
17620
17860
|
{ className: "dim-targetTitle" },
|
|
17621
|
-
|
|
17861
|
+
React32.createElement("strong", null, target.name || target.targetId),
|
|
17622
17862
|
h2("span", null, kindLabel(definition, target.kind))
|
|
17623
17863
|
),
|
|
17624
17864
|
h2("code", null, `targetId: ${target.targetId}`)
|
|
@@ -17704,26 +17944,26 @@ function DeliveryTargetSettingsPage({
|
|
|
17704
17944
|
onBack
|
|
17705
17945
|
}) {
|
|
17706
17946
|
const definition = CHANNEL_DEFINITIONS[channel7];
|
|
17707
|
-
const [activeTabId, setActiveTabId] =
|
|
17708
|
-
const [phase, setPhase] =
|
|
17709
|
-
const [targets, setTargets] =
|
|
17710
|
-
const [suggestionPhase, setSuggestionPhase] =
|
|
17711
|
-
const [suggestions, setSuggestions] =
|
|
17712
|
-
const [suggestionError, setSuggestionError] =
|
|
17713
|
-
const [error, setError] =
|
|
17714
|
-
const [editor, setEditor] =
|
|
17715
|
-
const [saving, setSaving] =
|
|
17716
|
-
const [botCopyState, setBotCopyState] =
|
|
17717
|
-
const [accessPolicy, setAccessPolicy] =
|
|
17718
|
-
const mounted =
|
|
17719
|
-
|
|
17947
|
+
const [activeTabId, setActiveTabId] = React32.useState(BOT_SETTINGS_TABS[0].id);
|
|
17948
|
+
const [phase, setPhase] = React32.useState("loading");
|
|
17949
|
+
const [targets, setTargets] = React32.useState([]);
|
|
17950
|
+
const [suggestionPhase, setSuggestionPhase] = React32.useState("idle");
|
|
17951
|
+
const [suggestions, setSuggestions] = React32.useState([]);
|
|
17952
|
+
const [suggestionError, setSuggestionError] = React32.useState(null);
|
|
17953
|
+
const [error, setError] = React32.useState(null);
|
|
17954
|
+
const [editor, setEditor] = React32.useState(null);
|
|
17955
|
+
const [saving, setSaving] = React32.useState(false);
|
|
17956
|
+
const [botCopyState, setBotCopyState] = React32.useState(null);
|
|
17957
|
+
const [accessPolicy, setAccessPolicy] = React32.useState(account.accessPolicy);
|
|
17958
|
+
const mounted = React32.useRef(true);
|
|
17959
|
+
React32.useEffect(() => {
|
|
17720
17960
|
setAccessPolicy(account.accessPolicy);
|
|
17721
17961
|
}, [account.botId, account.accessPolicy]);
|
|
17722
|
-
const invoke =
|
|
17962
|
+
const invoke = React32.useCallback(async (endpoint, payload = {}, signal) => {
|
|
17723
17963
|
if (typeof rpcCall !== "function") throw new Error("\u6295\u9012\u76EE\u6807\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
17724
17964
|
return unwrapRpcResult15(await rpcCall(endpoint, payload, signal));
|
|
17725
17965
|
}, [rpcCall]);
|
|
17726
|
-
const loadTargets =
|
|
17966
|
+
const loadTargets = React32.useCallback(async ({ signal, silent = false } = {}) => {
|
|
17727
17967
|
if (!silent) setPhase("loading");
|
|
17728
17968
|
setError(null);
|
|
17729
17969
|
try {
|
|
@@ -17737,7 +17977,7 @@ function DeliveryTargetSettingsPage({
|
|
|
17737
17977
|
setPhase("error");
|
|
17738
17978
|
}
|
|
17739
17979
|
}, [account.botId, invoke]);
|
|
17740
|
-
const loadSuggestions =
|
|
17980
|
+
const loadSuggestions = React32.useCallback(async () => {
|
|
17741
17981
|
setSuggestionPhase("loading");
|
|
17742
17982
|
setSuggestionError(null);
|
|
17743
17983
|
try {
|
|
@@ -17751,7 +17991,7 @@ function DeliveryTargetSettingsPage({
|
|
|
17751
17991
|
setSuggestionPhase("error");
|
|
17752
17992
|
}
|
|
17753
17993
|
}, [account.botId, definition, invoke]);
|
|
17754
|
-
|
|
17994
|
+
React32.useEffect(() => {
|
|
17755
17995
|
mounted.current = true;
|
|
17756
17996
|
const controller = new AbortController();
|
|
17757
17997
|
void loadTargets({ signal: controller.signal });
|
|
@@ -17872,8 +18112,12 @@ function DeliveryTargetSettingsPage({
|
|
|
17872
18112
|
}) : activeTab.id === "group" && channel7 === "feishu" ? h2(FeishuGroupSettingsPage, {
|
|
17873
18113
|
account,
|
|
17874
18114
|
rpcCall: accessRpcCall
|
|
18115
|
+
}) : activeTab.id === "voice" && channel7 === "feishu" ? h2(FeishuVoiceSettingsPage, {
|
|
18116
|
+
key: account.botId,
|
|
18117
|
+
account,
|
|
18118
|
+
rpcCall: accessRpcCall
|
|
17875
18119
|
}) : h2(
|
|
17876
|
-
|
|
18120
|
+
React32.Fragment,
|
|
17877
18121
|
null,
|
|
17878
18122
|
h2(
|
|
17879
18123
|
"section",
|
|
@@ -17984,7 +18228,7 @@ function DeliveryTargetSettingsPage({
|
|
|
17984
18228
|
}
|
|
17985
18229
|
|
|
17986
18230
|
// plugin-src/client/global-settings.js
|
|
17987
|
-
var
|
|
18231
|
+
var React33 = __toESM(require("react"), 1);
|
|
17988
18232
|
|
|
17989
18233
|
// src/channels/shared/inbound-ttl.mjs
|
|
17990
18234
|
var DEFAULT_INBOUND_TTL_HOURS = 168;
|
|
@@ -18069,14 +18313,14 @@ function GlobalButton({ children, kind = "secondary", className = "", ...props }
|
|
|
18069
18313
|
}, children);
|
|
18070
18314
|
}
|
|
18071
18315
|
function ImageInputSettings({ rpcCall }) {
|
|
18072
|
-
const [values, setValues] =
|
|
18073
|
-
const [phase, setPhase] =
|
|
18074
|
-
const [error, setError] =
|
|
18075
|
-
const [saved, setSaved] =
|
|
18076
|
-
const mounted =
|
|
18077
|
-
const saving =
|
|
18078
|
-
const id6 =
|
|
18079
|
-
const load =
|
|
18316
|
+
const [values, setValues] = React33.useState(DEFAULT_IMAGE_INPUT_SETTINGS);
|
|
18317
|
+
const [phase, setPhase] = React33.useState("loading");
|
|
18318
|
+
const [error, setError] = React33.useState(null);
|
|
18319
|
+
const [saved, setSaved] = React33.useState(false);
|
|
18320
|
+
const mounted = React33.useRef(false);
|
|
18321
|
+
const saving = React33.useRef(false);
|
|
18322
|
+
const id6 = React33.useId();
|
|
18323
|
+
const load = React33.useCallback(async (signal) => {
|
|
18080
18324
|
setPhase("loading");
|
|
18081
18325
|
setError(null);
|
|
18082
18326
|
try {
|
|
@@ -18092,7 +18336,7 @@ function ImageInputSettings({ rpcCall }) {
|
|
|
18092
18336
|
setPhase("error");
|
|
18093
18337
|
}
|
|
18094
18338
|
}, [rpcCall]);
|
|
18095
|
-
|
|
18339
|
+
React33.useEffect(() => {
|
|
18096
18340
|
mounted.current = true;
|
|
18097
18341
|
const controller = new AbortController();
|
|
18098
18342
|
void load(controller.signal);
|
|
@@ -18199,29 +18443,29 @@ function ImageInputSettings({ rpcCall }) {
|
|
|
18199
18443
|
);
|
|
18200
18444
|
}
|
|
18201
18445
|
function GlobalSettingsPanel({ rpcCall }) {
|
|
18202
|
-
const [phase, setPhase] =
|
|
18203
|
-
const [loadError, setLoadError] =
|
|
18204
|
-
const [ttlInput, setTtlInput] =
|
|
18205
|
-
const [savedTtl, setSavedTtl] =
|
|
18206
|
-
const [ttlError, setTtlError] =
|
|
18207
|
-
const [saveError, setSaveError] =
|
|
18208
|
-
const [saveSucceeded, setSaveSucceeded] =
|
|
18209
|
-
const [isSaving, setIsSaving] =
|
|
18210
|
-
const [sweepConfirming, setSweepConfirming] =
|
|
18211
|
-
const [sweeping, setSweeping] =
|
|
18212
|
-
const ttlErrorId =
|
|
18213
|
-
const ttlHintsId =
|
|
18214
|
-
const sweepTriggerId =
|
|
18215
|
-
const sweepConfirmId =
|
|
18216
|
-
const sweepConfirmTextId =
|
|
18217
|
-
const sweepConfirmButtonId =
|
|
18218
|
-
const mounted =
|
|
18219
|
-
const saving =
|
|
18220
|
-
const invoke =
|
|
18446
|
+
const [phase, setPhase] = React33.useState("loading");
|
|
18447
|
+
const [loadError, setLoadError] = React33.useState(null);
|
|
18448
|
+
const [ttlInput, setTtlInput] = React33.useState("");
|
|
18449
|
+
const [savedTtl, setSavedTtl] = React33.useState(null);
|
|
18450
|
+
const [ttlError, setTtlError] = React33.useState(false);
|
|
18451
|
+
const [saveError, setSaveError] = React33.useState(null);
|
|
18452
|
+
const [saveSucceeded, setSaveSucceeded] = React33.useState(false);
|
|
18453
|
+
const [isSaving, setIsSaving] = React33.useState(false);
|
|
18454
|
+
const [sweepConfirming, setSweepConfirming] = React33.useState(false);
|
|
18455
|
+
const [sweeping, setSweeping] = React33.useState(false);
|
|
18456
|
+
const ttlErrorId = React33.useId();
|
|
18457
|
+
const ttlHintsId = React33.useId();
|
|
18458
|
+
const sweepTriggerId = React33.useId();
|
|
18459
|
+
const sweepConfirmId = React33.useId();
|
|
18460
|
+
const sweepConfirmTextId = React33.useId();
|
|
18461
|
+
const sweepConfirmButtonId = React33.useId();
|
|
18462
|
+
const mounted = React33.useRef(true);
|
|
18463
|
+
const saving = React33.useRef(false);
|
|
18464
|
+
const invoke = React33.useCallback(async (endpoint, payload = {}, signal) => {
|
|
18221
18465
|
if (typeof rpcCall !== "function") throw new Error("\u901A\u7528\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
18222
18466
|
return unwrapRpcResult16(await rpcCall(endpoint, payload, signal));
|
|
18223
18467
|
}, [rpcCall]);
|
|
18224
|
-
const loadSettings =
|
|
18468
|
+
const loadSettings = React33.useCallback(async ({ signal } = {}) => {
|
|
18225
18469
|
setPhase("loading");
|
|
18226
18470
|
setLoadError(null);
|
|
18227
18471
|
try {
|
|
@@ -18245,7 +18489,7 @@ function GlobalSettingsPanel({ rpcCall }) {
|
|
|
18245
18489
|
setPhase("error");
|
|
18246
18490
|
}
|
|
18247
18491
|
}, [invoke]);
|
|
18248
|
-
|
|
18492
|
+
React33.useEffect(() => {
|
|
18249
18493
|
mounted.current = true;
|
|
18250
18494
|
const controller = new AbortController();
|
|
18251
18495
|
void loadSettings({ signal: controller.signal });
|
|
@@ -18254,7 +18498,7 @@ function GlobalSettingsPanel({ rpcCall }) {
|
|
|
18254
18498
|
controller.abort();
|
|
18255
18499
|
};
|
|
18256
18500
|
}, [loadSettings]);
|
|
18257
|
-
|
|
18501
|
+
React33.useEffect(() => {
|
|
18258
18502
|
if (!sweepConfirming) return;
|
|
18259
18503
|
globalThis.document?.getElementById(sweepConfirmButtonId)?.focus();
|
|
18260
18504
|
}, [sweepConfirmButtonId, sweepConfirming]);
|
|
@@ -19041,6 +19285,17 @@ var CSS15 = String.raw`
|
|
|
19041
19285
|
.dim-feishuGroupSelect:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary, #3370ff); box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 15%, transparent); }
|
|
19042
19286
|
.dim-feishuGroupSelect:disabled { cursor: not-allowed; opacity: .55; }
|
|
19043
19287
|
.dim-feishuGroupHelp { margin: -2px 0 0; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; line-height: 19px; }
|
|
19288
|
+
.dim-feishuVoiceForm { min-width: 0; display: grid; gap: 10px; }
|
|
19289
|
+
.dim-feishuVoiceField { min-width: 0; display: grid; gap: 5px; }
|
|
19290
|
+
.dim-feishuVoiceLabel { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 18px; }
|
|
19291
|
+
.dim-feishuVoiceInput { min-width: 0; width: 100%; height: 36px; padding: 0 11px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; line-height: 36px; transition: border-color .15s ease, box-shadow .15s ease; }
|
|
19292
|
+
.dim-feishuVoiceInput:hover:not(:disabled) { border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 42%, var(--dsw-alias-border-l2, #dfe1e5)); }
|
|
19293
|
+
.dim-feishuVoiceInput:focus-visible { outline: none; border-color: var(--dsw-alias-state-business-primary, #3370ff); box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 15%, transparent); }
|
|
19294
|
+
.dim-feishuVoiceInput:disabled { cursor: not-allowed; opacity: .55; }
|
|
19295
|
+
.dim-feishuVoiceActions { display: flex; justify-content: flex-start; }
|
|
19296
|
+
.dim-feishuVoiceSave { height: 34px; padding: 0 15px; border: 1px solid var(--dsw-alias-state-business-primary, #3370ff); border-radius: 8px; color: var(--dsw-alias-state-business-primary, #3370ff); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; line-height: 32px; cursor: pointer; transition: border-color .15s ease, color .15s ease, background .15s ease; }
|
|
19297
|
+
.dim-feishuVoiceSave:hover:not(:disabled) { color: #0f5fce; border-color: #0f5fce; background: color-mix(in srgb, #3370ff 6%, var(--dsw-alias-bg-layer-1, #fff)); }
|
|
19298
|
+
.dim-feishuVoiceSave:disabled { cursor: not-allowed; opacity: .55; }
|
|
19044
19299
|
.dim-feishuGroupPermissionAction { display: flex; justify-content: flex-start; }
|
|
19045
19300
|
.dim-feishuGroupPermissionAction .dim-deliveryButton { color: var(--dsw-alias-state-business-primary, #3370ff); border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 30%, var(--dsw-alias-border-l2, #dfe1e5)); }
|
|
19046
19301
|
.dim-feishuGroupError, .dim-feishuGroupRefreshError { margin: 0; padding: 9px 11px; border-radius: 8px; font-size: 12px; line-height: 18px; }
|
|
@@ -19555,7 +19810,7 @@ function installSessionChannelLogos(document2 = globalThis.document) {
|
|
|
19555
19810
|
}
|
|
19556
19811
|
|
|
19557
19812
|
// plugin-src/client/update-panel.js
|
|
19558
|
-
var
|
|
19813
|
+
var React34 = __toESM(require("react"), 1);
|
|
19559
19814
|
var import_react_dom4 = require("react-dom");
|
|
19560
19815
|
var import_valid = __toESM(require_valid(), 1);
|
|
19561
19816
|
var import_rcompare = __toESM(require_rcompare(), 1);
|
|
@@ -19648,11 +19903,11 @@ function manualUpdateCommand(snapshot) {
|
|
|
19648
19903
|
return `dsh plugin --profile ${profileArgument} add -w @xmanrui/dsh-im@${version}`;
|
|
19649
19904
|
}
|
|
19650
19905
|
function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
19651
|
-
const [copyState, setCopyState] =
|
|
19652
|
-
const commandRef =
|
|
19653
|
-
const mounted =
|
|
19654
|
-
const copying =
|
|
19655
|
-
|
|
19906
|
+
const [copyState, setCopyState] = React34.useState("idle");
|
|
19907
|
+
const commandRef = React34.useRef(null);
|
|
19908
|
+
const mounted = React34.useRef(false);
|
|
19909
|
+
const copying = React34.useRef(false);
|
|
19910
|
+
React34.useEffect(() => {
|
|
19656
19911
|
mounted.current = true;
|
|
19657
19912
|
return () => {
|
|
19658
19913
|
mounted.current = false;
|
|
@@ -19684,7 +19939,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
19684
19939
|
{ className: "dim-updateManual", "aria-label": "\u624B\u5DE5\u66F4\u65B0" },
|
|
19685
19940
|
h2("h4", { className: "dim-updateManualHeading" }, "\u624B\u5DE5\u66F4\u65B0"),
|
|
19686
19941
|
command ? h2(
|
|
19687
|
-
|
|
19942
|
+
React34.Fragment,
|
|
19688
19943
|
null,
|
|
19689
19944
|
h2("p", { className: "dim-updateManualHint" }, "\u81EA\u52A8\u66F4\u65B0\u5931\u8D25\u53EF\u4EE5\u4F7F\u7528\u547D\u4EE4\u66F4\u65B0\uFF1A"),
|
|
19690
19945
|
h2(
|
|
@@ -19720,7 +19975,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
19720
19975
|
"aria-hidden": "true",
|
|
19721
19976
|
focusable: "false"
|
|
19722
19977
|
}, copyState === "copied" ? h2("path", { d: "m4 10 4 4 8-8" }) : h2(
|
|
19723
|
-
|
|
19978
|
+
React34.Fragment,
|
|
19724
19979
|
null,
|
|
19725
19980
|
h2("rect", { x: 7, y: 7, width: 10, height: 11, rx: 1.5 }),
|
|
19726
19981
|
h2("path", { d: "M5 13H3.5A1.5 1.5 0 0 1 2 11.5v-8A1.5 1.5 0 0 1 3.5 2h8A1.5 1.5 0 0 1 13 3.5V5" })
|
|
@@ -19745,10 +20000,10 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
19745
20000
|
);
|
|
19746
20001
|
}
|
|
19747
20002
|
function UpdateDialog({ children, onClose }) {
|
|
19748
|
-
const dialogRef =
|
|
19749
|
-
const titleId =
|
|
19750
|
-
const descriptionId =
|
|
19751
|
-
|
|
20003
|
+
const dialogRef = React34.useRef(null);
|
|
20004
|
+
const titleId = React34.useId();
|
|
20005
|
+
const descriptionId = React34.useId();
|
|
20006
|
+
React34.useEffect(() => {
|
|
19752
20007
|
const previous = globalThis.document?.activeElement;
|
|
19753
20008
|
dialogRef.current?.focus?.();
|
|
19754
20009
|
return () => {
|
|
@@ -19806,20 +20061,20 @@ function UpdateDialog({ children, onClose }) {
|
|
|
19806
20061
|
return typeof document !== "undefined" && document.body ? (0, import_react_dom4.createPortal)(content, document.body) : content;
|
|
19807
20062
|
}
|
|
19808
20063
|
function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
19809
|
-
const tooltipId =
|
|
19810
|
-
const [snapshot, setSnapshot] =
|
|
19811
|
-
const [action, setAction] =
|
|
19812
|
-
const [error, setError] =
|
|
19813
|
-
const [open, setOpen] =
|
|
19814
|
-
const [uncertainInstall, setUncertainInstall] =
|
|
19815
|
-
const mounted =
|
|
19816
|
-
const busy =
|
|
19817
|
-
const readController =
|
|
19818
|
-
const pollReadController =
|
|
19819
|
-
const installRequest =
|
|
19820
|
-
const onStatusRef =
|
|
20064
|
+
const tooltipId = React34.useId();
|
|
20065
|
+
const [snapshot, setSnapshot] = React34.useState(null);
|
|
20066
|
+
const [action, setAction] = React34.useState("status");
|
|
20067
|
+
const [error, setError] = React34.useState(null);
|
|
20068
|
+
const [open, setOpen] = React34.useState(false);
|
|
20069
|
+
const [uncertainInstall, setUncertainInstall] = React34.useState(false);
|
|
20070
|
+
const mounted = React34.useRef(false);
|
|
20071
|
+
const busy = React34.useRef(false);
|
|
20072
|
+
const readController = React34.useRef(null);
|
|
20073
|
+
const pollReadController = React34.useRef(null);
|
|
20074
|
+
const installRequest = React34.useRef(null);
|
|
20075
|
+
const onStatusRef = React34.useRef(onStatus);
|
|
19821
20076
|
onStatusRef.current = onStatus;
|
|
19822
|
-
const accept =
|
|
20077
|
+
const accept = React34.useCallback((next) => {
|
|
19823
20078
|
setSnapshot(next);
|
|
19824
20079
|
onStatusRef.current?.(next);
|
|
19825
20080
|
}, []);
|
|
@@ -19828,7 +20083,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
19828
20083
|
setUncertainInstall(false);
|
|
19829
20084
|
accept(next);
|
|
19830
20085
|
};
|
|
19831
|
-
const invoke =
|
|
20086
|
+
const invoke = React34.useCallback(async (endpoint, payload = {}, signal) => {
|
|
19832
20087
|
if (typeof rpcCall !== "function") {
|
|
19833
20088
|
const unavailable = new Error("\u5F53\u524D Host \u4E0D\u652F\u6301\u66F4\u65B0\u63A5\u53E3\uFF0C\u8BF7\u5148\u624B\u52A8\u66F4\u65B0\u63D2\u4EF6\u5E76\u91CD\u542F\u3002");
|
|
19834
20089
|
unavailable.code = "update-unavailable";
|
|
@@ -19836,7 +20091,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
19836
20091
|
}
|
|
19837
20092
|
return unwrapSnapshot(await rpcCall(endpoint, payload, signal));
|
|
19838
20093
|
}, [rpcCall]);
|
|
19839
|
-
|
|
20094
|
+
React34.useEffect(() => {
|
|
19840
20095
|
mounted.current = true;
|
|
19841
20096
|
busy.current = true;
|
|
19842
20097
|
const controller = new AbortController();
|
|
@@ -19859,7 +20114,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
19859
20114
|
const activeJob = ACTIVE_STATES4.has(snapshot?.job?.state);
|
|
19860
20115
|
const restartRequired = snapshot?.job?.state === "restart-required" || snapshot?.blockedReason === "pending-restart";
|
|
19861
20116
|
const shouldPoll = activeJob || uncertainInstall;
|
|
19862
|
-
|
|
20117
|
+
React34.useEffect(() => {
|
|
19863
20118
|
if (!shouldPoll) return void 0;
|
|
19864
20119
|
let controller;
|
|
19865
20120
|
const scheduler = createPollScheduler({
|
|
@@ -19960,7 +20215,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
19960
20215
|
const buttonLabel = action === "checking" ? "\u68C0\u67E5\u4E2D\u2026" : action === "starting" || activeJob ? "\u6B63\u5728\u66F4\u65B0\u2026" : restartRequired ? "\u5F85\u624B\u52A8\u91CD\u542F" : snapshot?.canInstall ? "\u66F4\u65B0\u81F3" : "\u68C0\u67E5\u66F4\u65B0";
|
|
19961
20216
|
const buttonDescription = localizeText(buttonLabel) + (buttonLabel === "\u66F4\u65B0\u81F3" ? ` v${snapshot.latestVersion}` : "");
|
|
19962
20217
|
return h2(
|
|
19963
|
-
|
|
20218
|
+
React34.Fragment,
|
|
19964
20219
|
null,
|
|
19965
20220
|
h2(
|
|
19966
20221
|
"span",
|
|
@@ -20010,25 +20265,25 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
20010
20265
|
h2("dt", null, "\u8FD0\u884C\u7248\u672C"),
|
|
20011
20266
|
h2("dd", null, `v${snapshot?.runningVersion ?? clientVersion}`),
|
|
20012
20267
|
snapshot?.installedVersion && snapshot.installedVersion !== snapshot.runningVersion ? h2(
|
|
20013
|
-
|
|
20268
|
+
React34.Fragment,
|
|
20014
20269
|
null,
|
|
20015
20270
|
h2("dt", null, "\u5DF2\u5B89\u88C5\u7248\u672C"),
|
|
20016
20271
|
h2("dd", null, `v${snapshot.installedVersion}`)
|
|
20017
20272
|
) : null,
|
|
20018
20273
|
targetVersion ? h2(
|
|
20019
|
-
|
|
20274
|
+
React34.Fragment,
|
|
20020
20275
|
null,
|
|
20021
20276
|
h2("dt", null, "\u76EE\u6807\u7248\u672C"),
|
|
20022
20277
|
h2("dd", null, `v${targetVersion}`)
|
|
20023
20278
|
) : null,
|
|
20024
20279
|
latestVersion ? h2(
|
|
20025
|
-
|
|
20280
|
+
React34.Fragment,
|
|
20026
20281
|
null,
|
|
20027
20282
|
h2("dt", null, "\u6700\u65B0\u7248\u672C"),
|
|
20028
20283
|
h2("dd", null, `v${latestVersion}`)
|
|
20029
20284
|
) : null,
|
|
20030
20285
|
historicalTargetVersion ? h2(
|
|
20031
|
-
|
|
20286
|
+
React34.Fragment,
|
|
20032
20287
|
null,
|
|
20033
20288
|
h2("dt", null, "\u4E0A\u6B21\u66F4\u65B0\u76EE\u6807"),
|
|
20034
20289
|
h2("dd", null, `v${historicalTargetVersion}`)
|
|
@@ -20110,8 +20365,8 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
20110
20365
|
}
|
|
20111
20366
|
|
|
20112
20367
|
// plugin-src/client/panel-error-boundary.js
|
|
20113
|
-
var
|
|
20114
|
-
var IMPanelErrorBoundary = class extends
|
|
20368
|
+
var React35 = __toESM(require("react"), 1);
|
|
20369
|
+
var IMPanelErrorBoundary = class extends React35.Component {
|
|
20115
20370
|
state = { failed: false };
|
|
20116
20371
|
static getDerivedStateFromError() {
|
|
20117
20372
|
return { failed: true };
|
|
@@ -20304,28 +20559,28 @@ function IMSettingsTab({
|
|
|
20304
20559
|
browserLocation = globalThis.location,
|
|
20305
20560
|
navigateToRecoveryUrl = replacePageLocation
|
|
20306
20561
|
}) {
|
|
20307
|
-
const [selected, setSelected] =
|
|
20308
|
-
const [loopbackRecovery, setLoopbackRecovery] =
|
|
20309
|
-
const [runningVersion, setRunningVersion] =
|
|
20310
|
-
const [deliverySettings, setDeliverySettings] =
|
|
20562
|
+
const [selected, setSelected] = React36.useState(() => preferredSectionId === GLOBAL_SETTINGS_TAB_ID || CHANNELS.some((channel7) => channel7.id === preferredSectionId) ? preferredSectionId : "weixin");
|
|
20563
|
+
const [loopbackRecovery, setLoopbackRecovery] = React36.useState(null);
|
|
20564
|
+
const [runningVersion, setRunningVersion] = React36.useState(IM_PLUGIN_VERSION);
|
|
20565
|
+
const [deliverySettings, setDeliverySettings] = React36.useState(null);
|
|
20311
20566
|
const emailEnabled = useEmailChannelEnabled(emailRpcCall);
|
|
20312
|
-
const visibleChannels =
|
|
20567
|
+
const visibleChannels = React36.useMemo(
|
|
20313
20568
|
() => CHANNELS.filter((channel7) => channel7.id !== "email" || emailEnabled),
|
|
20314
20569
|
[emailEnabled]
|
|
20315
20570
|
);
|
|
20316
|
-
const githubTooltipId =
|
|
20317
|
-
const generalSettingsTooltipId =
|
|
20571
|
+
const githubTooltipId = React36.useId();
|
|
20572
|
+
const generalSettingsTooltipId = React36.useId();
|
|
20318
20573
|
const globalSettingsSelected = selected === GLOBAL_SETTINGS_TAB_ID;
|
|
20319
20574
|
const active = visibleChannels.find((channel7) => channel7.id === selected) ?? visibleChannels[0];
|
|
20320
20575
|
const activeTabId = globalSettingsSelected ? "dim-general-settings-trigger" : `dim-tab-${active.id}`;
|
|
20321
20576
|
const activePanelId = globalSettingsSelected ? `dim-panel-${GLOBAL_SETTINGS_TAB_ID}` : `dim-panel-${active.id}`;
|
|
20322
|
-
const reportLoopbackRecovery =
|
|
20577
|
+
const reportLoopbackRecovery = React36.useCallback((recovery) => {
|
|
20323
20578
|
setLoopbackRecovery((current) => current?.url === recovery.url ? current : recovery);
|
|
20324
20579
|
}, []);
|
|
20325
|
-
const reportUpdateStatus =
|
|
20580
|
+
const reportUpdateStatus = React36.useCallback((snapshot) => {
|
|
20326
20581
|
setRunningVersion(snapshot.runningVersion);
|
|
20327
20582
|
}, []);
|
|
20328
|
-
const rpcCalls =
|
|
20583
|
+
const rpcCalls = React36.useMemo(() => createLoopbackAwareRpcCalls({
|
|
20329
20584
|
dingtalkRpcCall,
|
|
20330
20585
|
discordRpcCall,
|
|
20331
20586
|
feishuRpcCall,
|
|
@@ -20367,7 +20622,7 @@ function IMSettingsTab({
|
|
|
20367
20622
|
weixinRpcCall,
|
|
20368
20623
|
whatsappRpcCall
|
|
20369
20624
|
]);
|
|
20370
|
-
const botSettingsContext =
|
|
20625
|
+
const botSettingsContext = React36.useMemo(() => Object.freeze({
|
|
20371
20626
|
openBotSettings: setDeliverySettings
|
|
20372
20627
|
}), []);
|
|
20373
20628
|
return h2(
|
|
@@ -20591,7 +20846,7 @@ function apply(ctx) {
|
|
|
20591
20846
|
};
|
|
20592
20847
|
const localeSnapshot = () => ctx.locale.getLocale?.()?.active ?? "";
|
|
20593
20848
|
function IMPanel({ preferredSectionId }) {
|
|
20594
|
-
|
|
20849
|
+
React36.useSyncExternalStore(subscribeLocale, localeSnapshot, localeSnapshot);
|
|
20595
20850
|
return h2(
|
|
20596
20851
|
IMPanelErrorBoundary,
|
|
20597
20852
|
null,
|