react-native-userleap 2.21.0 → 3.0.0

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.
@@ -13,8 +13,6 @@ import com.facebook.react.bridge.ReactMethod;
13
13
  import com.facebook.react.bridge.ReadableArray;
14
14
  import com.facebook.react.bridge.ReadableMap;
15
15
  import com.facebook.react.bridge.WritableMap;
16
- import com.facebook.react.modules.core.DeviceEventManagerModule;
17
-
18
16
  import com.userleap.EventListener;
19
17
  import com.userleap.EventName;
20
18
  import com.userleap.EventPayload;
@@ -26,13 +24,11 @@ import com.userleap.UserLeap;
26
24
  import org.json.JSONException;
27
25
  import org.json.JSONObject;
28
26
 
29
- import java.util.EnumSet;
30
27
  import java.util.HashMap;
31
28
  import java.util.Iterator;
32
29
  import java.util.List;
33
30
  import java.util.Map;
34
31
  import java.util.Objects;
35
- import java.util.Set;
36
32
  import java.util.stream.Collectors;
37
33
 
38
34
  import javax.annotation.Nullable;
@@ -44,34 +40,6 @@ public class UserLeapModule extends ReactContextBaseJavaModule {
44
40
 
45
41
  private static final String TAG = "UserLeapModule";
46
42
 
47
- /**
48
- * Lifecycle events we forward to React Native via DeviceEventEmitter.
49
- * Excluded:
50
- * - LOGGING_EVENT: handled separately via logcat
51
- * - REPLAY_CAPTURE: internal Web SDK plumbing, not meaningful to RN consumers
52
- * - REPLAY_EVENTS_UPLOADED_COMPLETED: deprecated alias for REPLAY_EVENTS_UPLOAD_COMPLETED
53
- */
54
- private static final Set<EventName> FORWARDED_EVENTS = EnumSet.of(
55
- EventName.SDK_READY,
56
- EventName.VISITOR_ID_UPDATED,
57
- EventName.SURVEY_HEIGHT,
58
- EventName.SURVEY_STATE_RETURNED,
59
- EventName.SURVEY_WILL_PRESENT,
60
- EventName.SURVEY_PRESENTED,
61
- EventName.SURVEY_APPEARED,
62
- EventName.QUESTION_ANSWERED,
63
- EventName.SURVEY_CLOSE_REQUESTED,
64
- EventName.SURVEY_WILL_CLOSE,
65
- EventName.SURVEY_CLOSED,
66
- EventName.SURVEY_COMPLETED,
67
- EventName.REPLAY_CAPTURE_STARTED,
68
- EventName.REPLAY_CAPTURE_STOPPED,
69
- EventName.REPLAY_CAPTURE_COMPLETED,
70
- EventName.REPLAY_RENDERING_COMPLETED,
71
- EventName.REPLAY_UPLOAD_COMPLETED,
72
- EventName.REPLAY_EVENTS_UPLOAD_COMPLETED
73
- );
74
-
75
43
  private final ReactApplicationContext reactContext;
76
44
 
77
45
  public UserLeapModule(ReactApplicationContext reactContext) {
@@ -84,48 +52,6 @@ public class UserLeapModule extends ReactContextBaseJavaModule {
84
52
  return "UserLeapBindings";
85
53
  }
86
54
 
87
- // ---------------------------------------------------------------------------
88
- // Required stubs for RN's NativeEventEmitter on the JS side.
89
- // ---------------------------------------------------------------------------
90
-
91
- @ReactMethod
92
- public void addListener(String eventName) {
93
- // No-op: listeners are registered once in configure() for the SDK lifetime.
94
- }
95
-
96
- @ReactMethod
97
- public void removeListeners(int count) {
98
- // No-op: listeners are registered once in configure() for the SDK lifetime.
99
- }
100
-
101
- // ---------------------------------------------------------------------------
102
- // Lifecycle event registration
103
- // ---------------------------------------------------------------------------
104
-
105
- private void registerForAllLifecycleEvents() {
106
- for (EventName eventName : FORWARDED_EVENTS) {
107
- UserLeap.INSTANCE.addEventListener(eventName, new EventListener() {
108
- @Override
109
- public void onEvent(SprigEvent event) {
110
- sendSprigEvent(event);
111
- }
112
- });
113
- }
114
- }
115
-
116
- private void sendSprigEvent(SprigEvent event) {
117
- if (!reactContext.hasActiveCatalystInstance()) {
118
- return;
119
- }
120
-
121
- WritableMap params = jsonObjectToWritableMap(event.getData());
122
- String eventName = toCamelCase(event.getName().name());
123
-
124
- reactContext
125
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
126
- .emit(eventName, params);
127
- }
128
-
129
55
  // ---------------------------------------------------------------------------
130
56
  // Bridge helpers
131
57
  // ---------------------------------------------------------------------------
@@ -280,8 +206,6 @@ public class UserLeapModule extends ReactContextBaseJavaModule {
280
206
  }
281
207
  });
