import { checkUseModalFrequency, updateUseModalFrequency, checkUseModalFrequencyGem, updateUseModalFrequencyGem } from '../check-frequency'; import { updateAutoDeductConfig } from './utils'; import { IUseModalFrequencyConfig, rewardsEmitter, UseModalFrequencyEventName, IUseModalEvent } from '@/common/rewards/reward-emitter'; import { UseModalEventName, UseModalResultEventName } from '@/common/rewards/reward-emitter'; import { createConfirmJolicoinModal, createLoading } from '@jolibox/ui'; import { track } from '@/native/report'; import { EventType } from '@jolibox/common'; import { TrackEvent } from '@jolibox/types'; import { createEventPromiseHandler } from '@/common/rewards/registers/utils/event-listener'; // 货币配置映射 interface CurrencyModalConfig { frequencyConfigKey: keyof IUseModalFrequencyConfig['joliCoinUseAndCharge']; trackEvents: { popupShow: TrackEvent; coinUnlock: TrackEvent; adUnlock: TrackEvent; }; frequencyChecker: (config: { dailyMaxPopUps?: number; minInterval?: number; }) => Promise<{ canShow: boolean; isFirst: boolean }>; frequencyUpdater: () => Promise; apiEndpointAutoDeduct: string; } const CURRENCY_MODAL_CONFIG: Record<'JOLI_COIN' | 'JOLI_GEM', CurrencyModalConfig> = { JOLI_COIN: { frequencyConfigKey: 'useJolicoin', trackEvents: { popupShow: 'unlock_popup_show', coinUnlock: 'coin_unlock_click', adUnlock: 'ad_unlock_click' }, frequencyChecker: checkUseModalFrequency, frequencyUpdater: updateUseModalFrequency, apiEndpointAutoDeduct: '/api/joli-coin/user-config' }, JOLI_GEM: { frequencyConfigKey: 'useJolicoin', // 暂时复用,可以后续扩展 trackEvents: { popupShow: 'gem_unlock_popup_show', coinUnlock: 'gem_unlock_click', adUnlock: 'gem_ad_unlock_click' }, frequencyChecker: checkUseModalFrequencyGem, frequencyUpdater: updateUseModalFrequencyGem, apiEndpointAutoDeduct: '/api/joli-gem/user-config' } }; const loading = createLoading(); const modalUseFrequencyConfig = createEventPromiseHandler< IUseModalFrequencyConfig, typeof UseModalFrequencyEventName >(rewardsEmitter, UseModalFrequencyEventName); modalUseFrequencyConfig.getData(); /** * confirm currency modal - 支持 jolicoin 和 gem */ rewardsEmitter.on( UseModalEventName, async (type: 'JOLI_COIN' | 'ADS-JOLI_COIN' | 'JOLI_GEM' | 'ADS-JOLI_GEM', params: IUseModalEvent) => { // 获取货币类型配置 const currencyType = params.currency; const modalConfig = CURRENCY_MODAL_CONFIG[currencyType]; if (type.includes('ADS-')) { await loading.show({ duration: 3000 }); const config = await modalUseFrequencyConfig.getData(); const { canShow: canShowUseModal, isFirst: isFirstUseModal } = await modalConfig.frequencyChecker( config.joliCoinUseAndCharge[modalConfig.frequencyConfigKey] ); console.log(`${currencyType} modal show by frequency`, canShowUseModal, isFirstUseModal); loading.hide(); // First, check for direct use: sufficient balance, auto-deduct enabled, and not the first modal. const { balance } = params.userCurrency; const useDirectly = balance >= params.quantity && params.enableAutoDeduct; if (useDirectly && !isFirstUseModal) { rewardsEmitter.emit(UseModalResultEventName, { useModalResult: 'CONFIRM' }); return; } // If not used directly, then check frequency control. if (!canShowUseModal) { // confirm by frequency control rewardsEmitter.emit(UseModalResultEventName, { useModalResult: 'FAILED' }); return; } } // 根据货币类型上报不同的埋点 track(modalConfig.trackEvents.popupShow, { eventType: EventType.View, targetType: 'game', currency: currencyType }); const { userCurrency, enableAutoDeduct, quantity } = params; const modal = createConfirmJolicoinModal({ data: { enableAutoDeduct, userCurrency, quantity, currency: currencyType }, buttons: { confirm: { text: params.confirmButtonText, onPress: () => { // 根据货币类型上报不同的埋点 track(modalConfig.trackEvents.coinUnlock as any, { targetType: 'game', eventType: EventType.Click, coinConsume: params.quantity, ifAutoUnlock: params.enableAutoDeduct, currency: currencyType }); rewardsEmitter.emit(UseModalResultEventName, { useModalResult: 'CONFIRM' }); modal.destroy(); } }, cancel: { text: params.cancelButtonText, onPress: ({ type }) => { if (type === 'FAILED') { // 根据货币类型上报不同的埋点 track(modalConfig.trackEvents.adUnlock as any, { targetType: 'game', eventType: EventType.Click, currency: currencyType }); } rewardsEmitter.emit(UseModalResultEventName, { useModalResult: (type ?? '') === 'CANCEL' ? 'CANCEL' : 'FAILED' }); modal.destroy(); } }, onEnableDeductChanged: async (enabled: boolean) => { await updateAutoDeductConfig(enabled, modalConfig.apiEndpointAutoDeduct); } } }); // 根据货币类型更新使用频次 await modalConfig.frequencyUpdater(); } );