react-native-radar 3.20.4 → 3.21.0-beta.1

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.
Files changed (133) hide show
  1. package/Radar.podspec +22 -0
  2. package/android/build.gradle +77 -35
  3. package/android/gradle.properties +5 -1
  4. package/android/src/main/AndroidManifest.xml +1 -3
  5. package/android/src/main/java/{io/radar/react/RNRadarModule.java → com/radar/RadarModuleImpl.java} +131 -258
  6. package/android/src/main/java/com/radar/RadarPackage.kt +35 -0
  7. package/android/src/main/java/{io/radar/react/RNRadarUtils.java → com/radar/RadarUtils.java} +3 -2
  8. package/android/src/newarch/java/com/radar/RadarModule.kt +381 -0
  9. package/android/src/oldarch/java/com/radar/RadarModule.java +416 -0
  10. package/android/src/{main/java/io/radar/react/RNRadarReceiver.java → oldarch/java/com/radar/RadarOldArchReceiver.java} +8 -8
  11. package/android/src/{main/java/io/radar/react/RNRadarVerifiedReceiver.java → oldarch/java/com/radar/RadarOldArchVerifiedReceiver.java} +4 -4
  12. package/app.plugin.js +1 -1
  13. package/ios/RNRadar.h +11 -2
  14. package/ios/{RNRadar.m → RNRadar.mm} +77 -39
  15. package/lib/commonjs/@types/RadarNativeInterface.js +2 -0
  16. package/lib/commonjs/@types/RadarNativeInterface.js.map +1 -0
  17. package/lib/commonjs/@types/types.js +2 -0
  18. package/lib/commonjs/@types/types.js.map +1 -0
  19. package/lib/commonjs/NativeRadar.js +2 -0
  20. package/lib/commonjs/NativeRadar.js.map +1 -0
  21. package/lib/commonjs/helpers.js +2 -0
  22. package/lib/commonjs/helpers.js.map +1 -0
  23. package/lib/commonjs/index.js +2 -0
  24. package/lib/commonjs/index.js.map +1 -0
  25. package/lib/commonjs/index.native.js +2 -0
  26. package/lib/commonjs/index.native.js.map +1 -0
  27. package/lib/commonjs/index.web.js +2 -0
  28. package/lib/commonjs/index.web.js.map +1 -0
  29. package/lib/commonjs/package.json +1 -0
  30. package/lib/commonjs/plugin/types.js +2 -0
  31. package/lib/commonjs/plugin/types.js.map +1 -0
  32. package/lib/commonjs/plugin/withRadar.js +2 -0
  33. package/lib/commonjs/plugin/withRadar.js.map +1 -0
  34. package/lib/commonjs/plugin/withRadarAndroid.js +2 -0
  35. package/lib/commonjs/plugin/withRadarAndroid.js.map +1 -0
  36. package/lib/commonjs/plugin/withRadarIOS.js +2 -0
  37. package/lib/commonjs/plugin/withRadarIOS.js.map +1 -0
  38. package/lib/commonjs/ui/autocomplete.js +2 -0
  39. package/lib/commonjs/ui/autocomplete.js.map +1 -0
  40. package/lib/commonjs/ui/images.js +2 -0
  41. package/lib/commonjs/ui/images.js.map +1 -0
  42. package/lib/commonjs/ui/map.js +2 -0
  43. package/lib/commonjs/ui/map.js.map +1 -0
  44. package/lib/commonjs/ui/styles.js +2 -0
  45. package/lib/commonjs/ui/styles.js.map +1 -0
  46. package/lib/commonjs/version.js +2 -0
  47. package/lib/commonjs/version.js.map +1 -0
  48. package/{dist → lib/typescript/src}/@types/RadarNativeInterface.d.ts +18 -7
  49. package/lib/typescript/src/@types/RadarNativeInterface.d.ts.map +1 -0
  50. package/{dist → lib/typescript/src}/@types/types.d.ts +5 -3
  51. package/lib/typescript/src/@types/types.d.ts.map +1 -0
  52. package/lib/typescript/src/NativeRadar.d.ts +87 -0
  53. package/lib/typescript/src/NativeRadar.d.ts.map +1 -0
  54. package/{dist → lib/typescript/src}/index.d.ts +1 -0
  55. package/lib/typescript/src/index.d.ts.map +1 -0
  56. package/lib/typescript/src/index.native.d.ts +7 -0
  57. package/lib/typescript/src/index.native.d.ts.map +1 -0
  58. package/lib/typescript/src/plugin/types.d.ts +13 -0
  59. package/lib/typescript/src/plugin/types.d.ts.map +1 -0
  60. package/{plugin/build → lib/typescript/src/plugin}/withRadar.d.ts +2 -1
  61. package/lib/typescript/src/plugin/withRadar.d.ts.map +1 -0
  62. package/{plugin/build → lib/typescript/src/plugin}/withRadarAndroid.d.ts +1 -0
  63. package/lib/typescript/src/plugin/withRadarAndroid.d.ts.map +1 -0
  64. package/{plugin/build → lib/typescript/src/plugin}/withRadarIOS.d.ts +1 -0
  65. package/lib/typescript/src/plugin/withRadarIOS.d.ts.map +1 -0
  66. package/lib/typescript/src/version.d.ts +2 -0
  67. package/lib/typescript/src/version.d.ts.map +1 -0
  68. package/package.json +85 -34
  69. package/react-native.config.js +10 -0
  70. package/src/@types/RadarNativeInterface.ts +127 -0
  71. package/src/@types/types.ts +808 -0
  72. package/src/NativeRadar.ts +95 -0
  73. package/src/helpers.js +11 -0
  74. package/src/index.native.ts +419 -0
  75. package/src/index.tsx +22 -0
  76. package/src/index.web.js +528 -0
  77. package/{plugin/build/types.d.ts → src/plugin/types.ts} +1 -1
  78. package/src/plugin/withRadar.ts +39 -0
  79. package/src/plugin/withRadarAndroid.ts +147 -0
  80. package/src/plugin/withRadarIOS.ts +80 -0
  81. package/src/ui/autocomplete.jsx +324 -0
  82. package/src/ui/back.png +0 -0
  83. package/src/ui/close.png +0 -0
  84. package/src/ui/images.js +5 -0
  85. package/src/ui/map-logo.png +0 -0
  86. package/src/ui/map.jsx +122 -0
  87. package/src/ui/marker.png +0 -0
  88. package/src/ui/radar-logo.png +0 -0
  89. package/src/ui/search.png +0 -0
  90. package/src/ui/styles.js +125 -0
  91. package/src/version.ts +3 -0
  92. package/android/build.gradle.template +0 -49
  93. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  94. package/android/gradle/wrapper/gradle-wrapper.properties +0 -6
  95. package/android/gradlew +0 -160
  96. package/android/gradlew.bat +0 -90
  97. package/android/proguard-rules.pro +0 -4
  98. package/android/src/main/java/io/radar/react/RNRadarPackage.java +0 -29
  99. package/dist/@types/RadarNativeInterface.js +0 -2
  100. package/dist/@types/types.js +0 -150
  101. package/dist/helpers.d.ts +0 -2
  102. package/dist/helpers.js +0 -11
  103. package/dist/index.js +0 -29
  104. package/dist/index.native.d.ts +0 -3
  105. package/dist/index.native.js +0 -150
  106. package/dist/index.web.d.ts +0 -113
  107. package/dist/index.web.js +0 -516
  108. package/dist/ui/autocomplete.d.ts +0 -5
  109. package/dist/ui/autocomplete.js +0 -206
  110. package/dist/ui/images.d.ts +0 -5
  111. package/dist/ui/images.js +0 -8
  112. package/dist/ui/map.d.ts +0 -6
  113. package/dist/ui/map.js +0 -122
  114. package/dist/ui/styles.d.ts +0 -172
  115. package/dist/ui/styles.js +0 -125
  116. package/ios/Cartfile.private +0 -1
  117. package/ios/Cartfile.resolved +0 -1
  118. package/ios/Cartfile.resolved.template +0 -1
  119. package/ios/RNRadar.xcodeproj/project.pbxproj +0 -521
  120. package/ios/RNRadar.xcodeproj/xcshareddata/xcschemes/RNRadar.xcscheme +0 -76
  121. package/plugin/build/index.d.ts +0 -3
  122. package/plugin/build/index.js +0 -6
  123. package/plugin/build/types.js +0 -2
  124. package/plugin/build/withRadar.js +0 -26
  125. package/plugin/build/withRadarAndroid.js +0 -98
  126. package/plugin/build/withRadarIOS.js +0 -76
  127. package/react-native-radar.podspec +0 -19
  128. /package/{dist → lib/commonjs}/ui/back.png +0 -0
  129. /package/{dist → lib/commonjs}/ui/close.png +0 -0
  130. /package/{dist → lib/commonjs}/ui/map-logo.png +0 -0
  131. /package/{dist → lib/commonjs}/ui/marker.png +0 -0
  132. /package/{dist → lib/commonjs}/ui/radar-logo.png +0 -0
  133. /package/{dist → lib/commonjs}/ui/search.png +0 -0
