1 import React, {FC, ReactElement, useState} from 'react';
2 import {
3 Alert,
4 Image,
5 View,
6 PermissionsAndroid,
7 Platform,
8 ScrollView,
9 StyleSheet,
10 } from 'react-native';
11 import Parse from 'parse/react-native';
12 import {
13 List,
14 Title,
15 Button as PaperButton,
16 Text as PaperText,
17 } from 'react-native-paper';
18 import Geolocation from 'react-native-geolocation-service';
19
20 export const QueryList: FC<{}> = ({}): ReactElement => {
21
22 const [queryResults, setQueryResults] = useState(null);
23
24
25 const requestLocationPermissions = async () => {
26 if (Platform.OS === 'ios') {
27
28 await Geolocation.requestAuthorization('whenInUse');
29 } else if (Platform.OS === 'android') {
30 let permissionCheck: boolean = await PermissionsAndroid.check(
31 PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
32 );
33
34 if (permissionCheck !== true) {
35 await PermissionsAndroid.request(
36 PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
37 {
38 title: 'Location Permission Request',
39 message:
40 'This app needs you permission for using your location for querying GeoPoints in Parse!',
41 buttonPositive: 'OK',
42 },
43 );
44 }
45 }
46 };
47
48 const doQueryNear = async function (): Promise<boolean> {
49
50 await requestLocationPermissions();
51
52 Geolocation.getCurrentPosition(
53 async (currentPosition: {
54 coords: {latitude: number; longitude: number};
55 }) => {
56
57 let currentLocationGeoPoint: Parse.GeoPoint = new Parse.GeoPoint(
58 currentPosition.coords.latitude,
59 currentPosition.coords.longitude,
60 );
61
62
63 let parseQuery: Parse.Query = new Parse.Query('City');
64
65
66 parseQuery.near('location', currentLocationGeoPoint);
67
68 try {
69 let results: [Parse.Object] = await parseQuery.find();
70
71 setQueryResults(results);
72 } catch (error) {
73
74 Alert.alert('Error!', error.message);
75 }
76 },
77 _error => {
78 Alert.alert(
79 'Error!',
80 'This app needs your location permission to query this!',
81 );
82 },
83 {enableHighAccuracy: true, timeout: 15000, maximumAge: 10000},
84 );
85 return true;
86 };
87
88 const doQueryWithinKilometers = async function (): Promise<boolean> {
89
90 await requestLocationPermissions();
91
92 Geolocation.getCurrentPosition(
93 async (currentPosition: {
94 coords: {latitude: number; longitude: number};
95 }) => {
96
97 let currentLocationGeoPoint: Parse.GeoPoint = new Parse.GeoPoint(
98 currentPosition.coords.latitude,
99 currentPosition.coords.longitude,
100 );
101
102
103 let parseQuery: Parse.Query = new Parse.Query('City');
104
105
106
107 parseQuery.withinKilometers('location', currentLocationGeoPoint, 3000);
108
109 try {
110 let results: [Parse.Object] = await parseQuery.find();
111
112 setQueryResults(results);
113 } catch (error) {
114
115 Alert.alert('Error!', error.message);
116 }
117 },
118 _error => {
119 Alert.alert(
120 'Error!',
121 'This app needs your location permission to query this!',
122 );
123 },
124 {enableHighAccuracy: true, timeout: 15000, maximumAge: 10000},
125 );
126 return true;
127 };
128
129 const doQueryWithinPolygon = async function (): Promise<boolean> {
130
131 let geoPoint1: Parse.GeoPoint = new Parse.GeoPoint(
132 15.822.238.344.514.300,00
133 -7.242.845.934.415.940,00
134 );
135 let geoPoint2: Parse.GeoPoint = new Parse.GeoPoint(
136 -0.7433770196268968,
137 -9.744.765.968.406.660,00
138 );
139 let geoPoint3: Parse.GeoPoint = new Parse.GeoPoint(
140 -59.997.149.373.299.100,00
141 -7.652.969.196.322.740,00
142 );
143 let geoPoint4: Parse.GeoPoint = new Parse.GeoPoint(
144 -9.488.786.415.007.200,00
145 -18.346.101.586.021.900,00
146 );
147 let geoPoint5: Parse.GeoPoint = new Parse.GeoPoint(
148 15.414.859.532.811.000,00
149 -6.000.625.459.569.370,00
150 );
151
152
153 let parseQuery: Parse.Query = new Parse.Query('City');
154
155
156 parseQuery.withinPolygon('location', [
157 geoPoint1,
158 geoPoint2,
159 geoPoint3,
160 geoPoint4,
161 geoPoint5,
162 ]);
163
164 try {
165 let results: [Parse.Object] = await parseQuery.find();
166
167 setQueryResults(results);
168 } catch (error) {
169
170 Alert.alert('Error!', error.message);
171 }
172 };
173
174 const clearQueryResults = async function (): Promise<boolean> {
175 setQueryResults(null);
176 return true;
177 };
178
179 return (
180 <>
181 <View style={Styles.header}>
182 <Image
183 style={Styles.header_logo}
184 source={ {
185 uri:
186 'https://blog.back4app.com/wp-content/uploads/2019/05/back4app-white-logo-500px.png',
187 } }
188 />
189 <PaperText style={Styles.header_text}>
190 <PaperText style={Styles.header_text_bold}>
191 {'React Native on Back4App - '}
192 </PaperText>
193 {' GeoPoint Queries'}
194 </PaperText>
195 </View>
196 <ScrollView style={Styles.wrapper}>
197 <View>
198 <Title>{'Result List'}</Title>
199 {}
200 {queryResults !== null &&
201 queryResults !== undefined &&
202 queryResults.map((result: Parse.Object) => (
203 <List.Item
204 key={result.id}
205 title={result.get('name')}
206 titleStyle={Styles.list_text}
207 style={Styles.list_item}
208 />
209 ))}
210 {queryResults === null ||
211 queryResults === undefined ||
212 (queryResults !== null &&
213 queryResults !== undefined &&
214 queryResults.length <= 0) ? (
215 <PaperText>{'No results here!'}</PaperText>
216 ) : null}
217 </View>
218 <View>
219 <Title>{'Query buttons'}</Title>
220 <PaperButton
221 onPress={() => doQueryNear()}
222 mode="contained"
223 icon="search-web"
224 color={'#208AEC'}
225 style={Styles.list_button}>
226 {'Query Near'}
227 </PaperButton>
228 <PaperButton
229 onPress={() => doQueryWithinKilometers()}
230 mode="contained"
231 icon="search-web"
232 color={'#208AEC'}
233 style={Styles.list_button}>
234 {'Query Within KM'}
235 </PaperButton>
236 <PaperButton
237 onPress={() => doQueryWithinPolygon()}
238 mode="contained"
239 icon="search-web"
240 color={'#208AEC'}
241 style={Styles.list_button}>
242 {'Query Within Polygon'}
243 </PaperButton>
244 <PaperButton
245 onPress={() => clearQueryResults()}
246 mode="contained"
247 icon="delete"
248 color={'#208AEC'}
249 style={Styles.list_button}>
250 {'Clear Results'}
251 </PaperButton>
252 </View>
253 </ScrollView>
254 </>
255 );
256 };
257
258
259 const Styles = StyleSheet.create({
260 header: {
261 alignItems: 'center',
262 paddingTop: 30,
263 paddingBottom: 50,
264 backgroundColor: '#208AEC',
265 },
266 header_logo: {
267 height: 50,
268 width: 220,
269 resizeMode: 'contain',
270 },
271 header_text: {
272 marginTop: 15,
273 color: '#f0f0f0',
274 fontSize: 16,
275 },
276 header_text_bold: {
277 color: '#fff',
278 fontWeight: 'bold',
279 },
280 wrapper: {
281 width: '90%',
282 alignSelf: 'center',
283 },
284 list_button: {
285 marginTop: 6,
286 marginLeft: 15,
287 height: 40,
288 },
289 list_item: {
290 borderBottomWidth: 1,
291 borderBottomColor: 'rgba(0, 0, 0, 0.12)',
292 },
293 list_text: {
294 fontSize: 15,
295 },
296 });