react-native-iap 7.5.0 → 7.5.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/CHANGELOG.md +9 -0
- package/README.md +46 -28
- package/android/src/amazon/java/com/dooboolab/RNIap/RNIapAmazonModule.java +10 -0
- package/android/src/play/java/com/dooboolab/RNIap/RNIapModule.java +16 -12
- package/package.json +1 -1
- package/src/hooks/useIAP.d.ts +2 -2
- package/src/hooks/useIAP.js +1 -1
- package/src/types/index.d.ts +1 -1
- package/src/hooks/withIAPContext.tsx +0 -150
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
## Changelogs
|
|
2
2
|
|
|
3
|
+
# 7.5.1
|
|
4
|
+
|
|
5
|
+
- Refresh SkuDetails (#1566)
|
|
6
|
+
- fix: NativeEventEmitter warnings since ReactNative 0.65 (#1544)
|
|
7
|
+
- Using TCK Tested JDK builds of OpenJDK (#1525)
|
|
8
|
+
- Add missing types for finishTransaction within useIAP() (#1533)
|
|
9
|
+
|
|
3
10
|
# 7.5.0
|
|
4
11
|
|
|
5
12
|
### Bugfix
|
|
13
|
+
|
|
6
14
|
- Fix canceled purchase dangling [#1504](https://github.com/dooboolab/react-native-iap/pull/1504)
|
|
7
15
|
|
|
8
16
|
### Dependencies
|
|
17
|
+
|
|
9
18
|
- Set default `androidX` version [#1505](https://github.com/dooboolab/react-native-iap/pull/1505)
|
|
10
19
|
- Update packages [#1506](https://github.com/dooboolab/react-native-iap/pull/1506)
|
|
11
20
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-

|
|
2
|
-
|
|
1
|
+
# 
|
|
2
|
+
|
|
3
3
|
[](https://npmjs.org/package/react-native-iap)
|
|
4
|
+
[](https://npmjs.org/package/react-native-iap)
|
|
4
5
|
[](https://npmjs.org/package/react-native-iap)
|
|
5
6
|
[](https://travis-ci.com/dooboolab/react-native-iap)
|
|
6
7
|
[](https://github.com/dooboolab/react-native-iap/actions/workflows/ci.yml)
|
|
@@ -20,10 +21,17 @@ Published in [website](https://react-native-iap.dooboolab.com).
|
|
|
20
21
|
|
|
21
22
|
## Announcement
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
- Version `8.0.0` is currently in release candidate. The module is completely rewritten with `Kotlin` and `Swift` for maintenenance issue by [andresesfm](https://github.com/andresesfm) 🔆. You may install this for early preview.
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
yarn add react-native-iap@next
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- React Native IAP hook is out. You can see [medium post](https://medium.com/dooboolab/announcing-react-native-iap-hooks-96c7ffd3f19a) on how to use it.
|
|
31
|
+
|
|
32
|
+
- The `react-native-iap` module hasn't been maintained well recently. We are thinking of participating again and make the module healthier. Please refer to [2021 Maintenance plan](https://github.com/dooboolab/react-native-iap/issues/1241) and share with us how you or your organization is using it. Happy new year 🎉
|
|
24
33
|
|
|
25
|
-
The
|
|
26
|
-
- The sample code is out in [Sponsor page](https://github.com/hyochan/dooboolab.com/blob/master/src/components/pages/Sponsor.tsx) in [dooboolab.com](https://github.com/hyochan/dooboolab.com) repository which sadly is rejected by Apple because of lacking product features. I will work on another example project to support this module. More information in [#1241 commment](https://github.com/dooboolab/react-native-iap/issues/1241#issuecomment-798540785).
|
|
34
|
+
- The sample code is out in [Sponsor page](https://github.com/hyochan/dooboolab.com/blob/master/src/components/pages/Sponsor.tsx) in [dooboolab.com](https://github.com/hyochan/dooboolab.com) repository which sadly is rejected by Apple because of lacking product features. I will work on another example project to support this module. More information in [#1241 commment](https://github.com/dooboolab/react-native-iap/issues/1241#issuecomment-798540785).
|
|
27
35
|
|
|
28
36
|
## Introduction
|
|
29
37
|
|
|
@@ -35,26 +43,28 @@ Also, implementing the client side is only one side of the coin, you'll have to
|
|
|
35
43
|
If you're looking for a module going further than react-native-iap, we recommend using [react-native-iaphub](https://github.com/iaphub/react-native-iaphub) which is taking care of everything from the client side to the server side.
|
|
36
44
|
|
|
37
45
|
⚠️ Most of users experiencing issues are caused by:
|
|
38
|
-
- A device simulator, use a real device for testing!
|
|
39
|
-
- The sandbox environment of the project not being configured properly ([Configure android sandbox](https://www.iaphub.com/docs/set-up-android/configure-sandbox-testing), [Configure ios sandbox](https://www.iaphub.com/docs/set-up-ios/configure-sandbox-testing/))
|
|
40
|
-
- An incorrect usage of the library
|
|
41
46
|
|
|
47
|
+
- A device simulator, use a real device for testing!
|
|
48
|
+
- The sandbox environment of the project not being configured properly ([Configure android sandbox](https://www.iaphub.com/docs/set-up-android/configure-sandbox-testing), [Configure ios sandbox](https://www.iaphub.com/docs/set-up-ios/configure-sandbox-testing/))
|
|
49
|
+
- An incorrect usage of the library
|
|
50
|
+
|
|
51
|
+
## Demo
|
|
42
52
|
|
|
43
|
-
Demo
|
|
44
|
-
----------
|
|
45
|
-
>
|
|
46
53
|
> 
|
|
47
54
|
|
|
48
55
|
<!-- Inline anchors -->
|
|
56
|
+
|
|
49
57
|
[a-acknowledge-purchase-android]: #finishing-a-purchase
|
|
50
58
|
[a-migration-guide]: #migration-guide
|
|
51
59
|
[a-purchase-flow]: #new-purchase-flow
|
|
52
60
|
|
|
53
61
|
<!-- Official Blog -->
|
|
62
|
+
|
|
54
63
|
[blog-config-steps]: https://medium.com/p/121622d26b67
|
|
55
64
|
[blog-v3-note]: https://medium.com/p/1259e0b0c017
|
|
56
65
|
|
|
57
66
|
<!-- Internals -->
|
|
67
|
+
|
|
58
68
|
[contribute]: https://github.com/dooboolab/react-native-iap/blob/master/CONTRIBUTING.md
|
|
59
69
|
[example]: https://github.com/dooboolab/react-native-iap/tree/master/IapExample
|
|
60
70
|
[issue-126-c1]: https://github.com/dooboolab/react-native-iap/issues/126#issuecomment-439084872
|
|
@@ -72,8 +82,9 @@ Demo
|
|
|
72
82
|
[readme-deprecated]: https://github.com/dooboolab/react-native-iap/blob/master/README_DEPRECATED.md
|
|
73
83
|
|
|
74
84
|
<!-- Externals -->
|
|
75
|
-
|
|
76
|
-
[android-
|
|
85
|
+
|
|
86
|
+
[android-acknowledge-purchase]: https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#acknowledgePurchase(com.android.billingclient.api.AcknowledgePurchaseParams,%20com.android.billingclient.api.AcknowledgePurchaseResponseListener) 'BillingClient#acknowledgePurchase()'
|
|
87
|
+
[android-end-connection]: https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#endConnection() 'BillingClient#endConnection()'
|
|
77
88
|
[android-iap-validation-guide]: https://developer.android.com/google/play/billing/billing_library_overview
|
|
78
89
|
[android-migrate-androidx]: https://developer.android.com/jetpack/androidx/migrate
|
|
79
90
|
[android-sku-details]: https://developer.android.com/reference/com/android/billingclient/api/SkuDetails
|
|
@@ -85,80 +96,87 @@ Demo
|
|
|
85
96
|
[stackoverflow-android-iap-validation]: https://stackoverflow.com/questions/35127086
|
|
86
97
|
[android-access-token-example-repo]: https://github.com/Bang9/android-get-access-token-example
|
|
87
98
|
|
|
88
|
-
Quick News
|
|
89
|
-
|
|
99
|
+
## Quick News
|
|
100
|
+
|
|
90
101
|
- We had hard time supporting `react-native-iap` issues that did not provide working codes or any other examples. Therefore, we've decided to make an `example` app called [DoobooIAP](https://github.com/hyochan/DoobooIAP), which will contain all the features of `IAP`'s and willing to continuously improve to support real-life examples. [@Bang9](http://github.com/bang9) who had been helping many others for `react-native-iap`, is willing to support this repo so he will grant $300 of our income in `opencollective` as described in [#855](https://github.com/dooboolab/react-native-iap/issues/855) :tada:.
|
|
91
102
|
- `react-native-iap@4.0.8` ~ `react-native-iap@4.1.0` is incompatible with `react-native <0.61`. This is fixed in `react-native-iap@4.1.1` and above.
|
|
92
103
|
- `react-native-iap@4.0.0` has been released. You can see [#716](https://github.com/dooboolab/react-native-iap/pull/716) for updates.
|
|
93
104
|
- In the past, `react-native-iap@^3.*` has been updated very promptly for migration issues.
|
|
94
|
-
|
|
105
|
+
Don't get surprised too much on why it is bumping up version so quickly these days.
|
|
95
106
|
1. Migrated to new `AndroidX` APIs.
|
|
96
107
|
2. Migrated to new `Android` billing client which is `> 2.0.0`.
|
|
97
108
|
- [`acknowledgePurchase()`][android-acknowledge-purchase] has been added since `3.2.0` which is very important.
|
|
98
109
|
3. New [Purchase Flow][a-purchase-flow]
|
|
99
110
|
4. More is coming in `iOS 13`.
|
|
100
111
|
|
|
101
|
-
Breaking Changes
|
|
102
|
-
----------------
|
|
112
|
+
## Breaking Changes
|
|
103
113
|
|
|
104
114
|
[7.4.0]
|
|
115
|
+
|
|
105
116
|
- Now using React's Context to manage IAP state
|
|
106
117
|
- Introduce `withIAPContext` HOC ([how to use](docs/docs/usage_instructions/using_hooks.md))
|
|
107
118
|
|
|
108
119
|
[7.1.0]
|
|
120
|
+
|
|
109
121
|
- `androidOldSku` is no longer required [#1438](https://github.com/dooboolab/react-native-iap/pull/1438).
|
|
110
122
|
|
|
111
123
|
[6.1.0]
|
|
124
|
+
|
|
112
125
|
- Creates two variants: `play` and `amazon` and only uses the required code.
|
|
113
126
|
```
|
|
114
127
|
NOTE: This would be a breaking change with a very simple fix described in the documentation. To add: `missingDimensionStrategy 'store', 'play'` `in build.gradle`
|
|
115
128
|
```
|
|
116
|
-
[3.0.0+]
|
|
117
|
-
[react-native-iap V3 note][blog-v3-note]
|
|
129
|
+
[3.0.0+]
|
|
130
|
+
[react-native-iap V3 note][blog-v3-note]
|
|
131
|
+
|
|
132
|
+
## Configuration of Google Play & iTunes Connect
|
|
118
133
|
|
|
119
|
-
Configuration of Google Play & iTunes Connect
|
|
120
|
-
---------------------------------------------
|
|
121
134
|
- Please refer to [Blog][blog-config-steps].
|
|
122
135
|
|
|
123
|
-
[Deprecated README][readme-deprecated]
|
|
124
|
-
|
|
136
|
+
## [Deprecated README][readme-deprecated]
|
|
137
|
+
|
|
125
138
|
- If you are using `react-native-iap@^2.*`, please follow the above README.
|
|
126
139
|
|
|
127
|
-
Usage
|
|
128
|
-
|
|
140
|
+
## Usage
|
|
141
|
+
|
|
129
142
|
You can look in the [`RNIapExample/`][example] folder to try the example.
|
|
130
143
|
|
|
131
144
|
NOTE: To run `RNIapExample` on Android use the variant flag as follows:
|
|
145
|
+
|
|
132
146
|
```
|
|
133
147
|
yarn android --variant=MY_VARIANT
|
|
134
148
|
```
|
|
149
|
+
|
|
135
150
|
where `MY_VARIANT` is `PlayDebug` or `AmazonDebug`
|
|
136
151
|
|
|
137
152
|
Below is basic implementation which is also provided in `RNIapExample` project.
|
|
138
153
|
|
|
139
154
|
If you want more advanced one please refer to [dooboolab.com/sponsor.tsx](https://github.com/hyochan/dooboolab.com/blob/master/src/components/pages/Sponsor.tsx)
|
|
140
155
|
|
|
141
|
-
Sponsoring
|
|
142
|
-
----------
|
|
156
|
+
## Sponsoring
|
|
143
157
|
|
|
144
158
|
Since `IAP` itself is not perfect on each platform, we desperately need
|
|
145
159
|
this project to be maintained. If you'd like to help us, please consider being
|
|
146
160
|
with us in [Open Collective](https://opencollective.com/react-native-iap).
|
|
147
161
|
|
|
148
162
|
### Sponsors
|
|
163
|
+
|
|
149
164
|
Support this project by becoming a sponsor. Your logo will show up here with
|
|
150
165
|
a link to your website. [Become a sponsor][open-collective-sponsor].
|
|
151
166
|
<a href="https://opencollective.com/react-native-iap#sponsors" target="_blank"><img src="https://opencollective.com/react-native-iap/sponsors.svg?width=890"></a>
|
|
152
167
|
|
|
153
168
|
### Backers
|
|
169
|
+
|
|
154
170
|
Please be our [Backers][open-collective-backer].
|
|
155
171
|
<a href="https://opencollective.com/react-native-iap#backers" target="_blank"><img src="https://opencollective.com/react-native-iap/backers.svg?width=890"></a>
|
|
156
172
|
|
|
157
173
|
### Contributing
|
|
174
|
+
|
|
158
175
|
Please make sure to read the [Contributing Guide][contribute] before making a pull request.
|
|
159
176
|
Thank you to all the people who helped to maintain and upgrade this project!
|
|
160
177
|
|
|
161
178
|
<a href="graphs/contributors"><img src="https://opencollective.com/react-native-iap/contributors.svg?width=890" /></a>
|
|
179
|
+
|
|
162
180
|
<hr>
|
|
163
181
|
|
|
164
182
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fdooboolab%2Freact-native-iap?ref=badge_large)
|
|
@@ -117,4 +117,14 @@ public class RNIapAmazonModule extends ReactContextBaseJavaModule {
|
|
|
117
117
|
public void startListening(final Promise promise) {
|
|
118
118
|
sendUnconsumedPurchases(promise);
|
|
119
119
|
}
|
|
120
|
+
|
|
121
|
+
@ReactMethod
|
|
122
|
+
public void addListener(String eventName) {
|
|
123
|
+
// Keep: Required for RN built in Event Emitter Calls.
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@ReactMethod
|
|
127
|
+
public void removeListeners(double count) {
|
|
128
|
+
// Keep: Required for RN built in Event Emitter Calls.
|
|
129
|
+
}
|
|
120
130
|
}
|
|
@@ -36,7 +36,9 @@ import com.google.android.gms.common.ConnectionResult;
|
|
|
36
36
|
import com.google.android.gms.common.GoogleApiAvailability;
|
|
37
37
|
import java.math.BigDecimal;
|
|
38
38
|
import java.util.ArrayList;
|
|
39
|
+
import java.util.HashMap;
|
|
39
40
|
import java.util.List;
|
|
41
|
+
import java.util.Map;
|
|
40
42
|
|
|
41
43
|
public class RNIapModule extends ReactContextBaseJavaModule implements PurchasesUpdatedListener {
|
|
42
44
|
final String TAG = "RNIapModule";
|
|
@@ -45,12 +47,12 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
|
|
|
45
47
|
private final ReactContext reactContext;
|
|
46
48
|
private BillingClient billingClientCache;
|
|
47
49
|
|
|
48
|
-
private final
|
|
50
|
+
private final Map<String, SkuDetails> skus;
|
|
49
51
|
|
|
50
52
|
public RNIapModule(ReactApplicationContext reactContext) {
|
|
51
53
|
super(reactContext);
|
|
52
54
|
this.reactContext = reactContext;
|
|
53
|
-
this.skus = new
|
|
55
|
+
this.skus = new HashMap<>();
|
|
54
56
|
LifecycleEventListener lifecycleEventListener =
|
|
55
57
|
new LifecycleEventListener() {
|
|
56
58
|
@Override
|
|
@@ -245,9 +247,7 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
|
|
|
245
247
|
|
|
246
248
|
if (skuDetailsList != null) {
|
|
247
249
|
for (SkuDetails sku : skuDetailsList) {
|
|
248
|
-
|
|
249
|
-
skus.add(sku);
|
|
250
|
-
}
|
|
250
|
+
skus.put(sku.getSku(), sku);
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
WritableNativeArray items = new WritableNativeArray();
|
|
@@ -417,13 +417,7 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
|
|
|
417
417
|
DoobooUtils.getInstance().addPromiseForKey(PROMISE_BUY_ITEM, promise);
|
|
418
418
|
final BillingFlowParams.Builder builder = BillingFlowParams.newBuilder();
|
|
419
419
|
|
|
420
|
-
SkuDetails selectedSku =
|
|
421
|
-
for (SkuDetails skuDetail : skus) {
|
|
422
|
-
if (skuDetail.getSku().equals(sku)) {
|
|
423
|
-
selectedSku = skuDetail;
|
|
424
|
-
break;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
420
|
+
SkuDetails selectedSku = skus.get(sku);
|
|
427
421
|
|
|
428
422
|
if (selectedSku == null) {
|
|
429
423
|
String debugMessage =
|
|
@@ -663,6 +657,16 @@ public class RNIapModule extends ReactContextBaseJavaModule implements Purchases
|
|
|
663
657
|
sendUnconsumedPurchases(promise);
|
|
664
658
|
}
|
|
665
659
|
|
|
660
|
+
@ReactMethod
|
|
661
|
+
public void addListener(String eventName) {
|
|
662
|
+
// Keep: Required for RN built in Event Emitter Calls.
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
@ReactMethod
|
|
666
|
+
public void removeListeners(double count) {
|
|
667
|
+
// Keep: Required for RN built in Event Emitter Calls.
|
|
668
|
+
}
|
|
669
|
+
|
|
666
670
|
@ReactMethod
|
|
667
671
|
public String getPackageName() {
|
|
668
672
|
return getReactApplicationContext().getPackageName();
|
package/package.json
CHANGED
package/src/hooks/useIAP.d.ts
CHANGED
|
@@ -9,13 +9,13 @@ declare type IAP_STATUS = {
|
|
|
9
9
|
availablePurchases: Purchase[];
|
|
10
10
|
currentPurchase?: Purchase;
|
|
11
11
|
currentPurchaseError?: PurchaseError;
|
|
12
|
-
finishTransaction: (purchase: Purchase) => Promise<string | void>;
|
|
12
|
+
finishTransaction: (purchase: Purchase, isConsumable?: boolean, developerPayloadAndroid?: string) => Promise<string | void>;
|
|
13
13
|
getAvailablePurchases: () => Promise<void>;
|
|
14
14
|
getPurchaseHistories: () => Promise<void>;
|
|
15
15
|
getProducts: (skus: string[]) => Promise<void>;
|
|
16
16
|
getSubscriptions: (skus: string[]) => Promise<void>;
|
|
17
17
|
requestPurchase: typeof iapRequestPurchase;
|
|
18
|
-
|
|
18
|
+
requestSubscription: typeof iapRequestSubscription;
|
|
19
19
|
};
|
|
20
20
|
export declare function useIAP(): IAP_STATUS;
|
|
21
21
|
export {};
|
package/src/hooks/useIAP.js
CHANGED
|
@@ -133,6 +133,6 @@ export function useIAP() {
|
|
|
133
133
|
getAvailablePurchases: getAvailablePurchases,
|
|
134
134
|
getPurchaseHistories: getPurchaseHistories,
|
|
135
135
|
requestPurchase: iapRequestPurchase,
|
|
136
|
-
|
|
136
|
+
requestSubscription: iapRequestSubscription,
|
|
137
137
|
};
|
|
138
138
|
}
|
package/src/types/index.d.ts
CHANGED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import React, {useContext, useEffect, useMemo, useState} from 'react';
|
|
2
|
-
import {NativeEventEmitter, NativeModules} from 'react-native';
|
|
3
|
-
import {
|
|
4
|
-
InAppPurchase,
|
|
5
|
-
Product,
|
|
6
|
-
Purchase,
|
|
7
|
-
PurchaseError,
|
|
8
|
-
Subscription,
|
|
9
|
-
SubscriptionPurchase,
|
|
10
|
-
} from '../types';
|
|
11
|
-
import {
|
|
12
|
-
getPromotedProductIOS,
|
|
13
|
-
initConnection,
|
|
14
|
-
purchaseErrorListener,
|
|
15
|
-
purchaseUpdatedListener,
|
|
16
|
-
} from '../iap';
|
|
17
|
-
|
|
18
|
-
type IAPContextType = {
|
|
19
|
-
connected: boolean;
|
|
20
|
-
products: Product[];
|
|
21
|
-
promotedProductsIOS: Product[];
|
|
22
|
-
subscriptions: Subscription[];
|
|
23
|
-
purchaseHistories: Purchase[];
|
|
24
|
-
availablePurchases: Purchase[];
|
|
25
|
-
currentPurchase?: Purchase;
|
|
26
|
-
currentPurchaseError?: PurchaseError;
|
|
27
|
-
setProducts: (products: Product[]) => void;
|
|
28
|
-
setSubscriptions: (subscriptions: Subscription[]) => void;
|
|
29
|
-
setPurchaseHistories: (purchaseHistories: Purchase[]) => void;
|
|
30
|
-
setAvailablePurchases: (availablePurchases: Purchase[]) => void;
|
|
31
|
-
setCurrentPurchase: (currentPurchase: Purchase | undefined) => void;
|
|
32
|
-
setCurrentPurchaseError: (
|
|
33
|
-
currentPurchaseError: PurchaseError | undefined,
|
|
34
|
-
) => void;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const {RNIapIos} = NativeModules;
|
|
38
|
-
const IAPEmitter = new NativeEventEmitter(RNIapIos);
|
|
39
|
-
|
|
40
|
-
// @ts-ignore
|
|
41
|
-
const IAPContext = React.createContext<IAPContextType>(null);
|
|
42
|
-
|
|
43
|
-
export function useIAPContext(): IAPContextType {
|
|
44
|
-
const ctx = useContext(IAPContext);
|
|
45
|
-
if (!ctx) throw new Error('You need wrap your app with withIAPContext HOC');
|
|
46
|
-
|
|
47
|
-
return ctx;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function withIAPContext<T>(Component: React.ComponentType<T>) {
|
|
51
|
-
return function WrapperComponent(props: T) {
|
|
52
|
-
const [connected, setConnected] = useState<boolean>(false);
|
|
53
|
-
const [products, setProducts] = useState<Product[]>([]);
|
|
54
|
-
|
|
55
|
-
const [promotedProductsIOS, setPromotedProductsIOS] = useState<Product[]>(
|
|
56
|
-
[],
|
|
57
|
-
);
|
|
58
|
-
const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);
|
|
59
|
-
const [purchaseHistories, setPurchaseHistories] = useState<Purchase[]>([]);
|
|
60
|
-
|
|
61
|
-
const [availablePurchases, setAvailablePurchases] = useState<Purchase[]>(
|
|
62
|
-
[],
|
|
63
|
-
);
|
|
64
|
-
const [currentPurchase, setCurrentPurchase] = useState<Purchase>();
|
|
65
|
-
|
|
66
|
-
const [currentPurchaseError, setCurrentPurchaseError] =
|
|
67
|
-
useState<PurchaseError>();
|
|
68
|
-
|
|
69
|
-
const context = useMemo(
|
|
70
|
-
() => ({
|
|
71
|
-
connected,
|
|
72
|
-
products,
|
|
73
|
-
subscriptions,
|
|
74
|
-
promotedProductsIOS,
|
|
75
|
-
purchaseHistories,
|
|
76
|
-
availablePurchases,
|
|
77
|
-
currentPurchase,
|
|
78
|
-
currentPurchaseError,
|
|
79
|
-
setProducts,
|
|
80
|
-
setSubscriptions,
|
|
81
|
-
setPurchaseHistories,
|
|
82
|
-
setAvailablePurchases,
|
|
83
|
-
setCurrentPurchase,
|
|
84
|
-
setCurrentPurchaseError,
|
|
85
|
-
}),
|
|
86
|
-
[
|
|
87
|
-
connected,
|
|
88
|
-
products,
|
|
89
|
-
subscriptions,
|
|
90
|
-
promotedProductsIOS,
|
|
91
|
-
purchaseHistories,
|
|
92
|
-
availablePurchases,
|
|
93
|
-
currentPurchase,
|
|
94
|
-
currentPurchaseError,
|
|
95
|
-
setProducts,
|
|
96
|
-
setSubscriptions,
|
|
97
|
-
setPurchaseHistories,
|
|
98
|
-
setAvailablePurchases,
|
|
99
|
-
setCurrentPurchase,
|
|
100
|
-
setCurrentPurchaseError,
|
|
101
|
-
],
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
initConnection().then(setConnected);
|
|
106
|
-
}, []);
|
|
107
|
-
|
|
108
|
-
useEffect(() => {
|
|
109
|
-
if (!connected) return;
|
|
110
|
-
|
|
111
|
-
const purchaseUpdateSubscription = purchaseUpdatedListener(
|
|
112
|
-
async (purchase: InAppPurchase | SubscriptionPurchase) => {
|
|
113
|
-
setCurrentPurchaseError(undefined);
|
|
114
|
-
setCurrentPurchase(purchase);
|
|
115
|
-
},
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
const purchaseErrorSubscription = purchaseErrorListener(
|
|
119
|
-
(error: PurchaseError) => {
|
|
120
|
-
setCurrentPurchase(undefined);
|
|
121
|
-
setCurrentPurchaseError(error);
|
|
122
|
-
},
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
const promotedProductsSubscription = IAPEmitter.addListener(
|
|
126
|
-
'iap-promoted-product',
|
|
127
|
-
async () => {
|
|
128
|
-
const product = await getPromotedProductIOS();
|
|
129
|
-
|
|
130
|
-
setPromotedProductsIOS((prevProducts) => [
|
|
131
|
-
...prevProducts,
|
|
132
|
-
...(product ? [product] : []),
|
|
133
|
-
]);
|
|
134
|
-
},
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
return () => {
|
|
138
|
-
purchaseUpdateSubscription.remove();
|
|
139
|
-
purchaseErrorSubscription.remove();
|
|
140
|
-
promotedProductsSubscription.remove();
|
|
141
|
-
};
|
|
142
|
-
}, [connected]);
|
|
143
|
-
|
|
144
|
-
return (
|
|
145
|
-
<IAPContext.Provider value={context}>
|
|
146
|
-
<Component {...props} />
|
|
147
|
-
</IAPContext.Provider>
|
|
148
|
-
);
|
|
149
|
-
};
|
|
150
|
-
}
|