282
208
 
283
- registerForAllLifecycleEvents();
284
-
285
209
  UserLeap.INSTANCE.configure(
286
210
  reactContext,
287
211
  environment,
package/index.d.ts CHANGED
@@ -5,31 +5,6 @@ declare namespace UserLeap {
5
5
  NO_SURVEY: string;
6
6
  };
7
7
 
8
- const LifecycleEvent: {
9
- sdkReady: number;
10
- visitorIdUpdated: number;
11
- surveyHeight: number;
12
- surveyWillPresent: number;
13
- surveyPresented: number;
14
- surveyAppeared: number;
15
- surveyCloseRequested: number;
16
- surveyWillClose: number;
17
- surveyClosed: number;
18
- replayCapture: number;
19
- replayCaptureStarted: number;
20
- replayCaptureStopped: number;
21
- replayCaptureCompleted: number;
22
- replayRenderingCompleted: number;
23
- replayUploadCompleted: number;
24
- replayEventsUploadCompleted: number;
25
- loggingEvent: number;
26
- surveyCompleted: number;
27
- surveyStateReturned: number;
28
- };
29
-
30
- // Usage: UserLeap.EventEmitter.addListener('surveyPresented', callback)
31
- const EventEmitter: any;
32
-
33
8
  function visitorIdentifier(): number;
34
9
  function visitorIdentifierString(): string;
35
10
  function sdkVersion(): string;
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Platform, NativeModules, NativeEventEmitter } from "react-native";
1
+ import { Platform, NativeModules } from "react-native";
2
2
 
3
3
  import { version } from "./package.json";
4
4
 
@@ -8,29 +8,6 @@ const SurveyState = {
8
8
  NO_SURVEY: "NO_SURVEY",
9
9
  };
10
10
 
11
- const LifecycleEvent = {
12
- sdkReady: 0,
13
- visitorIdUpdated: 1,
14
- surveyHeight: 2,
15
- surveyWillPresent: 3,
16
- surveyPresented: 4,
17
- surveyAppeared: 5,
18
- surveyCloseRequested: 6,
19
- surveyWillClose: 7,
20
- surveyClosed: 8,
21
- replayCapture: 9,
22
- replayCaptureStarted: 10,
23
- replayCaptureStopped: 11,
24
- replayCaptureCompleted: 12,
25
- replayRenderingCompleted: 13,
26
- replayUploadCompleted: 14,
27
- replayEventsUploadCompleted: 15,
28
- loggingEvent: 16,
29
- surveyCompleted: 17,
30
- surveyStateReturned: 18
31
- }
32
-
33
- const UserLeapEventEmitter = new NativeEventEmitter(NativeModules.UserLeapBindings);
34
11
 
35
12
  const stringifyAttributes = (attributes) => {
36
13
  if (!(attributes instanceof Object && attributes.constructor === Object))
@@ -45,7 +22,7 @@ const isValidPlatform = () => {
45
22
  //Platform.Version is a number for android and string for ios
46
23
  return (
47
24
  (Platform.OS === "android" && String(Platform.Version) >= "21") ||
48
- (Platform.OS === "ios" && String(Platform.Version) >= "10.3")
25
+ (Platform.OS === "ios" && String(Platform.Version) >= "15.0")
49
26
  );
50
27
  };
51
28
 
@@ -307,8 +284,6 @@ const UserLeap = {
307
284
  unpauseDisplayingSurveys,
308
285
  };
309
286
 
310
- UserLeap.LifecycleEvent = LifecycleEvent;
311
287
  UserLeap.SurveyState = SurveyState;
312
- UserLeap.EventEmitter = UserLeapEventEmitter;
313
288
 
314
289
  export default UserLeap;
@@ -1,7 +1,6 @@
1
1
  #import <React/RCTBridgeModule.h>
2
- #import <React/RCTEventEmitter.h>
3
2
  @import UserLeapKit;
4
3
 
5
- @interface UserLeapBindings : RCTEventEmitter <RCTBridgeModule, _SGRNExtractor>
4
+ @interface UserLeapBindings : NSObject <RCTBridgeModule, _SGRNExtractor>
6
5
  @property (nonatomic, weak) RCTBridge *bridge;
7
6
  @end
@@ -45,11 +45,6 @@
45
45
  return surveyStateBinding;
46
46
  }
