@jolibox/implement 1.1.18 → 1.1.19-beta.6

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.
Files changed (43) hide show
  1. package/.rush/temp/package-deps_build.json +23 -16
  2. package/.rush/temp/shrinkwrap-deps.json +1 -1
  3. package/dist/common/rewards/index.d.ts +1 -10
  4. package/dist/common/rewards/registers/use-ads.d.ts +3 -2
  5. package/dist/common/rewards/registers/use-jolicoin-only.d.ts +10 -0
  6. package/dist/common/rewards/registers/utils/coins/index.d.ts +32 -0
  7. package/dist/common/rewards/registers/utils/event-listener.d.ts +15 -0
  8. package/dist/common/rewards/registers/utils/index.d.ts +1 -0
  9. package/dist/common/rewards/reward-emitter.d.ts +58 -0
  10. package/dist/common/rewards/reward-helper.d.ts +2 -1
  11. package/dist/common/utils/index.d.ts +49 -2
  12. package/dist/h5/api/ads.d.ts +1 -1
  13. package/dist/h5/http/index.d.ts +1 -1
  14. package/dist/h5/rewards/index.d.ts +4 -0
  15. package/dist/index.js +197 -3
  16. package/dist/index.native.js +402 -21
  17. package/dist/native/api/ads.d.ts +1 -1
  18. package/dist/native/api/login.d.ts +4 -1
  19. package/dist/native/rewards/index.d.ts +4 -0
  20. package/dist/native/ui/modal-iframe.d.ts +26 -0
  21. package/implement.build.log +2 -2
  22. package/package.json +5 -4
  23. package/src/common/context/index.ts +3 -3
  24. package/src/common/rewards/fetch-reward.ts +9 -3
  25. package/src/common/rewards/index.ts +1 -12
  26. package/src/common/rewards/registers/use-ads.ts +3 -2
  27. package/src/common/rewards/registers/use-jolicoin-only.ts +57 -0
  28. package/src/common/rewards/registers/use-jolicoin.ts +27 -77
  29. package/src/common/rewards/registers/utils/coins/index.ts +186 -0
  30. package/src/common/rewards/registers/utils/event-listener.ts +66 -0
  31. package/src/common/rewards/registers/utils/index.ts +8 -0
  32. package/src/common/rewards/reward-emitter.ts +79 -0
  33. package/src/common/rewards/reward-helper.ts +3 -2
  34. package/src/common/utils/index.ts +117 -4
  35. package/src/h5/api/ads.ts +65 -12
  36. package/src/h5/http/index.ts +2 -2
  37. package/src/h5/rewards/index.ts +69 -0
  38. package/src/native/api/ads.ts +95 -33
  39. package/src/native/api/login.ts +1 -1
  40. package/src/native/api/navigate.ts +13 -1
  41. package/src/native/bootstrap/index.ts +25 -1
  42. package/src/native/rewards/index.ts +138 -0
  43. package/src/native/ui/modal-iframe.ts +271 -0
