fix(desktop): name the connected Telegram bot after QR setup

After a QR apply the success toast only said the gateway was restarting,
and reset() wiped the bot name, so the Quick setup card fell back to the
"already configured, will replace" warning with no sign of which bot was
just connected.

The toast now reads "Connected: @bot · Telegram saved; gateway
restarting…", and the card keeps a Connected badge with the @bot handle
in place of the replace warning until the next setup starts.

Co-authored-by: wangtao <wangtao@wangtaodeMacBook-Pro.local>
This commit is contained in:
Hermes Agent
2026-09-25 01:19:59 -05:00
committed by brooklyn!
parent 0fb7c95203
commit 32b4acf4c8
3 changed files with 31 additions and 3 deletions

View File

@@ -26,6 +26,7 @@ const watchGatewayRestartOutcome = vi.fn()
const startTelegramOnboarding = vi.fn()
const getTelegramOnboardingStatus = vi.fn()
const applyTelegramOnboarding = vi.fn()
const notify = vi.fn()
vi.mock('@/hermes', () => ({
approvePairing: (platformId: string, requestId: string, profile?: null | string) =>
@@ -64,7 +65,7 @@ vi.mock('@/lib/external-link', () => ({
}))
vi.mock('@/store/notifications', () => ({
notify: vi.fn(),
notify: (notification: unknown) => notify(notification),
notifyError: vi.fn()
}))
@@ -324,6 +325,7 @@ describe('MessagingView Telegram quick setup', () => {
status: 'ready'
})
applyTelegramOnboarding.mockResolvedValue({
bot_username: 'hermes_bot',
needs_restart: false,
ok: true,
platform: 'telegram',
@@ -348,6 +350,15 @@ describe('MessagingView Telegram quick setup', () => {
await waitFor(() => expect(applyTelegramOnboarding).toHaveBeenCalledWith('pair-1', ['8792111505'], 'worker'))
await waitFor(() => expect(watchGatewayRestartOutcome).toHaveBeenCalled())
expect(notify).toHaveBeenCalledWith({
kind: 'success',
message: 'Connected: @hermes_bot · Telegram saved; gateway restarting…',
title: 'Telegram setup saved'
})
// The pairing UI is gone, but the card still names the bot that was just connected.
expect(screen.queryByRole('button', { name: /Save and restart/ })).toBeNull()
expect(screen.getByText('Connected')).toBeTruthy()
expect(screen.getByText('@hermes_bot')).toBeTruthy()
} finally {
$settingsScopeOverride.set(null)
}

View File

@@ -413,7 +413,13 @@ export function MessagingView({ setStatusbarItemGroup: _setStatusbarItemGroup, .
await refreshPlatforms(true)
if (result.restart_started) {
notify({ kind: 'success', title: m.setupSaved('Telegram'), message: m.telegramQr.savedRestarting })
const connectedBot = result.bot_username ? `${m.states.connected}: @${result.bot_username}` : null
notify({
kind: 'success',
title: m.setupSaved('Telegram'),
message: [connectedBot, m.telegramQr.savedRestarting].filter(Boolean).join(' · ')
})
setRestartNeeded(false)
const ok = await watchGatewayRestartOutcome()

View File

@@ -72,6 +72,8 @@ export function TelegramQrSetup({ onApplied, platform, scopeProfile }: TelegramQ
const [qrDataUrl, setQrDataUrl] = useState('')
const [phase, setPhase] = useState<Phase>('idle')
const [botUsername, setBotUsername] = useState<null | string>(null)
// The bot a successful apply just saved; outlives reset() so the card still says which bot is connected.
const [connectedBot, setConnectedBot] = useState<null | string>(null)
const [allowedIds, setAllowedIds] = useState<string[]>([])
const [detectedOwnerId, setDetectedOwnerId] = useState<null | string>(null)
const [newAllowedId, setNewAllowedId] = useState('')
@@ -177,6 +179,7 @@ export function TelegramQrSetup({ onApplied, platform, scopeProfile }: TelegramQ
setPhase('starting')
setError('')
setBotUsername(null)
setConnectedBot(null)
setAllowedIds([])
setDetectedOwnerId(null)
setNewAllowedId('')
@@ -236,6 +239,7 @@ export function TelegramQrSetup({ onApplied, platform, scopeProfile }: TelegramQ
try {
const result = await applyTelegramOnboarding(setup.pairing_id, allowedIds, scopeProfile)
reset()
setConnectedBot(result.bot_username || botUsername)
onApplied(result)
} catch (applyError) {
setPhase('ready')
@@ -268,7 +272,14 @@ export function TelegramQrSetup({ onApplied, platform, scopeProfile }: TelegramQ
)}
</div>
{platform.configured && phase === 'idle' && (
{phase === 'idle' && connectedBot && (
<div className="mt-2 flex flex-wrap items-center gap-2">
<Badge variant="success">{t.messaging.states.connected}</Badge>
<span className="font-mono text-xs text-muted-foreground">@{connectedBot}</span>
</div>
)}
{platform.configured && phase === 'idle' && !connectedBot && (
<p className="mt-2 text-[length:var(--conversation-caption-font-size)] leading-(--conversation-caption-line-height) text-muted-foreground">
{q.replaceWarning}
</p>