react-native-radar 3.8.3 → 3.8.5
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.
- package/android/build.gradle +2 -2
- package/android/src/main/java/io/radar/react/RNRadarModule.java +8 -4
- package/ios/RNRadar.m +5 -2
- package/js/index.native.js +2 -2
- package/js/ui/autocomplete.jsx +24 -13
- package/js/ui/map-logo.png +0 -0
- package/js/ui/map.jsx +16 -4
- package/js/ui/styles.js +0 -19
- package/package.json +1 -1
- package/js/ui/README.md +0 -157
package/android/build.gradle
CHANGED
|
@@ -18,7 +18,7 @@ android {
|
|
|
18
18
|
minSdkVersion 16
|
|
19
19
|
targetSdkVersion 31
|
|
20
20
|
versionCode 1
|
|
21
|
-
versionName '3.8.
|
|
21
|
+
versionName '3.8.6'
|
|
22
22
|
}
|
|
23
23
|
lintOptions {
|
|
24
24
|
abortOnError false
|
|
@@ -45,5 +45,5 @@ repositories {
|
|
|
45
45
|
|
|
46
46
|
dependencies {
|
|
47
47
|
api 'com.facebook.react:react-native:+'
|
|
48
|
-
api 'io.radar:sdk:3.8.
|
|
48
|
+
api 'io.radar:sdk:3.8.6'
|
|
49
49
|
}
|
|
@@ -78,9 +78,13 @@ public class RNRadarModule extends ReactContextBaseJavaModule implements Permiss
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
@ReactMethod
|
|
81
|
-
public void initialize(String publishableKey) {
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
public void initialize(String publishableKey, boolean fraud) {
|
|
82
|
+
if (fraud) {
|
|
83
|
+
Radar.initialize(getReactApplicationContext(), publishableKey, receiver, Radar.RadarLocationServicesProvider.GOOGLE, fraud);
|
|
84
|
+
} else {
|
|
85
|
+
Radar.initialize(getReactApplicationContext(), publishableKey);
|
|
86
|
+
Radar.setReceiver(receiver);
|
|
87
|
+
}
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
@ReactMethod
|
|
@@ -871,7 +875,7 @@ public class RNRadarModule extends ReactContextBaseJavaModule implements Permiss
|
|
|
871
875
|
near.setLatitude(latitude);
|
|
872
876
|
near.setLongitude(longitude);
|
|
873
877
|
int limit = optionsMap.hasKey("limit") ? optionsMap.getInt("limit") : 10;
|
|
874
|
-
String country = optionsMap.hasKey("country") ? optionsMap.getString("country") : null;
|
|
878
|
+
String country = optionsMap.hasKey("countryCode") ? optionsMap.getString("countryCode") : optionsMap.hasKey("country") ? optionsMap.getString("country") : null;
|
|
875
879
|
String[] layers = optionsMap.hasKey("layers") ? RNRadarUtils.stringArrayForArray(optionsMap.getArray("layers")) : null;
|
|
876
880
|
|
|
877
881
|
Radar.autocomplete(query, near, layers, limit, country, new Radar.RadarGeocodeCallback() {
|
package/ios/RNRadar.m
CHANGED
|
@@ -91,7 +91,7 @@ RCT_EXPORT_MODULE();
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
RCT_EXPORT_METHOD(initialize:(NSString *)publishableKey) {
|
|
94
|
+
RCT_EXPORT_METHOD(initialize:(NSString *)publishableKey fraud:(BOOL)fraud) {
|
|
95
95
|
[Radar initializeWithPublishableKey:publishableKey];
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -756,7 +756,10 @@ RCT_EXPORT_METHOD(autocomplete:(NSDictionary *)optionsDict resolve:(RCTPromiseRe
|
|
|
756
756
|
}
|
|
757
757
|
|
|
758
758
|
NSArray *layers = optionsDict[@"layers"];
|
|
759
|
-
NSString *country = optionsDict[@"
|
|
759
|
+
NSString *country = optionsDict[@"countryCode"];
|
|
760
|
+
if (country == nil) {
|
|
761
|
+
country = optionsDict[@"country"];
|
|
762
|
+
}
|
|
760
763
|
|
|
761
764
|
__block RCTPromiseResolveBlock resolver = resolve;
|
|
762
765
|
__block RCTPromiseRejectBlock rejecter = reject;
|
package/js/index.native.js
CHANGED
|
@@ -6,8 +6,8 @@ if (!NativeModules.RNRadar && (Platform.OS === 'ios' || Platform.OS === 'android
|
|
|
6
6
|
|
|
7
7
|
const eventEmitter = new NativeEventEmitter(NativeModules.RNRadar);
|
|
8
8
|
|
|
9
|
-
const initialize = (publishableKey) => {
|
|
10
|
-
NativeModules.RNRadar.initialize(publishableKey);
|
|
9
|
+
const initialize = (publishableKey, fraud) => {
|
|
10
|
+
NativeModules.RNRadar.initialize(publishableKey, fraud);
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
const setLogLevel = (level) => {
|
package/js/ui/autocomplete.jsx
CHANGED
|
@@ -28,14 +28,15 @@ import {
|
|
|
28
28
|
import { default as defaultStyles } from './styles';
|
|
29
29
|
|
|
30
30
|
const defaultAutocompleteOptions = {
|
|
31
|
-
debounceMS: 200,
|
|
32
|
-
threshold: 3,
|
|
33
|
-
limit: 8,
|
|
34
|
-
placeholder: "Search address",
|
|
35
|
-
|
|
31
|
+
debounceMS: 200, // Debounce time in milliseconds
|
|
32
|
+
threshold: 3, // Minimum number of characters to trigger autocomplete
|
|
33
|
+
limit: 8, // Maximum number of results to return
|
|
34
|
+
placeholder: "Search address", // Placeholder text for the input field
|
|
35
|
+
showMarkers: true,
|
|
36
|
+
disabled: false,
|
|
36
37
|
};
|
|
37
38
|
|
|
38
|
-
const autocompleteUI = ({ options = {}
|
|
39
|
+
const autocompleteUI = ({ options = {} }) => {
|
|
39
40
|
const [query, setQuery] = useState("");
|
|
40
41
|
const [results, setResults] = useState([]);
|
|
41
42
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -43,20 +44,28 @@ const autocompleteUI = ({ options = {}, onSelect, location, style = {} }) => {
|
|
|
43
44
|
const timerRef = useRef(null);
|
|
44
45
|
const textInputRef = useRef(null);
|
|
45
46
|
|
|
47
|
+
|
|
46
48
|
const config = { ...defaultAutocompleteOptions, ...options };
|
|
49
|
+
const style = config.style || {};
|
|
47
50
|
|
|
48
51
|
const fetchResults = useCallback(
|
|
49
52
|
async (searchQuery) => {
|
|
50
53
|
if (searchQuery.length < config.threshold) return;
|
|
51
54
|
|
|
52
|
-
const
|
|
55
|
+
const { limit, layers, countryCode } = config;
|
|
56
|
+
const params = { query: searchQuery, limit, layers, countryCode };
|
|
53
57
|
|
|
54
|
-
if (
|
|
55
|
-
params.near =
|
|
58
|
+
if (config.near && config.near.latitude && config.near.longitude) {
|
|
59
|
+
params.near = config.near;
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
try {
|
|
59
63
|
const result = await Radar.autocomplete(params);
|
|
64
|
+
|
|
65
|
+
if (config.onResults && typeof config.onResults === "function") {
|
|
66
|
+
config.onResults(result.addresses);
|
|
67
|
+
}
|
|
68
|
+
|
|
60
69
|
setResults(result.addresses);
|
|
61
70
|
setIsOpen(true);
|
|
62
71
|
} catch (error) {
|
|
@@ -93,8 +102,8 @@ const autocompleteUI = ({ options = {}, onSelect, location, style = {} }) => {
|
|
|
93
102
|
setQuery(item.formattedAddress);
|
|
94
103
|
setIsOpen(false);
|
|
95
104
|
|
|
96
|
-
if (typeof
|
|
97
|
-
|
|
105
|
+
if (typeof config.onSelection === "function") {
|
|
106
|
+
config.onSelection(item);
|
|
98
107
|
}
|
|
99
108
|
};
|
|
100
109
|
|
|
@@ -129,7 +138,7 @@ const autocompleteUI = ({ options = {}, onSelect, location, style = {} }) => {
|
|
|
129
138
|
>
|
|
130
139
|
<View style={styles.addressContainer}>
|
|
131
140
|
<View style={styles.pinIconContainer}>
|
|
132
|
-
{config.
|
|
141
|
+
{config.showMarkers ? (
|
|
133
142
|
<Image source={MARKER_ICON} style={styles.pinIcon} />
|
|
134
143
|
) : null}
|
|
135
144
|
</View>
|
|
@@ -163,7 +172,7 @@ const autocompleteUI = ({ options = {}, onSelect, location, style = {} }) => {
|
|
|
163
172
|
style.modalInputContainer
|
|
164
173
|
),
|
|
165
174
|
resultList: StyleSheet.compose(defaultStyles.resultList, style.resultList),
|
|
166
|
-
resultItem: StyleSheet.compose(defaultStyles.resultItem, style.resultItem),
|
|
175
|
+
resultItem: StyleSheet.compose({...defaultStyles.resultItem, pressedBackgroundColor: '#F6FAFC'}, style.resultItem),
|
|
167
176
|
addressContainer: StyleSheet.compose(
|
|
168
177
|
defaultStyles.addressContainer,
|
|
169
178
|
style.addressContainer
|
|
@@ -219,6 +228,8 @@ const autocompleteUI = ({ options = {}, onSelect, location, style = {} }) => {
|
|
|
219
228
|
<TouchableOpacity
|
|
220
229
|
style={styles.inputContainer}
|
|
221
230
|
onPress={() => {
|
|
231
|
+
if (config.disabled) return;
|
|
232
|
+
|
|
222
233
|
setIsOpen(true);
|
|
223
234
|
// Set the focus on the other textinput after it opens
|
|
224
235
|
setTimeout(() => {
|
package/js/ui/map-logo.png
CHANGED
|
Binary file
|
package/js/ui/map.jsx
CHANGED
|
@@ -66,17 +66,29 @@ const RadarMap = ({ mapOptions, children }) => {
|
|
|
66
66
|
>
|
|
67
67
|
<MapLibreGL.CircleLayer
|
|
68
68
|
id="user-location-inner"
|
|
69
|
-
style={
|
|
69
|
+
style={{
|
|
70
|
+
circleRadius: 15,
|
|
71
|
+
circleColor: '#000257',
|
|
72
|
+
circleOpacity: 0.2,
|
|
73
|
+
circlePitchAlignment: 'map',
|
|
74
|
+
}}
|
|
70
75
|
/>
|
|
71
76
|
<MapLibreGL.CircleLayer
|
|
72
77
|
id="user-location-middle"
|
|
73
|
-
style={
|
|
78
|
+
style={{
|
|
79
|
+
circleRadius: 9,
|
|
80
|
+
circleColor: '#fff',
|
|
81
|
+
circlePitchAlignment: 'map',
|
|
82
|
+
}}
|
|
74
83
|
/>
|
|
75
84
|
<MapLibreGL.CircleLayer
|
|
76
85
|
id="user-location-outer"
|
|
77
|
-
style={
|
|
86
|
+
style={{
|
|
87
|
+
circleRadius: 6,
|
|
88
|
+
circleColor: '#000257',
|
|
89
|
+
circlePitchAlignment: 'map',
|
|
90
|
+
}}
|
|
78
91
|
/>
|
|
79
|
-
|
|
80
92
|
</MapLibreGL.ShapeSource>
|
|
81
93
|
);
|
|
82
94
|
|
package/js/ui/styles.js
CHANGED
|
@@ -62,7 +62,6 @@ const styles = StyleSheet.create({
|
|
|
62
62
|
paddingHorizontal: 16,
|
|
63
63
|
fontSize: 12,
|
|
64
64
|
backgroundColor: 'white',
|
|
65
|
-
pressedBackgroundColor: '#F6FAFC',
|
|
66
65
|
},
|
|
67
66
|
addressContainer: {
|
|
68
67
|
flexDirection: 'row',
|
|
@@ -121,24 +120,6 @@ const styles = StyleSheet.create({
|
|
|
121
120
|
height: 50,
|
|
122
121
|
resizeMode: 'contain',
|
|
123
122
|
},
|
|
124
|
-
userLocation: {
|
|
125
|
-
pulse: {
|
|
126
|
-
circleRadius: 15,
|
|
127
|
-
circleColor: '#000257',
|
|
128
|
-
circleOpacity: 0.2,
|
|
129
|
-
circlePitchAlignment: 'map',
|
|
130
|
-
},
|
|
131
|
-
background: {
|
|
132
|
-
circleRadius: 9,
|
|
133
|
-
circleColor: '#fff',
|
|
134
|
-
circlePitchAlignment: 'map',
|
|
135
|
-
},
|
|
136
|
-
foreground: {
|
|
137
|
-
circleRadius: 6,
|
|
138
|
-
circleColor: '#000257',
|
|
139
|
-
circlePitchAlignment: 'map',
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
123
|
});
|
|
143
124
|
|
|
144
125
|
export default styles;
|
package/package.json
CHANGED
package/js/ui/README.md
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
## Example usage
|
|
2
|
-
|
|
3
|
-
We provide UI elements for autocomplete & maps to make building easy.
|
|
4
|
-
|
|
5
|
-
### Adding an address autocomplete
|
|
6
|
-
|
|
7
|
-
Adding an address search autocomplete is straightforward. Our `<Autocomplete>` element is comprised of a TextInput and Flatlist with the results.
|
|
8
|
-
|
|
9
|
-
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.
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
import { View } from 'react-native';
|
|
13
|
-
import { useState, useEffect } from 'react';
|
|
14
|
-
import Radar, { Autocomplete } from 'react-native-radar';
|
|
15
|
-
|
|
16
|
-
export default function App() {
|
|
17
|
-
const [location, setLocation] = useState(null);
|
|
18
|
-
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
Radar.initialize('prj_live_pk_...');
|
|
21
|
-
|
|
22
|
-
Radar.trackOnce().then((result) => {
|
|
23
|
-
setLocation({
|
|
24
|
-
latitude: result.location.latitude,
|
|
25
|
-
longitude: result.location.longitude,
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
}, []);
|
|
29
|
-
|
|
30
|
-
const onSelect = (selectedAddress) => {
|
|
31
|
-
// Do something with the selected address
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<View style={{ marginTop: 50}}>
|
|
36
|
-
<Autocomplete location={location} onSelect={onSelect} />
|
|
37
|
-
</View>
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Adding a map
|
|
44
|
-
|
|
45
|
-
If you're using the Map element, you'll need to install [Maplibre React Native](https://github.com/maplibre/maplibre-react-native), which `react-native-radar` has an optional peer dependency.
|
|
46
|
-
```
|
|
47
|
-
npm install @maplibre/maplibre-react-native
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
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.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
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>`. Here's a minimal example:
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
import {View} from 'react-native';
|
|
57
|
-
import Radar, { Map } from 'react-native-radar';
|
|
58
|
-
import MapLibreGL from '@maplibre/maplibre-react-native';
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// A quirk of Map Libre requires us to set their deprecated access token to null
|
|
62
|
-
MapLibreGL.setAccessToken(null);
|
|
63
|
-
|
|
64
|
-
export default function App() {
|
|
65
|
-
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
Radar.initialize('prj_live_pk_...');
|
|
68
|
-
}, []);
|
|
69
|
-
|
|
70
|
-
return (
|
|
71
|
-
<View style={{ width: '100%', height: '95%'}}>
|
|
72
|
-
<Map />
|
|
73
|
-
</View>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
And here's how you might add a custom pin to the map and control the camera:
|
|
79
|
-
```
|
|
80
|
-
// ... rest of your file
|
|
81
|
-
|
|
82
|
-
const [cameraConfig, setCameraConfig] = useState({
|
|
83
|
-
triggerKey: Date.now(),
|
|
84
|
-
centerCoordinate: [-73.9911, 40.7342],
|
|
85
|
-
animationMode: 'flyTo',
|
|
86
|
-
animationDuration: 600,
|
|
87
|
-
zoomLevel: 12,
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
const onRegionDidChange = (event) => {
|
|
91
|
-
// handle region change
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const mapOptions = {
|
|
95
|
-
onRegionDidChange: onRegionDidChange,
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const onSelect = (selectedAddress) => {
|
|
99
|
-
// Do something with the selected address
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const pointsCollection = {
|
|
103
|
-
type: "FeatureCollection",
|
|
104
|
-
features: [{
|
|
105
|
-
type: "Feature",
|
|
106
|
-
properties: {
|
|
107
|
-
_id: '123',
|
|
108
|
-
},
|
|
109
|
-
geometry: {
|
|
110
|
-
type: "Point",
|
|
111
|
-
coordinates: [-73.9911, 40.7342]
|
|
112
|
-
}
|
|
113
|
-
}]
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const onPressIcon = (event) => {
|
|
117
|
-
// do something with the symbol, such as scrolling to the geofence
|
|
118
|
-
// associated with the icon in the list
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return (
|
|
122
|
-
<View style={{ width: '100%', marginTop: '10%', height: '90%'}}>
|
|
123
|
-
<Map mapOptions={mapOptions}>
|
|
124
|
-
<MapLibreGL.Camera
|
|
125
|
-
{...cameraConfig}
|
|
126
|
-
/>
|
|
127
|
-
<MapLibreGL.Images
|
|
128
|
-
images={{
|
|
129
|
-
icon: require('./assets/marker.png'),
|
|
130
|
-
}}
|
|
131
|
-
/>
|
|
132
|
-
<MapLibreGL.ShapeSource
|
|
133
|
-
id="points"
|
|
134
|
-
shape={pointsCollection}
|
|
135
|
-
onPress={onPressIcon}
|
|
136
|
-
>
|
|
137
|
-
|
|
138
|
-
<MapLibreGL.SymbolLayer
|
|
139
|
-
id="symbol"
|
|
140
|
-
style={{
|
|
141
|
-
iconImage: 'icon',
|
|
142
|
-
iconSize: [
|
|
143
|
-
'interpolate',
|
|
144
|
-
['linear'],
|
|
145
|
-
['zoom'],
|
|
146
|
-
0, 0.2, // Adjust the icon size for zoom level 0
|
|
147
|
-
12, 0.4, // Adjust the icon size for zoom level 12
|
|
148
|
-
22, 0.8, // Adjust the icon size for zoom level 22
|
|
149
|
-
],
|
|
150
|
-
iconAllowOverlap: true,
|
|
151
|
-
}}
|
|
152
|
-
/>
|
|
153
|
-
</MapLibreGL.ShapeSource>
|
|
154
|
-
</Map>
|
|
155
|
-
</View>
|
|
156
|
-
);
|
|
157
|
-
```
|