CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | import React, { useCallback } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
import { useCommits } from '../hooks/useRepo';
import { CommitRow } from '../components/CommitRow';
import { LoadingSpinner } from '../components/LoadingSpinner';
import { ErrorBanner } from '../components/ErrorBanner';
import { colors } from '../theme/colors';
import type { RepoStackParamList } from '../navigation/AppNavigator';
import type { CommitEntry } from '../api/repos';
type Props = NativeStackScreenProps<RepoStackParamList, 'Commits'>;
export function CommitsScreen({ route }: Props): React.ReactElement {
const { owner, repo, branch } = route.params;
const { commits, isLoading, error, loadMore, hasMore } = useCommits(
owner,
repo,
branch ?? 'HEAD',
);
const renderCommit = useCallback(
({ item }: { item: CommitEntry }) => <CommitRow commit={item} />,
[],
);
const keyExtractor = useCallback((item: CommitEntry) => item.sha, []);
const renderFooter = useCallback(() => {
if (!hasMore) return null;
return <LoadingSpinner size="small" />;
}, [hasMore]);
if (isLoading && commits.length === 0) return <LoadingSpinner fullScreen />;
return (
<SafeAreaView style={styles.safe} edges={['bottom']}>
{error !== null && <ErrorBanner message={error} />}
<FlatList
data={commits}
keyExtractor={keyExtractor}
renderItem={renderCommit}
onEndReached={loadMore}
onEndReachedThreshold={0.3}
ListFooterComponent={renderFooter}
ListEmptyComponent={
<View style={styles.emptyState}>
<Text style={styles.emptyText}>No commits found</Text>
</View>
}
ListHeaderComponent={
<View style={styles.header}>
<Text style={styles.headerText}>
{branch ?? 'HEAD'} — commit history
</Text>
</View>
}
style={styles.list}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
safe: {
flex: 1,
backgroundColor: colors.bg,
},
list: {
flex: 1,
},
header: {
padding: 12,
backgroundColor: colors.bgTertiary,
borderBottomWidth: 1,
borderBottomColor: colors.border,
},
headerText: {
fontSize: 12,
fontFamily: 'monospace',
color: colors.textMuted,
},
emptyState: {
padding: 40,
alignItems: 'center',
},
emptyText: {
fontSize: 14,
color: colors.textMuted,
},
});
|