react-native-radar 3.23.6-beta.1 → 3.23.7-beta.2

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/Radar.podspec CHANGED
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
16
16
  s.source_files = "ios/**/*.{h,m,mm,cpp}"
17
17
  s.private_header_files = "ios/**/*.h"
18
18
 
19
- s.dependency "RadarSDK", "3.23.3"
19
+ s.dependency "RadarSDK", "3.24.1"
20
20
 
21
21
  install_modules_dependencies(s)
22
22
  end
@@ -1,4 +1,4 @@
1
- def radar_sdk_version = '3.23.2'
1
+ def radar_sdk_version = '3.24.0'
2
2
 
3
3
  buildscript {
4
4
  ext.getExtOrDefault = {name ->
@@ -1298,4 +1298,15 @@ public class RadarModuleImpl {
1298
1298
  }
1299
1299
  Radar.showInAppMessage(inAppMessage);
1300
1300
  }
1301
+
1302
+ public void setPushNotificationToken(String token) {
1303
+ Radar.setPushNotificationToken(token);
1304
+ }
1305
+
1306
+ public void isInitialized(final Promise promise) {
1307
+ if (promise == null) {
1308
+ return;
1309
+ }
1310
+ promise.resolve(Radar.isInitialized());
1311
+ }
1301
1312
  }
@@ -140,10 +140,11 @@ class RadarModule(reactContext: ReactApplicationContext) :
140
140
  return NAME
141
141
  }
142
142
 
