diff --git a/src/renderer/src/components/CodexRestartChip.tsx b/src/renderer/src/components/CodexRestartChip.tsx index a4f11bdc0bb..522a47fc03e 100644 --- a/src/renderer/src/components/CodexRestartChip.tsx +++ b/src/renderer/src/components/CodexRestartChip.tsx @@ -1,4 +1,4 @@ -import { useEffect, useId, useMemo, useRef, useState } from 'react' +import { useEffect, useId, useMemo, useRef } from 'react' import { useShallow } from 'zustand/react/shallow' import { RefreshCw } from 'lucide-react' import { Button } from '@/components/ui/button' @@ -6,11 +6,7 @@ import { useAppStore } from '../store' import { selectCodexRestartInputs } from './codex-restart-chip-inputs' import { translate } from '@/i18n/i18n' import { shouldFocusMobileDriverAction } from './terminal-pane/mobile-driver-overlay-focus' -import { - buildCodexRestartNoticeKey, - createCodexRestartOverlayCollapseState, - getCodexRestartOverlayCollapseState -} from './codex-restart-overlay-collapse' +import { buildCodexRestartNoticeKey } from './codex-restart-notice-key' const EMPTY_TABS: { id: string }[] = [] @@ -99,16 +95,6 @@ export default function CodexRestartChip({ const clearCodexRestartNotice = useAppStore((s) => s.clearCodexRestartNotice) const noticeKey = restartNotice ? buildCodexRestartNoticeKey(restartNotice) : null - const [collapseState, setCollapseState] = useState(() => - createCodexRestartOverlayCollapseState(noticeKey) - ) - - const currentCollapseState = getCodexRestartOverlayCollapseState(collapseState, noticeKey) - useEffect(() => { - // Why: a new account switch must reopen loud mode without updating state - // during render, which can trip React's external-store snapshot guard. - setCollapseState((state) => getCodexRestartOverlayCollapseState(state, noticeKey)) - }, [noticeKey]) if (staleWorktreePtyIds.length === 0 || !restartNotice) { return null @@ -122,22 +108,11 @@ export default function CodexRestartChip({ dismissStaleWorktreePtyIds(staleWorktreePtyIds, clearCodexRestartNotice) } - if (currentCollapseState.collapsed) { - return ( - setCollapseState(createCodexRestartOverlayCollapseState(noticeKey))} - onRestart={handleRestart} - /> - ) - } - return ( setCollapseState({ noticeKey, collapsed: true })} onDismiss={handleDismiss} onRestart={handleRestart} /> @@ -148,14 +123,12 @@ function LoudRestartOverlay({ isVisible, noticeKey, restartNotice, - onCollapse, onDismiss, onRestart }: { isVisible: boolean noticeKey: string | null restartNotice: RestartNotice - onCollapse: () => void onDismiss: () => void onRestart: () => void }): React.JSX.Element { @@ -218,9 +191,6 @@ function LoudRestartOverlay({ - - - - ) -} diff --git a/src/renderer/src/components/codex-restart-chip.test.ts b/src/renderer/src/components/codex-restart-chip.test.ts index af542372bdd..468bb7c58df 100644 --- a/src/renderer/src/components/codex-restart-chip.test.ts +++ b/src/renderer/src/components/codex-restart-chip.test.ts @@ -92,7 +92,7 @@ describe('CodexRestartChip helpers', () => { expect(clearCodexRestartNotice).toHaveBeenCalledTimes(2) }) - it('renders a stale Codex restart notice without an external-store update loop', async () => { + it('renders only account-resolution actions without an external-store update loop', async () => { useAppStore.setState({ tabsByWorktree: { 'worktree-1': [ @@ -124,5 +124,8 @@ describe('CodexRestartChip helpers', () => { }) expect(container.textContent).toContain('Codex is still signed in as old@example.com') + expect( + Array.from(container.querySelectorAll('button'), (button) => button.textContent?.trim()) + ).toEqual(['Keep old account', 'Restart']) }) }) diff --git a/src/renderer/src/components/codex-restart-notice-key.test.ts b/src/renderer/src/components/codex-restart-notice-key.test.ts new file mode 100644 index 00000000000..17fbca689d9 --- /dev/null +++ b/src/renderer/src/components/codex-restart-notice-key.test.ts @@ -0,0 +1,13 @@ +import { describe, expect, it } from 'vitest' +import { buildCodexRestartNoticeKey } from './codex-restart-notice-key' + +describe('codex restart notice key', () => { + it('builds a stable notice key from account labels', () => { + expect( + buildCodexRestartNoticeKey({ + previousAccountLabel: 'Account A', + nextAccountLabel: 'Account B' + }) + ).toBe('Account A\u0000Account B') + }) +}) diff --git a/src/renderer/src/components/codex-restart-notice-key.ts b/src/renderer/src/components/codex-restart-notice-key.ts new file mode 100644 index 00000000000..3a3832d2c6a --- /dev/null +++ b/src/renderer/src/components/codex-restart-notice-key.ts @@ -0,0 +1,6 @@ +export function buildCodexRestartNoticeKey(args: { + previousAccountLabel: string + nextAccountLabel: string +}): string { + return `${args.previousAccountLabel}\u0000${args.nextAccountLabel}` +} diff --git a/src/renderer/src/components/codex-restart-overlay-collapse.test.ts b/src/renderer/src/components/codex-restart-overlay-collapse.test.ts deleted file mode 100644 index 255925ee8dc..00000000000 --- a/src/renderer/src/components/codex-restart-overlay-collapse.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { - buildCodexRestartNoticeKey, - createCodexRestartOverlayCollapseState, - getCodexRestartOverlayCollapseState -} from './codex-restart-overlay-collapse' - -describe('codex restart overlay collapse', () => { - it('builds a stable notice key from account labels', () => { - expect( - buildCodexRestartNoticeKey({ - previousAccountLabel: 'Account A', - nextAccountLabel: 'Account B' - }) - ).toBe('Account A\u0000Account B') - }) - - it('reopens loud mode when the notice key changes', () => { - const collapsed = { - noticeKey: buildCodexRestartNoticeKey({ - previousAccountLabel: 'Account A', - nextAccountLabel: 'Account B' - }), - collapsed: true - } - - expect( - getCodexRestartOverlayCollapseState( - collapsed, - buildCodexRestartNoticeKey({ - previousAccountLabel: 'Account A', - nextAccountLabel: 'Account C' - }) - ) - ).toEqual({ - noticeKey: 'Account A\u0000Account C', - collapsed: false - }) - }) - - it('preserves collapse state for the same notice key', () => { - const noticeKey = buildCodexRestartNoticeKey({ - previousAccountLabel: 'Account A', - nextAccountLabel: 'Account B' - }) - const collapsed = { noticeKey, collapsed: true } - - expect(getCodexRestartOverlayCollapseState(collapsed, noticeKey)).toBe(collapsed) - }) - - it('creates loud mode for a new notice key', () => { - const noticeKey = buildCodexRestartNoticeKey({ - previousAccountLabel: 'Account A', - nextAccountLabel: 'Account B' - }) - - expect(createCodexRestartOverlayCollapseState(noticeKey)).toEqual({ - noticeKey, - collapsed: false - }) - }) -}) diff --git a/src/renderer/src/components/codex-restart-overlay-collapse.ts b/src/renderer/src/components/codex-restart-overlay-collapse.ts deleted file mode 100644 index edc4e786eab..00000000000 --- a/src/renderer/src/components/codex-restart-overlay-collapse.ts +++ /dev/null @@ -1,32 +0,0 @@ -export type CodexRestartOverlayCollapseState = { - noticeKey: string | null - collapsed: boolean -} - -export function buildCodexRestartNoticeKey(args: { - previousAccountLabel: string - nextAccountLabel: string -}): string { - return `${args.previousAccountLabel}\u0000${args.nextAccountLabel}` -} - -export function getCodexRestartOverlayCollapseState( - state: CodexRestartOverlayCollapseState, - noticeKey: string | null -): CodexRestartOverlayCollapseState { - return state.noticeKey === noticeKey - ? state - : { - noticeKey, - collapsed: false - } -} - -export function createCodexRestartOverlayCollapseState( - noticeKey: string | null -): CodexRestartOverlayCollapseState { - return { - noticeKey, - collapsed: false - } -} diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 9c34e4df489..1d7263b6a1d 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -769,8 +769,7 @@ "9263e75f49": "Codex is using the previous account", "d3e8a1f4b2": "Account switched", "9375620cc3": "Restart this session to use {{value0}}. It stays on the previous account until you do.", - "6133594b12": "Keep old account", - "b9000fe511": "Not now" + "6133594b12": "Keep old account" }, "FirstLaunchBanner": { "b9e1b966c7": "Dismiss notice", diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 4311a1a9b12..a10a0ea150a 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -746,8 +746,7 @@ "a4c8e1b2f7": "Codex sigue conectado como {{value0}}", "d3e8a1f4b2": "Cuenta cambiada", "9375620cc3": "Restart this session to use {{value0}}. It stays on the previous account until you do.", - "6133594b12": "Keep old account", - "b9000fe511": "Not now" + "6133594b12": "Keep old account" }, "FirstLaunchBanner": { "b9e1b966c7": "Descartar aviso", diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index 891f1688b27..4531cc490a3 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -746,8 +746,7 @@ "a4c8e1b2f7": "Codex はまだ {{value0}} としてサインインしています", "d3e8a1f4b2": "アカウントを切り替えました", "9375620cc3": "Restart this session to use {{value0}}. It stays on the previous account until you do.", - "6133594b12": "Keep old account", - "b9000fe511": "Not now" + "6133594b12": "Keep old account" }, "FirstLaunchBanner": { "b9e1b966c7": "通知を閉じる", diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index b38075abb12..dd155b3a4bf 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -746,8 +746,7 @@ "a4c8e1b2f7": "Codex가 아직 {{value0}} 계정으로 로그인되어 있습니다", "d3e8a1f4b2": "계정 전환됨", "9375620cc3": "Restart this session to use {{value0}}. It stays on the previous account until you do.", - "6133594b12": "Keep old account", - "b9000fe511": "Not now" + "6133594b12": "Keep old account" }, "FirstLaunchBanner": { "b9e1b966c7": "알림 닫기", diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index 29b59a74789..825f838ddd4 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -746,8 +746,7 @@ "a4c8e1b2f7": "Codex 仍以 {{value0}} 身份登录", "d3e8a1f4b2": "账户已切换", "9375620cc3": "Restart this session to use {{value0}}. It stays on the previous account until you do.", - "6133594b12": "Keep old account", - "b9000fe511": "Not now" + "6133594b12": "Keep old account" }, "FirstLaunchBanner": { "b9e1b966c7": "关闭通知",