@@ -0,0 +1,79 @@
1
+ // rewards-emitter-wrapper.ts
2
+
3
+ import { EventEmitter } from '@jolibox/common';
4
+ import { IUnlockOption } from './type';
5
+ import { IJoliCoin } from './type';
6
+
7
+ export interface IUnlockOptionsEvent {
8
+ options: IUnlockOption[];
9
+ userJoliCoin: IJoliCoin;
10
+ }
11
+
12
+ export const UnlockOptionsEventName = 'UNLOCK_OPTIONS_CHANGED' as const;
13
+ export const InvokePaymentEventName = 'INVOKE_PAYMENT' as const;
14
+ export const PaymentResultEventName = 'ON_PAYMENT_RESULT' as const;
15
+ export const UseModalEventName = 'ON_USE_MODAL_EVENT' as const;
16
+ export const UseModalResultEventName = 'ON_USE_MODAL_RESULT' as const;
17
+
18
+ type IPaymentResult = 'SUCCESS' | 'FAILED' | 'CANCEL';
19
+ export interface IPaymentEvent {
20
+ userJoliCoin?: IJoliCoin;
21
+ paymentResult: IPaymentResult;
22
+ }
23
+
24
+ export interface IPaymentChoice {
25
+ productId: string;
26
+ totalAmountStr: string;
27
+ quantity: number;
28
+ }
29
+
30
+ export interface IInvokePaymentEvent {
31
+ userJoliCoin: IJoliCoin;
32
+ joliCoinQuantity: number;
33
+ enableAutoDeduct: boolean;
34
+ confirmButtonText: string;
35
+ cancelButtonText: string;
36
+ sequenceId?: string;
37
+ }
38
+
39
+ export interface IUseModalEvent {
40
+ enableAutoDeduct: boolean;
41
+ userJoliCoin: IJoliCoin;
42
+ joliCoinQuantity: number;
43
+ confirmButtonText: string;
44
+ cancelButtonText: string;
45
+ sequenceId?: string;
46
+ }
47
+
48
+ export interface IUseModalResultEvent {
49
+ useModalResult: 'CONFIRM' | 'CANCEL' | 'FAILED';
50
+ }
51
+
52
+ export interface RewardsEventMap extends Record<string, unknown[]> {
53
+ [UnlockOptionsEventName]: [IUnlockOptionsEvent];
54
+ [InvokePaymentEventName]: ['JOLI_COIN' | 'ADS-JOLI_COIN', IInvokePaymentEvent];
55
+ [PaymentResultEventName]: [IPaymentEvent];
56
+ [UseModalResultEventName]: [IUseModalResultEvent];
57
+ [UseModalEventName]: ['JOLI_COIN' | 'ADS-JOLI_COIN', IUseModalEvent];
58
+ }
59
+
60
+ export const originalRewardsEmitter = new EventEmitter<RewardsEventMap>();
61
+
62
+ export type RewardsEventType = keyof RewardsEventMap;
63
+
64
+ export interface RewardsEmitter {
65
+ on<T extends RewardsEventType>(event: T, callback: (...args: RewardsEventMap[T]) => void): void;
66
+ off<T extends RewardsEventType>(event: T, callback: (...args: RewardsEventMap[T]) => void): void;
67
+ emit<T extends RewardsEventType>(event: T, ...args: RewardsEventMap[T]): void;
68
+ }
69
+
70
+ // 创建包装器
71
+ export const createRewardsEmitterWrapper = (): RewardsEmitter => {
72
+ return {
73
+ on: originalRewardsEmitter.on.bind(originalRewardsEmitter),
74
+ off: originalRewardsEmitter.off.bind(originalRewardsEmitter),
75
+ emit: originalRewardsEmitter.emit.bind(originalRewardsEmitter)
76
+ };
77
+ };
78
+
79
+ export const rewardsEmitter = createRewardsEmitterWrapper();
@@ -1,11 +1,12 @@
1
- export type RewardType = 'ADS' | 'JOLI_COIN';
1
+ export type RewardType = 'ADS' | 'JOLI_COIN' | 'JOLI_COIN_ONLY';
2
2
 
3
3
  import { context } from '../context';
4
4
  import type { AdsRewardsHandler } from './registers/use-ads';
5
5
 
6
6
  export interface RewardHandlerMap {
7
7
  ADS: AdsRewardsHandler;
8
- JOLI_COIN: (params?: unknown) => Promise<boolean>;
8
+ JOLI_COIN: (params?: unknown) => Promise<boolean>; // coins + ads
9
+ JOLI_COIN_ONLY: (params?: unknown) => Promise<boolean>; // coins only
9
10
  }
10
11
 
11
12
  export type RewardHandler<T extends RewardType> = RewardHandlerMap[T];
@@ -1,5 +1,10 @@
1
+ /**
2
+ * event send to parent window
3
+ */
1
4
  const JOLIBOX_CUSTOM_ADS_EVENT_TYPE = 'JOLIBOX_ADS_EVENT';
