Skip to content

Commit

Permalink
Support for NamiWindow and dependency update (#209)
Browse files Browse the repository at this point in the history
* add ios uiwindow and supporting features
* update android dependency to 3.0.22
* update deeplink handler
* 3.0.23 apple bump
  • Loading branch information
namidan authored Jul 11, 2023
1 parent 797b5e3 commit ecd3bdc
Show file tree
Hide file tree
Showing 15 changed files with 185 additions and 63 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

implementation 'com.github.jeziellago:compose-markdown:0.3.0'
implementation "com.namiml:sdk-android:3.0.21"
implementation "com.namiml:sdk-android:3.0.22"

implementation 'com.facebook.react:react-native:+' // From node_modules
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class NamiBridgeModule(reactContext: ReactApplicationContext) :
} else {
Arguments.createArray()
}
val settingsList = mutableListOf("extendedClientInfo:react-native:3.0.17")
val settingsList = mutableListOf("extendedClientInfo:react-native:3.0.18")
namiCommandsReact?.toArrayList()?.filterIsInstance<String>()?.let { commandsFromReact ->
settingsList.addAll(commandsFromReact)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,29 @@ class NamiPaywallManagerBridgeModule(reactContext: ReactApplicationContext) :
}
}

@ReactMethod
fun registerSignInHandler() {
NamiPaywallManager.registerSignInHandler { activity ->
latestPaywallActivity = activity
val map = Arguments.createMap().apply {
putBoolean("paywallSignInRequested", true)
}
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("PaywallSignInRequested", map)
}
}

@ReactMethod
fun show() {
// Do nothing on Android side
}

@ReactMethod
fun hide() {
// Do nothing on Android side
}

@ReactMethod
fun addListener(eventName: String?) {
}
Expand Down
32 changes: 29 additions & 3 deletions examples/Basic/containers/CampaignScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import React, {
useLayoutEffect,
useState,
} from 'react';
import {NamiCampaign, NamiCampaignManager} from 'react-native-nami-sdk';
import {
NamiCampaign,
NamiCampaignManager,
NamiPaywallManager,
} from 'react-native-nami-sdk';
import {NamiPaywallAction} from 'react-native-nami-sdk/src/NamiPaywallManager';
import {
FlatList,
Expand All @@ -29,6 +33,15 @@ const HeaderRight = ({onRefreshPress}: {onRefreshPress: () => void}) => (
</TouchableOpacity>
);

// For Nami testing purposes only
const HeaderLeft = ({onButtonPress}: {onButtonPress: () => void}) => (
<TouchableOpacity style={styles.headerButton} onPress={onButtonPress}>
<Text testID="show_paywall_button" style={styles.headerButtonText}>
Show Paywall
</Text>
</TouchableOpacity>
);

const CampaignScreen: FC<CampaignScreenProps> = ({navigation}) => {
const [campaigns, setCampaigns] = useState<NamiCampaign[]>([]);
const [refresh, setRefresh] = useState<boolean>(false);
Expand All @@ -48,6 +61,12 @@ const CampaignScreen: FC<CampaignScreenProps> = ({navigation}) => {

useEffect(() => {
getAllCampaigns();
const subscriptionSignInRemover = NamiPaywallManager.registerSignInHandler(
() => {
console.log('sign in');
NamiPaywallManager.hide();
},
);
const subscriptionRemover =
NamiCampaignManager.registerAvailableCampaignsHandler(
(availableCampaigns) => {
Expand All @@ -60,6 +79,7 @@ const CampaignScreen: FC<CampaignScreenProps> = ({navigation}) => {
);
return () => {
subscriptionRemover();
subscriptionSignInRemover();
};
//Note: not needed in depts
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -103,9 +123,10 @@ const CampaignScreen: FC<CampaignScreenProps> = ({navigation}) => {
console.log('campaignName', campaignName);
console.log('campaignType', campaignType);
console.log('campaignUrl', campaignUrl);
console.log('paywallId', paywallId);
console.log('paywallName', paywallName);
console.log('segmentId', segmentId);
console.log('externalSegmentId', externalSegmentId);
console.log('paywallName', paywallName);
console.log('deeplinkUrl', deeplinkUrl);
},
);
Expand Down Expand Up @@ -135,11 +156,16 @@ const CampaignScreen: FC<CampaignScreenProps> = ({navigation}) => {
NamiCampaignManager.refresh();
}, []);

const onButtonPress = useCallback(() => {
NamiPaywallManager.show();
}, []);

useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => <HeaderRight onRefreshPress={onRefreshPress} />,
headerLeft: () => <HeaderLeft onButtonPress={onButtonPress} />,
});
}, [navigation, onRefreshPress]);
}, [navigation, onRefreshPress, onButtonPress]);

