Files
orca/mobile/src/session/MobileSourceControlButton.tsx
T
Kelvin Amoaba 01efbf8cd1 feat(mobile): show merged, closed and draft PR icons by state (#40921)
* feat(mobile): pick the PR glyph from PR state

Workspace rows always drew the open-PR glyph and only changed its color,
and the PR tab's state badge had no glyph. Both now show merged, closed and
draft glyphs, from one prStateIcon mapping that the details sheet and task
rows also use.

* feat(mobile): show the PR state on the session header's source-control button

The button always drew a branch glyph. When the worktree's catalog row has a
linked PR it now draws that PR's state glyph in its state colour, read from
the host list's worktree.ps query in its own component.

* fix(mobile): read the header's PR state from the catalog cache only

Opening a session must not request worktree.ps before its first paint, so the
source-control button reads what the host list last loaded instead of
fetching it.
2026-11-11 04:25:41 +00:00

49 lines
1.7 KiB
TypeScript

import { GitBranch } from 'lucide-react-native'
import { NavBarButton } from '../components/nav-bar/NavBarButton'
import { prStateIcon } from '../components/pr-state-token'
import { prStateColor } from '../components/WorktreeMetaGlyphs'
import {
HOST_LIST_TARGET,
hostWorktreeCatalogQuery,
NO_HOST_LIST_INPUT
} from '../host-screen/host-list-queries'
import { useMobileTranslation } from '../i18n/use-mobile-translation'
import { useHostQuery } from '../query/host-query'
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
import { UNCACHED_LINKED_PR_STATE } from '../../../src/shared/runtime-worktree-contracts'
// Its own component so catalog updates re-render only this button, not the whole session header.
export function MobileSourceControlButton({
hostId,
worktreeId,
active,
onPress
}: {
hostId: string
worktreeId: string
active: boolean
onPress: () => void
}) {
useMobileColorScheme()
const t = useMobileTranslation()
// Cache-only: the host list reads worktree.ps, and a session's first paint must not wait behind it.
const { data } = useHostQuery(
hostWorktreeCatalogQuery,
{ hostId, client: null },
HOST_LIST_TARGET,
NO_HOST_LIST_INPUT,
{ enabled: false }
)
const pr = data?.worktrees.find((row) => row.worktreeId === worktreeId)?.linkedPR ?? null
const knownState = pr && pr.state !== UNCACHED_LINKED_PR_STATE ? pr.state : null
return (
<NavBarButton
active={active}
accessibilityLabel={t('session.header.openSourceControl', 'Open source control')}
icon={pr ? prStateIcon(pr.state) : GitBranch}
iconColor={knownState ? prStateColor(knownState) : undefined}
onPress={onPress}
/>
)
}