Function bodies 80 total
EditScreenInfo function · typescript · L10-L47 (38 LOC)components/EditScreenInfo.tsx
export default function EditScreenInfo({ path }: { path: string }) {
return (
<View>
<View style={styles.getStartedContainer}>
<Text
style={styles.getStartedText}
lightColor="rgba(0,0,0,0.8)"
darkColor="rgba(255,255,255,0.8)">
Open up the code for this screen:
</Text>
<View
style={[styles.codeHighlightContainer, styles.homeScreenFilename]}
darkColor="rgba(255,255,255,0.05)"
lightColor="rgba(0,0,0,0.05)">
<MonoText>{path}</MonoText>
</View>
<Text
style={styles.getStartedText}
lightColor="rgba(0,0,0,0.8)"
darkColor="rgba(255,255,255,0.8)">
Change any of the text, save the file, and your app will automatically update.
</Text>
</View>
<View style={styles.helpContainer}>
<ExternalLink
style={styles.helpLink}
href="https://docs.expo.io/get-started/create-a-new-app/#openingExternalLink function · typescript · L6-L25 (20 LOC)components/ExternalLink.tsx
export function ExternalLink(
props: Omit<React.ComponentProps<typeof Link>, 'href'> & { href: string }
) {
return (
<Link
target="_blank"
{...props}
// @ts-expect-error: External URLs are not typed.
href={props.href}
onPress={(e) => {
if (Platform.OS !== 'web') {
// Prevent the default behavior of linking to the default browser on native.
e.preventDefault();
// Open the link in an in-app browser.
WebBrowser.openBrowserAsync(props.href as string);
}
}}
/>
);
}DashboardActions function · typescript · L11-L51 (41 LOC)components/home/DashboardActions.tsx
export function DashboardActions({ onNewSplit, onManualScan, onRecentLogs }: DashboardActionsProps) {
return (
<View className="mb-8">
<View className="flex-col gap-4">
{/* New Split Button — reduced vertical padding so height ~110px */}
<TouchableOpacity
onPress={onNewSplit}
activeOpacity={0.9}
className="w-full bg-primary py-4 px-6 rounded-[2.5rem] flex-col items-center justify-center gap-3 shadow-md shadow-primary/25"
>
<View className="w-12 h-12 bg-white/20 rounded-full items-center justify-center border border-white/30">
<Plus size={28} color="#ffffff" />
</View>
<Text className="text-white font-heading font-bold text-xl tracking-tight">New Split</Text>
</TouchableOpacity>
<View className="w-full flex-row gap-4">
<TouchableOpacity
onPress={onManualScan}
activeOpacity={0.8}
className="flex-1 bg-surface-container-lDashboardHeader function · typescript · L4-L10 (7 LOC)components/home/DashboardHeader.tsx
export function DashboardHeader() {
return (
<View className="px-6 py-4 mb-2">
<Text className="text-2xl font-heading font-black text-primary tracking-tight">Divvit</Text>
</View>
);
}MetricStats function · typescript · L17-L102 (86 LOC)components/home/MetricStats.tsx
export function MetricStats({ totalSplit, minutesSaved }: MetricStatsProps) {
return (
<View className="flex-row gap-4 mb-8 items-stretch">
{/* Total Split Card — amount bottom-aligned via justify-between */}
<View className="flex-1 bg-primary-container rounded-[2rem] p-6 shadow-md shadow-primary/20 min-h-[180px] justify-between">
<View className="flex-row justify-between items-start">
<Text className="text-sm font-heading font-bold text-white uppercase tracking-widest opacity-80">Total Split</Text>
<TrendingUp size={24} color="#ffffff" />
</View>
<View>
<Text className="text-4xl font-heading font-extrabold text-white tracking-tighter">{totalSplit}</Text>
<Text className="text-xs font-body font-semibold text-white/70 mt-1 uppercase tracking-wider">split so far...</Text>
</View>
</View>
{/* My Rewards Card */}
<View
className="flex-1 rounded-[2rem] min-h-[180px] justify-bPromotionCard function · typescript · L4-L34 (31 LOC)components/home/PromotionCard.tsx
export function PromotionCard() {
return (
<View className="mb-8">
<View className="flex-row justify-between items-end px-2 mb-4">
<Text className="text-xl font-heading font-extrabold tracking-tight text-on-surface">Promotions</Text>
<TouchableOpacity className="px-2">
<Text className="text-primary font-heading font-bold text-sm">See all</Text>
</TouchableOpacity>
</View>
<TouchableOpacity activeOpacity={0.9} className="relative overflow-hidden rounded-[2.5rem] h-48 bg-surface-container-highest">
<Image
source={{ uri: 'https://lh3.googleusercontent.com/aida-public/AB6AXuC0HuJSPVx3n6Fyd0eTXi_VplR-BSQaX7jW4h6o97bEff6gAdmiRhXUtVNkvcrn-HrzNLtI9iC_F8z_WrpW7rootEduIGxlNGBpkwCChLV7eWO65JYFZn6AaCsHe9tgDrvsEv02wV3UE1yAwXHG7yeHfjTkp_4djmU5nsy3L--XAWWzkjgRjFfKwTriERWLmmkewjZHYAt5lBx_0H_sqdvqd2lqAyAhbYhtzgupnt6KI_oaNPCOQfvOyvbXyVrUOOF4qc5Mgeruh2w' }}
style={{ position: 'absolute', top: 0, left: 0, right: 0RecentActivityList function · typescript · L17-L115 (99 LOC)components/home/RecentActivityList.tsx
export function RecentActivityList({ items, onItemPress, isLoading }: RecentActivityListProps) {
if (isLoading) {
return (
<View className="flex-col gap-4 mb-20">
<Text className="text-xl font-heading font-extrabold tracking-tight px-2 text-on-surface">Recent Activity</Text>
{[1, 2].map((i) => (
<View key={i} className="bg-white rounded-[1.5rem] p-4 flex-row items-center justify-between">
<View className="flex-row items-center gap-4 flex-1">
<View className="w-12 h-12 bg-gray-200 rounded-2xl" />
<View className="flex-1">
<View className="w-32 h-5 bg-gray-200 rounded mb-1" />
<View className="w-20 h-3 bg-gray-200 rounded" />
</View>
</View>
</View>
))}
</View>
);
}
return (
<View className="flex-col gap-4 mb-20">
<Text className="text-xl font-heading font-extrabold tracking-tight px-2 text-on-surface mb-2">ReceRepobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
ContactInfoCard function · typescript · L13-L68 (56 LOC)components/profile/ContactInfoCard.tsx
export default function ContactInfoCard({ isEditing, email, phone, setPhone, country }: Props) {
return (
<View className="bg-surface-container-low p-6 rounded-3xl space-y-6">
<View className="flex-row items-center justify-between mb-4">
<Text className="text-sm font-bold uppercase tracking-widest text-primary">Contact Information</Text>
<Contact color="rgba(75, 41, 180, 0.4)" size={20} />
</View>
<View className="space-y-4">
{/* Email */}
<View className="flex-row items-center bg-surface-container-lowest p-4 rounded-2xl">
<View className="w-10 h-10 rounded-xl items-center justify-center mr-4" style={{ backgroundColor: 'rgba(75, 41, 180, 0.05)' }}>
<Mail color="#4b29b4" size={20} />
</View>
<View className="flex-1">
<Text className="text-[10px] uppercase tracking-widerPaymentAccountsCard function · typescript · L13-L73 (61 LOC)components/profile/PaymentAccountsCard.tsx
export default function PaymentAccountsCard({ isEditing, venmoHandle, setVenmoHandle, cashappHandle, setCashappHandle }: Props) {
return (
<View className="bg-surface-container-low p-6 rounded-3xl mt-4">
<Text className="text-sm font-bold uppercase tracking-widest text-primary mb-4">Connected Accounts</Text>
<View className="space-y-3">
{/* Venmo */}
<View className="flex-row items-center justify-between bg-surface-container-lowest p-4 rounded-2xl">
<View className="flex-row items-center">
<View className="w-8 h-8 rounded-lg items-center justify-center mr-3" style={{ backgroundColor: 'rgba(0, 140, 255, 0.1)' }}>
<CreditCard color="#008CFF" size={16} />
</View>
{isEditing ? (
<View className="flex-row items-center">
<Text classNamQuickStatsCard function · typescript · L8-L23 (16 LOC)components/profile/QuickStatsCard.tsx
export default function QuickStatsCard({ totalSavings }: Props) {
return (
<View className="bg-primary p-6 rounded-3xl flex-col justify-between overflow-hidden relative mt-4">
<View className="absolute top-0 right-0 w-32 h-32 rounded-full -mr-16 -mt-16" style={{ backgroundColor: 'rgba(255, 255, 255, 0.1)' }} />
<View className="relative z-10">
<Text className="text-[10px] uppercase tracking-[0.2em] font-bold text-white opacity-70">Total Savings</Text>
<Text className="text-3xl font-extrabold mt-1 text-white">{totalSavings}</Text>
</View>
<TouchableOpacity className="relative z-10 mt-6 px-4 py-2 rounded-xl w-[40%] items-center" style={{ backgroundColor: 'rgba(255, 255, 255, 0.2)' }}>
<Text className="text-xs font-bold text-white">View Rewards</Text>
</TouchableOpacity>
</View>
);
}MonoText function · typescript · L3-L5 (3 LOC)components/StyledText.tsx
export function MonoText(props: TextProps) {
return <Text {...props} style={[props.style, { fontFamily: 'SpaceMono' }]} />;
}useThemeColor function · typescript · L19-L31 (13 LOC)components/Themed.tsx
export function useThemeColor(
props: { light?: string; dark?: string },
colorName: keyof typeof Colors.light & keyof typeof Colors.dark
) {
const theme = useColorScheme() ?? 'light';
const colorFromProps = props[theme];
if (colorFromProps) {
return colorFromProps;
} else {
return Colors[theme][colorName];
}
}Text function · typescript · L33-L38 (6 LOC)components/Themed.tsx
export function Text(props: TextProps) {
const { style, lightColor, darkColor, ...otherProps } = props;
const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
return <DefaultText style={[{ color }, style]} {...otherProps} />;
}View function · typescript · L40-L45 (6 LOC)components/Themed.tsx
export function View(props: ViewProps) {
const { style, lightColor, darkColor, ...otherProps } = props;
const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
return <DefaultView style={[{ backgroundColor }, style]} {...otherProps} />;
}useClientOnlyValue function · typescript · L2-L4 (3 LOC)components/useClientOnlyValue.ts
export function useClientOnlyValue<S, C>(server: S, client: C): S | C {
return client;
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
useClientOnlyValue function · typescript · L5-L12 (8 LOC)components/useClientOnlyValue.web.ts
export function useClientOnlyValue<S, C>(server: S, client: C): S | C {
const [value, setValue] = React.useState<S | C>(server);
React.useEffect(() => {
setValue(client);
}, [client]);
return value;
}useColorScheme function · typescript · L6-L8 (3 LOC)components/useColorScheme.web.ts
export function useColorScheme() {
return 'light';
}useAuth function · typescript · L27-L29 (3 LOC)context/AuthContext.tsx
export function useAuth() {
return useContext(AuthContext);
}AuthProvider function · typescript · L31-L244 (214 LOC)context/AuthContext.tsx
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [session, setSession] = useState<Session | null>(null);
const [user, setUser] = useState<User | null>(null);
const [profile, setProfile] = useState<any | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [hasProfile, setHasProfile] = useState(false);
const [hasOnboarded, setHasOnboarded] = useState(false);
// Fetch profile helper - returns the profile or null
const fetchProfile = useCallback(async (userId: string, accessToken?: string): Promise<any | null> => {
console.log('AuthContext: Fetching Profile for', userId);
try {
const supabaseUrl = process.env.EXPO_PUBLIC_SUPABASE_URL;
const supabaseKey = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY;
const headers: Record<string, string> = {
'apikey': supabaseKey!,
'Content-Type': 'application/json',
};
useHomeStats function · typescript · L96-L248 (153 LOC)hooks/useHomeStats.ts
export function useHomeStats(): HomeStats {
const { user, profile, session, isLoading: isAuthLoading } = useAuth();
const [isFetching, setIsFetching] = useState(false);
const [hasFetched, setHasFetched] = useState(false);
const [error, setError] = useState<string | null>(null);
const [completedBills, setCompletedBills] = useState<Bill[]>([]);
const [draftBills, setDraftBills] = useState<Bill[]>([]);
const fetchBills = useCallback(async () => {
// CRITICAL: Don't fetch while auth is still loading
if (isAuthLoading) {
return;
}
if (!user || !session) {
// Auth finished but no user - that's fine, no bills to show
setHasFetched(true);
return;
}
setIsFetching(true);
setError(null);
try {
const [completedResult, draftsResult] = await Promise.all([
supabase
.from('bills')
.select('*')uploadReceipt function · typescript · L20-L68 (49 LOC)services/api.ts
export async function uploadReceipt(imageUri: string) {
const formData = new FormData();
// Extract filename and type
const filename = imageUri.split('/').pop() || 'receipt.jpg';
const match = /\.(\w+)$/.exec(filename);
const type = match ? `image/${match[1]}` : 'image/jpeg';
// Append file to FormData
if (Platform.OS === 'web') {
// On Web, we need to convert the URI to a Blob
const fetchResponse = await fetch(imageUri);
const blob = await fetchResponse.blob();
formData.append('file', blob, filename);
} else {
// React Native specific way to handle file uploads
formData.append('file', {
uri: imageUri,
name: filename,
type,
} as any);
}
console.log(`[API] Uploading receipt to ${BASE_URL}/analyze...`);
try {
const response = await fetch(`${BASE_URL}/analyze`, {
method: 'POST',
body: formData,
headers: {
openVenmo function · typescript · L7-L37 (31 LOC)utils/payments.ts
export async function openVenmo(
handle: string,
amount: number,
note: string
): Promise<void> {
const cleanHandle = handle.replace(/^@/, '');
const encodedNote = encodeURIComponent(note);
const formattedAmount = amount.toFixed(2);
const deepLink = `venmo://paycharge?txn=pay&recipients=${cleanHandle}&amount=${formattedAmount}¬e=${encodedNote}`;
const webFallback = `https://venmo.com/${cleanHandle}`;
try {
const canOpen = await Linking.canOpenURL(deepLink);
if (canOpen) {
await Linking.openURL(deepLink);
} else {
await Linking.openURL(webFallback);
}
} catch (error) {
console.error('Venmo link error:', error);
Alert.alert(
'Cannot Open Venmo',
`Please pay @${cleanHandle} $${formattedAmount} on Venmo.`,
[
{ text: 'Open Venmo.com', onPress: () => Linking.openURL(webFallback) },
{ text: 'OK' },
]openCashApp function · typescript · L43-L71 (29 LOC)utils/payments.ts
export async function openCashApp(
handle: string,
amount: number
): Promise<void> {
const cleanHandle = handle.replace(/^\$/, '');
const formattedAmount = amount.toFixed(2);
const deepLink = `cashme://${cleanHandle}/${formattedAmount}`;
const webFallback = `https://cash.app/$${cleanHandle}/${formattedAmount}`;
try {
const canOpen = await Linking.canOpenURL(deepLink);
if (canOpen) {
await Linking.openURL(deepLink);
} else {
await Linking.openURL(webFallback);
}
} catch (error) {
console.error('CashApp link error:', error);
Alert.alert(
'Cannot Open Cash App',
`Please pay $${cleanHandle} $${formattedAmount} on Cash App.`,
[
{ text: 'Open Cash App', onPress: () => Linking.openURL(webFallback) },
{ text: 'OK' },
]
);
}
}Source: Repobility analyzer · https://repobility.com
requestVenmo function · typescript · L77-L107 (31 LOC)utils/payments.ts
export async function requestVenmo(
handle: string,
amount: number,
note: string
): Promise<void> {
const cleanHandle = handle.replace(/^@/, '');
const encodedNote = encodeURIComponent(note);
const formattedAmount = amount.toFixed(2);
const deepLink = `venmo://paycharge?txn=charge&recipients=${cleanHandle}&amount=${formattedAmount}¬e=${encodedNote}`;
const webFallback = `https://venmo.com/${cleanHandle}`;
try {
const canOpen = await Linking.canOpenURL(deepLink);
if (canOpen) {
await Linking.openURL(deepLink);
} else {
await Linking.openURL(webFallback);
}
} catch (error) {
console.error('Venmo request link error:', error);
Alert.alert(
'Cannot Open Venmo',
`Please request $${formattedAmount} from @${cleanHandle} on Venmo.`,
[
{ text: 'Open Venmo.com', onPress: () => Linking.openURL(webFallback) },
{ textrequestCashApp function · typescript · L112-L140 (29 LOC)utils/payments.ts
export async function requestCashApp(
handle: string,
amount: number
): Promise<void> {
const cleanHandle = handle.replace(/^\$/, '');
const formattedAmount = amount.toFixed(2);
const deepLink = `cashme://${cleanHandle}/${formattedAmount}`;
const webFallback = `https://cash.app/$${cleanHandle}/${formattedAmount}`;
try {
const canOpen = await Linking.canOpenURL(deepLink);
if (canOpen) {
await Linking.openURL(deepLink);
} else {
await Linking.openURL(webFallback);
}
} catch (error) {
console.error('CashApp request link error:', error);
Alert.alert(
'Cannot Open Cash App',
`Please request $${formattedAmount} from $${cleanHandle} on Cash App.`,
[
{ text: 'Open Cash App', onPress: () => Linking.openURL(webFallback) },
{ text: 'OK' },
]
);
}
}initiateApplePay function · typescript · L154-L172 (19 LOC)utils/payments.ts
export async function initiateApplePay(
amount: number,
merchantName: string,
): Promise<boolean> {
if (Platform.OS !== 'ios') {
Alert.alert('Not Available', 'Apple Pay is only available on iOS.');
return false;
}
// This function cannot use hooks (it's not a component).
// The real Apple Pay flow is in payment.tsx via usePlatformPay().
// This fallback shows an informational alert.
Alert.alert(
'Apple Pay',
`Authorize $${amount.toFixed(2)} payment to ${merchantName} via the Apple Pay button above.`,
[{ text: 'OK' }]
);
return false;
}uploadBillPhoto function · typescript · L5-L34 (30 LOC)utils/photoUpload.ts
export async function uploadBillPhoto(billId: string, uri: string): Promise<string> {
const base64 = await FileSystem.readAsStringAsync(uri, {
encoding: 'base64' as any,
});
const filePath = `${billId}.jpg`;
const { error: uploadError } = await supabase.storage
.from('bill-photos')
.upload(filePath, decode(base64), {
contentType: 'image/jpeg',
upsert: true,
});
if (uploadError) throw uploadError;
const { data } = supabase.storage
.from('bill-photos')
.getPublicUrl(filePath);
const publicUrl = data.publicUrl;
const { error: updateError } = await supabase
.from('bills')
.update({ group_photo_url: publicUrl })
.eq('id', billId);
if (updateError) throw updateError;
return publicUrl;
}getCurrentScheme function · typescript · L9-L15 (7 LOC)utils/url.ts
function getCurrentScheme(): string {
const scheme = Constants.expoConfig?.scheme;
if (Array.isArray(scheme)) {
return scheme[0] ?? 'divvit';
}
return scheme ?? 'divvit';
}getAuthCallbackUrl function · typescript · L26-L34 (9 LOC)utils/url.ts
export function getAuthCallbackUrl(): string {
const scheme = getCurrentScheme();
const redirectUrl = makeRedirectUri({
scheme,
path: 'auth/callback',
});
console.log('Detected Redirect URL:', redirectUrl);
return redirectUrl;
}getAppScheme function · typescript · L41-L43 (3 LOC)utils/url.ts
export function getAppScheme(): string {
return getCurrentScheme();
}‹ prevpage 2 / 2