From 299a47af4ad00f04b1bbed5011007e8d2cb71ce4 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Fri, 6 Nov 2026 19:09:12 -0800 Subject: [PATCH] Use one shared Hide button for chat cards (#38999) * feat(native-chat): one Hide button and toast for chat cards; PR card setting beside Changed files The opened-PR card now uses the changed-files card's Hide control and Hidden toast through a shared NativeChatCardHideButton, and its switch moves to Settings > Chat UI > Appearance next to Changed files summary, where Reset restores both. The saved key is unchanged. * refactor(native-chat): read the opened-PR card switch through its predicate * test(settings): Reset turns both hidden chat cards back on * Preserve the existing opened pull request Hide aria label * fix(native-chat): keep the gap before the PR card's Hide button --- .../native-chat/NativeChatCardHideButton.tsx | 44 +++++++++++++++++ ...ativeChatOpenedPullRequestCard.fixture.tsx | 26 ++++++++++ .../NativeChatOpenedPullRequestCard.tsx | 41 ++++++++-------- .../NativeChatTurnDiffRollup.fixture.tsx | 9 ++++ .../native-chat/NativeChatTurnDiffRollup.tsx | 47 +++++++------------ 5 files changed, 115 insertions(+), 52 deletions(-) create mode 100644 src/renderer/src/components/native-chat/NativeChatCardHideButton.tsx create mode 100644 src/renderer/src/components/native-chat/NativeChatOpenedPullRequestCard.fixture.tsx diff --git a/src/renderer/src/components/native-chat/NativeChatCardHideButton.tsx b/src/renderer/src/components/native-chat/NativeChatCardHideButton.tsx new file mode 100644 index 00000000000..d951ad00f5b --- /dev/null +++ b/src/renderer/src/components/native-chat/NativeChatCardHideButton.tsx @@ -0,0 +1,44 @@ +import { EyeOff } from 'lucide-react' +import { Button } from '@/components/ui/button' +import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' +import { translate } from '@/i18n/i18n' +import { hideNativeChatCardKind } from './native-chat-card-kind-hidden-toast' +import type { GlobalSettings } from '../../../../shared/global-settings-types' + +/** Put on a hideable chat card's outer element so its Hide button reveals on card hover. */ +export const NATIVE_CHAT_HIDEABLE_CARD_CLASS = 'group/chat-card' + +/** The Hide icon at the end of a chat card's header, shown on card hover or keyboard focus. */ +export function NativeChatCardHideButton({ + updates, + settingSectionId, + hiddenMessage, + ariaLabel +}: { + updates: Partial + settingSectionId: string + hiddenMessage: string + ariaLabel?: string +}): React.JSX.Element { + const label = translate('components.native-chat.turnDiff.hide', 'Hide') + return ( + // Keep the header one text line tall, as the transcript row-height estimate assumes. + + + + + + + {label} + + + + ) +} diff --git a/src/renderer/src/components/native-chat/NativeChatOpenedPullRequestCard.fixture.tsx b/src/renderer/src/components/native-chat/NativeChatOpenedPullRequestCard.fixture.tsx new file mode 100644 index 00000000000..103ed3b3151 --- /dev/null +++ b/src/renderer/src/components/native-chat/NativeChatOpenedPullRequestCard.fixture.tsx @@ -0,0 +1,26 @@ +import { defineFixture } from '../../component-fixtures/component-fixture' +import { NativeChatOpenedPullRequestCard } from './NativeChatOpenedPullRequestCard' +import type { NativeChatOpenedPullRequest } from '../../../../shared/native-chat/tools/native-chat-opened-pull-requests' + +const pullRequest: NativeChatOpenedPullRequest = { + provider: 'github', + url: 'https://github.com/stablyai/orca/pull/3', + slug: { owner: 'stablyai', repo: 'orca' }, + number: 3 +} + +// Keyboard focus shows the Hide button, as card hover does, without a pointer in the headless shot. +function focusHide(frame: HTMLElement): void { + frame.ownerDocument.dispatchEvent(new KeyboardEvent('keydown', { key: 'Tab', bubbles: true })) + frame.querySelector('button')?.focus() +} + +export const card = defineFixture({ + width: 560, + render: () => +}) +export const hideShown = defineFixture({ + width: 560, + render: () => , + interact: focusHide +}) diff --git a/src/renderer/src/components/native-chat/NativeChatOpenedPullRequestCard.tsx b/src/renderer/src/components/native-chat/NativeChatOpenedPullRequestCard.tsx index 4589b2ffe9a..be5d14ed507 100644 --- a/src/renderer/src/components/native-chat/NativeChatOpenedPullRequestCard.tsx +++ b/src/renderer/src/components/native-chat/NativeChatOpenedPullRequestCard.tsx @@ -10,7 +10,6 @@ import { import { GitPullRequest } from 'lucide-react' import { translate } from '@/i18n/i18n' import { cn } from '@/lib/utils' -import { EyeOffDismissButton } from '@/components/dismiss/EyeOffDismissButton' import { getReviewStateIcon } from '@/components/github/review-state-presentation' import { DiffLineCounts } from '@/components/right-sidebar/source-control/listing/diff-line-counts' import type { GitHubIssueOrPRLink } from '../../../../shared/github/links' @@ -20,7 +19,10 @@ import { type NativeChatOpenedPullRequest } from '../../../../shared/native-chat/tools/native-chat-opened-pull-requests' import { NATIVE_CHAT_OPENED_PULL_REQUESTS_SETTING_SECTION_ID } from '../settings/chat/native-chat-opened-pull-requests-setting-target' -import { hideNativeChatCardKind } from './native-chat-card-kind-hidden-toast' +import { + NativeChatCardHideButton, + NATIVE_CHAT_HIDEABLE_CARD_CLASS +} from './NativeChatCardHideButton' import { githubLinkPreviewKey, loadGitHubLinkPreview, @@ -214,8 +216,10 @@ export function NativeChatOpenedPullRequestCard({ const [first] = pullRequests const { githubRepo } = useContext(NativeChatLinkPeekContext) return ( -
-
+
+
{pullRequests.length === 1 && first ? translate('components.native-chat.openedPullRequests.one', 'Opened {{name}}', { @@ -227,24 +231,19 @@ export function NativeChatOpenedPullRequestCard({ { count: pullRequests.length, defaultValue_one: 'Opened {{count}} pull request' } )} +
- - void hideNativeChatCardKind( - { nativeChatOpenedPullRequests: false }, - NATIVE_CHAT_OPENED_PULL_REQUESTS_SETTING_SECTION_ID, - translate( - 'components.native-chat.openedPullRequests.hidden', - "Orca won't show opened pull requests anymore" - ) - ) - } - className="absolute right-1.5 top-1.5 opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100" - />
{pullRequests.map((pullRequest) => ( ('button')?.click() } }) +export const hideShown = defineFixture({ + width: 560, + render: () => , + // Keyboard focus shows the Hide button, as card hover does, without a pointer in the headless shot. + interact: (frame) => { + frame.ownerDocument.dispatchEvent(new KeyboardEvent('keydown', { key: 'Tab', bubbles: true })) + frame.querySelector('button[aria-label="Hide"]')?.focus() + } +}) const session: NativeChatLiveSession = { messages, diff --git a/src/renderer/src/components/native-chat/NativeChatTurnDiffRollup.tsx b/src/renderer/src/components/native-chat/NativeChatTurnDiffRollup.tsx index 5adace38bb2..0ddf64928c4 100644 --- a/src/renderer/src/components/native-chat/NativeChatTurnDiffRollup.tsx +++ b/src/renderer/src/components/native-chat/NativeChatTurnDiffRollup.tsx @@ -1,12 +1,14 @@ -import { ChevronRight, EyeOff } from 'lucide-react' +import { ChevronRight } from 'lucide-react' import { Button } from '@/components/ui/button' -import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' import { translate } from '@/i18n/i18n' import { NATIVE_CHAT_TURN_DIFF_SETTING_SECTION_ID } from '../settings/chat/native-chat-turn-diff-setting-target' import { DiffLineCounts } from '../right-sidebar/source-control/listing/diff-line-counts' import { NativeChatDiffCard } from './NativeChatDiffCard' import { NativeChatExpandable } from './NativeChatExpandable' -import { hideNativeChatCardKind } from './native-chat-card-kind-hidden-toast' +import { + NativeChatCardHideButton, + NATIVE_CHAT_HIDEABLE_CARD_CLASS +} from './NativeChatCardHideButton' import { useNativeChatDisclosure } from './native-chat-disclosure-store' import { nativeChatEditFileBaseName } from '../../../../shared/native-chat/tools/native-chat-edit-model' import { @@ -63,14 +65,6 @@ function TurnDiffFileRow({ file }: { file: NativeChatTurnDiffFile }): React.JSX. ) } -function hideTurnDiffs(): Promise { - return hideNativeChatCardKind( - { nativeChatTurnDiffSummary: false }, - NATIVE_CHAT_TURN_DIFF_SETTING_SECTION_ID, - translate('components.native-chat.turnDiff.hidden', "Orca won't show turn diffs anymore") - ) -} - export function NativeChatTurnDiffRollup({ diff }: { @@ -83,7 +77,9 @@ export function NativeChatTurnDiffRollup({ const files = showAll ? diff.files : diff.files.slice(0, NATIVE_CHAT_TURN_DIFF_FILE_LIMIT) const remaining = diff.files.length - files.length return ( -
+
{translate('components.native-chat.turnDiff.changedFiles', '{{count}} changed files', { @@ -95,25 +91,14 @@ export function NativeChatTurnDiffRollup({ {diff.truncated ? ( {translate('components.native-chat.turnDiff.partial', 'Partial diff')} ) : null} - {/* Shown on card hover or keyboard focus, like the transcript's other row actions. The - negative margin keeps the header one text line tall, as the row-height estimate assumes. */} - - - - - - - {translate('components.native-chat.turnDiff.hide', 'Hide')} - - - +
{files.map((file) => (