Skip to content

Commit

Permalink
recording: react native view not added (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
marandaneto authored Sep 17, 2024
1 parent d9ea951 commit 7b2e436
Showing 1 changed file with 63 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,58 +118,65 @@ public class PostHogReplayIntegration(
private val isSessionReplayEnabled: Boolean
get() = PostHog.isSessionReplayActive()

private val onRootViewsChangedListener =
OnRootViewsChangedListener { view, added ->
try {
if (added) {
view.phoneWindow?.let { window ->
if (view.windowAttachCount == 0) {
window.onDecorViewReady { decorView ->
try {
val listener =
decorView.onNextDraw(
mainHandler,
config.dateProvider,
config.sessionReplayConfig.debouncerDelayMs,
) {
if (!isSessionReplayEnabled) {
return@onNextDraw
}
val timestamp = config.dateProvider.currentTimeMillis()

executor.submit {
try {
generateSnapshot(WeakReference(decorView), WeakReference(window), timestamp)
} catch (e: Throwable) {
config.logger.log("Session Replay generateSnapshot failed: $e.")
}
private fun addView(
view: View,
added: Boolean,
) {
try {
if (added) {
view.phoneWindow?.let { window ->
if (view.windowAttachCount == 0) {
window.onDecorViewReady { decorView ->
try {
val listener =
decorView.onNextDraw(
mainHandler,
config.dateProvider,
config.sessionReplayConfig.debouncerDelayMs,
) {
if (!isSessionReplayEnabled) {
return@onNextDraw
}
val timestamp = config.dateProvider.currentTimeMillis()

executor.submit {
try {
generateSnapshot(WeakReference(decorView), WeakReference(window), timestamp)
} catch (e: Throwable) {
config.logger.log("Session Replay generateSnapshot failed: $e.")
}
}
}

val status = ViewTreeSnapshotStatus(listener)
decorViews[decorView] = status
} catch (e: Throwable) {
config.logger.log("Session Replay onDecorViewReady failed: $e.")
}
val status = ViewTreeSnapshotStatus(listener)
decorViews[decorView] = status
} catch (e: Throwable) {
config.logger.log("Session Replay onDecorViewReady failed: $e.")
}

window.touchEventInterceptors += onTouchEventListener
// TODO: can check if user pressed hardware back button (KEYCODE_BACK)
// window.keyEventInterceptors
}

window.touchEventInterceptors += onTouchEventListener
// TODO: can check if user pressed hardware back button (KEYCODE_BACK)
// window.keyEventInterceptors
}
} else {
view.phoneWindow?.let { window ->
window.peekDecorView()?.let { decorView ->
decorViews[decorView]?.let { status ->
cleanSessionState(decorView, status)
}
}
} else {
view.phoneWindow?.let { window ->
window.peekDecorView()?.let { decorView ->
decorViews[decorView]?.let { status ->
cleanSessionState(decorView, status)
}
}
}
} catch (e: Throwable) {
config.logger.log("Session Replay OnRootViewsChangedListener failed: $e.")
}
} catch (e: Throwable) {
config.logger.log("Session Replay OnRootViewsChangedListener failed: $e.")
}
}

private val onRootViewsChangedListener =
OnRootViewsChangedListener { view, added ->
addView(view, added)
}

private fun detectKeyboardVisibility(
Expand Down Expand Up @@ -289,6 +296,20 @@ public class PostHogReplayIntegration(
return
}

// workaround for react native that is started after the window is added
// Curtains.rootViews should be empty for normal apps yet
Curtains.rootViews.forEach { view ->
view.phoneWindow?.let { window ->
window.peekDecorView()?.let { decorView ->
val hasDecorView = decorViews[decorView] != null

if (!hasDecorView) {
addView(view, true)
}
}
}
}

try {
Curtains.onRootViewsChangedListeners += onRootViewsChangedListener
} catch (e: Throwable) {
Expand Down

0 comments on commit 7b2e436

Please sign in to comment.