apps-sdk 1.1.57 → 1.1.58
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 +188 -174
- package/types/index.d.ts +7 -7
package/package.json
CHANGED
|
@@ -1,203 +1,217 @@
|
|
|
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.termsAccepted = false;
|
|
17
|
+
this.currentStep = 0;
|
|
18
|
+
this.totalSteps = 0;
|
|
19
19
|
}
|
|
20
|
-
}
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} else if (!this.props.visible && prevProps.visible) {
|
|
26
|
-
await this.dismissOnboarding();
|
|
21
|
+
componentDidMount() {
|
|
22
|
+
const { placementID, lang } = this.props;
|
|
23
|
+
this.loadOnboarding(placementID, lang);
|
|
27
24
|
}
|
|
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);
|
|
25
|
+
|
|
26
|
+
async componentDidUpdate(prevProps) {
|
|
27
|
+
if (this.props.visible && !prevProps.visible) {
|
|
28
|
+
const { placementID, lang } = this.props;
|
|
29
|
+
await this.loadOnboarding(placementID, lang);
|
|
57
30
|
}
|
|
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
|
-
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
loadOnboarding = async (placementID, lang) => {
|
|
34
|
+
try {
|
|
35
|
+
this.setState({ isLoading: true });
|
|
36
|
+
const onboarding = await Adapty.getOnboardingForPlacement(placementID, lang);
|
|
89
37
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
38
|
+
if (onboarding) {
|
|
39
|
+
this.remoteConfig = onboarding.remoteConfig || {};
|
|
40
|
+
|
|
41
|
+
if (this.props.onRemoteConfigLoaded && this.remoteConfig) {
|
|
42
|
+
config.DEBUG_MODE && console.log('Remote config loaded:', this.remoteConfig);
|
|
43
|
+
this.props.onRemoteConfigLoaded(this.remoteConfig);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
this.setState({ onboarding, isLoading: false });
|
|
47
|
+
} else {
|
|
48
|
+
console.log('Onboarding not found for placement:', placementID, 'and language:', lang);
|
|
49
|
+
this.setState({ isLoading: false });
|
|
50
|
+
if (this.props.onError) {
|
|
51
|
+
this.props.onError(new Error('Onboarding not found'), this.remoteConfig);
|
|
52
|
+
}
|
|
96
53
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this.
|
|
101
|
-
|
|
102
|
-
// Pasar remoteConfig en el handler
|
|
103
|
-
if (onClose) {
|
|
104
|
-
onClose(actionId, meta, this.remoteConfig);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.log('Error loading onboarding:', error);
|
|
56
|
+
this.setState({ isLoading: false });
|
|
57
|
+
if (this.props.onError) {
|
|
58
|
+
this.props.onError(error, this.remoteConfig);
|
|
105
59
|
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// --------------------------------------- Event Handlers ---------------------------------------
|
|
64
|
+
handleCustom = (actionId, meta) => {
|
|
65
|
+
config.DEBUG_MODE && console.log('Onboarding custom action:', actionId, meta);
|
|
66
|
+
|
|
67
|
+
if (actionId === 'accept_terms') {
|
|
68
|
+
this.termsAccepted = true;
|
|
69
|
+
config.DEBUG_MODE && console.log('Terms accepted');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (this.props.onCustom) {
|
|
73
|
+
this.props.onCustom(actionId, meta, this.remoteConfig);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
handleClose = (actionId, meta) => {
|
|
78
|
+
const isLastStep = this.totalSteps > 0 && this.currentStep === this.totalSteps - 1;
|
|
79
|
+
const canClose = this.termsAccepted && isLastStep;
|
|
80
|
+
|
|
81
|
+
config.DEBUG_MODE && console.log('Onboarding close attempt:', {
|
|
82
|
+
actionId,
|
|
83
|
+
meta,
|
|
84
|
+
termsAccepted: this.termsAccepted,
|
|
85
|
+
currentStep: this.currentStep,
|
|
86
|
+
totalSteps: this.totalSteps,
|
|
87
|
+
isLastStep,
|
|
88
|
+
canClose
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (!canClose) {
|
|
92
|
+
config.DEBUG_MODE && console.log('Close prevented');
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
config.DEBUG_MODE && console.log('Close allowed');
|
|
97
|
+
|
|
98
|
+
if (this.props.onClose) {
|
|
99
|
+
this.props.onClose(actionId, meta, this.remoteConfig);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this.termsAccepted = false;
|
|
103
|
+
this.currentStep = 0;
|
|
104
|
+
this.totalSteps = 0;
|
|
105
|
+
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
handleStateUpdated = (action, meta) => {
|
|
110
|
+
if (meta && typeof meta === 'object') {
|
|
111
|
+
this.currentStep = meta.screen_index ?? this.currentStep;
|
|
112
|
+
this.totalSteps = meta.total_screens ?? this.totalSteps;
|
|
106
113
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// Reset para próxima vez
|
|
110
|
-
this.termsAccepted = false;
|
|
111
|
-
this.currentStep = 0;
|
|
112
|
-
this.totalSteps = 0;
|
|
113
|
-
|
|
114
|
-
return true;
|
|
115
|
-
},
|
|
116
|
-
onError: (error) => {
|
|
117
|
-
console.error('Onboarding error:', error);
|
|
118
|
-
this.isPresenting = false;
|
|
119
|
-
// Pasar remoteConfig en el handler
|
|
120
|
-
if (onError) {
|
|
121
|
-
onError(error, this.remoteConfig);
|
|
122
|
-
}
|
|
123
|
-
return true;
|
|
124
|
-
},
|
|
125
|
-
onAnalytics: (event, data) => {
|
|
126
|
-
config.DEBUG_MODE && console.log('Onboarding analytics:', event, data);
|
|
127
|
-
if (handlers.onAnalytics) {
|
|
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:', {
|
|
114
|
+
config.DEBUG_MODE && console.log('State updated:', {
|
|
144
115
|
action,
|
|
145
116
|
meta,
|
|
146
117
|
currentStep: this.currentStep,
|
|
147
118
|
totalSteps: this.totalSteps,
|
|
148
119
|
termsAccepted: this.termsAccepted
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
handlers.onFinishedLoading(meta, this.remoteConfig);
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (this.props.onStateUpdated) {
|
|
124
|
+
this.props.onStateUpdated(action, meta, this.remoteConfig);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
handleError = (error) => {
|
|
129
|
+
console.log('Onboarding error:', error);
|
|
163
130
|
|
|
164
|
-
await this.onboardingView.present();
|
|
165
|
-
} else {
|
|
166
|
-
console.warn('Onboarding not found for placement:', placementID, 'and language:', lang);
|
|
167
131
|
if (this.props.onError) {
|
|
168
|
-
|
|
132
|
+
this.props.onError(error, this.remoteConfig);
|
|
169
133
|
}
|
|
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
|
-
}
|
|
134
|
+
return true;
|
|
177
135
|
}
|
|
178
|
-
}
|
|
179
136
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
} catch (error) {
|
|
187
|
-
console.error('Error dismissing onboarding:', error);
|
|
188
|
-
}
|
|
137
|
+
handleAnalytics = (event, data) => {
|
|
138
|
+
config.DEBUG_MODE && console.log('Onboarding analytics:', event, data);
|
|
139
|
+
|
|
140
|
+
if (this.props.onAnalytics) {
|
|
141
|
+
this.props.onAnalytics(event, data, this.remoteConfig);
|
|
142
|
+
}
|
|
189
143
|
}
|
|
190
|
-
}
|
|
191
144
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
145
|
+
handlePaywall = (actionId, meta) => {
|
|
146
|
+
config.DEBUG_MODE && console.log('Onboarding paywall:', actionId, meta);
|
|
147
|
+
|
|
148
|
+
if (this.props.onPaywall) {
|
|
149
|
+
this.props.onPaywall(this.remoteConfig);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
handleFinishedLoading = (meta) => {
|
|
154
|
+
config.DEBUG_MODE && console.log('Onboarding finished loading', meta);
|
|
155
|
+
|
|
156
|
+
if (this.props.onFinishedLoading) {
|
|
157
|
+
this.props.onFinishedLoading(meta, this.remoteConfig);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// --------------------------------------- Event Handlers ---------------------------------------
|
|
161
|
+
|
|
162
|
+
render() {
|
|
163
|
+
const { visible } = this.props;
|
|
164
|
+
const { onboarding, isLoading } = this.state;
|
|
165
|
+
|
|
166
|
+
if (!visible) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const content = (
|
|
171
|
+
<View style={styles.container}>
|
|
172
|
+
{!isLoading && onboarding ? (
|
|
173
|
+
<AdaptyOnboardingView
|
|
174
|
+
onboarding={onboarding}
|
|
175
|
+
style={styles.onboardingView}
|
|
176
|
+
eventHandlers={{
|
|
177
|
+
onAnalytics: this.handleAnalytics,
|
|
178
|
+
onClose: this.handleClose,
|
|
179
|
+
onCustom: this.handleCustom,
|
|
180
|
+
onPaywall: this.handlePaywall,
|
|
181
|
+
onStateUpdated: this.handleStateUpdated,
|
|
182
|
+
onFinishedLoading: this.handleFinishedLoading,
|
|
183
|
+
onError: this.handleError,
|
|
184
|
+
}}
|
|
185
|
+
/>
|
|
186
|
+
) : null}
|
|
187
|
+
</View>
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<Modal
|
|
192
|
+
visible={visible}
|
|
193
|
+
animationType="slide"
|
|
194
|
+
presentationStyle="fullScreen"
|
|
195
|
+
onRequestClose={() => {
|
|
196
|
+
config.DEBUG_MODE && console.log('Modal onRequestClose prevented');
|
|
197
|
+
return false;
|
|
198
|
+
}}
|
|
199
|
+
>
|
|
200
|
+
{content}
|
|
201
|
+
</Modal>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
196
205
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
206
|
+
const styles = {
|
|
207
|
+
container: {
|
|
208
|
+
backgroundColor: '#000',
|
|
209
|
+
width: '100%',
|
|
210
|
+
height: '100%',
|
|
211
|
+
},
|
|
212
|
+
onboardingView: {
|
|
213
|
+
flex: 1,
|
|
214
|
+
},
|
|
201
215
|
}
|
|
202
216
|
|
|
203
217
|
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, {}> {}
|