Files
orca/mobile/src/source-control/MobileSourceControlHeader.tsx
T
Kelvin Amoaba f87a746200 feat(mobile): light and dark themes with desktop's palettes (#34217)
* feat(mobile): light and dark themes with desktop's palettes

Settings → Appearance offers System, Light and Dark. The shell passes the
resolved scheme to over-the-air pages in its init frame.

Fixes #22184

* fix(mobile): draw your chat messages in desktop's user bubble

Desktop uses a faint surface with a hairline border in both themes; the inverted fill went black in light.

* test(mobile): re-measure the page script sweep after the shared theme hooks

Every route now imports the theme hooks while the entry does not, so they emit one shared script (96 for the tree). Re-swept every route prefix; the worst route step is now 15.

* test(mobile): read themed stylesheets in the text-input font-size census

The census only unwrapped StyleSheet.create({...}); inputs styled through themedStyleSheet(() => ({...})) came back unread.
2026-10-27 17:35:31 +00:00

95 lines
2.9 KiB
TypeScript

import { Pressable, Text, View } from 'react-native'
import { ChevronLeft, ExternalLink, RefreshCw, X } from 'lucide-react-native'
import { colors } from '../theme/mobile-theme'
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
import { styles } from './mobile-source-control-styles'
type Props = {
embedded: boolean
worktreeLabel: string
ioBusy: boolean
onBack: () => void
// Dock dismissal does not pop a route; keep it separate from Back.
onClose: () => void
onRefresh: () => void
// Keep open-on-web in the header while the PR body scrolls.
onOpenPrWeb?: () => void
prNumber?: number | null
}
export function MobileSourceControlHeader({
embedded,
worktreeLabel,
ioBusy,
onBack,
onClose,
onRefresh,
onOpenPrWeb,
prNumber = null
}: Props) {
useMobileColorScheme()
return (
<View style={styles.topBar}>
{/* Dock dismissal and route Back have distinct semantics. */}
{embedded ? (
<Pressable
style={({ pressed }) => [styles.backButton, pressed && styles.backButtonPressed]}
onPress={onClose}
hitSlop={8}
accessibilityRole="button"
accessibilityLabel="Close source control"
>
<X size={22} color={colors.textSecondary} strokeWidth={2.2} />
</Pressable>
) : (
<Pressable
style={({ pressed }) => [styles.backButton, pressed && styles.backButtonPressed]}
onPress={onBack}
hitSlop={8}
accessibilityRole="button"
accessibilityLabel="Back to session"
>
<ChevronLeft size={22} color={colors.textSecondary} strokeWidth={2.2} />
</Pressable>
)}
<View style={styles.titleBlock}>
<Text style={styles.title} numberOfLines={1}>
Source Control
</Text>
<Text style={styles.meta} numberOfLines={1}>
{worktreeLabel}
</Text>
</View>
{onOpenPrWeb ? (
<Pressable
style={({ pressed }) => [styles.refreshButton, pressed && styles.refreshButtonPressed]}
onPress={onOpenPrWeb}
hitSlop={8}
accessibilityRole="link"
accessibilityLabel={
prNumber != null
? `Open pull request #${prNumber} on the web`
: 'Open pull request on the web'
}
>
<ExternalLink size={18} color={colors.textSecondary} strokeWidth={2.1} />
</Pressable>
) : null}
<Pressable
style={({ pressed }) => [
styles.refreshButton,
ioBusy && styles.refreshButtonDisabled,
pressed && styles.refreshButtonPressed
]}
onPress={onRefresh}
disabled={ioBusy}
hitSlop={8}
accessibilityRole="button"
accessibilityLabel="Refresh source control"
>
<RefreshCw size={18} color={colors.textSecondary} strokeWidth={2.1} />
</Pressable>
</View>
)
}