Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

NotificationsScreen.tsx

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

NotificationsScreen.tsxBlame102 lines · 1 contributor
c53cf00Claude1import React, { useContext, useEffect } from 'react';
2import {
3 View,
4 Text,
5 FlatList,
6 StyleSheet,
7 TouchableOpacity,
8 RefreshControl,
9} from 'react-native';
10import { SafeAreaView } from 'react-native-safe-area-context';
11import { colors } from '../theme/colors';
12import { fontSizes, fontWeights } from '../theme/typography';
9d7a803Claude13import { AuthContext } from '../navigation/AuthContext';
c53cf00Claude14import { useUserRepos } from '../hooks/useRepo';
15import { useNotifications } from '../hooks/useNotifications';
16import { NotifRow } from '../components/NotifRow';
17import { LoadingSpinner } from '../components/LoadingSpinner';
18import { EmptyState } from '../components/EmptyState';
19
20export function NotificationsScreen() {
21 const { user } = useContext(AuthContext);
22 const { repos } = useUserRepos(user?.username ?? null);
23
24 const repoRefs = repos.slice(0, 5).map((r) => ({
25 owner: user?.username ?? '',
26 name: r.name,
27 }));
28
29 const { notifications, loading, error, refresh, markAllRead, unreadCount } = useNotifications(repoRefs);
30
31 useEffect(() => {
32 if (repos.length > 0) {
33 refresh();
34 }
35 }, [repos.length]);
36
37 return (
38 <SafeAreaView style={styles.safe} edges={['top']}>
39 {/* Header */}
40 <View style={styles.header}>
41 <Text style={styles.title}>
42 Notifications{unreadCount > 0 ? ` (${unreadCount})` : ''}
43 </Text>
44 {unreadCount > 0 && (
45 <TouchableOpacity onPress={markAllRead} style={styles.markReadBtn} activeOpacity={0.75}>
46 <Text style={styles.markReadText}>Mark all read</Text>
47 </TouchableOpacity>
48 )}
49 </View>
50
51 {loading && notifications.length === 0 ? (
52 <LoadingSpinner size="large" />
53 ) : (
54 <FlatList
55 data={notifications}
56 keyExtractor={(item) => item.id}
57 renderItem={({ item }) => <NotifRow notification={item} />}
58 refreshControl={
59 <RefreshControl refreshing={loading} onRefresh={refresh} tintColor={colors.accent} />
60 }
61 ListEmptyComponent={
62 <EmptyState
63 title="No notifications"
64 subtitle="Activity from your repos will appear here"
65 icon="🔔"
66 />
67 }
68 />
69 )}
70 </SafeAreaView>
71 );
72}
73
74const styles = StyleSheet.create({
75 safe: { flex: 1, backgroundColor: colors.bg },
76 header: {
77 flexDirection: 'row',
78 justifyContent: 'space-between',
79 alignItems: 'center',
80 paddingHorizontal: 16,
81 paddingTop: 16,
82 paddingBottom: 12,
83 borderBottomWidth: 1,
84 borderBottomColor: colors.border,
85 },
86 title: {
87 color: colors.text,
88 fontSize: fontSizes.xl,
89 fontWeight: fontWeights.bold,
90 },
91 markReadBtn: {
92 paddingHorizontal: 12,
93 paddingVertical: 6,
94 backgroundColor: colors.accentDim,
95 borderRadius: 16,
96 },
97 markReadText: {
98 color: colors.accent,
99 fontSize: fontSizes.sm,
100 fontWeight: fontWeights.medium,
101 },
102});