Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/react-native-session-replay/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ android {
java.srcDirs += ['src/oldarch/kotlin']
}

if (reactNativeMinorVersion >= 75) {
if (reactNativeMinorVersion >= 76) {
java.srcDirs += ['src/rn76/kotlin']
} else if (reactNativeMinorVersion >= 75) {
java.srcDirs += ['src/rn75/kotlin']
} else {
java.srcDirs += ['src/rnlegacy/kotlin']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import android.graphics.drawable.InsetDrawable
import android.graphics.drawable.LayerDrawable
import com.datadog.android.internal.utils.densityNormalized
import com.datadog.android.sessionreplay.model.MobileSegment
import com.datadog.reactnative.sessionreplay.extensions.getRadius
import com.datadog.reactnative.sessionreplay.utils.DrawableUtils
import com.datadog.reactnative.sessionreplay.utils.formatAsRgba
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.uimanager.LengthPercentage
import com.facebook.react.uimanager.Spacing
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable

Expand Down Expand Up @@ -90,11 +90,6 @@ internal class ReactViewBackgroundDrawableUtils : DrawableUtils() {
)
}

private fun LengthPercentage?.getRadius(width: Float, height: Float) = this
?.resolve(width, height)
?.let { (it.horizontal + it.vertical) / 2f }
?: 0f

private companion object {
private const val COLOR_FIELD_NAME = "mColor"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import android.graphics.drawable.Drawable
import android.graphics.drawable.InsetDrawable
import android.graphics.drawable.LayerDrawable
import com.datadog.reactnative.sessionreplay.extensions.convertToDensityNormalized
import com.datadog.android.sessionreplay.model.MobileSegment
import com.datadog.reactnative.sessionreplay.extensions.getRadius
import com.datadog.reactnative.sessionreplay.utils.DrawableUtils
import com.datadog.reactnative.sessionreplay.utils.formatAsRgba
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.uimanager.Spacing
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable

internal class ReactViewBackgroundDrawableUtils : DrawableUtils() {
@OptIn(UnstableReactNativeAPI::class)
override fun resolveShapeAndBorder(
drawable: Drawable,
opacity: Float,
pixelDensity: Float
): Pair<MobileSegment.ShapeStyle?, MobileSegment.ShapeBorder?> {
if (drawable !is CSSBackgroundDrawable) {
return null to null
}

val borderProps = resolveBorder(drawable, pixelDensity)
val backgroundColor = getBackgroundColor(drawable)
val colorHexString = if (backgroundColor != null) {
formatAsRgba(backgroundColor)
} else {
return null to borderProps
}

return MobileSegment.ShapeStyle(
colorHexString,
opacity,
getBorderRadius(drawable)
) to borderProps
}

@OptIn(UnstableReactNativeAPI::class)
override fun getReactBackgroundFromDrawable(drawable: Drawable?): Drawable? {
if (drawable is CSSBackgroundDrawable) {
return drawable
}

if (drawable is InsetDrawable) {
return getReactBackgroundFromDrawable(drawable.drawable)
}

if (drawable is LayerDrawable) {
for (layerNumber in 0 until drawable.numberOfLayers) {
val layer = drawable.getDrawable(layerNumber)
if (layer is CSSBackgroundDrawable) {
return layer
}
}
}

return null
}

@OptIn(UnstableReactNativeAPI::class)
private fun getBorderRadius(drawable: CSSBackgroundDrawable): Float {
val width = drawable.intrinsicWidth.toFloat()
val height = drawable.intrinsicHeight.toFloat()
return drawable.borderRadius.uniform?.getRadius(width, height) ?: 0f
}

@OptIn(UnstableReactNativeAPI::class)
private fun getBackgroundColor(
backgroundDrawable: CSSBackgroundDrawable
): Int? {
return reflectionUtils.getDeclaredField(
backgroundDrawable,
COLOR_FIELD_NAME
) as Int?
}

@OptIn(UnstableReactNativeAPI::class)
private fun resolveBorder(
backgroundDrawable: CSSBackgroundDrawable,
pixelDensity: Float
): MobileSegment.ShapeBorder {
val borderWidth =
backgroundDrawable.fullBorderWidth.toLong().convertToDensityNormalized(pixelDensity)
val borderColor = formatAsRgba(backgroundDrawable.getBorderColor(Spacing.ALL))

return MobileSegment.ShapeBorder(
color = borderColor,
width = borderWidth
)
}

private companion object {
private const val COLOR_FIELD_NAME = "mColor"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.datadog.reactnative.sessionreplay.extensions

import com.facebook.react.uimanager.LengthPercentage

internal fun LengthPercentage?.getRadius(width: Float, height: Float) = this
?.resolve(width, height)
?.let { (it.horizontal + it.vertical) / 2f }
?: 0f