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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apps-sdk",
3
- "version": "1.1.57",
3
+ "version": "1.1.58",
4
4
  "description": "Apps SDK",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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
- constructor(props) {
7
- super(props);
8
- this.onboardingView = null;
9
- this.isPresenting = false;
10
- this.remoteConfig = null;
11
- this.termsAccepted = false;
12
- this.currentStep = 0;
13
- this.totalSteps = 0;
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
- async componentDidUpdate(prevProps) {
23
- if (this.props.visible && !prevProps.visible && !this.isPresenting) {
24
- await this.presentOnboarding();
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
- componentWillUnmount() {
31
- this.dismissOnboarding();
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
- this.onboardingView = await Adapty.createOnboardingView(onboarding);
60
-
61
- this.onboardingView.registerEventHandlers({
62
- onCustom: (actionId, meta) => {
63
- config.DEBUG_MODE && console.log('Onboarding custom action:', actionId, meta);
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
- // 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
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
- // 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);
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
- await this.onboardingView.dismiss();
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
- if (handlers.onStateUpdated) {
153
- handlers.onStateUpdated(action, meta, this.remoteConfig);
154
- }
155
- },
156
- onFinishedLoading: (meta) => {
157
- config.DEBUG_MODE && console.log('Onboarding finished loading', meta);
158
- if (handlers.onFinishedLoading) {
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
- this.props.onError(new Error('Onboarding not found'), this.remoteConfig);
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
- dismissOnboarding = async () => {
181
- if (this.onboardingView && this.isPresenting) {
182
- try {
183
- await this.onboardingView.dismiss();
184
- this.isPresenting = false;
185
- this.remoteConfig = null;
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
- // Método público para acceder al config desde el componente padre (opcional)
193
- getRemoteConfig = () => {
194
- return this.remoteConfig;
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
- render() {
198
- // Componente invisible, el onboarding se presenta nativamente
199
- return null;
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?: Record<string, any>, remoteConfig?: Record<string, any>) => void;
166
- onClose?: (actionId: string, meta?: Record<string, any>, remoteConfig?: Record<string, any>) => void;
167
- onError?: (error: Error | string | any, remoteConfig?: Record<string, any>) => void;
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: string | any, data?: Record<string, any>, remoteConfig?: Record<string, any>) => void;
170
- onPaywall?: (remoteConfig?: Record<string, any>) => void;
171
- onStateUpdated?: (action: any, meta?: Record<string, any>, remoteConfig?: Record<string, any>) => void;
172
- onFinishedLoading?: (meta?: Record<string, any>, remoteConfig?: Record<string, any>) => void;
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, {}> {}