11 import React, {FC, ReactElement, useState} from 'react';
22 import {
33 Alert,
44 Image,
55 View,
66 PermissionsAndroid,
77 Platform,
88 ScrollView,
99 StyleSheet,
1010 } from 'react-native';
1111 import Parse from 'parse/react-native';
1212 import {
1313 List,
1414 Title,
1515 Button as PaperButton,
1616 Text as PaperText,
1717 } from 'react-native-paper';
1818 import Geolocation from 'react-native-geolocation-service';
1919
2020 export const QueryList: FC<{}> = ({}): ReactElement => {
2121
2222 const [queryResults, setQueryResults] = useState(null);
2323
2424
2525 const requestLocationPermissions = async () => {
2626 if (Platform.OS === 'ios') {
2727
2828 await Geolocation.requestAuthorization('whenInUse');
2929 } else if (Platform.OS === 'android') {
3030 let permissionCheck: boolean = await PermissionsAndroid.check(
3131 PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
3232 );
3333
3434 if (permissionCheck !== true) {
3535 await PermissionsAndroid.request(
3636 PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
3737 {
3838 title: 'Location Permission Request',
3939 message:
4040 'This app needs you permission for using your location for querying GeoPoints in Parse!',
4141 buttonPositive: 'OK',
4242 },
4343 );
4444 }
4545 }
4646 };
4747
4848 const doQueryNear = async function (): Promise<boolean> {
4949
5050 await requestLocationPermissions();
5151
5252 Geolocation.getCurrentPosition(
5353 async (currentPosition: {
5454 coords: {latitude: number; longitude: number};
5555 }) => {
5656
5757 let currentLocationGeoPoint: Parse.GeoPoint = new Parse.GeoPoint(
5858 currentPosition.coords.latitude,
5959 currentPosition.coords.longitude,
6060 );
6161
6262
6363 let parseQuery: Parse.Query = new Parse.Query('City');
6464
6565
6666 parseQuery.near('location', currentLocationGeoPoint);
6767
6868 try {
6969 let results: [Parse.Object] = await parseQuery.find();
7070
7171 setQueryResults(results);
7272 } catch (error) {
7373
7474 Alert.alert('Error!', error.message);
7575 }
7676 },
7777 _error => {
7878 Alert.alert(
7979 'Error!',
8080 'This app needs your location permission to query this!',
8181 );
8282 },
8383 {enableHighAccuracy: true, timeout: 15000, maximumAge: 10000},
8484 );
8585 return true;
8686 };
8787
8888 const doQueryWithinKilometers = async function (): Promise<boolean> {
8989
9090 await requestLocationPermissions();
9191
9292 Geolocation.getCurrentPosition(
9393 async (currentPosition: {
9494 coords: {latitude: number; longitude: number};
9595 }) => {
9696
9797 let currentLocationGeoPoint: Parse.GeoPoint = new Parse.GeoPoint(
9898 currentPosition.coords.latitude,
9999 currentPosition.coords.longitude,
100100 );
101101
102102
103103 let parseQuery: Parse.Query = new Parse.Query('City');
104104
105105
106106
107107 parseQuery.withinKilometers('location', currentLocationGeoPoint, 3000);
108108
109109 try {
110110 let results: [Parse.Object] = await parseQuery.find();
111111
112112 setQueryResults(results);
113113 } catch (error) {
114114
115115 Alert.alert('Error!', error.message);
116116 }
117117 },
118118 _error => {
119119 Alert.alert(
120120 'Error!',
121121 'This app needs your location permission to query this!',
122122 );
123123 },
124124 {enableHighAccuracy: true, timeout: 15000, maximumAge: 10000},
125125 );
126126 return true;
127127 };
128128
129129 const doQueryWithinPolygon = async function (): Promise<boolean> {
130130
131131 let geoPoint1: Parse.GeoPoint = new Parse.GeoPoint(
132132 15.822.238.344.514.300,00
133133 -7.242.845.934.415.940,00
134134 );
135135 let geoPoint2: Parse.GeoPoint = new Parse.GeoPoint(
136136 -0.7433770196268968,
137137 -9.744.765.968.406.660,00
138138 );
139139 let geoPoint3: Parse.GeoPoint = new Parse.GeoPoint(
140140 -59.997.149.373.299.100,00
141141 -7.652.969.196.322.740,00
142142 );
143143 let geoPoint4: Parse.GeoPoint = new Parse.GeoPoint(
144144 -9.488.786.415.007.200,00
145145 -18.346.101.586.021.900,00
146146 );
147147 let geoPoint5: Parse.GeoPoint = new Parse.GeoPoint(
148148 15.414.859.532.811.000,00
149149 -6.000.625.459.569.370,00
150150 );
151151
152152
153153 let parseQuery: Parse.Query = new Parse.Query('City');
154154
155155
156156 parseQuery.withinPolygon('location', [
157157 geoPoint1,
158158 geoPoint2,
159159 geoPoint3,
160160 geoPoint4,
161161 geoPoint5,
162162 ]);
163163
164164 try {
165165 let results: [Parse.Object] = await parseQuery.find();
166166
167167 setQueryResults(results);
168168 } catch (error) {
169169
170170 Alert.alert('Error!', error.message);
171171 }
172172 };
173173
174174 const clearQueryResults = async function (): Promise<boolean> {
175175 setQueryResults(null);
176176 return true;
177177 };
178178
179179 return (
180180 <>
181181 <View style={Styles.header}>
182182 <Image
183183 style={Styles.header_logo}
184184 source={ {
185185 uri:
186186 'https://blog.back4app.com/wp-content/uploads/2019/05/back4app-white-logo-500px.png',
187187 } }
188188 />
189189 <PaperText style={Styles.header_text}>
190190 <PaperText style={Styles.header_text_bold}>
191191 {'React Native on Back4App - '}
192192 </PaperText>
193193 {' GeoPoint Queries'}
194194 </PaperText>
195195 </View>
196196 <ScrollView style={Styles.wrapper}>
197197 <View>
198198 <Title>{'Result List'}</Title>
199199 {}
200200 {queryResults !== null &&
201201 queryResults !== undefined &&
202202 queryResults.map((result: Parse.Object) => (
203203 <List.Item
204204 key={result.id}
205205 title={result.get('name')}
206206 titleStyle={Styles.list_text}
207207 style={Styles.list_item}
208208 />
209209 ))}
210210 {queryResults === null ||
211211 queryResults === undefined ||
212212 (queryResults !== null &&
213213 queryResults !== undefined &&
214214 queryResults.length <= 0) ? (
215215 <PaperText>{'No results here!'}</PaperText>
216216 ) : null}
217217 </View>
218218 <View>
219219 <Title>{'Query buttons'}</Title>
220220 <PaperButton
221221 onPress={() => doQueryNear()}
222222 mode="contained"
223223 icon="search-web"
224224 color={'#208AEC'}
225225 style={Styles.list_button}>
226226 {'Query Near'}
227227 </PaperButton>
228228 <PaperButton
229229 onPress={() => doQueryWithinKilometers()}
230230 mode="contained"
231231 icon="search-web"
232232 color={'#208AEC'}
233233 style={Styles.list_button}>
234234 {'Query Within KM'}
235235 </PaperButton>
236236 <PaperButton
237237 onPress={() => doQueryWithinPolygon()}
238238 mode="contained"
239239 icon="search-web"
240240 color={'#208AEC'}
241241 style={Styles.list_button}>
242242 {'Query Within Polygon'}
243243 </PaperButton>
244244 <PaperButton
245245 onPress={() => clearQueryResults()}
246246 mode="contained"
247247 icon="delete"
248248 color={'#208AEC'}
249249 style={Styles.list_button}>
250250 {'Clear Results'}
251251 </PaperButton>
252252 </View>
253253 </ScrollView>
254254 </>
255255 );
256256 };
257257
258258
259259 const Styles = StyleSheet.create({
260260 header: {
261261 alignItems: 'center',
262262 paddingTop: 30,
263263 paddingBottom: 50,
264264 backgroundColor: '#208AEC',
265265 },
266266 header_logo: {
267267 height: 50,
268268 width: 220,
269269 resizeMode: 'contain',
270270 },
271271 header_text: {
272272 marginTop: 15,
273273 color: '#f0f0f0',
274274 fontSize: 16,
275275 },
276276 header_text_bold: {
277277 color: '#fff',
278278 fontWeight: 'bold',
279279 },
280280 wrapper: {
281281 width: '90%',
282282 alignSelf: 'center',
283283 },
284284 list_button: {
285285 marginTop: 6,
286286 marginLeft: 15,
287287 height: 40,
288288 },
289289 list_item: {
290290 borderBottomWidth: 1,
291291 borderBottomColor: 'rgba(0, 0, 0, 0.12)',
292292 },
293293 list_text: {
294294 fontSize: 15,
295295 },
296296 });