Skip to content

Commit

Permalink
Merge pull request #100 from emartech/MV-332-inline-inapp
Browse files Browse the repository at this point in the history
MV-332 inline inapp
  • Loading branch information
eduzatoni authored Jan 22, 2024
2 parents 2834e26 + 67ae9a5 commit 46967dd
Show file tree
Hide file tree
Showing 14 changed files with 253 additions and 26 deletions.
2 changes: 1 addition & 1 deletion RNEmarsysWrapper.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ Pod::Spec.new do |s|
s.source_files = "ios/*.{h,m}"
s.requires_arc = true
s.dependency "React", ">= 0.67.3"
s.dependency "EmarsysSDK", "~> 3.4.0"
s.dependency "EmarsysSDK", "~> 3.5.0"

end
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@ repositories {

dependencies {
implementation "com.facebook.react:react-native:+"
implementation "com.emarsys:emarsys-sdk:3.6.+"
implementation "com.emarsys:emarsys-sdk:3.7.+"
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.emarsys.rnwrapper;

import android.util.Log;

import com.emarsys.Emarsys;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
Expand Down Expand Up @@ -72,7 +70,6 @@ private void sendEvents() {
}

public void provideReactContext(ReactContext reactContext) {
Log.d(this.getClass().getSimpleName(), "Registered for events.");
this.reactContext = reactContext;
eventEmitter = reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
reactContext.addLifecycleEventListener(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.emarsys.rnwrapper;

import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.emarsys.inapp.ui.InlineInAppView;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.events.RCTEventEmitter;

import java.util.Map;

public class RNEmarsysInlineInAppViewManager extends SimpleViewManager<InlineInAppView> {

private static final String TAG = "RNEmarsysInlineInAppView";
private final int COMMAND_LOAD_IN_APP = 1;

private final ReactApplicationContext reactContext;

public RNEmarsysInlineInAppViewManager(ReactApplicationContext reactContext) {
this.reactContext = reactContext;
}

@Override
public String getName() { return TAG; }

@Override
public InlineInAppView createViewInstance(ThemedReactContext context) {
InlineInAppView view = new InlineInAppView(reactContext,
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
view.setOnAppEventListener((property, json) -> {
WritableMap event = Arguments.createMap();
event.putString("eventName", property);
event.putMap("payload", MapUtil.jsonToWritableMap(json).getMap("payload"));
reactContext.getJSModule(RCTEventEmitter.class)
.receiveEvent(view.getId(), "onAppEvent", event);
return null;
});
view.setOnCompletionListener((error) -> {
WritableMap event = Arguments.createMap();
event.putString("error", error == null ? null : error.getLocalizedMessage());
reactContext.getJSModule(RCTEventEmitter.class)
.receiveEvent(view.getId(), "onCompleted", event);
});
view.setOnCloseListener(() -> {
reactContext.getJSModule(RCTEventEmitter.class)
.receiveEvent(view.getId(), "onClose", null);
return null;
});
return view;
}

public Map getExportedCustomBubblingEventTypeConstants() {
return MapBuilder.builder().put(
"onAppEvent",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "onAppEvent")
)
).put(
"onCompleted",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "onCompleted")
)
).put(
"onClose",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "onClose")
)
).build();
}

@Override
public Map<String, Integer> getCommandsMap() {
return MapBuilder.of("loadInApp", COMMAND_LOAD_IN_APP);
}

