Skip to content

Commit 36c40c6

Browse files
committed
feat: New architecture support
1 parent e669cd0 commit 36c40c6

File tree

13 files changed

+1303
-1138
lines changed

13 files changed

+1303
-1138
lines changed

android/build.gradle

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,16 @@ def supportsNamespace() {
4444
apply plugin: 'org.jlleitschuh.gradle.ktlint'
4545
apply plugin: 'com.android.library'
4646
apply plugin: 'kotlin-android'
47-
//if (isNewArchitectureEnabled()) {
48-
// apply plugin: 'com.facebook.react'
49-
//}
47+
if (isNewArchitectureEnabled()) {
48+
apply plugin: 'com.facebook.react'
49+
}
5050

5151
android {
5252
if (supportsNamespace()) {
5353
namespace 'com.mparticle.react'
54-
buildFeatures.buildConfig = true
54+
buildFeatures {
55+
buildConfig = true
56+
}
5557
sourceSets {
5658
main {
5759
manifest.srcFile "src/main/AndroidManifestNew.xml"
@@ -65,15 +67,15 @@ android {
6567
targetSdkVersion 33
6668
versionCode 2
6769
versionName "2.0.0"
68-
//buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
70+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
6971
}
7072
sourceSets {
7173
main {
72-
//if (isNewArchitectureEnabled()) {
73-
// java.srcDirs += ['src/newarch/java']
74-
//} else {
74+
if (isNewArchitectureEnabled()) {
75+
java.srcDirs += ['src/newarch/java']
76+
} else {
7577
java.srcDirs += ['src/oldarch/java']
76-
//}
78+
}
7779
}
7880
}
7981

android/gradle.properties

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,32 +24,3 @@ android.useAndroidX=true
2424

2525
# Automatically convert third-party libraries to use AndroidX
2626
android.enableJetifier=true
27-
28-
# Version of flipper SDK to use with React Native
29-
FLIPPER_VERSION=0.125.0
30-
31-
# Use this property to specify which architecture you want to build.
32-
# You can also override it from the CLI using
33-
# ./gradlew <task> -PreactNativeArchitectures=x86_64
34-
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
35-
36-
# Use this property to enable support to the new architecture.
37-
# This will allow you to use TurboModules and the Fabric render in
38-
# your application. You should enable this flag either if you want
39-
# to write custom TurboModules/Fabric components OR use libraries that
40-
# are providing them.
41-
newArchEnabled=false
42-
43-
# The hosted JavaScript engine
44-
# Supported values: expo.jsEngine = "hermes" | "jsc"
45-
expo.jsEngine=jsc
46-
47-
# Enable GIF support in React Native images (~200 B increase)
48-
expo.gif.enabled=true
49-
# Enable webp support in React Native images (~85 KB increase)
50-
expo.webp.enabled=true
51-
# Enable animated webp support (~3.4 MB increase)
52-
# Disabled by default because iOS doesn't support animated webp
53-
expo.webp.animated=false
54-
55-
sonar.gradle.skipCompile=true

android/src/main/java/com/mparticle/react/MParticleModule.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ public void setUploadInterval(int uploadInterval) {
7777

7878
@ReactMethod
7979
public void setLocation(double latitude, double longitude) {
80-
Location newLocation = new Location("");
80+
Location newLocation = new Location("");
8181
newLocation.setLatitude(latitude);
8282
newLocation.setLongitude(longitude);
8383
MParticle.getInstance().setLocation(newLocation);
84-
84+
8585
}
8686

8787
@ReactMethod
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.mparticle.react.rokt
2+
3+
import com.facebook.react.bridge.ReactApplicationContext
4+
import com.facebook.react.bridge.ReactContextBaseJavaModule
5+
import com.facebook.react.bridge.ReactMethod
6+
import com.facebook.react.bridge.ReadableMap
7+
import com.facebook.react.bridge.ReadableType
8+
import com.facebook.react.bridge.UiThreadUtil
9+
import com.facebook.react.uimanager.NativeViewHierarchyManager
10+
import com.facebook.react.uimanager.UIManagerHelper
11+
import com.facebook.react.uimanager.UIManagerModule
12+
import com.mparticle.MParticle
13+
import com.mparticle.WrapperSdk
14+
import com.mparticle.react.NativeMPRoktSpec
15+
import com.mparticle.rokt.RoktEmbeddedView
16+
import java.lang.ref.WeakReference
17+
import java.util.concurrent.CountDownLatch
18+
19+
class MPRoktModule(
20+
private val reactContext: ReactApplicationContext,
21+
) : NativeMPRoktSpec(reactContext) {
22+
init {
23+
MParticle.getInstance()?.setWrapperSdk(WrapperSdk.WrapperSdkReactNative, "")
24+
}
25+
26+
private val impl = MPRoktModuleImpl(reactContext)
27+
28+
override fun getName(): String = impl.getName()
29+
30+
@ReactMethod
31+
override fun selectPlacements(
32+
identifier: String,
33+
attributes: ReadableMap?,
34+
placeholders: ReadableMap?,
35+
roktConfig: ReadableMap?,
36+
fontFilesMap: ReadableMap?,
37+
) {
38+
if (identifier.isBlank()) {
39+
impl.logDebug("selectPlacements failed. identifier cannot be empty")
40+
return
41+
}
42+
MParticle.getInstance()?.Rokt()?.events(identifier)?.let {
43+
impl.startRoktEventListener(it, reactContext.currentActivity, identifier)
44+
}
45+
46+
// Process placeholders for Fabric
47+
val placeholdersMap = processPlaceholders(placeholders)
48+
val config = roktConfig?.let { impl.buildRoktConfig(it) }
49+
50+
MParticle.getInstance()?.Rokt()?.selectPlacements(
51+
identifier = identifier,
52+
attributes = impl.readableMapToMapOfStrings(attributes),
53+
callbacks = impl.createRoktCallback(),
54+
embeddedViews = placeholdersMap,
55+
fontTypefaces = null, // TODO
56+
config = config,
57+
)
58+
}
59+
60+
61+
/**
62+
* Process placeholders from ReadableMap to a map of Widgets for use with Rokt.
63+
* This method handles the Fabric-specific view resolution.
64+
*/
65+
private fun processPlaceholders(placeholders: ReadableMap?): Map<String, WeakReference<RoktEmbeddedView>> {
66+
val placeholdersMap = HashMap<String, WeakReference<RoktEmbeddedView>>()
67+
68+
if (placeholders != null) {
69+
// Use CountDownLatch to wait for UI thread processing
70+
val latch = CountDownLatch(1)
71+
72+
// Run view resolution on UI thread
73+
UiThreadUtil.runOnUiThread {
74+
try {
75+
val iterator = placeholders.keySetIterator()
76+
while (iterator.hasNextKey()) {
77+
val key = iterator.nextKey()
78+
try {
79+
// Get the tag value as an integer
80+
val reactTag =
81+
when {
82+
placeholders.getType(key) == ReadableType.Number ->
83+
placeholders.getDouble(key).toInt()
84+
85+
else -> {
86+
impl.logDebug("Invalid view tag for key: $key")
87+
continue
88+
}
89+
}
90+
91+
// Get the UIManager for this specific tag
92+
val uiManager =
93+
UIManagerHelper.getUIManagerForReactTag(reactContext, reactTag)
94+
if (uiManager == null) {
95+
impl.logDebug("UIManager not found for tag: $reactTag")
96+
continue
97+
}
98+
99+
// Resolve the view using the manager (now on UI thread)
100+
val view = uiManager.resolveView(reactTag)
101+
if (view is RoktEmbeddedView) {
102+
placeholdersMap[key] = WeakReference(view)
103+
impl.logDebug("Successfully found Widget for key: $key with tag: $reactTag")
104+
} else {
105+
impl.logDebug("View with tag $reactTag is not a Widget: ${view?.javaClass?.simpleName}")
106+
}
107+
} catch (e: Exception) {
108+
impl.logDebug("Error processing placeholder for key $key: ${e.message}")
109+
e.printStackTrace()
110+
}
111+
}
112+
} finally {
113+
latch.countDown()
114+
}
115+
}
116+
117+
try {
118+
// Wait for UI thread to finish processing
119+
latch.await()
120+
} catch (e: InterruptedException) {
121+
impl.logDebug("Interrupted while waiting for UI thread: ${e.message}")
122+
}
123+
}
124+
125+
return placeholdersMap
126+
}
127+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.mparticle.react.rokt
2+
3+
import com.facebook.react.common.MapBuilder
4+
import com.facebook.react.uimanager.SimpleViewManager
5+
import com.facebook.react.uimanager.ThemedReactContext
6+
import com.facebook.react.uimanager.ViewGroupManager
7+
import com.mparticle.rokt.RoktEmbeddedView
8+
9+
class RoktLayoutViewManager : SimpleViewManager<RoktEmbeddedView>() {
10+
private val impl = RoktLayoutViewManagerImpl()
11+
12+
override fun getName(): String = impl.getName()
13+
14+
override fun createViewInstance(reactContext: ThemedReactContext): RoktEmbeddedView = impl.createViewInstance(reactContext)
15+
16+
override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any>? =
17+
MapBuilder
18+
.builder<String, Any>()
19+
.put(
20+
RoktLayoutViewManagerImpl.EVENT_HEIGHT_CHANGED,
21+
MapBuilder.of("registrationName", RoktLayoutViewManagerImpl.EVENT_HEIGHT_CHANGED),
22+
).put(
23+
RoktLayoutViewManagerImpl.EVENT_MARGIN_CHANGED,
24+
MapBuilder.of("registrationName", RoktLayoutViewManagerImpl.EVENT_MARGIN_CHANGED),
25+
).build()
26+
27+
//override fun needsCustomLayoutForChildren(): Boolean = false
28+
29+
fun setPlaceholderName(
30+
view: RoktEmbeddedView?,
31+
value: String?,
32+
) {
33+
impl.setPlaceholderName(view, value)
34+
}
35+
}

0 commit comments

Comments
 (0)