@scalebun/react-native 1.10.7 → 1.11.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.
- package/android/src/main/java/com/scalebun/replaysdk/tracking/InteractionTracker.kt +25 -24
- package/dist/scalebun.full.js +236 -187
- package/dist/scalebun.slim.js +235 -186
- package/ios/Capture/InteractionTracker.swift +8 -4
- package/lib/commonjs/analytics/EventTracker.js +5 -5
- package/lib/commonjs/analytics/automaticEvents.js +3 -2
- package/lib/commonjs/core/constants/version.js +7 -2
- package/lib/commonjs/features/journey/ScaleBunDebugRoot.js +80 -103
- package/lib/commonjs/features/journey/interactionProtocol.js +47 -0
- package/lib/commonjs/features/journey/uiState.js +8 -1
- package/lib/commonjs/features/session/JourneyEventPipeline.js +6 -5
- package/lib/commonjs/features/session/SessionManager.js +37 -38
- package/lib/module/analytics/EventTracker.js +5 -5
- package/lib/module/analytics/automaticEvents.js +3 -2
- package/lib/module/core/constants/version.js +7 -2
- package/lib/module/features/journey/ScaleBunDebugRoot.js +80 -103
- package/lib/module/features/journey/interactionProtocol.js +38 -0
- package/lib/module/features/journey/uiState.js +8 -1
- package/lib/module/features/session/JourneyEventPipeline.js +6 -5
- package/lib/module/features/session/SessionManager.js +37 -38
- package/lib/typescript/analytics/EventTracker.d.ts +1 -1
- package/lib/typescript/analytics/automaticEvents.d.ts +3 -1
- package/lib/typescript/core/constants/version.d.ts +7 -2
- package/lib/typescript/features/journey/interactionProtocol.d.ts +21 -0
- package/lib/typescript/features/session/JourneyEventPipeline.d.ts +1 -0
- package/lib/typescript/features/session/SessionManager.d.ts +15 -10
- package/package.json +3 -2
- package/src/analytics/EventTracker.ts +5 -5
- package/src/analytics/automaticEvents.ts +4 -0
- package/src/core/constants/version.ts +7 -2
- package/src/features/journey/ScaleBunDebugRoot.tsx +96 -97
- package/src/features/journey/interactionProtocol.ts +65 -0
- package/src/features/journey/uiState.ts +9 -4
- package/src/features/session/JourneyEventPipeline.ts +7 -5
- package/src/features/session/SessionManager.ts +75 -38
|
@@ -9,6 +9,7 @@ import android.view.Window
|
|
|
9
9
|
import android.view.WindowManager
|
|
10
10
|
import java.lang.ref.WeakReference
|
|
11
11
|
import java.util.WeakHashMap
|
|
12
|
+
import java.util.UUID
|
|
12
13
|
import com.facebook.react.bridge.Arguments
|
|
13
14
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
14
15
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
@@ -34,13 +35,10 @@ class InteractionTracker(private val reactContext: ReactApplicationContext) {
|
|
|
34
35
|
private var touchDownX = 0f
|
|
35
36
|
private var touchDownY = 0f
|
|
36
37
|
private var touchDownTs = 0L
|
|
37
|
-
private var
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
private val SAME_COORD_WINDOW_MS = 500L
|
|
42
|
-
private var lastEmitRawX = Float.NaN
|
|
43
|
-
private var lastEmitRawY = Float.NaN
|
|
38
|
+
private var touchDownOccurredAt = 0L
|
|
39
|
+
private var touchInteractionId = ""
|
|
40
|
+
private var lastEmittedInteractionId = ""
|
|
41
|
+
private val processInteractionNonce = UUID.randomUUID().toString().take(8)
|
|
44
42
|
private val mainHandler = Handler(Looper.getMainLooper())
|
|
45
43
|
|
|
46
44
|
fun attach(activity: Activity) {
|
|
@@ -63,6 +61,9 @@ class InteractionTracker(private val reactContext: ReactApplicationContext) {
|
|
|
63
61
|
touchDownX = rawX
|
|
64
62
|
touchDownY = rawY
|
|
65
63
|
touchDownTs = ts
|
|
64
|
+
val id = "ixn-a-$processInteractionNonce-$ts"
|
|
65
|
+
if (id != touchInteractionId) touchDownOccurredAt = System.currentTimeMillis()
|
|
66
|
+
touchInteractionId = id
|
|
66
67
|
},
|
|
67
68
|
onUp = { rawX, rawY, ts ->
|
|
68
69
|
handleTouchUp(rawX, rawY, ts, resolveCaptureView(window))
|
|
@@ -86,6 +87,9 @@ class InteractionTracker(private val reactContext: ReactApplicationContext) {
|
|
|
86
87
|
touchDownX = rawX
|
|
87
88
|
touchDownY = rawY
|
|
88
89
|
touchDownTs = ts
|
|
90
|
+
val id = "ixn-a-$processInteractionNonce-$ts"
|
|
91
|
+
if (id != touchInteractionId) touchDownOccurredAt = System.currentTimeMillis()
|
|
92
|
+
touchInteractionId = id
|
|
89
93
|
},
|
|
90
94
|
onUp = { rawX, rawY, ts ->
|
|
91
95
|
val main = attachedWindow ?: return@DialogTouchObserver
|
|
@@ -137,21 +141,11 @@ class InteractionTracker(private val reactContext: ReactApplicationContext) {
|
|
|
137
141
|
ReplayLogger.debug("Native touch up dropped: no usable capture view")
|
|
138
142
|
return
|
|
139
143
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// Bit-identical float coordinates within half a second cannot be a second physical
|
|
146
|
-
// tap — a real double-tap lands on at least slightly different pixels — so this
|
|
147
|
-
// drops only machine duplicates. Distinct-coordinate taps still pass at THROTTLE_MS.
|
|
148
|
-
if (rawX == lastEmitRawX && rawY == lastEmitRawY && now - lastEmitTs < SAME_COORD_WINDOW_MS) {
|
|
149
|
-
lastEmitTs = now // keep a chained burst suppressed
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
lastEmitTs = now
|
|
153
|
-
lastEmitRawX = rawX
|
|
154
|
-
lastEmitRawY = rawY
|
|
144
|
+
// Window/dialog hooks can re-deliver one physical touch. The ACTION_DOWN identity is stable
|
|
145
|
+
// across those deliveries, unlike coordinates: two legitimate rapid taps may land on the
|
|
146
|
+
// exact same pixel and must both survive.
|
|
147
|
+
if (touchInteractionId.isNotEmpty() && touchInteractionId == lastEmittedInteractionId) return
|
|
148
|
+
lastEmittedInteractionId = touchInteractionId
|
|
155
149
|
|
|
156
150
|
val durationMs = ts - touchDownTs
|
|
157
151
|
val dx = rawX - touchDownX
|
|
@@ -215,6 +209,8 @@ class InteractionTracker(private val reactContext: ReactApplicationContext) {
|
|
|
215
209
|
screenshotW = viewW,
|
|
216
210
|
screenshotH = viewH,
|
|
217
211
|
durationMs = durationMs,
|
|
212
|
+
interactionId = touchInteractionId,
|
|
213
|
+
occurredAt = touchDownOccurredAt,
|
|
218
214
|
onDialogWindow = onDialogWindow
|
|
219
215
|
)
|
|
220
216
|
}
|
|
@@ -226,11 +222,16 @@ class InteractionTracker(private val reactContext: ReactApplicationContext) {
|
|
|
226
222
|
normalizedEndX: Float, normalizedEndY: Float,
|
|
227
223
|
screenshotW: Float, screenshotH: Float,
|
|
228
224
|
durationMs: Long,
|
|
225
|
+
interactionId: String,
|
|
226
|
+
occurredAt: Long,
|
|
229
227
|
onDialogWindow: Boolean = false
|
|
230
228
|
) {
|
|
231
229
|
try {
|
|
232
230
|
val params = Arguments.createMap().apply {
|
|
233
231
|
putString("gestureType", gestureType)
|
|
232
|
+
putString("interactionId", interactionId)
|
|
233
|
+
putInt("interactionProtocol", 1)
|
|
234
|
+
putDouble("occurredAt", occurredAt.toDouble())
|
|
234
235
|
putDouble("rawX", rawX.toDouble())
|
|
235
236
|
putDouble("rawY", rawY.toDouble())
|
|
236
237
|
putDouble("normalizedX", normalizedX.toDouble())
|
|
@@ -276,8 +277,8 @@ class InteractionTracker(private val reactContext: ReactApplicationContext) {
|
|
|
276
277
|
fun reset() {
|
|
277
278
|
lastInteractionMs = 0
|
|
278
279
|
lastEmitTs = 0
|
|
279
|
-
|
|
280
|
-
|
|
280
|
+
touchInteractionId = ""
|
|
281
|
+
lastEmittedInteractionId = ""
|
|
281
282
|
touchDownTs = 0
|
|
282
283
|
}
|
|
283
284
|
}
|