@xmanrui/dsh-im 4.9.1 → 4.10.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/PROACTIVE_DELIVERY.en.md +8 -0
- package/PROACTIVE_DELIVERY.md +8 -0
- package/lib/client.js +610 -56
- package/lib/index.js +273 -272
- package/package.json +12 -1
- package/plugin-src/client/channels/feishu/api.js +2 -0
- package/plugin-src/client/channels/feishu/index.js +54 -0
- package/plugin-src/client/global-settings.js +341 -0
- package/plugin-src/client/i18n.js +29 -0
- package/plugin-src/client/index.js +47 -6
- package/plugin-src/client/styles.js +49 -0
- package/plugin-src/host/channels/dingtalk/production.mjs +12 -0
- package/plugin-src/host/channels/feishu/production.mjs +14 -0
- package/plugin-src/host/channels/feishu/rpc.mjs +16 -0
- package/plugin-src/host/channels/qq/production.mjs +12 -0
- package/plugin-src/host/channels/shared/production.mjs +12 -0
- package/plugin-src/host/channels/slack/production.mjs +12 -0
- package/plugin-src/host/channels/wecom/production.mjs +12 -0
- package/plugin-src/host/channels/weixin/production.mjs +12 -0
- package/plugin-src/host/channels/whatsapp/production.mjs +12 -0
- package/plugin-src/host/delivery-adapter.mjs +1 -0
- package/plugin-src/host/delivery-service.mjs +15 -0
- package/plugin-src/host/harness-session-coordinator.mjs +26 -5
- package/plugin-src/host/inbound-ttl-rpc.mjs +83 -0
- package/plugin-src/host/inbound-ttl-runtime.mjs +85 -0
- package/plugin-src/host/inbound-ttl-service.mjs +179 -0
- package/plugin-src/host/index.mjs +8 -0
- package/plugin-src/host/modern-harness-api.mjs +58 -2
- package/src/channels/feishu/bridge.mjs +164 -4
- package/src/channels/feishu/feishu-channel.mjs +45 -10
- package/src/channels/feishu/feishu-runtime.mjs +9 -0
- package/src/channels/feishu/message-utils.mjs +13 -0
- package/src/channels/feishu/multi-bot-controller.mjs +16 -0
- package/src/channels/feishu/plugin-config-store.mjs +1 -0
- package/src/channels/feishu/state-store.mjs +25 -0
- package/src/channels/shared/bot-workspace-store.mjs +6 -0
- package/src/channels/shared/inbound-file.mjs +117 -2
- package/src/channels/shared/inbound-ttl-store.mjs +110 -0
- package/src/channels/shared/inbound-ttl.mjs +22 -0
package/lib/client.js
CHANGED
|
@@ -566,12 +566,12 @@ __export(index_exports, {
|
|
|
566
566
|
name: () => name
|
|
567
567
|
});
|
|
568
568
|
module.exports = __toCommonJS(index_exports);
|
|
569
|
-
var
|
|
569
|
+
var React24 = __toESM(require("react"), 1);
|
|
570
570
|
|
|
571
571
|
// package.json
|
|
572
572
|
var package_default = {
|
|
573
573
|
name: "@xmanrui/dsh-im",
|
|
574
|
-
version: "4.
|
|
574
|
+
version: "4.10.0",
|
|
575
575
|
description: "\u628A\u4E5D\u79CD IM \u673A\u5668\u4EBA\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect nine IM channels and a public AI Office to a local DeepSeek Harness.",
|
|
576
576
|
keywords: [
|
|
577
577
|
"deepseek-harness",
|
|
@@ -658,6 +658,17 @@ var package_default = {
|
|
|
658
658
|
"@deepseek-ai/dsh-client-locale"
|
|
659
659
|
],
|
|
660
660
|
platform: "web"
|
|
661
|
+
},
|
|
662
|
+
compatibility: {
|
|
663
|
+
dsh: "0.1.2-alpha.4 || 0.1.2-alpha.5 || 0.1.2-rc.1",
|
|
664
|
+
dshReleases: {
|
|
665
|
+
"0.1.2-alpha.4": "compatible",
|
|
666
|
+
"0.1.2-alpha.5": "compatible",
|
|
667
|
+
"0.1.2-rc.1": "compatible"
|
|
668
|
+
},
|
|
669
|
+
profiles: [
|
|
670
|
+
"web"
|
|
671
|
+
]
|
|
661
672
|
}
|
|
662
673
|
},
|
|
663
674
|
scripts: {
|
|
@@ -1057,6 +1068,11 @@ var EN = Object.freeze({
|
|
|
1057
1068
|
"\u9700\u5728\u98DE\u4E66\u4E3A\u8BE5\u673A\u5668\u4EBA\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF08im:message.group_msg\uFF09\uFF1B\u5F00\u901A\u540E\uFF0C\u673A\u5668\u4EBA\u4F1A\u5904\u7406\u7FA4\u804A\u4E2D\u7684\u6240\u6709\u53EF\u89C1\u6D88\u606F\u3002": "Grant this bot the \u201CRead all messages in associated group chat\u201D Feishu scope (im:message.group_msg); once granted, it will process every visible group message.",
|
|
1058
1069
|
"\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not update the group response mode. Try again.",
|
|
1059
1070
|
"\u7FA4\u6D88\u606F\u6743\u9650\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not authorize group-message permission. Try again.",
|
|
1071
|
+
"\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D": "Reply to group chats as Feishu topics",
|
|
1072
|
+
"\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not save the topic reply setting. Try again.",
|
|
1073
|
+
"\u5173\u95ED\uFF08\u7FA4\u5185\u76F4\u63A5\u56DE\u590D\uFF09": "Off (reply in the group feed)",
|
|
1074
|
+
"\u5F00\u542F\uFF08\u81EA\u52A8\u5F00\u542F\u72EC\u7ACB\u98DE\u4E66\u8BDD\u9898\uFF09": "On (auto-open a dedicated Feishu topic)",
|
|
1075
|
+
"\u5F00\u542F\u540E\uFF0C\u7FA4\u804A\u4E2D\u5411\u673A\u5668\u4EBA\u63D0\u95EE\u4F1A\u81EA\u52A8\u5F00\u542F\u72EC\u7ACB\u98DE\u4E66\u8BDD\u9898\uFF0C\u56DE\u590D\u843D\u5728\u8BDD\u9898\u5185\uFF1B\u6BCF\u4E2A\u8BDD\u9898\u662F dsh \u4F1A\u8BDD\u5217\u8868\u91CC\u4E00\u6761\u72EC\u7ACB\u4F1A\u8BDD\uFF0C\u4E0A\u4E0B\u6587\u4E92\u4E0D\u4E32\u3002\u79C1\u804A\u4E0D\u53D7\u5F71\u54CD\u3002": "When enabled, questions to the bot in a group auto-open a dedicated Feishu topic and replies stay inside it. Each topic is an independent conversation in dsh with its own context. Private chats are unaffected.",
|
|
1060
1076
|
"\u9489\u9489\u8BBE\u7F6E": "DingTalk settings",
|
|
1061
1077
|
"\u4F01\u4E1A\u5FAE\u4FE1\u8BBE\u7F6E": "WeCom settings",
|
|
1062
1078
|
"\u626B\u7801\u63A5\u5165\u673A\u5668\u4EBA": "Scan QR code",
|
|
@@ -1678,7 +1694,29 @@ var EN = Object.freeze({
|
|
|
1678
1694
|
"\u65B0\u5EFA\u76EE\u6807": "New target",
|
|
1679
1695
|
"\u6B63\u5728\u8BFB\u53D6\u6295\u9012\u76EE\u6807\u2026": "Loading delivery targets\u2026",
|
|
1680
1696
|
"\u5C1A\u672A\u914D\u7F6E\u6295\u9012\u76EE\u6807": "No delivery targets yet",
|
|
1681
|
-
"\u70B9\u51FB\u201C\u65B0\u5EFA\u76EE\u6807\u201D\u53EF\u4ECE\u5DF2\u804A\u8FC7\u7684\u4F1A\u8BDD\u9009\u62E9\uFF0C\u4E5F\u53EF\u624B\u52A8\u586B\u5199\u3002": "Select New target to choose a conversation or enter the details manually."
|
|
1697
|
+
"\u70B9\u51FB\u201C\u65B0\u5EFA\u76EE\u6807\u201D\u53EF\u4ECE\u5DF2\u804A\u8FC7\u7684\u4F1A\u8BDD\u9009\u62E9\uFF0C\u4E5F\u53EF\u624B\u52A8\u586B\u5199\u3002": "Select New target to choose a conversation or enter the details manually.",
|
|
1698
|
+
"\u5168\u5C40\u8BBE\u7F6E": "Global settings",
|
|
1699
|
+
"\u901A\u7528\u8BBE\u7F6E": "General settings",
|
|
1700
|
+
"\u901A\u7528\u8BBE\u7F6E\u5206\u7C7B": "General settings categories",
|
|
1701
|
+
"\u9644\u4EF6": "Attachments",
|
|
1702
|
+
"IM \u8BBE\u7F6E\u5BFC\u822A": "IM settings navigation",
|
|
1703
|
+
"\u9644\u4EF6\u4FDD\u7559\u65F6\u957F (\u5C0F\u65F6)": "Attachment retention (hours)",
|
|
1704
|
+
"\u67E5\u770B\u9644\u4EF6\u4FDD\u7559\u65F6\u957F\u8BF4\u660E": "View attachment retention details",
|
|
1705
|
+
"\u6C38\u4E45\u4FDD\u7559\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u6E05\u7406": "Keep forever; nothing is removed automatically",
|
|
1706
|
+
"\u6BCF Turn \u7ED3\u675F\u540E\u7ACB\u5373\u6E05\u7406": "Cleaned up as soon as each turn ends",
|
|
1707
|
+
"\u5C0F\u65F6\u540E\u81EA\u52A8\u6E05\u7406": "hours until automatic cleanup",
|
|
1708
|
+
"\u8BF7\u8F93\u5165 -1\u30010 \u6216 1~${INBOUND_TTL_MAX_HOURS} \u4E4B\u95F4\u7684\u6574\u6570\u3002": "Enter -1, 0, or an integer from 1 to ${INBOUND_TTL_MAX_HOURS}.",
|
|
1709
|
+
"\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002": "Could not save the setting. Try again later.",
|
|
1710
|
+
"\u5DF2\u4FDD\u5B58": "Saved",
|
|
1711
|
+
"\u901A\u7528\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002": "General settings are unavailable.",
|
|
1712
|
+
"\u6B63\u5728\u8BFB\u53D6\u901A\u7528\u8BBE\u7F6E\u2026": "Loading general settings\u2026",
|
|
1713
|
+
"\u65E0\u6CD5\u8BFB\u53D6\u901A\u7528\u8BBE\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002": "Could not load general settings. Try again later.",
|
|
1714
|
+
"\u901A\u7528\u8BBE\u7F6E\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94\u3002": "General settings returned an unrecognized response.",
|
|
1715
|
+
"\u6E05\u7406\u8FC7\u671F\u9644\u4EF6": "Clean up expired attachments",
|
|
1716
|
+
"\u786E\u8BA4\u6E05\u7406\u8FC7\u671F\u9644\u4EF6": "Confirm expired attachment cleanup",
|
|
1717
|
+
"\u786E\u8BA4\u6E05\u7406\u5F53\u524D\u5DF2\u8FC7\u671F\u7684\u9644\u4EF6\uFF1F": "Clean up the attachments that are currently expired?",
|
|
1718
|
+
"\u786E\u8BA4\u6E05\u7406": "Confirm cleanup",
|
|
1719
|
+
"\u6B63\u5728\u6E05\u7406\u2026": "Cleaning up\u2026"
|
|
1682
1720
|
});
|
|
1683
1721
|
var en = EN;
|
|
1684
1722
|
var zh = Object.freeze(Object.fromEntries(
|
|
@@ -1701,6 +1739,8 @@ function translateDynamic(text6) {
|
|
|
1701
1739
|
if (match) return `${match[1]}/${match[2]} online`;
|
|
1702
1740
|
match = /^已接入 (\d+) 个机器人,其中 (\d+) 个在线$/.exec(text6);
|
|
1703
1741
|
if (match) return `${match[2]} of ${match[1]} bots online`;
|
|
1742
|
+
match = /^请输入 -1、0 或 1~(\d+) 之间的整数。$/.exec(text6);
|
|
1743
|
+
if (match) return `Enter -1, 0, or an integer from 1 to ${match[1]}.`;
|
|
1704
1744
|
match = /^正在读取\s*(.+?)\s*机器人状态…$/.exec(text6);
|
|
1705
1745
|
if (match) return `Loading ${channelName(match[1])} bot status\u2026`;
|
|
1706
1746
|
match = /^无法读取\s*(.+?)\s*机器人状态$/.exec(text6);
|
|
@@ -4764,7 +4804,7 @@ var TOKEN_BOT_ENDPOINTS = Object.freeze({
|
|
|
4764
4804
|
function createTokenChannelApi(channel4, connectionSummary, {
|
|
4765
4805
|
normalizeBotExtension = () => ({})
|
|
4766
4806
|
} = {}) {
|
|
4767
|
-
const
|
|
4807
|
+
const unwrapRpcResult13 = (result) => {
|
|
4768
4808
|
if (!isRecord2(result) || typeof result.ok !== "boolean") {
|
|
4769
4809
|
throw new Error(`${channel4} \u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94`);
|
|
4770
4810
|
}
|
|
@@ -4821,11 +4861,11 @@ function createTokenChannelApi(channel4, connectionSummary, {
|
|
|
4821
4861
|
agentPresetCatalog: normalizeAgentPresetCatalog(source.agentPresetCatalog)
|
|
4822
4862
|
};
|
|
4823
4863
|
};
|
|
4824
|
-
const
|
|
4864
|
+
const presentError13 = (error) => ({
|
|
4825
4865
|
code: text2(error?.code, `${channel4.toUpperCase()}_ERROR`, 80),
|
|
4826
4866
|
message: text2(error?.message, `${channel4}\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5`)
|
|
4827
4867
|
});
|
|
4828
|
-
return Object.freeze({ unwrapRpcResult:
|
|
4868
|
+
return Object.freeze({ unwrapRpcResult: unwrapRpcResult13, normalizeSnapshot: normalizeSnapshot9, presentError: presentError13 });
|
|
4829
4869
|
}
|
|
4830
4870
|
|
|
4831
4871
|
// plugin-src/client/channels/discord/api.js
|
|
@@ -5374,6 +5414,7 @@ var FEISHU_ENDPOINTS = Object.freeze({
|
|
|
5374
5414
|
setContextEnhancement: "bot.context-enhancement.set",
|
|
5375
5415
|
setAccessPolicy: "bot.access-policy.set",
|
|
5376
5416
|
setGroupResponseMode: "bot.group-response-mode.set",
|
|
5417
|
+
setGroupTopicReply: "bot.group-topic-reply.set",
|
|
5377
5418
|
// Kept for rolling upgrades. The multi-bot UI never calls these endpoints.
|
|
5378
5419
|
testConnection: "connection.test",
|
|
5379
5420
|
disconnect: "connection.disconnect"
|
|
@@ -5524,6 +5565,7 @@ function normalizeBotConnection(value, fallbackBotId) {
|
|
|
5524
5565
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
5525
5566
|
...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
|
|
5526
5567
|
groupResponseMode: normalizeGroupResponseMode(value.groupResponseMode),
|
|
5568
|
+
groupTopicReply: value.groupTopicReply === true,
|
|
5527
5569
|
groupMessagePermissionGranted: value.groupMessagePermissionGranted === true,
|
|
5528
5570
|
bot: normalizeBot2(value.bot),
|
|
5529
5571
|
health: normalizeHealth(value.health, connected),
|
|
@@ -6182,6 +6224,57 @@ function GroupResponseModeEditor({
|
|
|
6182
6224
|
}, error) : null
|
|
6183
6225
|
);
|
|
6184
6226
|
}
|
|
6227
|
+
function GroupTopicReplyEditor({ value = false, disabled = false, onSave }) {
|
|
6228
|
+
const current = value === true ? "on" : "off";
|
|
6229
|
+
const [saving, setSaving] = React13.useState(false);
|
|
6230
|
+
const [error, setError] = React13.useState(null);
|
|
6231
|
+
const change = async (event) => {
|
|
6232
|
+
const next = event.target.value === "on";
|
|
6233
|
+
if ((next ? "on" : "off") === current || saving || disabled) return;
|
|
6234
|
+
setSaving(true);
|
|
6235
|
+
setError(null);
|
|
6236
|
+
try {
|
|
6237
|
+
await onSave?.(next);
|
|
6238
|
+
} catch (cause) {
|
|
6239
|
+
setError(cause?.message ?? "\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
6240
|
+
} finally {
|
|
6241
|
+
setSaving(false);
|
|
6242
|
+
}
|
|
6243
|
+
};
|
|
6244
|
+
return h2(
|
|
6245
|
+
"div",
|
|
6246
|
+
{ className: "bxf-responseMode dim-responseMode" },
|
|
6247
|
+
h2(
|
|
6248
|
+
"div",
|
|
6249
|
+
{ className: "bxf-responseModeHeader dim-responseModeHeader" },
|
|
6250
|
+
h2("span", null, "\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D"),
|
|
6251
|
+
saving ? h2("span", { className: "bxf-responseModeStatus dim-responseModeStatus" }, "\u4FDD\u5B58\u4E2D\u2026") : null
|
|
6252
|
+
),
|
|
6253
|
+
h2(
|
|
6254
|
+
"select",
|
|
6255
|
+
{
|
|
6256
|
+
className: "bxf-responseModeSelect dim-responseModeSelect",
|
|
6257
|
+
value: current,
|
|
6258
|
+
disabled: disabled || saving,
|
|
6259
|
+
"aria-label": "\u7FA4\u804A\u4EE5\u8BDD\u9898\u65B9\u5F0F\u56DE\u590D",
|
|
6260
|
+
onChange: (event) => {
|
|
6261
|
+
void change(event);
|
|
6262
|
+
}
|
|
6263
|
+
},
|
|
6264
|
+
h2("option", { value: "off" }, "\u5173\u95ED\uFF08\u7FA4\u5185\u76F4\u63A5\u56DE\u590D\uFF09"),
|
|
6265
|
+
h2("option", { value: "on" }, "\u5F00\u542F\uFF08\u81EA\u52A8\u5F00\u542F\u72EC\u7ACB\u98DE\u4E66\u8BDD\u9898\uFF09")
|
|
6266
|
+
),
|
|
6267
|
+
h2(
|
|
6268
|
+
"small",
|
|
6269
|
+
{ className: "bxf-responseModeHelp dim-responseModeHelp" },
|
|
6270
|
+
"\u5F00\u542F\u540E\uFF0C\u7FA4\u804A\u4E2D\u5411\u673A\u5668\u4EBA\u63D0\u95EE\u4F1A\u81EA\u52A8\u5F00\u542F\u72EC\u7ACB\u98DE\u4E66\u8BDD\u9898\uFF0C\u56DE\u590D\u843D\u5728\u8BDD\u9898\u5185\uFF1B\u6BCF\u4E2A\u8BDD\u9898\u662F dsh \u4F1A\u8BDD\u5217\u8868\u91CC\u4E00\u6761\u72EC\u7ACB\u4F1A\u8BDD\uFF0C\u4E0A\u4E0B\u6587\u4E92\u4E0D\u4E32\u3002\u79C1\u804A\u4E0D\u53D7\u5F71\u54CD\u3002"
|
|
6271
|
+
),
|
|
6272
|
+
error ? h2("p", {
|
|
6273
|
+
className: "bxf-responseModeError dim-responseModeError",
|
|
6274
|
+
role: "alert"
|
|
6275
|
+
}, error) : null
|
|
6276
|
+
);
|
|
6277
|
+
}
|
|
6185
6278
|
function BotCard({
|
|
6186
6279
|
connection,
|
|
6187
6280
|
busy,
|
|
@@ -6197,6 +6290,7 @@ function BotCard({
|
|
|
6197
6290
|
onAgentPresetSave,
|
|
6198
6291
|
onContextEnhancementSave,
|
|
6199
6292
|
onGroupResponseModeSave,
|
|
6293
|
+
onGroupTopicReplySave,
|
|
6200
6294
|
onGroupMessagePermissionAuthorize,
|
|
6201
6295
|
onRequestRemove,
|
|
6202
6296
|
onConfirmRemove,
|
|
@@ -6284,6 +6378,11 @@ function BotCard({
|
|
|
6284
6378
|
onSave: onGroupResponseModeSave,
|
|
6285
6379
|
onAuthorize: onGroupMessagePermissionAuthorize
|
|
6286
6380
|
}),
|
|
6381
|
+
h2(GroupTopicReplyEditor, {
|
|
6382
|
+
value: connection.groupTopicReply,
|
|
6383
|
+
disabled: Boolean(busy),
|
|
6384
|
+
onSave: onGroupTopicReplySave
|
|
6385
|
+
}),
|
|
6287
6386
|
provisionContent ? h2("section", {
|
|
6288
6387
|
className: "bxf-botProvision dim-botProvision",
|
|
6289
6388
|
"aria-label": `${bot.name}\u7684\u98DE\u4E66\u6388\u6743\u6D41\u7A0B`,
|
|
@@ -6393,6 +6492,7 @@ function BotList(props) {
|
|
|
6393
6492
|
onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(bot, agentPreset),
|
|
6394
6493
|
onContextEnhancementSave: (config) => props.onContextEnhancementSave(bot, config),
|
|
6395
6494
|
onGroupResponseModeSave: (groupResponseMode) => props.onGroupResponseModeSave(bot, groupResponseMode),
|
|
6495
|
+
onGroupTopicReplySave: (groupTopicReply) => props.onGroupTopicReplySave(bot, groupTopicReply),
|
|
6396
6496
|
onGroupMessagePermissionAuthorize: () => props.onGroupMessagePermissionAuthorize(bot),
|
|
6397
6497
|
onRequestRemove: () => props.onRequestRemove(bot),
|
|
6398
6498
|
onConfirmRemove: () => props.onConfirmRemove(bot),
|
|
@@ -7135,6 +7235,12 @@ function FeishuSettingsTab({ rpcCall }) {
|
|
|
7135
7235
|
{ config }
|
|
7136
7236
|
),
|
|
7137
7237
|
onGroupResponseModeSave: saveGroupResponseMode,
|
|
7238
|
+
onGroupTopicReplySave: (connection, groupTopicReply) => saveBotSetting(
|
|
7239
|
+
connection,
|
|
7240
|
+
"group-topic-reply",
|
|
7241
|
+
FEISHU_ENDPOINTS.setGroupTopicReply,
|
|
7242
|
+
{ groupTopicReply }
|
|
7243
|
+
),
|
|
7138
7244
|
onGroupMessagePermissionAuthorize: authorizeGroupMessages,
|
|
7139
7245
|
onRequestRemove: requestRemove,
|
|
7140
7246
|
onConfirmRemove: (bot) => void confirmRemove(bot),
|
|
@@ -13028,6 +13134,374 @@ function DeliveryTargetSettingsPage({
|
|
|
13028
13134
|
);
|
|
13029
13135
|
}
|
|
13030
13136
|
|
|
13137
|
+
// plugin-src/client/global-settings.js
|
|
13138
|
+
var React22 = __toESM(require("react"), 1);
|
|
13139
|
+
|
|
13140
|
+
// src/channels/shared/inbound-ttl.mjs
|
|
13141
|
+
var DEFAULT_INBOUND_TTL_HOURS = 168;
|
|
13142
|
+
var INBOUND_TTL_MAX_HOURS = 8760;
|
|
13143
|
+
var INTEGER_STRING = /^[+-]?\d+$/;
|
|
13144
|
+
function normalizeInboundTtlHours(value) {
|
|
13145
|
+
let candidate = value;
|
|
13146
|
+
if (typeof candidate === "string") {
|
|
13147
|
+
const trimmed = candidate.trim();
|
|
13148
|
+
if (!INTEGER_STRING.test(trimmed)) return null;
|
|
13149
|
+
candidate = Number(trimmed);
|
|
13150
|
+
}
|
|
13151
|
+
if (typeof candidate !== "number" || !Number.isInteger(candidate)) return null;
|
|
13152
|
+
if (candidate === -1) return -1;
|
|
13153
|
+
if (candidate >= 0 && candidate <= INBOUND_TTL_MAX_HOURS) return candidate;
|
|
13154
|
+
return null;
|
|
13155
|
+
}
|
|
13156
|
+
|
|
13157
|
+
// plugin-src/client/global-settings.js
|
|
13158
|
+
var GLOBAL_SETTINGS_RPC_CHANNEL = "/dsh-im-settings";
|
|
13159
|
+
var GLOBAL_SETTINGS_TAB_ID = "global-settings";
|
|
13160
|
+
var ATTACHMENTS_TAB_ID = "dim-general-settings-tab-attachments";
|
|
13161
|
+
var ATTACHMENTS_PANEL_ID = "dim-general-settings-panel-attachments";
|
|
13162
|
+
var GLOBAL_SETTINGS_ENDPOINTS = Object.freeze({
|
|
13163
|
+
getTtl: "settings.inbound-ttl.get",
|
|
13164
|
+
setTtl: "settings.inbound-ttl.set",
|
|
13165
|
+
sweep: "settings.inbound-ttl.sweep"
|
|
13166
|
+
});
|
|
13167
|
+
function presentError11(error, fallback) {
|
|
13168
|
+
return error?.message || fallback;
|
|
13169
|
+
}
|
|
13170
|
+
function unwrapRpcResult12(result) {
|
|
13171
|
+
if (result?.ok === true) return result.value;
|
|
13172
|
+
if (result?.ok === false) {
|
|
13173
|
+
const error = new Error(result.error?.message || "\u8BF7\u6C42\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
|
|
13174
|
+
error.code = result.error?.code;
|
|
13175
|
+
throw error;
|
|
13176
|
+
}
|
|
13177
|
+
return result;
|
|
13178
|
+
}
|
|
13179
|
+
function GlobalSettingsLogoGlyph({ size } = {}) {
|
|
13180
|
+
return h2("svg", {
|
|
13181
|
+
...size === void 0 ? {} : { width: size, height: size },
|
|
13182
|
+
viewBox: "0 0 24 24",
|
|
13183
|
+
focusable: "false",
|
|
13184
|
+
"aria-hidden": "true",
|
|
13185
|
+
"data-im-icon": "global-settings"
|
|
13186
|
+
}, h2("path", {
|
|
13187
|
+
fill: "currentColor",
|
|
13188
|
+
d: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.488.488 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96a.488.488 0 0 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58ZM12 15.6A3.61 3.61 0 0 1 8.4 12c0-1.98 1.62-3.6 3.6-3.6s3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6Z"
|
|
13189
|
+
}));
|
|
13190
|
+
}
|
|
13191
|
+
function GlobalButton({ children, kind = "secondary", className = "", ...props }) {
|
|
13192
|
+
return h2("button", {
|
|
13193
|
+
...props,
|
|
13194
|
+
type: props.type ?? "button",
|
|
13195
|
+
className: `dim-deliveryButton ${className}`.trim(),
|
|
13196
|
+
"data-kind": kind
|
|
13197
|
+
}, children);
|
|
13198
|
+
}
|
|
13199
|
+
function GlobalSettingsPanel({ rpcCall }) {
|
|
13200
|
+
const [phase, setPhase] = React22.useState("loading");
|
|
13201
|
+
const [loadError, setLoadError] = React22.useState(null);
|
|
13202
|
+
const [ttlInput, setTtlInput] = React22.useState("");
|
|
13203
|
+
const [savedTtl, setSavedTtl] = React22.useState(null);
|
|
13204
|
+
const [ttlError, setTtlError] = React22.useState(false);
|
|
13205
|
+
const [saveError, setSaveError] = React22.useState(null);
|
|
13206
|
+
const [saveSucceeded, setSaveSucceeded] = React22.useState(false);
|
|
13207
|
+
const [isSaving, setIsSaving] = React22.useState(false);
|
|
13208
|
+
const [sweepConfirming, setSweepConfirming] = React22.useState(false);
|
|
13209
|
+
const [sweeping, setSweeping] = React22.useState(false);
|
|
13210
|
+
const ttlErrorId = React22.useId();
|
|
13211
|
+
const ttlHintsId = React22.useId();
|
|
13212
|
+
const sweepTriggerId = React22.useId();
|
|
13213
|
+
const sweepConfirmId = React22.useId();
|
|
13214
|
+
const sweepConfirmTextId = React22.useId();
|
|
13215
|
+
const sweepConfirmButtonId = React22.useId();
|
|
13216
|
+
const mounted = React22.useRef(true);
|
|
13217
|
+
const saving = React22.useRef(false);
|
|
13218
|
+
const invoke = React22.useCallback(async (endpoint, payload = {}, signal) => {
|
|
13219
|
+
if (typeof rpcCall !== "function") throw new Error("\u901A\u7528\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
13220
|
+
return unwrapRpcResult12(await rpcCall(endpoint, payload, signal));
|
|
13221
|
+
}, [rpcCall]);
|
|
13222
|
+
const loadSettings = React22.useCallback(async ({ signal } = {}) => {
|
|
13223
|
+
setPhase("loading");
|
|
13224
|
+
setLoadError(null);
|
|
13225
|
+
try {
|
|
13226
|
+
const value = await invoke(GLOBAL_SETTINGS_ENDPOINTS.getTtl, {}, signal);
|
|
13227
|
+
if (signal?.aborted || !mounted.current) return;
|
|
13228
|
+
const ttlHours = normalizeInboundTtlHours(value?.ttlHours);
|
|
13229
|
+
if (ttlHours === null) {
|
|
13230
|
+
setLoadError("\u901A\u7528\u8BBE\u7F6E\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94\u3002");
|
|
13231
|
+
setPhase("error");
|
|
13232
|
+
return;
|
|
13233
|
+
}
|
|
13234
|
+
setSavedTtl(ttlHours);
|
|
13235
|
+
setTtlInput(String(ttlHours));
|
|
13236
|
+
setTtlError(false);
|
|
13237
|
+
setSaveError(null);
|
|
13238
|
+
setSaveSucceeded(false);
|
|
13239
|
+
setPhase("ready");
|
|
13240
|
+
} catch (caught) {
|
|
13241
|
+
if (signal?.aborted || caught?.name === "AbortError" || !mounted.current) return;
|
|
13242
|
+
setLoadError(presentError11(caught, "\u65E0\u6CD5\u8BFB\u53D6\u901A\u7528\u8BBE\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));
|
|
13243
|
+
setPhase("error");
|
|
13244
|
+
}
|
|
13245
|
+
}, [invoke]);
|
|
13246
|
+
React22.useEffect(() => {
|
|
13247
|
+
mounted.current = true;
|
|
13248
|
+
const controller = new AbortController();
|
|
13249
|
+
void loadSettings({ signal: controller.signal });
|
|
13250
|
+
return () => {
|
|
13251
|
+
mounted.current = false;
|
|
13252
|
+
controller.abort();
|
|
13253
|
+
};
|
|
13254
|
+
}, [loadSettings]);
|
|
13255
|
+
React22.useEffect(() => {
|
|
13256
|
+
if (!sweepConfirming) return;
|
|
13257
|
+
globalThis.document?.getElementById(sweepConfirmButtonId)?.focus();
|
|
13258
|
+
}, [sweepConfirmButtonId, sweepConfirming]);
|
|
13259
|
+
const commitTtl = async () => {
|
|
13260
|
+
if (phase === "loading" || saving.current) return;
|
|
13261
|
+
const proposed = normalizeInboundTtlHours(ttlInput.trim());
|
|
13262
|
+
if (proposed === null) {
|
|
13263
|
+
setSaveError(null);
|
|
13264
|
+
setSaveSucceeded(false);
|
|
13265
|
+
setTtlError(true);
|
|
13266
|
+
return;
|
|
13267
|
+
}
|
|
13268
|
+
setTtlError(false);
|
|
13269
|
+
if (proposed === savedTtl) return;
|
|
13270
|
+
saving.current = true;
|
|
13271
|
+
setIsSaving(true);
|
|
13272
|
+
setSaveError(null);
|
|
13273
|
+
setSaveSucceeded(false);
|
|
13274
|
+
try {
|
|
13275
|
+
const value = await invoke(GLOBAL_SETTINGS_ENDPOINTS.setTtl, { ttlHours: proposed });
|
|
13276
|
+
if (!mounted.current) return;
|
|
13277
|
+
const confirmed = normalizeInboundTtlHours(value?.ttlHours);
|
|
13278
|
+
const finalTtl = confirmed === null ? proposed : confirmed;
|
|
13279
|
+
setSavedTtl(finalTtl);
|
|
13280
|
+
setTtlInput((current) => current.trim() === String(proposed) ? String(finalTtl) : current);
|
|
13281
|
+
setLoadError(null);
|
|
13282
|
+
setSaveSucceeded(true);
|
|
13283
|
+
setPhase("ready");
|
|
13284
|
+
} catch (caught) {
|
|
13285
|
+
if (mounted.current) {
|
|
13286
|
+
setSaveError(presentError11(caught, "\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));
|
|
13287
|
+
}
|
|
13288
|
+
} finally {
|
|
13289
|
+
saving.current = false;
|
|
13290
|
+
if (mounted.current) setIsSaving(false);
|
|
13291
|
+
}
|
|
13292
|
+
};
|
|
13293
|
+
const requestSweep = () => {
|
|
13294
|
+
if (sweeping) return;
|
|
13295
|
+
setSweepConfirming(true);
|
|
13296
|
+
};
|
|
13297
|
+
const cancelSweep = ({ restoreFocus = false } = {}) => {
|
|
13298
|
+
setSweepConfirming(false);
|
|
13299
|
+
if (restoreFocus) globalThis.document?.getElementById(sweepTriggerId)?.focus();
|
|
13300
|
+
};
|
|
13301
|
+
const runSweep = async () => {
|
|
13302
|
+
setSweepConfirming(false);
|
|
13303
|
+
setSweeping(true);
|
|
13304
|
+
try {
|
|
13305
|
+
await invoke(GLOBAL_SETTINGS_ENDPOINTS.sweep, {});
|
|
13306
|
+
} catch {
|
|
13307
|
+
} finally {
|
|
13308
|
+
if (mounted.current) setSweeping(false);
|
|
13309
|
+
}
|
|
13310
|
+
};
|
|
13311
|
+
const inlineStatus = phase === "loading" ? { role: "status", message: "\u6B63\u5728\u8BFB\u53D6\u901A\u7528\u8BBE\u7F6E\u2026" } : ttlError ? { role: "alert", message: `\u8BF7\u8F93\u5165 -1\u30010 \u6216 1~${INBOUND_TTL_MAX_HOURS} \u4E4B\u95F4\u7684\u6574\u6570\u3002` } : saveError ? { role: "alert", message: saveError } : phase === "error" && loadError ? { role: "alert", message: loadError } : saveSucceeded ? { role: "status", message: "\u5DF2\u4FDD\u5B58" } : null;
|
|
13312
|
+
const proposedTtl = normalizeInboundTtlHours(ttlInput.trim());
|
|
13313
|
+
const canSave = phase !== "loading" && !isSaving && proposedTtl !== null && proposedTtl !== savedTtl;
|
|
13314
|
+
return h2(
|
|
13315
|
+
"section",
|
|
13316
|
+
{ className: "dim-generalSettingsPage", "aria-label": "\u901A\u7528\u8BBE\u7F6E" },
|
|
13317
|
+
h2(
|
|
13318
|
+
"header",
|
|
13319
|
+
{ className: "dim-generalSettingsHeader" },
|
|
13320
|
+
h2("h2", null, "\u901A\u7528\u8BBE\u7F6E")
|
|
13321
|
+
),
|
|
13322
|
+
h2(
|
|
13323
|
+
"div",
|
|
13324
|
+
{ className: "dim-generalSettingsTabsBar" },
|
|
13325
|
+
h2(
|
|
13326
|
+
"div",
|
|
13327
|
+
{
|
|
13328
|
+
className: "dim-generalSettingsTabs",
|
|
13329
|
+
role: "tablist",
|
|
13330
|
+
"aria-label": "\u901A\u7528\u8BBE\u7F6E\u5206\u7C7B"
|
|
13331
|
+
},
|
|
13332
|
+
h2("button", {
|
|
13333
|
+
type: "button",
|
|
13334
|
+
id: ATTACHMENTS_TAB_ID,
|
|
13335
|
+
className: "dim-generalSettingsTab",
|
|
13336
|
+
role: "tab",
|
|
13337
|
+
"aria-selected": true,
|
|
13338
|
+
"aria-controls": ATTACHMENTS_PANEL_ID
|
|
13339
|
+
}, "\u9644\u4EF6")
|
|
13340
|
+
)
|
|
13341
|
+
),
|
|
13342
|
+
h2(
|
|
13343
|
+
"div",
|
|
13344
|
+
{
|
|
13345
|
+
id: ATTACHMENTS_PANEL_ID,
|
|
13346
|
+
className: "dim-generalSettingsTabPanel",
|
|
13347
|
+
role: "tabpanel",
|
|
13348
|
+
"aria-labelledby": ATTACHMENTS_TAB_ID
|
|
13349
|
+
},
|
|
13350
|
+
h2(
|
|
13351
|
+
"section",
|
|
13352
|
+
{
|
|
13353
|
+
className: "dim-globalSection",
|
|
13354
|
+
"aria-label": "\u9644\u4EF6",
|
|
13355
|
+
"aria-busy": phase === "loading"
|
|
13356
|
+
},
|
|
13357
|
+
h2(
|
|
13358
|
+
"div",
|
|
13359
|
+
{ className: "dim-globalHead" },
|
|
13360
|
+
h2(
|
|
13361
|
+
"div",
|
|
13362
|
+
{ className: "dim-globalHeadTitle" },
|
|
13363
|
+
h2("h3", { id: "dim-globalTtlTitle" }, "\u9644\u4EF6\u4FDD\u7559\u65F6\u957F (\u5C0F\u65F6)"),
|
|
13364
|
+
h2(
|
|
13365
|
+
"div",
|
|
13366
|
+
{ className: "dim-globalTtlHelp" },
|
|
13367
|
+
h2("button", {
|
|
13368
|
+
type: "button",
|
|
13369
|
+
className: "dim-channelHelpButton dim-globalTtlHelpButton",
|
|
13370
|
+
"aria-label": "\u67E5\u770B\u9644\u4EF6\u4FDD\u7559\u65F6\u957F\u8BF4\u660E",
|
|
13371
|
+
"aria-describedby": ttlHintsId
|
|
13372
|
+
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
13373
|
+
h2(
|
|
13374
|
+
"div",
|
|
13375
|
+
{
|
|
13376
|
+
id: ttlHintsId,
|
|
13377
|
+
className: "dim-globalTtlTooltip",
|
|
13378
|
+
role: "tooltip"
|
|
13379
|
+
},
|
|
13380
|
+
h2(
|
|
13381
|
+
"ul",
|
|
13382
|
+
{ className: "dim-globalTtlHints" },
|
|
13383
|
+
h2(
|
|
13384
|
+
"li",
|
|
13385
|
+
null,
|
|
13386
|
+
h2("code", null, "-1"),
|
|
13387
|
+
h2("span", null, "\u6C38\u4E45\u4FDD\u7559\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u6E05\u7406")
|
|
13388
|
+
),
|
|
13389
|
+
h2(
|
|
13390
|
+
"li",
|
|
13391
|
+
null,
|
|
13392
|
+
h2("code", null, "0"),
|
|
13393
|
+
h2("span", null, "\u6BCF Turn \u7ED3\u675F\u540E\u7ACB\u5373\u6E05\u7406")
|
|
13394
|
+
),
|
|
13395
|
+
h2(
|
|
13396
|
+
"li",
|
|
13397
|
+
null,
|
|
13398
|
+
h2("code", null, `1~${INBOUND_TTL_MAX_HOURS}`),
|
|
13399
|
+
h2("span", null, "\u5C0F\u65F6\u540E\u81EA\u52A8\u6E05\u7406")
|
|
13400
|
+
)
|
|
13401
|
+
)
|
|
13402
|
+
)
|
|
13403
|
+
)
|
|
13404
|
+
)
|
|
13405
|
+
),
|
|
13406
|
+
h2(
|
|
13407
|
+
"form",
|
|
13408
|
+
{
|
|
13409
|
+
className: "dim-globalTtlRow",
|
|
13410
|
+
onSubmit: (event) => {
|
|
13411
|
+
event.preventDefault();
|
|
13412
|
+
void commitTtl();
|
|
13413
|
+
}
|
|
13414
|
+
},
|
|
13415
|
+
h2("input", {
|
|
13416
|
+
id: "dim-globalTtlInput",
|
|
13417
|
+
className: "dim-globalTtlInput",
|
|
13418
|
+
type: "text",
|
|
13419
|
+
value: ttlInput,
|
|
13420
|
+
placeholder: String(DEFAULT_INBOUND_TTL_HOURS),
|
|
13421
|
+
autoComplete: "off",
|
|
13422
|
+
disabled: phase === "loading" || isSaving,
|
|
13423
|
+
"aria-labelledby": "dim-globalTtlTitle",
|
|
13424
|
+
"aria-invalid": ttlError ? "true" : void 0,
|
|
13425
|
+
"aria-describedby": ttlError ? ttlErrorId : ttlHintsId,
|
|
13426
|
+
onBlur: () => {
|
|
13427
|
+
setTtlError(normalizeInboundTtlHours(ttlInput.trim()) === null);
|
|
13428
|
+
},
|
|
13429
|
+
onKeyDown: (event) => {
|
|
13430
|
+
if (event.key !== "Enter") return;
|
|
13431
|
+
event.preventDefault();
|
|
13432
|
+
void commitTtl();
|
|
13433
|
+
},
|
|
13434
|
+
onChange: (event) => {
|
|
13435
|
+
setTtlInput(event.target.value);
|
|
13436
|
+
setTtlError(false);
|
|
13437
|
+
setSaveError(null);
|
|
13438
|
+
setSaveSucceeded(false);
|
|
13439
|
+
}
|
|
13440
|
+
}),
|
|
13441
|
+
h2(GlobalButton, {
|
|
13442
|
+
type: "submit",
|
|
13443
|
+
kind: "primary",
|
|
13444
|
+
className: "dim-globalSaveButton",
|
|
13445
|
+
disabled: !canSave
|
|
13446
|
+
}, isSaving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58"),
|
|
13447
|
+
h2(
|
|
13448
|
+
"div",
|
|
13449
|
+
{
|
|
13450
|
+
className: "dim-globalSweepAction",
|
|
13451
|
+
onBlur: (event) => {
|
|
13452
|
+
if (sweepConfirming && !event.currentTarget.contains(event.relatedTarget)) cancelSweep();
|
|
13453
|
+
}
|
|
13454
|
+
},
|
|
13455
|
+
h2(GlobalButton, {
|
|
13456
|
+
id: sweepTriggerId,
|
|
13457
|
+
className: "dim-globalSweepButton",
|
|
13458
|
+
onClick: () => sweepConfirming ? cancelSweep() : requestSweep(),
|
|
13459
|
+
disabled: sweeping,
|
|
13460
|
+
"aria-haspopup": "dialog",
|
|
13461
|
+
"aria-expanded": sweepConfirming,
|
|
13462
|
+
"aria-controls": sweepConfirmId
|
|
13463
|
+
}, sweeping ? "\u6B63\u5728\u6E05\u7406\u2026" : "\u6E05\u7406\u8FC7\u671F\u9644\u4EF6"),
|
|
13464
|
+
sweepConfirming ? h2(
|
|
13465
|
+
"div",
|
|
13466
|
+
{
|
|
13467
|
+
id: sweepConfirmId,
|
|
13468
|
+
className: "dim-globalSweepConfirm",
|
|
13469
|
+
role: "alertdialog",
|
|
13470
|
+
"aria-label": "\u786E\u8BA4\u6E05\u7406\u8FC7\u671F\u9644\u4EF6",
|
|
13471
|
+
"aria-describedby": sweepConfirmTextId,
|
|
13472
|
+
onKeyDown: (event) => {
|
|
13473
|
+
if (event.key !== "Escape") return;
|
|
13474
|
+
event.preventDefault();
|
|
13475
|
+
cancelSweep({ restoreFocus: true });
|
|
13476
|
+
}
|
|
13477
|
+
},
|
|
13478
|
+
h2("p", { id: sweepConfirmTextId }, "\u786E\u8BA4\u6E05\u7406\u5F53\u524D\u5DF2\u8FC7\u671F\u7684\u9644\u4EF6\uFF1F"),
|
|
13479
|
+
h2(
|
|
13480
|
+
"div",
|
|
13481
|
+
{ className: "dim-globalSweepConfirmActions" },
|
|
13482
|
+
h2(GlobalButton, { onClick: () => cancelSweep({ restoreFocus: true }) }, "\u53D6\u6D88"),
|
|
13483
|
+
h2(GlobalButton, {
|
|
13484
|
+
id: sweepConfirmButtonId,
|
|
13485
|
+
kind: "danger",
|
|
13486
|
+
className: "dim-globalSweepConfirmButton",
|
|
13487
|
+
onClick: () => void runSweep()
|
|
13488
|
+
}, "\u786E\u8BA4\u6E05\u7406")
|
|
13489
|
+
)
|
|
13490
|
+
) : null
|
|
13491
|
+
),
|
|
13492
|
+
inlineStatus ? h2("p", {
|
|
13493
|
+
id: ttlErrorId,
|
|
13494
|
+
className: "dim-globalInline",
|
|
13495
|
+
"data-tone": inlineStatus.role === "alert" ? "error" : void 0,
|
|
13496
|
+
role: inlineStatus.role,
|
|
13497
|
+
"aria-live": inlineStatus.role === "status" ? "polite" : void 0
|
|
13498
|
+
}, inlineStatus.message) : null
|
|
13499
|
+
)
|
|
13500
|
+
)
|
|
13501
|
+
)
|
|
13502
|
+
);
|
|
13503
|
+
}
|
|
13504
|
+
|
|
13031
13505
|
// plugin-src/client/loopback-recovery.js
|
|
13032
13506
|
var TRANSPORT_FORBIDDEN = /^transport failure for \/[A-Za-z0-9._~-]+\/[A-Za-z0-9_$./~-]+: HTTP 403$/;
|
|
13033
13507
|
var LOOPBACK_RECOVERY_ERROR_CODE = "loopback-recovery-required";
|
|
@@ -13146,6 +13620,15 @@ var CSS11 = String.raw`
|
|
|
13146
13620
|
.dim-githubArrow { font-size: 13px; line-height: 1; }
|
|
13147
13621
|
.dim-githubTooltip { position: absolute; top: calc(100% + 8px); right: 0; z-index: 20; width: max-content; max-width: min(220px, 80vw); padding: 6px 9px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 8px 24px rgb(31 35 41 / 14%); font-size: 11px; line-height: 16px; font-weight: 500; white-space: nowrap; opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
|
|
13148
13622
|
.dim-githubAction:hover .dim-githubTooltip, .dim-githubAction:focus-within .dim-githubTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
13623
|
+
.dim-generalSettingsAction { position: relative; display: inline-flex; flex: none; }
|
|
13624
|
+
.dim-generalSettingsButton { width: 30px; height: 30px; display: grid; place-items: center; flex: none; padding: 0; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-layer-1, #fff); cursor: pointer; transition: border-color .15s ease, color .15s ease, background .15s ease, box-shadow .15s ease; }
|
|
13625
|
+
.dim-generalSettingsButton svg { display: block; }
|
|
13626
|
+
.dim-generalSettingsButton:hover { border-color: #aeb3bb; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
|
|
13627
|
+
.dim-generalSettingsButton[aria-current="page"] { border-color: color-mix(in srgb, var(--dim-blue) 42%, var(--dsw-alias-border-l2, #dfe1e5)); color: var(--dim-blue); background: var(--dim-blue-soft); }
|
|
13628
|
+
.dim-generalSettingsButton:focus-visible { outline: 2px solid color-mix(in srgb, var(--dim-blue) 70%, white); outline-offset: 2px; }
|
|
13629
|
+
.dim-generalSettingsTooltip { position: absolute; top: calc(100% + 8px); right: 0; z-index: 20; width: max-content; padding: 6px 9px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 8px 24px rgb(31 35 41 / 14%); font-size: 11px; line-height: 16px; font-weight: 500; white-space: nowrap; opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
|
|
13630
|
+
.dim-generalSettingsAction:hover .dim-generalSettingsTooltip, .dim-generalSettingsButton:focus-visible + .dim-generalSettingsTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
13631
|
+
.dim-generalSettingsButton[aria-current="page"] + .dim-generalSettingsTooltip { opacity: 0; visibility: hidden; transform: translateY(-3px); }
|
|
13149
13632
|
.dim-layout { display: grid; grid-template-columns: 174px 1px minmax(0, 1fr); gap: 24px; align-items: start; }
|
|
13150
13633
|
.dim-rail { max-height: 520px; display: grid; align-content: start; gap: 8px; overflow-y: auto; padding: 0 4px 1px 1px; scrollbar-width: thin; scrollbar-color: var(--dsw-alias-border-l2, #dfe1e5) transparent; }
|
|
13151
13634
|
.dim-rail::-webkit-scrollbar { width: 4px; }
|
|
@@ -13553,6 +14036,46 @@ var CSS11 = String.raw`
|
|
|
13553
14036
|
.dim-accessFeedback[data-tone="success"] { color: var(--dsw-alias-state-success-primary, #20a162); }
|
|
13554
14037
|
.dim-accessFeedback[data-tone="error"] { color: var(--dsw-alias-state-error-primary, #d54941); }
|
|
13555
14038
|
.dim-accessActions { display: flex; justify-content: flex-end; }
|
|
14039
|
+
.dim-generalSettingsPage { min-width: 0; display: grid; }
|
|
14040
|
+
.dim-generalSettingsHeader { min-width: 0; margin: 0 0 8px; }
|
|
14041
|
+
.dim-generalSettingsHeader h2 { margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 18px; line-height: 25px; font-weight: 680; }
|
|
14042
|
+
.dim-generalSettingsTabsBar { min-width: 0; border-bottom: 1px solid var(--dsw-alias-border-l2, #dfe1e5); }
|
|
14043
|
+
.dim-generalSettingsTabs { min-width: 0; display: flex; align-items: flex-end; gap: 24px; overflow-x: auto; scrollbar-width: none; }
|
|
14044
|
+
.dim-generalSettingsTabs::-webkit-scrollbar { display: none; }
|
|
14045
|
+
.dim-generalSettingsTab { position: relative; min-height: 38px; flex: none; display: inline-flex; align-items: center; justify-content: center; padding: 6px 2px 9px; border: 0; color: var(--dsw-alias-label-secondary, #646a73); background: transparent; font: inherit; font-size: 13px; line-height: 20px; font-weight: 560; white-space: nowrap; cursor: pointer; transition: color .15s ease; }
|
|
14046
|
+
.dim-generalSettingsTab::after { content: ''; position: absolute; right: 0; bottom: -1px; left: 0; height: 2px; border-radius: 2px 2px 0 0; background: transparent; transform: scaleX(.45); transition: background .15s ease, transform .15s ease; }
|
|
14047
|
+
.dim-generalSettingsTab:hover:not([aria-selected="true"]) { color: var(--dsw-alias-label-primary, #1f2329); }
|
|
14048
|
+
.dim-generalSettingsTab[aria-selected="true"] { color: var(--dim-blue); font-weight: 650; }
|
|
14049
|
+
.dim-generalSettingsTab[aria-selected="true"]::after { background: var(--dim-blue); transform: scaleX(1); }
|
|
14050
|
+
.dim-generalSettingsTab:focus-visible { outline: 2px solid var(--dim-blue); outline-offset: -2px; border-radius: 5px; }
|
|
14051
|
+
.dim-generalSettingsTabPanel { min-width: 0; padding-top: 14px; }
|
|
14052
|
+
.dim-globalSection { min-width: 0; padding: 14px 16px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 12px; background: var(--dsw-alias-bg-layer-3, #fff); }
|
|
14053
|
+
.dim-globalHead { min-width: 0; display: flex; align-items: center; }
|
|
14054
|
+
.dim-globalHeadTitle { min-width: 0; display: inline-flex; align-items: center; gap: 6px; }
|
|
14055
|
+
.dim-globalHead h3 { min-width: 0; overflow: hidden; margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 15px; line-height: 22px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
|
|
14056
|
+
.dim-globalTtlHelp { position: relative; display: inline-flex; flex: none; }
|
|
14057
|
+
.dim-globalTtlTooltip { position: absolute; top: calc(100% + 7px); left: 0; z-index: 30; width: max-content; max-width: min(280px, calc(100vw - 48px)); padding: 9px 10px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 10px 28px rgb(31 35 41 / 16%); opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
|
|
14058
|
+
.dim-globalTtlHelp:hover .dim-globalTtlTooltip, .dim-globalTtlHelpButton:focus-visible + .dim-globalTtlTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
14059
|
+
.dim-globalTtlHints { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
|
|
14060
|
+
.dim-globalTtlHints li { min-width: 0; display: flex; align-items: baseline; gap: 8px; }
|
|
14061
|
+
.dim-globalTtlHints code { flex: none; min-width: 44px; padding: 0 6px; border-radius: 5px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-module-platform, #f7f8fa); font: 10px/16px ui-monospace, SFMono-Regular, Menlo, monospace; text-align: center; }
|
|
14062
|
+
.dim-globalTtlHints span { min-width: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; }
|
|
14063
|
+
.dim-globalTtlRow { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; margin-top: 12px; }
|
|
14064
|
+
.dim-globalTtlInput { width: min(160px, 100%); min-width: 110px; max-width: 160px; flex: 1 1 130px; height: 34px; 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: 13px ui-monospace, SFMono-Regular, Menlo, monospace; transition: border-color .16s ease, box-shadow .16s ease; }
|
|
14065
|
+
.dim-globalTtlInput:hover:not(:disabled) { border-color: var(--dsw-alias-border-l3, #bbbfc4); }
|
|
14066
|
+
.dim-globalTtlInput:focus { outline: none; border-color: var(--dim-blue); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dim-blue) 14%, transparent); }
|
|
14067
|
+
.dim-globalTtlInput[aria-invalid="true"] { border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 62%, var(--dsw-alias-border-l2, #dfe1e5)); }
|
|
14068
|
+
.dim-globalTtlInput:disabled { cursor: not-allowed; opacity: .55; }
|
|
14069
|
+
.dim-globalSaveButton { min-width: 58px; min-height: 34px; }
|
|
14070
|
+
.dim-globalSweepAction { position: relative; display: inline-flex; flex: none; margin-left: auto; }
|
|
14071
|
+
.dim-globalSweepButton { flex: none; }
|
|
14072
|
+
.dim-globalSweepConfirm { position: absolute; top: calc(100% + 8px); right: 0; z-index: 35; width: 218px; padding: 11px 12px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 12px 30px rgb(31 35 41 / 18%); }
|
|
14073
|
+
.dim-globalSweepConfirm p { margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; line-height: 18px; }
|
|
14074
|
+
.dim-globalSweepConfirmActions { display: flex; justify-content: flex-end; gap: 7px; margin-top: 10px; }
|
|
14075
|
+
.dim-deliveryButton.dim-globalSweepConfirmButton { border-color: var(--dsw-alias-state-error-primary, #d54941); color: #fff; background: var(--dsw-alias-state-error-primary, #d54941); }
|
|
14076
|
+
.dim-deliveryButton.dim-globalSweepConfirmButton:hover:not(:disabled) { border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 82%, #000); background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d54941) 88%, #000); }
|
|
14077
|
+
.dim-globalInline { flex: 1 0 100%; min-width: 0; margin: 2px 0 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; overflow-wrap: anywhere; }
|
|
14078
|
+
.dim-globalInline[data-tone="error"] { color: var(--dsw-alias-state-error-primary, #d54941); }
|
|
13556
14079
|
.dim-panel .dim-botCard .dim-cardFooter { margin-top: 0; }
|
|
13557
14080
|
.dim-panel .ddt-headingCopy { display: none; }
|
|
13558
14081
|
.dim-panel .ddt-qrFrame, .dim-panel .ddt-countdown { width: min(270px, 100%); }
|
|
@@ -13637,7 +14160,7 @@ function installImStyles() {
|
|
|
13637
14160
|
}
|
|
13638
14161
|
|
|
13639
14162
|
// plugin-src/client/update-panel.js
|
|
13640
|
-
var
|
|
14163
|
+
var React23 = __toESM(require("react"), 1);
|
|
13641
14164
|
var import_react_dom3 = require("react-dom");
|
|
13642
14165
|
var import_valid = __toESM(require_valid(), 1);
|
|
13643
14166
|
var import_rcompare = __toESM(require_rcompare(), 1);
|
|
@@ -13684,7 +14207,7 @@ function unwrapSnapshot(result) {
|
|
|
13684
14207
|
}
|
|
13685
14208
|
return value;
|
|
13686
14209
|
}
|
|
13687
|
-
function
|
|
14210
|
+
function presentError12(error) {
|
|
13688
14211
|
const code = error?.rpcError?.code ?? error?.code ?? "";
|
|
13689
14212
|
const message = error?.rpcError?.message ?? error?.message ?? "";
|
|
13690
14213
|
if (code === "update-unavailable" || /(?:not[-_ ]found|unimplemented|unknown[-_ ](?:endpoint|channel)|no[-_ ]handler)/i.test(code) || /(?:not found|unknown (?:endpoint|channel)|not registered|no .*handler|HTTP 404)/i.test(message)) {
|
|
@@ -13727,11 +14250,11 @@ function manualUpdateCommand(snapshot) {
|
|
|
13727
14250
|
return `dsh plugin --profile ${profileArgument} add -w @xmanrui/dsh-im@${version}`;
|
|
13728
14251
|
}
|
|
13729
14252
|
function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
13730
|
-
const [copyState, setCopyState] =
|
|
13731
|
-
const commandRef =
|
|
13732
|
-
const mounted =
|
|
13733
|
-
const copying =
|
|
13734
|
-
|
|
14253
|
+
const [copyState, setCopyState] = React23.useState("idle");
|
|
14254
|
+
const commandRef = React23.useRef(null);
|
|
14255
|
+
const mounted = React23.useRef(false);
|
|
14256
|
+
const copying = React23.useRef(false);
|
|
14257
|
+
React23.useEffect(() => {
|
|
13735
14258
|
mounted.current = true;
|
|
13736
14259
|
return () => {
|
|
13737
14260
|
mounted.current = false;
|
|
@@ -13763,7 +14286,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
13763
14286
|
{ className: "dim-updateManual", "aria-label": "\u624B\u5DE5\u66F4\u65B0" },
|
|
13764
14287
|
h2("h4", { className: "dim-updateManualHeading" }, "\u624B\u5DE5\u66F4\u65B0"),
|
|
13765
14288
|
command ? h2(
|
|
13766
|
-
|
|
14289
|
+
React23.Fragment,
|
|
13767
14290
|
null,
|
|
13768
14291
|
h2("p", { className: "dim-updateManualHint" }, "\u81EA\u52A8\u66F4\u65B0\u5931\u8D25\u53EF\u4EE5\u4F7F\u7528\u547D\u4EE4\u66F4\u65B0\uFF1A"),
|
|
13769
14292
|
h2(
|
|
@@ -13799,7 +14322,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
13799
14322
|
"aria-hidden": "true",
|
|
13800
14323
|
focusable: "false"
|
|
13801
14324
|
}, copyState === "copied" ? h2("path", { d: "m4 10 4 4 8-8" }) : h2(
|
|
13802
|
-
|
|
14325
|
+
React23.Fragment,
|
|
13803
14326
|
null,
|
|
13804
14327
|
h2("rect", { x: 7, y: 7, width: 10, height: 11, rx: 1.5 }),
|
|
13805
14328
|
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" })
|
|
@@ -13824,10 +14347,10 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
13824
14347
|
);
|
|
13825
14348
|
}
|
|
13826
14349
|
function UpdateDialog({ children, onClose }) {
|
|
13827
|
-
const dialogRef =
|
|
13828
|
-
const titleId =
|
|
13829
|
-
const descriptionId =
|
|
13830
|
-
|
|
14350
|
+
const dialogRef = React23.useRef(null);
|
|
14351
|
+
const titleId = React23.useId();
|
|
14352
|
+
const descriptionId = React23.useId();
|
|
14353
|
+
React23.useEffect(() => {
|
|
13831
14354
|
const previous = globalThis.document?.activeElement;
|
|
13832
14355
|
dialogRef.current?.focus?.();
|
|
13833
14356
|
return () => {
|
|
@@ -13885,19 +14408,19 @@ function UpdateDialog({ children, onClose }) {
|
|
|
13885
14408
|
return typeof document !== "undefined" && document.body ? (0, import_react_dom3.createPortal)(content, document.body) : content;
|
|
13886
14409
|
}
|
|
13887
14410
|
function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
13888
|
-
const [snapshot, setSnapshot] =
|
|
13889
|
-
const [action, setAction] =
|
|
13890
|
-
const [error, setError] =
|
|
13891
|
-
const [open, setOpen] =
|
|
13892
|
-
const [uncertainInstall, setUncertainInstall] =
|
|
13893
|
-
const mounted =
|
|
13894
|
-
const busy =
|
|
13895
|
-
const readController =
|
|
13896
|
-
const pollReadController =
|
|
13897
|
-
const installRequest =
|
|
13898
|
-
const onStatusRef =
|
|
14411
|
+
const [snapshot, setSnapshot] = React23.useState(null);
|
|
14412
|
+
const [action, setAction] = React23.useState("status");
|
|
14413
|
+
const [error, setError] = React23.useState(null);
|
|
14414
|
+
const [open, setOpen] = React23.useState(false);
|
|
14415
|
+
const [uncertainInstall, setUncertainInstall] = React23.useState(false);
|
|
14416
|
+
const mounted = React23.useRef(false);
|
|
14417
|
+
const busy = React23.useRef(false);
|
|
14418
|
+
const readController = React23.useRef(null);
|
|
14419
|
+
const pollReadController = React23.useRef(null);
|
|
14420
|
+
const installRequest = React23.useRef(null);
|
|
14421
|
+
const onStatusRef = React23.useRef(onStatus);
|
|
13899
14422
|
onStatusRef.current = onStatus;
|
|
13900
|
-
const accept =
|
|
14423
|
+
const accept = React23.useCallback((next) => {
|
|
13901
14424
|
setSnapshot(next);
|
|
13902
14425
|
onStatusRef.current?.(next);
|
|
13903
14426
|
}, []);
|
|
@@ -13906,7 +14429,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
13906
14429
|
setUncertainInstall(false);
|
|
13907
14430
|
accept(next);
|
|
13908
14431
|
};
|
|
13909
|
-
const invoke =
|
|
14432
|
+
const invoke = React23.useCallback(async (endpoint, payload = {}, signal) => {
|
|
13910
14433
|
if (typeof rpcCall !== "function") {
|
|
13911
14434
|
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");
|
|
13912
14435
|
unavailable.code = "update-unavailable";
|
|
@@ -13914,14 +14437,14 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
13914
14437
|
}
|
|
13915
14438
|
return unwrapSnapshot(await rpcCall(endpoint, payload, signal));
|
|
13916
14439
|
}, [rpcCall]);
|
|
13917
|
-
|
|
14440
|
+
React23.useEffect(() => {
|
|
13918
14441
|
mounted.current = true;
|
|
13919
14442
|
busy.current = true;
|
|
13920
14443
|
const controller = new AbortController();
|
|
13921
14444
|
void invoke("update.status", {}, controller.signal).then((next) => {
|
|
13922
14445
|
if (!controller.signal.aborted) accept(next);
|
|
13923
14446
|
}).catch((cause) => {
|
|
13924
|
-
if (!controller.signal.aborted) setError(
|
|
14447
|
+
if (!controller.signal.aborted) setError(presentError12(cause));
|
|
13925
14448
|
}).finally(() => {
|
|
13926
14449
|
if (!controller.signal.aborted) {
|
|
13927
14450
|
busy.current = false;
|
|
@@ -13937,7 +14460,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
13937
14460
|
const activeJob = ACTIVE_STATES4.has(snapshot?.job?.state);
|
|
13938
14461
|
const restartRequired = snapshot?.job?.state === "restart-required" || snapshot?.blockedReason === "pending-restart";
|
|
13939
14462
|
const shouldPoll = activeJob || uncertainInstall;
|
|
13940
|
-
|
|
14463
|
+
React23.useEffect(() => {
|
|
13941
14464
|
if (!shouldPoll) return void 0;
|
|
13942
14465
|
let controller;
|
|
13943
14466
|
const scheduler = createPollScheduler({
|
|
@@ -13958,7 +14481,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
13958
14481
|
keepPolling = ACTIVE_STATES4.has(next.job?.state);
|
|
13959
14482
|
}
|
|
13960
14483
|
} catch (cause) {
|
|
13961
|
-
if (!pendingController.signal.aborted) setError(
|
|
14484
|
+
if (!pendingController.signal.aborted) setError(presentError12(cause));
|
|
13962
14485
|
} finally {
|
|
13963
14486
|
if (pollReadController.current === pendingController) pollReadController.current = null;
|
|
13964
14487
|
}
|
|
@@ -13989,7 +14512,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
13989
14512
|
else acceptAuthoritative(next);
|
|
13990
14513
|
}
|
|
13991
14514
|
} catch (cause) {
|
|
13992
|
-
if (!controller.signal.aborted && mounted.current) setError(
|
|
14515
|
+
if (!controller.signal.aborted && mounted.current) setError(presentError12(cause));
|
|
13993
14516
|
} finally {
|
|
13994
14517
|
if (!controller.signal.aborted && mounted.current) {
|
|
13995
14518
|
busy.current = false;
|
|
@@ -14015,7 +14538,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
14015
14538
|
if (mounted.current) acceptAuthoritative(next);
|
|
14016
14539
|
} catch (cause) {
|
|
14017
14540
|
if (mounted.current) {
|
|
14018
|
-
setError(
|
|
14541
|
+
setError(presentError12(cause));
|
|
14019
14542
|
setUncertainInstall(true);
|
|
14020
14543
|
}
|
|
14021
14544
|
} finally {
|
|
@@ -14035,7 +14558,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
14035
14558
|
const manualCommand = manualUpdateCommand(snapshot);
|
|
14036
14559
|
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";
|
|
14037
14560
|
return h2(
|
|
14038
|
-
|
|
14561
|
+
React23.Fragment,
|
|
14039
14562
|
null,
|
|
14040
14563
|
h2("button", {
|
|
14041
14564
|
type: "button",
|
|
@@ -14060,13 +14583,13 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
14060
14583
|
h2("dt", null, "\u8FD0\u884C\u7248\u672C"),
|
|
14061
14584
|
h2("dd", null, `v${snapshot?.runningVersion ?? clientVersion}`),
|
|
14062
14585
|
snapshot?.installedVersion && snapshot.installedVersion !== snapshot.runningVersion ? h2(
|
|
14063
|
-
|
|
14586
|
+
React23.Fragment,
|
|
14064
14587
|
null,
|
|
14065
14588
|
h2("dt", null, "\u5DF2\u5B89\u88C5\u7248\u672C"),
|
|
14066
14589
|
h2("dd", null, `v${snapshot.installedVersion}`)
|
|
14067
14590
|
) : null,
|
|
14068
14591
|
targetVersion ? h2(
|
|
14069
|
-
|
|
14592
|
+
React23.Fragment,
|
|
14070
14593
|
null,
|
|
14071
14594
|
h2("dt", null, "\u76EE\u6807\u7248\u672C"),
|
|
14072
14595
|
h2("dd", null, `v${targetVersion}`)
|
|
@@ -14266,23 +14789,28 @@ function IMSettingsTab({
|
|
|
14266
14789
|
officeRpcCall,
|
|
14267
14790
|
updateRpcCall,
|
|
14268
14791
|
deliveryRpcCall,
|
|
14792
|
+
globalSettingsRpcCall,
|
|
14269
14793
|
workspaceDirectoryPicker,
|
|
14270
14794
|
browserLocation = globalThis.location,
|
|
14271
14795
|
navigateToRecoveryUrl = replacePageLocation
|
|
14272
14796
|
}) {
|
|
14273
|
-
const [selected, setSelected] =
|
|
14274
|
-
const [loopbackRecovery, setLoopbackRecovery] =
|
|
14275
|
-
const [runningVersion, setRunningVersion] =
|
|
14276
|
-
const [deliverySettings, setDeliverySettings] =
|
|
14277
|
-
const githubTooltipId =
|
|
14797
|
+
const [selected, setSelected] = React24.useState("weixin");
|
|
14798
|
+
const [loopbackRecovery, setLoopbackRecovery] = React24.useState(null);
|
|
14799
|
+
const [runningVersion, setRunningVersion] = React24.useState(IM_PLUGIN_VERSION);
|
|
14800
|
+
const [deliverySettings, setDeliverySettings] = React24.useState(null);
|
|
14801
|
+
const githubTooltipId = React24.useId();
|
|
14802
|
+
const generalSettingsTooltipId = React24.useId();
|
|
14803
|
+
const globalSettingsSelected = selected === GLOBAL_SETTINGS_TAB_ID;
|
|
14278
14804
|
const active = CHANNELS.find((channel4) => channel4.id === selected) ?? CHANNELS[0];
|
|
14279
|
-
const
|
|
14805
|
+
const activeTabId = globalSettingsSelected ? "dim-general-settings-trigger" : `dim-tab-${active.id}`;
|
|
14806
|
+
const activePanelId = globalSettingsSelected ? `dim-panel-${GLOBAL_SETTINGS_TAB_ID}` : `dim-panel-${active.id}`;
|
|
14807
|
+
const reportLoopbackRecovery = React24.useCallback((recovery) => {
|
|
14280
14808
|
setLoopbackRecovery((current) => current?.url === recovery.url ? current : recovery);
|
|
14281
14809
|
}, []);
|
|
14282
|
-
const reportUpdateStatus =
|
|
14810
|
+
const reportUpdateStatus = React24.useCallback((snapshot) => {
|
|
14283
14811
|
setRunningVersion(snapshot.runningVersion);
|
|
14284
14812
|
}, []);
|
|
14285
|
-
const rpcCalls =
|
|
14813
|
+
const rpcCalls = React24.useMemo(() => createLoopbackAwareRpcCalls({
|
|
14286
14814
|
dingtalkRpcCall,
|
|
14287
14815
|
discordRpcCall,
|
|
14288
14816
|
feishuRpcCall,
|
|
@@ -14294,7 +14822,8 @@ function IMSettingsTab({
|
|
|
14294
14822
|
whatsappRpcCall,
|
|
14295
14823
|
officeRpcCall,
|
|
14296
14824
|
updateRpcCall,
|
|
14297
|
-
deliveryRpcCall
|
|
14825
|
+
deliveryRpcCall,
|
|
14826
|
+
globalSettingsRpcCall
|
|
14298
14827
|
}, {
|
|
14299
14828
|
location: browserLocation,
|
|
14300
14829
|
onRecovery: reportLoopbackRecovery
|
|
@@ -14304,6 +14833,7 @@ function IMSettingsTab({
|
|
|
14304
14833
|
discordRpcCall,
|
|
14305
14834
|
deliveryRpcCall,
|
|
14306
14835
|
feishuRpcCall,
|
|
14836
|
+
globalSettingsRpcCall,
|
|
14307
14837
|
officeRpcCall,
|
|
14308
14838
|
qqRpcCall,
|
|
14309
14839
|
reportLoopbackRecovery,
|
|
@@ -14314,7 +14844,7 @@ function IMSettingsTab({
|
|
|
14314
14844
|
weixinRpcCall,
|
|
14315
14845
|
whatsappRpcCall
|
|
14316
14846
|
]);
|
|
14317
|
-
const botSettingsContext =
|
|
14847
|
+
const botSettingsContext = React24.useMemo(() => Object.freeze({
|
|
14318
14848
|
openBotSettings: setDeliverySettings
|
|
14319
14849
|
}), []);
|
|
14320
14850
|
return h2(
|
|
@@ -14366,6 +14896,28 @@ function IMSettingsTab({
|
|
|
14366
14896
|
className: "dim-githubTooltip",
|
|
14367
14897
|
role: "tooltip"
|
|
14368
14898
|
}, "\u5E2E\u52A9\u4E0E\u53CD\u9988 \xB7 \u524D\u5F80 GitHub")
|
|
14899
|
+
),
|
|
14900
|
+
h2(
|
|
14901
|
+
"span",
|
|
14902
|
+
{ className: "dim-generalSettingsAction" },
|
|
14903
|
+
h2("button", {
|
|
14904
|
+
type: "button",
|
|
14905
|
+
id: "dim-general-settings-trigger",
|
|
14906
|
+
className: "dim-generalSettingsButton",
|
|
14907
|
+
"aria-label": "\u901A\u7528\u8BBE\u7F6E",
|
|
14908
|
+
"aria-describedby": generalSettingsTooltipId,
|
|
14909
|
+
"aria-controls": `dim-panel-${GLOBAL_SETTINGS_TAB_ID}`,
|
|
14910
|
+
"aria-current": globalSettingsSelected ? "page" : void 0,
|
|
14911
|
+
onClick: () => {
|
|
14912
|
+
setSelected(GLOBAL_SETTINGS_TAB_ID);
|
|
14913
|
+
setDeliverySettings(null);
|
|
14914
|
+
}
|
|
14915
|
+
}, h2(GlobalSettingsLogoGlyph, { size: 17 })),
|
|
14916
|
+
h2("span", {
|
|
14917
|
+
id: generalSettingsTooltipId,
|
|
14918
|
+
className: "dim-generalSettingsTooltip",
|
|
14919
|
+
role: "tooltip"
|
|
14920
|
+
}, "\u901A\u7528\u8BBE\u7F6E")
|
|
14369
14921
|
)
|
|
14370
14922
|
)
|
|
14371
14923
|
),
|
|
@@ -14374,7 +14926,7 @@ function IMSettingsTab({
|
|
|
14374
14926
|
{ className: "dim-layout" },
|
|
14375
14927
|
h2(
|
|
14376
14928
|
"nav",
|
|
14377
|
-
{ className: "dim-rail", role: "tablist", "aria-label": "IM \
|
|
14929
|
+
{ className: "dim-rail", role: "tablist", "aria-label": "IM \u8BBE\u7F6E\u5BFC\u822A" },
|
|
14378
14930
|
CHANNELS.map((channel4) => h2(
|
|
14379
14931
|
"button",
|
|
14380
14932
|
{
|
|
@@ -14383,7 +14935,7 @@ function IMSettingsTab({
|
|
|
14383
14935
|
role: "tab",
|
|
14384
14936
|
id: `dim-tab-${channel4.id}`,
|
|
14385
14937
|
className: "dim-channel",
|
|
14386
|
-
"aria-selected": channel4.id === active.id,
|
|
14938
|
+
"aria-selected": !globalSettingsSelected && channel4.id === active.id,
|
|
14387
14939
|
"aria-controls": `dim-panel-${channel4.id}`,
|
|
14388
14940
|
onClick: () => {
|
|
14389
14941
|
setSelected(channel4.id);
|
|
@@ -14405,8 +14957,8 @@ function IMSettingsTab({
|
|
|
14405
14957
|
{
|
|
14406
14958
|
className: "dim-panel",
|
|
14407
14959
|
role: "tabpanel",
|
|
14408
|
-
id:
|
|
14409
|
-
"aria-labelledby":
|
|
14960
|
+
id: activePanelId,
|
|
14961
|
+
"aria-labelledby": activeTabId
|
|
14410
14962
|
},
|
|
14411
14963
|
loopbackRecovery ? h2(LoopbackRecoveryNotice, {
|
|
14412
14964
|
recovery: loopbackRecovery,
|
|
@@ -14415,7 +14967,7 @@ function IMSettingsTab({
|
|
|
14415
14967
|
h2(
|
|
14416
14968
|
BotSettingsContext.Provider,
|
|
14417
14969
|
{ value: botSettingsContext },
|
|
14418
|
-
deliverySettings?.channel === active.id ? h2(DeliveryTargetSettingsPage, {
|
|
14970
|
+
globalSettingsSelected ? h2(GlobalSettingsPanel, { rpcCall: rpcCalls.globalSettingsRpcCall }) : deliverySettings?.channel === active.id ? h2(DeliveryTargetSettingsPage, {
|
|
14419
14971
|
channel: active.id,
|
|
14420
14972
|
account: deliverySettings,
|
|
14421
14973
|
rpcCall: rpcCalls.deliveryRpcCall,
|
|
@@ -14464,6 +15016,7 @@ function apply(ctx) {
|
|
|
14464
15016
|
const officeRpcCall = (endpoint, payload, signal) => ctx.connection.rpc.call(OFFICE_RPC_CHANNEL, endpoint, payload, signal);
|
|
14465
15017
|
const updateRpcCall = (endpoint, payload, signal) => ctx.connection.rpc.call(UPDATE_RPC_CHANNEL, endpoint, payload, signal);
|
|
14466
15018
|
const deliveryRpcCall = (endpoint, payload, signal) => ctx.connection.rpc.call(DELIVERY_RPC_CHANNEL, endpoint, payload, signal);
|
|
15019
|
+
const globalSettingsRpcCall = (endpoint, payload, signal) => ctx.connection.rpc.call(GLOBAL_SETTINGS_RPC_CHANNEL, endpoint, payload, signal);
|
|
14467
15020
|
const workspaceDirectoryPicker = Object.freeze({
|
|
14468
15021
|
listDirectory: (path, signal) => callWorkspaceDirectoryApi(ctx, "listDirectory", path, signal),
|
|
14469
15022
|
pickDirectory: () => callWorkspaceDirectoryApi(ctx, "pickDirectory")
|
|
@@ -14487,6 +15040,7 @@ function apply(ctx) {
|
|
|
14487
15040
|
officeRpcCall,
|
|
14488
15041
|
updateRpcCall,
|
|
14489
15042
|
deliveryRpcCall,
|
|
15043
|
+
globalSettingsRpcCall,
|
|
14490
15044
|
workspaceDirectoryPicker
|
|
14491
15045
|
})
|
|
14492
15046
|
}, IMSettingsTab));
|