@pinwheel/react-native-pinwheel 3.6.1 → 3.7.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/README.md CHANGED
@@ -122,19 +122,25 @@ Enables Link to run with a dark mode theme.
122
122
 
123
123
  ## Running The Example App Locally
124
124
 
125
- You may want to run the example app locally to get started.
125
+ You may want to run the example app locally to get started. The application is located inside of the example_expo directory inside of the repository.
126
126
 
127
127
  #### Dependencies
128
128
 
129
- - Node 16.7.0 (check with `node -v` and upgrade versions using `nvm` if needed)
130
- - iPhone 14 simulator (open your Simulator app and check the available versions)
131
- - iOS 16 running on the simulator (open your Simulator app and check the available versions)
132
- - `pod` version 1.11.3 (check with `pod --version`)
133
- - Add your pinwheel secret to `example/env.js` (create this file) with `export default "<YOUR PINWHEEL SECRET>"`.
129
+ - Node 22.18.0 (check with `node -v` and upgrade versions using `nvm` if needed)
130
+ - Xcode for iOS
131
+ - Android Studio for Android
134
132
 
135
133
  #### Directions
136
-
137
- - `npm run dev`
134
+ **Enter the `example_expo` directory and run the following commands:**
135
+ - Create a `.env` file with your Pinwheel API secret. An example env file is located at example_repo/.env.example.
136
+ - Directions to run the [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/)
137
+ - Directions to run the [Android simulator](https://docs.expo.dev/workflow/android-studio-emulator/)
138
+ ```
139
+ EXPO_PUBLIC_PINWHEEL_API_KEY=YOUR_API_SECRET
140
+ ```
141
+ - `npm i`
142
+ - `npm run ios` (for iOS)
143
+ - `npm run android` (for Android)
138
144
 
139
145
  #### Troubleshooting
140
146
 
@@ -15,7 +15,9 @@ Pod::Spec.new do |s|
15
15
 
16
16
  s.source_files = "ios/**/*.{h,m,mm,swift}"
17
17
 
18
+ s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
19
+
18
20
  install_modules_dependencies(s)
19
21
 
20
- s.dependency 'PinwheelSDK', '3.4.2'
22
+ s.dependency 'PinwheelSDK', '3.5.0'
21
23
  end
@@ -32,7 +32,7 @@ repositories {
32
32
  google()
33
33
  }
34
34
 
35
- def PW_ANDROID_SDK_VERSION = '3.5.2'
35
+ def PW_ANDROID_SDK_VERSION = '3.6.0'
36
36
 
37
37
  dependencies {
38
38
  def pwVersion = rootProject.hasProperty('pwVersion') ? rootProject.pwVersion : PW_ANDROID_SDK_VERSION
@@ -21,6 +21,7 @@ class Pinwheel : FrameLayout {
21
21
  private var pinwheelEventListener: PinwheelEventListener? = null
22
22
  private var handleInsets: Boolean = true
23
23
  private var useDarkMode: Boolean = false
24
+ private var useSecureOrigin: Boolean = false
24
25
  private var fragmentContainer: FrameLayout? = null
25
26
 
26
27
  constructor(context: Context) : super(context) {
@@ -80,6 +81,10 @@ class Pinwheel : FrameLayout {
80
81
  this.useDarkMode = useDarkMode
81
82
  }
82
83
 
84
+ fun setUseSecureOrigin(useSecureOrigin: Boolean) {
85
+ this.useSecureOrigin = useSecureOrigin
86
+ }
87
+
83
88
  fun getReactNativeVersion(): String {
84
89
  val version = ReactNativeVersion.VERSION
85
90
  return "${version["major"]}.${version["minor"]}.${version["patch"]}"
@@ -89,7 +94,15 @@ class Pinwheel : FrameLayout {
89
94
  Handler(Looper.getMainLooper()).post {
90
95
  if (this.pinwheelFragment == null) {
91
96
  this.token?.let {
92
- val pinwheelFragment = PinwheelFragment.newInstanceWithAdvancedOptions(it, "react native", "3.6.1", getReactNativeVersion(), this.handleInsets, this.useDarkMode)
97
+ val pinwheelFragment = PinwheelFragment.newInstanceWithAdvancedOptions(
98
+ it,
99
+ "react native",
100
+ "3.7.1",
101
+ getReactNativeVersion(),
102
+ this.handleInsets,
103
+ this.useDarkMode,
104
+ this.useSecureOrigin
105
+ )
93
106
  pinwheelEventListener?.let { listener ->
94
107
  pinwheelFragment.pinwheelEventListener = listener
95
108
  }
@@ -48,6 +48,11 @@ class PinwheelManager(private val reactContext: ReactApplicationContext) :
48
48
  view.setUseDarkMode(useDarkMode)
49
49
  }
50
50
 
51
+ @ReactProp(name = "useSecureOrigin")
52
+ override fun setUseSecureOrigin(view: Pinwheel, useSecureOrigin: Boolean) {
53
+ view.setUseSecureOrigin(useSecureOrigin)
54
+ }
55
+
51
56
  @ReactPropGroup(names = ["width", "height"], customType = "Style")
52
57
  fun setStyle(view: Pinwheel, index: Int, value: Int) {
53
58
  if (index == 0) propWidth = value
@@ -0,0 +1,97 @@
1
+ import Foundation
2
+ import PinwheelSDK
3
+ import UIKit
4
+
5
+ @objc public protocol PWPinwheelWrapperDelegate {
6
+ func onEvent(name: String, event: [String: AnyObject])
7
+ }
8
+
9
+ @objcMembers
10
+ public final class PWPinwheelWrapperVC: UIViewController {
11
+ private let token: String
12
+ private let delegateBridge: PWPinwheelWrapperDelegate
13
+
14
+ private let useSecureOrigin: Bool
15
+ private let useDarkMode: Bool
16
+ private let sdk: String
17
+ private let version: String
18
+
19
+ private var pinwheelVC: PinwheelViewController?
20
+
21
+ public init(
22
+ token: String,
23
+ delegate: PWPinwheelWrapperDelegate,
24
+ sdk: String,
25
+ version: String,
26
+ useSecureOrigin: Bool,
27
+ useDarkMode: Bool = false,
28
+ useAppBoundDomains: Bool = false,
29
+ useAppBoundDomainsForNativeLink: Bool = false
30
+ ) {
31
+ self.token = token
32
+ self.delegateBridge = delegate
33
+ self.sdk = sdk
34
+ self.version = version
35
+ self.useSecureOrigin = useSecureOrigin
36
+ self.useDarkMode = useDarkMode
37
+ super.init(nibName: nil, bundle: nil)
38
+
39
+ var config = PinwheelConfig(mode: .sandbox, environment: .production, sdk: sdk, version: version)
40
+ config.useSecureOrigin = useSecureOrigin
41
+
42
+ let vc = PinwheelViewController(
43
+ token: token,
44
+ delegate: self,
45
+ config: config,
46
+ useDarkMode: useDarkMode,
47
+ useAppBoundDomains: useAppBoundDomains,
48
+ useAppBoundDomainsForNativeLink: useAppBoundDomainsForNativeLink
49
+ )
50
+ self.pinwheelVC = vc
51
+ }
52
+
53
+ public required init?(coder: NSCoder) {
54
+ nil
55
+ }
56
+
57
+ public override func viewDidLoad() {
58
+ super.viewDidLoad()
59
+ guard let pinwheelVC else { return }
60
+
61
+ addChild(pinwheelVC)
62
+ view.addSubview(pinwheelVC.view)
63
+ pinwheelVC.didMove(toParent: self)
64
+
65
+ pinwheelVC.view.translatesAutoresizingMaskIntoConstraints = false
66
+ NSLayoutConstraint.activate([
67
+ pinwheelVC.view.topAnchor.constraint(equalTo: view.topAnchor),
68
+ pinwheelVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
69
+ pinwheelVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
70
+ pinwheelVC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
71
+ ])
72
+ }
73
+ }
74
+
75
+ // MARK: - PinwheelDelegate
76
+
77
+ extension PWPinwheelWrapperVC: PinwheelDelegate {
78
+ public func onEvent(name: PinwheelEventType, event: PinwheelEventPayload?) {
79
+ var payload: [String: AnyObject] = [:]
80
+
81
+ if let event {
82
+ do {
83
+ let json = try event.jsonString()
84
+ if let jsonData = json.data(using: .utf8) {
85
+ let jsonObject = try JSONSerialization.jsonObject(with: jsonData)
86
+ if let jsonDictionary = jsonObject as? [String: AnyObject] {
87
+ payload = jsonDictionary
88
+ }
89
+ }
90
+ } catch {
91
+ // Best-effort payload serialization; still forward event name.
92
+ }
93
+ }
94
+
95
+ delegateBridge.onEvent(name: name.rawValue, event: payload)
96
+ }
97
+ }
@@ -17,6 +17,7 @@ RCT_EXPORT_MODULE(RTNPinwheel)
17
17
 
18
18
  RCT_EXPORT_VIEW_PROPERTY(token, NSString);
19
19
  RCT_EXPORT_VIEW_PROPERTY(useDarkMode, BOOL);
20
+ RCT_EXPORT_VIEW_PROPERTY(useSecureOrigin, BOOL);
20
21
 
21
22
  @end
22
23
 
@@ -34,5 +35,6 @@ RCT_EXPORT_MODULE(RTNPinwheelView)
34
35
 
35
36
  RCT_EXPORT_VIEW_PROPERTY(token, NSString);
36
37
  RCT_EXPORT_VIEW_PROPERTY(useDarkMode, BOOL);
38
+ RCT_EXPORT_VIEW_PROPERTY(useSecureOrigin, BOOL);
37
39
 
38
40
  @end
@@ -5,25 +5,35 @@
5
5
  # endif
6
6
 
7
7
  #import <WebKit/WebKit.h>
8
- #import <PinwheelSDK/PinwheelSDK-Swift.h>
9
8
  #import <UIKit/UIKit.h>
10
9
 
11
10
  NS_ASSUME_NONNULL_BEGIN
12
11
 
12
+ #ifdef __cplusplus
13
+ extern "C" {
14
+ #endif
15
+ @protocol PWPinwheelWrapperDelegate;
16
+ #ifdef __cplusplus
17
+ }
18
+ #endif
19
+
20
+ @class PWPinwheelWrapperVC;
21
+
13
22
  #ifdef RCT_NEW_ARCH_ENABLED
14
23
 
15
- @interface RTNPinwheelView : RCTViewComponentView <PinwheelWrapperDelegate>
24
+ @interface RTNPinwheelView : RCTViewComponentView <PWPinwheelWrapperDelegate>
16
25
 
17
26
  #else
18
27
 
19
- @interface RTNPinwheelView : UIView <PinwheelWrapperDelegate>
28
+ @interface RTNPinwheelView : UIView <PWPinwheelWrapperDelegate>
20
29
 
21
30
  #endif
22
31
 
23
32
 
24
- @property (nonatomic, strong, nullable) PinwheelWrapperVC *pinwheelWrapperVC;
33
+ @property (nonatomic, strong, nullable) PWPinwheelWrapperVC *pinwheelWrapperVC;
25
34
  @property (nonatomic, strong) NSString *token;
26
35
  @property (nonatomic, assign) BOOL useDarkMode;
36
+ @property (nonatomic, assign) BOOL useSecureOrigin;
27
37
 
28
38
  - (instancetype)initWithFrame:(CGRect)frame token:(NSString *)token;
29
39
 
@@ -9,6 +9,7 @@
9
9
 
10
10
  #import "RCTFabricComponentsPlugins.h"
11
11
  #import "RTNPinwheelEvents.h"
12
+ #import "RNPinwheelSDK-Swift.h"
12
13
 
13
14
  using namespace facebook::react;
14
15
 
@@ -71,13 +72,14 @@ using namespace facebook::react;
71
72
  }
72
73
 
73
74
  self.pinwheelWrapperVC =
74
- [[PinwheelWrapperVC alloc] initWithToken:self.token
75
- delegate:self
76
- sdk:@"react native"
77
- version:@"3.6.1"
78
- useDarkMode:self.useDarkMode
79
- useAppBoundDomains:NO
80
- useAppBoundDomainsForNativeLink:NO];
75
+ [[PWPinwheelWrapperVC alloc] initWithToken:self.token
76
+ delegate:self
77
+ sdk:@"react native"
78
+ version:@"3.7.1"
79
+ useSecureOrigin:self.useSecureOrigin
80
+ useDarkMode:self.useDarkMode
81
+ useAppBoundDomains:NO
82
+ useAppBoundDomainsForNativeLink:NO];
81
83
 
82
84
  // Guard against double-attachment (shouldn’t happen after cleanup, but safe).
83
85
  if (self.pinwheelWrapperVC.parentViewController == parentVC) {
@@ -127,6 +129,10 @@ using namespace facebook::react;
127
129
  self.useDarkMode = newViewProps.useDarkMode;
128
130
  }
129
131
 
132
+ if (oldViewProps.useSecureOrigin != newViewProps.useSecureOrigin) {
133
+ self.useSecureOrigin = newViewProps.useSecureOrigin;
134
+ }
135
+
130
136
  // Ensures that the view is always re-initialized whenever the props change,
131
137
  // or the React Native component is re-mounted. On the new architecture, there
132
138
  // are optimizations which causes the view to be re-used in these scenarios,
@@ -181,6 +187,7 @@ Class<RCTComponentViewProtocol> RTNPinwheelCls(void) {
181
187
 
182
188
  #import "RTNPinwheelEvents.h"
183
189
  #import "RTNPinwheelView.h"
190
+ #import "RNPinwheelSDK-Swift.h"
184
191
 
185
192
  @implementation RTNPinwheelView
186
193
 
@@ -234,13 +241,14 @@ Class<RCTComponentViewProtocol> RTNPinwheelCls(void) {
234
241
  }
235
242
 
236
243
  self.pinwheelWrapperVC =
237
- [[PinwheelWrapperVC alloc] initWithToken:self.token
238
- delegate:self
239
- sdk:@"react native"
240
- version:@"3.6.1"
241
- useDarkMode:self.useDarkMode
242
- useAppBoundDomains:NO
243
- useAppBoundDomainsForNativeLink:NO];
244
+ [[PWPinwheelWrapperVC alloc] initWithToken:self.token
245
+ delegate:self
246
+ sdk:@"react native"
247
+ version:@"3.7.1"
248
+ useSecureOrigin:self.useSecureOrigin
249
+ useDarkMode:self.useDarkMode
250
+ useAppBoundDomains:NO
251
+ useAppBoundDomainsForNativeLink:NO];
244
252
 
245
253
  // Guard against double-attachment (shouldn’t happen after cleanup, but safe).
246
254
  if (self.pinwheelWrapperVC.parentViewController == parentVC) {
@@ -281,6 +289,13 @@ Class<RCTComponentViewProtocol> RTNPinwheelCls(void) {
281
289
  }
282
290
  }
283
291
 
292
+ - (void)setUseSecureOrigin:(BOOL)newUseSecureOrigin {
293
+ if (_useSecureOrigin != newUseSecureOrigin) {
294
+ _useSecureOrigin = newUseSecureOrigin;
295
+ [self initPinwheelWrapperVC];
296
+ }
297
+ }
298
+
284
299
  - (void)layoutSubviews {
285
300
  [super layoutSubviews];
286
301
  self.pinwheelWrapperVC.view.frame = self.bounds;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinwheel/react-native-pinwheel",
3
- "version": "3.6.1",
3
+ "version": "3.7.1",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -22,7 +22,8 @@
22
22
  ],
23
23
  "scripts": {
24
24
  "build": "tsc",
25
- "dev": "./scripts/dev_expo.sh"
25
+ "dev": "./scripts/dev_expo.sh",
26
+ "dev:bare": "./scripts/dev_bare.sh"
26
27
  },
27
28
  "author": "Pinwheel",
28
29
  "license": "MIT",
package/src/Pinwheel.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { LinkOptions } from './client-events/client';
3
- declare const Pinwheel: ({ linkToken, onLogin, onLoginAttempt, onSuccess, onError, onExit, onEvent, handleInsets, useDarkMode, }: LinkOptions & {
3
+ declare const Pinwheel: ({ linkToken, onLogin, onLoginAttempt, onSuccess, onError, onExit, onEvent, handleInsets, useDarkMode, useSecureOrigin, }: LinkOptions & {
4
4
  handleInsets?: boolean;
5
5
  useDarkMode?: boolean;
6
6
  }) => React.JSX.Element;
package/src/Pinwheel.tsx CHANGED
@@ -19,6 +19,7 @@ const Pinwheel = ({
19
19
  onEvent,
20
20
  handleInsets,
21
21
  useDarkMode,
22
+ useSecureOrigin,
22
23
  }: LinkOptions & {
23
24
  handleInsets?: boolean;
24
25
  useDarkMode?: boolean;
@@ -83,6 +84,7 @@ const Pinwheel = ({
83
84
  token={linkToken}
84
85
  handleInsets={handleInsets ?? true}
85
86
  useDarkMode={useDarkMode ?? false}
87
+ useSecureOrigin={useSecureOrigin ?? false}
86
88
  />
87
89
  )}
88
90
  </SafeAreaView>
@@ -4,6 +4,7 @@ export interface NativeProps extends ViewProps {
4
4
  token: string;
5
5
  handleInsets: boolean;
6
6
  useDarkMode: boolean;
7
+ useSecureOrigin: boolean;
7
8
  }
8
9
  declare const _default: HostComponent<NativeProps>;
9
10
  export default _default;
@@ -10,6 +10,7 @@ export interface NativeProps extends ViewProps {
10
10
  token: string;
11
11
  handleInsets: boolean;
12
12
  useDarkMode: boolean;
13
+ useSecureOrigin: boolean;
13
14
  }
14
15
 
15
16
  export default codegenNativeComponent<NativeProps>(
@@ -1,6 +1,7 @@
1
1
  import type { LoginEventPayload, SuccessEventPayload, EventHandler, ErrorEventPayload, LoginAttemptEventPayload } from './registry/v3';
2
2
  export type LinkOptions = {
3
3
  linkToken: string;
4
+ useSecureOrigin?: boolean;
4
5
  onLogin?: (payload: LoginEventPayload) => void;
5
6
  onLoginAttempt?: (payload: LoginAttemptEventPayload) => void;
6
7
  onSuccess?: (payload: SuccessEventPayload) => void;
@@ -3,15 +3,16 @@ import type {
3
3
  SuccessEventPayload,
4
4
  EventHandler,
5
5
  ErrorEventPayload,
6
- LoginAttemptEventPayload
7
- } from './registry/v3'
6
+ LoginAttemptEventPayload,
7
+ } from './registry/v3';
8
8
 
9
9
  export type LinkOptions = {
10
- linkToken: string
11
- onLogin?: (payload: LoginEventPayload) => void
12
- onLoginAttempt?: (payload: LoginAttemptEventPayload) => void
13
- onSuccess?: (payload: SuccessEventPayload) => void
14
- onError?: (error: ErrorEventPayload) => void
15
- onExit?: (error?: ErrorEventPayload) => void
16
- onEvent?: EventHandler
17
- }
10
+ linkToken: string;
11
+ useSecureOrigin?: boolean;
12
+ onLogin?: (payload: LoginEventPayload) => void;
13
+ onLoginAttempt?: (payload: LoginAttemptEventPayload) => void;
14
+ onSuccess?: (payload: SuccessEventPayload) => void;
15
+ onError?: (error: ErrorEventPayload) => void;
16
+ onExit?: (error?: ErrorEventPayload) => void;
17
+ onEvent?: EventHandler;
18
+ };