@Override
public void receiveCommand(
@NonNull InlineInAppView root,
String commandId,
@Nullable ReadableArray args
) {
super.receiveCommand(root, commandId, args);

int commandIdInt = Integer.parseInt(commandId);
switch (commandIdInt) {
case COMMAND_LOAD_IN_APP:
String viewId = args.getString(0);
root.loadInApp(viewId);
break;
default: { }
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,6 @@ private Product convertMapToProduct(ReadableMap map) {
ReadableType type = map.getType(key);
switch (type) {
case Null:
Log.d("Logs", "Received null in map");
break;
case Boolean:
available = map.getBoolean(key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
public class RNEmarsysWrapperPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
return Arrays.asList(
new RNEmarsysWrapperModule(reactContext),
new RNEmarsysPushWrapperModule(reactContext),
new RNEmarsysInAppWrapperModule(reactContext),
Expand All @@ -23,13 +23,9 @@ public List<NativeModule> createNativeModules(ReactApplicationContext reactConte
new RNEmarsysPredictWrapperModule(reactContext));
}

// Deprecated from RN 0.47
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
return Arrays.asList(
new RNEmarsysInlineInAppViewManager(reactContext));
}
}
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NativeModules, NativeEventEmitter } from 'react-native';
const { RNEmarsysWrapper } = NativeModules;

import Push from './src/push';
import InApp from './src/inapp';
import InApp, { InlineInAppView } from './src/inapp';
import Inbox from './src/inbox';
import Predict from './src/predict';
import Geofence from './src/geofence';
Expand Down Expand Up @@ -124,6 +124,7 @@ const Emarsys = {

push: Push,
inApp: InApp,
InlineInAppView,
inbox: Inbox,
predict: Predict,
geofence: Geofence,
Expand Down
1 change: 0 additions & 1 deletion ios/MapUtil.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ + (NSString*) toJsonString:(NSDictionary *)dict WithPrettyPrint:(BOOL) prettyPri
error:&error];

if (! jsonData) {
NSLog(@"error");
return @"{}";
} else {
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
Expand Down
17 changes: 17 additions & 0 deletions ios/RNEmarsysInlineInAppViewManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#import <React/RCTViewManager.h>
#import <React/RCTUIManager.h>

#import "EMSInlineInAppView.h"

@interface RNEmarsysInlineInAppView: EMSInlineInAppView

@property (nonatomic, copy) RCTBubblingEventBlock onAppEvent;
@property (nonatomic, copy) RCTBubblingEventBlock onCompleted;
@property (nonatomic, copy) RCTBubblingEventBlock onClose;

@end


@interface RNEmarsysInlineInAppViewManager : RCTViewManager

@end
42 changes: 42 additions & 0 deletions ios/RNEmarsysInlineInAppViewManager.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#import "RNEmarsysInlineInAppViewManager.h"

@implementation RNEmarsysInlineInAppView

@end


@implementation RNEmarsysInlineInAppViewManager

RCT_EXPORT_MODULE()

- (UIView *)view {
RNEmarsysInlineInAppView *view = [[RNEmarsysInlineInAppView alloc] init];
__weak RNEmarsysInlineInAppView *weakView = view;
view.eventHandler = ^(NSString *eventName, NSDictionary<NSString *, NSObject *> *payload) {
if (!weakView.onAppEvent) { return; }
weakView.onAppEvent(@{ @"eventName": eventName, @"payload": payload });
};
view.completionBlock = ^(NSError *error) {
if (!weakView.onCompleted) { return; }
weakView.onCompleted(@{ @"error": error ? error.localizedDescription : [NSNull null] });
};
view.closeBlock = ^ {
if (!weakView.onClose) { return; }
weakView.onClose(@{ });
};
return view;
}

RCT_EXPORT_VIEW_PROPERTY(onAppEvent, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onCompleted, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onClose, RCTBubblingEventBlock)

RCT_EXPORT_METHOD(loadInApp:(NSNumber * _Nonnull)viewTag withViewId:(NSString * _Nonnull)viewId) {
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
UIView *view = viewRegistry[viewTag];
if (!view || ![view isKindOfClass:[EMSInlineInAppView class]]) { return; }
[(EMSInlineInAppView *)view loadInAppWithViewId:viewId];
}];
}

@end
3 changes: 1 addition & 2 deletions ios/RNEmarsysWrapper.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,11 @@ - (dispatch_queue_t)methodQueue {
activity.webpageURL = activityURL;

[Emarsys trackDeepLinkWithUserActivity:activity sourceHandler:^(NSString *source) {
NSLog(@"trackDeepLink. Source url: %@", source);
resolve([NSNumber numberWithBool:YES]);
}];
}
@catch (NSException *ex) {
NSLog(@"RNEmarsysWrapper trackDeepLink: %@ %@", ex.name, ex.reason);
reject(ex.name, ex.reason, nil);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions sample/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ dependencies {
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.multidex:multidex:2.0.1"

implementation "com.emarsys:emarsys-sdk:3.6.+"
implementation "com.emarsys:emarsys-firebase:3.6.+"
implementation "com.emarsys:emarsys-sdk:3.7.+"
implementation "com.emarsys:emarsys-firebase:3.7.+"

// JSC from node_modules
if (useIntlJsc) {
Expand Down
40 changes: 34 additions & 6 deletions sample/src/components/InApp/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ const styles = StyleSheet.create({
width: "100%",
maxWidth: 420,
},
buttonSetEventHandler: {
marginTop: 24,
width: "100%",
maxWidth: 420,
},
button: {
marginTop: 24,
width: "100%",
Expand Down Expand Up @@ -247,6 +242,14 @@ export default class InApp extends Component {
}
}

constructor(props) {
super(props);
this.inlineInAppView = React.createRef();
this.state = {
inlineInAppViewHeight: 0
}
}

render() {
return (
<SafeAreaView style={styles.inbase}>
Expand All @@ -273,7 +276,7 @@ export default class InApp extends Component {
/>
</View>
)}
<View style={ styles.buttonSetEventHandler }>
<View style={ styles.button }>
<Button
title="Set Event Handler"
color="#04446E"
Expand All @@ -283,6 +286,31 @@ export default class InApp extends Component {
/>
</View>

<View style={ styles.button }>
<Button
title="Load Inline InApp"
color="#04446E"
onPress={() => {
this.inlineInAppView.current.loadInApp('view-id')
}}
/>
</View>
<Emarsys.InlineInAppView ref={this.inlineInAppView}
style={{width: "100%", height: this.state.inlineInAppViewHeight}}
onAppEvent={(eventName, payload) => {
showAlert(eventName, JSON.stringify(payload))
}}
onCompleted={error => {
if (error == null) {
this.setState({ inlineInAppViewHeight: 125 })
} else {
console.log(error)
}
}}
onClose={_ => {
this.setState({ inlineInAppViewHeight: 0 })
}} />

<View style={ styles.hr } />

<View style={ styles.button }>
Expand Down
Loading

0 comments on commit 46967dd

Please sign in to comment.