react-native-radar 3.7.6-beta.1 → 3.7.6-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,7 @@ android {
18
18
  minSdkVersion 16
19
19
  targetSdkVersion 31
20
20
  versionCode 1
21
- versionName '3.7.6-beta.1'
21
+ versionName '3.7.5'
22
22
  }
23
23
  lintOptions {
24
24
  abortOnError false
package/ios/RNRadar.h CHANGED
@@ -1,5 +1,4 @@
1
1
  #import <RadarSDK/RadarSDK.h>
2
- #import <RadarSDK/RadarSettings.h>
3
2
  #import <React/RCTBridgeModule.h>
4
3
  #import <React/RCTEventEmitter.h>
5
4
 
package/ios/RNRadar.m CHANGED
@@ -139,14 +139,6 @@ RCT_EXPORT_METHOD(setAnonymousTrackingEnabled:(BOOL)enabled) {
139
139
  [Radar setAnonymousTrackingEnabled:enabled];
140
140
  }
141
141
 
142
- RCT_EXPORT_METHOD(host:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
143
- resolve([RadarSettings host]);
144
- }
145
-
146
- RCT_EXPORT_METHOD(publishableKey:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
147
- resolve([RadarSettings publishableKey]);
148
- }
149
-
150
142
  RCT_REMAP_METHOD(getPermissionsStatus, getPermissionsStatusWithResolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
151
143
  CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
152
144
  NSString *statusStr;
@@ -737,16 +729,19 @@ RCT_EXPORT_METHOD(autocomplete:(NSDictionary *)optionsDict resolve:(RCTPromiseRe
737
729
  }
738
730
 
739
731
  NSDictionary *nearDict = optionsDict[@"near"];
740
- CLLocation *near = nil;
741
- if (nearDict && [nearDict isKindOfClass:[NSDictionary class]]) {
742
- double latitude = [RCTConvert double:nearDict[@"latitude"]];
743
- double longitude = [RCTConvert double:nearDict[@"longitude"]];
744
- NSDate *timestamp = [NSDate new];
745
- near = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:timestamp];
746
- }
732
+ if (nearDict == nil || ![nearDict isKindOfClass:[NSDictionary class]]) {
733
+ if (reject) {
734
+ reject([Radar stringForStatus:RadarStatusErrorBadRequest], [Radar stringForStatus:RadarStatusErrorBadRequest], nil);
735
+ }
747
736
 
737
+ return;
738
+ }
748
739
 
749
740
  NSString *query = optionsDict[@"query"];
741
+ double latitude = [RCTConvert double:nearDict[@"latitude"]];
742
+ double longitude = [RCTConvert double:nearDict[@"longitude"]];
743
+ NSDate *timestamp = [NSDate new];
744
+ CLLocation *near = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:timestamp];
750
745
  NSNumber *limitNumber = optionsDict[@"limit"];
751
746
  int limit;
752
747
  if (limitNumber != nil && [limitNumber isKindOfClass:[NSNumber class]]) {
package/js/index.js CHANGED
@@ -1,12 +1,9 @@
1
1
  import { Platform } from 'react-native';
2
2
 
3
3
  let module = {};
4
- if (Platform.OS === 'web') {
5
- module = require('./index.web').default;
6
- } else {
4
+ if (Platform.OS === 'web')
5
+ module = require('./index.web').default;
6
+ else
7
7
  module = require('./index.native').default;
8
- }
9
- export default module;
10
8
 
11
- export { default as Autocomplete } from './ui/autocomplete';
12
- export { default as Map } from './ui/map';
9
+ export default module;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "React Native module for Radar, the leading geofencing and location tracking platform",
4
4
  "homepage": "https://radar.com",
5
5
  "license": "Apache-2.0",
6
- "version": "3.7.6-beta.1",
6
+ "version": "3.7.6-beta.4",
7
7
  "main": "js/index.js",
8
8
  "files": [
9
9
  "android",
@@ -13,7 +13,9 @@
13
13
  "react-native-radar.podspec"
14
14
  ],
15
15
  "scripts": {
16
- "test": "jest ./test/*.test.js"
16
+ "test": "jest ./test/*.test.js",
17
+ "check-latest-tag": "node ./scripts/check-latest-tag.cjs",
18
+ "check-beta-tag": "node ./scripts/check-beta-tag.cjs"
17
19
  },
18
20
  "jest": {
19
21
  "preset": "react-native",
@@ -25,8 +27,7 @@
25
27
  },
26
28
  "peerDependencies": {
27
29
  "react": ">= 16.8.6",
28
- "react-native": ">= 0.60.0",
29
- "@maplibre/maplibre-react-native": "^9.0.1"
30
+ "react-native": ">= 0.60.0"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@babel/core": "^7.2.2",
package/js/helpers.js DELETED
@@ -1,15 +0,0 @@
1
- import { NativeModules, Platform } from 'react-native';
2
-
3
- if (!NativeModules.RNRadar && (Platform.OS === 'ios' || Platform.OS === 'android')) {
4
- throw new Error('NativeModules.RNRadar is undefined');
5
- }
6
-
7
- const getHost = () => (
8
- NativeModules.RNRadar.host()
9
- );
10
-
11
- const getPublishableKey = () => (
12
- NativeModules.RNRadar.publishableKey()
13
- );
14
-
15
- export { getHost, getPublishableKey };
package/js/ui/README.md DELETED
@@ -1,67 +0,0 @@
1
- ## Example usage
2
-
3
- We provide UI elements for autocomplete & maps to make building easy.
4
-
5
- If you're using the Map element, you'll need to install [Maplibre React Native](https://github.com/maplibre/maplibre-react-native).
6
- ```
7
- npm install @maplibre/maplibre-react-native
8
- ```
9
-
10
- Then make sure to complete required [platform specific installation steps](https://github.com/maplibre/maplibre-react-native/blob/main/docs/GettingStarted.md#review-platform-specific-info) as well.
11
-
12
- ### Adding a map
13
-
14
- We've taken care of linking the map tile server to the map, so all you need to do is make sure you've initialized the Radar SDK and use `<Map>`
15
-
16
- ```
17
- import {StyleSheet, View} from 'react-native';
18
- import Radar, { Map } from 'react-native-radar';
19
-
20
- export default function App() {
21
- Radar.initialize('prj_place_your_own_token_here');
22
-
23
- // A quirk of Map Libre requires us to set their deprecated access token to null
24
- MapLibreGL.setAccessToken(null);
25
-
26
- return (
27
- <View style={styles.page}>
28
- <Map />
29
- </View>
30
- );
31
- }
32
- ```
33
-
34
- TODO: fill in details on customization, including using MapLibre elements
35
-
36
- ### Adding an address autocomplete
37
-
38
- Adding an address search autocomplete is similarly easy. Our `<Autocomplete>` element is comprised of a TextInput and Flatlist with the results.
39
-
40
- The example below provides optional `location` and `onSelect` props to the component. Providing a location will improve autocomplete result quality. Without it, the API utilizes the IP address location to rank results.
41
-
42
- ```
43
- import Radar, { Map } from 'react-native-radar';
44
-
45
- export default function App() {
46
- const [location, setLocation] = useState(null);
47
-
48
- Radar.trackOnce().then((result) => {
49
- setLocation({
50
- latitude: result.location.latitude,
51
- longitude: result.location.longitude,
52
- });
53
- });
54
-
55
- const onSelect (selectedAddress) => {
56
- // Do something with the selected address
57
- }
58
-
59
- return (
60
- <View style={style.page}>
61
- <Autocomplete location={location} onSelect={onSelect} />
62
- </View>
63
- );
64
- }
65
- ```
66
-
67
- TODO: fill in details of customization
@@ -1,280 +0,0 @@
1
- // Autocomplete.js
2
- import React, { useState, useCallback, useRef } from 'react';
3
- import {
4
- View,
5
- TextInput,
6
- FlatList,
7
- TouchableOpacity,
8
- Text,
9
- StyleSheet,
10
- Image,
11
- } from 'react-native';
12
- import Radar from '../index.native';
13
-
14
- const defaultStyles = StyleSheet.create({
15
- container: {
16
- width: '100%',
17
- alignItems: 'center',
18
- justifyContent: 'center',
19
- padding: 8,
20
- },
21
- inputContainer: {
22
- flexDirection: 'row',
23
- alignItems: 'center',
24
- width: '95%',
25
- backgroundColor: 'white',
26
- borderRadius: 5,
27
- shadowColor: "#061A2B",
28
- shadowOffset: {
29
- width: 0,
30
- height: 4,
31
- },
32
- shadowOpacity: 0.1,
33
- shadowRadius: 12,
34
- elevation: 5,
35
- },
36
- inputIcon: {
37
- marginLeft: 10,
38
- height: 18,
39
- width: 18,
40
- backgroundColor: 'white',
41
- color: 'white',
42
- },
43
- input: {
44
- flex: 1,
45
- backgroundColor: 'white',
46
- height: 40,
47
- fontSize: 14,
48
- paddingTop: 2,
49
- paddingHorizontal: 8,
50
- borderRadius: 5,
51
- shadowOpacity: 0,
52
- },
53
- inputFocused: {
54
- shadowColor: "#81BEFF",
55
- shadowOffset: {
56
- width: 0,
57
- height: 0,
58
- },
59
- shadowOpacity: 1,
60
- shadowRadius: 4,
61
- elevation: 4,
62
- },
63
- resultListWrapper: {
64
- width: '95%',
65
- marginTop: 8,
66
- backgroundColor: 'white',
67
- borderRadius: 5,
68
- paddingVertical: 8,
69
- paddingHorizontal: 8,
70
- shadowColor: "#061A2B",
71
- shadowOffset: {
72
- width: 0,
73
- height: 4,
74
- },
75
- shadowOpacity: 0.1,
76
- shadowRadius: 12,
77
- elevation: 5,
78
- },
79
- resultList: {
80
- width: '100%',
81
- },
82
- resultItem: {
83
- paddingRight: 16,
84
- paddingVertical: 8,
85
- height: 56,
86
- fontSize: 12,
87
- },
88
- addressContainer: {
89
- flexDirection: 'row',
90
- alignItems: 'center',
91
- },
92
- pinIconContainer: {
93
- width: 28,
94
- },
95
- pinIcon: {
96
- height: 20,
97
- width: 20,
98
- marginRight: 8,
99
- marginBottom: 14,
100
- },
101
- addressTextContainer: {
102
- flex: 1,
103
- },
104
- addressText: {
105
- fontSize: 14,
106
- color: '#000',
107
- fontWeight: '600',
108
- },
109
- addressSubtext: {
110
- fontSize: 12,
111
- color: '#5A6872',
112
- },
113
- footerContainer: {
114
- flexDirection: 'row',
115
- alignItems: 'center',
116
- padding: 10,
117
- alignSelf: 'flex-end',
118
- },
119
- footerText: {
120
- marginTop: 2,
121
- marginRight: 4,
122
- fontSize: 10,
123
- color: '#5A6872',
124
- },
125
- logo: {
126
- width: 50,
127
- height: 15,
128
- resizeMode: 'contain',
129
- },
130
- });
131
-
132
- const defaultAutocompleteOptions = {
133
- debounceMS: 200,
134
- threshold: 3,
135
- limit: 8,
136
- placeholder: 'Search address',
137
- showPin: true,
138
- };
139
-
140
- const autocompleteUI = ({ options = {}, onSelect, location, style = {} }) => {
141
- const [query, setQuery] = useState('');
142
- const [results, setResults] = useState([]);
143
- const [isOpen, setIsOpen] = useState(false);
144
- const [isInputFocused, setInputFocused] = useState(false);
145
- const timerRef = useRef(null);
146
-
147
- const config = { ...defaultAutocompleteOptions, ...options };
148
-
149
- const fetchResults = useCallback(async (searchQuery) => {
150
- if (searchQuery.length < config.threshold) return;
151
-
152
- const params = { query: searchQuery, limit: config.limit };
153
-
154
- if (location && location.latitude && location.longitude) {
155
- params.near = location;
156
- }
157
-
158
- try {
159
- const result = await Radar.autocomplete(params);
160
- setResults(result.addresses);
161
- setIsOpen(true);
162
- } catch (error) {
163
- if (config.onError && typeof config.onError === 'function') {
164
- config.onError(error);
165
- }
166
- }
167
- }, [config]);
168
-
169
- const handleInput = useCallback(
170
- (text) => {
171
- setQuery(text);
172
-
173
- // Clear the existing timer
174
- if (timerRef.current) {
175
- clearTimeout(timerRef.current);
176
- }
177
-
178
- if (text.length < config.threshold) {
179
- return;
180
- }
181
-
182
- // Set the new timer
183
- timerRef.current = setTimeout(() => {
184
- fetchResults(text);
185
- }, config.debounceMS);
186
- },
187
- [config, fetchResults],
188
- );
189
-
190
- const handleSelect = (item) => {
191
- setQuery(item.formattedAddress);
192
- setIsOpen(false);
193
-
194
- if (typeof onSelect === 'function') {
195
- onSelect(item);
196
- }
197
- };
198
-
199
- const renderFooter = () => {
200
- if (results.length === 0) return null;
201
-
202
- return (
203
- <View style={styles.footerContainer}>
204
- <View style={{ flexDirection: 'row', alignItems: 'center' }}>
205
- <Text style={styles.footerText}>Powered by</Text>
206
- <Image source={require('./radar-logo.png')} resizeMode="contain" style={defaultStyles.logo} />
207
- </View>
208
- </View>
209
- );
210
- };
211
-
212
- const renderItem = ({ item }) => (
213
- <TouchableOpacity style={styles.resultItem} onPress={() => handleSelect(item)}>
214
- <View style={styles.addressContainer}>
215
- <View style={styles.pinIconContainer}>
216
- {config.showPin ? (
217
- <Image source={require('./marker.png')} style={styles.pinIcon} />
218
- ) : null}
219
- </View>
220
- <View style={styles.addressTextContainer}>
221
- <Text numberOfLines={1} style={styles.addressText}>
222
- {item.addressLabel || item?.placeLabel}
223
- </Text>
224
- <Text numberOfLines={1} style={styles.addressSubtext}>
225
- {item?.formattedAddress?.replace(`${item?.addressLabel || item?.placeLabel}, `, '')}
226
- </Text>
227
- </View>
228
- </View>
229
- </TouchableOpacity>
230
- );
231
-
232
- const styles = {
233
- ...defaultStyles,
234
- container: StyleSheet.compose(defaultStyles.container, style.container),
235
- input: StyleSheet.compose(defaultStyles.input, style.input),
236
- resultList: StyleSheet.compose(defaultStyles.resultList, style.resultList),
237
- resultItem: StyleSheet.compose(defaultStyles.resultItem, style.resultItem),
238
- addressContainer: StyleSheet.compose(defaultStyles.addressContainer, style.addressContainer),
239
- pinIconContainer: StyleSheet.compose(defaultStyles.pinIconContainer, style.pinIconContainer),
240
- pinIcon: StyleSheet.compose(defaultStyles.pinIcon, style.pinIcon),
241
- addressTextContainer: StyleSheet.compose(defaultStyles.addressTextContainer, style.addressTextContainer),
242
- addressText: StyleSheet.compose(defaultStyles.addressText, style.addressText),
243
- addressSubtext: StyleSheet.compose(defaultStyles.addressSubtext, style.addressSubtext),
244
- footerContainer: StyleSheet.compose(defaultStyles.footerContainer, style.footerContainer),
245
- footerText: StyleSheet.compose(defaultStyles.footerText, style.footerText),
246
- };
247
-
248
- const inputStyle = isInputFocused
249
- ? StyleSheet.compose(styles.inputContainer, defaultStyles.inputFocused)
250
- : styles.inputContainer;
251
-
252
- return (
253
- <View style={styles.container}>
254
- <View style={inputStyle}>
255
- <Image source={require('./search.png')} style={styles.inputIcon} />
256
- <TextInput
257
- style={styles.input}
258
- onChangeText={handleInput}
259
- onFocus={() => setInputFocused(true)}
260
- onBlur={() => setInputFocused(false)}
261
- value={query}
262
- placeholder={config.placeholder}
263
- />
264
- </View>
265
- {isOpen && (
266
- <View style={defaultStyles.resultListWrapper}>
267
- <FlatList
268
- style={styles.resultList}
269
- data={results}
270
- renderItem={renderItem}
271
- keyExtractor={(item) => item.formattedAddress + item.postalCode}
272
- ListFooterComponent={renderFooter}
273
- />
274
- </View>
275
- )}
276
- </View>
277
- );
278
- };
279
-
280
- export default autocompleteUI;
Binary file
package/js/ui/map.jsx DELETED
@@ -1,66 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { StyleSheet, View, Image } from 'react-native';
3
- import MapLibreGL from '@maplibre/maplibre-react-native';
4
- import { getHost, getPublishableKey } from '../helpers';
5
-
6
- const DEFAULT_STYLE = 'radar-default-v1';
7
-
8
- const styles = StyleSheet.create({
9
- container: {
10
- flex: 1,
11
- },
12
- map: {
13
- flex: 1,
14
- },
15
- logo: {
16
- position: 'absolute',
17
- bottom: -10,
18
- left: 5,
19
- width: 50,
20
- height: 50,
21
- resizeMode: 'contain',
22
- },
23
- });
24
-
25
- const createStyleURL = async (style = DEFAULT_STYLE) => {
26
- const host = await getHost();
27
- const publishableKey = await getPublishableKey();
28
- return `${host}/maps/styles/${style}?publishableKey=${publishableKey}`;
29
- };
30
-
31
- const RadarMap = ({ mapOptions, children }) => {
32
- const [styleURL, setStyleURL] = useState(null);
33
-
34
- useEffect(() => {
35
- createStyleURL(mapOptions?.mapStyle || DEFAULT_STYLE).then((result) => {
36
- setStyleURL(result);
37
- });
38
- }, [mapOptions]);
39
-
40
- if (!styleURL) {
41
- return null;
42
- }
43
-
44
- return (
45
- <View style={styles.container}>
46
- <MapLibreGL.MapView
47
- style={styles.map}
48
- pitchEnabled={false}
49
- compassEnabled={false}
50
- logoEnabled={false}
51
- attributionEnabled
52
- onRegionDidChange={mapOptions.onRegionDidChange ? mapOptions.onRegionDidChange : null}
53
- styleURL={styleURL}
54
- >
55
- <MapLibreGL.UserLocation />
56
- {children}
57
- </MapLibreGL.MapView>
58
- <Image
59
- source={require('./map-logo.png')}
60
- style={styles.logo}
61
- />
62
- </View>
63
- );
64
- };
65
-
66
- export default RadarMap;
package/js/ui/marker.png DELETED
Binary file
Binary file
package/js/ui/search.png DELETED
Binary file