mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 09:07:40 +00:00
fix(settings): Antigravity's sign-in reads as an Account line, never an empty box (#30850)
Settings > Chat > Providers showed Antigravity's sign-in as a filled grey box holding only a bright primary "Sign in" button. The host learns whether its chats are signed in only when a chat starts, so after launch the status line had nothing to say and the box sat empty. The area is now a plain row under the provider's name: "Account" on one line, the status on the next, and an outline "Sign in" button. Until the host knows, the status line says chats need an Antigravity sign-in separate from the agy terminal account.
This commit is contained in:
@@ -9,6 +9,7 @@ import type {
|
||||
import type { RuntimeClientTarget } from '../../../../shared/runtime-client-target'
|
||||
import { callAntigravityChatSignIn } from '@/runtime/runtime-antigravity-accounts-client'
|
||||
import { AntigravityChatSignInRow } from './AntigravityChatSignInRow'
|
||||
import { AntigravityProviderSignInArea } from './AntigravityProviderSignInArea'
|
||||
import { TooltipProvider } from '../ui/tooltip'
|
||||
|
||||
const url = 'https://accounts.google.com/o/oauth2/v2/auth?state=s'
|
||||
@@ -157,3 +158,40 @@ it('sends the address pasted from a browser on another computer to the host', as
|
||||
callbackUrl: pasted
|
||||
})
|
||||
})
|
||||
|
||||
// A host learns its sign-in only when a chat starts, so after launch it has no answer to show.
|
||||
it("names the account and why it's needed before the host knows its sign-in", async () => {
|
||||
const owner = { kind: 'environment', environmentId: 'provider-unanswered' } as const
|
||||
render(
|
||||
<AntigravityProviderSignInArea
|
||||
owner={owner}
|
||||
label="this computer"
|
||||
install={{
|
||||
kind: 'active',
|
||||
subject: { target: owner, runtimeId: null, agent: 'antigravity' },
|
||||
removable: true,
|
||||
snapshot: {
|
||||
kind: 'known',
|
||||
state: {
|
||||
agent: 'antigravity',
|
||||
revision: 1,
|
||||
available: true,
|
||||
version: '1.0.0',
|
||||
installedVersion: '1.0.0',
|
||||
installedCurrent: true,
|
||||
source: 'managed',
|
||||
operation: null
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
await act(async () => undefined)
|
||||
expect(screen.getByText('Account')).toBeTruthy()
|
||||
expect(screen.getByRole('status').textContent).toBe(
|
||||
'Chats need an Antigravity sign-in, separate from your agy terminal account.'
|
||||
)
|
||||
expect(screen.getByRole('button', { name: 'Sign in' }).hasAttribute('disabled')).toBe(false)
|
||||
await act(async () => publish(owner, null, 'signedOut'))
|
||||
expect(screen.getByRole('status').textContent).toMatch(/^Not signed in\./)
|
||||
})
|
||||
|
||||
@@ -203,11 +203,13 @@ export function PastedAddressForm(props: {
|
||||
}
|
||||
|
||||
/** One host's chat sign-in as both Settings layouts show it. `signedOut` is the line for a host
|
||||
* that answered it is not signed in. */
|
||||
* that answered it is not signed in; `unanswered` stands in while it has nothing else to say, as a
|
||||
* host learns its sign-in only when a chat starts or asks to sign in. */
|
||||
export function useAntigravityChatSignInControls(props: {
|
||||
owner: RuntimeClientTarget
|
||||
label: string
|
||||
signedOut: string
|
||||
unanswered?: string
|
||||
disabled: boolean
|
||||
}) {
|
||||
const { owner, label } = props
|
||||
@@ -235,7 +237,11 @@ export function useAntigravityChatSignInControls(props: {
|
||||
/** The browser's link, while this client's sign-in waits on it. */
|
||||
url: ownFlow && flow?.phase === 'waiting' ? (flow.url ?? null) : null,
|
||||
line:
|
||||
status === 'known' ? chatSignInLine(flow, auth, openFailed, label, props.signedOut) : null,
|
||||
status === 'known'
|
||||
? (chatSignInLine(flow, auth, openFailed, label, props.signedOut) ??
|
||||
props.unanswered ??
|
||||
null)
|
||||
: null,
|
||||
alert:
|
||||
error ??
|
||||
(status === 'readFailed' ? readFailed : null) ??
|
||||
|
||||
@@ -38,6 +38,10 @@ export function AntigravityProviderSignInArea(props: {
|
||||
'settings.chat.providers.antigravityNotSignedIn',
|
||||
'Not signed in. Chats need an Antigravity sign-in, separate from your agy terminal account.'
|
||||
),
|
||||
unanswered: translate(
|
||||
'settings.chat.providers.antigravitySignInNeeded',
|
||||
'Chats need an Antigravity sign-in, separate from your agy terminal account.'
|
||||
),
|
||||
disabled: antigravityChatSignInBlocked(props.install)
|
||||
})
|
||||
const { alert, copy, copyLabel, ownFlow, url } = signIn
|
||||
@@ -45,26 +49,31 @@ export function AntigravityProviderSignInArea(props: {
|
||||
const line = alert && !ownFlow ? null : signIn.line
|
||||
return (
|
||||
// Indented to the provider's name, past its icon.
|
||||
<div className="ml-10 space-y-2 rounded-md bg-muted/40 px-3 py-2.5">
|
||||
{/* The line keeps its height until the host answers, so nothing shifts when it does. */}
|
||||
<div className="flex min-h-6 items-center gap-2">
|
||||
<div
|
||||
role="status"
|
||||
className="flex min-w-0 flex-1 items-center gap-1.5 text-xs text-muted-foreground"
|
||||
>
|
||||
{ownFlow ? <LoadingSpinner className="size-3 shrink-0" /> : null}
|
||||
<span className="min-w-0 break-words">
|
||||
{line}
|
||||
{line && alert ? ' ' : null}
|
||||
{alert && (
|
||||
<span role="alert" className="text-destructive">
|
||||
{alert}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
<div className="ml-10 space-y-2">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-xs font-medium leading-none">
|
||||
{translate('settings.chat.providers.antigravityAccount', 'Account')}
|
||||
</p>
|
||||
{/* The line keeps its height until the host answers, so nothing shifts when it does. */}
|
||||
<div
|
||||
role="status"
|
||||
className="mt-1 flex min-h-4 items-center gap-1.5 text-xs text-muted-foreground"
|
||||
>
|
||||
{ownFlow ? <LoadingSpinner className="size-3 shrink-0" /> : null}
|
||||
<span className="min-w-0 break-words">
|
||||
{line}
|
||||
{line && alert ? ' ' : null}
|
||||
{alert && (
|
||||
<span role="alert" className="text-destructive">
|
||||
{alert}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{ownFlow ? (
|
||||
<>
|
||||
<div className="flex shrink-0 items-center gap-1">
|
||||
{url && (
|
||||
<Button size="xs" variant="ghost" onClick={() => void copy.copyText()}>
|
||||
{copy.status === 'copied' ? <Check /> : <Copy />}
|
||||
@@ -74,12 +83,12 @@ export function AntigravityProviderSignInArea(props: {
|
||||
<Button size="xs" variant="ghost" disabled={signIn.pending} onClick={signIn.cancel}>
|
||||
{translate('accounts.antigravity.chatCancel', 'Cancel')}
|
||||
</Button>
|
||||
</>
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
size="xs"
|
||||
// Signed in, the button only switches account, so it steps back from the primary.
|
||||
variant={signIn.action === 'changeAccount' ? 'ghost' : 'default'}
|
||||
// Signed in, the button only switches account, so it steps back further.
|
||||
variant={signIn.action === 'changeAccount' ? 'ghost' : 'outline'}
|
||||
disabled={signIn.signInDisabled}
|
||||
onClick={signIn.start}
|
||||
>
|
||||
|
||||
@@ -217,7 +217,9 @@
|
||||
"install": "Install",
|
||||
"toggleLabel": "Open {{value0}} as a chat",
|
||||
"antigravityDescription": "Antigravity chats run a server Orca downloads to this host, separate from the agy CLI.",
|
||||
"antigravityNotSignedIn": "Not signed in. Chats need an Antigravity sign-in, separate from your agy terminal account."
|
||||
"antigravityNotSignedIn": "Not signed in. Chats need an Antigravity sign-in, separate from your agy terminal account.",
|
||||
"antigravityAccount": "Account",
|
||||
"antigravitySignInNeeded": "Chats need an Antigravity sign-in, separate from your agy terminal account."
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -40,7 +40,9 @@
|
||||
"providers": {
|
||||
"title": "Proveedores",
|
||||
"antigravityDescription": "Los chats de Antigravity usan un servidor que Orca descarga en este host, independiente de la CLI de agy.",
|
||||
"antigravityNotSignedIn": "No has iniciado sesión. Los chats necesitan un inicio de sesión de Antigravity, independiente de tu cuenta de agy en la terminal."
|
||||
"antigravityNotSignedIn": "No has iniciado sesión. Los chats necesitan un inicio de sesión de Antigravity, independiente de tu cuenta de agy en la terminal.",
|
||||
"antigravityAccount": "Cuenta",
|
||||
"antigravitySignInNeeded": "Los chats necesitan un inicio de sesión de Antigravity, independiente de tu cuenta de agy en la terminal."
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -144,7 +144,9 @@
|
||||
"providers": {
|
||||
"title": "Fournisseurs",
|
||||
"antigravityDescription": "Les chats Antigravity utilisent un serveur qu’Orca télécharge sur cet hôte, distinct de la CLI agy.",
|
||||
"antigravityNotSignedIn": "Non connecté. Les discussions nécessitent une connexion Antigravity, distincte de votre compte agy du terminal."
|
||||
"antigravityNotSignedIn": "Non connecté. Les discussions nécessitent une connexion Antigravity, distincte de votre compte agy du terminal.",
|
||||
"antigravityAccount": "Compte",
|
||||
"antigravitySignInNeeded": "Les discussions nécessitent une connexion Antigravity, distincte de votre compte agy du terminal."
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -40,7 +40,9 @@
|
||||
"providers": {
|
||||
"title": "プロバイダー",
|
||||
"antigravityDescription": "Antigravity チャットは、Orca がこのホストにダウンロードするサーバーで動作します。agy CLI とは別です。",
|
||||
"antigravityNotSignedIn": "サインインしていません。チャットには、ターミナルの agy アカウントとは別の Antigravity サインインが必要です。"
|
||||
"antigravityNotSignedIn": "サインインしていません。チャットには、ターミナルの agy アカウントとは別の Antigravity サインインが必要です。",
|
||||
"antigravityAccount": "アカウント",
|
||||
"antigravitySignInNeeded": "チャットには、ターミナルの agy アカウントとは別の Antigravity サインインが必要です。"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -40,7 +40,9 @@
|
||||
"providers": {
|
||||
"title": "공급자",
|
||||
"antigravityDescription": "Antigravity 채팅은 Orca가 이 호스트에 다운로드하는 서버에서 실행되며, agy CLI와는 별개입니다.",
|
||||
"antigravityNotSignedIn": "로그인되어 있지 않습니다. 채팅에는 터미널 agy 계정과 별개인 Antigravity 로그인이 필요합니다."
|
||||
"antigravityNotSignedIn": "로그인되어 있지 않습니다. 채팅에는 터미널 agy 계정과 별개인 Antigravity 로그인이 필요합니다.",
|
||||
"antigravityAccount": "계정",
|
||||
"antigravitySignInNeeded": "채팅에는 터미널 agy 계정과 별개인 Antigravity 로그인이 필요합니다."
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -40,7 +40,9 @@
|
||||
"providers": {
|
||||
"title": "提供方",
|
||||
"antigravityDescription": "Antigravity 聊天运行在 Orca 下载到此主机的服务器上,与 agy CLI 相互独立。",
|
||||
"antigravityNotSignedIn": "未登录。聊天需要单独的 Antigravity 登录,与终端中的 agy 帐户分开。"
|
||||
"antigravityNotSignedIn": "未登录。聊天需要单独的 Antigravity 登录,与终端中的 agy 帐户分开。",
|
||||
"antigravityAccount": "账户",
|
||||
"antigravitySignInNeeded": "聊天需要单独的 Antigravity 登录,与终端中的 agy 帐户分开。"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
Reference in New Issue
Block a user