2
5
  const JOLIBOX_CUSTOM_REWARDS_EVENT_TYPE = 'JOLIBOX_CUSTOM_REWARDS_EVENT';
6
+ const JOLIBOX_TOPUP_EVENT = 'JOLIBOX_TOPUP_EVENT';
7
+ const JOLIBOX_JOLI_COIN_USE_EVENT = 'JOLIBOX_JOLI_COIN_USE_EVENT';
3
8
 
4
9
  interface JoliboxCustomEvent {
5
10
  [JOLIBOX_CUSTOM_ADS_EVENT_TYPE]: {
@@ -11,12 +16,28 @@ interface JoliboxCustomEvent {
11
16
  balance: number;
12
17
  };
13
18
  };
19
+ [JOLIBOX_TOPUP_EVENT]: {
20
+ ['JOLI_COIN']?: {
21
+ quantity: number;
22
+ balance: number;
23
+ enableAutoDeduct?: boolean;
24
+ };
25
+ type: 'ADS-JOLI_COIN' | 'JOLI_COIN';
26
+ sequenceId: string;
27
+ };
28
+ //
29
+ [JOLIBOX_JOLI_COIN_USE_EVENT]: {
30
+ ['JOLI_COIN']?: {
31
+ quantity: number;
32
+ balance: number;
33
+ enableAutoDeduct?: boolean;
34
+ };
35
+ type: 'ADS-JOLI_COIN' | 'JOLI_COIN';
36
+ sequenceId: string;
37
+ };
14
38
  }
15
39
 
