From 75a97ae0438e9712a2a47ae0f51010857c1cfe7c Mon Sep 17 00:00:00 2001 From: Masoud Fallahpourbaee Date: Sun, 15 Oct 2023 17:19:40 +0200 Subject: [PATCH] Add the full implementation of onKlarnaMessage prop to KlarnaStandaloneWebView component --- .../KlarnaStandaloneWebViewEventSender.java | 17 ++++++++++++++ .../KlarnaStandaloneWebViewManager.java | 7 +++--- .../newarch/KlarnaStandaloneWebViewWrapper.mm | 23 ++++++++++++++++++- .../oldarch/KlarnaStandaloneWebViewWrapper.mm | 23 +++++++++++++++++-- src/KlarnaStandaloneWebView.tsx | 10 ++++++-- .../KlarnaStandaloneWebViewNativeComponent.ts | 7 ++++-- 6 files changed, 77 insertions(+), 10 deletions(-) diff --git a/android/src/main/java/com/klarna/mobile/sdk/reactnative/standalonewebview/KlarnaStandaloneWebViewEventSender.java b/android/src/main/java/com/klarna/mobile/sdk/reactnative/standalonewebview/KlarnaStandaloneWebViewEventSender.java index 0f7410bb..9561779c 100644 --- a/android/src/main/java/com/klarna/mobile/sdk/reactnative/standalonewebview/KlarnaStandaloneWebViewEventSender.java +++ b/android/src/main/java/com/klarna/mobile/sdk/reactnative/standalonewebview/KlarnaStandaloneWebViewEventSender.java @@ -9,6 +9,7 @@ import com.facebook.react.bridge.WritableMap; import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.events.EventDispatcher; +import com.klarna.mobile.sdk.api.KlarnaProductEvent; import com.klarna.mobile.sdk.api.standalonewebview.KlarnaStandaloneWebView; import com.klarna.mobile.sdk.reactnative.common.ArgumentsUtil; @@ -17,6 +18,7 @@ import java.util.Map; // TODO: Double-check that we're sending the correct values for parameters of the events. + /** * This class is responsible for sending some KlarnaStandaloneWebView-related events to the React Native side. */ @@ -25,6 +27,7 @@ public class KlarnaStandaloneWebViewEventSender { private static final String PARAM_NAME_NAVIGATION_EVENT = "navigationEvent"; private static final String PARAM_NAME_NAVIGATION_ERROR = "navigationError"; private static final String PARAM_NAME_PROGRESS_EVENT = "progressEvent"; + private static final String PARAM_NAME_KLARNA_MESSAGE_EVENT = "klarnaMessageEvent"; private static final String PARAM_NAME_ERROR_MESSAGE = "errorMessage"; private static final String PARAM_NAME_EVENT = "event"; private static final String PARAM_NAME_NEW_URL = "newUrl"; @@ -33,6 +36,7 @@ public class KlarnaStandaloneWebViewEventSender { private static final String PARAM_NAME_PROGRESS = "progress"; private static final String PARAM_NAME_IS_LOADING = "isLoading"; private static final String PARAM_NAME_WEB_VIEW_STATE = "webViewState"; + private static final String PARAM_NAME_ACTION = "action"; private final Map, EventDispatcher> viewToDispatcher; @@ -65,6 +69,13 @@ public void sendNavigationEvent(KlarnaStandaloneWebView view, KlarnaStandaloneWe postEventForView(event, params, view); } + public void sendKlarnaMessageEvent(@NonNull KlarnaStandaloneWebView view, @NonNull KlarnaProductEvent klarnaProductEvent) { + WritableMap params = ArgumentsUtil.createMap(new HashMap<>() {{ + put(PARAM_NAME_KLARNA_MESSAGE_EVENT, buildKlarnaMessageEventMap(klarnaProductEvent)); + }}); + postEventForView(KlarnaStandaloneWebViewEvent.Event.ON_KLARNA_MESSAGE, params, view); + } + /** * Creates an event from event name and a map of params. Sends it via the right dispatcher. * @@ -116,4 +127,10 @@ private ReadableMap buildNavigationEventMap(@Nullable KlarnaStandaloneWebView vi } } + private ReadableMap buildKlarnaMessageEventMap(KlarnaProductEvent klarnaProductEvent) { + return ArgumentsUtil.createMap(new HashMap<>() {{ + put(PARAM_NAME_ACTION, klarnaProductEvent.getAction()); + }}); + } + } diff --git a/android/src/main/java/com/klarna/mobile/sdk/reactnative/standalonewebview/KlarnaStandaloneWebViewManager.java b/android/src/main/java/com/klarna/mobile/sdk/reactnative/standalonewebview/KlarnaStandaloneWebViewManager.java index 2547aec7..9aa713de 100644 --- a/android/src/main/java/com/klarna/mobile/sdk/reactnative/standalonewebview/KlarnaStandaloneWebViewManager.java +++ b/android/src/main/java/com/klarna/mobile/sdk/reactnative/standalonewebview/KlarnaStandaloneWebViewManager.java @@ -30,7 +30,6 @@ import java.util.Map; import java.util.Objects; -// TODO Add support for sending onKlarnaMessage events. public class KlarnaStandaloneWebViewManager extends RNKlarnaStandaloneWebViewSpec { // Commands that can be triggered from React Native side @@ -47,12 +46,14 @@ public class KlarnaStandaloneWebViewManager extends RNKlarnaStandaloneWebViewSpe private final KlarnaEventHandler klarnaEventHandler = new KlarnaEventHandler() { @Override public void onEvent(@NonNull KlarnaComponent klarnaComponent, @NonNull KlarnaProductEvent klarnaProductEvent) { - // Not used as of now + if (klarnaComponent instanceof KlarnaStandaloneWebView) { + klarnaStandaloneWebViewEventSender.sendKlarnaMessageEvent((KlarnaStandaloneWebView) klarnaComponent, klarnaProductEvent); + } } @Override public void onError(@NonNull KlarnaComponent klarnaComponent, @NonNull KlarnaMobileSDKError klarnaMobileSDKError) { - // No used as of now + // Not used as of now } }; private final KlarnaStandaloneWebViewClient klarnaStandaloneWebViewClient = new KlarnaStandaloneWebViewClient() { diff --git a/ios/Sources/view/newarch/KlarnaStandaloneWebViewWrapper.mm b/ios/Sources/view/newarch/KlarnaStandaloneWebViewWrapper.mm index 9261df30..dcee3231 100644 --- a/ios/Sources/view/newarch/KlarnaStandaloneWebViewWrapper.mm +++ b/ios/Sources/view/newarch/KlarnaStandaloneWebViewWrapper.mm @@ -15,7 +15,7 @@ using namespace facebook::react; -@interface KlarnaStandaloneWebViewWrapper () +@interface KlarnaStandaloneWebViewWrapper () @property (nonatomic, strong) KlarnaStandaloneWebView* klarnaStandaloneWebView; @@ -33,6 +33,7 @@ - (id)init { // TODO: What should we pass here for 'returnUrl'? [self initializeKlarnaStandaloneWebView: @"returnUrl://"]; self.klarnaStandaloneWebView.delegate = self; + self.klarnaStandaloneWebView.eventHandler = self; // TODO: Where is the proper place to call removeObserver? [self.klarnaStandaloneWebView addObserver:self forKeyPath:PROPERTY_NAME_ESTIMATED_PROGRESS options:NSKeyValueObservingOptionNew context:nil]; return self; @@ -213,6 +214,26 @@ - (void)klarnaStandaloneWebView:(KlarnaStandaloneWebView * _Nonnull)webView didF #pragma mark - RCTRNKlarnaStandaloneWebViewViewProtocol methods +- (void)klarnaComponent:(id _Nonnull)klarnaComponent dispatchedEvent:(KlarnaProductEvent * _Nonnull)event { + if (_eventEmitter) { + RCTLogInfo(@"Sending onKlarnaMessage event"); + std::dynamic_pointer_cast(_eventEmitter) + ->onKlarnaMessage(RNKlarnaStandaloneWebViewEventEmitter::OnKlarnaMessage{ + .klarnaMessageEvent = { + .action = std::string([[event action] UTF8String]), + } + }); + } else { + RCTLogInfo(@"_eventEmitter is nil!"); + } +} + +- (void)klarnaComponent:(id _Nonnull)klarnaComponent encounteredError:(KlarnaError * _Nonnull)error { + // Not used as of now +} + +#pragma mark - RCTRNKlarnaStandaloneWebViewViewProtocol methods + - (void)load:(nonnull NSString *)url { [self.klarnaStandaloneWebView loadURL:[NSURL URLWithString:url]]; } diff --git a/ios/Sources/view/oldarch/KlarnaStandaloneWebViewWrapper.mm b/ios/Sources/view/oldarch/KlarnaStandaloneWebViewWrapper.mm index 5243a00a..93fec845 100644 --- a/ios/Sources/view/oldarch/KlarnaStandaloneWebViewWrapper.mm +++ b/ios/Sources/view/oldarch/KlarnaStandaloneWebViewWrapper.mm @@ -5,13 +5,12 @@ #import #import -@interface KlarnaStandaloneWebViewWrapper () +@interface KlarnaStandaloneWebViewWrapper () @property (nonatomic, strong) KlarnaStandaloneWebView* klarnaStandaloneWebView; @end -// TODO: Add support for sending onKlarnaMessage event. // TODO: Double-check that we're sending the correct values for parameters of the events. @implementation KlarnaStandaloneWebViewWrapper @@ -22,6 +21,8 @@ - (id)init { self = [super init]; [self initializeKlarnaStandaloneWebView]; self.klarnaStandaloneWebView.delegate = self; + self.klarnaStandaloneWebView.eventHandler = self; + // TODO: Where is the proper place to call removeObserver? [self.klarnaStandaloneWebView addObserver:self forKeyPath:PROPERTY_NAME_ESTIMATED_PROGRESS options:NSKeyValueObservingOptionNew context:nil]; return self; } @@ -175,6 +176,24 @@ - (void)klarnaStandaloneWebView:(KlarnaStandaloneWebView * _Nonnull)webView didF }); } +#pragma mark - KlarnaEventHandler methods + +- (void)klarnaComponent:(id _Nonnull)klarnaComponent dispatchedEvent:(KlarnaProductEvent * _Nonnull)event { + if (!self.onKlarnaMessage) { + RCTLog(@"Missing 'onKlarnaMessage' callback prop."); + return; + } + self.onKlarnaMessage(@{ + @"klarnaMessageEvent": @{ + @"action": event.action + } + }); +} + +- (void)klarnaComponent:(id _Nonnull)klarnaComponent encounteredError:(KlarnaError * _Nonnull)error { + // Not used as of now +} + @end #endif diff --git a/src/KlarnaStandaloneWebView.tsx b/src/KlarnaStandaloneWebView.tsx index 06549b51..7484ff83 100644 --- a/src/KlarnaStandaloneWebView.tsx +++ b/src/KlarnaStandaloneWebView.tsx @@ -121,7 +121,9 @@ export class KlarnaStandaloneWebView extends Component< event: NativeSyntheticEvent< Readonly<{ readonly klarnaMessageEvent: Readonly<{ - readonly message: string; + action: string; + // Dictionary is not support for events + // readonly params: { [key: string]: any }; }>; }> > @@ -188,7 +190,11 @@ export interface KlarnaWebViewProgressEvent { } export interface KlarnaWebViewKlarnaMessageEvent { - readonly message: string; + readonly action: string; + // Dictionary is not support for events + // readonly params: { [key: string]: any }; + // TODO What is a KlarnaWebViewComponent? + // readonly component: KlarnaWebViewComponent; } export default KlarnaStandaloneWebView; diff --git a/src/specs/KlarnaStandaloneWebViewNativeComponent.ts b/src/specs/KlarnaStandaloneWebViewNativeComponent.ts index 17b9f0a0..0e3c777a 100644 --- a/src/specs/KlarnaStandaloneWebViewNativeComponent.ts +++ b/src/specs/KlarnaStandaloneWebViewNativeComponent.ts @@ -47,10 +47,13 @@ type KlarnaWebViewProgressEvent = Readonly<{ }>; }>; -// TODO add the fields when the definition is known. For now we just add a message type KlarnaWebViewKlarnaMessageEvent = Readonly<{ readonly klarnaMessageEvent: Readonly<{ - readonly message: string; + readonly action: string; + // Dictionary is not support for events + // readonly params: { [key: string]: any }; + // TODO What is a KlarnaWebViewComponent? + // readonly component: KlarnaWebViewComponent; }>; }>;