@datadog/mobile-react-native-session-replay 2.1.0-alpha.0 → 2.1.1-alpha.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.
@@ -20,7 +20,8 @@ Pod::Spec.new do |s|
20
20
 
21
21
  # /!\ Remember to keep the version in sync with DatadogSDKReactNative.podspec
22
22
  s.dependency 'DatadogSessionReplay', '~> 2.6.0'
23
-
23
+ s.dependency 'DatadogSDKReactNative'
24
+
24
25
  s.test_spec 'Tests' do |test_spec|
25
26
  test_spec.dependency "React-RCTText"
26
27
  test_spec.source_files = 'ios/Tests/*.swift'
@@ -189,6 +189,7 @@ dependencies {
189
189
  }
190
190
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
191
191
  implementation "com.datadoghq:dd-sdk-android-session-replay:2.5.0"
192
+ implementation project(path: ':datadog_mobile-react-native')
192
193
 
193
194
  testImplementation "org.junit.platform:junit-platform-launcher:1.6.2"
194
195
  testImplementation "org.junit.jupiter:junit-jupiter-api:5.6.2"
@@ -10,6 +10,7 @@ import com.datadog.android.Datadog
10
10
  import com.datadog.android.api.feature.FeatureSdkCore
11
11
  import com.datadog.android.sessionreplay.SessionReplayConfiguration
12
12
  import com.datadog.android.sessionreplay.SessionReplayPrivacy
13
+ import com.datadog.reactnative.DatadogSDKWrapperStorage
13
14
  import com.facebook.react.bridge.Promise
14
15
  import com.facebook.react.bridge.ReactContext
15
16
  import java.util.Locale
