@pinwheel/react-native-pinwheel 2.4.0 → 2.5.0
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/CHANGELOG.md +85 -0
- package/README.md +3 -10
- package/RNPinwheelSDK.podspec +18 -0
- package/android/build.gradle +50 -0
- package/android/src/main/AndroidManifest.xml +6 -0
- package/android/src/main/java/com/underdog_tech/react/PinwheelPackage.kt +16 -0
- package/android/src/main/java/com/underdog_tech/react/PinwheelViewManager.kt +213 -0
- package/android/src/main/java/com/underdog_tech/react/RNTPinwheelEvents.kt +51 -0
- package/{lib/constants.d.ts → constants.d.ts} +1 -1
- package/{lib/constants.js → constants.js} +1 -1
- package/index.js +52 -0
- package/ios/RNTPinwheelEvents.h +9 -0
- package/ios/RNTPinwheelEvents.m +62 -0
- package/ios/RNTPinwheelManager.m +21 -0
- package/ios/RNTPinwheelView.h +12 -0
- package/ios/RNTPinwheelView.m +65 -0
- package/package.json +4 -9
- package/pinwheel-view.d.ts +6 -0
- package/pinwheel-view.js +2 -0
- package/pinwheel-wrapper.android.d.ts +4 -0
- package/pinwheel-wrapper.android.js +28 -0
- package/pinwheel-wrapper.ios.d.ts +4 -0
- package/pinwheel-wrapper.ios.js +17 -0
- package/lib/index.js +0 -122
- /package/{lib/index.d.ts → index.d.ts} +0 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## 2.5.x Releases
|
|
6
|
+
|
|
7
|
+
[2.5.0](#250)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
### 2.5.0
|
|
12
|
+
|
|
13
|
+
#### Notes
|
|
14
|
+
|
|
15
|
+
We're thrilled to announce the latest version of our SDK! While you'll find that our familiar API contract remains unchanged, there's a host of improvements that make this upgrade indispensable:
|
|
16
|
+
|
|
17
|
+
- **Enhanced Redundancy**: 🛡️ We've fortified our systems, ensuring smoother recovery from integration failures for a significant percentage of our traffic.
|
|
18
|
+
- **Superior Uptime**: 🦾 Reliability is a top priority. This upgrade brings even more robust uptime for DDS integrations.
|
|
19
|
+
- **Increased Conversion**: ↗️ We are leveraging system level features to increase conversion.
|
|
20
|
+
- **Easy Upgrade**: 🥧 No changes were made to the API contract. Easy as pie.
|
|
21
|
+
|
|
22
|
+
## 2.4.x Releases
|
|
23
|
+
|
|
24
|
+
[2.4.0](#240)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
### 2.4.0
|
|
29
|
+
|
|
30
|
+
- Removing `overrides` from main package.
|
|
31
|
+
- Updating example app to use newest ReactNative versions.
|
|
32
|
+
- Changing devDependencies to use newest React Native Webview (for typing).
|
|
33
|
+
|
|
34
|
+
## 2.3.x Releases
|
|
35
|
+
|
|
36
|
+
[2.3.4](#234) | [2.3.5](#235) | [2.3.6](#236) | [2.3.10](#2310) | [2.3.12](#2312) | [2.3.13](#2313) | [2.3.14](#2314) | [2.3.17](#2317)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### 2.3.17
|
|
41
|
+
|
|
42
|
+
Export `ScreenTransition` event payload type for the `screen_transition` event.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### 2.3.14
|
|
46
|
+
|
|
47
|
+
Remove `hermes-engine` and `shell-quote` sub-dependencies from package-lock files.
|
|
48
|
+
|
|
49
|
+
### 2.3.13
|
|
50
|
+
|
|
51
|
+
Bump `hermes-engine` and `shell-quote` sub-dependency package.
|
|
52
|
+
|
|
53
|
+
### 2.3.12
|
|
54
|
+
|
|
55
|
+
Add CircleCI scripting and local scripts.
|
|
56
|
+
- Add `npm run dev` script.
|
|
57
|
+
- Remove need for hardcoding api secret in code to run locally.
|
|
58
|
+
|
|
59
|
+
### 2.3.10
|
|
60
|
+
|
|
61
|
+
Use node 16.7.0 instead of 12.16.1 to install dependencies.
|
|
62
|
+
|
|
63
|
+
### [2.3.6](https://github.com/underdog-tech/react-native-pinwheel/releases/tag/2.3.6)
|
|
64
|
+
|
|
65
|
+
N/A
|
|
66
|
+
|
|
67
|
+
### [2.3.5](https://github.com/underdog-tech/react-native-pinwheel/releases/tag/2.3.5)
|
|
68
|
+
|
|
69
|
+
N/A
|
|
70
|
+
|
|
71
|
+
### [2.3.4](https://github.com/underdog-tech/react-native-pinwheel/releases/tag/2.3.4)
|
|
72
|
+
|
|
73
|
+
#### Added
|
|
74
|
+
|
|
75
|
+
- Export `EventPayload` type.
|
|
76
|
+
- Export `PinwheelError` type.
|
|
77
|
+
- Export `PinwheelErrorType` type.
|
|
78
|
+
- Export `EmptyPayloadObject` type as `Record<string, never>`.
|
|
79
|
+
|
|
80
|
+
##### Updated
|
|
81
|
+
|
|
82
|
+
- `EventPayload` is no longer a union containing `{}`. It now contains `Record<string, never>` instead due to [this behavior](https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-all-types-assignable-to-empty-interfaces).
|
|
83
|
+
- Mark exported `Error` type as **@deprecated** because it collides with the built-in javascript `Error` object. Replaced with `PinwheelError`.
|
|
84
|
+
- Mark exported `ErrorType` type as **@deprecated** because the new naming convention is prefixing with "`PinwheelError`". Replaced with `PinwheelErrorType`.
|
|
85
|
+
- Update `onExit` type to be `(error: PinwheelError | Record<string, never>)` to be accurate with current functionality.
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ You may want to run the example app locally to get started.
|
|
|
8
8
|
|
|
9
9
|
#### Dependencies
|
|
10
10
|
|
|
11
|
-
- Node 16.7.0 (check with `node -v` and upgrade versions using `nvm`)
|
|
11
|
+
- Node 16.7.0 (check with `node -v` and upgrade versions using `nvm` if needed)
|
|
12
12
|
- iPhone 14 simulator (open your Simulator app and check the available versions)
|
|
13
13
|
- iOS 16 running on the simulator (open your Simulator app and check the available versions)
|
|
14
14
|
- `pod` version 1.11.3 (check with `pod --version`)
|
|
@@ -35,14 +35,7 @@ For this or other errors related to command line developer tools:
|
|
|
35
35
|
|
|
36
36
|
## Installation
|
|
37
37
|
|
|
38
|
-
1. Install
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
$ npm install --save react-native-webview
|
|
42
|
-
$ cd ios && pod install
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
2. Install Pinwheel React Native SDK
|
|
38
|
+
1. Install Pinwheel React Native SDK
|
|
46
39
|
|
|
47
40
|
```bash
|
|
48
41
|
$ npm install --save @pinwheel/react-native-pinwheel
|
|
@@ -54,7 +47,7 @@ $ npm install --save @pinwheel/react-native-pinwheel
|
|
|
54
47
|
|
|
55
48
|
To initialize Link Modal, a short-lived link token will need to be generated first. Your server can generate the link token by sending a POST request to the /v1/link_tokens endpoint. DO NOT ever send this request from the client side and publicly expose your api_secret.
|
|
56
49
|
|
|
57
|
-
The link token returned is valid for
|
|
50
|
+
The link token returned is valid for one hour, after which it expires and can no longer be used to initialize Link. The expiration time is returned as a unix timestamp.
|
|
58
51
|
|
|
59
52
|
### Pinwheel Component
|
|
60
53
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Pod::Spec.new do |s|
|
|
2
|
+
s.name = "RNPinwheelSDK"
|
|
3
|
+
s.version = "2.5.0"
|
|
4
|
+
s.summary = "React Native plugin for Pinwheel's SDK"
|
|
5
|
+
s.description = <<-DESC
|
|
6
|
+
An open source React Native plugin for calling Pinwheel's native SDKs to manage payroll data.
|
|
7
|
+
DESC
|
|
8
|
+
s.homepage = "https://github.com/underdog-tech/react-native-pinwheel"
|
|
9
|
+
s.license = { :file => 'LICENSE' }
|
|
10
|
+
s.author = { 'Pinwheel' => 'info@pinwheelapi.com' }
|
|
11
|
+
s.platform = :ios, "12.0"
|
|
12
|
+
s.source = { :path => 'ios' }
|
|
13
|
+
s.source_files = "ios/**/*.{h,m}"
|
|
14
|
+
s.public_header_files = 'ios/**/*.h'
|
|
15
|
+
s.requires_arc = true
|
|
16
|
+
s.dependency "React"
|
|
17
|
+
s.dependency 'PinwheelSDK', '2.4.4'
|
|
18
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : '1.7.22'
|
|
3
|
+
|
|
4
|
+
repositories {
|
|
5
|
+
google()
|
|
6
|
+
mavenCentral()
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
dependencies {
|
|
10
|
+
classpath 'com.android.tools.build:gradle:7.2.2'
|
|
11
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
apply plugin: 'com.android.library'
|
|
16
|
+
apply plugin: 'kotlin-android'
|
|
17
|
+
|
|
18
|
+
android {
|
|
19
|
+
compileSdkVersion 33
|
|
20
|
+
|
|
21
|
+
defaultConfig {
|
|
22
|
+
minSdkVersion 24
|
|
23
|
+
targetSdkVersion 33
|
|
24
|
+
versionCode 1
|
|
25
|
+
versionName "1.0"
|
|
26
|
+
}
|
|
27
|
+
compileOptions {
|
|
28
|
+
sourceCompatibility = 1.8
|
|
29
|
+
targetCompatibility = 1.8
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
sourceSets {
|
|
33
|
+
main.java.srcDirs += 'src/main/java'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
rootProject.allprojects {
|
|
38
|
+
repositories {
|
|
39
|
+
google()
|
|
40
|
+
mavenCentral()
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
def PW_SDK_VERSION = '2.4.3'
|
|
45
|
+
|
|
46
|
+
dependencies {
|
|
47
|
+
def pwVersion = rootProject.hasProperty('pwVersion') ? rootProject.pwVersion : PW_SDK_VERSION
|
|
48
|
+
implementation 'com.facebook.react:react-native:+'
|
|
49
|
+
implementation "com.getpinwheel:pinwheel-android:$pwVersion"
|
|
50
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.underdog_tech.react
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.bridge.NativeModule
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
class PinwheelPackage : ReactPackage {
|
|
9
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
10
|
+
return listOf(RNTPinwheelEvents(reactContext)).toMutableList()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
override fun createViewManagers(
|
|
14
|
+
reactContext: ReactApplicationContext
|
|
15
|
+
) = listOf(PinwheelViewManager(reactContext))
|
|
16
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
package com.underdog_tech.react
|
|
2
|
+
|
|
3
|
+
import android.view.Choreographer
|
|
4
|
+
import android.view.View
|
|
5
|
+
import android.view.ViewGroup
|
|
6
|
+
import android.widget.FrameLayout
|
|
7
|
+
import androidx.fragment.app.FragmentActivity
|
|
8
|
+
import com.facebook.react.bridge.Arguments
|
|
9
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
10
|
+
import com.facebook.react.bridge.ReadableArray
|
|
11
|
+
import com.facebook.react.bridge.WritableMap
|
|
12
|
+
import com.facebook.react.bridge.WritableNativeMap
|
|
13
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
14
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
15
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
16
|
+
import com.facebook.react.uimanager.annotations.ReactPropGroup
|
|
17
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
18
|
+
import com.underdog_tech.pinwheel_android.PinwheelFragment
|
|
19
|
+
import com.underdog_tech.pinwheel_android.PinwheelEventListener
|
|
20
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelEventType
|
|
21
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelEventPayload
|
|
22
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelAmount
|
|
23
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelTarget
|
|
24
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelAllocation
|
|
25
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelParams
|
|
26
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelResult
|
|
27
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelError
|
|
28
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelSelectedEmployerPayload
|
|
29
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelSelectedPlatformPayload
|
|
30
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelLoginPayload
|
|
31
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelLoginAttemptPayload
|
|
32
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelDDFormCreatePayload
|
|
33
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelScreenTransitionPayload
|
|
34
|
+
import com.underdog_tech.pinwheel_android.model.PinwheelInputAmountPayload
|
|
35
|
+
|
|
36
|
+
fun PinwheelTarget.toWritableMap(): WritableMap {
|
|
37
|
+
return Arguments.createMap().apply {
|
|
38
|
+
putString("accountType", this@toWritableMap.accountType)
|
|
39
|
+
putString("accountName", this@toWritableMap.accountName)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
fun PinwheelAllocation.toWritableMap(): WritableMap {
|
|
44
|
+
return Arguments.createMap().apply {
|
|
45
|
+
putString("type", this@toWritableMap.type)
|
|
46
|
+
this@toWritableMap.value?.let { putDouble("value", it.toDouble()) }
|
|
47
|
+
putMap("target", this@toWritableMap.target?.toWritableMap())
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fun PinwheelParams.toWritableMap(): WritableMap {
|
|
52
|
+
return Arguments.createMap().apply {
|
|
53
|
+
putMap("amount", this@toWritableMap.amount?.toWritableMap())
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fun PinwheelEventPayload.toWritableMap(): WritableMap = when (this) {
|
|
58
|
+
is PinwheelAmount -> Arguments.createMap().apply {
|
|
59
|
+
putDouble("value", this@toWritableMap.value.toDouble())
|
|
60
|
+
putString("unit", this@toWritableMap.unit)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
is PinwheelInputAmountPayload -> Arguments.createMap().apply {
|
|
64
|
+
putString("action", this@toWritableMap.action)
|
|
65
|
+
putMap("allocation", this@toWritableMap.allocation?.toWritableMap())
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
is PinwheelResult -> Arguments.createMap().apply {
|
|
69
|
+
putString("accountId", this@toWritableMap.accountId)
|
|
70
|
+
putString("platformId", this@toWritableMap.platformId)
|
|
71
|
+
putString("job", this@toWritableMap.job)
|
|
72
|
+
putMap("params", this@toWritableMap.params?.toWritableMap())
|
|
73
|
+
}
|
|
74
|
+
is PinwheelError -> Arguments.createMap().apply {
|
|
75
|
+
putString("type", this@toWritableMap.type)
|
|
76
|
+
putString("code", this@toWritableMap.code)
|
|
77
|
+
putString("message", this@toWritableMap.message)
|
|
78
|
+
putBoolean("pendingRetry", this@toWritableMap.pendingRetry)
|
|
79
|
+
}
|
|
80
|
+
is PinwheelSelectedEmployerPayload -> Arguments.createMap().apply {
|
|
81
|
+
putString("selectedEmployerId", this@toWritableMap.selectedEmployerId)
|
|
82
|
+
putString("selectedEmployerName", this@toWritableMap.selectedEmployerName)
|
|
83
|
+
}
|
|
84
|
+
is PinwheelSelectedPlatformPayload -> Arguments.createMap().apply {
|
|
85
|
+
putString("selectedPlatformId", this@toWritableMap.selectedPlatformId)
|
|
86
|
+
putString("selectedPlatformName", this@toWritableMap.selectedPlatformName)
|
|
87
|
+
}
|
|
88
|
+
is PinwheelLoginPayload -> Arguments.createMap().apply {
|
|
89
|
+
putString("accountId", this@toWritableMap.accountId)
|
|
90
|
+
putString("platformId", this@toWritableMap.platformId)
|
|
91
|
+
}
|
|
92
|
+
is PinwheelLoginAttemptPayload -> Arguments.createMap().apply {
|
|
93
|
+
putString("platformId", this@toWritableMap.platformId)
|
|
94
|
+
}
|
|
95
|
+
is PinwheelDDFormCreatePayload -> Arguments.createMap().apply {
|
|
96
|
+
putString("url", this@toWritableMap.url)
|
|
97
|
+
}
|
|
98
|
+
is PinwheelScreenTransitionPayload -> Arguments.createMap().apply {
|
|
99
|
+
putString("screenName", this@toWritableMap.screenName)
|
|
100
|
+
putString("selectedEmployerId", this@toWritableMap.selectedEmployerId)
|
|
101
|
+
putString("selectedEmployerName", this@toWritableMap.selectedEmployerName)
|
|
102
|
+
putString("selectedPlatformId", this@toWritableMap.selectedPlatformId)
|
|
103
|
+
putString("selectedPlatformName", this@toWritableMap.selectedPlatformName)
|
|
104
|
+
}
|
|
105
|
+
else -> throw IllegalArgumentException("Unsupported PinwheelEventPayload type")
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
class PinwheelViewManager(
|
|
109
|
+
private val reactContext: ReactApplicationContext
|
|
110
|
+
) : ViewGroupManager<FrameLayout>(), PinwheelEventListener {
|
|
111
|
+
private var propWidth: Int? = reactContext.resources.displayMetrics.widthPixels
|
|
112
|
+
private var propHeight: Int? = reactContext.resources.displayMetrics.heightPixels
|
|
113
|
+
private var token: String? = null
|
|
114
|
+
|
|
115
|
+
override fun getName() = REACT_CLASS
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Return a FrameLayout which will later hold the Fragment
|
|
119
|
+
*/
|
|
120
|
+
override fun createViewInstance(reactContext: ThemedReactContext): FrameLayout {
|
|
121
|
+
return FrameLayout(reactContext)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Map the "create" command to an integer
|
|
126
|
+
*/
|
|
127
|
+
override fun getCommandsMap() = mapOf("create" to COMMAND_CREATE)
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Handle "create" command (called from JS) and call createFragment method
|
|
131
|
+
*/
|
|
132
|
+
override fun receiveCommand(
|
|
133
|
+
root: FrameLayout,
|
|
134
|
+
commandId: String,
|
|
135
|
+
args: ReadableArray?
|
|
136
|
+
) {
|
|
137
|
+
super.receiveCommand(root, commandId, args)
|
|
138
|
+
val reactNativeViewId = requireNotNull(args).getInt(0)
|
|
139
|
+
|
|
140
|
+
when (commandId.toInt()) {
|
|
141
|
+
COMMAND_CREATE -> createFragment(root, reactNativeViewId)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@ReactPropGroup(names = ["width", "height"], customType = "Style")
|
|
146
|
+
fun setStyle(view: FrameLayout, index: Int, value: Int) {
|
|
147
|
+
if (index == 0) propWidth = value
|
|
148
|
+
if (index == 1) propHeight = value
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@ReactProp(name="token")
|
|
152
|
+
fun setToken(view: FrameLayout, token: String) {
|
|
153
|
+
this.token = token
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Replace your React Native view with a custom fragment
|
|
158
|
+
*/
|
|
159
|
+
fun createFragment(root: FrameLayout, reactNativeViewId: Int) {
|
|
160
|
+
val parentView = root.findViewById<ViewGroup>(reactNativeViewId)
|
|
161
|
+
setupLayout(parentView)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
this.token?.let {
|
|
165
|
+
val pinwheelFragment = PinwheelFragment.newInstance(it, "react native", "2.5.0")
|
|
166
|
+
pinwheelFragment.pinwheelEventListener = this
|
|
167
|
+
val activity = reactContext.currentActivity as FragmentActivity
|
|
168
|
+
activity.supportFragmentManager
|
|
169
|
+
.beginTransaction()
|
|
170
|
+
.replace(reactNativeViewId, pinwheelFragment, reactNativeViewId.toString())
|
|
171
|
+
.commit()
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
fun setupLayout(view: View) {
|
|
176
|
+
Choreographer.getInstance().postFrameCallback(object: Choreographer.FrameCallback {
|
|
177
|
+
override fun doFrame(frameTimeNanos: Long) {
|
|
178
|
+
manuallyLayoutChildren(view)
|
|
179
|
+
view.viewTreeObserver.dispatchOnGlobalLayout()
|
|
180
|
+
Choreographer.getInstance().postFrameCallback(this)
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
override fun onEvent(eventName: PinwheelEventType, payload: PinwheelEventPayload?) {
|
|
186
|
+
val params = WritableNativeMap()
|
|
187
|
+
params.putString("name", eventName.toString())
|
|
188
|
+
params.putMap("payload", payload?.toWritableMap())
|
|
189
|
+
reactContext
|
|
190
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
191
|
+
.emit("PINWHEEL_EVENT", params)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Layout all children properly
|
|
196
|
+
*/
|
|
197
|
+
private fun manuallyLayoutChildren(view: View) {
|
|
198
|
+
// propWidth and propHeight coming from react-native props
|
|
199
|
+
val width = requireNotNull(propWidth)
|
|
200
|
+
val height = requireNotNull(propHeight)
|
|
201
|
+
|
|
202
|
+
view.measure(
|
|
203
|
+
View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
|
|
204
|
+
View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY))
|
|
205
|
+
|
|
206
|
+
view.layout(0, 0, width, height)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
companion object {
|
|
210
|
+
private const val REACT_CLASS = "RNTPinwheel"
|
|
211
|
+
private const val COMMAND_CREATE = 1
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
package com.underdog_tech.react
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
6
|
+
import com.facebook.react.bridge.ReactMethod
|
|
7
|
+
import com.facebook.react.bridge.WritableMap
|
|
8
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
9
|
+
|
|
10
|
+
class RNTPinwheelEvents(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
|
11
|
+
companion object {
|
|
12
|
+
private const val EVENT_KEY = "PINWHEEL_EVENT"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
override fun getName(): String {
|
|
16
|
+
return "RNTPinwheelEvents"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@ReactMethod
|
|
20
|
+
fun anExposedMethod() {
|
|
21
|
+
val currentContext = reactApplicationContext
|
|
22
|
+
val eventName = "PINWHEEL_EVENT"
|
|
23
|
+
val params: WritableMap = Arguments.createMap().apply {
|
|
24
|
+
putString("type", "myEventType")
|
|
25
|
+
}
|
|
26
|
+
sendEvent(currentContext, eventName, params)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fun sendEvent(reactContext: ReactApplicationContext, eventName: String, params: WritableMap?) {
|
|
30
|
+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java).emit(eventName, params)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private var listenerCount = 0
|
|
34
|
+
|
|
35
|
+
@ReactMethod
|
|
36
|
+
fun addListener(eventName: String) {
|
|
37
|
+
if (listenerCount == 0) {
|
|
38
|
+
// Set up any upstream listeners or background tasks as necessary
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
listenerCount += 1
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@ReactMethod
|
|
45
|
+
fun removeListeners(count: Int) {
|
|
46
|
+
listenerCount -= count
|
|
47
|
+
if (listenerCount == 0) {
|
|
48
|
+
// Remove upstream listeners, stop unnecessary background tasks
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Importing package.json here causes a problem with the folder structure when we npm pack and publish.
|
|
3
3
|
*/
|
|
4
|
-
export declare const VERSION = "2.
|
|
4
|
+
export declare const VERSION = "2.5.0";
|
|
5
5
|
export declare const LINK_PAGE_URL = "https://cdn.getpinwheel.com/link-v2.3.0.html";
|
|
6
6
|
export declare const PINWHEEL_DOMAIN = "getpinwheel.com";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Importing package.json here causes a problem with the folder structure when we npm pack and publish.
|
|
3
3
|
*/
|
|
4
|
-
export const VERSION = '2.
|
|
4
|
+
export const VERSION = '2.5.0';
|
|
5
5
|
export const LINK_PAGE_URL = 'https://cdn.getpinwheel.com/link-v2.3.0.html';
|
|
6
6
|
export const PINWHEEL_DOMAIN = 'getpinwheel.com';
|
package/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
// @ts-ignore-next-line
|
|
3
|
+
import Pinwheel from './pinwheel-wrapper';
|
|
4
|
+
import { SafeAreaView, StyleSheet } from 'react-native';
|
|
5
|
+
const styles = StyleSheet.create({
|
|
6
|
+
container: {
|
|
7
|
+
flex: 1,
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
export const PINWHEEL_MESSAGE_TYPES = {
|
|
11
|
+
PINWHEEL_EXIT: 'PINWHEEL_EXIT',
|
|
12
|
+
PINWHEEL_MODAL_CLOSE: 'PINWHEEL_MODAL_CLOSE',
|
|
13
|
+
PINWHEEL_LOAD_COMPLETE: 'PINWHEEL_LOAD_COMPLETE',
|
|
14
|
+
PINWHEEL_SUCCESS: 'PINWHEEL_SUCCESS',
|
|
15
|
+
PINWHEEL_EVENT: 'PINWHEEL_EVENT',
|
|
16
|
+
};
|
|
17
|
+
export default ({ linkToken, onLogin, onLoginAttempt, onSuccess, onError, onExit, onEvent }) => {
|
|
18
|
+
const handleEvent = (event) => {
|
|
19
|
+
if (!event) {
|
|
20
|
+
// first event is always an empty string
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const { name, payload } = event;
|
|
24
|
+
onEvent && onEvent(name, payload);
|
|
25
|
+
switch (name.toLowerCase()) {
|
|
26
|
+
case 'exit':
|
|
27
|
+
// console.log(`case: exit, onExit: ${onExit}`);
|
|
28
|
+
onExit && onExit(payload);
|
|
29
|
+
break;
|
|
30
|
+
case 'success':
|
|
31
|
+
// console.log(`case: success, onSuccess: ${onSuccess}`);
|
|
32
|
+
onSuccess && onSuccess(payload);
|
|
33
|
+
break;
|
|
34
|
+
case 'login':
|
|
35
|
+
// console.log(`case: login, onLogin: ${onLogin}`);
|
|
36
|
+
onLogin && onLogin(payload);
|
|
37
|
+
break;
|
|
38
|
+
case 'login_attempt':
|
|
39
|
+
// console.log(`case: login_attempt, onLoginAttempt: ${onLoginAttempt}`);
|
|
40
|
+
onLoginAttempt && onLoginAttempt(payload);
|
|
41
|
+
break;
|
|
42
|
+
case 'error':
|
|
43
|
+
// console.log(`case: error, onError: ${onError}`);
|
|
44
|
+
onError && onError(payload);
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return (<SafeAreaView style={styles.container}>
|
|
50
|
+
{linkToken && <Pinwheel token={linkToken} style={{ flex: 1 }} onEvent={handleEvent}/>}
|
|
51
|
+
</SafeAreaView>);
|
|
52
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#import "RNTPinwheelEvents.h"
|
|
2
|
+
|
|
3
|
+
@implementation RNTPinwheelEvents
|
|
4
|
+
{
|
|
5
|
+
bool hasListeners; // This is an instance variable declaration.
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
RCT_EXPORT_MODULE();
|
|
9
|
+
+ (BOOL)requiresMainQueueSetup {
|
|
10
|
+
return NO; // change this to NO if you don't need the main thread
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
+ (instancetype)sharedInstance {
|
|
14
|
+
static RNTPinwheelEvents *sharedInstance = nil;
|
|
15
|
+
static dispatch_once_t onceToken;
|
|
16
|
+
dispatch_once(&onceToken, ^{
|
|
17
|
+
sharedInstance = [[super allocWithZone:NULL] init];
|
|
18
|
+
});
|
|
19
|
+
return sharedInstance;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
+ (id)allocWithZone:(struct _NSZone *)zone {
|
|
23
|
+
return [self sharedInstance];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
- (id)copyWithZone:(NSZone *)zone {
|
|
27
|
+
return self;
|
|
28
|
+
}
|
|
29
|
+
// Overriding the default init to make sure it's not used directly
|
|
30
|
+
- (instancetype)init {
|
|
31
|
+
if (self = [super init]) {
|
|
32
|
+
// Custom initialization if needed
|
|
33
|
+
}
|
|
34
|
+
return self;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Will be called when this module's first listener is added.
|
|
38
|
+
-(void)startObserving {
|
|
39
|
+
NSLog(@"startObserving called");
|
|
40
|
+
hasListeners = YES;
|
|
41
|
+
// Set up any upstream listeners or background tasks as necessary
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Will be called when this module's last listener is removed, or on dealloc.
|
|
45
|
+
-(void)stopObserving {
|
|
46
|
+
NSLog(@"stopObserving called");
|
|
47
|
+
hasListeners = NO;
|
|
48
|
+
// Remove upstream listeners, stop unnecessary background tasks
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
- (void)handlePinwheelEvent:(NSDictionary<NSString *, id> *)payload
|
|
52
|
+
{
|
|
53
|
+
if (hasListeners) {// Only send events if anyone is listening
|
|
54
|
+
[self sendEventWithName:@"PINWHEEL_EVENT" body:payload];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
- (NSArray<NSString *> *)supportedEvents {
|
|
59
|
+
return @[@"PINWHEEL_EVENT"]; // Add more event names here.
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#import <React/RCTViewManager.h>
|
|
2
|
+
#import "RNTPinwheelView.h"
|
|
3
|
+
|
|
4
|
+
@interface RNTPinwheelManager : RCTViewManager
|
|
5
|
+
|
|
6
|
+
@end
|
|
7
|
+
|
|
8
|
+
@implementation RNTPinwheelManager : RCTViewManager
|
|
9
|
+
|
|
10
|
+
RCT_EXPORT_MODULE(RNTPinwheelManager);
|
|
11
|
+
|
|
12
|
+
- (UIView *)view
|
|
13
|
+
{
|
|
14
|
+
RNTPinwheelView *pv = [[RNTPinwheelView alloc] init];
|
|
15
|
+
return pv;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
RCT_EXPORT_VIEW_PROPERTY(token, NSString);
|
|
19
|
+
|
|
20
|
+
@end
|
|
21
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
#import <PinwheelSDK/PinwheelSDK-Swift.h>
|
|
3
|
+
#import "RNTPinwheelEvents.h"
|
|
4
|
+
|
|
5
|
+
@interface RNTPinwheelView : UIView <PinwheelWrapperDelegate>
|
|
6
|
+
|
|
7
|
+
@property (nonatomic, strong) PinwheelWrapperVC *pinwheelWrapperVC;
|
|
8
|
+
@property (nonatomic, assign) NSString *token;
|
|
9
|
+
|
|
10
|
+
- (instancetype)initWithFrame:(CGRect)frame token:(NSString *)token;
|
|
11
|
+
|
|
12
|
+
@end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#import "RNTPinwheelView.h"
|
|
2
|
+
|
|
3
|
+
@implementation RNTPinwheelView
|
|
4
|
+
|
|
5
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
6
|
+
if ((self = [super initWithFrame:frame])) {
|
|
7
|
+
[self initPinwheelWrapperVC];
|
|
8
|
+
}
|
|
9
|
+
return self;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
- (instancetype)initWithFrame:(CGRect)frame token:(NSString *)token {
|
|
13
|
+
if ((self = [super initWithFrame:frame])) {
|
|
14
|
+
_token = token;
|
|
15
|
+
}
|
|
16
|
+
return self;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
- (void)initPinwheelWrapperVC {
|
|
20
|
+
if (self.token != nil && self.pinwheelWrapperVC == nil) {
|
|
21
|
+
self.pinwheelWrapperVC = [[PinwheelWrapperVC alloc] initWithToken:self.token delegate:self sdk:@"react native" version: @"2.5.0"];
|
|
22
|
+
[self addSubview:self.pinwheelWrapperVC.view];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
- (void)setToken:(NSString *)newToken {
|
|
27
|
+
if (![_token isEqualToString:newToken]) {
|
|
28
|
+
_token = newToken;
|
|
29
|
+
[self initPinwheelWrapperVC];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
- (void)layoutSubviews
|
|
34
|
+
{
|
|
35
|
+
[super layoutSubviews];
|
|
36
|
+
self.pinwheelWrapperVC.view.frame = self.bounds;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
- (void)onEventWithName:(NSString *)name event:(NSDictionary<NSString *, id> *)event {
|
|
40
|
+
NSLog(@"%@", name);
|
|
41
|
+
NSDictionary *dataToSend = @{@"name": name, @"payload": event};
|
|
42
|
+
[RNTPinwheelEvents.sharedInstance handlePinwheelEvent:dataToSend];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
- (void)onExit:(NSDictionary<NSString *, id> *)error {
|
|
46
|
+
NSLog(@"%@", error);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
- (void)onSuccess:(NSDictionary<NSString *, id> *)result {
|
|
50
|
+
NSLog(@"%@", result);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
- (void)onLogin:(NSDictionary<NSString *, id> *)result {
|
|
54
|
+
NSLog(@"%@", result);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
- (void)onLoginAttempt:(NSDictionary<NSString *, id> *)result {
|
|
58
|
+
NSLog(@"%@", result);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
- (void)onError:(NSDictionary<NSString *, id> *)error {
|
|
62
|
+
NSLog(@"%@", error);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@end
|
package/package.json
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pinwheel/react-native-pinwheel",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Pinwheel React Native SDK",
|
|
6
|
-
"main": "
|
|
7
|
-
"types": "
|
|
8
|
-
"files": [
|
|
9
|
-
"lib/**/*"
|
|
10
|
-
],
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
11
8
|
"scripts": {
|
|
12
9
|
"build": "tsc",
|
|
13
10
|
"bump-pkg-version": "./scripts/bump-pkg-version.sh",
|
|
@@ -17,12 +14,10 @@
|
|
|
17
14
|
"license": "MIT",
|
|
18
15
|
"peerDependencies": {
|
|
19
16
|
"react": "^16.13.1 || ^17 || ^18",
|
|
20
|
-
"react-native": "*"
|
|
21
|
-
"react-native-webview": "*"
|
|
17
|
+
"react-native": "*"
|
|
22
18
|
},
|
|
23
19
|
"devDependencies": {
|
|
24
20
|
"@types/react-native": "^0.72.2",
|
|
25
|
-
"react-native-webview": "^13.3.1",
|
|
26
21
|
"typescript": "^4.0.3"
|
|
27
22
|
}
|
|
28
23
|
}
|
package/pinwheel-view.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { UIManager, findNodeHandle, NativeEventEmitter, NativeModules } from 'react-native';
|
|
3
|
+
import { RNTPinwheel } from './pinwheel-view';
|
|
4
|
+
const createFragment = (viewId) => {
|
|
5
|
+
UIManager.dispatchViewManagerCommand(viewId,
|
|
6
|
+
// we are calling the 'create' command
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
UIManager.RNTPinwheel.Commands.create.toString(), [viewId]);
|
|
9
|
+
};
|
|
10
|
+
const RNTPinwheelView = (props) => {
|
|
11
|
+
const ref = useRef(null);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
setTimeout(() => {
|
|
14
|
+
const viewId = findNodeHandle(ref.current);
|
|
15
|
+
if (viewId) {
|
|
16
|
+
createFragment(viewId);
|
|
17
|
+
}
|
|
18
|
+
// events
|
|
19
|
+
const { RNTPinwheelEvents } = NativeModules;
|
|
20
|
+
const eventEmitter = new NativeEventEmitter(RNTPinwheelEvents);
|
|
21
|
+
const eventListener = eventEmitter.addListener('PINWHEEL_EVENT', (event) => {
|
|
22
|
+
props.onEvent(event);
|
|
23
|
+
});
|
|
24
|
+
}, 10);
|
|
25
|
+
}, []);
|
|
26
|
+
return <RNTPinwheel {...props} onEvent={(event) => { console.log `rawbee: ${JSON.stringify(event)}`; }} ref={ref}/>;
|
|
27
|
+
};
|
|
28
|
+
export default RNTPinwheelView;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import { NativeEventEmitter, NativeModules } from 'react-native';
|
|
3
|
+
import { RNTPinwheel } from './pinwheel-view';
|
|
4
|
+
const RNTPinwheelView = (props) => {
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const { RNTPinwheelEvents } = NativeModules;
|
|
7
|
+
const eventEmitter = new NativeEventEmitter(RNTPinwheelEvents);
|
|
8
|
+
const eventListener = eventEmitter.addListener('PINWHEEL_EVENT', (event) => {
|
|
9
|
+
props.onEvent(event);
|
|
10
|
+
});
|
|
11
|
+
return () => {
|
|
12
|
+
eventListener.remove();
|
|
13
|
+
};
|
|
14
|
+
}, []);
|
|
15
|
+
return <RNTPinwheel {...props}/>;
|
|
16
|
+
};
|
|
17
|
+
export default RNTPinwheelView;
|
package/lib/index.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { WebView } from 'react-native-webview';
|
|
3
|
-
import { Linking, Platform, SafeAreaView, StyleSheet } from 'react-native';
|
|
4
|
-
import { LINK_PAGE_URL, PINWHEEL_DOMAIN, VERSION } from './constants';
|
|
5
|
-
const styles = StyleSheet.create({
|
|
6
|
-
container: {
|
|
7
|
-
flex: 1,
|
|
8
|
-
},
|
|
9
|
-
});
|
|
10
|
-
export const PINWHEEL_MESSAGE_TYPES = {
|
|
11
|
-
PINWHEEL_EXIT: 'PINWHEEL_EXIT',
|
|
12
|
-
PINWHEEL_MODAL_CLOSE: 'PINWHEEL_MODAL_CLOSE',
|
|
13
|
-
PINWHEEL_LOAD_COMPLETE: 'PINWHEEL_LOAD_COMPLETE',
|
|
14
|
-
PINWHEEL_SUCCESS: 'PINWHEEL_SUCCESS',
|
|
15
|
-
PINWHEEL_EVENT: 'PINWHEEL_EVENT',
|
|
16
|
-
};
|
|
17
|
-
export default ({ linkToken, onLogin, onLoginAttempt, onSuccess, onError, onExit, onEvent }) => {
|
|
18
|
-
const handleEvent = (event) => {
|
|
19
|
-
if (!event) {
|
|
20
|
-
// first event is always an empty string
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
let eventData;
|
|
24
|
-
try {
|
|
25
|
-
eventData = JSON.parse(event.nativeEvent.data);
|
|
26
|
-
}
|
|
27
|
-
catch (_error) {
|
|
28
|
-
let error = _error;
|
|
29
|
-
console.error(error);
|
|
30
|
-
onExit && onExit(error);
|
|
31
|
-
onError && onError(error);
|
|
32
|
-
onEvent && onEvent('error', error);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
const { type, eventName, payload } = eventData;
|
|
36
|
-
if (type === 'PINWHEEL_EVENT') {
|
|
37
|
-
onEvent && onEvent(eventName, payload);
|
|
38
|
-
switch (eventName) {
|
|
39
|
-
case 'exit':
|
|
40
|
-
onExit && onExit(payload);
|
|
41
|
-
break;
|
|
42
|
-
case 'success':
|
|
43
|
-
onSuccess && onSuccess(payload);
|
|
44
|
-
break;
|
|
45
|
-
case 'login':
|
|
46
|
-
onLogin && onLogin(payload);
|
|
47
|
-
break;
|
|
48
|
-
case 'login_attempt':
|
|
49
|
-
onLoginAttempt && onLoginAttempt(payload);
|
|
50
|
-
break;
|
|
51
|
-
case 'error':
|
|
52
|
-
onError && onError(payload);
|
|
53
|
-
break;
|
|
54
|
-
default:
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
const now = Date.now();
|
|
59
|
-
const [major, minor, patch] = VERSION.split('.').map(x => Number(x));
|
|
60
|
-
const runFirst = `
|
|
61
|
-
const uuidKey = 'pinwheel-uuid';
|
|
62
|
-
const localStorage = window.localStorage;
|
|
63
|
-
let uuid = localStorage.getItem(uuidKey);
|
|
64
|
-
if(!uuid) {
|
|
65
|
-
uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
66
|
-
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
|
67
|
-
return v.toString(16);
|
|
68
|
-
});
|
|
69
|
-
localStorage.setItem(uuidKey, uuid);
|
|
70
|
-
}
|
|
71
|
-
try {
|
|
72
|
-
window.addEventListener('message', event => {
|
|
73
|
-
window.ReactNativeWebView.postMessage(JSON.stringify(event.data))
|
|
74
|
-
});
|
|
75
|
-
window.postMessage(
|
|
76
|
-
{
|
|
77
|
-
type: 'PINWHEEL_INIT',
|
|
78
|
-
payload: {
|
|
79
|
-
platform: "${Platform.OS}",
|
|
80
|
-
sdk: 'react native',
|
|
81
|
-
version: {
|
|
82
|
-
major: ${major},
|
|
83
|
-
minor: ${minor},
|
|
84
|
-
patch: ${patch}
|
|
85
|
-
},
|
|
86
|
-
initializationOptions: {
|
|
87
|
-
hasOnSuccess: ${!!onSuccess},
|
|
88
|
-
hasOnEvent: ${!!onEvent},
|
|
89
|
-
hasOnExit: ${!!onExit},
|
|
90
|
-
hasOnError: ${!!onError},
|
|
91
|
-
hasOnLogin: ${!!onLogin},
|
|
92
|
-
},
|
|
93
|
-
linkToken: '${linkToken}',
|
|
94
|
-
uniqueUserId: uuid,
|
|
95
|
-
initializationTimestamp: ${now}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
);
|
|
99
|
-
} catch (err) {
|
|
100
|
-
console.error(err);
|
|
101
|
-
}
|
|
102
|
-
true;
|
|
103
|
-
`;
|
|
104
|
-
return (<SafeAreaView style={styles.container}>
|
|
105
|
-
<WebView source={{ uri: LINK_PAGE_URL }} onMessage={handleEvent} injectedJavaScript={runFirst} onShouldStartLoadWithRequest={(request) => {
|
|
106
|
-
const targetURL = request.url;
|
|
107
|
-
const isLinkPage = targetURL.includes(PINWHEEL_DOMAIN);
|
|
108
|
-
if (!isLinkPage) {
|
|
109
|
-
Linking.canOpenURL(targetURL).then(supported => {
|
|
110
|
-
if (supported) {
|
|
111
|
-
Linking.openURL(targetURL).then(() => { });
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
console.warn('Don\'t know how to open URL: ' + targetURL);
|
|
115
|
-
}
|
|
116
|
-
return false;
|
|
117
|
-
}).catch(err => console.error('An error occurred ', err));
|
|
118
|
-
}
|
|
119
|
-
return isLinkPage;
|
|
120
|
-
}}/>
|
|
121
|
-
</SafeAreaView>);
|
|
122
|
-
};
|
|
File without changes
|