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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | import React, { useCallback } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { colors } from '../theme/colors';
import type { CommitEntry } from '../api/repos';
interface CommitRowProps {
commit: CommitEntry;
onPress?: (commit: CommitEntry) => void;
}
function formatRelative(dateStr: string): string {
const diff = Date.now() - new Date(dateStr).getTime();
const mins = Math.floor(diff / 60000);
if (mins < 1) return 'just now';
if (mins < 60) return `${mins}m ago`;
const hrs = Math.floor(mins / 60);
if (hrs < 24) return `${hrs}h ago`;
const days = Math.floor(hrs / 24);
if (days < 30) return `${days}d ago`;
const months = Math.floor(days / 30);
if (months < 12) return `${months}mo ago`;
return `${Math.floor(months / 12)}y ago`;
}
function shortMessage(msg: string): string {
const firstLine = msg.split('\n')[0] ?? msg;
if (firstLine.length <= 72) return firstLine;
return firstLine.slice(0, 69) + '...';
}
export function CommitRow({ commit, onPress }: CommitRowProps): React.ReactElement {
const handlePress = useCallback(() => onPress?.(commit), [commit, onPress]);
return (
<TouchableOpacity
style={styles.row}
onPress={handlePress}
activeOpacity={onPress !== undefined ? 0.75 : 1}
>
<View style={styles.content}>
<Text style={styles.message} numberOfLines={2}>
{shortMessage(commit.message)}
</Text>
<View style={styles.meta}>
<Text style={styles.author}>{commit.authorName}</Text>
<Text style={styles.dot}>·</Text>
<Text style={styles.metaText}>{formatRelative(commit.authorDate)}</Text>
</View>
</View>
<View style={styles.shaContainer}>
<Text style={styles.sha}>{commit.sha.slice(0, 7)}</Text>
</View>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
row: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: colors.bgSecondary,
borderBottomWidth: 1,
borderBottomColor: colors.border,
paddingVertical: 12,
paddingHorizontal: 16,
gap: 12,
},
content: {
flex: 1,
gap: 4,
},
message: {
fontSize: 14,
color: colors.text,
lineHeight: 20,
},
meta: {
flexDirection: 'row',
alignItems: 'center',
gap: 5,
},
author: {
fontSize: 12,
fontWeight: '500',
color: colors.textMuted,
},
dot: {
fontSize: 12,
color: colors.textMuted,
},
metaText: {
fontSize: 12,
color: colors.textMuted,
},
shaContainer: {
paddingHorizontal: 8,
paddingVertical: 3,
backgroundColor: colors.bgTertiary,
borderRadius: 4,
borderWidth: 1,
borderColor: colors.border,
},
sha: {
fontSize: 12,
fontFamily: 'monospace',
color: colors.textLink,
},
});
|