apps-sdk 1.1.57 → 1.1.59
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/package.json +1 -1
- package/src/components/AdaptyOnboarding.js +162 -179
- package/types/index.d.ts +7 -7
package/package.json
CHANGED
|
@@ -1,203 +1,186 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { Modal } from 'react-native';
|
|
3
|
+
import { AdaptyOnboardingView } from 'react-native-adapty/dist/ui';
|
|
4
|
+
import { View } from "react-native";
|
|
2
5
|
import Adapty from '../libraries/Adapty';
|
|
3
6
|
import * as config from '../../config';
|
|
4
7
|
|
|
5
8
|
class AdaptyOnboarding extends React.Component {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
async componentDidMount() {
|
|
17
|
-
if (this.props.visible) {
|
|
18
|
-
await this.presentOnboarding();
|
|
9
|
+
constructor(props) {
|
|
10
|
+
super(props);
|
|
11
|
+
this.state = {
|
|
12
|
+
onboarding: null,
|
|
13
|
+
isLoading: true,
|
|
14
|
+
};
|
|
15
|
+
this.remoteConfig = null;
|
|
16
|
+
this.currentStep = 0;
|
|
17
|
+
this.totalSteps = 0;
|
|
19
18
|
}
|
|
20
|
-
}
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} else if (!this.props.visible && prevProps.visible) {
|
|
26
|
-
await this.dismissOnboarding();
|
|
20
|
+
componentDidMount() {
|
|
21
|
+
const { placementID, lang } = this.props;
|
|
22
|
+
this.loadOnboarding(placementID, lang);
|
|
27
23
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
presentOnboarding = async () => {
|
|
35
|
-
const {
|
|
36
|
-
placementID,
|
|
37
|
-
lang,
|
|
38
|
-
onCustom,
|
|
39
|
-
onClose,
|
|
40
|
-
onError,
|
|
41
|
-
onRemoteConfigLoaded,
|
|
42
|
-
...handlers
|
|
43
|
-
} = this.props;
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
this.isPresenting = true;
|
|
47
|
-
const onboarding = await Adapty.getOnboardingForPlacement(placementID, lang);
|
|
48
|
-
|
|
49
|
-
if (onboarding) {
|
|
50
|
-
// Extraer y guardar remote config
|
|
51
|
-
this.remoteConfig = onboarding.remoteConfig || {};
|
|
52
|
-
|
|
53
|
-
// Callback inicial con el config
|
|
54
|
-
if (onRemoteConfigLoaded && this.remoteConfig) {
|
|
55
|
-
config.DEBUG_MODE && console.log('Remote config loaded:', this.remoteConfig);
|
|
56
|
-
onRemoteConfigLoaded(this.remoteConfig);
|
|
24
|
+
|
|
25
|
+
async componentDidUpdate(prevProps) {
|
|
26
|
+
if (this.props.visible && !prevProps.visible) {
|
|
27
|
+
const { placementID, lang } = this.props;
|
|
28
|
+
await this.loadOnboarding(placementID, lang);
|
|
57
29
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// Marcar términos aceptados solo cuando se dispara este action
|
|
66
|
-
if (actionId === 'accept_terms') {
|
|
67
|
-
this.termsAccepted = true;
|
|
68
|
-
config.DEBUG_MODE && console.log('Terms accepted - can close when reaching last step');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Pasar remoteConfig en el handler
|
|
72
|
-
if (onCustom) {
|
|
73
|
-
onCustom(actionId, meta, this.remoteConfig);
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
onClose: async (actionId, meta) => {
|
|
77
|
-
const isLastStep = this.totalSteps > 0 && this.currentStep === this.totalSteps - 1;
|
|
78
|
-
const canClose = this.termsAccepted && isLastStep;
|
|
79
|
-
|
|
80
|
-
config.DEBUG_MODE && console.log('Onboarding close attempt:', {
|
|
81
|
-
actionId,
|
|
82
|
-
meta,
|
|
83
|
-
termsAccepted: this.termsAccepted,
|
|
84
|
-
currentStep: this.currentStep,
|
|
85
|
-
totalSteps: this.totalSteps,
|
|
86
|
-
isLastStep,
|
|
87
|
-
canClose
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Solo permitir cerrar si:
|
|
91
|
-
// 1. El usuario aceptó los términos Y
|
|
92
|
-
// 2. Está en el último paso del onboarding
|
|
93
|
-
if (!canClose) {
|
|
94
|
-
config.DEBUG_MODE && console.log('Onboarding close prevented - must accept terms and reach last step');
|
|
95
|
-
return false; // Bloquear cierre
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Permitir cerrar
|
|
99
|
-
config.DEBUG_MODE && console.log('Onboarding close allowed - terms accepted and last step reached');
|
|
100
|
-
this.isPresenting = false;
|
|
101
|
-
|
|
102
|
-
// Pasar remoteConfig en el handler
|
|
103
|
-
if (onClose) {
|
|
104
|
-
onClose(actionId, meta, this.remoteConfig);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
await this.onboardingView.dismiss();
|
|
108
|
-
|
|
109
|
-
// Reset para próxima vez
|
|
110
|
-
this.termsAccepted = false;
|
|
111
|
-
this.currentStep = 0;
|
|
112
|
-
this.totalSteps = 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
loadOnboarding = async (placementID, lang) => {
|
|
33
|
+
try {
|
|
34
|
+
this.setState({ isLoading: true });
|
|
35
|
+
const onboarding = await Adapty.getOnboardingForPlacement(placementID, lang);
|
|
113
36
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
37
|
+
if (onboarding) {
|
|
38
|
+
this.remoteConfig = onboarding.remoteConfig || {};
|
|
39
|
+
|
|
40
|
+
if (this.props.onRemoteConfigLoaded && this.remoteConfig) {
|
|
41
|
+
config.DEBUG_MODE && console.log('Remote config loaded:', this.remoteConfig);
|
|
42
|
+
this.props.onRemoteConfigLoaded(this.remoteConfig);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.setState({ onboarding, isLoading: false });
|
|
46
|
+
} else {
|
|
47
|
+
console.log('Onboarding not found for placement:', placementID, 'and language:', lang);
|
|
48
|
+
this.setState({ isLoading: false });
|
|
49
|
+
if (this.props.onError) {
|
|
50
|
+
this.props.onError(new Error('Onboarding not found'), this.remoteConfig);
|
|
51
|
+
}
|
|
122
52
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
handlers.onAnalytics(event, data, this.remoteConfig);
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
onPaywall: () => {
|
|
132
|
-
config.DEBUG_MODE && console.log('Onboarding paywall event');
|
|
133
|
-
if (handlers.onPaywall) {
|
|
134
|
-
handlers.onPaywall(this.remoteConfig);
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
onStateUpdated: (action, meta) => {
|
|
138
|
-
// Extraer información del paso actual desde meta
|
|
139
|
-
if (meta && typeof meta === 'object') {
|
|
140
|
-
this.currentStep = meta.screen_index ?? this.currentStep;
|
|
141
|
-
this.totalSteps = meta.total_screens ?? this.totalSteps;
|
|
142
|
-
|
|
143
|
-
config.DEBUG_MODE && console.log('Onboarding state updated:', {
|
|
144
|
-
action,
|
|
145
|
-
meta,
|
|
146
|
-
currentStep: this.currentStep,
|
|
147
|
-
totalSteps: this.totalSteps,
|
|
148
|
-
termsAccepted: this.termsAccepted
|
|
149
|
-
});
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.log('Error loading onboarding:', error);
|
|
55
|
+
this.setState({ isLoading: false });
|
|
56
|
+
if (this.props.onError) {
|
|
57
|
+
this.props.onError(error, this.remoteConfig);
|
|
150
58
|
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// --------------------------------------- Event Handlers ---------------------------------------
|
|
63
|
+
handleCustom = (actionId, meta) => {
|
|
64
|
+
if (this.props.onCustom) {
|
|
65
|
+
this.props.onCustom(actionId, meta, this.remoteConfig);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
handleClose = (actionId, meta) => {
|
|
70
|
+
const isLastStep = this.totalSteps > 0 && this.currentStep === this.totalSteps - 1;
|
|
71
|
+
|
|
72
|
+
config.DEBUG_MODE && console.log('Onboarding close attempt AdaptyOnboarding:', {actionId, meta, currentStep: this.currentStep, totalSteps: this.totalSteps, isLastStep });
|
|
73
|
+
|
|
74
|
+
if (this.props.onClose) {
|
|
75
|
+
this.props.onClose(actionId, meta, this.remoteConfig);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.currentStep = 0;
|
|
79
|
+
this.totalSteps = 0;
|
|
80
|
+
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
handleStateUpdated = (action, meta) => {
|
|
85
|
+
if (meta && typeof meta === 'object') {
|
|
86
|
+
this.currentStep = meta.screen_index ?? this.currentStep;
|
|
87
|
+
this.totalSteps = meta.total_screens ?? this.totalSteps;
|
|
151
88
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
});
|
|
89
|
+
config.DEBUG_MODE && console.log('State updated AdaptyOnboarding:', {action, meta, currentStep: this.currentStep, totalSteps: this.totalSteps});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (this.props.onStateUpdated) {
|
|
93
|
+
this.props.onStateUpdated(action, meta, this.remoteConfig);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
handleError = (error) => {
|
|
98
|
+
console.log('Onboarding error:', error);
|
|
163
99
|
|
|
164
|
-
await this.onboardingView.present();
|
|
165
|
-
} else {
|
|
166
|
-
console.warn('Onboarding not found for placement:', placementID, 'and language:', lang);
|
|
167
100
|
if (this.props.onError) {
|
|
168
|
-
|
|
101
|
+
this.props.onError(error, this.remoteConfig);
|
|
169
102
|
}
|
|
170
|
-
|
|
171
|
-
} catch (error) {
|
|
172
|
-
console.error('Error presenting onboarding:', error);
|
|
173
|
-
this.isPresenting = false;
|
|
174
|
-
if (this.props.onError) {
|
|
175
|
-
this.props.onError(error, this.remoteConfig);
|
|
176
|
-
}
|
|
103
|
+
return true;
|
|
177
104
|
}
|
|
178
|
-
}
|
|
179
105
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
} catch (error) {
|
|
187
|
-
console.error('Error dismissing onboarding:', error);
|
|
188
|
-
}
|
|
106
|
+
handleAnalytics = (event, data) => {
|
|
107
|
+
config.DEBUG_MODE && console.log('Onboarding analytics AdaptyOnboarding:', event, data);
|
|
108
|
+
|
|
109
|
+
if (this.props.onAnalytics) {
|
|
110
|
+
this.props.onAnalytics(event, data, this.remoteConfig);
|
|
111
|
+
}
|
|
189
112
|
}
|
|
190
|
-
}
|
|
191
113
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
114
|
+
handlePaywall = (actionId, meta) => {
|
|
115
|
+
config.DEBUG_MODE && console.log('Onboarding paywall AdaptyOnboarding:', actionId, meta);
|
|
116
|
+
|
|
117
|
+
if (this.props.onPaywall) {
|
|
118
|
+
this.props.onPaywall(this.remoteConfig);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
handleFinishedLoading = (meta) => {
|
|
123
|
+
config.DEBUG_MODE && console.log('Onboarding finished loading AdaptyOnboarding:', meta);
|
|
124
|
+
|
|
125
|
+
if (this.props.onFinishedLoading) {
|
|
126
|
+
this.props.onFinishedLoading(meta, this.remoteConfig);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// --------------------------------------- Event Handlers ---------------------------------------
|
|
130
|
+
|
|
131
|
+
render() {
|
|
132
|
+
const { visible } = this.props;
|
|
133
|
+
const { onboarding, isLoading } = this.state;
|
|
134
|
+
|
|
135
|
+
if (!visible) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const content = (
|
|
140
|
+
<View style={styles.container}>
|
|
141
|
+
{!isLoading && onboarding ? (
|
|
142
|
+
<AdaptyOnboardingView
|
|
143
|
+
onboarding={onboarding}
|
|
144
|
+
style={styles.onboardingView}
|
|
145
|
+
eventHandlers={{
|
|
146
|
+
onAnalytics: this.handleAnalytics,
|
|
147
|
+
onClose: this.handleClose,
|
|
148
|
+
onCustom: this.handleCustom,
|
|
149
|
+
onPaywall: this.handlePaywall,
|
|
150
|
+
onStateUpdated: this.handleStateUpdated,
|
|
151
|
+
onFinishedLoading: this.handleFinishedLoading,
|
|
152
|
+
onError: this.handleError,
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
) : null}
|
|
156
|
+
</View>
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<Modal
|
|
161
|
+
visible={visible}
|
|
162
|
+
animationType="slide"
|
|
163
|
+
presentationStyle="fullScreen"
|
|
164
|
+
onRequestClose={() => {
|
|
165
|
+
config.DEBUG_MODE && console.log('Modal onRequestClose prevented');
|
|
166
|
+
return false;
|
|
167
|
+
}}
|
|
168
|
+
>
|
|
169
|
+
{content}
|
|
170
|
+
</Modal>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
196
174
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
175
|
+
const styles = {
|
|
176
|
+
container: {
|
|
177
|
+
backgroundColor: '#000',
|
|
178
|
+
width: '100%',
|
|
179
|
+
height: '100%',
|
|
180
|
+
},
|
|
181
|
+
onboardingView: {
|
|
182
|
+
flex: 1,
|
|
183
|
+
},
|
|
201
184
|
}
|
|
202
185
|
|
|
203
186
|
export default AdaptyOnboarding;
|
package/types/index.d.ts
CHANGED
|
@@ -162,14 +162,14 @@ declare module 'apps-sdk' {
|
|
|
162
162
|
visible: boolean;
|
|
163
163
|
placementID: string;
|
|
164
164
|
lang: string;
|
|
165
|
-
onCustom?: (actionId: string, meta
|
|
166
|
-
onClose?: (actionId: string, meta
|
|
167
|
-
onError?: (error: Error |
|
|
165
|
+
onCustom?: (actionId: string, meta: Record<string, any> | undefined, remoteConfig: Record<string, any> | null) => void;
|
|
166
|
+
onClose?: (actionId: string, meta: Record<string, any> | undefined, remoteConfig: Record<string, any> | null) => boolean;
|
|
167
|
+
onError?: (error: Error | any, remoteConfig: Record<string, any> | null) => boolean;
|
|
168
168
|
onRemoteConfigLoaded?: (remoteConfig: Record<string, any>) => void;
|
|
169
|
-
onAnalytics?: (event:
|
|
170
|
-
onPaywall?: (
|
|
171
|
-
onStateUpdated?: (action: any, meta
|
|
172
|
-
onFinishedLoading?: (meta
|
|
169
|
+
onAnalytics?: (event: any, data: any, remoteConfig: Record<string, any> | null) => void;
|
|
170
|
+
onPaywall?: (actionId: string, meta: Record<string, any> | undefined) => void;
|
|
171
|
+
onStateUpdated?: (action: any, meta: Record<string, any> | undefined, remoteConfig: Record<string, any> | null) => void;
|
|
172
|
+
onFinishedLoading?: (meta: Record<string, any> | undefined, remoteConfig: Record<string, any> | null) => void;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
export class AdaptyOnboarding extends Component<AdaptyOnboardingProps, {}> {}
|