const renderItem = ({item, index}: {item: NamiCampaign; index: number}) => {
const lasItem = index === campaigns.length - 1;
Expand Down
2 changes: 0 additions & 2 deletions examples/Basic/containers/ProfileScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ const ProfileScreen: FC<ProfileScreenProps> = ({navigation}) => {
const [displayedDeviceId, setDisplayedDeviceId] = useState<string>('');

const onLoginPress = useCallback(() => {
// b909a31c-7a73-11ed-a1eb-0242ac120002
// f1851c87-e0ff-4349-a824-cd9b5e5211b9
NamiCustomerManager.login('E97EDA7D-F1BC-48E1-8DF4-F67EF4A4E4FF');
}, []);

Expand Down
14 changes: 14 additions & 0 deletions examples/Basic/services/deeplinking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,28 @@ export async function handleDeepLink(event) {
campaignId,
campaignLabel,
paywallId,
campaignName,
campaignType,
campaignUrl,
segmentId,
externalSegmentId,
paywallName,
deeplinkUrl,
) => {
console.log('action', action);
console.log('skuId', skuId);
console.log('purchaseError', purchaseError);
console.log('purchases', purchases);
console.log('campaignId', campaignId);
console.log('campaignLabel', campaignLabel);
console.log('campaignName', campaignName);
console.log('campaignType', campaignType);
console.log('campaignUrl', campaignUrl);
console.log('paywallId', paywallId);
console.log('paywallName', paywallName);
console.log('segmentId', segmentId);
console.log('externalSegmentId', externalSegmentId);
console.log('deeplinkUrl', deeplinkUrl);
},
);
}
Expand Down
14 changes: 14 additions & 0 deletions examples/TestNamiTV/services/deeplinking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,28 @@ export async function handleDeepLink(event) {
campaignId,
campaignLabel,
paywallId,
campaignName,
campaignType,
campaignUrl,
segmentId,
externalSegmentId,
paywallName,
deeplinkUrl,
) => {
console.log('action', action);
console.log('skuId', skuId);
console.log('purchaseError', purchaseError);
console.log('purchases', purchases);
console.log('campaignId', campaignId);
console.log('campaignLabel', campaignLabel);
console.log('campaignName', campaignName);
console.log('campaignType', campaignType);
console.log('campaignUrl', campaignUrl);
console.log('paywallId', paywallId);
console.log('paywallName', paywallName);
console.log('segmentId', segmentId);
console.log('externalSegmentId', externalSegmentId);
console.log('deeplinkUrl', deeplinkUrl);
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion ios/Nami.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ @implementation NamiBridge (RCTExternModule)
}

// Start commands with header iformation for Nami to let them know this is a React client.
NSMutableArray *namiCommandStrings = [NSMutableArray arrayWithArray:@[@"extendedClientInfo:react-native:3.0.17"]];
NSMutableArray *namiCommandStrings = [NSMutableArray arrayWithArray:@[@"extendedClientInfo:react-native:3.0.18"]];