@@ -0,0 +1,80 @@
1
+ import { ConfigPlugin, withInfoPlist, withDangerousMod } from "expo/config-plugins";
2
+ import type { RadarPluginProps } from "./types";
3
+ import fs from 'fs/promises';
4
+ import path from 'path';
5
+
6
+ export const withRadarIOS: ConfigPlugin<RadarPluginProps> = (config, args) => {
7
+ config = withInfoPlist(config, (config) => {
8
+ config.modResults.NSLocationWhenInUseUsageDescription =
9
+ args.iosNSLocationWhenInUseUsageDescription ??
10
+ "This app uses the location service to provide location-based services.";
11
+ if (args.iosNSLocationAlwaysAndWhenInUseUsageDescription) {
12
+ config.modResults.NSLocationAlwaysAndWhenInUseUsageDescription =
13
+ args.iosNSLocationAlwaysAndWhenInUseUsageDescription;
14
+ }
15
+ if (args.iosBackgroundMode) {
16
+ config.modResults.UIBackgroundModes = ["location", "fetch"];
17
+ }
18
+ if (args.iosFraud) {
19
+ config.modResults.NSAppTransportSecurity = {
20
+ NSAllowsArbitraryLoads: false,
21
+ NSPinnedDomains: {
22
+ "api-verified.radar.io": {
23
+ NSIncludesSubdomains: true,
24
+ NSPinnedLeafIdentities: [
25
+ {
26
+ "SPKI-SHA256-BASE64":
27
+ "15ktYXSSU2llpy7YyCgeqUKDBkjcimK/weUcec960sI=",
28
+ },
29
+ {
30
+ "SPKI-SHA256-BASE64":
31
+ "15ktYXSSU2llpy7YyCgeqUKDBkjcimK/weUcec960sI=",
32
+ },
33
+ ],
34
+ },
35
+ },
36
+ };
37
+ }
38
+ if (args.addRadarSDKMotion) {
39
+ config.modResults.NSMotionUsageDescription =
40
+ args.iosNSMotionUsageDescription ??
41
+ "This app uses the motion service to provide motion-based services.";
42
+ }
43
+
44
+ return config;
45
+ });
46
+
47
+ if (args.addRadarSDKMotion) {
48
+ config = withDangerousMod(config, [
49
+ 'ios',
50
+ async config => {
51
+ const filePath = path.join(config.modRequest.platformProjectRoot, 'Podfile');
52
+ const contents = await fs.readFile(filePath, 'utf-8');
53
+
54
+ // Check if the pod declaration already exists
55
+ if (contents.indexOf("pod 'RadarSDKMotion', '3.20.1'") === -1) {
56
+ // Find the target block
57
+ const targetRegex = /target '(\w+)' do/g;
58
+ const match = targetRegex.exec(contents);
59
+ if (match) {
60
+ const targetStartIndex = match.index;
61
+ const targetEndIndex = contents.indexOf('end', targetStartIndex) + 3;
62
+
63
+ // Insert the pod declaration within the target block
64
+ const targetBlock = contents.substring(targetStartIndex, targetEndIndex);
65
+ // Just for this version of the SDK, we will be using 3.21.1 of the SDKMotion pod. There is no difference between the source code of 3.21.2 and 3.21.1 for RadarSDKMotion.
66
+ const updatedTargetBlock = targetBlock.replace(/(target '(\w+)' do)/, `$1\n pod 'RadarSDKMotion', '3.20.1'`);
67
+ const newContents = contents.replace(targetBlock, updatedTargetBlock);
68
+
69
+ // Write the updated contents back to the Podfile
70
+ await fs.writeFile(filePath, newContents);
71
+ }
72
+ }
73
+
74
+ return config;
75
+ },
76
+ ]);
77
+ }
78
+
79
+ return config;
80
+ };
@@ -0,0 +1,324 @@
1
+ // Autocomplete.js
2
+ import React, { useState, useCallback, useRef, useEffect } from 'react';
3
+ import {
4
+ View,
5
+ TextInput,
6
+ FlatList,
7
+ TouchableOpacity,
8
+ Text,
9
+ StyleSheet,
10
+ Image,
11
+ Modal,
12
+ KeyboardAvoidingView,
13
+ Animated,
14
+ Dimensions,
15
+ Easing,
16
+ Keyboard,
17
+ SafeAreaView,
18
+ Pressable,
19
+ Platform,
20
+ } from 'react-native';
21
+ import Radar from '../index.native';
22
+ import {
23
+ BACK_ICON,
24
+ SEARCH_ICON,
25
+ RADAR_LOGO,
26
+ MARKER_ICON,
27
+ CLOSE_ICON,
28
+ } from "./images";
29
+ import { default as defaultStyles } from './styles';
30
+
31
+ const defaultAutocompleteOptions = {
32
+ debounceMS: 200, // Debounce time in milliseconds
33
+ minCharacters: 3, // Minimum number of characters to trigger autocomplete
34
+ limit: 8, // Maximum number of results to return
35
+ placeholder: "Search address", // Placeholder text for the input field
36
+ showMarkers: true,
37
+ disabled: false,
38
+ };
39
+
40
+ const autocompleteUI = ({ options = {} }) => {
41
+ const [query, setQuery] = useState("");
42
+ const [results, setResults] = useState([]);
43
+ const [isOpen, setIsOpen] = useState(false);
44
+ const animationValue = useRef(new Animated.Value(0)).current; // animation value
45
+ const timerRef = useRef(null);
46
+ const textInputRef = useRef(null);
47
+
48
+
49
+ const config = { ...defaultAutocompleteOptions, ...options };
50
+ const style = config.style || {};
51
+
52
+ const fetchResults = useCallback(
53
+ async (searchQuery) => {
54
+ if (searchQuery.length < config.minCharacters) return;
55
+
56
+ const { limit, layers, countryCode } = config;
57
+ const params = { query: searchQuery, limit, layers, countryCode };
58
+
59
+ if (config.near && config.near.latitude && config.near.longitude) {
60
+ params.near = config.near;
61
+ }
62
+
63
+ try {
64
+ const result = await Radar.autocomplete(params);
65
+
66
+ if (config.onResults && typeof config.onResults === "function") {
67
+ config.onResults(result.addresses);
68
+ }
69
+
70
+ setResults(result.addresses);
71
+ setIsOpen(true);
72
+ } catch (error) {
73
+ if (config.onError && typeof config.onError === "function") {
74
+ config.onError(error);
75
+ }
76
+ }
77
+ },
78
+ [config]
79
+ );
80
+
81
+ const handleInput = useCallback(
82
+ (text) => {
83
+ setQuery(text);
84
+
85
+ // Clear the existing timer
86
+ if (timerRef.current) {
87
+ clearTimeout(timerRef.current);
88
+ }
89
+
90
+ if (text.length < config.minCharacters) {
91
+ return;
92
+ }
93
+
94
+ // Set the new timer
95
+ timerRef.current = setTimeout(() => {
96
+ fetchResults(text);
97
+ }, config.debounceMS);
98
+ },
99
+ [config, fetchResults]
100
+ );
101
+
102
+ const handleSelect = (item) => {
103
+ setQuery(item.formattedAddress);
104
+ setIsOpen(false);
105
+
106
+ if (typeof config.onSelection === "function") {
107
+ config.onSelection(item);
108
+ }
109
+ };
110
+
111
+ const renderFooter = () => {
112
+ if (results.length === 0) return null;
113
+
114
+ return (
115
+ <View style={styles.footerContainer}>
116
+ <View style={{ flexDirection: "row", alignItems: "center" }}>
117
+ <Text style={styles.footerText}>Powered by</Text>
118
+ <Image
119
+ source={RADAR_LOGO}
120
+ resizeMode="contain"
121
+ style={defaultStyles.logo}
122
+ />
123
+ </View>
124
+ </View>
125
+ );
126
+ };
127
+
128
+ const renderItem = ({ item }) => (
129
+ <Pressable
130
+ style={({ pressed }) => [
131
+ {
132
+ ...styles.resultItem,
133
+ backgroundColor: pressed
134
+ ? styles.resultItem.pressedBackgroundColor
135
+ : styles.resultItem.backgroundColor,
136
+ },
137
+ ]}
138
+ onPress={() => handleSelect(item)}
139
+ >
140
+ <View style={styles.addressContainer}>
141
+ <View style={styles.pinIconContainer}>
142
+ {config.showMarkers ? (
143
+ <Image source={MARKER_ICON} style={styles.pinIcon} />
144
+ ) : null}
145
+ </View>
146
+ <View style={styles.addressTextContainer}>
147
+ <Text numberOfLines={1} style={styles.addressText}>
148
+ {item.addressLabel || item?.placeLabel}
149
+ </Text>
150
+ {item?.formattedAddress.length > 0 && (
151
+ <Text numberOfLines={1} style={styles.addressSubtext}>
152
+ {item?.formattedAddress?.replace(
153
+ `${item?.addressLabel || item?.placeLabel}, `,
154
+ ""
155
+ )}
156
+ </Text>
157
+ )}
158
+ </View>
159
+ </View>
160
+ </Pressable>
161
+ );
162
+
163
+ const styles = {
164
+ ...defaultStyles,
165
+ container: StyleSheet.compose(defaultStyles.container, style.container),
166
+ input: StyleSheet.compose(defaultStyles.input, style.input),
167
+ inputContainer: StyleSheet.compose(
168
+ defaultStyles.inputContainer,
169
+ style.inputContainer
170
+ ),
171
+ modalInputContainer: StyleSheet.compose(
172
+ defaultStyles.modalInputContainer,
173
+ style.modalInputContainer
174
+ ),
175
+ resultList: StyleSheet.compose(defaultStyles.resultList, style.resultList),
176
+ resultItem: StyleSheet.compose({...defaultStyles.resultItem, pressedBackgroundColor: '#F6FAFC'}, style.resultItem),
177
+ addressContainer: StyleSheet.compose(
178
+ defaultStyles.addressContainer,
179
+ style.addressContainer
180
+ ),
181
+ pinIconContainer: StyleSheet.compose(
182
+ defaultStyles.pinIconContainer,
183
+ style.pinIconContainer
184
+ ),
185
+ pinIcon: StyleSheet.compose(defaultStyles.pinIcon, style.pinIcon),
186
+ addressTextContainer: StyleSheet.compose(
187
+ defaultStyles.addressTextContainer,
188
+ style.addressTextContainer
189
+ ),
190
+ addressText: StyleSheet.compose(
191
+ defaultStyles.addressText,
192
+ style.addressText
193
+ ),
194
+ addressSubtext: StyleSheet.compose(
195
+ defaultStyles.addressSubtext,
196
+ style.addressSubtext
197
+ ),
198
+ footerContainer: StyleSheet.compose(
199
+ defaultStyles.footerContainer,
200
+ style.footerContainer
201
+ ),
202
+ footerText: StyleSheet.compose(defaultStyles.footerText, style.footerText),
203
+ };
204
+
205
+ useEffect(() => {
206
+ Animated.timing(animationValue, {
207
+ toValue: isOpen ? 1 : 0,
208
+ duration: 300,
209
+ easing: Easing.inOut(Easing.ease),
210
+ useNativeDriver: false,
211
+ }).start();
212
+ }, [isOpen]);
213
+
214
+ const screenHeight = Dimensions.get("window").height;
215
+
216
+ const inputHeight = animationValue.interpolate({
217
+ inputRange: [0, 1],
218
+ outputRange: [40, screenHeight],
219
+ });
220
+
221
+ const modalOpacity = animationValue.interpolate({
222
+ inputRange: [0, 0.5, 1],
223
+ outputRange: [0, 0, 1],
224
+ });
225
+
226
+ return (
227
+ <View style={styles.container}>
228
+ <Animated.View style={{ height: inputHeight }}>
229
+ <TouchableOpacity
230
+ style={styles.inputContainer}
231
+ onPress={() => {
232
+ if (config.disabled) return;
233
+
234
+ setIsOpen(true);
235
+ // Set the focus on the other textinput after it opens
236
+ setTimeout(() => {
237
+ textInputRef.current.focus();
238
+ }, 100);
239
+ }}
240
+ >
241
+ <Image source={SEARCH_ICON} style={styles.inputIcon} />
242
+ <TextInput
243
+ style={styles.input}
244
+ onFocus={() => {
245
+ setIsOpen(true);
246
+ setTimeout(() => {
247
+ textInputRef.current.focus();
248
+ }, 100);
249
+ }}
250
+ value={query}
251
+ returnKeyType="done"
252
+ placeholder={config.placeholder}
253
+ placeholderTextColor="#acbdc8"
254
+ />
255
+ </TouchableOpacity>
256
+ </Animated.View>
257
+ <Modal
258
+ animationType="slide"
259
+ transparent={false}
260
+ visible={isOpen}
261
+ onRequestClose={() => setIsOpen(false)}
262
+ >
263
+ <Animated.View style={{ flex: 1, opacity: modalOpacity }}>
264
+ <SafeAreaView>
265
+ <KeyboardAvoidingView
266
+ behavior={Platform.OS === "ios" ? "padding" : "height"}
267
+ keyboardVerticalOffset={50}
268
+ style={styles.container}
269
+ >
270
+ <View style={styles.modalInputContainer}>
271
+ <TouchableOpacity
272
+ onPress={() => {
273
+ setIsOpen(false);
274
+ }}
275
+ >
276
+ <Image source={BACK_ICON} style={styles.inputIcon} />
277
+ </TouchableOpacity>
278
+ <TextInput
279
+ ref={textInputRef}
280
+ style={styles.input}
281
+ onChangeText={handleInput}
282
+ value={query}
283
+ placeholder={config.placeholder}
284
+ returnKeyType="done"
285
+ onSubmitEditing={() => {
286
+ setIsOpen(false);
287
+ }}
288
+ placeholderTextColor="#acbdc8"
289
+ />
290
+ <TouchableOpacity
291
+ onPress={() => {
292
+ setQuery("");
293
+ }}
294
+ >
295
+ <Image source={CLOSE_ICON} style={styles.closeIcon} />
296
+ </TouchableOpacity>
297
+ </View>
298
+ {results.length > 0 && (
299
+ <View style={styles.resultListWrapper}>
300
+ <FlatList
301
+ style={styles.resultList}
302
+ data={results}
303
+ onScroll={() => {
304
+ textInputRef.current.blur();
305
+ Keyboard.dismiss();
306
+ }}
307
+ keyboardShouldPersistTaps="handled"
308
+ renderItem={renderItem}
309
+ keyExtractor={(item) =>
310
+ item.formattedAddress + item.postalCode
311
+ }
312
+ />
313
+ {renderFooter()}
314
+ </View>
315
+ )}
316
+ </KeyboardAvoidingView>
317
+ </SafeAreaView>
318
+ </Animated.View>
319
+ </Modal>
320
+ </View>
321
+ );
322
+ };
323
+
324
+ export default autocompleteUI;
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ export const BACK_ICON = require('./back.png');
2
+ export const SEARCH_ICON = require('./search.png');
3
+ export const RADAR_LOGO = require('./radar-logo.png');
4
+ export const MARKER_ICON = require('./marker.png');
5
+ export const CLOSE_ICON = require('./close.png');
Binary file
package/src/ui/map.jsx ADDED
@@ -0,0 +1,122 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { View, Image } from 'react-native';
3
+ import Radar from '../index.native';
4
+ import { getHost, getPublishableKey } from '../helpers';
5
+ import styles from './styles';
6
+
7
+ let MapLibreGL;
8
+ try {
9
+ MapLibreGL = require('@maplibre/maplibre-react-native');
10
+ } catch (e) {
11
+ MapLibreGL = null;
12
+ }
13
+
14
+ const DEFAULT_STYLE = 'radar-default-v1';
15
+
16
+ const createStyleURL = async (style = DEFAULT_STYLE) => {
17
+ const host = await getHost();
18
+ const publishableKey = await getPublishableKey();
19
+ return `${host}/maps/styles/${style}?publishableKey=${publishableKey}`;
20
+ };
21
+
22
+ const RadarMap = ({ mapOptions, children }) => {
23
+ const [styleURL, setStyleURL] = useState(null);
24
+ const [userLocation, setUserLocation] = useState(null);
25
+
26
+ useEffect(() => {
27
+ createStyleURL(mapOptions?.mapStyle || DEFAULT_STYLE).then((result) => {
28
+ setStyleURL(result);
29
+ });
30
+ }, [mapOptions]);
31
+
32
+ useEffect(() => {
33
+ Radar.getLocation().then((result) => {
34
+ if (result?.location?.latitude && result?.location?.longitude) {
35
+ setUserLocation({
36
+ latitude: result.location.latitude,
37
+ longitude: result.location.longitude,
38
+ });
39
+ }
40
+ }).catch((err) => {
41
+ // eslint-disable-next-line no-console
42
+ console.warn(`Radar SDK: Failed to get location: ${err}`);
43
+ });
44
+ }, [mapOptions]);
45
+
46
+ if (!styleURL) {
47
+ return null;
48
+ }
49
+
50
+ if (!MapLibreGL) {
51
+ return null;
52
+ }
53
+
54
+ const geoJSONUserLocation = {
55
+ type: 'FeatureCollection',
56
+ features: userLocation?.longitude !== undefined ? [
57
+ {
58
+ type: 'Feature',
59
+ geometry: {
60
+ type: 'Point',
61
+ coordinates: [userLocation.longitude, userLocation.latitude],
62
+ },
63
+ },
64
+ ] : [],
65
+ };
66
+
67
+ const userLocationMapIndicator = (
68
+ <MapLibreGL.ShapeSource
69
+ id="user-location"
70
+ shape={geoJSONUserLocation}
71
+ >
72
+ <MapLibreGL.CircleLayer
73
+ id="user-location-inner"
74
+ style={{
75
+ circleRadius: 15,
76
+ circleColor: '#000257',
77
+ circleOpacity: 0.2,
78
+ circlePitchAlignment: 'map',
79
+ }}
80
+ />
81
+ <MapLibreGL.CircleLayer
82
+ id="user-location-middle"
83
+ style={{
84
+ circleRadius: 9,
85
+ circleColor: '#fff',
86
+ circlePitchAlignment: 'map',
87
+ }}
88
+ />
89
+ <MapLibreGL.CircleLayer
90
+ id="user-location-outer"
91
+ style={{
92
+ circleRadius: 6,
93
+ circleColor: '#000257',
94
+ circlePitchAlignment: 'map',
95
+ }}
96
+ />
97
+ </MapLibreGL.ShapeSource>
98
+ );
99
+
100
+ return (
101
+ <View style={styles.mapContainer}>
102
+ <MapLibreGL.MapView
103
+ style={styles.map}
104
+ pitchEnabled={false}
105
+ compassEnabled={false}
106
+ logoEnabled={false}
107
+ attributionEnabled
108
+ onRegionDidChange={mapOptions?.onRegionDidChange ? mapOptions.onRegionDidChange : null}
109
+ styleURL={styleURL}
110
+ >
111
+ {userLocationMapIndicator}
112
+ {children}
113
+ </MapLibreGL.MapView>
114
+ <Image
115
+ source={require('./map-logo.png')}
116
+ style={styles.mapLogo}
117
+ />
118
+ </View>
119
+ );
120
+ };
121
+
122
+ export default RadarMap;
Binary file
Binary file
Binary file
@@ -0,0 +1,125 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ const styles = StyleSheet.create({
4
+ container: {
5
+ width: '100%',
6
+ height: '100%',
7
+ alignItems: 'center',
8
+ paddingTop: 8,
9
+ },
10
+ inputContainer: {
11
+ flexDirection: 'row',
12
+ alignItems: 'center',
13
+ marginHorizontal: 16,
14
+ backgroundColor: 'white',
15
+ borderRadius: 5,
16
+ borderColor: '#DBE5EB',
17
+ borderWidth: 1,
18
+ width: '95%', // only difference between this and the modalInputContainer
19
+ },
20
+ modalInputContainer: {
21
+ flexDirection: 'row',
22
+ alignItems: 'center',
23
+ marginHorizontal: 16,
24
+ backgroundColor: 'white',
25
+ borderRadius: 5,
26
+ borderColor: '#DBE5EB',
27
+ borderWidth: 1,
28
+ },
29
+ inputIcon: {
30
+ marginLeft: 10,
31
+ height: 18,
32
+ width: 18,
33
+ backgroundColor: 'white',
34
+ },
35
+ closeIcon: {
36
+ marginRight: 10,
37
+ height: 18,
38
+ width: 18,
39
+ backgroundColor: 'white',
40
+ },
41
+ input: {
42
+ flex: 1,
43
+ backgroundColor: 'white',
44
+ height: 40,
45
+ fontSize: 14,
46
+ paddingHorizontal: 8,
47
+ borderRadius: 5,
48
+ },
49
+ resultListWrapper: {
50
+ width: '100%',
51
+ marginBottom: 30,
52
+ backgroundColor: 'white',
53
+ borderRadius: 5,
54
+ paddingVertical: 8,
55
+ },
56
+ resultList: {
57
+ width: '100%',
58
+ },
59
+ resultItem: {
60
+ paddingRight: 16,
61
+ paddingVertical: 8,
62
+ paddingHorizontal: 16,
63
+ fontSize: 12,
64
+ backgroundColor: 'white',
65
+ },
66
+ addressContainer: {
67
+ flexDirection: 'row',
68
+ alignItems: 'center',
69
+ },
70
+ pinIconContainer: {
71
+ width: 28,
72
+ marginRight: 8,
73
+ },
74
+ pinIcon: {
75
+ height: 26,
76
+ width: 26,
77
+ },
78
+ addressTextContainer: {
79
+ flex: 1,
80
+ },
81
+ addressText: {
82
+ fontSize: 14,
83
+ lineHeight: 24,
84
+ color: '#000',
85
+ fontWeight: '600',
86
+ },
87
+ addressSubtext: {
88
+ fontSize: 14,
89
+ color: '#5A6872',
90
+ },
91
+ footerContainer: {
92
+ flexDirection: 'row',
93
+ alignItems: 'center',
94
+ paddingVertical: 10,
95
+ marginRight: 16,
96
+ alignSelf: 'flex-end',
97
+ },
98
+ footerText: {
99
+ marginTop: 2,
100
+ marginRight: 4,
101
+ fontSize: 10,
102
+ color: '#5A6872',
103
+ },
104
+ logo: {
105
+ width: 50,
106
+ height: 15,
107
+ resizeMode: 'contain',
108
+ },
109
+ mapContainer: {
110
+ flex: 1,
111
+ },
112
+ map: {
113
+ flex: 1,
114
+ },
115
+ mapLogo: {
116
+ position: 'absolute',
117
+ bottom: -10,
118
+ left: 5,
119
+ width: 50,
120
+ height: 50,
121
+ resizeMode: 'contain',
122
+ },
123
+ });
124
+
125
+ export default styles;
package/src/version.ts ADDED
@@ -0,0 +1,3 @@
1
+ // This file contains the version of the react-native-radar package
2
+ // It should be updated to match the version in package.json
3
+ export const VERSION = '3.21.0-beta.1';