@@ -30,7 +31,7 @@ class DdSessionReplayImplementation(
30
31
  * @param customEndpoint Custom server url for sending replay data.
31
32
  */
32
33
  fun enable(replaySampleRate: Double, defaultPrivacyLevel: String, customEndpoint: String, promise: Promise) {
33
- val sdkCore = Datadog.getInstance() as FeatureSdkCore
34
+ val sdkCore = DatadogSDKWrapperStorage.getSdkCore() as FeatureSdkCore
34
35
  val logger = sdkCore.internalLogger
35
36
  val configuration = SessionReplayConfiguration.Builder(replaySampleRate.toFloat())
36
37
  .setPrivacy(buildPrivacy(defaultPrivacyLevel))
@@ -40,7 +41,7 @@ class DdSessionReplayImplementation(
40
41
  configuration.useCustomEndpoint(customEndpoint)
41
42
  }
42
43
 
43
- sessionReplayProvider().enable(configuration.build())
44
+ sessionReplayProvider().enable(configuration.build(), sdkCore)
44
45
  promise.resolve(null)
45
46
  }
46
47
 
@@ -144,6 +144,12 @@ internal class ReactTextPropertiesResolver(
144
144
  }
145
145
 
146
146
  private fun getTextColor(shadowNodeWrapper: ShadowNodeWrapper): String? {
147
+ val isColorSet = shadowNodeWrapper
148
+ .getDeclaredShadowNodeField(IS_COLOR_SET_FIELD_NAME) as Boolean?
149
+ if (isColorSet != true) {
150
+ // Improvement: get default text color if different from black
151
+ return "#000000FF"
152
+ }
147
153
  val resolvedColor = shadowNodeWrapper
148
154
  .getDeclaredShadowNodeField(COLOR_FIELD_NAME) as Int?
149
155
  if (resolvedColor != null) {
@@ -187,6 +193,7 @@ internal class ReactTextPropertiesResolver(
187
193
  internal const val TEXT_ATTRIBUTES_FIELD_NAME = "mTextAttributes"
188
194
  internal const val FONT_FAMILY_FIELD_NAME = "mFontFamily"
189
195
  internal const val COLOR_FIELD_NAME = "mColor"
196
+ internal const val IS_COLOR_SET_FIELD_NAME = "mIsColorSet"
190
197
 
191
198
  private const val ROBOTO_TYPEFACE_NAME = "roboto"
192
199
  private const val SERIF_FAMILY_NAME = "serif"
@@ -6,6 +6,7 @@
6
6
 
7
7
  package com.datadog.reactnative.sessionreplay
8
8
 
9
+ import com.datadog.android.api.SdkCore
9
10
  import com.datadog.android.sessionreplay.SessionReplay
10
11
  import com.datadog.android.sessionreplay.SessionReplayConfiguration
11
12
 
@@ -16,9 +17,11 @@ internal class SessionReplaySDKWrapper : SessionReplayWrapper {
16
17
  */
17
18
  override fun enable(
18
19
  sessionReplayConfiguration: SessionReplayConfiguration,
20
+ sdkCore: SdkCore
19
21
  ) {
20
22
  SessionReplay.enable(
21
23
  sessionReplayConfiguration,
24
+ sdkCore,
22
25
  )
23
26
  }
24
27
  }
@@ -6,6 +6,7 @@
6
6
 
7
7
  package com.datadog.reactnative.sessionreplay
8
8
 
9
+ import com.datadog.android.api.SdkCore
9
10
  import com.datadog.android.sessionreplay.SessionReplayConfiguration
10
11
 
11
12
  /**
@@ -18,5 +19,6 @@ interface SessionReplayWrapper {
18
19
  */
19
20
  fun enable(
20
21
  sessionReplayConfiguration: SessionReplayConfiguration,
22
+ sdkCore: SdkCore
21
23
  )
22
24
  }
@@ -84,7 +84,7 @@ internal class DdSessionReplayImplementationTest {
84
84
  )
85
85
 
86
86
  // Then
87
- verify(mockSessionReplay).enable(sessionReplayConfigCaptor.capture())
87
+ verify(mockSessionReplay).enable(sessionReplayConfigCaptor.capture(), any())
88
88
  assertThat(sessionReplayConfigCaptor.firstValue)
89
89
  .hasFieldEqualTo("sampleRate", replaySampleRate.toFloat())
90
90
  .hasFieldEqualTo("privacy", privacy)
@@ -104,7 +104,7 @@ internal class DdSessionReplayImplementationTest {
104
104
  testedSessionReplay.enable(replaySampleRate, privacy, "", mockPromise)
105
105
 
106
106
  // Then
107
- verify(mockSessionReplay).enable(sessionReplayConfigCaptor.capture())
107
+ verify(mockSessionReplay).enable(sessionReplayConfigCaptor.capture(), any())
108
108
  assertThat(sessionReplayConfigCaptor.firstValue)
109
109
  .hasFieldEqualTo("sampleRate", replaySampleRate.toFloat())
110
110
  .hasFieldEqualTo("privacy", SessionReplayPrivacy.MASK)
@@ -10,6 +10,7 @@ import android.widget.TextView
10
10
  import com.datadog.android.sessionreplay.model.MobileSegment
11
11
  import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver.Companion.COLOR_FIELD_NAME
12
12
  import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver.Companion.FONT_FAMILY_FIELD_NAME
13
+ import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver.Companion.IS_COLOR_SET_FIELD_NAME
13
14
  import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver.Companion.MONOSPACE_FAMILY_NAME
14
15
  import com.datadog.reactnative.sessionreplay.ReactTextPropertiesResolver.Companion.TEXT_ATTRIBUTES_FIELD_NAME
15
16
  import com.datadog.reactnative.sessionreplay.ShadowNodeWrapper.Companion.UI_IMPLEMENTATION_FIELD_NAME
@@ -238,11 +239,13 @@ internal class ReactTextPropertiesResolverTest {
238
239
  }
239
240
 
240
241
  @Test
241
- fun `M resolve font color W addReactNativeProperties()`(
242
+ fun `M resolve font color W addReactNativeProperties() { color is defined by developer }`(
242
243
  @IntForgery fakeTextColor: Int
243
244
  ) {
244
245
  // Given
245
246
  whenever(mockTextView.background).thenReturn(null)
247
+ whenever(mockReflectionUtils.getDeclaredField(mockShadowNode, IS_COLOR_SET_FIELD_NAME))
248
+ .thenReturn(true)
246
249
  whenever(mockReflectionUtils.getDeclaredField(mockShadowNode, COLOR_FIELD_NAME))
247
250
  .thenReturn(fakeTextColor)
248
251
 
@@ -253,10 +256,30 @@ internal class ReactTextPropertiesResolverTest {
253
256
  assertThat(result.textStyle.color).isEqualTo(formatAsRgba(fakeTextColor))
254
257
  }
255
258
 
259
+ @Test
260
+ fun `M resolve font color W addReactNativeProperties() { color is not defined by developer }`(
261
+ @IntForgery fakeTextColor: Int
262
+ ) {
263
+ // Given
264
+ whenever(mockTextView.background).thenReturn(null)
265
+ whenever(mockReflectionUtils.getDeclaredField(mockShadowNode, IS_COLOR_SET_FIELD_NAME))
266
+ .thenReturn(false)
267
+ whenever(mockReflectionUtils.getDeclaredField(mockShadowNode, COLOR_FIELD_NAME))
268
+ .thenReturn(fakeTextColor)
269
+
270
+ // When
271
+ val result = testedResolver.addReactNativeProperties(fakeWireframe, mockTextView, 0f)
272
+
273
+ // Then
274
+ assertThat(result.textStyle.color).isEqualTo("#000000FF")
275
+ }
276
+
256
277
  @Test
257
278
  fun `M fallback W addReactNativeProperties() { cannot resolve fontColor }`() {
258
279
  // Given
259
280
  whenever(mockTextView.background).thenReturn(null)
281
+ whenever(mockReflectionUtils.getDeclaredField(mockShadowNode, IS_COLOR_SET_FIELD_NAME))
282
+ .thenReturn(true)
260
283
  whenever(mockShadowNodeWrapper.getDeclaredShadowNodeField(COLOR_FIELD_NAME))
261
284
  .thenReturn(null)
262
285
 
@@ -7,6 +7,7 @@
7
7
  import Foundation
8
8
  @_spi(Internal) import DatadogSessionReplay
9
9
  import DatadogInternal
10
+ import DatadogSDKReactNative
10
11
  import React
11
12
 
12
13
  @objc
@@ -42,9 +43,15 @@ public class DdSessionReplayImplementation: NSObject {
42
43
 
43
44
  sessionReplayConfiguration.setAdditionalNodeRecorders([RCTTextViewRecorder(uiManager: self.uiManager)])
44
45
 
45
- sessionReplay.enable(
46
- with: sessionReplayConfiguration
47
- )
46
+ if let core = DatadogSDKWrapper.shared.getCoreInstance() {
47
+ sessionReplay.enable(
48
+ with: sessionReplayConfiguration,
49
+ in: core
50
+ )
51
+ } else {
52
+ consolePrint("Core instance was not found when initializing Session Replay.")
53
+ }
54
+
48
55
  resolve(nil)
49
56
  }
50
57
 
@@ -64,12 +71,13 @@ public class DdSessionReplayImplementation: NSObject {
64
71
 
65
72
  internal protocol SessionReplayProtocol {
66
73
  func enable(
67
- with configuration: SessionReplay.Configuration
74
+ with configuration: SessionReplay.Configuration,
75
+ in core: DatadogCoreProtocol
68
76
  )
69
77
  }
70
78
 
71
79
  internal class NativeSessionReplay: SessionReplayProtocol {
72
- func enable(with configuration: DatadogSessionReplay.SessionReplay.Configuration) {
73
- SessionReplay.enable(with: configuration)
80
+ func enable(with configuration: DatadogSessionReplay.SessionReplay.Configuration, in core: DatadogCoreProtocol) {
81
+ SessionReplay.enable(with: configuration, in: core)
74
82
  }
75
83
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datadog/mobile-react-native-session-replay",
3
- "version": "2.1.0-alpha.0",
3
+ "version": "2.1.1-alpha.0",
4
4
  "description": "A client-side React Native module to enable session replay with Datadog",
5
5
  "keywords": [
6
6
  "datadog",