mirror of
https://github.com/stablyai/orca.git
synced 2026-10-06 08:02:28 +00:00
* fix(mobile): keep source-control layout steady while Create PR eligibility loads The Create PR entry unmounted until the first hostedReview.getCreationEligibility answer arrived, so on a cold open the changed-files list painted first and then shifted down 54pt (createPrBlock marginTop 12 + createPrButton minHeight 42) when the button appeared — while the user was already tapping (#8411). - buildMobileCreatePrAction: cold loading now reserves the row with a disabled placeholder instead of unmounting it. - useMobileHostedReviewEligibility: a fetch-imminent idle frame renders as an in-flight load, so the reservation is present on the first painted frame. - New per-worktree+branch memory of the last resolved eligibility seeds cold loads, so branches whose answer is hidden (existing review, unsupported provider) do not get a placeholder that collapses on every reopen. Fixes #8411 * fix(mobile): harden source-control layout reservation * fix(mobile): keep review status row footprint fixed * fix(mobile): derive eligibility state from keyed snapshots
248 lines
5.7 KiB
TypeScript
248 lines
5.7 KiB
TypeScript
import { StyleSheet } from 'react-native'
|
|
import { colors, radii, spacing, typography } from '../theme/mobile-theme'
|
|
import { diffStyles } from './mobile-source-control-diff-styles'
|
|
import { listStyles } from './mobile-source-control-list-styles'
|
|
|
|
const baseStyles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: colors.bgBase
|
|
},
|
|
header: {
|
|
backgroundColor: colors.bgPanel,
|
|
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
borderBottomColor: colors.borderSubtle
|
|
},
|
|
topBar: {
|
|
minHeight: 58,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
paddingHorizontal: spacing.sm
|
|
},
|
|
backButton: {
|
|
width: 36,
|
|
height: 36,
|
|
borderRadius: 18,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
marginRight: spacing.xs
|
|
},
|
|
backButtonPressed: {
|
|
backgroundColor: colors.bgRaised
|
|
},
|
|
titleBlock: {
|
|
flex: 1,
|
|
minWidth: 0
|
|
},
|
|
title: {
|
|
color: colors.textPrimary,
|
|
fontSize: 16,
|
|
fontWeight: '700'
|
|
},
|
|
meta: {
|
|
color: colors.textSecondary,
|
|
fontSize: typography.metaSize,
|
|
marginTop: 2
|
|
},
|
|
refreshButton: {
|
|
width: 36,
|
|
height: 36,
|
|
borderRadius: radii.button,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
marginLeft: spacing.xs
|
|
},
|
|
refreshButtonPressed: {
|
|
backgroundColor: colors.bgRaised
|
|
},
|
|
refreshButtonDisabled: {
|
|
opacity: 0.45
|
|
},
|
|
summaryCard: {
|
|
margin: spacing.lg,
|
|
marginBottom: spacing.sm,
|
|
padding: spacing.md,
|
|
borderRadius: radii.card,
|
|
backgroundColor: colors.bgPanel,
|
|
borderWidth: StyleSheet.hairlineWidth,
|
|
borderColor: colors.borderSubtle
|
|
},
|
|
summaryHeader: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
gap: spacing.md
|
|
},
|
|
branchLine: {
|
|
flex: 1,
|
|
minWidth: 0,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: spacing.xs
|
|
},
|
|
branchText: {
|
|
flex: 1,
|
|
color: colors.textPrimary,
|
|
fontSize: typography.bodySize,
|
|
fontWeight: '600'
|
|
},
|
|
syncText: {
|
|
color: colors.textSecondary,
|
|
fontSize: typography.metaSize
|
|
},
|
|
countRow: {
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
gap: spacing.md,
|
|
marginTop: spacing.sm
|
|
},
|
|
countText: {
|
|
color: colors.textSecondary,
|
|
fontSize: typography.metaSize
|
|
},
|
|
// Separate line under counts — keeps Abort inside the card on narrow phones.
|
|
conflictRow: {
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
alignItems: 'center',
|
|
gap: spacing.sm,
|
|
marginTop: spacing.sm,
|
|
alignSelf: 'flex-start',
|
|
maxWidth: '100%'
|
|
},
|
|
conflictText: {
|
|
color: colors.statusAmber,
|
|
fontSize: typography.metaSize,
|
|
textTransform: 'capitalize'
|
|
},
|
|
// Match bulk-action hit target so Abort reads as a real control, not a chip.
|
|
abortButton: {
|
|
minHeight: 32,
|
|
paddingHorizontal: spacing.md,
|
|
paddingVertical: spacing.xs,
|
|
borderRadius: radii.button,
|
|
borderWidth: 1,
|
|
borderColor: colors.statusAmber,
|
|
backgroundColor: colors.bgRaised,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
flexShrink: 0
|
|
},
|
|
abortPressed: {
|
|
opacity: 0.75
|
|
},
|
|
abortButtonDisabled: {
|
|
opacity: 0.45
|
|
},
|
|
abortText: {
|
|
color: colors.statusAmber,
|
|
fontSize: typography.bodySize,
|
|
fontWeight: '600',
|
|
textTransform: 'capitalize'
|
|
},
|
|
reconnectBanner: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: spacing.sm,
|
|
marginHorizontal: spacing.lg,
|
|
marginTop: spacing.lg,
|
|
marginBottom: -spacing.sm,
|
|
paddingHorizontal: spacing.md,
|
|
paddingVertical: spacing.sm,
|
|
borderRadius: radii.button,
|
|
backgroundColor: colors.bgRaised,
|
|
borderWidth: StyleSheet.hairlineWidth,
|
|
borderColor: colors.statusAmber
|
|
},
|
|
reconnectBannerText: {
|
|
color: colors.textPrimary,
|
|
fontSize: typography.metaSize
|
|
},
|
|
actionError: {
|
|
marginTop: spacing.sm,
|
|
paddingHorizontal: spacing.md,
|
|
paddingVertical: spacing.sm,
|
|
borderRadius: radii.button,
|
|
backgroundColor: colors.bgRaised,
|
|
borderWidth: StyleSheet.hairlineWidth,
|
|
borderColor: colors.statusRed
|
|
},
|
|
actionErrorText: {
|
|
color: colors.textPrimary,
|
|
fontSize: typography.metaSize,
|
|
lineHeight: 16
|
|
},
|
|
bulkRow: {
|
|
flexDirection: 'row',
|
|
gap: spacing.sm,
|
|
marginTop: spacing.md
|
|
},
|
|
bulkButton: {
|
|
flex: 1,
|
|
minHeight: 36,
|
|
borderRadius: radii.button,
|
|
backgroundColor: colors.bgRaised,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
flexDirection: 'row',
|
|
gap: spacing.xs
|
|
},
|
|
bulkMenuButton: {
|
|
width: 42,
|
|
minHeight: 36,
|
|
borderRadius: radii.button,
|
|
backgroundColor: colors.bgRaised,
|
|
alignItems: 'center',
|
|
justifyContent: 'center'
|
|
},
|
|
bulkButtonDisabled: {
|
|
opacity: 0.45
|
|
},
|
|
bulkButtonPressed: {
|
|
opacity: 0.75
|
|
},
|
|
bulkButtonText: {
|
|
color: colors.textPrimary,
|
|
fontSize: typography.bodySize,
|
|
fontWeight: '600'
|
|
},
|
|
createPrBlock: {
|
|
marginTop: spacing.md
|
|
},
|
|
createPrButton: {
|
|
height: 42,
|
|
borderRadius: radii.button,
|
|
backgroundColor: colors.textPrimary,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
flexDirection: 'row',
|
|
gap: spacing.xs,
|
|
paddingHorizontal: spacing.md
|
|
},
|
|
createPrButtonDisabled: {
|
|
backgroundColor: colors.bgRaised,
|
|
borderWidth: StyleSheet.hairlineWidth,
|
|
borderColor: colors.borderSubtle
|
|
},
|
|
createPrButtonPressed: {
|
|
opacity: 0.78
|
|
},
|
|
createPrButtonText: {
|
|
color: colors.bgBase,
|
|
fontSize: typography.bodySize,
|
|
fontWeight: '700'
|
|
},
|
|
createPrButtonTextDisabled: {
|
|
color: colors.textSecondary
|
|
},
|
|
createPrButtonHint: {
|
|
fontSize: typography.metaSize,
|
|
fontWeight: '600',
|
|
lineHeight: 16,
|
|
textAlign: 'center',
|
|
flexShrink: 1
|
|
}
|
|
})
|
|
|
|
export const styles = { ...baseStyles, ...listStyles, ...diffStyles }
|