1import * as Maps from 'expo-maps';
2import { LocationChangePriority } from 'expo-maps/src/Common.types';
3import React, { useContext, useState } from 'react';
4import { StyleSheet, View, Text, FlatList, Platform } from 'react-native';
5import { Snackbar } from 'react-native-paper';
6
7import SwitchContainer from '../components/SwitchContainer';
8import ProviderContext from '../context/ProviderContext';
9
10export default function CallbacksExample() {
11  const provider = useContext(ProviderContext);
12
13  const [onMapLoadedEnabled, setOnMapLoadedEnabled] = useState(true);
14  const [onMapPressEnabled, setOnMapPressEnabled] = useState(true);
15  const [onDoublePressEnabled, setOnDoublePressEnabled] = useState(true);
16  const [onLongPressEnabled, setOnLongPressEnabled] = useState(true);
17  const [onRegionChangeEnabled, setOnRegionChangeEnabled] = useState(false);
18  const [onRegionChangeStartedEnable, setOnRegionChangeStartedEnabled] = useState(false);
19  const [onRegionChangeCmpEnabled, setOnRegChangeCmpEnabled] = useState(false);
20  const [onPoiClickEnabled, setOnPoiClickEnabled] = useState(true);
21  const [onMarkerPressEnabled, setOnMarkerPressEnabled] = useState(true);
22  const [onMarkerDragEnabled, setOnMarkerDragEnabled] = useState(false);
23  const [onMarkerDragStartedEnabled, setOnMarkerDragStartedEnabled] = useState(true);
24  const [onMarkerDragCompleteEnabled, setOnMarkerDragCompleteEnabled] = useState(true);
25  const [onClusterPressEnabled, setOnClusterPressEnabled] = useState(true);
26  const [onLocationButtonPressEnabled, setOnLocationButtonPressEnabled] = useState(true);
27  const [onLocationDotPressEnabled, setOnLocationDotPressEnabled] = useState(true);
28  const [onLocationChangeEnabled, setOnLocationChangeEnabled] = useState(false);
29
30  const [snackbarText, setSnackbarText] = useState<string | undefined>(undefined);
31
32  const [latitude] = useState<number>(40.4);
33  const [longitude] = useState<number>(-3.7);
34
35  const callbacksData = [
36    {
37      title: 'Enable onMapLoaded event',
38      value: onMapLoadedEnabled,
39      onValueChange: () => {
40        setOnMapLoadedEnabled(!onMapLoadedEnabled);
41      },
42    },
43    {
44      title: 'Enable onMapPress event',
45      value: onMapPressEnabled,
46      onValueChange: () => {
47        setOnMapPressEnabled(!onMapPressEnabled);
48      },
49    },
50    {
51      title: 'Enable onDoublePress event',
52      value: onDoublePressEnabled,
53      onValueChange: () => {
54        setOnDoublePressEnabled(!onDoublePressEnabled);
55      },
56      enabled: provider === 'apple',
57    },
58
59    {
60      title: 'Enable onLongPress event',
61      value: onLongPressEnabled,
62      onValueChange: () => {
63        setOnLongPressEnabled(!onLongPressEnabled);
64      },
65    },
66    {
67      title: 'Enable onRegionChange event',
68      value: onRegionChangeEnabled,
69      onValueChange: () => {
70        setOnRegionChangeEnabled(!onRegionChangeEnabled);
71      },
72    },
73    {
74      title: 'Enable onRegionChangeStarted event',
75      value: onRegionChangeStartedEnable,
76      onValueChange: () => {
77        setOnRegionChangeStartedEnabled(!onRegionChangeStartedEnable);
78      },
79    },
80    {
81      title: 'Enable onRegionChangeComplete event',
82      value: onRegionChangeCmpEnabled,
83      onValueChange: () => {
84        setOnRegChangeCmpEnabled(!onRegionChangeCmpEnabled);
85      },
86    },
87    {
88      title: 'Enable onPoiClick event',
89      value: onPoiClickEnabled,
90      onValueChange: () => {
91        setOnPoiClickEnabled(!onPoiClickEnabled);
92      },
93      enabled: provider === 'google',
94    },
95    {
96      title: 'Enable onMarkerPress event',
97      value: onMarkerPressEnabled,
98      onValueChange: () => {
99        setOnMarkerPressEnabled(!onMarkerPressEnabled);
100      },
101    },
102    {
103      title: 'Enable onMarkerDrag event',
104      value: onMarkerDragEnabled,
105      onValueChange: () => {
106        setOnMarkerDragEnabled(!onMarkerDragEnabled);
107      },
108    },
109    {
110      title: 'Enable onMarkerDragStarted event',
111      value: onMarkerDragStartedEnabled,
112      onValueChange: () => {
113        setOnMarkerDragStartedEnabled(!onMarkerDragStartedEnabled);
114      },
115    },
116    {
117      title: 'Enable onMarkerDragComplete event',
118      value: onMarkerDragCompleteEnabled,
119      onValueChange: () => {
120        setOnMarkerDragCompleteEnabled(!onMarkerDragCompleteEnabled);
121      },
122    },
123    {
124      title: 'Enable onClusterPressEnabled event',
125      value: onClusterPressEnabled,
126      onValueChange: () => {
127        setOnClusterPressEnabled(!onClusterPressEnabled);
128      },
129    },
130    {
131      title: 'Enable onLocationChange event',
132      value: onLocationChangeEnabled,
133      onValueChange: () => {
134        setOnLocationChangeEnabled(!onLocationChangeEnabled);
135      },
136    },
137    {
138      title: 'Enable onLocationButtonPress event',
139      value: onLocationButtonPressEnabled,
140      onValueChange: () => {
141        setOnLocationButtonPressEnabled(!onLocationButtonPressEnabled);
142      },
143    },
144    {
145      title: 'Enable onLocationDotPress event.',
146      value: onLocationDotPressEnabled,
147      onValueChange: () => {
148        setOnLocationDotPressEnabled(!onLocationDotPressEnabled);
149      },
150      enabled: provider !== 'google' || Platform.OS === 'android',
151    },
152  ];
153  return (
154    <View style={styles.container}>
155      <Maps.ExpoMap
156        style={{ flex: 1, width: '100%' }}
157        provider={provider}
158        onMapPress={(event) => {
159          onMapPressEnabled &&
160            setSnackbarText('Map clicked at:' + JSON.stringify(event.nativeEvent));
161        }}
162        onDoublePress={(event) => {
163          onDoublePressEnabled &&
164            setSnackbarText('Double press at:' + JSON.stringify(event.nativeEvent));
165        }}
166        onLongPress={(event) => {
167          onLongPressEnabled &&
168            setSnackbarText('Long press at:' + JSON.stringify(event.nativeEvent));
169        }}
170        onMapLoaded={() => {
171          onMapLoadedEnabled && setSnackbarText('Map has loaded!');
172        }}
173        onRegionChange={(event) => {
174          onRegionChangeEnabled &&
175            setSnackbarText('Camera moved to:' + JSON.stringify(event.nativeEvent));
176        }}
177        onRegionChangeStarted={(event) => {
178          onRegionChangeStartedEnable &&
179            setSnackbarText('Camera started moving from:' + JSON.stringify(event.nativeEvent));
180        }}
181        onRegionChangeComplete={(event) => {
182          onRegionChangeCmpEnabled &&
183            setSnackbarText('Camera finished moving to:' + JSON.stringify(event.nativeEvent));
184        }}
185        onPoiClick={(event) => {
186          onPoiClickEnabled && setSnackbarText('Clicked POI:' + JSON.stringify(event.nativeEvent));
187        }}
188        onMarkerPress={(event) => {
189          onMarkerPressEnabled &&
190            setSnackbarText('Clicked marker: ' + JSON.stringify(event.nativeEvent));
191        }}
192        onMarkerDrag={(event) => {
193          onMarkerDragEnabled &&
194            setSnackbarText('Dragging marker: ' + JSON.stringify(event.nativeEvent));
195        }}
196        onMarkerDragStarted={(event) => {
197          onMarkerDragStartedEnabled &&
198            setSnackbarText('Marker drag started: ' + JSON.stringify(event.nativeEvent));
199        }}
200        onMarkerDragComplete={(event) => {
201          onMarkerDragCompleteEnabled &&
202            setSnackbarText('Marker drag complete: ' + JSON.stringify(event.nativeEvent));
203        }}
204        onClusterPress={(event) => {
205          onClusterPressEnabled &&
206            setSnackbarText('Clicked on a cluster: ' + JSON.stringify(event.nativeEvent));
207        }}
208        onLocationChange={(event) => {
209          onLocationChangeEnabled &&
210            setSnackbarText("User's location has changed!" + JSON.stringify(event.nativeEvent));
211        }}
212        onLocationChangeEventInterval={2500}
213        onLocationChangeEventPriority={LocationChangePriority.PRIORITY_HIGH_ACCURACY}
214        onLocationButtonPress={(event) => {
215          onLocationButtonPressEnabled &&
216            setSnackbarText(
217              'Location button has been pressed!' + JSON.stringify(event.nativeEvent)
218            );
219        }}
220        onLocationDotPress={(event) => {
221          onLocationDotPressEnabled &&
222            setSnackbarText('Location dot has been pressed!' + JSON.stringify(event.nativeEvent));
223        }}>
224        <Maps.Marker
225          id="100"
226          latitude={48.85}
227          longitude={2.35}
228          markerTitle="Paris"
229          markerSnippet="Marker with an id: 100"
230          color="blue"
231        />
232        <Maps.Marker
233          id="101"
234          latitude={latitude}
235          longitude={longitude}
236          markerTitle="Madrid"
237          markerSnippet="Draggable marker with an id: 101"
238          draggable
239          color="green"
240        />
241        <Maps.Cluster
242          id="10"
243          name="sample_cluster_group"
244          minimumClusterSize={2}
245          color="purple"
246          opacity={0.5}
247          markerTitle="Cluster"
248          markerSnippet="Cluster with an id: 10">
249          <Maps.Marker
250            id="1"
251            color="blue"
252            draggable
253            latitude={50}
254            longitude={10}
255            markerTitle="Marker"
256            markerSnippet="Marker with an id: 1"
257          />
258          <Maps.Marker id="123" latitude={51} longitude={10} />
259          <Maps.Marker id="1234" latitude={52} longitude={10.15} />
260          <Maps.Marker id="12345" latitude={52} longitude={9.85} />
261        </Maps.Cluster>
262      </Maps.ExpoMap>
263      <Snackbar
264        visible={snackbarText !== undefined}
265        onDismiss={() => setSnackbarText(undefined)}
266        style={{ backgroundColor: 'white' }}
267        wrapperStyle={styles.snackbar}
268        duration={2000}>
269        <Text style={{ color: 'black' }}>{snackbarText}</Text>
270      </Snackbar>
271      <View style={{ maxHeight: 200 }}>
272        <FlatList
273          contentContainerStyle={styles.eventsList}
274          data={callbacksData}
275          renderItem={({ item }) => <SwitchContainer {...item} />}
276        />
277      </View>
278    </View>
279  );
280}
281
282const styles = StyleSheet.create({
283  container: {
284    flex: 1,
285  },
286  snackbar: {
287    top: 0,
288  },
289  eventsList: {
290    padding: 20,
291  },
292});
293