mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-12 21:40:50 +08:00
fix: preserve Telegram compatibility and stabilize Office
This commit is contained in:
parent
7f114e1c36
commit
24e690498b
23 changed files with 1679 additions and 314 deletions
365
lib/client.js
365
lib/client.js
|
|
@ -40,7 +40,7 @@ __export(index_exports, {
|
|||
name: () => name
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
var React17 = __toESM(require("react"), 1);
|
||||
var React18 = __toESM(require("react"), 1);
|
||||
|
||||
// plugin-src/client/channel-logos.js
|
||||
var React = __toESM(require("react"), 1);
|
||||
|
|
@ -671,6 +671,28 @@ var EN = Object.freeze({
|
|||
"\u63A5\u5165 Telegram \u673A\u5668\u4EBA": "Connect a Telegram bot",
|
||||
"\u5148\u901A\u8FC7 @BotFather \u83B7\u53D6 Bot Token\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002": "Get a Bot Token from @BotFather, then connect it here.",
|
||||
"\u586B\u5199 @BotFather \u751F\u6210\u7684 Bot Token": "Enter the Bot Token from @BotFather",
|
||||
"\u8BBF\u95EE\u6A21\u5F0F": "Access mode",
|
||||
"\u8BBF\u95EE\u8BBE\u7F6E": "Access settings",
|
||||
"Telegram \u8BBF\u95EE\u6A21\u5F0F": "Telegram access mode",
|
||||
"\u7FA4\u804A\u5168\u90E8\u5FFD\u7565\uFF0C\u79C1\u804A\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u7528\u6237\u3002": "All group messages are ignored; only allowlisted users may send DMs.",
|
||||
"\u4FDD\u6301\u539F\u6709\u884C\u4E3A\uFF1A\u79C1\u804A\u76F4\u63A5\u54CD\u5E94\uFF0C\u7FA4\u804A\u5728\u88AB\u63D0\u53CA\u6216\u56DE\u590D\u65F6\u54CD\u5E94\u3002": "Keep the original behavior: respond to DMs and to group mentions or replies.",
|
||||
"\u5B89\u5168\u6A21\u5F0F": "Safe mode",
|
||||
"\u517C\u5BB9\u6A21\u5F0F": "Compatible mode",
|
||||
"\u5DF2\u751F\u6548\uFF1A\u5B89\u5168\u6A21\u5F0F": "Active: Safe mode",
|
||||
"\u5DF2\u751F\u6548\uFF1A\u517C\u5BB9\u6A21\u5F0F": "Active: Compatible mode",
|
||||
"\u6A21\u5F0F": "Mode",
|
||||
"\u517C\u5BB9\u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF09": "Compatible mode (default)",
|
||||
"\u5B89\u5168\u6A21\u5F0F\uFF08\u79C1\u804A\u767D\u540D\u5355\uFF09": "Safe mode (private-chat allowlist)",
|
||||
"\u5141\u8BB8\u79C1\u804A\u7684 Telegram User ID": "Telegram User IDs allowed to send DMs",
|
||||
"\u6BCF\u884C\u4E00\u4E2A\u6570\u5B57 User ID": "One numeric User ID per line",
|
||||
"\u767D\u540D\u5355\u4EC5\u5C5E\u4E8E\u5F53\u524D\u673A\u5668\u4EBA\u3002": "This allowlist belongs only to the current bot.",
|
||||
"\u517C\u5BB9\u6A21\u5F0F\u4E0B\u6682\u4E0D\u4F7F\u7528\u767D\u540D\u5355\uFF0C\u5207\u6362\u6A21\u5F0F\u65F6\u4F1A\u4FDD\u7559\u3002": "Compatible mode does not enforce the allowlist; it is retained when modes change.",
|
||||
"\u767D\u540D\u5355\u4E3A\u7A7A\uFF1B\u4FDD\u5B58\u540E\u8BE5\u673A\u5668\u4EBA\u4F1A\u62D2\u7EDD\u6240\u6709\u5165\u7AD9\u6D88\u606F\u3002": "The allowlist is empty; this bot will reject all inbound messages after saving.",
|
||||
"\u6B63\u5728\u4FDD\u5B58\u2026": "Saving\u2026",
|
||||
"\u4FDD\u5B58\u8BBF\u95EE\u8BBE\u7F6E": "Save access settings",
|
||||
"User ID \u5FC5\u987B\u662F 1\u201316 \u4F4D\u6B63\u6574\u6570\uFF0C\u6BCF\u884C\u4E00\u4E2A\u3002": "Each User ID must be a 1\u201316 digit positive integer on its own line.",
|
||||
"Telegram \u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002": "Telegram access settings are currently unavailable.",
|
||||
"Telegram \u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\u3002": "Could not save Telegram access settings.",
|
||||
"\u63A5\u5165 Discord \u673A\u5668\u4EBA": "Connect a Discord bot",
|
||||
"\u5148\u5728 Developer Portal \u521B\u5EFA Bot \u5E76\u9080\u8BF7\u5230\u670D\u52A1\u5668\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002": "Create a bot in the Developer Portal and invite it to your server, then connect it here.",
|
||||
"\u586B\u5199 Discord Developer Portal \u7684 Bot Token": "Enter the Bot Token from the Discord Developer Portal",
|
||||
|
|
@ -2464,7 +2486,9 @@ var TOKEN_BOT_ENDPOINTS = Object.freeze({
|
|||
deleteBot: "bot.delete",
|
||||
setWorkspace: "bot.workspace.set"
|
||||
});
|
||||
function createTokenChannelApi(channel4, connectionSummary) {
|
||||
function createTokenChannelApi(channel4, connectionSummary, {
|
||||
normalizeBotExtension = () => ({})
|
||||
} = {}) {
|
||||
const unwrapRpcResult10 = (result) => {
|
||||
if (!isRecord2(result) || typeof result.ok !== "boolean") {
|
||||
throw new Error(`${channel4} \u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94`);
|
||||
|
|
@ -2480,6 +2504,7 @@ function createTokenChannelApi(channel4, connectionSummary) {
|
|||
if (!isRecord2(value) || !id(value.botId)) return void 0;
|
||||
const connected = value.connected === true;
|
||||
const state = ACCOUNT_STATES2.has(value.state) ? value.state : "offline";
|
||||
const extension = normalizeBotExtension(value);
|
||||
return {
|
||||
botId: id(value.botId),
|
||||
connected,
|
||||
|
|
@ -2500,7 +2525,8 @@ function createTokenChannelApi(channel4, connectionSummary) {
|
|||
error: isRecord2(value.error) ? {
|
||||
code: text(value.error.code, `${channel4.toUpperCase()}_ACCOUNT_ERROR`, 80),
|
||||
message: text(value.error.message, `${channel4}\u8FDE\u63A5\u5C1A\u672A\u5C31\u7EEA`)
|
||||
} : null
|
||||
} : null,
|
||||
...isRecord2(extension) ? extension : {}
|
||||
};
|
||||
};
|
||||
const normalizeSnapshot9 = (value) => {
|
||||
|
|
@ -2580,9 +2606,11 @@ function createTokenChannelSettings(definition) {
|
|||
credentialOpenLabel = "\u624B\u52A8\u63A5\u5165",
|
||||
credentialCloseLabel = "\u6536\u8D77\u51ED\u636E",
|
||||
credentialNoun = "Bot Token",
|
||||
emptyActionLabel = "\u586B\u5199 Bot Token"
|
||||
emptyActionLabel = "\u586B\u5199 Bot Token",
|
||||
AccountSettings = null,
|
||||
accountSettingsEndpoint = null
|
||||
} = definition;
|
||||
function AccountCard5({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
||||
function AccountCard5({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onAccountSettingsSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
||||
const state = busy === "reconnect" ? "connecting" : account.state;
|
||||
const tone = account.connected ? "success" : state === "error" ? "error" : "warning";
|
||||
const stateLabel2 = account.connected ? "\u8FD0\u884C\u6B63\u5E38" : state === "connecting" ? "\u6B63\u5728\u8FDE\u63A5" : "\u8FDE\u63A5\u672A\u5C31\u7EEA";
|
||||
|
|
@ -2640,6 +2668,11 @@ function createTokenChannelSettings(definition) {
|
|||
disabled: Boolean(busy),
|
||||
onSave: onWorkspaceSave
|
||||
}),
|
||||
AccountSettings ? h2(AccountSettings, {
|
||||
account,
|
||||
busy: Boolean(busy),
|
||||
onSave: onAccountSettingsSave
|
||||
}) : null,
|
||||
h2(
|
||||
"div",
|
||||
{ className: "ddt-accountFooter dim-cardFooter" },
|
||||
|
|
@ -2824,6 +2857,12 @@ function createTokenChannelSettings(definition) {
|
|||
endpoints.setWorkspace,
|
||||
{ botId: account.botId, workspace }
|
||||
),
|
||||
onAccountSettingsSave: AccountSettings && accountSettingsEndpoint ? (payload) => botAction(
|
||||
account,
|
||||
"settings",
|
||||
accountSettingsEndpoint,
|
||||
{ botId: account.botId, ...payload }
|
||||
) : void 0,
|
||||
onRequestRemove: () => setRemoveTarget(account.botId),
|
||||
onCancelRemove: () => setRemoveTarget(null),
|
||||
onConfirmRemove: async () => {
|
||||
|
|
@ -6117,18 +6156,46 @@ var SlackAccountCard = channel2.AccountCard;
|
|||
|
||||
// plugin-src/client/channels/telegram/api.js
|
||||
var TELEGRAM_RPC_CHANNEL = "/telegram";
|
||||
var TELEGRAM_ENDPOINTS = TOKEN_BOT_ENDPOINTS;
|
||||
var api3 = createTokenChannelApi("Telegram", " Bot API \u957F\u8F6E\u8BE2");
|
||||
var TELEGRAM_ENDPOINTS = Object.freeze({
|
||||
...TOKEN_BOT_ENDPOINTS,
|
||||
setAccessPolicy: "bot.access-policy.set"
|
||||
});
|
||||
var api3 = createTokenChannelApi("Telegram", " Bot API \u957F\u8F6E\u8BE2", {
|
||||
normalizeBotExtension: (value) => {
|
||||
const source = value?.accessPolicy;
|
||||
const accessMode = source?.accessMode === "private-allowlist" ? "private-allowlist" : "compatible";
|
||||
const allowedUsers = Array.isArray(source?.allowedUsers) ? [...new Set(source.allowedUsers.filter((entry) => typeof entry === "string" && /^[1-9]\d{0,15}$/.test(entry)))] : [];
|
||||
return { accessPolicy: { accessMode, allowedUsers } };
|
||||
}
|
||||
});
|
||||
var unwrapRpcResult6 = api3.unwrapRpcResult;
|
||||
var normalizeSnapshot5 = api3.normalizeSnapshot;
|
||||
var presentError6 = api3.presentError;
|
||||
|
||||
// plugin-src/client/channels/telegram/index.js
|
||||
var React14 = __toESM(require("react"), 1);
|
||||
|
||||
// plugin-src/client/channels/telegram/styles.js
|
||||
var TELEGRAM_STYLE_ID = "xmanrui-dsh-im-telegram-settings";
|
||||
var CSS7 = String.raw`
|
||||
.dtg-page { --ddt-accent: #229ed9; --ddt-accent-deep: #1687bd; --ddt-accent-wash: #eaf7fd; }
|
||||
.dtg-avatar { color: #fff; background: #229ed9; }
|
||||
.dtg-avatar svg { display: block; }
|
||||
.dtg-access { display: grid; gap: 10px; padding: 12px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 10px; background: var(--dsw-alias-bg-layer-2, #f7f8fa); }
|
||||
.dtg-accessHeading { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
|
||||
.dtg-accessHeading strong { font-size: 13px; }
|
||||
.dtg-accessHeading p { margin: 3px 0 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 1.5; }
|
||||
.dtg-accessBadge { flex: none; padding: 3px 8px; border-radius: 999px; color: #1687bd; background: #eaf7fd; font-size: 11px; font-weight: 700; }
|
||||
.dtg-accessBadge[data-mode="private-allowlist"] { color: #a15c00; background: #fff3d6; }
|
||||
.dtg-accessField { display: grid; gap: 5px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; font-weight: 600; }
|
||||
.dtg-accessField select, .dtg-accessField textarea { width: 100%; box-sizing: border-box; border: 1px solid var(--dsw-alias-border-l1, #c9cdd4); border-radius: 7px; color: inherit; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-weight: 400; }
|
||||
.dtg-accessField select { height: 34px; padding: 0 9px; }
|
||||
.dtg-accessField textarea { min-height: 68px; padding: 8px 9px; resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
||||
.dtg-accessField small { color: var(--dsw-alias-label-secondary, #646a73); font-weight: 400; }
|
||||
.dtg-accessWarning, .dtg-accessError { margin: 0; font-size: 12px; line-height: 1.5; }
|
||||
.dtg-accessWarning { color: #a15c00; }
|
||||
.dtg-accessError { color: var(--dsw-alias-state-error-primary, #d83931); }
|
||||
.dtg-accessActions { display: flex; justify-content: flex-end; }
|
||||
`;
|
||||
function installTelegramStyles() {
|
||||
if (typeof document === "undefined") return () => {
|
||||
|
|
@ -6145,6 +6212,116 @@ function installTelegramStyles() {
|
|||
}
|
||||
|
||||
// plugin-src/client/channels/telegram/index.js
|
||||
function policyFor(account) {
|
||||
return {
|
||||
accessMode: account?.accessPolicy?.accessMode === "private-allowlist" ? "private-allowlist" : "compatible",
|
||||
allowedUsers: Array.isArray(account?.accessPolicy?.allowedUsers) ? account.accessPolicy.allowedUsers : []
|
||||
};
|
||||
}
|
||||
function allowedUsersFromText(value) {
|
||||
const entries = value.split(/\r?\n/).map((entry) => entry.trim()).filter(Boolean);
|
||||
if (entries.some((entry) => !/^[1-9]\d{0,15}$/.test(entry))) {
|
||||
throw new TypeError("User ID \u5FC5\u987B\u662F 1\u201316 \u4F4D\u6B63\u6574\u6570\uFF0C\u6BCF\u884C\u4E00\u4E2A\u3002");
|
||||
}
|
||||
return [...new Set(entries)];
|
||||
}
|
||||
function TelegramAccessSettings({ account, busy = false, onSave }) {
|
||||
const policy = policyFor(account);
|
||||
const sourceUsers = policy.allowedUsers.join("\n");
|
||||
const [accessMode, setAccessMode] = React14.useState(policy.accessMode);
|
||||
const [allowedUsers, setAllowedUsers] = React14.useState(sourceUsers);
|
||||
const [error, setError] = React14.useState(null);
|
||||
React14.useEffect(() => {
|
||||
setAccessMode(policy.accessMode);
|
||||
setAllowedUsers(sourceUsers);
|
||||
setError(null);
|
||||
}, [policy.accessMode, sourceUsers]);
|
||||
const save = async (event) => {
|
||||
event.preventDefault();
|
||||
setError(null);
|
||||
try {
|
||||
const normalized = allowedUsersFromText(allowedUsers);
|
||||
if (typeof onSave !== "function") throw new Error("Telegram \u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
||||
await onSave({ accessMode, allowedUsers: normalized });
|
||||
} catch (caught) {
|
||||
setError(caught?.message ?? "Telegram \u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\u3002");
|
||||
}
|
||||
};
|
||||
const privateAllowlist = accessMode === "private-allowlist";
|
||||
const savedPrivateAllowlist = policy.accessMode === "private-allowlist";
|
||||
const emptyAllowlist = privateAllowlist && allowedUsers.trim() === "";
|
||||
return h2(
|
||||
"form",
|
||||
{ className: "dtg-access", onSubmit: save },
|
||||
h2(
|
||||
"div",
|
||||
{ className: "dtg-accessHeading" },
|
||||
h2(
|
||||
"div",
|
||||
null,
|
||||
h2("strong", null, "\u8BBF\u95EE\u8BBE\u7F6E"),
|
||||
h2("p", null, savedPrivateAllowlist ? "\u7FA4\u804A\u5168\u90E8\u5FFD\u7565\uFF0C\u79C1\u804A\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u7528\u6237\u3002" : "\u4FDD\u6301\u539F\u6709\u884C\u4E3A\uFF1A\u79C1\u804A\u76F4\u63A5\u54CD\u5E94\uFF0C\u7FA4\u804A\u5728\u88AB\u63D0\u53CA\u6216\u56DE\u590D\u65F6\u54CD\u5E94\u3002")
|
||||
),
|
||||
h2(
|
||||
"span",
|
||||
{ className: "dtg-accessBadge", "data-mode": policy.accessMode },
|
||||
savedPrivateAllowlist ? "\u5DF2\u751F\u6548\uFF1A\u5B89\u5168\u6A21\u5F0F" : "\u5DF2\u751F\u6548\uFF1A\u517C\u5BB9\u6A21\u5F0F"
|
||||
)
|
||||
),
|
||||
h2(
|
||||
"label",
|
||||
{ className: "dtg-accessField" },
|
||||
h2("span", null, "\u6A21\u5F0F"),
|
||||
h2(
|
||||
"select",
|
||||
{
|
||||
value: accessMode,
|
||||
disabled: busy,
|
||||
"aria-label": "Telegram \u8BBF\u95EE\u6A21\u5F0F",
|
||||
onChange: (event) => {
|
||||
setAccessMode(event.target.value);
|
||||
setError(null);
|
||||
}
|
||||
},
|
||||
h2("option", { value: "compatible" }, "\u517C\u5BB9\u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF09"),
|
||||
h2("option", { value: "private-allowlist" }, "\u5B89\u5168\u6A21\u5F0F\uFF08\u79C1\u804A\u767D\u540D\u5355\uFF09")
|
||||
)
|
||||
),
|
||||
h2(
|
||||
"label",
|
||||
{ className: "dtg-accessField" },
|
||||
h2("span", null, "\u5141\u8BB8\u79C1\u804A\u7684 Telegram User ID"),
|
||||
h2("textarea", {
|
||||
value: allowedUsers,
|
||||
disabled: busy,
|
||||
rows: 3,
|
||||
placeholder: "\u6BCF\u884C\u4E00\u4E2A\u6570\u5B57 User ID",
|
||||
"aria-label": "\u5141\u8BB8\u79C1\u804A\u7684 Telegram User ID",
|
||||
onChange: (event) => {
|
||||
setAllowedUsers(event.target.value);
|
||||
setError(null);
|
||||
}
|
||||
}),
|
||||
h2("small", null, privateAllowlist ? "\u767D\u540D\u5355\u4EC5\u5C5E\u4E8E\u5F53\u524D\u673A\u5668\u4EBA\u3002" : "\u517C\u5BB9\u6A21\u5F0F\u4E0B\u6682\u4E0D\u4F7F\u7528\u767D\u540D\u5355\uFF0C\u5207\u6362\u6A21\u5F0F\u65F6\u4F1A\u4FDD\u7559\u3002")
|
||||
),
|
||||
emptyAllowlist ? h2(
|
||||
"p",
|
||||
{ className: "dtg-accessWarning", role: "status" },
|
||||
"\u767D\u540D\u5355\u4E3A\u7A7A\uFF1B\u4FDD\u5B58\u540E\u8BE5\u673A\u5668\u4EBA\u4F1A\u62D2\u7EDD\u6240\u6709\u5165\u7AD9\u6D88\u606F\u3002"
|
||||
) : null,
|
||||
error ? h2("p", { className: "dtg-accessError", role: "alert" }, error) : null,
|
||||
h2(
|
||||
"div",
|
||||
{ className: "dtg-accessActions" },
|
||||
h2("button", {
|
||||
type: "submit",
|
||||
className: "ddt-button",
|
||||
"data-kind": "secondary",
|
||||
disabled: busy
|
||||
}, busy ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u8BBF\u95EE\u8BBE\u7F6E")
|
||||
)
|
||||
);
|
||||
}
|
||||
var channel3 = createTokenChannelSettings({
|
||||
channel: "Telegram",
|
||||
endpoints: TELEGRAM_ENDPOINTS,
|
||||
|
|
@ -6157,7 +6334,9 @@ var channel3 = createTokenChannelSettings({
|
|||
tokenPlaceholder: "\u586B\u5199 @BotFather \u751F\u6210\u7684 Bot Token",
|
||||
emptyTitle: "\u63A5\u5165 Telegram \u673A\u5668\u4EBA",
|
||||
emptyDescription: "\u5148\u901A\u8FC7 @BotFather \u83B7\u53D6 Bot Token\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002",
|
||||
platformLabel: "Telegram"
|
||||
platformLabel: "Telegram",
|
||||
AccountSettings: TelegramAccessSettings,
|
||||
accountSettingsEndpoint: TELEGRAM_ENDPOINTS.setAccessPolicy
|
||||
});
|
||||
var TelegramSettingsTab = channel3.SettingsTab;
|
||||
var TelegramAccountCard = channel3.AccountCard;
|
||||
|
|
@ -6280,7 +6459,7 @@ function formatRemaining4(milliseconds) {
|
|||
}
|
||||
|
||||
// plugin-src/client/channels/wecom/index.js
|
||||
var React14 = __toESM(require("react"), 1);
|
||||
var React15 = __toESM(require("react"), 1);
|
||||
|
||||
// plugin-src/client/channels/wecom/styles.js
|
||||
var WECOM_STYLE_ID = "xmanrui-dsh-im-wecom-settings";
|
||||
|
|
@ -6305,7 +6484,7 @@ function installWecomStyles() {
|
|||
|
||||
// plugin-src/client/channels/wecom/index.js
|
||||
var ACTIVE_STATES2 = /* @__PURE__ */ new Set(["pending", "refreshing", "connecting"]);
|
||||
var Button10 = React14.forwardRef(function Button11({ children, kind = "secondary", className = "", ...props }, ref) {
|
||||
var Button10 = React15.forwardRef(function Button11({ children, kind = "secondary", className = "", ...props }, ref) {
|
||||
return h2("button", {
|
||||
...props,
|
||||
ref,
|
||||
|
|
@ -6590,21 +6769,21 @@ function AccountCard3({
|
|||
);
|
||||
}
|
||||
function WecomSettingsTab({ rpcCall }) {
|
||||
const [model, setModel] = React14.useState({ phase: "loading", bots: [], totals: { configured: 0, connected: 0 }, error: null });
|
||||
const [provision, setProvision] = React14.useState(null);
|
||||
const [busy, setBusy] = React14.useState(false);
|
||||
const [busyByBot, setBusyByBot] = React14.useState({});
|
||||
const [feedbackByBot, setFeedbackByBot] = React14.useState({});
|
||||
const [removeTarget, setRemoveTarget] = React14.useState(null);
|
||||
const [credentialOpen, setCredentialOpen] = React14.useState(false);
|
||||
const [credentialError, setCredentialError] = React14.useState(null);
|
||||
const [notice, setNotice] = React14.useState("");
|
||||
const [now, setNow] = React14.useState(Date.now());
|
||||
const mounted = React14.useRef(true);
|
||||
const [model, setModel] = React15.useState({ phase: "loading", bots: [], totals: { configured: 0, connected: 0 }, error: null });
|
||||
const [provision, setProvision] = React15.useState(null);
|
||||
const [busy, setBusy] = React15.useState(false);
|
||||
const [busyByBot, setBusyByBot] = React15.useState({});
|
||||
const [feedbackByBot, setFeedbackByBot] = React15.useState({});
|
||||
const [removeTarget, setRemoveTarget] = React15.useState(null);
|
||||
const [credentialOpen, setCredentialOpen] = React15.useState(false);
|
||||
const [credentialError, setCredentialError] = React15.useState(null);
|
||||
const [notice, setNotice] = React15.useState("");
|
||||
const [now, setNow] = React15.useState(Date.now());
|
||||
const mounted = React15.useRef(true);
|
||||
const workspaceFence = useWorkspaceSnapshotFence();
|
||||
const addButtonRef = React14.useRef(null);
|
||||
const noticeFrameRef = React14.useRef(null);
|
||||
const announce = React14.useCallback((message) => {
|
||||
const addButtonRef = React15.useRef(null);
|
||||
const noticeFrameRef = React15.useRef(null);
|
||||
const announce = React15.useCallback((message) => {
|
||||
if (!mounted.current) return;
|
||||
if (noticeFrameRef.current !== null) {
|
||||
window.cancelAnimationFrame(noticeFrameRef.current);
|
||||
|
|
@ -6618,7 +6797,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
});
|
||||
}
|
||||
}, []);
|
||||
React14.useEffect(() => {
|
||||
React15.useEffect(() => {
|
||||
const disposeDingtalk = installDingtalkStyles();
|
||||
const disposeWecom = installWecomStyles();
|
||||
mounted.current = true;
|
||||
|
|
@ -6632,11 +6811,11 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
disposeDingtalk();
|
||||
};
|
||||
}, []);
|
||||
const invoke = React14.useCallback(async (endpoint, payload = {}, signal) => {
|
||||
const invoke = React15.useCallback(async (endpoint, payload = {}, signal) => {
|
||||
if (typeof rpcCall !== "function") throw new TypeError("\u4F01\u4E1A\u5FAE\u4FE1\u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
||||
return unwrapRpcResult7(await rpcCall(endpoint, payload, signal));
|
||||
}, [rpcCall]);
|
||||
const loadStatus = React14.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
||||
const loadStatus = React15.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
||||
const workspaceVersion = workspaceFence.beginStatus();
|
||||
if (workspaceVersion === null) return void 0;
|
||||
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
||||
|
|
@ -6656,12 +6835,12 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
return void 0;
|
||||
}
|
||||
}, [invoke, workspaceFence]);
|
||||
React14.useEffect(() => {
|
||||
React15.useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
void loadStatus({ signal: controller.signal, restore: true });
|
||||
return () => controller.abort();
|
||||
}, [loadStatus]);
|
||||
React14.useEffect(() => {
|
||||
React15.useEffect(() => {
|
||||
if (model.phase !== "ready") return void 0;
|
||||
const controller = new AbortController();
|
||||
const timer = window.setInterval(() => void loadStatus({ signal: controller.signal, silent: true }), 15e3);
|
||||
|
|
@ -6670,12 +6849,12 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
window.clearInterval(timer);
|
||||
};
|
||||
}, [loadStatus, model.phase]);
|
||||
React14.useEffect(() => {
|
||||
React15.useEffect(() => {
|
||||
if (!provision || !ACTIVE_STATES2.has(provision.status)) return void 0;
|
||||
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
||||
return () => window.clearInterval(timer);
|
||||
}, [provision?.attemptId, provision?.status]);
|
||||
const startProvisioning = React14.useCallback(async (replace = false) => {
|
||||
const startProvisioning = React15.useCallback(async (replace = false) => {
|
||||
setCredentialOpen(false);
|
||||
setCredentialError(null);
|
||||
setBusy(true);
|
||||
|
|
@ -6693,7 +6872,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
if (mounted.current) setBusy(false);
|
||||
}
|
||||
}, [invoke, provision?.attemptId]);
|
||||
const bindCredentials = React14.useCallback(async ({ identity, secret }) => {
|
||||
const bindCredentials = React15.useCallback(async ({ identity, secret }) => {
|
||||
const snapshotVersion = workspaceFence.beginMutation();
|
||||
setBusy(true);
|
||||
setCredentialError(null);
|
||||
|
|
@ -6715,7 +6894,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
if (mounted.current) setBusy(false);
|
||||
}
|
||||
}, [invoke, loadStatus, workspaceFence]);
|
||||
const closeProvision = React14.useCallback(async () => {
|
||||
const closeProvision = React15.useCallback(async () => {
|
||||
setBusy(true);
|
||||
try {
|
||||
if (provision?.attemptId && ACTIVE_STATES2.has(provision.status)) {
|
||||
|
|
@ -6726,7 +6905,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
if (mounted.current) setBusy(false);
|
||||
}
|
||||
}, [invoke, provision?.attemptId, provision?.status]);
|
||||
React14.useEffect(() => {
|
||||
React15.useEffect(() => {
|
||||
const attemptId = provision?.attemptId;
|
||||
if (!attemptId || !ACTIVE_STATES2.has(provision.status)) return void 0;
|
||||
const controller = new AbortController();
|
||||
|
|
@ -6756,7 +6935,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
window.clearTimeout(timer);
|
||||
};
|
||||
}, [invoke, loadStatus, provision?.attemptId, provision?.pollIntervalMs, provision?.status]);
|
||||
const botAction = React14.useCallback(async (account, operation, endpoint, payload) => {
|
||||
const botAction = React15.useCallback(async (account, operation, endpoint, payload) => {
|
||||
const snapshotVersion = workspaceFence.beginMutation();
|
||||
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
||||
try {
|
||||
|
|
@ -6775,7 +6954,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
});
|
||||
}
|
||||
}, [invoke, loadStatus, workspaceFence]);
|
||||
const reconnect = React14.useCallback(async (account) => {
|
||||
const reconnect = React15.useCallback(async (account) => {
|
||||
setFeedbackByBot((current) => {
|
||||
const next = { ...current };
|
||||
delete next[account.botId];
|
||||
|
|
@ -6888,7 +7067,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
}),
|
||||
h2("div", { className: "ddt-visuallyHidden", role: "status", "aria-live": "polite" }, notice),
|
||||
model.phase === "loading" ? h2(LoadingView4) : model.phase === "error" ? h2("div", { className: "ddt-card dim-surfaceCard" }, h2("div", { className: "ddt-inlineError dim-inlineError" }, h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u72B6\u6001"), h2("p", null, model.error?.message), h2(Button10, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6"))) : h2(
|
||||
React14.Fragment,
|
||||
React15.Fragment,
|
||||
null,
|
||||
credentialView,
|
||||
provisionView,
|
||||
|
|
@ -6899,7 +7078,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|||
}
|
||||
|
||||
// plugin-src/client/channels/weixin/index.js
|
||||
var React15 = __toESM(require("react"), 1);
|
||||
var React16 = __toESM(require("react"), 1);
|
||||
|
||||
// plugin-src/client/channels/weixin/api.js
|
||||
var WEIXIN_RPC_CHANNEL = "/weixin";
|
||||
|
|
@ -7172,7 +7351,7 @@ function installWeixinStyles() {
|
|||
}
|
||||
|
||||
// plugin-src/client/channels/weixin/index.js
|
||||
var Button12 = React15.forwardRef(function Button13({ children, kind = "secondary", className = "", ...props }, ref) {
|
||||
var Button12 = React16.forwardRef(function Button13({ children, kind = "secondary", className = "", ...props }, ref) {
|
||||
return h2("button", {
|
||||
...props,
|
||||
ref,
|
||||
|
|
@ -7245,14 +7424,14 @@ function EmptyView5({ onStart, busy }) {
|
|||
);
|
||||
}
|
||||
function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
||||
const [imageFailed, setImageFailed] = React15.useState(false);
|
||||
const [imageFailed, setImageFailed] = React16.useState(false);
|
||||
const source = safeQrSource5(provision.qrCodeDataUrl);
|
||||
const href = safeVerificationUrl(provision.verificationUrl);
|
||||
const remaining = Math.max(0, provision.expiresAt - now);
|
||||
const expired = remaining === 0 || provision.status === "expired";
|
||||
const duration = Math.max(1, provision.durationMs ?? 5 * 6e4);
|
||||
const progress = Math.round(Math.min(1, remaining / duration) * 100);
|
||||
React15.useEffect(() => setImageFailed(false), [source]);
|
||||
React16.useEffect(() => setImageFailed(false), [source]);
|
||||
return h2(
|
||||
"div",
|
||||
{ className: "dxw-card dim-surfaceCard" },
|
||||
|
|
@ -7319,9 +7498,9 @@ function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
|||
);
|
||||
}
|
||||
function VerificationPanel({ provision, busy, onSubmit, onCancel }) {
|
||||
const [code, setCode] = React15.useState("");
|
||||
const [code, setCode] = React16.useState("");
|
||||
const valid = /^\d{4,8}$/.test(code);
|
||||
React15.useEffect(() => setCode(""), [provision.attemptId]);
|
||||
React16.useEffect(() => setCode(""), [provision.attemptId]);
|
||||
return h2(
|
||||
"div",
|
||||
{ className: "dxw-card dim-surfaceCard" },
|
||||
|
|
@ -7541,40 +7720,40 @@ function mergeWeixinProvisioningSnapshot(current, incoming, { restoreProvisionin
|
|||
};
|
||||
}
|
||||
function WeixinSettingsTab({ rpcCall }) {
|
||||
const [model, setModel] = React15.useState({
|
||||
const [model, setModel] = React16.useState({
|
||||
phase: "loading",
|
||||
bots: [],
|
||||
totals: EMPTY_TOTALS3,
|
||||
revision: 0,
|
||||
error: null
|
||||
});
|
||||
const [provision, setProvision] = React15.useState(null);
|
||||
const [busy, setBusy] = React15.useState(false);
|
||||
const [busyByBot, setBusyByBot] = React15.useState({});
|
||||
const [feedbackByBot, setFeedbackByBot] = React15.useState({});
|
||||
const [removeTarget, setRemoveTarget] = React15.useState(null);
|
||||
const [notice, setNotice] = React15.useState("");
|
||||
const [now, setNow] = React15.useState(() => Date.now());
|
||||
const addButtonRef = React15.useRef(null);
|
||||
const mountedRef = React15.useRef(true);
|
||||
const [provision, setProvision] = React16.useState(null);
|
||||
const [busy, setBusy] = React16.useState(false);
|
||||
const [busyByBot, setBusyByBot] = React16.useState({});
|
||||
const [feedbackByBot, setFeedbackByBot] = React16.useState({});
|
||||
const [removeTarget, setRemoveTarget] = React16.useState(null);
|
||||
const [notice, setNotice] = React16.useState("");
|
||||
const [now, setNow] = React16.useState(() => Date.now());
|
||||
const addButtonRef = React16.useRef(null);
|
||||
const mountedRef = React16.useRef(true);
|
||||
const workspaceFence = useWorkspaceSnapshotFence();
|
||||
const scheduleAnimationFrame = useAnimationFrameScheduler();
|
||||
React15.useEffect(() => {
|
||||
React16.useEffect(() => {
|
||||
mountedRef.current = true;
|
||||
return () => {
|
||||
mountedRef.current = false;
|
||||
};
|
||||
}, []);
|
||||
const announce = React15.useCallback((value) => {
|
||||
const announce = React16.useCallback((value) => {
|
||||
setNotice("");
|
||||
scheduleAnimationFrame(() => {
|
||||
if (value) setNotice(value);
|
||||
}, "announcement");
|
||||
}, [scheduleAnimationFrame]);
|
||||
const invoke = React15.useCallback(async (endpoint, payload = {}, signal) => {
|
||||
const invoke = React16.useCallback(async (endpoint, payload = {}, signal) => {
|
||||
return unwrapRpcResult8(await rpcCall(endpoint, payload, signal));
|
||||
}, [rpcCall]);
|
||||
const loadStatus = React15.useCallback(async ({
|
||||
const loadStatus = React16.useCallback(async ({
|
||||
signal,
|
||||
silent = false,
|
||||
restoreProvisioning = false
|
||||
|
|
@ -7610,12 +7789,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
return void 0;
|
||||
}
|
||||
}, [invoke, workspaceFence]);
|
||||
React15.useEffect(() => {
|
||||
React16.useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
void loadStatus({ signal: controller.signal, restoreProvisioning: true });
|
||||
return () => controller.abort();
|
||||
}, [loadStatus]);
|
||||
React15.useEffect(() => {
|
||||
React16.useEffect(() => {
|
||||
if (model.phase !== "ready") return void 0;
|
||||
const controller = new AbortController();
|
||||
let running = false;
|
||||
|
|
@ -7634,12 +7813,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
window.clearInterval(timer);
|
||||
};
|
||||
}, [loadStatus, model.phase]);
|
||||
React15.useEffect(() => {
|
||||
React16.useEffect(() => {
|
||||
if (!provision || !["pending", "scanned"].includes(provision.status)) return void 0;
|
||||
const timer = window.setInterval(() => setNow(Date.now()), 1e3);
|
||||
return () => window.clearInterval(timer);
|
||||
}, [provision?.attemptId, provision?.status]);
|
||||
const startProvisioning = React15.useCallback(async ({ replace = false } = {}) => {
|
||||
const startProvisioning = React16.useCallback(async ({ replace = false } = {}) => {
|
||||
setBusy(true);
|
||||
try {
|
||||
if (replace && provision?.attemptId) {
|
||||
|
|
@ -7660,7 +7839,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
setBusy(false);
|
||||
}
|
||||
}, [announce, invoke, provision?.attemptId]);
|
||||
const cancelProvisioning = React15.useCallback(async () => {
|
||||
const cancelProvisioning = React16.useCallback(async () => {
|
||||
setBusy(true);
|
||||
try {
|
||||
if (provision?.attemptId && !["failed", "expired", "cancelled"].includes(provision.status)) {
|
||||
|
|
@ -7675,7 +7854,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
setBusy(false);
|
||||
}
|
||||
}, [announce, invoke, provision?.attemptId, provision?.status, scheduleAnimationFrame]);
|
||||
const submitVerification = React15.useCallback(async (verifyCode) => {
|
||||
const submitVerification = React16.useCallback(async (verifyCode) => {
|
||||
if (!provision?.attemptId) return;
|
||||
setBusy(true);
|
||||
try {
|
||||
|
|
@ -7691,7 +7870,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
setBusy(false);
|
||||
}
|
||||
}, [announce, invoke, provision?.attemptId]);
|
||||
React15.useEffect(() => {
|
||||
React16.useEffect(() => {
|
||||
const attemptId = provision?.attemptId;
|
||||
if (!attemptId || !["pending", "scanned", "connecting"].includes(provision.status)) return void 0;
|
||||
const controller = new AbortController();
|
||||
|
|
@ -7739,7 +7918,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
controller.abort();
|
||||
};
|
||||
}, [announce, invoke, loadStatus, provision?.attemptId, provision?.status, provision?.pollIntervalMs]);
|
||||
const setBotBusy = React15.useCallback((botId, value) => {
|
||||
const setBotBusy = React16.useCallback((botId, value) => {
|
||||
setBusyByBot((current) => {
|
||||
const next = { ...current };
|
||||
if (value) next[botId] = value;
|
||||
|
|
@ -7747,7 +7926,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
return next;
|
||||
});
|
||||
}, []);
|
||||
const reconnect = React15.useCallback(async (account) => {
|
||||
const reconnect = React16.useCallback(async (account) => {
|
||||
const snapshotVersion = workspaceFence.beginMutation();
|
||||
setBotBusy(account.botId, "reconnect");
|
||||
setFeedbackByBot((current) => {
|
||||
|
|
@ -7792,7 +7971,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
setBotBusy(account.botId, null);
|
||||
}
|
||||
}, [announce, invoke, loadStatus, setBotBusy, workspaceFence]);
|
||||
const saveWorkspace = React15.useCallback(async (account, workspace) => {
|
||||
const saveWorkspace = React16.useCallback(async (account, workspace) => {
|
||||
const workspaceVersion = workspaceFence.beginMutation();
|
||||
setBotBusy(account.botId, "workspace");
|
||||
try {
|
||||
|
|
@ -7815,7 +7994,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
if (mountedRef.current) setBotBusy(account.botId, null);
|
||||
}
|
||||
}, [invoke, loadStatus, setBotBusy, workspaceFence]);
|
||||
const remove = React15.useCallback(async (account) => {
|
||||
const remove = React16.useCallback(async (account) => {
|
||||
const snapshotVersion = workspaceFence.beginMutation();
|
||||
setBotBusy(account.botId, "delete");
|
||||
try {
|
||||
|
|
@ -7891,7 +8070,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|||
h2(Button12, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
||||
)
|
||||
) : h2(
|
||||
React15.Fragment,
|
||||
React16.Fragment,
|
||||
null,
|
||||
provisionView,
|
||||
model.bots.length === 0 && !provision ? h2(EmptyView5, { onStart: () => void startProvisioning(), busy }) : null,
|
||||
|
|
@ -8023,7 +8202,7 @@ function formatRemaining6(milliseconds) {
|
|||
}
|
||||
|
||||
// plugin-src/client/channels/whatsapp/index.js
|
||||
var React16 = __toESM(require("react"), 1);
|
||||
var React17 = __toESM(require("react"), 1);
|
||||
|
||||
// plugin-src/client/channels/whatsapp/styles.js
|
||||
var WHATSAPP_STYLE_ID = "xmanrui-dsh-im-whatsapp-settings";
|
||||
|
|
@ -8048,7 +8227,7 @@ function installWhatsappStyles() {
|
|||
|
||||
// plugin-src/client/channels/whatsapp/index.js
|
||||
var ACTIVE_STATES3 = /* @__PURE__ */ new Set(["pending", "connecting"]);
|
||||
var Button14 = React16.forwardRef(function Button15({ children, kind = "secondary", className = "", ...props }, ref) {
|
||||
var Button14 = React17.forwardRef(function Button15({ children, kind = "secondary", className = "", ...props }, ref) {
|
||||
return h2("button", {
|
||||
...props,
|
||||
ref,
|
||||
|
|
@ -8363,22 +8542,22 @@ function WhatsappAccountCard({
|
|||
);
|
||||
}
|
||||
function WhatsappSettingsTab({ rpcCall }) {
|
||||
const [model, setModel] = React16.useState({
|
||||
const [model, setModel] = React17.useState({
|
||||
phase: "loading",
|
||||
bots: [],
|
||||
totals: { configured: 0, connected: 0 },
|
||||
error: null
|
||||
});
|
||||
const [provision, setProvision] = React16.useState(null);
|
||||
const [busy, setBusy] = React16.useState(false);
|
||||
const [busyByBot, setBusyByBot] = React16.useState({});
|
||||
const [testNoticeByBot, setTestNoticeByBot] = React16.useState({});
|
||||
const [removeTarget, setRemoveTarget] = React16.useState(null);
|
||||
const [now, setNow] = React16.useState(Date.now());
|
||||
const mounted = React16.useRef(true);
|
||||
const [provision, setProvision] = React17.useState(null);
|
||||
const [busy, setBusy] = React17.useState(false);
|
||||
const [busyByBot, setBusyByBot] = React17.useState({});
|
||||
const [testNoticeByBot, setTestNoticeByBot] = React17.useState({});
|
||||
const [removeTarget, setRemoveTarget] = React17.useState(null);
|
||||
const [now, setNow] = React17.useState(Date.now());
|
||||
const mounted = React17.useRef(true);
|
||||
const workspaceFence = useWorkspaceSnapshotFence();
|
||||
const addButtonRef = React16.useRef(null);
|
||||
React16.useEffect(() => {
|
||||
const addButtonRef = React17.useRef(null);
|
||||
React17.useEffect(() => {
|
||||
const disposeDingtalk = installDingtalkStyles();
|
||||
const disposeWhatsapp = installWhatsappStyles();
|
||||
mounted.current = true;
|
||||
|
|
@ -8388,11 +8567,11 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|||
disposeDingtalk();
|
||||
};
|
||||
}, []);
|
||||
const invoke = React16.useCallback(async (endpoint, payload = {}, signal) => {
|
||||
const invoke = React17.useCallback(async (endpoint, payload = {}, signal) => {
|
||||
if (typeof rpcCall !== "function") throw new TypeError("WhatsApp \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
||||
return unwrapRpcResult9(await rpcCall(endpoint, payload, signal));
|
||||
}, [rpcCall]);
|
||||
const loadStatus = React16.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
||||
const loadStatus = React17.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
||||
const workspaceVersion = workspaceFence.beginStatus();
|
||||
if (workspaceVersion === null) return void 0;
|
||||
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
||||
|
|
@ -8416,12 +8595,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|||
return void 0;
|
||||
}
|
||||
}, [invoke, workspaceFence]);
|
||||
React16.useEffect(() => {
|
||||
React17.useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
void loadStatus({ signal: controller.signal, restore: true });
|
||||
return () => controller.abort();
|
||||
}, [loadStatus]);
|
||||
React16.useEffect(() => {
|
||||
React17.useEffect(() => {
|
||||
if (model.phase !== "ready") return void 0;
|
||||
const controller = new AbortController();
|
||||
const timer = window.setInterval(
|
||||
|
|
@ -8433,12 +8612,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|||
window.clearInterval(timer);
|
||||
};
|
||||
}, [loadStatus, model.phase]);
|
||||
React16.useEffect(() => {
|
||||
React17.useEffect(() => {
|
||||
if (!provision || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
||||
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
||||
return () => window.clearInterval(timer);
|
||||
}, [provision?.attemptId, provision?.status]);
|
||||
const startProvisioning = React16.useCallback(async (replace = false) => {
|
||||
const startProvisioning = React17.useCallback(async (replace = false) => {
|
||||
setBusy(true);
|
||||
try {
|
||||
if (replace && provision?.attemptId) {
|
||||
|
|
@ -8456,7 +8635,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|||
if (mounted.current) setBusy(false);
|
||||
}
|
||||
}, [invoke, provision?.attemptId]);
|
||||
const closeProvision = React16.useCallback(async () => {
|
||||
const closeProvision = React17.useCallback(async () => {
|
||||
setBusy(true);
|
||||
try {
|
||||
if (provision?.attemptId && ACTIVE_STATES3.has(provision.status)) {
|
||||
|
|
@ -8467,7 +8646,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|||
if (mounted.current) setBusy(false);
|
||||
}
|
||||
}, [invoke, provision?.attemptId, provision?.status]);
|
||||
React16.useEffect(() => {
|
||||
React17.useEffect(() => {
|
||||
const attemptId = provision?.attemptId;
|
||||
if (!attemptId || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
||||
const controller = new AbortController();
|
||||
|
|
@ -8508,7 +8687,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|||
if (timer) window.clearTimeout(timer);
|
||||
};
|
||||
}, [invoke, loadStatus, provision?.attemptId, provision?.status]);
|
||||
const botAction = React16.useCallback(async (account, operation, endpoint, payload) => {
|
||||
const botAction = React17.useCallback(async (account, operation, endpoint, payload) => {
|
||||
const snapshotVersion = workspaceFence.beginMutation();
|
||||
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
||||
if (operation === "reconnect") {
|
||||
|
|
@ -8607,7 +8786,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|||
h2(Button14, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
||||
)
|
||||
) : h2(
|
||||
React16.Fragment,
|
||||
React17.Fragment,
|
||||
null,
|
||||
provision?.status === "pending" ? h2(QrPanel5, {
|
||||
provision,
|
||||
|
|
@ -8999,8 +9178,8 @@ function IMSettingsTab({
|
|||
officeRpcCall,
|
||||
workspaceDirectoryPicker
|
||||
}) {
|
||||
const [selected, setSelected] = React17.useState("weixin");
|
||||
const githubTooltipId = React17.useId();
|
||||
const [selected, setSelected] = React18.useState("weixin");
|
||||
const githubTooltipId = React18.useId();
|
||||
const active = CHANNELS.find((channel4) => channel4.id === selected) ?? CHANNELS[0];
|
||||
return h2(
|
||||
WorkspaceDirectoryPickerContext.Provider,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue