@oxyhq/services 5.12.2 → 5.12.4
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 +1 -1
- package/lib/commonjs/core/OxyServices.js +1 -1
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +36 -3
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/index.js +0 -1
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +0 -153
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/module/core/OxyServices.js +1 -1
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +38 -5
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/index.js +1 -1
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.js +1 -153
- package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/typescript/core/OxyServices.d.ts +1 -1
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/index.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
- package/package.json +11 -10
- package/src/core/OxyServices.ts +1 -1
- package/src/ui/components/OxyProvider.tsx +37 -4
- package/src/ui/index.ts +1 -1
- package/src/ui/screens/PaymentGatewayScreen.tsx +6 -154
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OxyProvider.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/OxyProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6F,MAAM,OAAO,CAAC;AAIlH,OAAO,KAAK,EAAE,gBAAgB,EAAyB,MAAM,qBAAqB,CAAC;AAcnF;;;;;;GAMG;AACH,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAkG3C,CAAC;
|
|
1
|
+
{"version":3,"file":"OxyProvider.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/OxyProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6F,MAAM,OAAO,CAAC;AAIlH,OAAO,KAAK,EAAE,gBAAgB,EAAyB,MAAM,qBAAqB,CAAC;AAcnF;;;;;;GAMG;AACH,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAkG3C,CAAC;AAqTF,eAAe,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AASA,QAAA,IAAI,WAAW,KAAA,EAAE,eAAe,KAAA,EAAE,OAAO,KAAA,EAAE,MAAM,KAAA,EAAE,YAAY,KAAA,EAAE,YAAY,KAAA,EAAE,UAAU,KAAA,EAAE,UAAU,KAAA,EAAE,OAAO,KAAA,EAAE,MAAM,KAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AASA,QAAA,IAAI,WAAW,KAAA,EAAE,eAAe,KAAA,EAAE,OAAO,KAAA,EAAE,MAAM,KAAA,EAAE,YAAY,KAAA,EAAE,YAAY,KAAA,EAAE,UAAU,KAAA,EAAE,UAAU,KAAA,EAAE,OAAO,KAAA,EAAE,MAAM,KAAA,EAAmH,kBAAkB,KAAA,EAAE,eAAe,KAAA,EAAE,uBAAuB,KAAA,EAAE,SAAS,KAAA,EAAE,aAAa,KAAA,EAAE,SAAS,KAAA,EAAE,YAAY,KAAA,EAAE,YAAY,KAAA,EAAE,UAAU,KAAA,EAAE,KAAK,KAAA,CAAC;AAiD1X,OAAO,EACL,WAAW,EACX,eAAe,EACf,OAAO,EACP,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,OAAO,EACP,MAAM,EACN,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,SAAS,EACT,aAAa,EACb,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,KAAK,EACN,CAAC;AAGF,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaymentGatewayScreen.d.ts","sourceRoot":"","sources":["../../../../src/ui/screens/PaymentGatewayScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAkB/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"PaymentGatewayScreen.d.ts","sourceRoot":"","sources":["../../../../src/ui/screens/PaymentGatewayScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAkB/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAsB3D,MAAM,MAAM,WAAW,GAAG;IACtB,IAAI,EAAE,SAAS,GAAG,cAAc,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAGF,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,yBAA0B,SAAQ,eAAe;IACvD,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACzD,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAoDD,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAssB7D,CAAC;AAooBF,eAAe,oBAAoB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/services",
|
|
3
|
-
"version": "5.12.
|
|
3
|
+
"version": "5.12.4",
|
|
4
4
|
"description": "Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
7
7
|
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "src/index.ts",
|
|
8
9
|
"source": "src/index.ts",
|
|
9
10
|
"sideEffects": false,
|
|
10
11
|
"publishConfig": {
|
|
@@ -12,25 +13,30 @@
|
|
|
12
13
|
},
|
|
13
14
|
"exports": {
|
|
14
15
|
".": {
|
|
15
|
-
"react-native": "./
|
|
16
|
+
"react-native": "./src/index.ts",
|
|
17
|
+
"node": {
|
|
18
|
+
"import": "./lib/module/core/index.js",
|
|
19
|
+
"require": "./lib/commonjs/core/index.js",
|
|
20
|
+
"types": "./lib/typescript/core/index.d.ts"
|
|
21
|
+
},
|
|
16
22
|
"import": "./lib/module/index.js",
|
|
17
23
|
"require": "./lib/commonjs/index.js",
|
|
18
24
|
"types": "./lib/typescript/index.d.ts"
|
|
19
25
|
},
|
|
20
26
|
"./core": {
|
|
21
|
-
"react-native": "./
|
|
27
|
+
"react-native": "./src/core/index.ts",
|
|
22
28
|
"import": "./lib/module/core/index.js",
|
|
23
29
|
"require": "./lib/commonjs/core/index.js",
|
|
24
30
|
"types": "./lib/typescript/core/index.d.ts"
|
|
25
31
|
},
|
|
26
32
|
"./ui": {
|
|
27
|
-
"react-native": "./
|
|
33
|
+
"react-native": "./src/ui/index.ts",
|
|
28
34
|
"import": "./lib/module/ui/index.js",
|
|
29
35
|
"require": "./lib/commonjs/ui/index.js",
|
|
30
36
|
"types": "./lib/typescript/ui/index.d.ts"
|
|
31
37
|
},
|
|
32
38
|
"./full": {
|
|
33
|
-
"react-native": "./
|
|
39
|
+
"react-native": "./src/index.ts",
|
|
34
40
|
"import": "./lib/module/index.js",
|
|
35
41
|
"require": "./lib/commonjs/index.js",
|
|
36
42
|
"types": "./lib/typescript/index.d.ts"
|
|
@@ -116,7 +122,6 @@
|
|
|
116
122
|
"metro-react-native-babel-preset": "^0.77.0",
|
|
117
123
|
"react-native-builder-bob": "^0.30.3",
|
|
118
124
|
"react-native-gesture-handler": "~2.24.0",
|
|
119
|
-
"react-native-iap": "^13.0.4",
|
|
120
125
|
"react-native-reanimated": "~3.17.4",
|
|
121
126
|
"react-native-safe-area-context": "^5.6.1",
|
|
122
127
|
"react-native-svg": "15.11.2",
|
|
@@ -140,7 +145,6 @@
|
|
|
140
145
|
"react": ">=18.0.0",
|
|
141
146
|
"react-native": ">=0.76.0",
|
|
142
147
|
"react-native-gesture-handler": ">=2.16.1",
|
|
143
|
-
"react-native-iap": "^12.16.0",
|
|
144
148
|
"react-native-reanimated": ">=3.16.0",
|
|
145
149
|
"react-native-safe-area-context": "^5.4.0",
|
|
146
150
|
"react-native-svg": ">=13.0.0"
|
|
@@ -172,9 +176,6 @@
|
|
|
172
176
|
},
|
|
173
177
|
"@react-navigation/native": {
|
|
174
178
|
"optional": true
|
|
175
|
-
},
|
|
176
|
-
"react-native-iap": {
|
|
177
|
-
"optional": true
|
|
178
179
|
}
|
|
179
180
|
},
|
|
180
181
|
"react-native-builder-bob": {
|
package/src/core/OxyServices.ts
CHANGED
|
@@ -1786,7 +1786,7 @@ export const OXY_CLOUD_URL = 'https://cloud.oxyhq.com';
|
|
|
1786
1786
|
/**
|
|
1787
1787
|
* Export the default Oxy API URL (for documentation)
|
|
1788
1788
|
*/
|
|
1789
|
-
export const OXY_API_URL = 'https://api.oxy.so';
|
|
1789
|
+
export const OXY_API_URL = (typeof process !== 'undefined' && process.env && process.env.OXY_API_URL) || 'https://api.oxy.so';
|
|
1790
1790
|
|
|
1791
1791
|
/**
|
|
1792
1792
|
* Pre-configured client instance for easy import
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useRef, useState, useEffect, useMemo, forwardRef, useImperativeHandle } from 'react';
|
|
2
|
-
import { View, Text, StyleSheet, Platform, Animated, StatusBar, AppState } from 'react-native';
|
|
2
|
+
import { View, Text, StyleSheet, Platform, Animated, StatusBar, Keyboard, KeyboardEvent, AppState } from 'react-native';
|
|
3
3
|
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
4
4
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
5
5
|
import type { OxyProviderProps, BottomSheetController } from '../navigation/types';
|
|
@@ -196,8 +196,40 @@ const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
}), [fadeAnim, slideAnim]);
|
|
199
|
-
//
|
|
199
|
+
// Keyboard handling (unchanged)
|
|
200
|
+
const [keyboardVisible, setKeyboardVisible] = useState(false);
|
|
201
|
+
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
200
202
|
const insets = useSafeAreaInsets();
|
|
203
|
+
useEffect(() => {
|
|
204
|
+
// Use 'did' events on iOS to avoid multiple intermediate willShow updates
|
|
205
|
+
const showEvent = Platform.OS === 'ios' ? 'keyboardDidShow' : 'keyboardDidShow';
|
|
206
|
+
const hideEvent = Platform.OS === 'ios' ? 'keyboardDidHide' : 'keyboardDidHide';
|
|
207
|
+
let lastH = 0;
|
|
208
|
+
let lastTs = 0;
|
|
209
|
+
const MIN_DELTA = 8;
|
|
210
|
+
const MIN_INTERVAL = 80; // ms
|
|
211
|
+
const onShow = (e: KeyboardEvent) => {
|
|
212
|
+
const h = e?.endCoordinates?.height ?? 0;
|
|
213
|
+
const now = Date.now();
|
|
214
|
+
if (Math.abs(h - lastH) < MIN_DELTA && now - lastTs < MIN_INTERVAL) return;
|
|
215
|
+
lastH = h;
|
|
216
|
+
lastTs = now;
|
|
217
|
+
setKeyboardVisible(true);
|
|
218
|
+
setKeyboardHeight(h);
|
|
219
|
+
};
|
|
220
|
+
const onHide = () => {
|
|
221
|
+
lastH = 0;
|
|
222
|
+
lastTs = Date.now();
|
|
223
|
+
setKeyboardVisible(false);
|
|
224
|
+
setKeyboardHeight(0);
|
|
225
|
+
};
|
|
226
|
+
const showSub = Keyboard.addListener(showEvent as any, onShow as any);
|
|
227
|
+
const hideSub = Keyboard.addListener(hideEvent as any, onHide as any);
|
|
228
|
+
return () => {
|
|
229
|
+
showSub.remove();
|
|
230
|
+
hideSub.remove();
|
|
231
|
+
};
|
|
232
|
+
}, []);
|
|
201
233
|
// Present the modal when component mounts, but only if autoPresent is true
|
|
202
234
|
useEffect(() => {
|
|
203
235
|
if (autoPresent && modalRef.current) {
|
|
@@ -291,14 +323,15 @@ const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
|
|
|
291
323
|
style={styles.bottomSheetContainer}
|
|
292
324
|
keyboardBehavior="interactive"
|
|
293
325
|
keyboardBlurBehavior="restore"
|
|
294
|
-
android_keyboardInputMode="
|
|
326
|
+
android_keyboardInputMode="adjustPan"
|
|
295
327
|
enableOverDrag={false}
|
|
296
328
|
enableContentPanningGesture={true}
|
|
297
329
|
enableHandlePanningGesture={true}
|
|
298
330
|
overDragResistanceFactor={2.5}
|
|
299
331
|
enableBlurKeyboardOnGesture={true}
|
|
332
|
+
detached
|
|
300
333
|
topInset={(insets?.top ?? 0) + (appInsets?.top ?? 0)}
|
|
301
|
-
bottomInset={(appInsets?.bottom ?? 0)}
|
|
334
|
+
bottomInset={((Platform.OS === 'android' ? (keyboardVisible ? keyboardHeight : 0) : 0)) + (appInsets?.bottom ?? 0)}
|
|
302
335
|
onChange={(index) => { isOpenRef.current = index !== -1; }}
|
|
303
336
|
onDismiss={() => { isOpenRef.current = false; }}
|
|
304
337
|
>
|
package/src/ui/index.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import isFrontend from './isFrontend';
|
|
8
8
|
|
|
9
9
|
// Real UI exports
|
|
10
|
-
let OxyProvider, OxySignInButton, OxyLogo, Avatar, FollowButton, OxyPayButton, FontLoader, setupFonts, OxyIcon, useOxy, useOxyAuth, useOxyUser, useOxyKarma, useOxyPayments, useOxyDevices, useOxyNotifications, useOxySocket, useOxyQR,
|
|
10
|
+
let OxyProvider, OxySignInButton, OxyLogo, Avatar, FollowButton, OxyPayButton, FontLoader, setupFonts, OxyIcon, useOxy, useOxyAuth, useOxyUser, useOxyKarma, useOxyPayments, useOxyDevices, useOxyNotifications, useOxySocket, useOxyQR, OxyContextProvider, OxyContextState, OxyContextProviderProps, useFollow, ProfileScreen, OxyRouter, useAuthStore, fontFamilies, fontStyles, toast;
|
|
11
11
|
|
|
12
12
|
if (isFrontend) {
|
|
13
13
|
OxyProvider = require('./components/OxyProvider').default;
|
|
@@ -25,7 +25,7 @@ import { Ionicons } from '@expo/vector-icons';
|
|
|
25
25
|
import { FAIRWalletIcon } from '../components/icon';
|
|
26
26
|
import { toast } from 'sonner';
|
|
27
27
|
import QRCode from 'react-native-qrcode-svg';
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
import { GroupedSection } from '../components';
|
|
30
30
|
|
|
31
31
|
// Restrict payment methods to Card, Oxy Pay, and FairCoin (QR)
|
|
@@ -35,16 +35,7 @@ const PAYMENT_METHODS = [
|
|
|
35
35
|
{ key: 'faircoin', label: 'FAIRWallet', icon: 'qr-code-outline', description: 'Pay with FairCoin by scanning a QR code.' },
|
|
36
36
|
];
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
const ANDROID_IAP_METHOD = {
|
|
40
|
-
key: 'googleplay',
|
|
41
|
-
label: 'Google Play Billing',
|
|
42
|
-
icon: 'logo-google-playstore',
|
|
43
|
-
description: 'Pay securely with your Google Play account.'
|
|
44
|
-
};
|
|
45
|
-
if (Platform.OS === 'android' && !PAYMENT_METHODS.find(m => m.key === 'googleplay')) {
|
|
46
|
-
PAYMENT_METHODS.push(ANDROID_IAP_METHOD);
|
|
47
|
-
}
|
|
38
|
+
|
|
48
39
|
|
|
49
40
|
// Add PaymentItem type
|
|
50
41
|
export type PaymentItem = {
|
|
@@ -116,7 +107,6 @@ const getItemTypeIcon = (type: string, color: string) => {
|
|
|
116
107
|
}
|
|
117
108
|
};
|
|
118
109
|
|
|
119
|
-
const IAP_PRODUCT_IDS = ['test_product_1', 'test_product_2']; // TODO: Replace with real product IDs
|
|
120
110
|
|
|
121
111
|
// Helper to get unique item types (move to top-level, before component)
|
|
122
112
|
const getUniqueItemTypes = (items: PaymentItem[]) => {
|
|
@@ -155,11 +145,7 @@ const PaymentGatewayScreen: React.FC<PaymentGatewayScreenProps> = (props) => {
|
|
|
155
145
|
const [isPaying, setIsPaying] = useState(false);
|
|
156
146
|
const [success, setSuccess] = useState(false);
|
|
157
147
|
|
|
158
|
-
|
|
159
|
-
const [iapProducts, setIapProducts] = useState<RNIap.Product[]>([]);
|
|
160
|
-
const [iapError, setIapError] = useState<string | null>(null);
|
|
161
|
-
const [iapLoading, setIapLoading] = useState(false);
|
|
162
|
-
const [iapPurchase, setIapPurchase] = useState<RNIap.Purchase | null>(null);
|
|
148
|
+
|
|
163
149
|
|
|
164
150
|
// Animations
|
|
165
151
|
const fadeAnim = useRef(new Animated.Value(1)).current;
|
|
@@ -335,42 +321,7 @@ const PaymentGatewayScreen: React.FC<PaymentGatewayScreenProps> = (props) => {
|
|
|
335
321
|
Linking.openURL(url);
|
|
336
322
|
};
|
|
337
323
|
|
|
338
|
-
|
|
339
|
-
useEffect(() => {
|
|
340
|
-
if (paymentMethod !== 'googleplay' || Platform.OS !== 'android') return;
|
|
341
|
-
let purchaseUpdateSub: any, purchaseErrorSub: any;
|
|
342
|
-
setIapLoading(true);
|
|
343
|
-
RNIap.initConnection()
|
|
344
|
-
.then(() => RNIap.getProducts({ skus: IAP_PRODUCT_IDS }))
|
|
345
|
-
.then(setIapProducts)
|
|
346
|
-
.catch((e: any) => setIapError(e.message))
|
|
347
|
-
.finally(() => setIapLoading(false));
|
|
348
|
-
purchaseUpdateSub = RNIap.purchaseUpdatedListener((purchase: any) => {
|
|
349
|
-
setIapPurchase(purchase);
|
|
350
|
-
setSuccess(true);
|
|
351
|
-
nextStep();
|
|
352
|
-
});
|
|
353
|
-
purchaseErrorSub = RNIap.purchaseErrorListener((err: any) => {
|
|
354
|
-
setIapError(err.message);
|
|
355
|
-
});
|
|
356
|
-
return () => {
|
|
357
|
-
purchaseUpdateSub && purchaseUpdateSub.remove();
|
|
358
|
-
purchaseErrorSub && purchaseErrorSub.remove();
|
|
359
|
-
RNIap.endConnection();
|
|
360
|
-
};
|
|
361
|
-
}, [paymentMethod]);
|
|
362
|
-
|
|
363
|
-
const handleIapBuy = async (sku: string) => {
|
|
364
|
-
setIapError(null);
|
|
365
|
-
setIapLoading(true);
|
|
366
|
-
try {
|
|
367
|
-
await RNIap.requestPurchase({ sku });
|
|
368
|
-
} catch (e: any) {
|
|
369
|
-
setIapError(e.message);
|
|
370
|
-
} finally {
|
|
371
|
-
setIapLoading(false);
|
|
372
|
-
}
|
|
373
|
-
};
|
|
324
|
+
|
|
374
325
|
|
|
375
326
|
// Helper for dynamic styles
|
|
376
327
|
const getStepIndicatorStyle = (active: boolean) => [
|
|
@@ -842,73 +793,13 @@ const PaymentGatewayScreen: React.FC<PaymentGatewayScreenProps> = (props) => {
|
|
|
842
793
|
</Animated.View>
|
|
843
794
|
);
|
|
844
795
|
|
|
845
|
-
// Step: Google Play Billing (Android only)
|
|
846
|
-
const renderGooglePlayStep = () => (
|
|
847
|
-
<Animated.View style={[styles.stepContainer, {
|
|
848
|
-
opacity: fadeAnim,
|
|
849
|
-
transform: [
|
|
850
|
-
{ translateY: slideAnim },
|
|
851
|
-
{ scale: scaleAnim },
|
|
852
|
-
]
|
|
853
|
-
}]}
|
|
854
|
-
>
|
|
855
|
-
<View style={styles.section}>
|
|
856
|
-
<Text style={styles.sectionTitle}>Google Play Products</Text>
|
|
857
|
-
|
|
858
|
-
{iapLoading && (
|
|
859
|
-
<View style={styles.loadingContainer}>
|
|
860
|
-
<Text style={styles.loadingText}>Loading products...</Text>
|
|
861
|
-
</View>
|
|
862
|
-
)}
|
|
863
796
|
|
|
864
|
-
{iapError && (
|
|
865
|
-
<View style={styles.paymentErrorContainer}>
|
|
866
|
-
<Text style={styles.paymentErrorText}>{iapError}</Text>
|
|
867
|
-
</View>
|
|
868
|
-
)}
|
|
869
|
-
|
|
870
|
-
{!iapLoading && !iapError && (
|
|
871
|
-
<GroupedSection
|
|
872
|
-
items={iapProducts.map(product => ({
|
|
873
|
-
id: product.productId,
|
|
874
|
-
icon: 'pricetag',
|
|
875
|
-
iconColor: colors.primary,
|
|
876
|
-
title: product.title,
|
|
877
|
-
subtitle: product.localizedPrice,
|
|
878
|
-
onPress: () => handleIapBuy(product.productId),
|
|
879
|
-
disabled: iapLoading,
|
|
880
|
-
}))}
|
|
881
|
-
theme={theme}
|
|
882
|
-
/>
|
|
883
|
-
)}
|
|
884
|
-
|
|
885
|
-
{iapPurchase && (
|
|
886
|
-
<View style={styles.iapSuccessContainer}>
|
|
887
|
-
<Text style={styles.iapSuccessText}>Purchase successful!</Text>
|
|
888
|
-
</View>
|
|
889
|
-
)}
|
|
890
|
-
</View>
|
|
891
|
-
<GroupedPillButtons
|
|
892
|
-
buttons={[
|
|
893
|
-
{
|
|
894
|
-
text: 'Back',
|
|
895
|
-
onPress: prevStep,
|
|
896
|
-
icon: 'arrow-back',
|
|
897
|
-
variant: 'transparent',
|
|
898
|
-
},
|
|
899
|
-
]}
|
|
900
|
-
colors={colors}
|
|
901
|
-
/>
|
|
902
|
-
</Animated.View>
|
|
903
|
-
);
|
|
904
797
|
|
|
905
798
|
const renderCurrentStep = () => {
|
|
906
799
|
switch (currentStep) {
|
|
907
800
|
case 0: return renderSummaryStep();
|
|
908
801
|
case 1: return renderMethodStep();
|
|
909
|
-
case 2:
|
|
910
|
-
if (paymentMethod === 'googleplay') return renderGooglePlayStep();
|
|
911
|
-
return renderDetailsStep();
|
|
802
|
+
case 2: return renderDetailsStep();
|
|
912
803
|
case 3: return renderReviewStep();
|
|
913
804
|
case 4: return renderSuccessStep();
|
|
914
805
|
default: return renderSummaryStep();
|
|
@@ -1410,46 +1301,7 @@ const createStyles = (colors: any, theme: string) => StyleSheet.create({
|
|
|
1410
1301
|
marginTop: 6,
|
|
1411
1302
|
marginBottom: 2,
|
|
1412
1303
|
},
|
|
1413
|
-
|
|
1414
|
-
loadingContainer: {
|
|
1415
|
-
padding: 16,
|
|
1416
|
-
alignItems: 'center',
|
|
1417
|
-
backgroundColor: '#fff',
|
|
1418
|
-
borderRadius: 12,
|
|
1419
|
-
marginBottom: 16,
|
|
1420
|
-
},
|
|
1421
|
-
loadingText: {
|
|
1422
|
-
color: colors.secondaryText,
|
|
1423
|
-
fontSize: 16,
|
|
1424
|
-
fontStyle: 'italic',
|
|
1425
|
-
},
|
|
1426
|
-
paymentErrorContainer: {
|
|
1427
|
-
padding: 16,
|
|
1428
|
-
backgroundColor: '#ffebee',
|
|
1429
|
-
borderRadius: 12,
|
|
1430
|
-
marginBottom: 16,
|
|
1431
|
-
borderWidth: 1,
|
|
1432
|
-
borderColor: '#ffcdd2',
|
|
1433
|
-
},
|
|
1434
|
-
paymentErrorText: {
|
|
1435
|
-
color: '#d32f2f',
|
|
1436
|
-
fontSize: 14,
|
|
1437
|
-
textAlign: 'center',
|
|
1438
|
-
},
|
|
1439
|
-
iapSuccessContainer: {
|
|
1440
|
-
padding: 16,
|
|
1441
|
-
backgroundColor: '#e8f5e8',
|
|
1442
|
-
borderRadius: 12,
|
|
1443
|
-
marginTop: 16,
|
|
1444
|
-
borderWidth: 1,
|
|
1445
|
-
borderColor: '#c8e6c9',
|
|
1446
|
-
},
|
|
1447
|
-
iapSuccessText: {
|
|
1448
|
-
color: colors.success || '#4BB543',
|
|
1449
|
-
fontSize: 16,
|
|
1450
|
-
textAlign: 'center',
|
|
1451
|
-
fontWeight: '600',
|
|
1452
|
-
},
|
|
1304
|
+
|
|
1453
1305
|
// Summary step styles
|
|
1454
1306
|
summaryDescriptionContainer: {
|
|
1455
1307
|
marginBottom: 16,
|