// Add additional namiCommands app may have sent in.
NSObject *appCommandStrings = configDict[@"namiCommands"];
Expand Down
100 changes: 50 additions & 50 deletions ios/NamiCampaignManagerBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import Foundation
import NamiApple
import React
import os
import React

@objc(RNNamiCampaignManager)
class RNNamiCampaignManager: RCTEventEmitter {
Expand Down Expand Up @@ -94,22 +94,22 @@ class RNNamiCampaignManager: RCTEventEmitter {

let dictionaries = purchases.map { purchase in RNNamiPurchaseManager.purchaseToPurchaseDict(purchase) }

let payload: [String: Any?] = [
"campaignId": campaignId,
"campaignName": campaignName,
"campaignType": campaignType,
"campaignLabel": campaignLabel,
"campaignUrl": campaignUrl,
"paywallId": paywallId,
"paywallName": paywallName,
"segmentId": segmentId,
"externalSegmentId": externalSegmentId,
"action": actionString,
"skuId": skuId,
"purchaseError": errorSting,
"purchases": dictionaries,
"deeplinkUrl": deeplinkUrl,
]
let payload: [String: Any?] = [
"campaignId": campaignId,
"campaignName": campaignName,
"campaignType": campaignType,
"campaignLabel": campaignLabel,
"campaignUrl": campaignUrl,
"paywallId": paywallId,
"paywallName": paywallName,
"segmentId": segmentId,
"externalSegmentId": externalSegmentId,
"action": actionString,
"skuId": skuId,
"purchaseError": errorSting,
"purchases": dictionaries,
"deeplinkUrl": deeplinkUrl,
]

RNNamiCampaignManager.shared?.sendEvent(withName: "ResultCampaign", body: payload)
}
Expand All @@ -124,7 +124,7 @@ class RNNamiCampaignManager: RCTEventEmitter {
withUrl: String?,
context: NSDictionary?,
callback: @escaping RCTResponseSenderBlock,
paywallCallback: @escaping RCTResponseSenderBlock
paywallCallback _: @escaping RCTResponseSenderBlock
) {
var paywallLaunchContext: PaywallLaunchContext?

Expand All @@ -149,45 +149,45 @@ class RNNamiCampaignManager: RCTEventEmitter {
if let urlString = withUrl, let urlObject = URL(string: urlString) {
launchMethod = {
NamiCampaignManager.launch(url: urlObject, context: paywallLaunchContext,
launchHandler: { (success, error) in
self.handleLaunch(
callback: callback,
success: success,
error: error)
},
paywallActionHandler: { (campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl) in
self.handlePaywallAction(campaignId: campaignId, campaignName: campaignName, campaignType: campaignType, campaignLabel: campaignLabel, campaignUrl: campaignUrl, paywallId: paywallId, paywallName: paywallName, segmentId: segmentId, externalSegmentId: externalSegmentId, action: action, sku: sku, purchaseError: purchaseError, purchases: purchases, deeplinkUrl: deeplinkUrl)
}
)
launchHandler: { success, error in
self.handleLaunch(
callback: callback,
success: success,
error: error
)
},
paywallActionHandler: { campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl in
self.handlePaywallAction(campaignId: campaignId, campaignName: campaignName, campaignType: campaignType, campaignLabel: campaignLabel, campaignUrl: campaignUrl, paywallId: paywallId, paywallName: paywallName, segmentId: segmentId, externalSegmentId: externalSegmentId, action: action, sku: sku, purchaseError: purchaseError, purchases: purchases, deeplinkUrl: deeplinkUrl)
})
}
} else if let label = label {
launchMethod = {
NamiCampaignManager.launch(label: label, context: paywallLaunchContext,
launchHandler: { (success, error) in
self.handleLaunch(
callback: callback,
success: success,
error: error)
},
paywallActionHandler: { (campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl) in
self.handlePaywallAction(campaignId: campaignId, campaignName: campaignName, campaignType: campaignType, campaignLabel: campaignLabel, campaignUrl: campaignUrl, paywallId: paywallId, paywallName: paywallName, segmentId: segmentId, externalSegmentId: externalSegmentId, action: action, sku: sku, purchaseError: purchaseError, purchases: purchases, deeplinkUrl: deeplinkUrl)
}
)
launchHandler: { success, error in
self.handleLaunch(
callback: callback,
success: success,
error: error
)
},
paywallActionHandler: { campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl in
self.handlePaywallAction(campaignId: campaignId, campaignName: campaignName, campaignType: campaignType, campaignLabel: campaignLabel, campaignUrl: campaignUrl, paywallId: paywallId, paywallName: paywallName, segmentId: segmentId, externalSegmentId: externalSegmentId, action: action, sku: sku, purchaseError: purchaseError, purchases: purchases, deeplinkUrl: deeplinkUrl)
})
}
} else {
print("Neither URL nor label provided calling default launch.")
launchMethod = {
NamiCampaignManager.launch(context: paywallLaunchContext,
launchHandler: { (success, error) in
self.handleLaunch(
callback:callback,
success: success,
error: error)
},
paywallActionHandler: { (campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl) in
self.handlePaywallAction(campaignId: campaignId, campaignName: campaignName, campaignType: campaignType, campaignLabel: campaignLabel, campaignUrl: campaignUrl, paywallId: paywallId, paywallName: paywallName, segmentId: segmentId, externalSegmentId: externalSegmentId, action: action, sku: sku, purchaseError: purchaseError, purchases: purchases, deeplinkUrl: deeplinkUrl)
}
)
launchHandler: { success, error in
self.handleLaunch(
callback: callback,
success: success,
error: error
)
},
paywallActionHandler: { campaignId, campaignName, campaignType, campaignLabel, campaignUrl, paywallId, paywallName, segmentId, externalSegmentId, _, action, sku, purchaseError, purchases, deeplinkUrl in
self.handlePaywallAction(campaignId: campaignId, campaignName: campaignName, campaignType: campaignType, campaignLabel: campaignLabel, campaignUrl: campaignUrl, paywallId: paywallId, paywallName: paywallName, segmentId: segmentId, externalSegmentId: externalSegmentId, action: action, sku: sku, purchaseError: purchaseError, purchases: purchases, deeplinkUrl: deeplinkUrl)
})
}
}

