diff --git a/CHANGELOG.md b/CHANGELOG.md index ef6a8716b1..87c181eb75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ WeChat original voice can be prepared for playback, native quotes and retained l ### Fixed - **Bind app** no longer hides apps the IM plugin can't serve yet. A Discord app whose plugin lacks checked sending now shows greyed out with **update the IM plugin to bind this app**, instead of silently missing from the list ([#1123](https://github.com/BotHarness/BotHarness/issues/1123)). +- **Bind app** no longer lists apps already bound to the same Bot; they are already shown under External identities ([#1127](https://github.com/BotHarness/BotHarness/issues/1127)). - Shared Channel messages now show the external sender’s retained name, including existing Discord history; bubbles render retained native @ names as chips using the Lark Inbox renderer, while original text and IDs stay intact and unavailable names keep the literal fallback ([#1061](https://github.com/BotHarness/BotHarness/issues/1061)). diff --git a/CHANGELOG.zh.md b/CHANGELOG.zh.md index 774892942d..937c539b48 100644 --- a/CHANGELOG.zh.md +++ b/CHANGELOG.zh.md @@ -49,6 +49,7 @@ ### Fixed - **绑定应用** 不再隐藏 IM 插件暂时不支持的应用。插件缺少受检发送能力的 Discord 应用现在会置灰显示,并注明 **需要更新 IM 插件后才能绑定**,不会再悄悄从列表里消失([#1123](https://github.com/BotHarness/BotHarness/issues/1123))。 +- **绑定应用** 不再列出已经绑定到这个 Bot 的应用,它们已经显示在「外部身份」里([#1127](https://github.com/BotHarness/BotHarness/issues/1127))。 - 共享频道消息现在显示已保存的外部发送人名称,已有 Discord 历史也会更新显示;气泡复用 Lark 收件箱的渲染方式,将已保存名称的原生 @ 提及显示为标签;原文和 ID 保持不变,未知名称保留原始文本([#1061](https://github.com/BotHarness/BotHarness/issues/1061))。 diff --git a/docs/assets/pr/1127-hide-own-apps/README.md b/docs/assets/pr/1127-hide-own-apps/README.md new file mode 100644 index 0000000000..88815fec6f --- /dev/null +++ b/docs/assets/pr/1127-hide-own-apps/README.md @@ -0,0 +1,8 @@ +# #1127 Bind app leaves out the Bot's own apps + +Captured from a real DSH Host (0.2.0-rc.1) with a simulated Lark provider. Bind app is opened from Bob, whose own app (运维值班) is no longer listed; Ada's two apps stay greyed out. + +| | Light | Dark | +| --- | ----------------------- | ---------------------- | +| zh | ![](bind-zh-light.webp) | ![](bind-zh-dark.webp) | +| en | ![](bind-en-light.webp) | ![](bind-en-dark.webp) | diff --git a/docs/assets/pr/1127-hide-own-apps/bind-en-dark.webp b/docs/assets/pr/1127-hide-own-apps/bind-en-dark.webp new file mode 100644 index 0000000000..e4e72b3bb1 Binary files /dev/null and b/docs/assets/pr/1127-hide-own-apps/bind-en-dark.webp differ diff --git a/docs/assets/pr/1127-hide-own-apps/bind-en-light.webp b/docs/assets/pr/1127-hide-own-apps/bind-en-light.webp new file mode 100644 index 0000000000..4b256798e5 Binary files /dev/null and b/docs/assets/pr/1127-hide-own-apps/bind-en-light.webp differ diff --git a/docs/assets/pr/1127-hide-own-apps/bind-zh-dark.webp b/docs/assets/pr/1127-hide-own-apps/bind-zh-dark.webp new file mode 100644 index 0000000000..e852c6041a Binary files /dev/null and b/docs/assets/pr/1127-hide-own-apps/bind-zh-dark.webp differ diff --git a/docs/assets/pr/1127-hide-own-apps/bind-zh-light.webp b/docs/assets/pr/1127-hide-own-apps/bind-zh-light.webp new file mode 100644 index 0000000000..53f2b98a3c Binary files /dev/null and b/docs/assets/pr/1127-hide-own-apps/bind-zh-light.webp differ diff --git a/docs/channel-sidebar/external-identities.md b/docs/channel-sidebar/external-identities.md index 44e25312dd..65d01a3ea0 100644 --- a/docs/channel-sidebar/external-identities.md +++ b/docs/channel-sidebar/external-identities.md @@ -22,7 +22,7 @@ The same goes for Slack and Discord: DM the app or @mention it in a channel it b 1. First connect the app under **Settings → IM Bots**, following the guide for your platform. 2. Click **+ Bind app**. -3. Choose the connected app under **App**. The dropdown is searchable: type to filter. Every connected app is listed: apps a Bot already uses are greyed out and say which Bot (or **already bound to this Bot**), and disconnected apps say **not connected**. **Manage app credentials** opens **Settings → IM bots**. +3. Choose the connected app under **App**. The dropdown is searchable: type to filter. Every connected app this Bot doesn't already have is listed: apps another Bot uses are greyed out and say which Bot, and disconnected apps say **not connected**. **Manage app credentials** opens **Settings → IM bots**. 4. Click **Bind app**. The dialog then shows the real receiving state: - **Ready**: DMs and @mentions to the app now reach this Bot’s Inbox. - **Connecting**: the app is still opening its receiver. Wait a moment. diff --git a/docs/channel-sidebar/external-identities.zh.md b/docs/channel-sidebar/external-identities.zh.md index c102e9c8e8..b88fa85ace 100644 --- a/docs/channel-sidebar/external-identities.zh.md +++ b/docs/channel-sidebar/external-identities.zh.md @@ -22,7 +22,7 @@ Slack 和 Discord 同样适用:私聊应用、或在它所在的频道里 @ 1. 先按对应平台的教程,在 **设置 → IM机器人** 连接应用。 2. 点击 **+ 绑定应用**。 -3. 在 **应用** 中选择已连接的应用。下拉框支持搜索,输入文字即可筛选。这里列出所有已连接的应用:已被 Bot 使用的应用置灰,并注明是哪个 Bot(或 **已绑定到这个 Bot**);未连接的应用注明 **未连接**。**管理应用凭据** 会打开 **设置 → IM机器人**。 +3. 在 **应用** 中选择已连接的应用。下拉框支持搜索,输入文字即可筛选。这里列出这个 Bot 还没绑定的所有已连接应用:已被其他 Bot 使用的应用置灰,并注明是哪个 Bot;未连接的应用注明 **未连接**。**管理应用凭据** 会打开 **设置 → IM机器人**。 4. 点击 **绑定应用**。弹窗随后显示真实的接收状态: - **已就绪**:发给这个应用的私聊和群里 @ 它的消息,现在会进入这个 Bot 的收件箱。 - **正在连接**:应用正在建立接收连接,稍等片刻。 diff --git a/packages/client/src/client/external-identity-list.tsx b/packages/client/src/client/external-identity-list.tsx index 554fb788af..e86299285f 100644 --- a/packages/client/src/client/external-identity-list.tsx +++ b/packages/client/src/client/external-identity-list.tsx @@ -277,7 +277,14 @@ export function ExternalIdentityList({ disabled={busy} value={accountKey} onSelect={setAccountKey} - options={[...accounts] + options={accounts + .filter( + (account) => + !identities.some( + (i) => + i.providerId === account.providerId && i.accountRef === account.ref, + ), + ) .sort( (a, b) => Number(a.boundBotSlug !== undefined || !a.connected || !!a.unsupported) - @@ -294,16 +301,10 @@ export function ExternalIdentityList({ ? account.connected ? platform(account.platform) : t('identity.appOffline', { platform: platform(account.platform) }) - : identities.some( - (i) => - i.providerId === account.providerId && - i.accountRef === account.ref, - ) - ? t('identity.appThisBot', { platform: platform(account.platform) }) - : t('identity.appUsedBy', { - platform: platform(account.platform), - name: botName(account.boundBotSlug), - }), + : t('identity.appUsedBy', { + platform: platform(account.platform), + name: botName(account.boundBotSlug), + }), disabled: !account.connected || account.boundBotSlug !== undefined || diff --git a/packages/client/src/client/locale.ts b/packages/client/src/client/locale.ts index 728b869109..f2984a721b 100644 --- a/packages/client/src/client/locale.ts +++ b/packages/client/src/client/locale.ts @@ -812,7 +812,6 @@ export const zh = { 'identity.kind.group': '群聊', 'identity.lastMessage': '最近消息 {time}', 'identity.appUsedBy': '{platform} · 已被 {name} 使用', - 'identity.appThisBot': '{platform} · 已绑定到这个 Bot', 'identity.appOffline': '{platform} · 未连接', 'identity.appUnsupported': '{platform} · 需要更新 IM 插件后才能绑定', 'identity.manageApps': '管理应用凭据', @@ -2960,7 +2959,6 @@ My relationship with the Human, established lore and topics to avoid: [fill in]. 'identity.kind.group': 'Group', 'identity.lastMessage': 'Last message {time}', 'identity.appUsedBy': '{platform} · used by {name}', - 'identity.appThisBot': '{platform} · already bound to this Bot', 'identity.appOffline': '{platform} · not connected', 'identity.appUnsupported': '{platform} · update the IM plugin to bind this app', 'identity.manageApps': 'Manage app credentials', diff --git a/packages/client/test/external-identity-list.test.ts b/packages/client/test/external-identity-list.test.ts index bd45630c2c..ff0b9f5c0f 100644 --- a/packages/client/test/external-identity-list.test.ts +++ b/packages/client/test/external-identity-list.test.ts @@ -252,7 +252,7 @@ it('Bind app shows real readiness after the commit and the app row lists its con } }); -it('Bind app lists every app, disables the ones a Bot uses with its owner or the Provider cannot serve, and offers a second app of a bound platform', async () => { +it('Bind app leaves out this Bot’s own apps, disables the ones another Bot uses with its owner or the Provider cannot serve, and offers a second app of a bound platform', async () => { Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); const app = (ref: string, boundBotSlug?: string) => ({ providerId: 'dsh-im/feishu', @@ -315,7 +315,6 @@ it('Bind app lists every app, disables the ones a Bot uses with its owner or the const options = [...document.querySelectorAll('[role="option"]')]; expect(options.map((o) => [o.dataset.value, o.disabled, o.textContent])).toEqual([ ['dsh-im/feishu:free', false, expect.stringContaining('App free')], - ['dsh-im/feishu:mine', true, expect.stringContaining('已绑定到这个 Bot')], ['dsh-im/feishu:old', true, expect.stringContaining('需要更新 IM 插件')], ['dsh-im/feishu:theirs', true, expect.stringContaining('已被 Bea 使用')], ]);