Skip to content

Commit 645435e

Browse files
committed
Fix offline caching and add more reliable erroring
1 parent 2ba1d37 commit 645435e

20 files changed

+419
-295
lines changed

src/components/OfflineBanner.tsx

Lines changed: 0 additions & 63 deletions
This file was deleted.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { Ionicons } from "@expo/vector-icons";
2+
import { useTheme } from "@react-navigation/native";
3+
import * as Linking from "expo-linking";
4+
import { Text, View } from "react-native";
5+
6+
import { palette } from "../../styles/theme";
7+
import Button from "../Button";
8+
9+
interface AccessDeniedProps {
10+
orgId: string;
11+
onGoBack: () => void;
12+
}
13+
14+
export default function AccessDenied({ orgId, onGoBack }: AccessDeniedProps) {
15+
const { colors: themeColors } = useTheme();
16+
17+
return (
18+
<View
19+
style={{
20+
flex: 1,
21+
backgroundColor: themeColors.background,
22+
justifyContent: "center",
23+
alignItems: "center",
24+
padding: 24,
25+
}}
26+
>
27+
<View
28+
style={{
29+
backgroundColor: themeColors.card,
30+
borderRadius: 20,
31+
padding: 32,
32+
width: "100%",
33+
maxWidth: 400,
34+
alignItems: "center",
35+
elevation: 8,
36+
}}
37+
>
38+
<View
39+
style={{
40+
width: 96,
41+
height: 96,
42+
borderRadius: 48,
43+
backgroundColor: `${palette.primary}15`,
44+
justifyContent: "center",
45+
alignItems: "center",
46+
marginBottom: 32,
47+
}}
48+
>
49+
<Ionicons name="lock-closed" size={48} color={palette.primary} />
50+
</View>
51+
<Text
52+
style={{
53+
color: themeColors.text,
54+
fontSize: 28,
55+
fontWeight: "700",
56+
marginBottom: 16,
57+
textAlign: "center",
58+
letterSpacing: -0.5,
59+
}}
60+
>
61+
Access Denied
62+
</Text>
63+
<Text
64+
style={{
65+
color: palette.muted,
66+
fontSize: 17,
67+
lineHeight: 24,
68+
textAlign: "center",
69+
marginBottom: 32,
70+
paddingHorizontal: 8,
71+
}}
72+
>
73+
You don't have permission to view this organization. Please contact
74+
the organization's manager for access.
75+
</Text>
76+
<Button
77+
style={{
78+
width: "100%",
79+
backgroundColor: themeColors.primary,
80+
borderRadius: 12,
81+
height: 50,
82+
marginBottom: 16,
83+
}}
84+
color="#fff"
85+
onPress={onGoBack}
86+
>
87+
Go Back
88+
</Button>
89+
<Button
90+
style={{
91+
width: "100%",
92+
backgroundColor: palette.slate,
93+
borderRadius: 12,
94+
height: 50,
95+
}}
96+
color="#fff"
97+
onPress={() => Linking.openURL(`https://hcb.hackclub.com/${orgId}`)}
98+
>
99+
View on Website
100+
</Button>
101+
</View>
102+
</View>
103+
);
104+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { Ionicons } from "@expo/vector-icons";
2+
import { useTheme } from "@react-navigation/native";
3+
import { Text, View } from "react-native";
4+
5+
import { palette } from "../../styles/theme";
6+
import Button from "../Button";
7+
8+
interface OfflineNoDataProps {
9+
onRetry: () => void;
10+
onGoBack: () => void;
11+
}
12+
13+
export default function OfflineNoData({
14+
onRetry,
15+
onGoBack,
16+
}: OfflineNoDataProps) {
17+
const { colors: themeColors } = useTheme();
18+
19+
return (
20+
<View
21+
style={{
22+
flex: 1,
23+
backgroundColor: themeColors.background,
24+
justifyContent: "center",
25+
alignItems: "center",
26+
padding: 24,
27+
}}
28+
>
29+
<View
30+
style={{
31+
backgroundColor: themeColors.card,
32+
borderRadius: 20,
33+
padding: 32,
34+
width: "100%",
35+
maxWidth: 400,
36+
alignItems: "center",
37+
elevation: 8,
38+
}}
39+
>
40+
<View
41+
style={{
42+
width: 96,
43+
height: 96,
44+
borderRadius: 48,
45+
backgroundColor: `${palette.slate}15`,
46+
justifyContent: "center",
47+
alignItems: "center",
48+
marginBottom: 32,
49+
}}
50+
>
51+
<Ionicons name="cloud-offline" size={48} color={palette.slate} />
52+
</View>
53+
<Text
54+
style={{
55+
color: themeColors.text,
56+
fontSize: 28,
57+
fontWeight: "700",
58+
marginBottom: 16,
59+
textAlign: "center",
60+
letterSpacing: -0.5,
61+
}}
62+
>
63+
No Cached Data
64+
</Text>
65+
<Text
66+
style={{
67+
color: palette.muted,
68+
fontSize: 17,
69+
lineHeight: 24,
70+
textAlign: "center",
71+
marginBottom: 32,
72+
paddingHorizontal: 8,
73+
}}
74+
>
75+
You're offline and we don't have any cached data for this
76+
organization. Please connect to the internet to load the organization
77+
details.
78+
</Text>
79+
<Button
80+
style={{
81+
width: "100%",
82+
backgroundColor: themeColors.primary,
83+
borderRadius: 12,
84+
height: 50,
85+
marginBottom: 16,
86+
}}
87+
color="#fff"
88+
onPress={onRetry}
89+
>
90+
Try Again
91+
</Button>
92+
<Button
93+
style={{
94+
width: "100%",
95+
backgroundColor: palette.slate,
96+
borderRadius: 12,
97+
height: 50,
98+
}}
99+
color="#fff"
100+
onPress={onGoBack}
101+
>
102+
Go Back
103+
</Button>
104+
</View>
105+
</View>
106+
);
107+
}

src/core/AppContent.tsx

Lines changed: 7 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { ActionSheetProvider } from "@expo/react-native-action-sheet";
2-
import { Ionicons } from "@expo/vector-icons";
32
import AsyncStorage from "@react-native-async-storage/async-storage";
43
import {
54
NavigationContainer,
@@ -21,89 +20,28 @@ import {
2120
useMemo,
2221
useState,
2322
} from "react";
24-
import { ColorSchemeName, View, Text, ActivityIndicator } from "react-native";
23+
import { ColorSchemeName, View, ActivityIndicator } from "react-native";
2524
import { AlertNotificationRoot } from "react-native-alert-notification";
2625
import { GestureHandlerRootView } from "react-native-gesture-handler";
27-
import {
28-
SafeAreaProvider,
29-
SafeAreaView,
30-
useSafeAreaInsets,
31-
} from "react-native-safe-area-context";
26+
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
3227
import { SWRConfig } from "swr";
3328

3429
import AuthContext from "../auth/auth";
3530
import useClient from "../lib/client";
3631
import { logError } from "../lib/errorUtils";
3732
import { TabParamList } from "../lib/NavigatorParamList";
3833
import { useIsDark } from "../lib/useColorScheme";
39-
import { useOffline } from "../lib/useOffline";
4034
import { resetStripeTerminalInitialization } from "../lib/useStripeTerminalInit";
4135
import Login from "../pages/login";
4236
import { CacheProvider } from "../providers/cacheProvider";
4337
import { useLinkingPref } from "../providers/LinkingContext";
4438
import { useThemeContext } from "../providers/ThemeContext";
45-
import { lightTheme, palette, theme } from "../styles/theme";
39+
import { lightTheme, theme } from "../styles/theme";
4640
import { getStateFromPath } from "../utils/getStateFromPath";
4741

4842
import { navRef } from "./navigationRef";
4943
import Navigator from "./Navigator";
5044

51-
function OfflineBanner() {
52-
const insets = useSafeAreaInsets();
53-
const { isOnline } = useOffline();
54-
55-
if (isOnline) return null;
56-
57-
return (
58-
<View
59-
style={{
60-
position: "absolute",
61-
zIndex: 999,
62-
width: "100%",
63-
alignItems: "center",
64-
pointerEvents: "none",
65-
top: insets.top + 6,
66-
}}
67-
>
68-
<View
69-
style={{
70-
flexDirection: "row",
71-
alignItems: "center",
72-
backgroundColor: theme.dark
73-
? palette.darkless
74-
: lightTheme.colors.card,
75-
paddingVertical: 8,
76-
paddingHorizontal: 16,
77-
borderRadius: 20,
78-
shadowColor: "#000",
79-
shadowOffset: {
80-
width: 0,
81-
height: 3,
82-
},
83-
shadowOpacity: 0.2,
84-
shadowRadius: 5,
85-
elevation: 6,
86-
}}
87-
>
88-
<Ionicons
89-
name="cloud-offline-outline"
90-
size={18}
91-
color={palette.primary}
92-
/>
93-
<Text
94-
style={{
95-
color: palette.primary,
96-
fontWeight: "bold",
97-
marginLeft: 8,
98-
fontSize: 15,
99-
}}
100-
>
101-
Offline Mode
102-
</Text>
103-
</View>
104-
</View>
105-
);
106-
}
10745
SplashScreen.preventAutoHideAsync();
10846

10947
SplashScreen.setOptions({
@@ -492,6 +430,10 @@ export default function AppContent({
492430
revalidateOnFocus: true,
493431
revalidateOnReconnect: true,
494432
dedupingInterval: 2000,
433+
shouldRetryOnError: true,
434+
keepPreviousData: true,
435+
errorRetryCount: 3,
436+
errorRetryInterval: 1000,
495437
}}
496438
>
497439
<ActionSheetProvider>
@@ -502,7 +444,6 @@ export default function AppContent({
502444
linking={linking}
503445
onReady={onNavigationReady}
504446
>
505-
<OfflineBanner />
506447
{tokens?.accessToken && isAuthenticated ? (
507448
<Navigator />
508449
) : (

0 commit comments

Comments
 (0)