Skip to content
Open
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: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

playImplementation "com.namiml:sdk-android:3.3.5.2"
amazonImplementation "com.namiml:sdk-amazon:3.3.5.2"
playImplementation "com.namiml:sdk-android:3.3.5.3"
amazonImplementation "com.namiml:sdk-amazon:3.3.5.3"

implementation "com.facebook.react:react-native:+" // From node_modules
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class NamiCampaignManagerBridgeModule internal constructor(
private val reactContext: ReactApplicationContext,
) : ReactContextBaseJavaModule(reactContext),
TurboModule {

// Capture the context early to avoid bridge destruction issues
private val capturedContext = reactContext
companion object {
const val NAME = "RNNamiCampaignManager"
const val CAMPAIGN_ID = "campaignId"
Expand Down Expand Up @@ -268,13 +271,22 @@ class NamiCampaignManagerBridgeModule internal constructor(

private fun emitEvent(
event: String,
map: WritableMap,
payload: Any?,
) {
val emitter = reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
if (emitter is DeviceEventManagerModule.RCTDeviceEventEmitter) {
emitter.emit(event, map)
} else {
Log.w(NAME, "Cannot emit $event event: RCTDeviceEventEmitter instance is null")
try {
// Check if the bridge is still active
if (capturedContext.hasActiveCatalystInstance()) {
val emitter = capturedContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
if (emitter is DeviceEventManagerModule.RCTDeviceEventEmitter) {
emitter.emit(event, payload)
} else {
Log.w(NAME, "Cannot emit $event event: RCTDeviceEventEmitter instance is null")
}
} else {
Log.w(NAME, "Cannot emit $event event: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
Log.w(NAME, "Error emitting $event event: ${e.message}")
}
}

Expand Down Expand Up @@ -390,9 +402,7 @@ class NamiCampaignManagerBridgeModule internal constructor(
availableCampaigns.forEach { campaign ->
array.pushMap(campaignToReadableMap(campaign))
}
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("AvailableCampaignsChanged", array)
emitEvent("AvailableCampaignsChanged", array)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class NamiCustomerManagerBridgeModule internal constructor(
private val reactContext: ReactApplicationContext
) : ReactContextBaseJavaModule(reactContext), TurboModule {

// Capture the context early to avoid bridge destruction issues
private val capturedContext = reactContext

companion object {
const val NAME = "RNNamiCustomerManager"
}
Expand Down Expand Up @@ -117,9 +120,17 @@ class NamiCustomerManagerBridgeModule internal constructor(
fun registerJourneyStateHandler() {
NamiCustomerManager.registerJourneyStateHandler { journeyState ->
val handledJourneyState = journeyStateToReadableMap(journeyState)
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("JourneyStateChanged", handledJourneyState)
try {
if (capturedContext.hasActiveCatalystInstance()) {
capturedContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit("JourneyStateChanged", handledJourneyState)
} else {
android.util.Log.w(NAME, "Cannot emit JourneyStateChanged: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
android.util.Log.w(NAME, "Error emitting JourneyStateChanged event: ${e.message}")
}
}
}

Expand All @@ -130,9 +141,17 @@ class NamiCustomerManagerBridgeModule internal constructor(
body.putString("action", action.toString())
body.putBoolean("success", success)
body.putString("error", error.toString())
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("AccountStateChanged", body)
try {
if (capturedContext.hasActiveCatalystInstance()) {
capturedContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit("AccountStateChanged", body)
} else {
android.util.Log.w(NAME, "Cannot emit AccountStateChanged: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
android.util.Log.w(NAME, "Error emitting AccountStateChanged event: ${e.message}")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class NamiEntitlementManagerBridgeModule internal constructor(
reactContext: ReactApplicationContext
) : ReactContextBaseJavaModule(reactContext), TurboModule {

// Capture the context early to avoid bridge destruction issues
private val capturedContext = reactContext

companion object {
const val NAME = "RNNamiEntitlementManager"
}
Expand Down Expand Up @@ -48,9 +51,17 @@ class NamiEntitlementManagerBridgeModule internal constructor(
}
}
}
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("EntitlementsChanged", resultArray)
try {
if (capturedContext.hasActiveCatalystInstance()) {
capturedContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit("EntitlementsChanged", resultArray)
} else {
android.util.Log.w(NAME, "Cannot emit EntitlementsChanged: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
android.util.Log.w(NAME, "Error emitting EntitlementsChanged event: ${e.message}")
}
}
}

Expand All @@ -63,9 +74,17 @@ class NamiEntitlementManagerBridgeModule internal constructor(
resultArray.pushMap(entitlementDict)
}
}
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("EntitlementsChanged", resultArray)
try {
if (capturedContext.hasActiveCatalystInstance()) {
capturedContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit("EntitlementsChanged", resultArray)
} else {
android.util.Log.w(NAME, "Cannot emit EntitlementsChanged: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
android.util.Log.w(NAME, "Error emitting EntitlementsChanged event: ${e.message}")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class NamiFlowManagerBridgeModule internal constructor(
reactContext: ReactApplicationContext,
) : ReactContextBaseJavaModule(reactContext),
TurboModule {

// Capture the context early to avoid bridge destruction issues
private val capturedContext = reactContext
companion object {
const val NAME = "RNNamiFlowManager"
}
Expand Down Expand Up @@ -83,9 +86,17 @@ class NamiFlowManagerBridgeModule internal constructor(
eventName: String,
params: WritableMap?,
) {
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(eventName, params)
try {
if (capturedContext.hasActiveCatalystInstance()) {
capturedContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit(eventName, params)
} else {
Log.w(NAME, "Cannot emit $eventName: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
Log.w(NAME, "Error emitting $eventName event: ${e.message}")
}
}

// Required for RN EventEmitter support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import com.facebook.react.bridge.UiThreadUtil
class NamiOverlayControlBridgeModule(private val ctx: ReactApplicationContext)
: ReactContextBaseJavaModule(ctx), TurboModule {

// Capture the context early to avoid bridge destruction issues
private val capturedContext = ctx

companion object {
const val NAME = "RNNamiOverlayControl"
var currentOverlayActivity: ReactOverlayActivity? = null
Expand Down Expand Up @@ -97,9 +100,11 @@ class NamiOverlayControlBridgeModule(private val ctx: ReactApplicationContext)
// Emit ready event after a short delay to ensure activity is started
android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
try {
if (ctx.catalystInstance != null) {
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("NamiOverlayReady", null)
if (capturedContext.hasActiveCatalystInstance()) {
capturedContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit("NamiOverlayReady", null)
} else {
Log.w(NAME, "Cannot emit NamiOverlayReady: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
Log.e(NAME, "Failed to emit NamiOverlayReady: ${e.message}")
Expand Down Expand Up @@ -142,9 +147,11 @@ class NamiOverlayControlBridgeModule(private val ctx: ReactApplicationContext)
}
}
try {
if (ctx.catalystInstance != null) {
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("NamiOverlayResult", payload)
if (capturedContext.hasActiveCatalystInstance()) {
capturedContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit("NamiOverlayResult", payload)
} else {
Log.w(NAME, "Cannot emit NamiOverlayResult: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
Log.e(NAME, "Failed to emit NamiOverlayResult: ${e.message}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ class NamiPaywallManagerBridgeModule internal constructor(
reactContext: ReactApplicationContext
) : ReactContextBaseJavaModule(reactContext), TurboModule {

// Capture the context early to avoid bridge destruction issues
private val capturedContext = reactContext

companion object {
const val NAME = "RNNamiPaywallManager"
}
Expand Down Expand Up @@ -191,7 +194,16 @@ class NamiPaywallManagerBridgeModule internal constructor(
@ReactMethod fun removeListeners(count: Int?) {}

private fun emitEvent(name: String, payload: Any?) {
val emitter = reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
emitter.emit(name, payload)
try {
// Check if the bridge is still active
if (capturedContext.hasActiveCatalystInstance()) {
val emitter = capturedContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
emitter?.emit(name, payload)
} else {
Log.w(NAME, "Cannot emit $name event: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
Log.w(NAME, "Error emitting $name event: ${e.message}")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class NamiPurchaseManagerBridgeModule internal constructor(
private val reactContext: ReactApplicationContext
) : ReactContextBaseJavaModule(reactContext), TurboModule {

// Capture the context early to avoid bridge destruction issues
private val capturedContext = reactContext

companion object {
const val NAME = "RNNamiPurchaseManager"
}
Expand Down Expand Up @@ -97,9 +100,17 @@ class NamiPurchaseManagerBridgeModule internal constructor(
}

private fun emitEvent(eventName: String, payload: WritableMap) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(eventName, payload)
try {
if (capturedContext.hasActiveCatalystInstance()) {
capturedContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit(eventName, payload)
} else {
Log.w(NAME, "Cannot emit $eventName: Bridge has been destroyed or is inactive")
}
} catch (e: Exception) {
Log.w(NAME, "Error emitting $eventName event: ${e.message}")
}
}

@ReactMethod fun addListener(eventName: String?) {}
Expand Down
2 changes: 1 addition & 1 deletion dist/src/version.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
* Auto-generated file. Do not edit manually.
* React Native Nami SDK version.
*/
export declare const NAMI_REACT_NATIVE_VERSION = "3.3.5-2";
export declare const NAMI_REACT_NATIVE_VERSION = "3.3.5-3";
2 changes: 1 addition & 1 deletion examples/Basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"react-native-base64": "^0.2.1",
"react-native-iap": "12.16.0",
"react-native-logs": "^5.1.0",
"react-native-nami-sdk": "file:../../react-native-nami-sdk-3.3.5-2.tgz",
"react-native-nami-sdk": "file:../../react-native-nami-sdk-3.3.5-3.tgz",
"react-native-permissions": "^5.4.1",
"react-native-reanimated": "3.18.0",
"react-native-safe-area-context": "^4.10.7",
Expand Down
10 changes: 5 additions & 5 deletions examples/TestNamiTV/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ react {

/* Bundling */
// A list containing the node command and its flags. Default is just 'node'.
nodeExecutableAndArgs = [nodeExecutable]
nodeExecutableAndArgs = ['/Users/dannami/.nvm/versions/node/v21.7.3/bin/node']
//
// The command to run when bundling. By default is 'bundle'
// bundleCommand = "ram-bundle"
Expand Down Expand Up @@ -122,10 +122,10 @@ android {
keyPassword 'android'
}
release {
storeFile file('release.keystore')
storePassword 'android'
keyAlias 'androidreleasekey'
keyPassword 'android'
storeFile file('/Users/dannami/Nami/SigningKeys/GooglePlay/release.keystore')
storePassword 'kyFYiLg7QVe78QaEg'
keyAlias 'namirelease'
keyPassword 'kyFYiLg7QVe78QaEg'
}
}
buildTypes {
Expand Down
8 changes: 8 additions & 0 deletions examples/TestNamiTV/config/getInitialConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@ import initAppleStageConfig from '../nami_initial_config_apple_stg.json';
import initAndroidStageConfig from '../nami_initial_config_android_stg.json';
import initAppleProductionConfig from '../nami_initial_config_apple_prod.json';
import initAndroidProductionConfig from '../nami_initial_config_android_prod.json';
import initAmazonProductionConfig from '../nami_initial_config_amazon_prod.json';
import initAmazonStageConfig from '../nami_initial_config_amazon_stg.json';

export const getInitialConfig = () => {
const flavor = NativeModules.RNConfig.FLAVOR;

switch (Platform.OS) {
case 'amazon':
return JSON.stringify(
flavor === 'production'
? initAmazonProductionConfig
: initAmazonStageConfig,
);
case 'android':
return JSON.stringify(
flavor === 'production'
Expand Down
5 changes: 3 additions & 2 deletions examples/TestNamiTV/containers/SignInScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import { View, Text, Button, StyleSheet } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { NamiCustomerManager } from 'react-native-nami-sdk';
import { v4 as uuidv4 } from 'uuid';

Check failure on line 6 in examples/TestNamiTV/containers/SignInScreen.tsx

View workflow job for this annotation

GitHub Actions / ESLint

'uuidv4' is defined but never used

export const SignInScreen = () => {
const navigation = useNavigation();

const handleLogin = () => {
const randomUUID = uuidv4();
NamiCustomerManager.login(randomUUID);
//const randomUUID = uuidv4();
//NamiCustomerManager.login(randomUUID);
NamiCustomerManager.setCustomerAttribute('currentSubscriber', 'true');
navigation.goBack();
};

Expand Down
Empty file.
1 change: 1 addition & 0 deletions examples/TestNamiTV/nami_initial_config_amazon_stg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions examples/TestNamiTV/services/purchase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export async function handlePurchaseUpdate(
storeType: 'Amazon',
});
} else {
NamiCustomerManager.setCustomerAttribute('currentSubscriber', 'true');
NamiPaywallManager.buySkuComplete({
product: sku,
purchaseToken: purchase.purchaseToken ?? '',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-nami-sdk",
"version": "3.3.5-2",
"version": "3.3.5-3",
"description": "React Native SDK for Nami - No-code paywall and onboarding flows with A/B testing.",
"main": "index.ts",
"types": "dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
* Auto-generated file. Do not edit manually.
* React Native Nami SDK version.
*/
export const NAMI_REACT_NATIVE_VERSION = '3.3.5-2';
export const NAMI_REACT_NATIVE_VERSION = '3.3.5-3';
Loading