apps-sdk 2.1.1 → 2.1.3
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/config.js +50 -16
- package/index.js +2 -1
- package/package.json +2 -2
- package/src/libraries/Authentication.js +799 -0
- package/src/libraries/Networking.js +13 -2
- package/src/libraries/Rating.js +312 -50
- package/src/libraries/Session.js +5 -0
- package/src/libraries/index.js +1 -0
- package/types/index.d.ts +39 -1
|
@@ -126,12 +126,23 @@ class Networking {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
setEndpoints(domains) {
|
|
129
|
+
// Update BASE_URLS instead of ENDPOINTS directly
|
|
129
130
|
for (let key in domains) {
|
|
130
131
|
if (domains.hasOwnProperty(key)) {
|
|
131
|
-
|
|
132
|
+
const upperKey = key.toUpperCase();
|
|
133
|
+
// Map backend domains to BASE_URLS
|
|
134
|
+
if (upperKey === 'CONTENTS') {
|
|
135
|
+
config.BASE_URLS.CORE = domains[key];
|
|
136
|
+
} else if (upperKey === 'EVENTS') {
|
|
137
|
+
config.BASE_URLS.EVENTS = domains[key];
|
|
138
|
+
} else if (upperKey === 'LEGAL') {
|
|
139
|
+
// LEGAL uses WEBAPP, no separate BASE_URL
|
|
140
|
+
config.BASE_URLS.WEBAPP = domains[key];
|
|
141
|
+
}
|
|
132
142
|
}
|
|
133
143
|
}
|
|
134
|
-
|
|
144
|
+
// Store updated BASE_URLS
|
|
145
|
+
storage.storeData("BASE_URLS", config.BASE_URLS);
|
|
135
146
|
}
|
|
136
147
|
|
|
137
148
|
setImageCompression(compression) {
|
package/src/libraries/Rating.js
CHANGED
|
@@ -1,65 +1,327 @@
|
|
|
1
1
|
import * as StoreReview from 'expo-store-review';
|
|
2
|
+
import { Platform } from 'react-native';
|
|
2
3
|
import Storage from './Storage';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Storage keys
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
const STORAGE_KEYS = {
|
|
9
|
+
FIRST_AI_INTERACTION_DONE: 'RATING_FIRST_AI_INTERACTION_DONE',
|
|
10
|
+
USER_SENTIMENT_POSITIVE: 'RATING_USER_SENTIMENT_POSITIVE',
|
|
11
|
+
RATING_ATTEMPTS_COUNT: 'RATING_ATTEMPTS_COUNT',
|
|
12
|
+
FEEDBACK_SUBMITTED: 'RATING_FEEDBACK_SUBMITTED',
|
|
13
|
+
LAST_RATING_PROMPT_DATE: 'RATING_LAST_RATING_PROMPT_DATE',
|
|
14
|
+
DOWNLOAD_SHARE_PROMPT_SHOWN: 'RATING_DOWNLOAD_SHARE_PROMPT_SHOWN',
|
|
15
|
+
LOW_CREDITS_PROMPT_SHOWN: 'RATING_LOW_CREDITS_PROMPT_SHOWN',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Constants
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
const MAX_RATING_ATTEMPTS = 2; // Max native rating prompts shown lifetime
|
|
22
|
+
const RATING_DELAY_MS = 5000; // Delay before showing prompt after AI response
|
|
23
|
+
const LOW_CREDITS_THRESHOLD = 3; // Credits level considered "low"
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Rating class
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
5
28
|
class Rating {
|
|
6
|
-
|
|
29
|
+
|
|
30
|
+
// In-memory state (also persisted in storage)
|
|
31
|
+
_hasCompletedFirstInteraction = false;
|
|
32
|
+
_isShowingPrompt = false;
|
|
33
|
+
|
|
34
|
+
// UI callbacks — injected via configure()
|
|
35
|
+
_onShowSentimentPrompt = null; // (source: string) => void
|
|
36
|
+
_onShowFeedbackForm = null; // () => void
|
|
37
|
+
_onTrackEvent = null; // (eventName: string, props: object) => void
|
|
38
|
+
_onSubmitFeedback = null; // (text: string) => Promise<void> (optional app-level hook)
|
|
39
|
+
|
|
40
|
+
// -----------------------------------------------------------------------
|
|
41
|
+
// configure — call once on app startup (after initialize) with UI hooks
|
|
42
|
+
// -----------------------------------------------------------------------
|
|
43
|
+
configure = ({
|
|
44
|
+
onShowSentimentPrompt,
|
|
45
|
+
onShowFeedbackForm,
|
|
46
|
+
onTrackEvent,
|
|
47
|
+
onSubmitFeedback,
|
|
48
|
+
} = {}) => {
|
|
49
|
+
if (onShowSentimentPrompt) this._onShowSentimentPrompt = onShowSentimentPrompt;
|
|
50
|
+
if (onShowFeedbackForm) this._onShowFeedbackForm = onShowFeedbackForm;
|
|
51
|
+
if (onTrackEvent) this._onTrackEvent = onTrackEvent;
|
|
52
|
+
if (onSubmitFeedback) this._onSubmitFeedback = onSubmitFeedback;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// -----------------------------------------------------------------------
|
|
56
|
+
// initialize — load persisted state from storage
|
|
57
|
+
// -----------------------------------------------------------------------
|
|
58
|
+
initialize = async () => {
|
|
7
59
|
try {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
60
|
+
const hasInteracted = await Storage.getData(STORAGE_KEYS.FIRST_AI_INTERACTION_DONE);
|
|
61
|
+
this._hasCompletedFirstInteraction = hasInteracted === 'true';
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error('[RatingFlow] Failed to initialize:', error);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// -----------------------------------------------------------------------
|
|
68
|
+
// onAIInteractionSuccess
|
|
69
|
+
// Called after every successful AI response.
|
|
70
|
+
// @param isUserInitiated — true if the user explicitly triggered the action
|
|
71
|
+
// -----------------------------------------------------------------------
|
|
72
|
+
onAIInteractionSuccess = async (isUserInitiated = false) => {
|
|
73
|
+
if (this._isShowingPrompt) return;
|
|
74
|
+
|
|
75
|
+
if (!this._hasCompletedFirstInteraction) {
|
|
76
|
+
// Only show on user-initiated interactions (not auto-generated intro/welcome)
|
|
77
|
+
if (!isUserInitiated) return;
|
|
78
|
+
|
|
79
|
+
await Storage.storeData(STORAGE_KEYS.FIRST_AI_INTERACTION_DONE, 'true');
|
|
80
|
+
this._hasCompletedFirstInteraction = true;
|
|
81
|
+
|
|
82
|
+
setTimeout(async () => {
|
|
83
|
+
const canShow = await this._checkBasicEligibility();
|
|
84
|
+
if (canShow) {
|
|
85
|
+
await this._updateLastShownDate();
|
|
86
|
+
this._showSentimentPrompt('ai_interaction');
|
|
87
|
+
}
|
|
88
|
+
}, RATING_DELAY_MS);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const userSaidYes = await Storage.getData(STORAGE_KEYS.USER_SENTIMENT_POSITIVE);
|
|
93
|
+
|
|
94
|
+
if (userSaidYes === 'true') {
|
|
95
|
+
setTimeout(async () => {
|
|
96
|
+
const canShow = await this._checkBasicEligibility();
|
|
97
|
+
const shownToday = await this._wasShownToday();
|
|
98
|
+
if (canShow && !shownToday && !this._isShowingPrompt) {
|
|
99
|
+
await this._updateLastShownDate();
|
|
100
|
+
this._trackEvent('rate_prompt_shown', { source: 'ai_interaction', type: 'direct_rating' });
|
|
101
|
+
await this.triggerNativeRating();
|
|
102
|
+
}
|
|
103
|
+
}, RATING_DELAY_MS);
|
|
104
|
+
} else {
|
|
105
|
+
setTimeout(async () => {
|
|
106
|
+
const canShow = await this._checkBasicEligibility();
|
|
107
|
+
const shownToday = await this._wasShownToday();
|
|
108
|
+
if (canShow && !shownToday && !this._isShowingPrompt) {
|
|
109
|
+
await this._updateLastShownDate();
|
|
110
|
+
this._showSentimentPrompt('ai_interaction');
|
|
32
111
|
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
112
|
+
}, RATING_DELAY_MS);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// -----------------------------------------------------------------------
|
|
117
|
+
// onCreditsRunningLow
|
|
118
|
+
// Called after a successful action when credits are low.
|
|
119
|
+
// @param currentCredits — current credit count
|
|
120
|
+
// -----------------------------------------------------------------------
|
|
121
|
+
onCreditsRunningLow = async (currentCredits) => {
|
|
122
|
+
if (this._isShowingPrompt) return;
|
|
123
|
+
if (currentCredits > LOW_CREDITS_THRESHOLD) return;
|
|
124
|
+
|
|
125
|
+
const canShow = await this._checkBasicEligibility();
|
|
126
|
+
if (!canShow) return;
|
|
127
|
+
|
|
128
|
+
const shownToday = await this._wasShownToday();
|
|
129
|
+
if (shownToday) return;
|
|
130
|
+
|
|
131
|
+
const userSaidYes = await Storage.getData(STORAGE_KEYS.USER_SENTIMENT_POSITIVE);
|
|
132
|
+
if (userSaidYes === 'true') {
|
|
133
|
+
await this._updateLastShownDate();
|
|
134
|
+
this._trackEvent('rate_prompt_shown', { source: 'credits_low', type: 'direct_rating' });
|
|
135
|
+
await this.triggerNativeRating();
|
|
136
|
+
} else {
|
|
137
|
+
const alreadyShown = await Storage.getData(STORAGE_KEYS.LOW_CREDITS_PROMPT_SHOWN);
|
|
138
|
+
if (alreadyShown === 'true') return;
|
|
139
|
+
await Storage.storeData(STORAGE_KEYS.LOW_CREDITS_PROMPT_SHOWN, 'true');
|
|
140
|
+
await this._updateLastShownDate();
|
|
141
|
+
this._showSentimentPrompt('credits_low');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// -----------------------------------------------------------------------
|
|
146
|
+
// onResultDownloadedOrShared
|
|
147
|
+
// Called when the user downloads or shares an AI result.
|
|
148
|
+
// @param actionType — 'download' | 'share'
|
|
149
|
+
// -----------------------------------------------------------------------
|
|
150
|
+
onResultDownloadedOrShared = async (actionType) => {
|
|
151
|
+
if (this._isShowingPrompt) return;
|
|
152
|
+
|
|
153
|
+
const canShow = await this._checkBasicEligibility();
|
|
154
|
+
if (!canShow) return;
|
|
155
|
+
|
|
156
|
+
const shownToday = await this._wasShownToday();
|
|
157
|
+
if (shownToday) return;
|
|
158
|
+
|
|
159
|
+
const userSaidYes = await Storage.getData(STORAGE_KEYS.USER_SENTIMENT_POSITIVE);
|
|
160
|
+
if (userSaidYes === 'true') {
|
|
161
|
+
await this._updateLastShownDate();
|
|
162
|
+
this._trackEvent('rate_prompt_shown', { source: `result_${actionType}`, type: 'direct_rating' });
|
|
163
|
+
await this.triggerNativeRating();
|
|
164
|
+
} else {
|
|
165
|
+
const alreadyShown = await Storage.getData(STORAGE_KEYS.DOWNLOAD_SHARE_PROMPT_SHOWN);
|
|
166
|
+
if (alreadyShown === 'true') return;
|
|
167
|
+
await Storage.storeData(STORAGE_KEYS.DOWNLOAD_SHARE_PROMPT_SHOWN, 'true');
|
|
168
|
+
await this._updateLastShownDate();
|
|
169
|
+
this._showSentimentPrompt(`result_${actionType}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// -----------------------------------------------------------------------
|
|
174
|
+
// triggerNativeRating — calls StoreReview.requestReview()
|
|
175
|
+
// -----------------------------------------------------------------------
|
|
176
|
+
triggerNativeRating = async () => {
|
|
177
|
+
this._trackEvent('native_rating_prompt_called', { platform: Platform.OS });
|
|
178
|
+
try {
|
|
179
|
+
const attemptsStr = await Storage.getData(STORAGE_KEYS.RATING_ATTEMPTS_COUNT);
|
|
180
|
+
const newAttempts = (attemptsStr ? parseInt(attemptsStr, 10) : 0) + 1;
|
|
181
|
+
await Storage.storeData(STORAGE_KEYS.RATING_ATTEMPTS_COUNT, String(newAttempts));
|
|
182
|
+
await StoreReview.requestReview();
|
|
183
|
+
} catch (error) {
|
|
184
|
+
console.error('[RatingFlow] Rating request failed:', error);
|
|
185
|
+
this._trackEvent('native_rating_api_error', { platform: Platform.OS, error: String(error) });
|
|
186
|
+
} finally {
|
|
187
|
+
this._isShowingPrompt = false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// -----------------------------------------------------------------------
|
|
192
|
+
// onUserRespondedYes — call from the sentiment prompt YES handler
|
|
193
|
+
// -----------------------------------------------------------------------
|
|
194
|
+
onUserRespondedYes = async () => {
|
|
195
|
+
this._trackEvent('rate_prompt_response', { response: 'yes' });
|
|
196
|
+
await Storage.storeData(STORAGE_KEYS.USER_SENTIMENT_POSITIVE, 'true');
|
|
197
|
+
await this.triggerNativeRating();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// -----------------------------------------------------------------------
|
|
201
|
+
// onUserRespondedNo — call from the sentiment prompt NO handler
|
|
202
|
+
// -----------------------------------------------------------------------
|
|
203
|
+
onUserRespondedNo = () => {
|
|
204
|
+
this._trackEvent('rate_prompt_response', { response: 'no' });
|
|
205
|
+
this._showFeedbackForm();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// -----------------------------------------------------------------------
|
|
209
|
+
// submitFeedback — call when the user submits written feedback
|
|
210
|
+
// @param feedbackText — the feedback string
|
|
211
|
+
// -----------------------------------------------------------------------
|
|
212
|
+
submitFeedback = async (feedbackText) => {
|
|
213
|
+
try {
|
|
214
|
+
this._trackEvent('feedback_submitted', { feedback_text: feedbackText });
|
|
215
|
+
await Storage.storeData(STORAGE_KEYS.FEEDBACK_SUBMITTED, 'true');
|
|
216
|
+
if (this._onSubmitFeedback) await this._onSubmitFeedback(feedbackText);
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.error('[RatingFlow] Failed to submit feedback:', error);
|
|
219
|
+
throw error;
|
|
220
|
+
} finally {
|
|
221
|
+
this._isShowingPrompt = false;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// -----------------------------------------------------------------------
|
|
226
|
+
// onFeedbackCanceled — call when the user dismisses the feedback form
|
|
227
|
+
// -----------------------------------------------------------------------
|
|
228
|
+
onFeedbackCanceled = () => {
|
|
229
|
+
this._trackEvent('feedback_canceled');
|
|
230
|
+
this._isShowingPrompt = false;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// -----------------------------------------------------------------------
|
|
234
|
+
// reset — clears all persisted rating state (for debugging/testing)
|
|
235
|
+
// -----------------------------------------------------------------------
|
|
236
|
+
reset = async () => {
|
|
237
|
+
await Promise.all(Object.values(STORAGE_KEYS).map(key => Storage.removeData(key)));
|
|
238
|
+
this._hasCompletedFirstInteraction = false;
|
|
239
|
+
this._isShowingPrompt = false;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// -----------------------------------------------------------------------
|
|
243
|
+
// Legacy: showRatingDialog — kept for backwards compatibility
|
|
244
|
+
// -----------------------------------------------------------------------
|
|
245
|
+
showRatingDialog = async (force = false) => {
|
|
246
|
+
try {
|
|
247
|
+
if (force) {
|
|
248
|
+
await this.triggerNativeRating();
|
|
249
|
+
return { success: true, shown: true };
|
|
41
250
|
}
|
|
251
|
+
const canShow = await this._checkBasicEligibility();
|
|
252
|
+
if (!canShow) return { success: false, shown: false, tooSoon: true };
|
|
253
|
+
await this.triggerNativeRating();
|
|
254
|
+
return { success: true, shown: true };
|
|
255
|
+
} catch (error) {
|
|
256
|
+
console.error('[RatingFlow] showRatingDialog error:', error);
|
|
257
|
+
return { success: false, shown: false, error: true, message: error.message };
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// =======================================================================
|
|
262
|
+
// Private helpers
|
|
263
|
+
// =======================================================================
|
|
264
|
+
|
|
265
|
+
_checkBasicEligibility = async () => {
|
|
266
|
+
try {
|
|
267
|
+
const isAvailable = await StoreReview.isAvailableAsync();
|
|
268
|
+
if (!isAvailable) return false;
|
|
269
|
+
|
|
270
|
+
const feedbackSubmitted = await Storage.getData(STORAGE_KEYS.FEEDBACK_SUBMITTED);
|
|
271
|
+
if (feedbackSubmitted === 'true') return false;
|
|
272
|
+
|
|
273
|
+
const attemptsStr = await Storage.getData(STORAGE_KEYS.RATING_ATTEMPTS_COUNT);
|
|
274
|
+
const attempts = attemptsStr ? parseInt(attemptsStr, 10) : 0;
|
|
275
|
+
if (attempts >= MAX_RATING_ATTEMPTS) return false;
|
|
276
|
+
|
|
277
|
+
return true;
|
|
42
278
|
} catch (error) {
|
|
43
|
-
console.
|
|
44
|
-
return
|
|
45
|
-
success: false,
|
|
46
|
-
shown: false,
|
|
47
|
-
error: true,
|
|
48
|
-
message: error.message
|
|
49
|
-
};
|
|
279
|
+
console.error('[RatingFlow] Error checking basic eligibility:', error);
|
|
280
|
+
return false;
|
|
50
281
|
}
|
|
51
282
|
}
|
|
52
283
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
await StoreReview.requestReview();
|
|
61
|
-
await Storage.storeData('lastReviewRequest', now.toString());
|
|
284
|
+
_wasShownToday = async () => {
|
|
285
|
+
try {
|
|
286
|
+
const lastShownDate = await Storage.getData(STORAGE_KEYS.LAST_RATING_PROMPT_DATE);
|
|
287
|
+
if (lastShownDate) {
|
|
288
|
+
const lastDate = new Date(lastShownDate);
|
|
289
|
+
const now = new Date();
|
|
290
|
+
return lastDate.toDateString() === now.toDateString();
|
|
62
291
|
}
|
|
292
|
+
return false;
|
|
293
|
+
} catch (error) {
|
|
294
|
+
console.error('[RatingFlow] Error checking last shown date:', error);
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
_updateLastShownDate = async () => {
|
|
300
|
+
await Storage.storeData(STORAGE_KEYS.LAST_RATING_PROMPT_DATE, new Date().toISOString());
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
_showSentimentPrompt = (source) => {
|
|
304
|
+
this._isShowingPrompt = true;
|
|
305
|
+
this._trackEvent('rate_prompt_shown', { source: source || 'ai_interaction' });
|
|
306
|
+
if (this._onShowSentimentPrompt) {
|
|
307
|
+
this._onShowSentimentPrompt(source);
|
|
308
|
+
} else {
|
|
309
|
+
console.warn('[RatingFlow] No sentiment prompt handler configured. Call AppsSDK.rating.configure().');
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
_showFeedbackForm = () => {
|
|
314
|
+
this._trackEvent('feedback_screen_shown');
|
|
315
|
+
if (this._onShowFeedbackForm) {
|
|
316
|
+
this._onShowFeedbackForm();
|
|
317
|
+
} else {
|
|
318
|
+
console.warn('[RatingFlow] No feedback form handler configured. Call AppsSDK.rating.configure().');
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
_trackEvent = (eventName, properties = {}) => {
|
|
323
|
+
if (this._onTrackEvent) {
|
|
324
|
+
this._onTrackEvent(eventName, { ...properties, timestamp: new Date().toISOString() });
|
|
63
325
|
}
|
|
64
326
|
}
|
|
65
327
|
}
|
package/src/libraries/Session.js
CHANGED
|
@@ -35,6 +35,11 @@ class Session {
|
|
|
35
35
|
config.ENDPOINTS.USER_CREATE_ID = endpoint;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
setBaseUrl = (baseUrl) => {
|
|
39
|
+
config.DEBUG_MODE && console.debug("setBaseUrl - baseUrl: ", baseUrl);
|
|
40
|
+
config.BASE_URLS.CORE = baseUrl;
|
|
41
|
+
}
|
|
42
|
+
|
|
38
43
|
initSession = async () => {
|
|
39
44
|
config.DEBUG_MODE && console.debug("initSession");
|
|
40
45
|
await Networking.sendEvent(config.EVENT_TYPES.OTHER, 'init_session');
|
package/src/libraries/index.js
CHANGED
|
@@ -14,3 +14,4 @@ export { default as HomeActions } from './QuickActions';
|
|
|
14
14
|
export { default as Facebook } from './Facebook';
|
|
15
15
|
export { default as Firebase } from './Firebase';
|
|
16
16
|
export { default as Legal } from './Legal';
|
|
17
|
+
export { default as Authentication } from './Authentication';
|
package/types/index.d.ts
CHANGED
|
@@ -37,6 +37,10 @@ declare module 'apps-sdk' {
|
|
|
37
37
|
init(): Promise<void>;
|
|
38
38
|
setDebugMode(debugMode: boolean): void;
|
|
39
39
|
setConfigEndpoint(endpoint: string): void;
|
|
40
|
+
setUserCreateEndpoint(endpoint: string): void;
|
|
41
|
+
setBaseUrl(baseUrl: string): void;
|
|
42
|
+
getCredits(webappUrl: string, websiteId: string): Promise<number>;
|
|
43
|
+
getWebappBasePayload(websiteId: string, additionalData?: any): any;
|
|
40
44
|
initSession(): Promise<void>;
|
|
41
45
|
storeSessionStructure(): Promise<void>;
|
|
42
46
|
checkFirstOpen(): Promise<void>;
|
|
@@ -119,8 +123,42 @@ declare module 'apps-sdk' {
|
|
|
119
123
|
isSpecialEvent(eventKeyword: string): boolean;
|
|
120
124
|
}
|
|
121
125
|
|
|
126
|
+
export interface RatingConfigOptions {
|
|
127
|
+
/** Called when the sentiment prompt ("Are you enjoying the app?") should be shown. */
|
|
128
|
+
onShowSentimentPrompt: (source: string) => void;
|
|
129
|
+
/** Called when the feedback form should be shown (user said NO). */
|
|
130
|
+
onShowFeedbackForm: () => void;
|
|
131
|
+
/** Called to track analytics events. */
|
|
132
|
+
onTrackEvent: (eventName: string, properties: Record<string, any>) => void;
|
|
133
|
+
/** Optional: called after feedback text is submitted. */
|
|
134
|
+
onSubmitFeedback?: (feedbackText: string) => Promise<void>;
|
|
135
|
+
}
|
|
136
|
+
|
|
122
137
|
export class Rating {
|
|
123
|
-
|
|
138
|
+
/** Register UI callbacks. Call once on app startup after initialize(). */
|
|
139
|
+
configure(options: RatingConfigOptions): void;
|
|
140
|
+
/** Load persisted state from storage. Call on app startup. */
|
|
141
|
+
initialize(): Promise<void>;
|
|
142
|
+
/** Trigger rating flow after a successful AI interaction. */
|
|
143
|
+
onAIInteractionSuccess(isUserInitiated?: boolean): Promise<void>;
|
|
144
|
+
/** Trigger rating flow when credits are running low. */
|
|
145
|
+
onCreditsRunningLow(currentCredits: number): Promise<void>;
|
|
146
|
+
/** Trigger rating flow after user downloads or shares a result. */
|
|
147
|
+
onResultDownloadedOrShared(actionType: 'download' | 'share'): Promise<void>;
|
|
148
|
+
/** Directly call StoreReview.requestReview(). */
|
|
149
|
+
triggerNativeRating(): Promise<void>;
|
|
150
|
+
/** Call this when the user taps YES on the sentiment prompt. */
|
|
151
|
+
onUserRespondedYes(): Promise<void>;
|
|
152
|
+
/** Call this when the user taps NO on the sentiment prompt. */
|
|
153
|
+
onUserRespondedNo(): void;
|
|
154
|
+
/** Submit written feedback text. */
|
|
155
|
+
submitFeedback(feedbackText: string): Promise<void>;
|
|
156
|
+
/** Call when the user dismisses the feedback form without submitting. */
|
|
157
|
+
onFeedbackCanceled(): void;
|
|
158
|
+
/** Reset all persisted rating state (for debugging/testing). */
|
|
159
|
+
reset(): Promise<void>;
|
|
160
|
+
/** @deprecated Legacy method — use the new flow methods instead. */
|
|
161
|
+
showRatingDialog(force?: boolean): Promise<{ success: boolean; shown: boolean; [key: string]: any }>;
|
|
124
162
|
}
|
|
125
163
|
|
|
126
164
|
export class NotificationsPush {
|