@virex-tech/paywallo-sdk 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/{MonetySdk.podspec → PaywalloSdk.podspec} +4 -4
- package/README.md +19 -19
- package/android/build.gradle +1 -1
- package/dist/index.js +17 -121
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +17 -121
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -5
- package/react-native.config.js +3 -3
- package/android/src/main/java/com/monety/sdk/MonetySdkPackage.kt +0 -16
- package/android/src/main/java/com/monety/sdk/PanelStoreKitModule.kt +0 -315
- package/android/src/main/java/com/monety/sdk/PanelWebView.kt +0 -74
- package/android/src/main/java/com/monety/sdk/PanelWebViewManager.kt +0 -52
- package/ios/PanelStoreKit.m +0 -21
- package/ios/PanelStoreKit.swift +0 -245
- package/ios/PanelWebView.h +0 -15
- package/ios/PanelWebView.m +0 -182
- package/ios/PanelWebViewManager.m +0 -41
- package/ios/PanelWebViewModule.h +0 -8
- package/ios/PanelWebViewModule.m +0 -42
package/ios/PanelStoreKit.swift
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import Foundation
|
|
2
|
-
import StoreKit
|
|
3
|
-
|
|
4
|
-
// React Native bridge types — avoids need for bridging header
|
|
5
|
-
typealias RCTPromiseResolveBlock = @convention(block) (Any?) -> Void
|
|
6
|
-
typealias RCTPromiseRejectBlock = @convention(block) (String?, String?, Error?) -> Void
|
|
7
|
-
|
|
8
|
-
@available(iOS 15.0, *)
|
|
9
|
-
@objc(PanelStoreKit)
|
|
10
|
-
class PanelStoreKit: NSObject {
|
|
11
|
-
|
|
12
|
-
private var updateListenerTask: Task<Void, Never>?
|
|
13
|
-
|
|
14
|
-
override init() {
|
|
15
|
-
super.init()
|
|
16
|
-
startTransactionListener()
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
deinit {
|
|
20
|
-
updateListenerTask?.cancel()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// MARK: - Transaction Listener
|
|
24
|
-
|
|
25
|
-
private func startTransactionListener() {
|
|
26
|
-
updateListenerTask = Task { [weak self] in
|
|
27
|
-
for await _ in Transaction.updates {
|
|
28
|
-
guard let _ = self else { return }
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// MARK: - Get Products
|
|
34
|
-
|
|
35
|
-
@objc
|
|
36
|
-
func getProducts(
|
|
37
|
-
_ productIds: [String],
|
|
38
|
-
resolve: @escaping RCTPromiseResolveBlock,
|
|
39
|
-
reject: @escaping RCTPromiseRejectBlock
|
|
40
|
-
) {
|
|
41
|
-
Task {
|
|
42
|
-
do {
|
|
43
|
-
let products = try await Product.products(for: Set(productIds))
|
|
44
|
-
let result = products.map { self.productToDict($0) }
|
|
45
|
-
resolve(result)
|
|
46
|
-
} catch {
|
|
47
|
-
reject("PRODUCTS_ERROR", "Failed to load products: \(error.localizedDescription)", error)
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// MARK: - Purchase
|
|
53
|
-
|
|
54
|
-
@objc
|
|
55
|
-
func purchase(
|
|
56
|
-
_ productId: String,
|
|
57
|
-
appAccountToken: String?,
|
|
58
|
-
resolve: @escaping RCTPromiseResolveBlock,
|
|
59
|
-
reject: @escaping RCTPromiseRejectBlock
|
|
60
|
-
) {
|
|
61
|
-
Task {
|
|
62
|
-
do {
|
|
63
|
-
let products = try await Product.products(for: [productId])
|
|
64
|
-
guard let product = products.first else {
|
|
65
|
-
reject("PRODUCT_NOT_FOUND", "Product \(productId) not found", nil)
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
var options = Set<Product.PurchaseOption>()
|
|
70
|
-
if let tokenStr = appAccountToken, let uuid = UUID(uuidString: tokenStr) {
|
|
71
|
-
options.insert(.appAccountToken(uuid))
|
|
72
|
-
}
|
|
73
|
-
let result = try await product.purchase(options: options)
|
|
74
|
-
|
|
75
|
-
switch result {
|
|
76
|
-
case .success(let verification):
|
|
77
|
-
switch verification {
|
|
78
|
-
case .verified(let transaction):
|
|
79
|
-
let purchaseResult: [String: Any] = [
|
|
80
|
-
"transactionId": String(transaction.id),
|
|
81
|
-
"productId": transaction.productID,
|
|
82
|
-
"receipt": verification.jwsRepresentation,
|
|
83
|
-
"transactionDate": Int(transaction.purchaseDate.timeIntervalSince1970 * 1000),
|
|
84
|
-
]
|
|
85
|
-
resolve(purchaseResult)
|
|
86
|
-
case .unverified(_, let error):
|
|
87
|
-
reject(
|
|
88
|
-
"VERIFICATION_FAILED",
|
|
89
|
-
"Transaction verification failed: \(error.localizedDescription)", error)
|
|
90
|
-
}
|
|
91
|
-
case .userCancelled:
|
|
92
|
-
resolve(nil)
|
|
93
|
-
case .pending:
|
|
94
|
-
resolve(["pending": true])
|
|
95
|
-
@unknown default:
|
|
96
|
-
reject("UNKNOWN_RESULT", "Unknown purchase result", nil)
|
|
97
|
-
}
|
|
98
|
-
} catch {
|
|
99
|
-
reject("PURCHASE_ERROR", "Purchase failed: \(error.localizedDescription)", error)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// MARK: - Finish Transaction
|
|
105
|
-
|
|
106
|
-
@objc
|
|
107
|
-
func finishTransaction(
|
|
108
|
-
_ transactionIdStr: String,
|
|
109
|
-
resolve: @escaping RCTPromiseResolveBlock,
|
|
110
|
-
reject: @escaping RCTPromiseRejectBlock
|
|
111
|
-
) {
|
|
112
|
-
Task {
|
|
113
|
-
guard let transactionId = UInt64(transactionIdStr) else {
|
|
114
|
-
reject("INVALID_ID", "Invalid transaction ID", nil)
|
|
115
|
-
return
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
for await result in Transaction.currentEntitlements {
|
|
119
|
-
guard case .verified(let transaction) = result else { continue }
|
|
120
|
-
if transaction.id == transactionId {
|
|
121
|
-
await transaction.finish()
|
|
122
|
-
resolve(nil)
|
|
123
|
-
return
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
for await result in Transaction.unfinished {
|
|
128
|
-
guard case .verified(let transaction) = result else { continue }
|
|
129
|
-
if transaction.id == transactionId {
|
|
130
|
-
await transaction.finish()
|
|
131
|
-
resolve(nil)
|
|
132
|
-
return
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Already finished or not found — success either way
|
|
137
|
-
resolve(nil)
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// MARK: - Get Active Transactions
|
|
142
|
-
|
|
143
|
-
@objc
|
|
144
|
-
func getActiveTransactions(
|
|
145
|
-
_ resolve: @escaping RCTPromiseResolveBlock,
|
|
146
|
-
reject: @escaping RCTPromiseRejectBlock
|
|
147
|
-
) {
|
|
148
|
-
Task {
|
|
149
|
-
var transactions: [[String: Any]] = []
|
|
150
|
-
|
|
151
|
-
for await result in Transaction.currentEntitlements {
|
|
152
|
-
guard case .verified(let transaction) = result else { continue }
|
|
153
|
-
|
|
154
|
-
let dict: [String: Any] = [
|
|
155
|
-
"transactionId": String(transaction.id),
|
|
156
|
-
"productId": transaction.productID,
|
|
157
|
-
"receipt": result.jwsRepresentation,
|
|
158
|
-
"transactionDate": Int(transaction.purchaseDate.timeIntervalSince1970 * 1000),
|
|
159
|
-
]
|
|
160
|
-
transactions.append(dict)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
resolve(transactions)
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// MARK: - Helpers
|
|
168
|
-
|
|
169
|
-
private func productToDict(_ product: Product) -> [String: Any] {
|
|
170
|
-
var dict: [String: Any] = [
|
|
171
|
-
"productId": product.id,
|
|
172
|
-
"title": product.displayName,
|
|
173
|
-
"description": product.description,
|
|
174
|
-
"price": product.price.description,
|
|
175
|
-
"priceValue": NSDecimalNumber(decimal: product.price).doubleValue,
|
|
176
|
-
"localizedPrice": product.displayPrice,
|
|
177
|
-
"type": productTypeString(product.type),
|
|
178
|
-
]
|
|
179
|
-
|
|
180
|
-
// Extract currency from jsonRepresentation
|
|
181
|
-
if let json = try? JSONSerialization.jsonObject(with: product.jsonRepresentation) as? [String: Any] {
|
|
182
|
-
// Try to extract currency from the product JSON
|
|
183
|
-
if let attrs = json["attributes"] as? [String: Any],
|
|
184
|
-
let offers = attrs["offers"] as? [[String: Any]],
|
|
185
|
-
let firstOffer = offers.first,
|
|
186
|
-
let currencyCode = firstOffer["currencyCode"] as? String {
|
|
187
|
-
dict["currency"] = currencyCode
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Fallback currency from locale
|
|
192
|
-
if dict["currency"] == nil {
|
|
193
|
-
if #available(iOS 16, *) {
|
|
194
|
-
dict["currency"] = Locale.current.currency?.identifier ?? "USD"
|
|
195
|
-
} else {
|
|
196
|
-
dict["currency"] = Locale.current.currencyCode ?? "USD"
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if let sub = product.subscription {
|
|
201
|
-
dict["subscriptionPeriod"] = formatPeriod(sub.subscriptionPeriod)
|
|
202
|
-
|
|
203
|
-
if let introOffer = sub.introductoryOffer {
|
|
204
|
-
if introOffer.paymentMode == .freeTrial {
|
|
205
|
-
dict["freeTrialPeriod"] = formatPeriod(introOffer.period)
|
|
206
|
-
} else {
|
|
207
|
-
dict["introductoryPrice"] = introOffer.displayPrice
|
|
208
|
-
dict["introductoryPriceValue"] = NSDecimalNumber(decimal: introOffer.price).doubleValue
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return dict
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
private func productTypeString(_ type: Product.ProductType) -> String {
|
|
217
|
-
switch type {
|
|
218
|
-
case .autoRenewable: return "subscription"
|
|
219
|
-
case .consumable: return "consumable"
|
|
220
|
-
case .nonConsumable: return "non_consumable"
|
|
221
|
-
case .nonRenewable: return "non_renewable"
|
|
222
|
-
default: return "unknown"
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
private func formatPeriod(_ period: Product.SubscriptionPeriod) -> String {
|
|
227
|
-
switch period.unit {
|
|
228
|
-
case .day:
|
|
229
|
-
return period.value == 7 ? "P1W" : "P\(period.value)D"
|
|
230
|
-
case .week:
|
|
231
|
-
return "P\(period.value)W"
|
|
232
|
-
case .month:
|
|
233
|
-
return "P\(period.value)M"
|
|
234
|
-
case .year:
|
|
235
|
-
return "P\(period.value)Y"
|
|
236
|
-
@unknown default:
|
|
237
|
-
return "P\(period.value)D"
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
@objc
|
|
242
|
-
static func requiresMainQueueSetup() -> Bool {
|
|
243
|
-
return false
|
|
244
|
-
}
|
|
245
|
-
}
|
package/ios/PanelWebView.h
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#import <UIKit/UIKit.h>
|
|
2
|
-
#import <WebKit/WebKit.h>
|
|
3
|
-
#import <React/RCTComponent.h>
|
|
4
|
-
|
|
5
|
-
@interface PanelWebView : UIView
|
|
6
|
-
|
|
7
|
-
@property (nonatomic, copy) NSString *sourceUrl;
|
|
8
|
-
@property (nonatomic, copy) NSString *sourceHtml;
|
|
9
|
-
@property (nonatomic, copy) NSString *injectedJavaScript;
|
|
10
|
-
@property (nonatomic, copy) RCTDirectEventBlock onMessage;
|
|
11
|
-
@property (nonatomic, copy) RCTDirectEventBlock onLoadEnd;
|
|
12
|
-
|
|
13
|
-
- (void)injectJavaScript:(NSString *)script;
|
|
14
|
-
|
|
15
|
-
@end
|
package/ios/PanelWebView.m
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
#import "PanelWebView.h"
|
|
2
|
-
#import "PanelWebViewModule.h"
|
|
3
|
-
#import <AVFoundation/AVFoundation.h>
|
|
4
|
-
|
|
5
|
-
@interface PanelWebView () <WKNavigationDelegate, WKScriptMessageHandler>
|
|
6
|
-
|
|
7
|
-
@property (nonatomic, strong) WKWebView *webView;
|
|
8
|
-
@property (nonatomic, assign) BOOL navigationFinished;
|
|
9
|
-
@property (nonatomic, copy) NSString *pendingInjectedJS;
|
|
10
|
-
|
|
11
|
-
@end
|
|
12
|
-
|
|
13
|
-
@implementation PanelWebView
|
|
14
|
-
|
|
15
|
-
- (instancetype)initWithFrame:(CGRect)frame
|
|
16
|
-
{
|
|
17
|
-
self = [super initWithFrame:frame];
|
|
18
|
-
if (self) {
|
|
19
|
-
_navigationFinished = NO;
|
|
20
|
-
[self setupWebView];
|
|
21
|
-
}
|
|
22
|
-
return self;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
- (void)setupWebView
|
|
26
|
-
{
|
|
27
|
-
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
|
|
28
|
-
WKUserContentController *contentController = [[WKUserContentController alloc] init];
|
|
29
|
-
[contentController addScriptMessageHandler:self name:@"ReactNativeWebView"];
|
|
30
|
-
|
|
31
|
-
NSString *injectionScript = @"window.ReactNativeWebView = { postMessage: function(data) { "
|
|
32
|
-
@"try { "
|
|
33
|
-
@" if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.ReactNativeWebView) { "
|
|
34
|
-
@" window.webkit.messageHandlers.ReactNativeWebView.postMessage(data); "
|
|
35
|
-
@" return; "
|
|
36
|
-
@" } "
|
|
37
|
-
@"} catch(e) {} "
|
|
38
|
-
@"var iframe = document.createElement('iframe'); "
|
|
39
|
-
@"iframe.style.display = 'none'; "
|
|
40
|
-
@"iframe.src = 'panelbridge://message?' + encodeURIComponent(data); "
|
|
41
|
-
@"document.body.appendChild(iframe); "
|
|
42
|
-
@"setTimeout(function() { if (iframe.parentNode) iframe.parentNode.removeChild(iframe); }, 100); "
|
|
43
|
-
@"} };";
|
|
44
|
-
WKUserScript *userScript = [[WKUserScript alloc] initWithSource:injectionScript
|
|
45
|
-
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
|
|
46
|
-
forMainFrameOnly:YES];
|
|
47
|
-
[contentController addUserScript:userScript];
|
|
48
|
-
|
|
49
|
-
config.userContentController = contentController;
|
|
50
|
-
config.allowsInlineMediaPlayback = YES;
|
|
51
|
-
config.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
|
|
52
|
-
|
|
53
|
-
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
|
|
54
|
-
withOptions:AVAudioSessionCategoryOptionMixWithOthers
|
|
55
|
-
error:nil];
|
|
56
|
-
|
|
57
|
-
_webView = [[WKWebView alloc] initWithFrame:self.bounds configuration:config];
|
|
58
|
-
_webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
59
|
-
_webView.navigationDelegate = self;
|
|
60
|
-
_webView.scrollView.bounces = NO;
|
|
61
|
-
_webView.scrollView.scrollEnabled = NO;
|
|
62
|
-
_webView.scrollView.minimumZoomScale = 1.0;
|
|
63
|
-
_webView.scrollView.maximumZoomScale = 1.0;
|
|
64
|
-
_webView.opaque = NO;
|
|
65
|
-
_webView.backgroundColor = [UIColor whiteColor];
|
|
66
|
-
self.backgroundColor = [UIColor whiteColor];
|
|
67
|
-
|
|
68
|
-
[self addSubview:_webView];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
- (void)setSourceUrl:(NSString *)sourceUrl
|
|
72
|
-
{
|
|
73
|
-
_sourceUrl = [sourceUrl copy];
|
|
74
|
-
_navigationFinished = NO;
|
|
75
|
-
if (sourceUrl && sourceUrl.length > 0 && (!_sourceHtml || _sourceHtml.length == 0)) {
|
|
76
|
-
NSURL *url = [NSURL URLWithString:sourceUrl];
|
|
77
|
-
if (url) {
|
|
78
|
-
NSURLRequest *request = [NSURLRequest requestWithURL:url];
|
|
79
|
-
[_webView loadRequest:request];
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
- (void)setSourceHtml:(NSString *)sourceHtml
|
|
85
|
-
{
|
|
86
|
-
_sourceHtml = [sourceHtml copy];
|
|
87
|
-
_navigationFinished = NO;
|
|
88
|
-
if (sourceHtml && sourceHtml.length > 0) {
|
|
89
|
-
NSURL *baseURL = [NSURL URLWithString:@"https://app.monety.io"];
|
|
90
|
-
[_webView loadHTMLString:sourceHtml baseURL:baseURL];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
- (void)setInjectedJavaScript:(NSString *)injectedJavaScript
|
|
95
|
-
{
|
|
96
|
-
_injectedJavaScript = [injectedJavaScript copy];
|
|
97
|
-
if (!injectedJavaScript || injectedJavaScript.length == 0) return;
|
|
98
|
-
|
|
99
|
-
if (_navigationFinished && _webView) {
|
|
100
|
-
[self executeJavaScript:injectedJavaScript];
|
|
101
|
-
} else {
|
|
102
|
-
self.pendingInjectedJS = injectedJavaScript;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
- (void)executeJavaScript:(NSString *)script
|
|
107
|
-
{
|
|
108
|
-
[_webView evaluateJavaScript:script completionHandler:nil];
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
- (void)injectJavaScript:(NSString *)script
|
|
112
|
-
{
|
|
113
|
-
[self executeJavaScript:script];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
#pragma mark - WKScriptMessageHandler
|
|
117
|
-
|
|
118
|
-
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
|
|
119
|
-
{
|
|
120
|
-
if ([message.name isEqualToString:@"ReactNativeWebView"]) {
|
|
121
|
-
NSString *body = message.body;
|
|
122
|
-
if ([body isKindOfClass:[NSString class]]) {
|
|
123
|
-
if (self.onMessage) {
|
|
124
|
-
self.onMessage(@{@"data": body});
|
|
125
|
-
}
|
|
126
|
-
[PanelWebViewModule emitWebViewMessage:@{@"data": body}];
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
#pragma mark - WKNavigationDelegate
|
|
132
|
-
|
|
133
|
-
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
|
|
134
|
-
{
|
|
135
|
-
_navigationFinished = YES;
|
|
136
|
-
|
|
137
|
-
if (self.onLoadEnd) {
|
|
138
|
-
self.onLoadEnd(@{});
|
|
139
|
-
}
|
|
140
|
-
[PanelWebViewModule emitWebViewLoadEnd];
|
|
141
|
-
|
|
142
|
-
if (self.pendingInjectedJS && self.pendingInjectedJS.length > 0) {
|
|
143
|
-
[self executeJavaScript:self.pendingInjectedJS];
|
|
144
|
-
self.pendingInjectedJS = nil;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
|
|
149
|
-
{
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
|
|
153
|
-
{
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
|
|
157
|
-
{
|
|
158
|
-
NSURL *url = navigationAction.request.URL;
|
|
159
|
-
|
|
160
|
-
if ([url.scheme isEqualToString:@"panelbridge"]) {
|
|
161
|
-
NSString *query = url.query;
|
|
162
|
-
if (query) {
|
|
163
|
-
NSString *data = [query stringByRemovingPercentEncoding];
|
|
164
|
-
if (self.onMessage) {
|
|
165
|
-
self.onMessage(@{@"data": data});
|
|
166
|
-
}
|
|
167
|
-
[PanelWebViewModule emitWebViewMessage:@{@"data": data}];
|
|
168
|
-
}
|
|
169
|
-
decisionHandler(WKNavigationActionPolicyCancel);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
decisionHandler(WKNavigationActionPolicyAllow);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
- (void)layoutSubviews
|
|
177
|
-
{
|
|
178
|
-
[super layoutSubviews];
|
|
179
|
-
_webView.frame = self.bounds;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
@end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
#import <React/RCTViewManager.h>
|
|
2
|
-
#import <React/RCTBridge.h>
|
|
3
|
-
#import <React/RCTUIManager.h>
|
|
4
|
-
#import "PanelWebView.h"
|
|
5
|
-
|
|
6
|
-
@interface PanelWebViewManager : RCTViewManager
|
|
7
|
-
@end
|
|
8
|
-
|
|
9
|
-
@implementation PanelWebViewManager
|
|
10
|
-
|
|
11
|
-
RCT_EXPORT_MODULE(PanelWebView)
|
|
12
|
-
|
|
13
|
-
- (UIView *)view
|
|
14
|
-
{
|
|
15
|
-
return [[PanelWebView alloc] init];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
RCT_EXPORT_VIEW_PROPERTY(sourceUrl, NSString)
|
|
19
|
-
RCT_EXPORT_VIEW_PROPERTY(sourceHtml, NSString)
|
|
20
|
-
RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString)
|
|
21
|
-
RCT_EXPORT_VIEW_PROPERTY(onMessage, RCTDirectEventBlock)
|
|
22
|
-
RCT_EXPORT_VIEW_PROPERTY(onLoadEnd, RCTDirectEventBlock)
|
|
23
|
-
|
|
24
|
-
RCT_EXPORT_METHOD(injectJavaScript:(nonnull NSNumber *)reactTag script:(NSString *)script)
|
|
25
|
-
{
|
|
26
|
-
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
27
|
-
PanelWebView *view = (PanelWebView *)viewRegistry[reactTag];
|
|
28
|
-
if (![view isKindOfClass:[PanelWebView class]]) {
|
|
29
|
-
RCTLogError(@"Invalid view returned from registry, expecting PanelWebView, got: %@", view);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
[view injectJavaScript:script];
|
|
33
|
-
}];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
+ (BOOL)requiresMainQueueSetup
|
|
37
|
-
{
|
|
38
|
-
return YES;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@end
|
package/ios/PanelWebViewModule.h
DELETED
package/ios/PanelWebViewModule.m
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
#import "PanelWebViewModule.h"
|
|
2
|
-
|
|
3
|
-
static PanelWebViewModule *sharedInstance = nil;
|
|
4
|
-
|
|
5
|
-
@implementation PanelWebViewModule
|
|
6
|
-
|
|
7
|
-
RCT_EXPORT_MODULE(PanelWebViewModule);
|
|
8
|
-
|
|
9
|
-
- (instancetype)init
|
|
10
|
-
{
|
|
11
|
-
self = [super init];
|
|
12
|
-
if (self) {
|
|
13
|
-
sharedInstance = self;
|
|
14
|
-
}
|
|
15
|
-
return self;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
- (NSArray<NSString *> *)supportedEvents
|
|
19
|
-
{
|
|
20
|
-
return @[@"PanelWebViewMessage", @"PanelWebViewLoadEnd"];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
+ (void)emitWebViewMessage:(NSDictionary *)message
|
|
24
|
-
{
|
|
25
|
-
if (sharedInstance) {
|
|
26
|
-
[sharedInstance sendEventWithName:@"PanelWebViewMessage" body:message];
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
+ (void)emitWebViewLoadEnd
|
|
31
|
-
{
|
|
32
|
-
if (sharedInstance) {
|
|
33
|
-
[sharedInstance sendEventWithName:@"PanelWebViewLoadEnd" body:@{}];
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
+ (BOOL)requiresMainQueueSetup
|
|
38
|
-
{
|
|
39
|
-
return YES;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
@end
|