47
47
 
48
- /// These are required by RCTEventEmitter.
49
- - (NSArray<NSString *> *)supportedEvents {
50
- return [LifecycleEventUtil allNameStrings];
51
- }
52
-
53
48
  RCT_EXPORT_MODULE()
54
49
 
55
50
  RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(visitorIdentifier)
@@ -71,32 +66,6 @@ RCT_EXPORT_METHOD(configure:(NSString *)environmentId configuration:(NSDictionar
71
66
  {
72
67
  [[UserLeap shared] configureWithEnvironment:environmentId configuration:configuration];
73
68
  [[UserLeap shared] _passWithRnExtractor:self];
74
-
75
- /// Register for all the LifeCycle events.
76
- [self registerForAllLifecycleEvents];
77
- }
78
-
79
- - (void)registerForAllLifecycleEvents {
80
-
81
- for (NSNumber *eventVal in [LifecycleEventUtil all]) {
82
- [[UserLeap shared] registerEventListenerFor:[eventVal intValue] listener:^(NSDictionary<NSString *,id> * eventData) {
83
-
84
- NSString *type = eventData[LifecycleEventDataKey.eventType];
85
- if (!type) {
86
- return;
87
- }
88
-
89
- LifecycleEvent lifecycleEvent = [LifecycleEventUtil fromString:type];
90
- if (lifecycleEvent != LifecycleEventUnknown) {
91
-
92
- /// Always make sure the type exists in the supportedEvents; sending an unsupported event will crash the app.
93
- NSString *lifecycleEventName = [LifecycleEventUtil stringName:lifecycleEvent];
94
- if ([[self supportedEvents] containsObject: lifecycleEventName]) {
95
- [self sendEventWithName:lifecycleEventName body:eventData];
96
- }
97
- }
98
- }];
99
- }
100
69
  }
101
70
 
102
71
 
@@ -245,21 +214,54 @@ RCT_EXPORT_METHOD(trackIdentifyAndPresent:(NSString *)eventName userId:(NSString
245
214
  }
246
215
 
247
216
  - (_SGRNTextProperties *)textPropertiesFromView:(UIView * _Nonnull)passedView {
248
- if (![passedView isKindOfClass:[RCTTextView class]]) { return nil;}
249
- RCTUIManager* uiManager = [self.bridge moduleForClass:[RCTUIManager class]];
250
- RCTTextView *textView = (RCTTextView *)passedView;
251
- __block _SGRNTextProperties *textProperties = [[_SGRNTextProperties alloc] init];
252
- dispatch_sync(RCTGetUIManagerQueue(), ^{
253
- RCTShadowView *shadowView = [uiManager shadowViewForReactTag:textView.reactTag];
254
- if ([shadowView isKindOfClass:[RCTTextShadowView class]]) {
255
- RCTTextShadowView *textShadowView = (RCTTextShadowView *)shadowView;
256
- textProperties.text = [self extractText: textShadowView.reactSubviews];
257
- textProperties.color = textShadowView.textAttributes.foregroundColor;
258
- textProperties.alignment = textShadowView.textAttributes.alignment;
259
- textProperties.font = textShadowView.textAttributes.effectiveFont;
217
+
218
+ // Legacy for pre new arch.
219
+ if ([passedView isKindOfClass:[RCTTextView class]]) {
220
+ RCTUIManager* uiManager = [self.bridge moduleForClass:[RCTUIManager class]];
221
+ RCTTextView *textView = (RCTTextView *)passedView;
222
+ __block _SGRNTextProperties *textProperties = [[_SGRNTextProperties alloc] init];
223
+ dispatch_sync(RCTGetUIManagerQueue(), ^{
224
+ RCTShadowView *shadowView = [uiManager shadowViewForReactTag:textView.reactTag];
225
+ if ([shadowView isKindOfClass:[RCTTextShadowView class]]) {
226
+ RCTTextShadowView *textShadowView = (RCTTextShadowView *)shadowView;
227
+ NSString *text = [self extractText: textShadowView.reactSubviews];
228
+ if (text.length == 0) return;
229
+ textProperties.text = text;
230
+ textProperties.color = textShadowView.textAttributes.foregroundColor;
231
+ textProperties.alignment = textShadowView.textAttributes.alignment;
232
+ textProperties.font = textShadowView.textAttributes.effectiveFont;
233
+ }
234
+ });
235
+ if (textProperties.text.length == 0) return nil;
236
+ return textProperties;
237
+ }
238
+
239
+ // Text under new arch.
240
+ Class ParagraphComponentView = NSClassFromString(@"RCTParagraphComponentView");
241
+ if (ParagraphComponentView && [passedView isKindOfClass:ParagraphComponentView]) {
242
+ NSString *text = [self extractTextFromParagraphComponentView:passedView];
243
+ if (text.length == 0) return nil;
244
+ _SGRNTextProperties *textProperties = [[_SGRNTextProperties alloc] init];
245
+ textProperties.text = text;
246
+ if ([passedView respondsToSelector:@selector(attributedText)]) {
247
+ NSAttributedString *attrText = [passedView performSelector:@selector(attributedText)];
248
+ if (attrText.length > 0) {
249
+ NSDictionary *attrs = [attrText attributesAtIndex:0 effectiveRange:nil];
250
+ if (!textProperties.color && attrs[NSForegroundColorAttributeName]) {
251
+ textProperties.color = attrs[NSForegroundColorAttributeName];
252
+ }
253
+ if (!textProperties.font && attrs[NSFontAttributeName]) {
254
+ textProperties.font = attrs[NSFontAttributeName];
255
+ }
256
+ NSParagraphStyle *style = attrs[NSParagraphStyleAttributeName];
257
+ if (style) {
258
+ textProperties.alignment = style.alignment;
259
+ }
260
+ }
260
261
  }
261
- });
262
- return textProperties;
262
+ return textProperties;
263
+ }
264
+ return nil;
263
265
  }
264
266
 
265
267
  RCT_EXPORT_METHOD(dismissActiveSurvey)
@@ -302,4 +304,22 @@ RCT_EXPORT_METHOD(unpauseDisplayingSurveys)
302
304
  }
303
305
  return text;
304
306
  }
307
+
308
+ - (NSString *)extractTextFromParagraphComponentView:(UIView *)view {
309
+ if ([view respondsToSelector:@selector(attributedText)]) {
310
+ NSAttributedString *attrText = [view performSelector:@selector(attributedText)];
311
+ return attrText.string;
312
+ }
313
+ if ([view respondsToSelector:@selector(text)]) {
314
+ NSString *text = [view performSelector:@selector(text)];
315
+ return text;
316
+ }
317
+ NSMutableString *result = [NSMutableString string];
318
+ for (UIView *subview in view.subviews) {
319
+ NSString *subText = [self extractTextFromParagraphComponentView:subview];
320
+ if (subText) [result appendString:subText];
321
+ }
322
+ return result;
323
+ }
324
+
305
325
  @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-userleap",
3
- "version": "2.21.0",
3
+ "version": "3.0.0",
4
4
  "description": "React Native module for UserLeap",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -17,11 +17,6 @@
17
17
  "scripts": {
18
18
  "test": "echo \"Error: no test specified\" && exit 1"
19
19
  },
20
- "repository": {
21
- "type": "git",
22
- "url": "git+https://github.com/UserLeap/react-native-userleap.git",
23
- "baseUrl": "https://github.com/UserLeap/react-native-userleap"
24
- },
25
20
  "keywords": [
26
21
  "userleap",
27
22
  "react-native",
@@ -38,9 +33,12 @@
38
33
  "babel-jest": "29.7.0",
39
34
  "eslint": "7.32.0",
40
35
  "jest": "29.7.0",
41
- "metro-react-native-babel-preset": "0.67.0",
42
- "react": "18.2.0",
43
- "react-native": "0.74.7",
36
+ "@react-native/babel-preset": "^0.81.0",
37
+ "react": "19.1.0",
38
+ "react-native": "0.81.0",
44
39
  "react-test-renderer": "18.2.0"
40
+ },
41
+ "overrides": {
42
+ "js-yaml": "3.14.2"
45
43
  }
46
44
  }