Expand All @@ -205,8 +205,8 @@ class RNNamiCampaignManager: RCTEventEmitter {
func isCampaignAvailable(
campaignSource: String?,
resolve: @escaping RCTPromiseResolveBlock,
reject _: @escaping RCTPromiseRejectBlock)
{
reject _: @escaping RCTPromiseRejectBlock
) {
var isCampaignAvailable: Bool
if let source = campaignSource {
if isURL(string: source), let url = URL(string: source) {
Expand Down
9 changes: 7 additions & 2 deletions ios/NamiPaywallManagerBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// NamiPaywallManager.m
// namiReactNative
//
// Created by Kendall Gelner on 11/22/19.
// Copyright © 2019 Nami ML Inc. All rights reserved.
// Copyright © 2023 Nami ML Inc. All rights reserved.
//

#import <Foundation/Foundation.h>
Expand All @@ -22,8 +21,14 @@ @interface RCT_EXTERN_MODULE(RNNamiPaywallManager, NSObject)

RCT_EXTERN_METHOD(registerCloseHandler)

RCT_EXTERN_METHOD(registerSignInHandler)

RCT_EXTERN_METHOD(dismiss:(BOOL)animated)

RCT_EXTERN_METHOD(show)

RCT_EXTERN_METHOD(hide)

+ (BOOL)requiresMainQueueSetup {
return YES;
}
Expand Down
Loading

0 comments on commit ecd3bdc

Please sign in to comment.