143
- override fun initialize(publishableKey: String, fraud: Boolean): Unit {
143
+ override fun initialize(publishableKey: String, fraud: Boolean, options: ReadableMap?): Unit {
144
+ // options parameter is no-op on Android for now
144
145
  val editor = reactApplicationContext.getSharedPreferences("RadarSDK", Context.MODE_PRIVATE).edit()
145
146
  editor.putString("x_platform_sdk_type", "ReactNative")
146
- editor.putString("x_platform_sdk_version", "3.23.6-beta.1")
147
+ editor.putString("x_platform_sdk_version", "3.23.7-beta.2")
147
148
  editor.apply()
148
149
 
149
150
  Radar.initialize(reactApplicationContext, publishableKey, radarReceiver, Radar.RadarLocationServicesProvider.GOOGLE, fraud, null, radarInAppMessageReceiver, currentActivity)
@@ -432,6 +433,14 @@ class RadarModule(reactContext: ReactApplicationContext) :
432
433
  radarModuleImpl.showInAppMessage(inAppMessage)
433
434
  }
434
435
 
436
+ override fun setPushNotificationToken(token: String): Unit {
437
+ radarModuleImpl.setPushNotificationToken(token)
438
+ }
439
+
440
+ override fun isInitialized(promise: Promise): Unit {
441
+ radarModuleImpl.isInitialized(promise)
442
+ }
443
+
435
444
 
436
445
  companion object {
437
446
  const val NAME = "RNRadar"
@@ -98,11 +98,12 @@ public class RadarModule extends ReactContextBaseJavaModule implements Permissio
98
98
  }
99
99
 
100
100
  @ReactMethod
101
- public void initialize(String publishableKey, boolean fraud) {
101
+ public void initialize(String publishableKey, boolean fraud, ReadableMap options) {
102
+ // options parameter is no-op on Android for now
102
103
  this.fraud = fraud;
103
104
  SharedPreferences.Editor editor = getReactApplicationContext().getSharedPreferences("RadarSDK", Context.MODE_PRIVATE).edit();
104
105
  editor.putString("x_platform_sdk_type", "ReactNative");
105
- editor.putString("x_platform_sdk_version", "3.23.6-beta.1");
106
+ editor.putString("x_platform_sdk_version", "3.23.7-beta.2");
106
107
  editor.apply();
107
108
  Radar.initialize(getReactApplicationContext(), publishableKey, receiver, Radar.RadarLocationServicesProvider.GOOGLE, fraud, null, inAppMessageReceiver, getCurrentActivity());
108
109
  if (fraud) {
@@ -444,4 +445,14 @@ public class RadarModule extends ReactContextBaseJavaModule implements Permissio
444
445
  radarModuleImpl.showInAppMessage(inAppMessageMap);
445
446
  }
446
447
 
448
+ @ReactMethod
449
+ public void setPushNotificationToken(String token) {
450
+ radarModuleImpl.setPushNotificationToken(token);
451
+ }
452
+
453
+ @ReactMethod
454
+ public void isInitialized(final Promise promise) {
455
+ radarModuleImpl.isInitialized(promise);
456
+ }
457
+
447
458
  }
@@ -1,6 +1,6 @@
1
1
  import type { RadarPermissionsStatus, RadarTrackCallback, RadarTrackOnceOptions, RadarLocationUpdateCallback, RadarClientLocationUpdateCallback, RadarErrorCallback, RadarLogUpdateCallback, RadarEventUpdateCallback, RadarTokenUpdateCallback, RadarLogLevel, RadarMetadata, RadarTrackingOptionsDesiredAccuracy, RadarLocationCallback, RadarTrackVerifiedCallback, RadarTrackVerifiedOptions, RadarTrackingOptions, RadarVerifiedTrackingOptions, RadarMockTrackingOptions, RadarTrackingOptionsForegroundService, RadarNotificationOptions, RadarTripOptions, RadarStartTripOptions, RadarTripCallback, RadarUpdateTripOptions, RadarContextCallback, RadarSearchPlacesOptions, RadarSearchPlacesCallback, RadarSearchGeofencesCallback, RadarSearchGeofencesOptions, RadarAutocompleteOptions, RadarAddressCallback, RadarReverseGeocodeOptions, RadarGeocodeOptions, RadarValidateAddressCallback, RadarIPGeocodeCallback, RadarAddress, RadarLogConversionOptions, RadarGetDistanceOptions, RadarRouteCallback, RadarGetMatrixOptions, RadarLogConversionCallback, RadarRouteMatrix, Location, RadarNewInAppMessageCallback, RadarInAppMessageDismissedCallback, RadarInAppMessageClickedCallback, RadarInAppMessage } from "./types";
2
2
  export interface RadarNativeInterface {
3
- initialize: (publishableKey: string, fraud?: boolean) => void;
3
+ initialize: (publishableKey: string, fraud?: boolean, options?: Object | null) => void;
4
4
  setLogLevel: (level: RadarLogLevel) => void;
5
5
  setUserId: (userId: string) => void;
6
6
  getUserId: () => Promise<string>;
@@ -57,6 +57,8 @@ export interface RadarNativeInterface {
57
57
  nativeSdkVersion: () => Promise<string>;
58
58
  rnSdkVersion: () => string;
59
59
  showInAppMessage: (inAppMessage: RadarInAppMessage) => void;
60
+ setPushNotificationToken: (token: string) => void;
61
+ isInitialized: () => Promise<boolean>;
60
62
  onLocationUpdated: (callback: RadarLocationUpdateCallback | null) => void;
61
63
  onClientLocationUpdated: (callback: RadarClientLocationUpdateCallback | null) => void;
62
64
  onError: (callback: RadarErrorCallback | null) => void;
@@ -541,3 +541,18 @@ export interface RadarTrackingOptionsForegroundService {
541
541
  iconColor?: string;
542
542
  }
543
543
  export type RadarTripStatus = "unknown" | "started" | "approaching" | "arrived" | "expired" | "completed" | "canceled";
544
+ export interface RadarMapOptions {
545
+ mapStyle?: string;
546
+ showUserLocation?: boolean;
547
+ onRegionDidChange?: (feature: RadarMapRegionChangeEvent) => void;
548
+ onDidFinishLoadingMap?: () => void;
549
+ onWillStartLoadingMap?: () => void;
550
+ onDidFailLoadingMap?: () => void;
551
+ }
552
+ export interface RadarMapRegionChangeEvent {
553
+ center: [number, number];
554
+ zoom: number;
555
+ bounds?: [number, number, number, number];
556
+ bearing?: number;
557
+ pitch?: number;
558
+ }
@@ -32,7 +32,7 @@ export type InAppMessageClickedEmitter = {
32
32
  inAppMessage: Object;
33
33
  };
34
34
  export interface Spec extends TurboModule {
35
- initialize(publishableKey: string, fraud: boolean): void;
35
+ initialize(publishableKey: string, fraud: boolean, options: Object | null): void;
36
36
  requestPermissions(background: boolean): Promise<string>;
37
37
  getPermissionsStatus(): Promise<string>;
38
38
  trackOnce(trackOnceOptions: Object | null): Promise<Object>;
@@ -90,6 +90,8 @@ export interface Spec extends TurboModule {
90
90
  getHost(): Promise<string>;
91
91
  getPublishableKey(): Promise<string>;
92
92
  showInAppMessage(inAppMessage: Object): void;
93
+ setPushNotificationToken(token: string): void;
94
+ isInitialized(): Promise<boolean>;
93
95
  readonly locationEmitter: EventEmitter<LocationEmitter>;
94
96
  readonly clientLocationEmitter: EventEmitter<ClientLocationEmitter>;
95
97
  readonly errorEmitter: EventEmitter<ErrorEmitter>;
package/dist/index.d.ts CHANGED
@@ -5,5 +5,8 @@ declare let RadarRNWeb: any;
5
5
  export { RadarRNWeb };
6
6
  declare let Autocomplete: any;
7
7
  export { Autocomplete };
8
+ declare let Map: any;
9
+ export { Map };
10
+ export type { RadarMapProps } from "./ui/map";
8
11
  export * from "./@types/types";
9
12
  export * from "./@types/RadarNativeInterface";
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.Autocomplete = exports.RadarRNWeb = void 0;
17
+ exports.Map = exports.Autocomplete = exports.RadarRNWeb = void 0;
18
18
  const react_native_1 = require("react-native");
19
19
  let nativeModule;
20
20
  nativeModule =
@@ -26,5 +26,7 @@ let RadarRNWeb = react_native_1.Platform.OS === "web" ? require("./index.web").d
26
26
  exports.RadarRNWeb = RadarRNWeb;
27
27
  let Autocomplete = react_native_1.Platform.OS !== "web" ? require("./ui/autocomplete").default : {};
28
28
  exports.Autocomplete = Autocomplete;
29
+ let Map = react_native_1.Platform.OS !== "web" ? require("./ui/map").default : {};
30
+ exports.Map = Map;
29
31
  __exportStar(require("./@types/types"), exports);
30
32
  __exportStar(require("./@types/RadarNativeInterface"), exports);
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.addListener = addListener;
16
16
  const react_native_1 = require("react-native");
17
+ const react_native_2 = require("react-native");
17
18
  const version_1 = require("./version");
18
19
  const NativeRadar_1 = __importDefault(require("./NativeRadar"));
19
20
  const NativeRadar = NativeRadar_1.default;
@@ -31,7 +32,7 @@ const NativeRadar = NativeRadar_1.default;
31
32
  // },
32
33
  // });
33
34
  const compatEventEmitter = NativeRadar.locationEmitter == null
34
- ? new react_native_1.NativeEventEmitter(react_native_1.NativeModules.RNRadar)
35
+ ? new react_native_2.NativeEventEmitter(react_native_2.NativeModules.RNRadar)
35
36
  : null;
36
37
  function addListener(event, handler) {
37
38
  if (compatEventEmitter != null) {
@@ -49,8 +50,8 @@ let newInAppMessageUpdateSubscription = null;
49
50
  let inAppMessageDismissedUpdateSubscription = null;
50
51
  let inAppMessageClickedUpdateSubscription = null;
51
52
  const Radar = {
52
- initialize: (publishableKey, fraud) => {
53
- NativeRadar.initialize(publishableKey, !!fraud);
53
+ initialize: (publishableKey, fraud, options) => {
54
+ NativeRadar.initialize(publishableKey, !!fraud, options || null);
54
55
  Radar.onNewInAppMessage((inAppMessage) => {
55
56
  Radar.showInAppMessage(inAppMessage);
56
57
  });
@@ -191,6 +192,13 @@ const Radar = {
191
192
  showInAppMessage: (inAppMessage) => {
192
193
  return NativeRadar.showInAppMessage(inAppMessage);
193
194
  },
195
+ setPushNotificationToken: (token) => {
196
+ if (react_native_1.Platform.OS === 'android') {
197
+ return NativeRadar.setPushNotificationToken(token);
198
+ }
199
+ // iOS handles push notifications differently via AppDelegate
200
+ // See: https://docs.radar.com/sdk/silent-push#silent-push
201
+ },
194
202
  requestPermissions: (background) => {
195
203
  return NativeRadar.requestPermissions(background);
196
204
  },
@@ -359,5 +367,8 @@ const Radar = {
359
367
  getPublishableKey: function () {
360
368
  return NativeRadar.getPublishableKey();
361
369
  },
370
+ isInitialized: function () {
371
+ return NativeRadar.isInitialized();
372
+ },
362
373
  };
363
374
  exports.default = Radar;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { RadarMapOptions } from '../@types/types';
3
+ export interface RadarMapProps {
4
+ /**
5
+ * Configuration options for the RadarMap component
6
+ */
7
+ mapOptions?: RadarMapOptions;
8
+ /**
9
+ * Child components to render within the map
10
+ */
11
+ children?: React.ReactNode;
12
+ }
13
+ /**
14
+ * TypeScript wrapper for the RadarMap component that provides type safety
15
+ * while delegating the implementation to the JavaScript version.
16
+ *
17
+ * @param props - The props for the RadarMap component
18
+ * @returns The RadarMap component with proper TypeScript typing
19
+ */
20
+ declare const RadarMap: React.FC<RadarMapProps>;
21
+ export default RadarMap;
package/dist/ui/map.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const RadarMapJS = require('./map.jsx').default;
8
+ /**
9
+ * TypeScript wrapper for the RadarMap component that provides type safety
10
+ * while delegating the implementation to the JavaScript version.
11
+ *
12
+ * @param props - The props for the RadarMap component
13
+ * @returns The RadarMap component with proper TypeScript typing
14
+ */
15
+ const RadarMap = (props) => {
16
+ return react_1.default.createElement(RadarMapJS, props);
17
+ };
18
+ exports.default = RadarMap;
@@ -0,0 +1,139 @@
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
+ /**
23
+ * RadarMap component for displaying maps with Radar integration
24
+ * @param {Object} props - Component props
25
+ * @param {Object} [props.mapOptions] - Map configuration options
26
+ * @param {string} [props.mapOptions.mapStyle] - Map style identifier (defaults to 'radar-default-v1')
27
+ * @param {boolean} [props.mapOptions.showUserLocation] - Whether to show the user's location on the map (default: true)
28
+ * @param {function} [props.mapOptions.onRegionDidChange] - Callback fired when the map region changes
29
+ * @param {Object} props.mapOptions.onRegionDidChange.feature - The region feature data
30
+ * @param {function} [props.mapOptions.onDidFinishLoadingMap] - Callback fired when the map finishes loading
31
+ * @param {function} [props.mapOptions.onWillStartLoadingMap] - Callback fired when the map starts loading
32
+ * @param {function} [props.mapOptions.onDidFailLoadingMap] - Callback fired when the map fails to load
33
+ * @param {React.ReactNode} [props.children] - Child components to render within the map
34
+ * @returns {React.Component|null} The RadarMap component or null if dependencies are missing
35
+ */
36
+
37
+ const RadarMap = ({ mapOptions, children }) => {
38
+ const [styleURL, setStyleURL] = useState(null);
39
+ const [userLocation, setUserLocation] = useState(null);
40
+
41
+ useEffect(() => {
42
+ createStyleURL(mapOptions?.mapStyle || DEFAULT_STYLE).then((result) => {
43
+ setStyleURL(result);
44
+ });
45
+ }, [mapOptions]);
46
+
47
+ useEffect(() => {
48
+ Radar.getLocation().then((result) => {
49
+ if (result?.location?.latitude && result?.location?.longitude) {
50
+ setUserLocation({
51
+ latitude: result.location.latitude,
52
+ longitude: result.location.longitude,
53
+ });
54
+ }
55
+ }).catch((err) => {
56
+ // eslint-disable-next-line no-console
57
+ console.warn(`Radar SDK: Failed to get location: ${err}`);
58
+ });
59
+ }, [mapOptions]);
60
+
61
+ if (!styleURL) {
62
+ return null;
63
+ }
64
+
65
+ if (!MapLibreGL) {
66
+ return null;
67
+ }
68
+
69
+ const geoJSONUserLocation = {
70
+ type: 'FeatureCollection',
71
+ features: userLocation?.longitude !== undefined ? [
72
+ {
73
+ type: 'Feature',
74
+ geometry: {
75
+ type: 'Point',
76
+ coordinates: [userLocation.longitude, userLocation.latitude],
77
+ },
78
+ },
79
+ ] : [],
80
+ };
81
+
82
+ const userLocationMapIndicator = (
83
+ <MapLibreGL.ShapeSource
84
+ id="user-location"
85
+ shape={geoJSONUserLocation}
86
+ >
87
+ <MapLibreGL.CircleLayer
88
+ id="user-location-inner"
89
+ style={{
90
+ circleRadius: 15,
91
+ circleColor: '#000257',
92
+ circleOpacity: 0.2,
93
+ circlePitchAlignment: 'map',
94
+ }}
95
+ />
96
+ <MapLibreGL.CircleLayer
97
+ id="user-location-middle"
98
+ style={{
99
+ circleRadius: 9,
100
+ circleColor: '#fff',
101
+ circlePitchAlignment: 'map',
102
+ }}
103
+ />
104
+ <MapLibreGL.CircleLayer
105
+ id="user-location-outer"
106
+ style={{
107
+ circleRadius: 6,
108
+ circleColor: '#000257',
109
+ circlePitchAlignment: 'map',
110
+ }}
111
+ />
112
+ </MapLibreGL.ShapeSource>
113
+ );
114
+
115
+ return (
116
+ <View style={styles.mapContainer}>
117
+ <MapLibreGL.MapView
118
+ style={styles.map}
119
+ pitchEnabled={false}
120
+ compassEnabled={false}
121
+ logoEnabled={false}
122
+ attributionEnabled
123
+ onRegionDidChange={mapOptions?.onRegionDidChange ? mapOptions.onRegionDidChange : null}
124
+ onDidFinishLoadingMap={mapOptions?.onDidFinishLoadingMap ? mapOptions.onDidFinishLoadingMap : null}
125
+ onWillStartLoadingMap={mapOptions?.onWillStartLoadingMap ? mapOptions.onWillStartLoadingMap : null}
126
+ onDidFailLoadingMap={mapOptions?.onDidFailLoadingMap ? mapOptions.onDidFailLoadingMap : null}
127
+ mapStyle={styleURL}>
128
+ {mapOptions?.showUserLocation !== false && userLocationMapIndicator}
129
+ {children}
130
+ </MapLibreGL.MapView>
131
+ <Image
132
+ source={require('./map-logo.png')}
133
+ style={styles.mapLogo}
134
+ />
135
+ </View>
136
+ );
137
+ };
138
+
139
+ export default RadarMap;
@@ -150,4 +150,23 @@ declare namespace styles {
150
150
  export { height_5 as height };
151
151
  export let resizeMode: "contain";
152
152
  }
153
+ namespace mapContainer {
154
+ let flex_2: number;
155
+ export { flex_2 as flex };
156
+ }
157
+ namespace map {
158
+ let flex_3: number;
159
+ export { flex_3 as flex };
160
+ }
161
+ namespace mapLogo {
162
+ export let position: "absolute";
163
+ export let bottom: number;
164
+ export let left: number;
165
+ let width_9: number;
166
+ export { width_9 as width };
167
+ let height_6: number;
168
+ export { height_6 as height };
169
+ let resizeMode_1: "contain";
170
+ export { resizeMode_1 as resizeMode };
171
+ }
153
172
  }
package/dist/ui/styles.js CHANGED
@@ -107,5 +107,19 @@ const styles = react_native_1.StyleSheet.create({
107
107
  height: 15,
108
108
  resizeMode: 'contain',
109
109
  },
110
+ mapContainer: {
111
+ flex: 1,
112
+ },
113
+ map: {
114
+ flex: 1,
115
+ },
116
+ mapLogo: {
117
+ position: 'absolute',
118
+ bottom: -10,
119
+ left: 5,
120
+ width: 50,
121
+ height: 50,
122
+ resizeMode: 'contain',
123
+ },
110
124
  });
111
125
  exports.default = styles;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "3.23.6-beta.1";
1
+ export declare const VERSION = "3.23.7-beta.2";
package/dist/version.js CHANGED
@@ -3,4 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // This file contains the version of the react-native-radar package
5
5
  // It should be updated to match the version in package.json
6
- exports.VERSION = '3.23.6-beta.1';
6
+ exports.VERSION = '3.23.7-beta.2';
package/ios/RNRadar.mm CHANGED
@@ -184,10 +184,15 @@ RCT_EXPORT_MODULE()
184
184
  #endif
185
185
  }
186
186
 
187
- RCT_EXPORT_METHOD(initialize:(NSString *)publishableKey fraud:(BOOL)fraud) {
187
+ RCT_EXPORT_METHOD(initialize:(NSString *)publishableKey fraud:(BOOL)fraud options:(NSDictionary *)options) {
188
188
  [[NSUserDefaults standardUserDefaults] setObject:@"ReactNative" forKey:@"radar-xPlatformSDKType"];
189
- [[NSUserDefaults standardUserDefaults] setObject:@"3.23.6-beta.1" forKey:@"radar-xPlatformSDKVersion"];
190
- [Radar initializeWithPublishableKey:publishableKey];
189
+ [[NSUserDefaults standardUserDefaults] setObject:@"3.23.7-beta.2" forKey:@"radar-xPlatformSDKVersion"];
190
+
191
+ RadarInitializeOptions *radarOptions = [[RadarInitializeOptions alloc] init];
192
+ if (options != nil && options[@"silentPush"]) {
193
+ radarOptions.silentPush = [options[@"silentPush"] boolValue];
194
+ }
195
+ [Radar initializeWithPublishableKey:publishableKey options:radarOptions];
191
196
  }
192
197
 
193
198
  RCT_EXPORT_METHOD(setLogLevel:(NSString *)level) {
@@ -1294,6 +1299,15 @@ RCT_EXPORT_METHOD(showInAppMessage:(NSDictionary *)inAppMessageDict) {
1294
1299
  }
1295
1300
  }
1296
1301
 
1302
+ RCT_EXPORT_METHOD(setPushNotificationToken:(NSString *)token) {
1303
+ // No-op on iOS - push notifications are configured differently
1304
+ // iOS uses didRegisterForRemoteNotificationsWithDeviceToken in AppDelegate
1305
+ }
1306
+
1307
+ RCT_EXPORT_METHOD(isInitialized:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
1308
+ resolve(@(Radar.isInitialized));
1309
+ }
1310
+
1297
1311
  RCT_EXPORT_METHOD(logConversion:(NSDictionary *)optionsDict resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
1298
1312
  if (optionsDict == nil) {
1299
1313
  if (reject) {
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.23.6-beta.1",
6
+ "version": "3.23.7-beta.2",
7
7
  "main": "dist/index.js",
8
8
  "files": [
9
9
  "dist",
@@ -56,11 +56,15 @@
56
56
  ]
57
57
  },
58
58
  "peerDependencies": {
59
+ "@maplibre/maplibre-react-native": ">=10.2.1",
59
60
  "expo": ">=43.0.5",
60
61
  "react": ">= 16.8.6",
61
62
  "react-native": ">= 0.60.0"
62
63
  },
63
64
  "peerDependenciesMeta": {
65
+ "@maplibre/maplibre-react-native": {
66
+ "optional": true
67
+ },
64
68
  "expo": {
65
69
  "optional": true
66
70
  }
@@ -45,6 +45,7 @@ const withRadarAndroid = (config, args) => {
45
45
  return withAppBuildGradle(config, (config) => {
46
46
  if (config.modResults.language === "groovy") {
47
47
  config.modResults.contents = modifyAppBuildGradle(config.modResults.contents, args.androidFraud ?? false);
48
+ config.modResults.contents = addCoreLibraryDesugaring(config.modResults.contents);
48
49
  }
49
50
  else {
50
51
  throw new Error("Cannot configure Sentry in the app gradle because the build.gradle is not groovy");
@@ -91,5 +92,45 @@ function modifyAppBuildGradle(buildGradle, androidFraud) {
91
92
  replacementString +=
92
93
  "\n\n" + ' implementation "com.google.android.play:integrity:1.2.0"';
93
94
  }
94
- return buildGradle.replace(pattern, (match) => match + replacementString);
95
+ buildGradle = buildGradle.replace(pattern, (match) => match + replacementString);
96
+ return buildGradle;
97
+ }
98
+ function addCoreLibraryDesugaring(buildGradle) {
99
+ if (buildGradle.includes('coreLibraryDesugaringEnabled true')) {
100
+ return buildGradle;
101
+ }
102
+ const androidBlockRegex = /android\s*\{([\s\S]*?)^\}/m;
103
+ const compileOptionsRegex = /compileOptions\s*\{([\s\S]*?)^\s*\}/m;
104
+ const androidMatch = buildGradle.match(androidBlockRegex);
105
+ if (androidMatch) {
106
+ const androidBlock = androidMatch[0];
107
+ const androidBlockContent = androidMatch[1];
108
+ const compileOptionsMatch = androidBlockContent.match(compileOptionsRegex);
109
+ if (compileOptionsMatch) {
110
+ if (!/coreLibraryDesugaringEnabled\s+true/.test(compileOptionsMatch[0])) {
111
+ const updatedCompileOptions = compileOptionsMatch[0].replace(/^\s*\}/m, ' coreLibraryDesugaringEnabled true\n }');
112
+ const updatedAndroidBlock = androidBlock.replace(compileOptionsMatch[0], updatedCompileOptions);
113
+ buildGradle = buildGradle.replace(androidBlock, updatedAndroidBlock);
114
+ }
115
+ }
116
+ else {
117
+ const insertIndex = buildGradle.indexOf(androidMatch[0]) + androidMatch[0].indexOf('{') + 1;
118
+ buildGradle =
119
+ buildGradle.slice(0, insertIndex) +
120
+ '\n compileOptions {\n coreLibraryDesugaringEnabled true\n }\n' +
121
+ buildGradle.slice(insertIndex);
122
+ }
123
+ }
124
+ if (!buildGradle.includes('coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.5"')) {
125
+ const dependenciesPattern = '\ndependencies {\n';
126
+ const dependenciesIndex = buildGradle.indexOf(dependenciesPattern);
127
+ if (dependenciesIndex !== -1) {
128
+ const dependenciesPivot = dependenciesIndex + dependenciesPattern.length;
129
+ buildGradle =
130
+ buildGradle.slice(0, dependenciesPivot) +
131
+ ' coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.5"\n\n' +
132
+ buildGradle.slice(dependenciesPivot);
133
+ }
134
+ }
135
+ return buildGradle;
95
136
  }
@@ -49,7 +49,7 @@ import type {
49
49
  } from "./types";
50
50
 
51
51
  export interface RadarNativeInterface {
52
- initialize: (publishableKey: string, fraud?: boolean) => void;
52
+ initialize: (publishableKey: string, fraud?: boolean, options?: Object | null) => void;
53
53
  setLogLevel: (level: RadarLogLevel) => void;
54
54
  setUserId: (userId: string) => void;
55
55
  getUserId: () => Promise<string>;
@@ -124,6 +124,8 @@ export interface RadarNativeInterface {
124
124
  nativeSdkVersion: () => Promise<string>;
125
125
  rnSdkVersion: () => string;
126
126
  showInAppMessage: (inAppMessage: RadarInAppMessage) => void;
127
+ setPushNotificationToken: (token: string) => void;
128
+ isInitialized: () => Promise<boolean>;
127
129
 
128
130
  onLocationUpdated: (callback: RadarLocationUpdateCallback | null) => void;
129
131
  onClientLocationUpdated: (
@@ -846,3 +846,20 @@ export type RadarTripStatus =
846
846
  | "expired"
847
847
  | "completed"
848
848
  | "canceled";
849
+
850
+ export interface RadarMapOptions {
851
+ mapStyle?: string;
852
+ showUserLocation?: boolean;
853
+ onRegionDidChange?: (feature: RadarMapRegionChangeEvent) => void;
854
+ onDidFinishLoadingMap?: () => void;
855
+ onWillStartLoadingMap?: () => void;
856
+ onDidFailLoadingMap?: () => void;
857
+ }
858
+
859
+ export interface RadarMapRegionChangeEvent {
860
+ center: [number, number];
861
+ zoom: number;
862
+ bounds?: [number, number, number, number];
863
+ bearing?: number;
864
+ pitch?: number;
865
+ }
@@ -43,7 +43,7 @@ export type InAppMessageClickedEmitter = {
43
43
  };
44
44
 
45
45
  export interface Spec extends TurboModule {
46
- initialize(publishableKey: string, fraud: boolean): void;
46
+ initialize(publishableKey: string, fraud: boolean, options: Object | null): void;
47
47
  requestPermissions(background: boolean): Promise<string>;
48
48
  getPermissionsStatus(): Promise<string>;
49
49
  trackOnce(trackOnceOptions: Object | null): Promise<Object>;
@@ -101,6 +101,8 @@ export interface Spec extends TurboModule {
101
101
  getHost(): Promise<string>;
102
102
  getPublishableKey(): Promise<string>;
103
103
  showInAppMessage(inAppMessage: Object): void;
104
+ setPushNotificationToken(token: string): void;
105
+ isInitialized(): Promise<boolean>;
104
106
  readonly locationEmitter: EventEmitter<LocationEmitter>;
105
107
  readonly clientLocationEmitter: EventEmitter<ClientLocationEmitter>;
106
108
  readonly errorEmitter: EventEmitter<ErrorEmitter>;
@@ -1,4 +1,5 @@
1
1
  import type { EventSubscription } from "react-native";
2
+ import { Platform } from "react-native";
2
3
  import type { RadarNativeInterface } from "./@types/RadarNativeInterface";
3
4
  import type {
4
5
  RadarTrackCallback,
@@ -118,8 +119,8 @@ let inAppMessageDismissedUpdateSubscription: EventSubscription | null = null;
118
119
  let inAppMessageClickedUpdateSubscription: EventSubscription | null = null;
119
120
 
120
121
  const Radar: RadarNativeInterface = {
121
- initialize: (publishableKey: string, fraud?: boolean) => {
122
- NativeRadar.initialize(publishableKey, !!fraud);
122
+ initialize: (publishableKey: string, fraud?: boolean, options?: Object | null) => {
123
+ NativeRadar.initialize(publishableKey, !!fraud, options || null);
123
124
  Radar.onNewInAppMessage((inAppMessage) => {
124
125
  Radar.showInAppMessage(inAppMessage);
125
126
  });
@@ -317,6 +318,14 @@ const Radar: RadarNativeInterface = {
317
318
  return NativeRadar.showInAppMessage(inAppMessage);
318
319
  },
319
320
 
321
+ setPushNotificationToken: (token: string) => {
322
+ if (Platform.OS === 'android') {
323
+ return NativeRadar.setPushNotificationToken(token);
324
+ }
325
+ // iOS handles push notifications differently via AppDelegate
326
+ // See: https://docs.radar.com/sdk/silent-push#silent-push
327
+ },
328
+
320
329
  requestPermissions: (background: boolean) => {
321
330
  return NativeRadar.requestPermissions(
322
331
  background
@@ -534,6 +543,9 @@ const Radar: RadarNativeInterface = {
534
543
  getPublishableKey: function (): Promise<string> {
535
544
  return NativeRadar.getPublishableKey();
536
545
  },
546
+ isInitialized: function (): Promise<boolean> {
547
+ return NativeRadar.isInitialized();
548
+ },
537
549
  };
538
550
 
539
551
  export default Radar;
package/src/index.tsx CHANGED
@@ -18,5 +18,10 @@ let Autocomplete =
18
18
  Platform.OS !== "web" ? require("./ui/autocomplete").default : {};
19
19
  export { Autocomplete };
20
20
 
21
+ let Map = Platform.OS !== "web" ? require("./ui/map").default : {};
22
+ export { Map };
23
+
24
+ export type { RadarMapProps } from "./ui/map";
25
+
21
26
  export * from "./@types/types";
22
27
  export * from "./@types/RadarNativeInterface";
package/src/ui/map.jsx ADDED
@@ -0,0 +1,139 @@
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
+ /**
23
+ * RadarMap component for displaying maps with Radar integration
24
+ * @param {Object} props - Component props
25
+ * @param {Object} [props.mapOptions] - Map configuration options
26
+ * @param {string} [props.mapOptions.mapStyle] - Map style identifier (defaults to 'radar-default-v1')
27
+ * @param {boolean} [props.mapOptions.showUserLocation] - Whether to show the user's location on the map (default: true)
28
+ * @param {function} [props.mapOptions.onRegionDidChange] - Callback fired when the map region changes
29
+ * @param {Object} props.mapOptions.onRegionDidChange.feature - The region feature data
30
+ * @param {function} [props.mapOptions.onDidFinishLoadingMap] - Callback fired when the map finishes loading
31
+ * @param {function} [props.mapOptions.onWillStartLoadingMap] - Callback fired when the map starts loading
32
+ * @param {function} [props.mapOptions.onDidFailLoadingMap] - Callback fired when the map fails to load
33
+ * @param {React.ReactNode} [props.children] - Child components to render within the map
34
+ * @returns {React.Component|null} The RadarMap component or null if dependencies are missing
35
+ */
36
+
37
+ const RadarMap = ({ mapOptions, children }) => {
38
+ const [styleURL, setStyleURL] = useState(null);
39
+ const [userLocation, setUserLocation] = useState(null);
40
+
41
+ useEffect(() => {
42
+ createStyleURL(mapOptions?.mapStyle || DEFAULT_STYLE).then((result) => {
43
+ setStyleURL(result);
44
+ });
45
+ }, [mapOptions]);
46
+
47
+ useEffect(() => {
48
+ Radar.getLocation().then((result) => {
49
+ if (result?.location?.latitude && result?.location?.longitude) {
50
+ setUserLocation({
51
+ latitude: result.location.latitude,
52
+ longitude: result.location.longitude,
53
+ });
54
+ }
55
+ }).catch((err) => {
56
+ // eslint-disable-next-line no-console
57
+ console.warn(`Radar SDK: Failed to get location: ${err}`);
58
+ });
59
+ }, [mapOptions]);
60
+
61
+ if (!styleURL) {
62
+ return null;
63
+ }
64
+
65
+ if (!MapLibreGL) {
66
+ return null;
67
+ }
68
+
69
+ const geoJSONUserLocation = {
70
+ type: 'FeatureCollection',
71
+ features: userLocation?.longitude !== undefined ? [
72
+ {
73
+ type: 'Feature',
74
+ geometry: {
75
+ type: 'Point',
76
+ coordinates: [userLocation.longitude, userLocation.latitude],
77
+ },
78
+ },
79
+ ] : [],
80
+ };
81
+
82
+ const userLocationMapIndicator = (
83
+ <MapLibreGL.ShapeSource
84
+ id="user-location"
85
+ shape={geoJSONUserLocation}
86
+ >
87
+ <MapLibreGL.CircleLayer
88
+ id="user-location-inner"
89
+ style={{
90
+ circleRadius: 15,
91
+ circleColor: '#000257',
92
+ circleOpacity: 0.2,
93
+ circlePitchAlignment: 'map',
94
+ }}
95
+ />
96
+ <MapLibreGL.CircleLayer
97
+ id="user-location-middle"
98
+ style={{
99
+ circleRadius: 9,
100
+ circleColor: '#fff',
101
+ circlePitchAlignment: 'map',
102
+ }}
103
+ />
104
+ <MapLibreGL.CircleLayer
105
+ id="user-location-outer"
106
+ style={{
107
+ circleRadius: 6,
108
+ circleColor: '#000257',
109
+ circlePitchAlignment: 'map',
110
+ }}
111
+ />
112
+ </MapLibreGL.ShapeSource>
113
+ );
114
+
115
+ return (
116
+ <View style={styles.mapContainer}>
117
+ <MapLibreGL.MapView
118
+ style={styles.map}
119
+ pitchEnabled={false}
120
+ compassEnabled={false}
121
+ logoEnabled={false}
122
+ attributionEnabled
123
+ onRegionDidChange={mapOptions?.onRegionDidChange ? mapOptions.onRegionDidChange : null}
124
+ onDidFinishLoadingMap={mapOptions?.onDidFinishLoadingMap ? mapOptions.onDidFinishLoadingMap : null}
125
+ onWillStartLoadingMap={mapOptions?.onWillStartLoadingMap ? mapOptions.onWillStartLoadingMap : null}
126
+ onDidFailLoadingMap={mapOptions?.onDidFailLoadingMap ? mapOptions.onDidFailLoadingMap : null}
127
+ mapStyle={styleURL}>
128
+ {mapOptions?.showUserLocation !== false && userLocationMapIndicator}
129
+ {children}
130
+ </MapLibreGL.MapView>
131
+ <Image
132
+ source={require('./map-logo.png')}
133
+ style={styles.mapLogo}
134
+ />
135
+ </View>
136
+ );
137
+ };
138
+
139
+ export default RadarMap;
package/src/ui/map.tsx ADDED
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { RadarMapOptions } from '../@types/types';
3
+
4
+ const RadarMapJS = require('./map.jsx').default;
5
+
6
+ export interface RadarMapProps {
7
+ /**
8
+ * Configuration options for the RadarMap component
9
+ */
10
+ mapOptions?: RadarMapOptions;
11
+ /**
12
+ * Child components to render within the map
13
+ */
14
+ children?: React.ReactNode;
15
+ }
16
+
17
+ /**
18
+ * TypeScript wrapper for the RadarMap component that provides type safety
19
+ * while delegating the implementation to the JavaScript version.
20
+ *
21
+ * @param props - The props for the RadarMap component
22
+ * @returns The RadarMap component with proper TypeScript typing
23
+ */
24
+ const RadarMap: React.FC<RadarMapProps> = (props) => {
25
+ return React.createElement(RadarMapJS, props);
26
+ };
27
+
28
+ export default RadarMap;
package/src/ui/styles.js CHANGED
@@ -106,6 +106,20 @@ const styles = StyleSheet.create({
106
106
  height: 15,
107
107
  resizeMode: 'contain',
108
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
+ },
109
123
  });
110
124
 
111
125
  export default styles;
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // This file contains the version of the react-native-radar package
2
2
  // It should be updated to match the version in package.json
3
- export const VERSION = '3.23.6-beta.1';
3
+ export const VERSION = '3.23.7-beta.2';