Skip to content

Commit

Permalink
Add two new properties to KlarnaStandaloneWebView to control the over…
Browse files Browse the repository at this point in the history
…scroll and bounce effects
  • Loading branch information
MasoudFallahpourbaee committed Jun 26, 2024
1 parent 4389fd7 commit 28020da
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext r
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return List.of(
new KlarnaPaymentViewManager(reactContext),
new KlarnaStandaloneWebViewManager(reactContext, (Application) reactContext.getApplicationContext()),
new KlarnaStandaloneWebViewManager(reactContext),
new KlarnaCheckoutViewManager(reactContext)
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.klarna.mobile.sdk.reactnative.standalonewebview;

import android.app.Application;
import android.graphics.Bitmap;
import android.os.Build;
import android.view.View;
import android.webkit.RenderProcessGoneDetail;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -33,17 +34,22 @@

public class KlarnaStandaloneWebViewManager extends RNKlarnaStandaloneWebViewSpec<KlarnaStandaloneWebView> {

private static final String REACT_CLASS = "RNKlarnaStandaloneWebView";

// Commands that can be triggered from React Native side
public static final String COMMAND_LOAD = "load";
public static final String COMMAND_GO_FORWARD = "goForward";
public static final String COMMAND_GO_BACK = "goBack";
public static final String COMMAND_RELOAD = "reload";

private static final String REACT_CLASS = "RNKlarnaStandaloneWebView";
private static final String OVER_SCROLL_MODE_ALWAYS = "always";
private static final String OVER_SCROLL_MODE_CONTENT = "content";
private static final String OVER_SCROLL_MODE_NEVER = "never";

// Store a list of views to event dispatchers so we send up events via the right views.
private final Map<WeakReference<KlarnaStandaloneWebView>, EventDispatcher> viewToDispatcher;
private final KlarnaStandaloneWebViewEventSender klarnaStandaloneWebViewEventSender;
private final ReactApplicationContext reactAppContext;
private final KlarnaEventHandler klarnaEventHandler = new KlarnaEventHandler() {
@Override
public void onEvent(@NonNull KlarnaComponent klarnaComponent, @NonNull KlarnaProductEvent klarnaProductEvent) {
Expand Down Expand Up @@ -95,8 +101,9 @@ public void onRenderProcessGone(@Nullable KlarnaStandaloneWebView view, @Nullabl
}
};

public KlarnaStandaloneWebViewManager(ReactApplicationContext reactContext, Application applicationContext) {
public KlarnaStandaloneWebViewManager(ReactApplicationContext reactContext) {
super();
this.reactAppContext = reactContext;
viewToDispatcher = new HashMap<>();
klarnaStandaloneWebViewEventSender = new KlarnaStandaloneWebViewEventSender(viewToDispatcher);
}
Expand All @@ -109,6 +116,37 @@ public void setReturnUrl(KlarnaStandaloneWebView view, @Nullable String returnUr
}
}

@ReactProp(name = "overScrollMode")
@Override
public void setOverScrollMode(KlarnaStandaloneWebView view, String overScrollMode) {
for (int i = 0; i < view.getChildCount(); i++) {
View v = view.getChildAt(i);
if (v instanceof WebView) {
applyOverScrollMode(v, overScrollMode);
}
}
}

private void applyOverScrollMode(View view, String overScrollMode) {
switch (overScrollMode) {
case OVER_SCROLL_MODE_NEVER:
view.setOverScrollMode(View.OVER_SCROLL_NEVER);
break;
case OVER_SCROLL_MODE_CONTENT:
view.setOverScrollMode(View.OVER_SCROLL_IF_CONTENT_SCROLLS);
break;
case OVER_SCROLL_MODE_ALWAYS:
default:
view.setOverScrollMode(View.OVER_SCROLL_ALWAYS);
break;
}
}

@Override
public void setBounces(KlarnaStandaloneWebView view, boolean value) {
// No need to implement this as it is not supported in Android
}

@NonNull
@Override
public String getName() {
Expand Down Expand Up @@ -186,7 +224,7 @@ public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
@Override
protected KlarnaStandaloneWebView createViewInstance(@NonNull ThemedReactContext themedReactContext) {
KlarnaStandaloneWebView klarnaStandaloneWebView = new KlarnaStandaloneWebView(
/* context */ themedReactContext,
/* context */ reactAppContext,
/* attrs */ null,
/* defStyleAttr */ 0,
/* webViewClient */ klarnaStandaloneWebViewClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
public abstract class RNKlarnaStandaloneWebViewSpec<T extends View> extends SimpleViewManager<T> {
public abstract void setReturnUrl(T view, @Nullable String returnUrl);

public abstract void setOverScrollMode(T view, String overScrollMode);

public abstract void setBounces(T view, boolean bounces);

public abstract void load(T view, String url);

public abstract void goForward(T view);
Expand Down
1 change: 1 addition & 0 deletions ios/Sources/KlarnaStandaloneWebViewManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ @implementation KlarnaStandaloneWebViewManager
#pragma mark - View

RCT_EXPORT_VIEW_PROPERTY(returnUrl, NSString)
RCT_EXPORT_VIEW_PROPERTY(bounces, BOOL)
RCT_EXPORT_VIEW_PROPERTY(onLoadStart, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onLoadEnd, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onError, RCTDirectEventBlock)
Expand Down
1 change: 1 addition & 0 deletions ios/Sources/view/KlarnaStandaloneWebViewWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, copy) RCTDirectEventBlock onKlarnaMessage;

@property (nonatomic, strong) NSString* returnUrl;
@property (nonatomic, assign) BOOL bounces;
#endif

#pragma mark - React Native Overrides
Expand Down
16 changes: 16 additions & 0 deletions ios/Sources/view/newarch/KlarnaStandaloneWebViewWrapper.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ @interface KlarnaStandaloneWebViewWrapper () <KlarnaStandaloneWebViewDelegate, K

@property (nonatomic, strong) KlarnaStandaloneWebView *klarnaStandaloneWebView;

typedef void (^WebViewOperation)(WKWebView *);

@end

@implementation KlarnaStandaloneWebViewWrapper
Expand Down Expand Up @@ -144,6 +146,11 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
self.klarnaStandaloneWebView.returnURL = [NSURL URLWithString:newReturnUrl];
}

WebViewOperation setBounces = ^(WKWebView *webView) {
webView.scrollView.bounces = newViewProps.bounces;
};
[self applyOperationToWebViews:setBounces];

[super updateProps:props oldProps:oldProps];
}

Expand Down Expand Up @@ -294,6 +301,15 @@ - (NSString *)serializeDictionaryToJsonString:(NSDictionary<NSString *, id<NSCod
}
}

- (void)applyOperationToWebViews:(WebViewOperation)operation {
for (UIView *subView in self.klarnaStandaloneWebView.subviews) {
if ([subView isKindOfClass:[WKWebView class]]) {
WKWebView *webView = (WKWebView *) subView;
operation(webView);
}
}
}

@end

#endif
18 changes: 18 additions & 0 deletions ios/Sources/view/oldarch/KlarnaStandaloneWebViewWrapper.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

@interface KlarnaStandaloneWebViewWrapper () <KlarnaStandaloneWebViewDelegate, KlarnaEventHandler>

typedef void (^WebViewOperation)(WKWebView *);

@property (nonatomic, strong) KlarnaStandaloneWebView* klarnaStandaloneWebView;

@end
Expand Down Expand Up @@ -68,6 +70,13 @@ - (void)setReturnUrl:(NSString *)returnUrl {
}
}

- (void)setBounces:(BOOL)bounces {
WebViewOperation setBounces = ^(WKWebView *webView) {
webView.scrollView.bounces = bounces;
};
[self applyOperationToWebViews:setBounces];
}

- (void)initializeKlarnaStandaloneWebView {
if (self.returnUrl != nil && self.returnUrl.length > 0) {
self.klarnaStandaloneWebView = [[KlarnaStandaloneWebView alloc] initWithReturnURL:[NSURL URLWithString:self.returnUrl]];
Expand Down Expand Up @@ -225,6 +234,15 @@ - (NSString *)serializeDictionaryToJsonString:(NSDictionary<NSString *, id<NSCod
return [[NSMutableDictionary alloc] initWithDictionary: event];
}

- (void)applyOperationToWebViews:(WebViewOperation)operation {
for (UIView *subView in self.klarnaStandaloneWebView.subviews) {
if ([subView isKindOfClass:[WKWebView class]]) {
WKWebView *webView = (WKWebView *) subView;
operation(webView);
}
}
}

@end

#endif
4 changes: 4 additions & 0 deletions src/KlarnaStandaloneWebView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import type { Double } from 'react-native/Libraries/Types/CodegenTypes';
export interface KlarnaWebViewProps {
style?: ViewStyle;
readonly returnUrl: string;
readonly overScrollMode?: 'always' | 'content' | 'never';
readonly bounces?: boolean;
readonly onLoadStart?: (
navigationEvent: KlarnaWebViewNavigationEvent
) => void;
Expand Down Expand Up @@ -48,6 +50,8 @@ export class KlarnaStandaloneWebView extends Component<
ref={this.standaloneWebViewRef}
style={this.props.style}
returnUrl={this.props.returnUrl || ''}
overScrollMode={this.props.overScrollMode ?? 'always'}
bounces={this.props.bounces ?? true}
onLoadStart={(
event: NativeSyntheticEvent<
Readonly<{
Expand Down
6 changes: 6 additions & 0 deletions src/specs/KlarnaStandaloneWebViewNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ export interface RNKlarnaStandaloneWebViewProps extends ViewProps {
onError: DirectEventHandler<KlarnaWebViewError>;
onLoadProgress: DirectEventHandler<KlarnaWebViewProgressEvent>;
onKlarnaMessage: DirectEventHandler<KlarnaWebViewKlarnaMessageEvent>;

/* Android only */
onRenderProcessGone: DirectEventHandler<KlarnaWebViewRenderProcessGoneEvent>;
overScrollMode: string;
/* End of Android only */

/* iOS only */
bounces: boolean;
/* End of iOS only */
}

type KlarnaWebViewNavigationEvent = Readonly<{
Expand Down

0 comments on commit 28020da

Please sign in to comment.