import { InvokeUnloginModalEventName, IUseModalFrequencyConfig, rewardsEmitter, UseModalFrequencyEventName, UseUnloginModalResultEventName } from '@/common/rewards/reward-emitter'; import { createEventPromiseHandler } from '@/common/rewards/registers/utils/event-listener'; import { checkUnloginModalFrequency, updateUnloginModalFrequency, checkUnloginModalFrequencyGem, updateUnloginModalFrequencyGem } from '../check-frequency'; import { StandardResponse, TrackEvent } from '@jolibox/types'; import { innerFetch as fetch } from '@/native/network'; import { reportError } from '@/common/report/errors/report'; import { EventType, InternalInvokeMethodError } from '@jolibox/common'; import { loginImplement } from '@/native/api/login'; import { createToast, createUnloginJolicoinModal } from '@jolibox/ui'; import { track } from '@/native/report'; // 货币配置映射 interface CurrencyUnloginConfig { frequencyChecker: (config: { show: boolean; dailyMaxPopUps?: number; minInterval?: number; }) => Promise<{ canShow: boolean; isFirst: boolean }>; frequencyUpdater: () => Promise; trackEvents: { modalExpose: TrackEvent; clickConfirm: TrackEvent; clickConfirmLogin: TrackEvent; modalHide: TrackEvent; clickClose: TrackEvent; clickWatchAds: TrackEvent; }; toastMessage: { i18nKey: string; usedText: string; }; } const CURRENCY_UNLOGIN_CONFIG: Record<'JOLI_COIN' | 'JOLI_GEM', CurrencyUnloginConfig> = { JOLI_COIN: { frequencyChecker: checkUnloginModalFrequency, frequencyUpdater: updateUnloginModalFrequency, trackEvents: { modalExpose: 'LoginGuideModal', clickConfirm: 'LoginGuideModal', clickConfirmLogin: 'LoginGuideModal', modalHide: 'LoginGuideModal', clickClose: 'LoginGuideModal', clickWatchAds: 'LoginGuideModal' }, toastMessage: { i18nKey: '{slot-i18ntran-loginGuide.rewardTips}', usedText: 'Jolicoin Used' } }, JOLI_GEM: { frequencyChecker: checkUnloginModalFrequencyGem, frequencyUpdater: updateUnloginModalFrequencyGem, trackEvents: { modalExpose: 'GemLoginGuideModal', // 暂时复用,可后续扩展为 GemLoginGuideModal clickConfirm: 'GemLoginGuideModal', clickConfirmLogin: 'GemLoginGuideModal', modalHide: 'GemLoginGuideModal', clickClose: 'GemLoginGuideModal', clickWatchAds: 'GemLoginGuideModal' }, toastMessage: { i18nKey: '{slot-i18ntran-loginGuide.gemRewardTips}', usedText: 'Gem Used' } } }; const unloginModalConfig = createEventPromiseHandler< IUseModalFrequencyConfig, typeof UseModalFrequencyEventName >(rewardsEmitter, UseModalFrequencyEventName); unloginModalConfig.getData(); rewardsEmitter.on( InvokeUnloginModalEventName, async (type: 'JOLI_COIN' | 'ADS-JOLI_COIN' | 'JOLI_GEM' | 'ADS-JOLI_GEM', params) => { try { // 获取货币类型配置 const currencyType = params.currency; const unloginConfig = CURRENCY_UNLOGIN_CONFIG[currencyType]; if (type.includes('ADS-')) { const config = await unloginModalConfig.getData(); console.log(`${currencyType} unlogin guide config`, config.loginGuide); if (!config.loginGuide.show) { rewardsEmitter.emit(UseUnloginModalResultEventName, { result: 'NOT_SUPPORT' }); return; } const { canShow: canShowUseModal } = await unloginConfig.frequencyChecker(config.loginGuide); console.log(`${currencyType} canShowUseModal`, canShowUseModal); if (!canShowUseModal) { rewardsEmitter.emit(UseUnloginModalResultEventName, { result: 'FAILED' }); return; } } const { firstLogin } = (await getRewardCoin()) ?? {}; if (!firstLogin?.reward) { console.log('[JoliboxSDK] unlogin modal reward is empty'); rewardsEmitter.emit(UseUnloginModalResultEventName, { result: 'NOT_SUPPORT' }); return; } // 根据货币类型上报不同的埋点 track( unloginConfig.trackEvents.modalExpose, { eventType: EventType.Expose, currency: currencyType }, EventType.Expose ); const modal = createUnloginJolicoinModal({ data: { rewardType: type, rewardValue: firstLogin.reward.rewardValue, currency: params.currency }, buttons: { confirm: { text: params.confirmButtonText, onPress: async () => { // 根据货币类型上报不同的埋点 track( unloginConfig.trackEvents.clickConfirm, { type: 'click_confirm', eventType: EventType.Click, currency: currencyType }, EventType.Click ); const { isLogin, extra, isFirstLogin } = await loginImplement({}, true); if (!isLogin) { console.log('login failed'); return; } track( unloginConfig.trackEvents.clickConfirmLogin, { type: 'click_confirm_login', isFirstLogin, eventType: EventType.Click, currency: currencyType }, EventType.Click ); if (isFirstLogin && extra?.firstLogin?.reward) { const { rewardValue } = extra.firstLogin.reward; createToast(unloginConfig.toastMessage.i18nKey, { i18nParams: { text: unloginConfig.toastMessage.usedText, coin: rewardValue }, position: 'top', duration: 3000 }); } rewardsEmitter.emit(UseUnloginModalResultEventName, { result: 'SUCCESS', rewards: { claimedRewardValue: extra?.firstLogin?.reward?.rewardValue ?? 0, isFirstLogin: isFirstLogin ?? false, currency: params.currency } }); modal.destroy(); return; } }, cancel: { text: params.cancelButtonText, onPress: ({ type }) => { // 根据货币类型上报不同的埋点 track( unloginConfig.trackEvents.modalHide, { eventType: EventType.Hide, currency: currencyType }, EventType.Hide ); const trackType = type === 'CANCEL' ? 'click_close' : 'click_watch_ads'; const trackEvent = type === 'CANCEL' ? unloginConfig.trackEvents.clickClose : unloginConfig.trackEvents.clickWatchAds; track( trackEvent, { type: trackType, eventType: EventType.Click, currency: currencyType }, EventType.Click ); rewardsEmitter.emit(UseUnloginModalResultEventName, { result: 'FAILED' }); modal.destroy(); } } } }); await unloginConfig.frequencyUpdater(); } catch (e) { reportError(new InternalInvokeMethodError(e as Error)); rewardsEmitter.emit(UseUnloginModalResultEventName, { result: 'FAILED' }); } } ); interface IRewardCoinResponse { firstLogin: { reward: { rewardType: 'JOLI_COIN' | 'JOLI_GEM'; rewardValue: number; }; }; } const getRewardCoin = async (): Promise => { const { response } = await fetch>('/api/base/global-config', { method: 'GET', appendHostCookie: true, responseType: 'json' }); return response.data?.data; };