Skip to content

Commit

Permalink
chore: gradient backgrounds support (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
marandaneto authored Jan 24, 2024
1 parent 6665c47 commit 238ade4
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 30 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Next

- recording: gradient background support ([#88](https://github.com/PostHog/posthog-android/pull/88))

## 3.1.4 - 2024-01-19

- Set `Content-Length` header for gzip bodies because of more strict proxies ([#86](https://github.com/PostHog/posthog-android/pull/86))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
Expand Down Expand Up @@ -248,7 +250,7 @@ public class PostHogReplayIntegration(
val wireframe = view.toWireframe() ?: return

// if the decorView has no backgroundColor, we use the theme color
if (wireframe.style?.backgroundColor == null || wireframe.style?.backgroundColor == "#ffffff") {
if (wireframe.style?.backgroundColor == null) {
context.theme?.toRGBColor()?.let {
wireframe.style?.backgroundColor = it
}
Expand Down Expand Up @@ -341,8 +343,13 @@ public class PostHogReplayIntegration(
if (view is ViewStub) {
return null
}
if (view.id == android.R.id.statusBarBackground || view.id == android.R.id.navigationBarBackground) {
return null

var type: String? = null
if (view.id == android.R.id.statusBarBackground) {
type = "status_bar"
}
if (view.id == android.R.id.navigationBarBackground) {
type = "navigation_bar"
}

val coordinates = IntArray(2)
Expand All @@ -359,14 +366,13 @@ public class PostHogReplayIntegration(
background.toRGBColor()?.let { color ->
style.backgroundColor = color
} ?: run {
style.backgroundColor = "#ffffff"
style.backgroundImage = background.base64(view.width, view.height)
}
}

var checked: Boolean? = null

var text: String? = null
var type: String? = null
var inputType: String? = null
var value: Any? = null
// button inherits from textview
Expand Down Expand Up @@ -514,7 +520,7 @@ public class PostHogReplayIntegration(
type = "image"
if (!view.isNoCapture(config.sessionReplayConfig.maskAllImages)) {
// TODO: we can probably do a LRU caching here for already captured images
base64 = view.drawable?.base64()
base64 = view.drawable?.base64(view.width, view.height)
}
}

Expand Down Expand Up @@ -616,7 +622,9 @@ public class PostHogReplayIntegration(
}
}
color?.let {
return it.defaultColor.toRGBColor()
if (it.defaultColor != -1) {
return it.defaultColor.toRGBColor()
}
}
}
return null
Expand All @@ -628,31 +636,44 @@ public class PostHogReplayIntegration(
this.height > 0
}

private fun Drawable.base64(): String? {
private fun Bitmap.base64(): String? {
if (!isValid()) {
return null
}

ByteArrayOutputStream(allocationByteCount).use {
compress(Bitmap.CompressFormat.PNG, 30, it)
val byteArray = it.toByteArray()
return Base64.encodeToString(byteArray, Base64.DEFAULT)
}
}

private fun Drawable.base64(width: Int, height: Int): String? {
when (this) {
is BitmapDrawable -> {
if (!bitmap.isValid()) {
return null
}

ByteArrayOutputStream(bitmap.allocationByteCount).use {
bitmap.compress(Bitmap.CompressFormat.PNG, 30, it)
val byteArray = it.toByteArray()
return Base64.encodeToString(byteArray, Base64.DEFAULT)
try {
return bitmap.base64()
} catch (_: Throwable) {
// ignore
}
}

is LayerDrawable -> {
return getFirstDrawable()?.base64()
return getFirstDrawable()?.base64(width, height)
}

is InsetDrawable -> {
drawable?.let {
return it.base64()
return it.base64(width, height)
}
}
}
// TODO: vector, gradient drawables

try {
return toBitmap(width, height).base64()
} catch (_: Throwable) {
// ignore
}
return null
}

Expand Down Expand Up @@ -722,6 +743,15 @@ public class PostHogReplayIntegration(
return Triple(addedItems, removedItems, updatedItems)
}

private fun Drawable.toBitmap(width: Int, height: Int): Bitmap {
val bitmap = Bitmap.createBitmap(displayMetrics, width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY)
setBounds(0, 0, canvas.width, canvas.height)
draw(canvas)
return bitmap
}

private fun MotionEvent.getRawXCompat(index: Int): Float {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
getRawX(index)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class MyApp : Application() {
// remove("\$device_name")
}
}
sessionReplayConfig.maskAllTextInputs = true
sessionReplayConfig.maskAllTextInputs = false
sessionReplayConfig.maskAllImages = false
sessionReplayConfig.captureLogcat = true
}
PostHogAndroid.setup(this, config)
Expand Down
23 changes: 13 additions & 10 deletions posthog/api/posthog.api
Original file line number Diff line number Diff line change
Expand Up @@ -464,26 +464,28 @@ public final class com/posthog/internal/replay/RRRemovedNode {

public final class com/posthog/internal/replay/RRStyle {
public fun <init> ()V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String;
public final fun component10 ()Ljava/lang/Integer;
public final fun component10 ()Ljava/lang/String;
public final fun component11 ()Ljava/lang/Integer;
public final fun component12 ()Ljava/lang/Integer;
public final fun component13 ()Ljava/lang/Integer;
public final fun component14 ()Ljava/lang/String;
public final fun component14 ()Ljava/lang/Integer;
public final fun component15 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/lang/Integer;
public final fun component3 ()Ljava/lang/String;
public final fun component4 ()Ljava/lang/Integer;
public final fun component5 ()Ljava/lang/String;
public final fun component6 ()Ljava/lang/Integer;
public final fun component7 ()Ljava/lang/String;
public final fun component5 ()Ljava/lang/Integer;
public final fun component6 ()Ljava/lang/String;
public final fun component7 ()Ljava/lang/Integer;
public final fun component8 ()Ljava/lang/String;
public final fun component9 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)Lcom/posthog/internal/replay/RRStyle;
public static synthetic fun copy$default (Lcom/posthog/internal/replay/RRStyle;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;ILjava/lang/Object;)Lcom/posthog/internal/replay/RRStyle;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)Lcom/posthog/internal/replay/RRStyle;
public static synthetic fun copy$default (Lcom/posthog/internal/replay/RRStyle;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;ILjava/lang/Object;)Lcom/posthog/internal/replay/RRStyle;
public fun equals (Ljava/lang/Object;)Z
public final fun getBackgroundColor ()Ljava/lang/String;
public final fun getBackgroundImage ()Ljava/lang/String;
public final fun getBar ()Ljava/lang/String;
public final fun getBorderColor ()Ljava/lang/String;
public final fun getBorderRadius ()Ljava/lang/Integer;
Expand All @@ -499,6 +501,7 @@ public final class com/posthog/internal/replay/RRStyle {
public final fun getVerticalAlign ()Ljava/lang/String;
public fun hashCode ()I
public final fun setBackgroundColor (Ljava/lang/String;)V
public final fun setBackgroundImage (Ljava/lang/String;)V
public final fun setBar (Ljava/lang/String;)V
public final fun setBorderColor (Ljava/lang/String;)V
public final fun setBorderRadius (Ljava/lang/Integer;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.posthog.PostHogInternal
public data class RRStyle(
public var color: String? = null,
public var backgroundColor: String? = null,
public var backgroundImage: String? = null,
public var borderWidth: Int? = null,
public var borderRadius: Int? = null,
public var borderColor: String? = null,
Expand Down

0 comments on commit 238ade4

Please sign in to comment.