import { ActivityIndicator, Pressable, SectionList, Text, TextInput, View } from 'react-native' import { GitBranch, Minus, MoreHorizontal, Plus, Sparkles } from 'lucide-react-native' import { colors, spacing } from '../theme/mobile-theme' import { MobileSourceControlReviewEntry } from './mobile-source-control-review-entry' import { KEYBOARD_COMMIT_BAR_CLEARANCE } from './mobile-source-control-screen-state' import { makeRenderFileRow, BranchCompareFooter } from './MobileSourceControlFileRows' import type { MobileSourceControlState } from './use-mobile-source-control-state' import { styles } from './mobile-source-control-styles' type Props = { state: MobileSourceControlState hostId: string worktreeId: string name: string } // The ready-state body: summary card, changed-files list, and commit bar. export function MobileSourceControlContent({ state, hostId, worktreeId, name }: Props) { const { connState, insets, screenState, busyAction, commitMessage, setCommitMessage, generatingMessage, setShowActionSheet, setDiscardTarget, actionError, keyboardLift, openingPath, openingBranchPath, status, sections, branchEntries, hasVisibleChanges, reviewableCount, stageablePaths, unstageablePaths, stagedCount, unstagedCount, branchLabel, syncLabel, primaryAction, stageAll, unstageAll, generateCommitMessage, cancelGenerateCommitMessage, abortConflictOperation, openFile, openBranchDiff, runGitAction } = state const ioBusy = busyAction !== null || openingPath !== null || openingBranchPath !== null const shouldShowGenerateButton = stagedCount > 0 || generatingMessage return ( <> {branchLabel} {syncLabel ? {syncLabel} : null} {unstagedCount} changed {stagedCount} staged {branchEntries.length > 0 ? ( {branchEntries.length} on branch ) : null} {status && status.conflictOperation !== 'unknown' ? ( {status.conflictOperation} {(status.conflictOperation === 'merge' || status.conflictOperation === 'rebase') && ( [styles.abortButton, pressed && styles.abortPressed]} disabled={busyAction !== null} onPress={() => void abortConflictOperation(status.conflictOperation)} > {busyAction === `abort-${status.conflictOperation}` ? 'Aborting…' : `Abort ${status.conflictOperation}`} )} ) : null} {actionError ? ( {actionError} ) : null} [ styles.bulkButton, (stageablePaths.length === 0 || ioBusy) && styles.bulkButtonDisabled, pressed && styles.bulkButtonPressed ]} onPress={() => void stageAll()} disabled={ioBusy || stageablePaths.length === 0} > {busyAction === 'stage-all' ? ( ) : ( )} Stage All [ styles.bulkButton, (unstageablePaths.length === 0 || ioBusy) && styles.bulkButtonDisabled, pressed && styles.bulkButtonPressed ]} onPress={() => void unstageAll()} disabled={ioBusy || unstageablePaths.length === 0} > {busyAction === 'unstage-all' ? ( ) : ( )} Unstage All [ styles.bulkMenuButton, pressed && styles.bulkButtonPressed, ioBusy && styles.bulkButtonDisabled ]} onPress={() => setShowActionSheet(true)} disabled={ioBusy} hitSlop={8} accessibilityLabel="Open source control actions" > {!hasVisibleChanges ? ( No Changes Working tree is clean. ) : ( `${item.area}:${item.path}:${item.oldPath ?? ''}`} renderSectionHeader={({ section }) => ( {section.title} {section.data.length} )} ListFooterComponent={ } stickySectionHeadersEnabled={false} contentContainerStyle={styles.listContent} /> )} 0 ? keyboardLift + KEYBOARD_COMMIT_BAR_CLEARANCE : keyboardLift, paddingBottom: keyboardLift > 0 ? spacing.md : spacing.md + insets.bottom } ]} > {stagedCount === 0 ? ( No staged files ) : ( )} {shouldShowGenerateButton ? ( [ styles.generateButton, busyAction !== null && styles.commitButtonDisabled, pressed && styles.commitButtonPressed ]} // Why: commit-message AI belongs to the commit path; hiding it // during Stage All keeps the quick action visually unambiguous. disabled={busyAction !== null} onPress={() => generatingMessage ? cancelGenerateCommitMessage() : void generateCommitMessage() } accessibilityLabel={ generatingMessage ? 'Cancel commit message generation' : 'Generate commit message with AI' } > {generatingMessage ? ( ) : ( )} ) : null} [ styles.commitButton, primaryAction.disabled && styles.commitButtonDisabled, pressed && styles.commitButtonPressed ]} onPress={primaryAction.onPress} disabled={primaryAction.disabled} accessibilityLabel={primaryAction.accessibilityLabel} accessibilityHint={primaryAction.accessibilityHint} > {primaryAction.loading ? ( ) : ( {primaryAction.label} )} ) }