feat(#6): add randomized fake startup loader with suitcase progress
This commit is contained in:
@@ -63,6 +63,8 @@ export default function AppRoot() {
|
|||||||
const scrollRef = useRef(null);
|
const scrollRef = useRef(null);
|
||||||
|
|
||||||
const [loaded, setLoaded] = useState(false);
|
const [loaded, setLoaded] = useState(false);
|
||||||
|
const [fakeLoadDone, setFakeLoadDone] = useState(false);
|
||||||
|
const [fakeLoadProgress, setFakeLoadProgress] = useState(0);
|
||||||
const [tab, setTab] = useState('trips');
|
const [tab, setTab] = useState('trips');
|
||||||
const [data, setData] = useState(emptyData);
|
const [data, setData] = useState(emptyData);
|
||||||
|
|
||||||
@@ -83,6 +85,8 @@ export default function AppRoot() {
|
|||||||
const [dialogState, setDialogState] = useState({ visible: false, title: '', message: '', buttons: [] });
|
const [dialogState, setDialogState] = useState({ visible: false, title: '', message: '', buttons: [] });
|
||||||
|
|
||||||
const topInset = Platform.OS === 'android' ? (RNStatusBar.currentHeight || 0) + 10 : 0;
|
const topInset = Platform.OS === 'android' ? (RNStatusBar.currentHeight || 0) + 10 : 0;
|
||||||
|
const fakeLoadTotalMs = useMemo(() => 1200 + Math.floor(Math.random() * 2801), []);
|
||||||
|
const appReady = loaded && fakeLoadDone;
|
||||||
|
|
||||||
const visibleTrips = useMemo(() => data.trips.filter((trip) => !trip.archived), [data.trips]);
|
const visibleTrips = useMemo(() => data.trips.filter((trip) => !trip.archived), [data.trips]);
|
||||||
|
|
||||||
@@ -165,6 +169,26 @@ export default function AppRoot() {
|
|||||||
})();
|
})();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const startedAt = Date.now();
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
const elapsed = Date.now() - startedAt;
|
||||||
|
setFakeLoadProgress(Math.min(1, elapsed / fakeLoadTotalMs));
|
||||||
|
}, 60);
|
||||||
|
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
setFakeLoadProgress(1);
|
||||||
|
setFakeLoadDone(true);
|
||||||
|
clearInterval(interval);
|
||||||
|
}, fakeLoadTotalMs);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval);
|
||||||
|
clearTimeout(timeout);
|
||||||
|
};
|
||||||
|
}, [fakeLoadTotalMs]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!loaded) return;
|
if (!loaded) return;
|
||||||
AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(data)).catch(() => {
|
AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(data)).catch(() => {
|
||||||
@@ -733,12 +757,17 @@ export default function AppRoot() {
|
|||||||
openAddItemModal();
|
openAddItemModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loaded) {
|
if (!appReady) {
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={[styles.safe, { paddingTop: topInset }]}>
|
<SafeAreaView style={[styles.safe, { paddingTop: topInset }]}>
|
||||||
<StatusBar style="light" translucent={false} />
|
<StatusBar style="light" translucent={false} />
|
||||||
<View style={styles.center}>
|
<View style={styles.center}>
|
||||||
<Text style={styles.muted}>Loading local data...</Text>
|
<Text style={styles.loadingEmoji}>🧳</Text>
|
||||||
|
<Text style={styles.loadingTitle}>Packing your list...</Text>
|
||||||
|
<View style={styles.loadingBarTrack}>
|
||||||
|
<View style={[styles.loadingBarFill, { width: `${Math.round(fakeLoadProgress * 100)}%` }]} />
|
||||||
|
</View>
|
||||||
|
<Text style={styles.muted}>{Math.round(fakeLoadProgress * 100)}%</Text>
|
||||||
</View>
|
</View>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -26,6 +26,28 @@ export const styles = StyleSheet.create({
|
|||||||
muted: {
|
muted: {
|
||||||
color: '#8793a5',
|
color: '#8793a5',
|
||||||
},
|
},
|
||||||
|
loadingEmoji: {
|
||||||
|
fontSize: 52,
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
loadingTitle: {
|
||||||
|
color: '#f8fafc',
|
||||||
|
fontWeight: '700',
|
||||||
|
fontSize: 17,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
loadingBarTrack: {
|
||||||
|
width: 220,
|
||||||
|
height: 10,
|
||||||
|
borderRadius: 999,
|
||||||
|
backgroundColor: '#1e293b',
|
||||||
|
overflow: 'hidden',
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
loadingBarFill: {
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: '#2563eb',
|
||||||
|
},
|
||||||
|
|
||||||
tripPickerWrap: {
|
tripPickerWrap: {
|
||||||
marginBottom: 6,
|
marginBottom: 6,
|
||||||
|
|||||||
Reference in New Issue
Block a user