@jolibox/implement 1.1.31 → 1.1.33
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/.rush/temp/package-deps_build.json +10 -10
- package/dist/common/report/types.d.ts +2 -1
- package/dist/index.js +9 -9
- package/dist/index.native.js +98 -63
- package/dist/native/rewards/check-frequency.d.ts +8 -2
- package/implement.build.log +2 -2
- package/package.json +5 -5
- package/src/common/report/track.ts +4 -2
- package/src/common/report/types.ts +3 -3
- package/src/common/rewards/registers/utils/coins/index.ts +1 -5
- package/src/native/api/get-system-info.ts +10 -2
- package/src/native/payment/registers/jolicoin-iap.ts +7 -5
- package/src/native/report/index.ts +5 -2
- package/src/native/rewards/check-frequency.ts +32 -8
- package/src/native/rewards/index.ts +80 -4
- package/src/native/ui/retention.ts +39 -1
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
export declare const checkUseModalFrequency: (config: {
|
|
7
7
|
dailyMaxPopUps: number;
|
|
8
8
|
minInterval: number;
|
|
9
|
-
}) => Promise<
|
|
9
|
+
}) => Promise<{
|
|
10
|
+
canShow: boolean;
|
|
11
|
+
isFirst: boolean;
|
|
12
|
+
}>;
|
|
10
13
|
export declare const updateUseModalFrequency: () => Promise<void>;
|
|
11
14
|
/**
|
|
12
15
|
* check can show paymentModal
|
|
@@ -14,7 +17,10 @@ export declare const updateUseModalFrequency: () => Promise<void>;
|
|
|
14
17
|
export declare const checkPaymentFrequency: (config: {
|
|
15
18
|
dailyMaxPopUps: number;
|
|
16
19
|
minInterval: number;
|
|
17
|
-
}) => Promise<
|
|
20
|
+
}) => Promise<{
|
|
21
|
+
canShow: boolean;
|
|
22
|
+
isFirst: boolean;
|
|
23
|
+
}>;
|
|
18
24
|
/**
|
|
19
25
|
* update paymentFrequency
|
|
20
26
|
*/
|
package/implement.build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Invoking: npm run clean && npm run build:esm && tsc
|
|
2
2
|
|
|
3
|
-
> @jolibox/implement@1.1.
|
|
3
|
+
> @jolibox/implement@1.1.33 clean
|
|
4
4
|
> rimraf ./dist
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
> @jolibox/implement@1.1.
|
|
7
|
+
> @jolibox/implement@1.1.33 build:esm
|
|
8
8
|
> BUILD_VERSION=$(node -p "require('./package.json').version") node esbuild.config.js --format=esm
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jolibox/implement",
|
|
3
3
|
"description": "This project is Jolibox JS-SDk implement for Native && H5",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.33",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@jolibox/common": "1.1.
|
|
10
|
-
"@jolibox/types": "1.1.
|
|
11
|
-
"@jolibox/native-bridge": "1.1.
|
|
12
|
-
"@jolibox/ads": "1.1.
|
|
9
|
+
"@jolibox/common": "1.1.33",
|
|
10
|
+
"@jolibox/types": "1.1.33",
|
|
11
|
+
"@jolibox/native-bridge": "1.1.33",
|
|
12
|
+
"@jolibox/ads": "1.1.33",
|
|
13
13
|
"localforage": "1.10.0",
|
|
14
14
|
"@jolibox/ui": "1.0.0",
|
|
15
15
|
"web-vitals": "4.2.4"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { debounce } from '@jolibox/common';
|
|
1
|
+
import { debounce, EventType } from '@jolibox/common';
|
|
2
2
|
import { ReportHandler, Track, TrackPerformance, CommonReportConfig } from './types';
|
|
3
3
|
import { PerformanceType, TrackEvent } from '@jolibox/types';
|
|
4
4
|
import { InternalGlobalJSError } from '@jolibox/common';
|
|
@@ -7,11 +7,13 @@ import { reportError } from './errors/report';
|
|
|
7
7
|
// Track system event, wrap common config
|
|
8
8
|
export function createTrack(reportHandler: ReportHandler, common: CommonReportConfig): Track {
|
|
9
9
|
const track = (tag: TrackEvent, info: Record<string, unknown> | null, webviewId?: number): void => {
|
|
10
|
+
const { eventType, ...rest } = info ?? {};
|
|
10
11
|
const data = {
|
|
11
12
|
tag,
|
|
13
|
+
eventType: (eventType ?? EventType.Other) as number,
|
|
12
14
|
...common,
|
|
13
15
|
extra: {
|
|
14
|
-
...
|
|
16
|
+
...rest
|
|
15
17
|
}
|
|
16
18
|
};
|
|
17
19
|
if (tag == 'globalJsError') {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PerformanceType, TrackEvent } from '@jolibox/types';
|
|
2
|
-
import { EProject } from '@jolibox/common';
|
|
2
|
+
import { EProject, EventType } from '@jolibox/common';
|
|
3
3
|
|
|
4
4
|
export interface Track {
|
|
5
|
-
(tag: TrackEvent, info: Record<string, unknown> | null): void;
|
|
5
|
+
(tag: TrackEvent, info: Record<string, unknown> | null, eventType?: number): void;
|
|
6
6
|
debounce: (tag: TrackEvent, info: Record<string, unknown>) => void;
|
|
7
7
|
}
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ export interface TrackPerformance {
|
|
|
13
13
|
|
|
14
14
|
export type ReportHandler = (
|
|
15
15
|
event: string,
|
|
16
|
-
data: { tag: TrackEvent; data?: Record<string, string | number | boolean | null> },
|
|
16
|
+
data: { tag: TrackEvent; eventType?: number; data?: Record<string, string | number | boolean | null> },
|
|
17
17
|
webviewId?: number
|
|
18
18
|
) => void;
|
|
19
19
|
|
|
@@ -81,9 +81,7 @@ export const createShowUnlockWithJolicoinModal = (
|
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
const checkIfCancel = (result: IPaymentResult | IUseModalResult) => {
|
|
84
|
-
|
|
85
|
-
throw new Error('CANCEL');
|
|
86
|
-
}
|
|
84
|
+
return result == 'CANCEL';
|
|
87
85
|
};
|
|
88
86
|
|
|
89
87
|
export const createCommonJolicoinRewardHandler = (
|
|
@@ -118,7 +116,6 @@ export const createCommonJolicoinRewardHandler = (
|
|
|
118
116
|
userJoliCoin: unlockOptions?.userJoliCoin,
|
|
119
117
|
joliCoinQuantity
|
|
120
118
|
});
|
|
121
|
-
checkIfCancel(paymentResult);
|
|
122
119
|
|
|
123
120
|
if (paymentResult !== 'SUCCESS') {
|
|
124
121
|
handleUnlockFailed?.(params);
|
|
@@ -137,7 +134,6 @@ export const createCommonJolicoinRewardHandler = (
|
|
|
137
134
|
joliCoinQuantity
|
|
138
135
|
});
|
|
139
136
|
|
|
140
|
-
checkIfCancel(shouldUnlock);
|
|
141
137
|
if (shouldUnlock !== 'CONFIRM') {
|
|
142
138
|
handleUnlockFailed?.(params);
|
|
143
139
|
return false;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createCommands } from '@jolibox/common';
|
|
2
2
|
import { createSyncAPI, registerCanIUse } from './base';
|
|
3
3
|
import { invokeNative } from '@jolibox/native-bridge';
|
|
4
|
+
import { context } from '@/common/context';
|
|
4
5
|
|
|
5
6
|
const commands = createCommands();
|
|
6
7
|
|
|
@@ -19,7 +20,11 @@ const getSystemInfoSync = createSyncAPI(API_GET_SYSTEM_SYNC, {
|
|
|
19
20
|
language: data.deviceInfo.lang,
|
|
20
21
|
brand: data.deviceInfo.brand,
|
|
21
22
|
appName: data.hostInfo?.appName,
|
|
22
|
-
SDKVersion: data.sdkInfo.jssdkVersion
|
|
23
|
+
SDKVersion: data.sdkInfo.jssdkVersion,
|
|
24
|
+
viewport: {
|
|
25
|
+
statusBarHeight: context.viewport.statusBarHeight,
|
|
26
|
+
navigationBarHeight: context.viewport.navigationBarHeight
|
|
27
|
+
}
|
|
23
28
|
};
|
|
24
29
|
}
|
|
25
30
|
});
|
|
@@ -40,5 +45,8 @@ registerCanIUse('env', {
|
|
|
40
45
|
});
|
|
41
46
|
|
|
42
47
|
registerCanIUse('getSystemInfoSync', {
|
|
43
|
-
version: '1.0.0'
|
|
48
|
+
version: '1.0.0',
|
|
49
|
+
properties: {
|
|
50
|
+
viewport: '1.0.33'
|
|
51
|
+
}
|
|
44
52
|
});
|
|
@@ -58,11 +58,13 @@ onNative('onPaymentStateChange', (data) => {
|
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
const failedStatus = IPaymentIAPFailedStatusMap[status]
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
const failedStatus = IPaymentIAPFailedStatusMap[status];
|
|
62
|
+
if (failedStatus) {
|
|
63
|
+
createToast(`{slot-error} {slot-i18n-jolicoin.${failedStatus}}`, {
|
|
64
|
+
position: 'center',
|
|
65
|
+
duration: 3000
|
|
66
|
+
});
|
|
67
|
+
}
|
|
66
68
|
deferred.resolve({
|
|
67
69
|
code: 'FAILED' as ResponseType,
|
|
68
70
|
message: 'jolicoin payment failed'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import './errors';
|
|
2
|
-
import { createCommands, isObject, isString, EventEmitter, EProject } from '@jolibox/common';
|
|
2
|
+
import { createCommands, isObject, isString, EventEmitter, EProject, EventType } from '@jolibox/common';
|
|
3
3
|
export * from '../../common/report/types';
|
|
4
4
|
import { createTracks, ReportHandler } from '@/common/report';
|
|
5
5
|
import { context } from '@/common/context';
|
|
@@ -20,10 +20,13 @@ const reportNative: ReportHandler = (event, data, webviewId) => {
|
|
|
20
20
|
session_id: context.sessionId,
|
|
21
21
|
user_id: context.hostUserInfo?.uid ?? ''
|
|
22
22
|
};
|
|
23
|
+
const eventType = (_data.eventType ?? EventType.Other) as number;
|
|
24
|
+
|
|
23
25
|
invokeNative('trackAsync', {
|
|
24
26
|
event: data.tag ?? event,
|
|
25
27
|
data: extra,
|
|
26
|
-
webviewId
|
|
28
|
+
webviewId,
|
|
29
|
+
eventType
|
|
27
30
|
});
|
|
28
31
|
};
|
|
29
32
|
|
|
@@ -22,19 +22,31 @@ export const checkUseModalFrequency = async (config: { dailyMaxPopUps: number; m
|
|
|
22
22
|
const res = (await getGlobalStorage('joli_coin_use_modal_frequency')) as StandardResponse<string>;
|
|
23
23
|
console.log('checkUseModalFrequency', res.data);
|
|
24
24
|
if (!res.data) {
|
|
25
|
-
return
|
|
25
|
+
return {
|
|
26
|
+
canShow: true,
|
|
27
|
+
isFirst: true
|
|
28
|
+
};
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
const fequeycies = parseFrequency(res.data);
|
|
29
32
|
const todayFequencies = filterTodayTimestamps(fequeycies);
|
|
30
33
|
if (todayFequencies.length >= dailyMaxPopUps) {
|
|
31
|
-
return
|
|
34
|
+
return {
|
|
35
|
+
canShow: false,
|
|
36
|
+
isFirst: false
|
|
37
|
+
};
|
|
32
38
|
}
|
|
33
39
|
const now = Date.now();
|
|
34
40
|
if (now - todayFequencies[todayFequencies.length - 1] < minInterval) {
|
|
35
|
-
return
|
|
41
|
+
return {
|
|
42
|
+
canShow: false,
|
|
43
|
+
isFirst: false
|
|
44
|
+
};
|
|
36
45
|
}
|
|
37
|
-
return
|
|
46
|
+
return {
|
|
47
|
+
canShow: true,
|
|
48
|
+
isFirst: false
|
|
49
|
+
};
|
|
38
50
|
};
|
|
39
51
|
|
|
40
52
|
export const updateUseModalFrequency = async () => {
|
|
@@ -56,18 +68,30 @@ export const checkPaymentFrequency = async (config: { dailyMaxPopUps: number; mi
|
|
|
56
68
|
const res = (await getGlobalStorage('joli_coin_payment_frequency')) as StandardResponse<string>;
|
|
57
69
|
console.log('checkPaymentFrequency', res.data);
|
|
58
70
|
if (!res.data) {
|
|
59
|
-
return
|
|
71
|
+
return {
|
|
72
|
+
canShow: true,
|
|
73
|
+
isFirst: true
|
|
74
|
+
};
|
|
60
75
|
}
|
|
61
76
|
const frequencies = parseFrequency(res.data);
|
|
62
77
|
const todayFequencies = filterTodayTimestamps(frequencies);
|
|
63
78
|
if (todayFequencies.length >= dailyMaxPopUps) {
|
|
64
|
-
return
|
|
79
|
+
return {
|
|
80
|
+
canShow: false,
|
|
81
|
+
isFirst: false
|
|
82
|
+
};
|
|
65
83
|
}
|
|
66
84
|
const now = Date.now();
|
|
67
85
|
if (now - todayFequencies[todayFequencies.length - 1] < minInterval) {
|
|
68
|
-
return
|
|
86
|
+
return {
|
|
87
|
+
canShow: false,
|
|
88
|
+
isFirst: false
|
|
89
|
+
};
|
|
69
90
|
}
|
|
70
|
-
return
|
|
91
|
+
return {
|
|
92
|
+
canShow: true,
|
|
93
|
+
isFirst: false
|
|
94
|
+
};
|
|
71
95
|
};
|
|
72
96
|
|
|
73
97
|
/**
|
|
@@ -19,6 +19,7 @@ import { innerFetch as fetch } from '../network';
|
|
|
19
19
|
import { StandardResponse } from '@jolibox/types';
|
|
20
20
|
import { context } from '@/common/context';
|
|
21
21
|
import { login } from '../api/login';
|
|
22
|
+
import { EventType } from '@jolibox/common';
|
|
22
23
|
|
|
23
24
|
import { createEventPromiseHandler } from '@/common/rewards/registers/utils/event-listener';
|
|
24
25
|
import {
|
|
@@ -32,6 +33,7 @@ import { createLoading } from '@jolibox/ui';
|
|
|
32
33
|
import { canIUseNative } from '../api/base';
|
|
33
34
|
import { applyNative } from '@jolibox/native-bridge';
|
|
34
35
|
import { isUndefinedOrNull } from '@jolibox/common';
|
|
36
|
+
import { track } from '../report';
|
|
35
37
|
|
|
36
38
|
const modalUseFrequencyConfig = createEventPromiseHandler<
|
|
37
39
|
IUseModalFrequencyConfig,
|
|
@@ -77,15 +79,33 @@ rewardsEmitter.on(UseModalEventName, async (type: 'JOLI_COIN' | 'ADS-JOLI_COIN',
|
|
|
77
79
|
duration: 3000
|
|
78
80
|
});
|
|
79
81
|
const config = await modalUseFrequencyConfig.getData();
|
|
80
|
-
const canShowUseModal = await checkUseModalFrequency(
|
|
81
|
-
|
|
82
|
+
const { canShow: canShowUseModal, isFirst: isFirstUseModal } = await checkUseModalFrequency(
|
|
83
|
+
config.joliCoinUseAndCharge.useJolicoin
|
|
84
|
+
);
|
|
85
|
+
console.log('use modal show by frequency', canShowUseModal, isFirstUseModal);
|
|
82
86
|
loading.hide();
|
|
87
|
+
|
|
88
|
+
// First, check for direct use: sufficient balance, auto-deduct enabled, and not the first modal.
|
|
89
|
+
const { balance } = params.userJoliCoin;
|
|
90
|
+
const useDirectly = balance >= params.joliCoinQuantity && params.enableAutoDeduct;
|
|
91
|
+
if (useDirectly && !isFirstUseModal) {
|
|
92
|
+
rewardsEmitter.emit(UseModalResultEventName, { useModalResult: 'CONFIRM' });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// If not used directly, then check frequency control.
|
|
83
97
|
if (!canShowUseModal) {
|
|
84
|
-
//
|
|
98
|
+
// confirm by frequency control
|
|
85
99
|
rewardsEmitter.emit(UseModalResultEventName, { useModalResult: 'CONFIRM' });
|
|
86
100
|
return;
|
|
87
101
|
}
|
|
88
102
|
}
|
|
103
|
+
|
|
104
|
+
track('unlock_popup_show', {
|
|
105
|
+
eventType: EventType.View,
|
|
106
|
+
targetType: 'game'
|
|
107
|
+
});
|
|
108
|
+
|
|
89
109
|
const modal = createConfirmJolicoinModal({
|
|
90
110
|
data: {
|
|
91
111
|
enableAutoDeduct: params.enableAutoDeduct,
|
|
@@ -96,6 +116,12 @@ rewardsEmitter.on(UseModalEventName, async (type: 'JOLI_COIN' | 'ADS-JOLI_COIN',
|
|
|
96
116
|
confirm: {
|
|
97
117
|
text: params.confirmButtonText,
|
|
98
118
|
onPress: () => {
|
|
119
|
+
track('coin_unlock_click', {
|
|
120
|
+
targetType: 'game',
|
|
121
|
+
eventType: EventType.Click,
|
|
122
|
+
coinConsume: params.joliCoinQuantity,
|
|
123
|
+
ifAutoUnlock: params.enableAutoDeduct
|
|
124
|
+
});
|
|
99
125
|
rewardsEmitter.emit(UseModalResultEventName, { useModalResult: 'CONFIRM' });
|
|
100
126
|
modal.destroy();
|
|
101
127
|
}
|
|
@@ -103,6 +129,12 @@ rewardsEmitter.on(UseModalEventName, async (type: 'JOLI_COIN' | 'ADS-JOLI_COIN',
|
|
|
103
129
|
cancel: {
|
|
104
130
|
text: params.cancelButtonText,
|
|
105
131
|
onPress: ({ type }) => {
|
|
132
|
+
if (type === 'FAILED') {
|
|
133
|
+
track('ad_unlock_click', {
|
|
134
|
+
targetType: 'game',
|
|
135
|
+
eventType: EventType.Click
|
|
136
|
+
});
|
|
137
|
+
}
|
|
106
138
|
rewardsEmitter.emit(UseModalResultEventName, {
|
|
107
139
|
useModalResult: (type ?? '') === 'CANCEL' ? 'CANCEL' : 'FAILED'
|
|
108
140
|
});
|
|
@@ -140,7 +172,9 @@ rewardsEmitter.on(
|
|
|
140
172
|
duration: 3000
|
|
141
173
|
});
|
|
142
174
|
const config = await modalUseFrequencyConfig.getData();
|
|
143
|
-
const canShowPaymentModal = await checkPaymentFrequency(
|
|
175
|
+
const { canShow: canShowPaymentModal } = await checkPaymentFrequency(
|
|
176
|
+
config.joliCoinUseAndCharge.charge
|
|
177
|
+
);
|
|
144
178
|
console.log('use payment show by frequency', canShowPaymentModal);
|
|
145
179
|
loading.hide();
|
|
146
180
|
if (!canShowPaymentModal) {
|
|
@@ -164,6 +198,12 @@ rewardsEmitter.on(
|
|
|
164
198
|
rewardsEmitter.emit(PaymentResultEventName, { paymentResult: 'FAILED' });
|
|
165
199
|
return;
|
|
166
200
|
}
|
|
201
|
+
|
|
202
|
+
track('coinorder_show', {
|
|
203
|
+
targetType: 'game',
|
|
204
|
+
eventType: EventType.View
|
|
205
|
+
});
|
|
206
|
+
|
|
167
207
|
const modal = createPaymentJolicoinModal({
|
|
168
208
|
data: {
|
|
169
209
|
userJolicoin: params.userJoliCoin,
|
|
@@ -179,6 +219,15 @@ rewardsEmitter.on(
|
|
|
179
219
|
confirm: {
|
|
180
220
|
text: params.confirmButtonText,
|
|
181
221
|
onPress: async (productId: string) => {
|
|
222
|
+
track('order_pay_ensure', {
|
|
223
|
+
targetType: 'game',
|
|
224
|
+
eventType: EventType.Click,
|
|
225
|
+
payWay: 'app_iap',
|
|
226
|
+
coinAmount: params.joliCoinQuantity,
|
|
227
|
+
orderPrice:
|
|
228
|
+
balenceDetails.paymentChoices.find((choice) => choice.productId === productId)
|
|
229
|
+
?.totalAmountStr ?? ''
|
|
230
|
+
});
|
|
182
231
|
if (!context.hostUserInfo?.isLogin) {
|
|
183
232
|
const { data } = await login();
|
|
184
233
|
if (!data?.isLogin) {
|
|
@@ -211,6 +260,16 @@ rewardsEmitter.on(
|
|
|
211
260
|
appStoreProductId
|
|
212
261
|
});
|
|
213
262
|
loading.hide();
|
|
263
|
+
track('order_pay_result', {
|
|
264
|
+
eventType: EventType.Other,
|
|
265
|
+
targetType: 'game',
|
|
266
|
+
payWay: 'app_iap',
|
|
267
|
+
coinAmount: params.joliCoinQuantity,
|
|
268
|
+
orderPrice:
|
|
269
|
+
balenceDetails.paymentChoices.find((choice) => choice.productId === productId)
|
|
270
|
+
?.totalAmountStr ?? '',
|
|
271
|
+
payResult: code
|
|
272
|
+
});
|
|
214
273
|
if (code !== 'SUCCESS') {
|
|
215
274
|
/** add timeout for google panel closed */
|
|
216
275
|
console.info('[JoliboxSDK] payment failed in payment.invokePaymet');
|
|
@@ -226,12 +285,26 @@ rewardsEmitter.on(
|
|
|
226
285
|
rewardsEmitter.emit(PaymentResultEventName, {
|
|
227
286
|
paymentResult: (type ?? '') === 'CANCEL' ? 'CANCEL' : 'FAILED'
|
|
228
287
|
});
|
|
288
|
+
track('ad_unlock_click', {
|
|
289
|
+
targetType: 'game',
|
|
290
|
+
eventType: EventType.Click
|
|
291
|
+
});
|
|
229
292
|
modal.destroy();
|
|
230
293
|
}
|
|
231
294
|
},
|
|
232
295
|
onEnableDeductChanged: async (enabled: boolean) => {
|
|
233
296
|
await updateAutoDeductConfig(enabled);
|
|
234
297
|
}
|
|
298
|
+
},
|
|
299
|
+
onSelect: (productId: string) => {
|
|
300
|
+
track('coinorder_click', {
|
|
301
|
+
targetType: 'game',
|
|
302
|
+
eventType: EventType.Click,
|
|
303
|
+
coinAmount: params.joliCoinQuantity,
|
|
304
|
+
orderPrice:
|
|
305
|
+
balenceDetails.paymentChoices.find((choice) => choice.productId === productId)
|
|
306
|
+
?.totalAmountStr ?? ''
|
|
307
|
+
});
|
|
235
308
|
}
|
|
236
309
|
});
|
|
237
310
|
|
|
@@ -292,5 +365,8 @@ const getBalenceDetails = async (): Promise<
|
|
|
292
365
|
mergeResponseData(response.data?.data, data);
|
|
293
366
|
}
|
|
294
367
|
console.info('productDetails', response.data?.data);
|
|
368
|
+
if (response.data?.data?.paymentChoices.length === 0) {
|
|
369
|
+
throw new Error('paymentChoices is empty');
|
|
370
|
+
}
|
|
295
371
|
return response.data?.data;
|
|
296
372
|
};
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { context } from '@/common/context';
|
|
2
2
|
import { invokeNative, subscribe } from '@jolibox/native-bridge';
|
|
3
|
-
import { Deferred } from '@jolibox/common';
|
|
3
|
+
import { Deferred, EventType } from '@jolibox/common';
|
|
4
4
|
import { createRecommendModal, IGame, IRecommendationButton, RecommendModalOnCloseParams } from '@jolibox/ui';
|
|
5
5
|
import { innerFetch as fetch } from '../network';
|
|
6
|
+
import { track } from '../report';
|
|
7
|
+
|
|
8
|
+
enum RecommendGuideType {
|
|
9
|
+
Hide = 'Hide',
|
|
10
|
+
View = 'View',
|
|
11
|
+
Click = 'Click'
|
|
12
|
+
}
|
|
6
13
|
|
|
7
14
|
let exitRecommendationsCache: {
|
|
8
15
|
code: string;
|
|
@@ -96,6 +103,17 @@ export async function openRetentionSchema() {
|
|
|
96
103
|
const { gameListInfo, title, buttons } = data.data;
|
|
97
104
|
|
|
98
105
|
isOpenRetentionSchema = true;
|
|
106
|
+
|
|
107
|
+
const modalContentForReport = {
|
|
108
|
+
domain: 'GAME',
|
|
109
|
+
buttons: data.data.buttons.map((btn) => `${btn.type}-${btn.text}`).join(','),
|
|
110
|
+
list: gameListInfo.games.map((game) => game.gameId).join(',')
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
track('RecommendedGuide', {
|
|
114
|
+
eventType: EventType.View,
|
|
115
|
+
...modalContentForReport
|
|
116
|
+
});
|
|
99
117
|
const modal = createRecommendModal({
|
|
100
118
|
games: gameListInfo.games,
|
|
101
119
|
title,
|
|
@@ -104,17 +122,33 @@ export async function openRetentionSchema() {
|
|
|
104
122
|
isOpenRetentionSchema = false;
|
|
105
123
|
switch (params.type) {
|
|
106
124
|
case 'quit':
|
|
125
|
+
track('RecommendedGuide', {
|
|
126
|
+
eventType: EventType.Click,
|
|
127
|
+
type: 'QUIT',
|
|
128
|
+
domain: 'GAME'
|
|
129
|
+
});
|
|
107
130
|
quitResultDeffer.resolve(false);
|
|
108
131
|
break;
|
|
109
132
|
case 'dismiss':
|
|
133
|
+
track('RecommendedGuide', {
|
|
134
|
+
eventType: EventType.Hide,
|
|
135
|
+
...modalContentForReport
|
|
136
|
+
});
|
|
110
137
|
quitResultDeffer.resolve(true);
|
|
111
138
|
modal.destroy();
|
|
139
|
+
|
|
112
140
|
break;
|
|
113
141
|
case 'navigate':
|
|
114
142
|
// TODO: 跳转游戏
|
|
115
143
|
if (params.data?.game) {
|
|
116
144
|
const game = params.data.game;
|
|
117
145
|
openGameSchema(game);
|
|
146
|
+
track('GameItem', {
|
|
147
|
+
eventType: EventType.Click,
|
|
148
|
+
gameId: game.gameId,
|
|
149
|
+
layerName: 'RecommendedGuide',
|
|
150
|
+
domain: 'GAME'
|
|
151
|
+
});
|
|
118
152
|
setTimeout(() => {
|
|
119
153
|
quitResultDeffer.resolve(false);
|
|
120
154
|
}, 0);
|
|
@@ -125,6 +159,10 @@ export async function openRetentionSchema() {
|
|
|
125
159
|
break;
|
|
126
160
|
default:
|
|
127
161
|
// 关闭弹框,留在当前游戏
|
|
162
|
+
track('RecommendedGuide', {
|
|
163
|
+
eventType: EventType.Hide,
|
|
164
|
+
...modalContentForReport
|
|
165
|
+
});
|
|
128
166
|
quitResultDeffer.resolve(true);
|
|
129
167
|
break;
|
|
130
168
|
}
|