1import { Image, ImageErrorEventData, ImageLoadEventData, ImageProgressEventData } from 'expo-image';
2import { useCallback, useState } from 'react';
3import { StyleSheet, View } from 'react-native';
4
5import Button from '../../components/Button';
6import ConsoleBox from '../../components/ConsoleBox';
7import { Colors } from '../../constants';
8
9const generateSeed = () => 1 + Math.round(Math.random() * 2137);
10
11export default function ImageEventsScreen() {
12  const [uri, setSourceUri] = useState(getRandomImageUri());
13  const [logs, setLogs] = useState<string[]>([]);
14
15  const onLoadStart = useCallback(() => {
16    logs.push('�� onLoadStart');
17    setLogs([...logs]);
18  }, [logs]);
19
20  const onLoad = useCallback(
21    (event: ImageLoadEventData) => {
22      logs.push(`�� onLoad: ${JSON.stringify(event, null, 2)}`);
23      setLogs([...logs]);
24    },
25    [logs]
26  );
27
28  const onProgress = useCallback(
29    (event: ImageProgressEventData) => {
30      logs.push(`�� onProgress: ${JSON.stringify(event, null, 2)}`);
31      setLogs([...logs]);
32    },
33    [logs]
34  );
35
36  const onError = useCallback(
37    (event: ImageErrorEventData) => {
38      logs.push(`�� onError: ${JSON.stringify(event, null, 2)}`);
39      setLogs([...logs]);
40    },
41    [logs]
42  );
43
44  const onLoadEnd = useCallback(() => {
45    logs.push('�� onLoadEnd');
46    setLogs([...logs]);
47  }, [logs]);
48
49  const loadNewImage = useCallback(() => {
50    setSourceUri(getRandomImageUri());
51    setLogs([]);
52  }, []);
53
54  const loadWithError = useCallback(() => {
55    setSourceUri(`https://expo.dev/?r=${generateSeed()}`);
56    setLogs([]);
57  }, []);
58
59  return (
60    <View style={styles.container}>
61      <Image
62        style={styles.image}
63        source={{ uri }}
64        onLoadStart={onLoadStart}
65        onLoad={onLoad}
66        onProgress={onProgress}
67        onError={onError}
68        onLoadEnd={onLoadEnd}
69      />
70
71      <View style={styles.buttons}>
72        <Button title="Load new image" onPress={loadNewImage} />
73        <Button title="Load with error" onPress={loadWithError} />
74      </View>
75
76      <ConsoleBox style={styles.logs}>{logs.join('\n')}</ConsoleBox>
77    </View>
78  );
79}
80
81function getRandomImageUri(): string {
82  return `https://picsum.photos/seed/${generateSeed()}/3000/2000`;
83}
84
85const styles = StyleSheet.create({
86  container: {
87    flex: 1,
88  },
89  image: {
90    height: 200,
91    margin: 20,
92    borderWidth: 1,
93    borderColor: Colors.border,
94  },
95  buttons: {
96    flexDirection: 'row',
97    justifyContent: 'space-evenly',
98  },
99  logs: {
100    flex: 1,
101    margin: 20,
102  },
103});
104