16
- export const notifyCustomEvent = <T extends keyof JoliboxCustomEvent>(
17
- eventName: T,
18
- data: JoliboxCustomEvent[T]
19
- ) => {
40
+ const notifyCustomEvent = <T extends keyof JoliboxCustomEvent>(eventName: T, data: JoliboxCustomEvent[T]) => {
20
41
  window.dispatchEvent(new CustomEvent(eventName, { detail: data }));
21
42
  window.parent?.postMessage(
22
43
  {
@@ -28,3 +49,95 @@ export const notifyCustomEvent = <T extends keyof JoliboxCustomEvent>(
28
49
  '*'
29
50
  );
30
51
  };
52
+
53
+ /**
54
+ * received event to parent window
55
+ * @param eventName
56
+ * @param data
57
+ */
58
+
59
+ const ON_JOLIBOX_TOPUP_JOLI_COIN_RESULT = 'ON_JOLIBOX_TOPUP_JOLI_COIN_RESULT';
60
+ const ON_JOLIBOX_JOLI_COIN_USE_RESULT = 'ON_JOLIBOX_JOLI_COIN_USE_RESULT';
61
+
62
+ interface ReceivedJoliboxCustomEvent {
63
+ [ON_JOLIBOX_TOPUP_JOLI_COIN_RESULT]: {
64
+ sequenceId: string;
65
+ result: 'SUCCESS' | 'CANCEL' | 'ADS';
66
+ type: 'ADS-JOLI_COIN' | 'JOLI_COIN';
67
+ joliCoin: {
68
+ enableAutoDeduct: boolean;
69
+ balance: number;
70
+ };
71
+ };
72
+ [ON_JOLIBOX_JOLI_COIN_USE_RESULT]: {
73
+ sequenceId: string;
74
+ result: 'USE_COIN' | 'ADS' | 'CANCEL';
75
+ };
76
+ }
77
+
78
+ type ReceivedJoliboxCustomEventResult = keyof ReceivedJoliboxCustomEvent;
79
+
80
+ interface MessageData<T extends ReceivedJoliboxCustomEventResult> {
81
+ type: T;
82
+ data: ReceivedJoliboxCustomEvent[T];
83
+ }
84
+
85
+ const eventCallbacks = new Map<string, Set<(data: any) => void>>();
86
+
87
+ const globalMessageHandler = (event: MessageEvent) => {
88
+ if (event.source !== window.parent) {
89
+ return;
90
+ }
91
+
92
+ try {
93
+ const message = event.data as MessageData<any>;
94
+ if (message && message.type) {
95
+ const callbacks = eventCallbacks.get(message.type);
96
+ if (callbacks) {
97
+ callbacks.forEach((callback) => {
98
+ try {
99
+ callback(message.data);
100
+ } catch (error) {
101
+ console.warn('Callback execution failed:', error);
102
+ }
103
+ });
104
+ }
105
+ }
106
+ } catch (error) {
107
+ console.warn('Failed to parse message:', error);
108
+ }
109
+ };
110
+
111
+ let isInitialized = false;
112
+ const initializeGlobalListener = () => {
113
+ if (!isInitialized) {
114
+ window.addEventListener('message', globalMessageHandler);
115
+ isInitialized = true;
116
+ }
117
+ };
118
+
119
+ const onCustomEvent = <T extends ReceivedJoliboxCustomEventResult>(
120
+ eventName: T,
121
+ callback: (data: ReceivedJoliboxCustomEvent[T]) => void
122
+ ) => {
123
+ initializeGlobalListener();
124
+
125
+ if (!eventCallbacks.has(eventName)) {
126
+ eventCallbacks.set(eventName, new Set());
127
+ }
128
+ const callbacks = eventCallbacks.get(eventName)!;
129
+
130
+ callbacks.add(callback);
131
+ return () => {
132
+ callbacks.delete(callback);
133
+ if (callbacks.size === 0) {
134
+ eventCallbacks.delete(eventName);
135
+ }
136
+ if (eventCallbacks.size === 0) {
137
+ window.removeEventListener('message', globalMessageHandler);
138
+ isInitialized = false;
139
+ }
140
+ };
141
+ };
142
+
143
+ export { onCustomEvent, notifyCustomEvent };
package/src/h5/api/ads.ts CHANGED
@@ -1,23 +1,68 @@
1
- import { JoliboxAdsImpl, adEventEmitter } from '@/common/ads';
2
1
  import { track } from '../report';
3
- import { createCommands } from '@jolibox/common';
2
+ import { createCommands, EventEmitter, platform } from '@jolibox/common';
4
3
  import { httpClientManager } from '../http';
5
4
  import { notifyCustomEvent } from '@/common/utils';
6
- import { createAdsRewardHandler, rewardsHelper, createJolicoinRewardHandler } from '@/common/rewards';
5
+ import {
6
+ createAdsRewardHandler,
7
+ rewardsHelper,
8
+ createJolicoinRewardHandler,
9
+ createJolicoinOnlyRewardHandler
10
+ } from '@/common/rewards';
11
+ import { JoliboxAdsForGame, type IAdsContext } from '@jolibox/ads';
12
+ import { context } from '@/common/context';
13
+ import '../rewards';
7
14
 
8
15
  const commands = createCommands();
9
16
 
17
+ const adEventEmitter = new EventEmitter<{
18
+ isAdShowing: [boolean];
19
+ }>();
20
+
10
21
  const httpClient = httpClientManager.create();
11
- const ads = new JoliboxAdsImpl(track, httpClient, () => httpClientManager.getNetworkStatus());
22
+
23
+ const adsContext: IAdsContext<'GAME'> = {
24
+ httpClient,
25
+ checkNetwork: () => httpClientManager.getNetworkStatus(),
26
+ track,
27
+ eventEmitter: adEventEmitter,
28
+ getContextInfo: () => {
29
+ return {
30
+ hostAppId: context.hostInfo?.aid ?? '1',
31
+ deviceId: context.deviceInfo.did ?? '',
32
+ adId: context.deviceInfo.did ?? '', //TODO: @Deng Xue
33
+ sessionId: context.sessionId ?? '',
34
+ userId: context.hostUserInfo?.uid ?? '',
35
+ objectType: 'GAME',
36
+ objectId: context.mpId,
37
+ testAdsMode: context.testAdsMode,
38
+ channel: context.joliSource ?? '',
39
+ deviceBrand: context.deviceInfo.brand,
40
+ deviceModel: context.deviceInfo.model,
41
+ osType: platform.isAndroid ? 'ANDROID' : platform.isiOS ? 'IOS' : 'PC',
42
+ runtimeType: 'WEB',
43
+ platform: 1000 // WebSDK
44
+ };
45
+ }
46
+ };
47
+
48
+ const handleUnlockSuccess = (params: { quantity: number; balance: number }) => {
49
+ notifyCustomEvent('JOLIBOX_CUSTOM_REWARDS_EVENT', {
50
+ JOLI_COIN: params
51
+ });
52
+ };
53
+
54
+ const ads = new JoliboxAdsForGame(adsContext);
12
55
  rewardsHelper.registerRewardHandler('ADS', createAdsRewardHandler(ads));
13
56
  rewardsHelper.registerRewardHandler(
14
57
  'JOLI_COIN',
15
- createJolicoinRewardHandler(ads.httpClient, {
16
- onUnlockSuccess: (params: { quantity: number; balance: number }) => {
17
- notifyCustomEvent('JOLIBOX_CUSTOM_REWARDS_EVENT', {
18
- JOLI_COIN: params
19
- });
20
- }
58
+ createJolicoinRewardHandler(httpClient, {
59
+ onUnlockSuccess: handleUnlockSuccess.bind(this)
60
+ }) as unknown as (params?: unknown) => Promise<boolean>
61
+ );
62
+ rewardsHelper.registerRewardHandler(
63
+ 'JOLI_COIN_ONLY',
64
+ createJolicoinOnlyRewardHandler(httpClient, {
65
+ onUnlockSuccess: handleUnlockSuccess.bind(this)
21
66
  }) as unknown as (params?: unknown) => Promise<boolean>
22
67
  );
23
68
 
@@ -35,8 +80,16 @@ commands.registerCommand('AdsSDK.adConfig', (params) => {
35
80
 
36
81
  commands.registerCommand('AdsSDK.adBreak', (params) => {
37
82
  if (params.type === 'reward') {
38
- rewardsHelper.getRewardsTypes(ads.httpClient).then((rewardsTypes) => {
39
- rewardsHelper.handleReward(rewardsTypes, params);
83
+ rewardsHelper.getRewardsTypes(httpClient).then((rewardsTypes) => {
84
+ rewardsHelper.handleReward(rewardsTypes, params).catch((e) => {
85
+ // error should terminate the reward handler, invoke unlock failed
86
+ console.info('handleReward failed', e);
87
+ params.adBreakDone?.({
88
+ breakType: params.type,
89
+ breakFormat: params.type === 'reward' ? 'reward' : 'interstitial',
90
+ breakStatus: 'noAdPreloaded'
91
+ });
92
+ });
40
93
  });
41
94
  } else {
42
95
  ads.adBreak(params);
@@ -46,7 +46,7 @@ export class HttpClientManager {
46
46
  }
47
47
  }
48
48
 
49
- getNetworkStatus(): boolean {
49
+ getNetworkStatus = (): boolean => {
50
50
  if (this.networkRequests.length === 0) {
51
51
  return true;
52
52
  }
@@ -55,7 +55,7 @@ export class HttpClientManager {
55
55
  const successRate = successCount / this.networkRequests.length;
56
56
 
57
57
  return successRate >= 0.6;
58
- }
58
+ };
59
59
  }
60
60
 
61
61
  class JoliboxHttpClient implements IHttpClient {
@@ -0,0 +1,69 @@
1
+ /**
2
+ * rewards event handlers
3
+ */
4
+
5
+ import {
6
+ rewardsEmitter,
7
+ UseModalEventName,
8
+ IUseModalEvent,
9
+ PaymentResultEventName,
10
+ UseModalResultEventName,
11
+ InvokePaymentEventName,
12
+ IInvokePaymentEvent,
13
+ IUseModalResultEvent
14
+ } from '@/common/rewards/reward-emitter';
15
+ import { notifyCustomEvent, onCustomEvent } from '@/common/utils';
16
+ import { uuidv4 as v4 } from '@jolibox/common';
17
+
18
+ /**
19
+ * confirm jolicoin modal
20
+ */
21
+ const UseCoinEventMap: Record<string, IUseModalResultEvent['useModalResult']> = {
22
+ USE_COIN: 'CONFIRM',
23
+ ADS: 'FAILED',
24
+ CANCEL: 'CANCEL'
25
+ };
26
+ onCustomEvent('ON_JOLIBOX_JOLI_COIN_USE_RESULT', (data) => {
27
+ console.log('onCustomEvent ON_JOLIBOX_JOLI_COIN_USE_RESULT', UseCoinEventMap[data.result]);
28
+
29
+ rewardsEmitter.emit(UseModalResultEventName, {
30
+ useModalResult: UseCoinEventMap[data.result]
31
+ });
32
+ });
33
+ rewardsEmitter.on(UseModalEventName, (type: 'JOLI_COIN' | 'ADS-JOLI_COIN', params: IUseModalEvent) => {
34
+ notifyCustomEvent('JOLIBOX_JOLI_COIN_USE_EVENT', {
35
+ JOLI_COIN: {
36
+ quantity: params.joliCoinQuantity,
37
+ balance: params.userJoliCoin.balance,
38
+ enableAutoDeduct: params.enableAutoDeduct
39
+ },
40
+ type,
41
+ sequenceId: params.sequenceId ?? v4()
42
+ });
43
+ });
44
+
45
+ /**
46
+ * payment jolicoin modal
47
+ */
48
+ onCustomEvent('ON_JOLIBOX_TOPUP_JOLI_COIN_RESULT', (data) => {
49
+ rewardsEmitter.emit(PaymentResultEventName, {
50
+ paymentResult: data.result == 'ADS' ? 'FAILED' : data.result,
51
+ userJoliCoin: data.joliCoin
52
+ });
53
+ });
54
+
55
+ rewardsEmitter.on(
56
+ InvokePaymentEventName,
57
+ async (type: 'JOLI_COIN' | 'ADS-JOLI_COIN', params: IInvokePaymentEvent) => {
58
+ // 充值面板
59
+ notifyCustomEvent('JOLIBOX_TOPUP_EVENT', {
60
+ JOLI_COIN: {
61
+ quantity: params.joliCoinQuantity,
62
+ balance: params.userJoliCoin.balance,
63
+ enableAutoDeduct: params.enableAutoDeduct
64
+ },
65
+ type,
66
+ sequenceId: params.sequenceId ?? v4()
67
+ });
68
+ }
69
+ );
@@ -1,61 +1,116 @@
1
1
  import { createCommands } from '@jolibox/common';
2
2
  import { createSyncAPI, registerCanIUse } from './base';
3
3
  import { createToast } from '@jolibox/ui';
4
+ import '../rewards';
4
5
 
5
6
  const commands = createCommands();
6
7
 
7
- import { IAdsInitParams, JoliboxAdsImpl, IAdConfigParams, IAdBreakParams, IAdUnitParams } from '@/common/ads';
8
+ // import { IAdsInitParams, JoliboxAdsImpl, IAdConfigParams, IAdBreakParams, IAdUnitParams } from '@/common/ads';
9
+ import {
10
+ JoliboxAdsForGame,
11
+ type IAdsInitParams,
12
+ type IAdsContext,
13
+ type IAdConfigParams,
14
+ type IAdBreakParams,
15
+ type IAdUnitParams
16
+ } from '@jolibox/ads';
8
17
  import { track } from '../report';
18
+ import { context } from '@/common/context';
9
19
 
10
20
  import { innerFetch as fetch } from '../network';
11
21
  import { invokeNative } from '@jolibox/native-bridge';
12
- import { rewardsHelper, createAdsRewardHandler, createJolicoinRewardHandler } from '@/common/rewards';
22
+ import {
23
+ rewardsHelper,
24
+ createAdsRewardHandler,
25
+ createJolicoinRewardHandler,
26
+ createJolicoinOnlyRewardHandler
27
+ } from '@/common/rewards';
13
28
 
14
29
  const checkNetworkStatus = () => {
15
30
  const { data } = invokeNative('getNetworkStatusSync');
16
31
  return !!data?.isConnected;
17
32
  };
18
- const ads = new JoliboxAdsImpl(
33
+
34
+ const httpClient = {
35
+ get: <T>(url: string, options?: any) =>
36
+ fetch<T>(url, {
37
+ method: 'GET',
38
+ responseType: 'json',
39
+ appendHostCookie: true,
40
+ ...options
41
+ }).then((res) => res.response.data as T),
42
+ post: <T>(url: string, options?: any) =>
43
+ fetch<T>(url, {
44
+ method: 'POST',
45
+ responseType: 'json',
46
+ appendHostCookie: true,
47
+ ...options
48
+ }).then((res) => res.response.data as T)
49
+ };
50
+
51
+ const adsContext: IAdsContext<'GAME'> = {
52
+ httpClient,
53
+ checkNetwork: checkNetworkStatus,
19
54
  track,
20
- {
21
- get: <T>(url: string, options?: any) =>
22
- fetch<T>(url, {
23
- method: 'GET',
24
- responseType: 'json',
25
- appendHostCookie: true,
26
- ...options
27
- }).then((res) => res.response.data as T),
28
- post: <T>(url: string, data: any, options?: any) =>
29
- fetch<T>(url, {
30
- method: 'POST',
31
- responseType: 'json',
32
- appendHostCookie: true,
33
- ...options
34
- }).then((res) => res.response.data as T)
35
- },
36
- checkNetworkStatus
37
- );
55
+ getContextInfo: () => {
56
+ return {
57
+ hostAppId: context.hostInfo?.aid ?? '1',
58
+ deviceId: context.deviceInfo.did ?? '',
59
+ adId: context.deviceInfo.did ?? '', //TODO: @Deng Xue
60
+ sessionId: context.sessionId ?? '',
61
+ userId: context.hostUserInfo?.uid ?? '',
62
+ objectType: 'GAME',
63
+ objectId: context.mpId,
64
+ testAdsMode: context.testAdsMode,
65
+ channel: context.joliSource ?? '',
66
+ deviceBrand: context.deviceInfo.brand,
67
+ deviceModel: context.deviceInfo.model,
68
+ osType: context.platform === 'android' ? 'ANDROID' : context.platform === 'ios' ? 'IOS' : 'PC',
69
+ runtimeType: 'APP',
70
+ platform: 1000 // WebSDK
71
+ };
72
+ }
73
+ };
74
+
75
+ const ads = new JoliboxAdsForGame(adsContext);
38
76
 
39
77
  rewardsHelper.registerRewardHandler('ADS', createAdsRewardHandler(ads));
40
78
  rewardsHelper.registerRewardHandler(
41
79
  'JOLI_COIN',
42
- createJolicoinRewardHandler(ads.httpClient, {
80
+ createJolicoinRewardHandler(httpClient, {
43
81
  onUnlockSuccess: (params) => {
44
- const { quantity, balance } = params;
45
- const balanceStr = balance >= 1000 ? '999+' : balance;
46
- createToast(`{slot-checkmark} −${quantity} {slot-coin} | Balance: ${balanceStr} {slot-coin}`, {
47
- customStyle: {
48
- mark: {
49
- marginRight: '8px'
50
- }
51
- }
52
- });
82
+ showUnlockSuccessToast(params);
53
83
  },
54
84
  onUnlockFailed: () => {
55
85
  console.log('onUnlockFailed');
56
86
  }
57
87
  }) as unknown as (params?: unknown) => Promise<boolean>
58
88
  );
89
+
90
+ rewardsHelper.registerRewardHandler(
91
+ 'JOLI_COIN_ONLY',
92
+ createJolicoinOnlyRewardHandler(httpClient, {
93
+ onUnlockSuccess: (params) => {
94
+ showUnlockSuccessToast(params);
95
+ },
96
+ onUnlockFailed: () => {
97
+ console.log('onUnlockFailed');
98
+ }
99
+ }) as unknown as (params?: unknown) => Promise<boolean>
100
+ );
101
+
102
+ const showUnlockSuccessToast = (params: { quantity: number; balance: number }) => {
103
+ const { quantity } = params;
104
+ const toastTemplate = `{slot-coin} ${quantity} JoliCoins used`;
105
+ createToast(toastTemplate, {
106
+ customStyle: {
107
+ mark: {
108
+ marginRight: '8px'
109
+ }
110
+ }
111
+ });
112
+ };
113
+
59
114
  const adInit = createSyncAPI('adInit', {
60
115
  implement: (config?: IAdsInitParams) => {
61
116
  ads.init(config);
@@ -71,8 +126,15 @@ const adConfig = createSyncAPI('adConfig', {
71
126
  const adBreak = createSyncAPI('adBreak', {
72
127
  implement: (params: IAdBreakParams) => {
73
128
  if (params.type === 'reward') {
74
- rewardsHelper.getRewardsTypes(ads.httpClient).then((rewardsTypes) => {
75
- rewardsHelper.handleReward(rewardsTypes, params);
129
+ rewardsHelper.getRewardsTypes(httpClient).then((rewardsTypes) => {
130
+ rewardsHelper.handleReward(rewardsTypes, params).catch((e) => {
131
+ console.info('handleReward failed in native', e);
132
+ params.adBreakDone?.({
133
+ breakType: params.type,
134
+ breakFormat: params.type === 'reward' ? 'reward' : 'interstitial',
135
+ breakStatus: 'noAdPreloaded'
136
+ });
137
+ });
76
138
  });
77
139
  } else {
78
140
  ads.adBreak(params);
@@ -23,7 +23,7 @@ registerCanIUse('checkSession', {
23
23
  }
24
24
  });
25
25
 
26
- const login = createAPI('login', {
26
+ export const login = createAPI('login', {
27
27
  async implement() {
28
28
  const {
29
29
  data: { isLogin }
@@ -1,4 +1,4 @@
1
- import { createCommands, UserCustomError } from '@jolibox/common';
1
+ import { createCommands, hostEmitter, UserCustomError } from '@jolibox/common';
2
2
  import { invokeNative } from '@jolibox/native-bridge';
3
3
  import { createSyncAPI, t, registerCanIUse } from './base';
4
4
  import { context } from '@/common/context';
@@ -44,9 +44,17 @@ const closePageSync = createSyncAPI('closePageSync', {
44
44
  }
45
45
  });
46
46
 
47
+ const interceptSystemExitSync = createSyncAPI('interceptSystemExitSync', {
48
+ paramsSchema: t.tuple(t.boolean()),
49
+ implement: (intercept) => {
50
+ hostEmitter.emit('onInterceptSystemExit', { intercept });
51
+ }
52
+ });
53
+
47
54
  commands.registerCommand('RouterSDK.openSchema', openSchemaSync);
48
55
  commands.registerCommand('RouterSDK.openPage', openPageSync);
49
56
  commands.registerCommand('RouterSDK.closePage', closePageSync);
57
+ commands.registerCommand('RouterSDK.interceptSystemExit', interceptSystemExitSync);
50
58
 
51
59
  registerCanIUse('router.openSchema', {
52
60
  version: '1.1.10'
@@ -59,3 +67,7 @@ registerCanIUse('router.openPage', {
59
67
  registerCanIUse('router.closePage', {
60
68
  version: '1.1.10'
61
69
  });
70
+
71
+ registerCanIUse('router.interceptSystemExit', {
72
+ version: '1.1.18'
73
+ });