import { IHttpClient } from '@/common/http'; import { context } from '@/common/context'; import { uuidv4 } from '@jolibox/common'; import { UnlockOptionsEventName, IUnlockOptionsEvent } from '@/common/rewards/reward-emitter'; import { IAdBreakParams } from '@/common/ads'; import { EventPromiseHandler } from '../../event-listener'; import { CURRENCY_CONFIG, CurrencyType } from '../currency-config'; import { createInitiateAndAwaitPayment, registerUseJolicoinCommand, registerUsePaymentCommand, registerUseUnloginCommand, createShowUnlockWithCurrencyModal, createShowUnloginModal } from '../commands'; import { rewardsCommands } from '../rewards-command'; import { RewardsCommandType } from '@jolibox/types'; import { refreshBalanceCache, warmupBalanceCache } from './cached-fetch-balance'; import { CURRENCY_HANDLERS } from '../commands/currency-handlers'; import { checkIfSupportSubscription } from '../../common'; interface ICurrencyUnlockRes { code: 'SUCCESS' | 'BALANCE_NOT_ENOUGH' | 'EPISODE_LOCK_JUMP' | 'EPISODE_UNLOCK_ALREADY'; message: string; data: { transactionId: string; quantity: number; balance: number; }; } const createCommonCurrencyRewardHandler = ( type: 'JOLI_COIN' | 'ADS-JOLI_COIN', httpClient: IHttpClient, currencyType: CurrencyType, { handlers: { handleUnlockSuccess, handleUnlockFailed, unlockOptionsHandler, initiateAndAwaitPayment, showUnlockWithCurrencyModal, showUnloginModal, hasSubscription } }: { handlers: { handleUnlockSuccess?: (data: { quantity: number; balance: number }) => void; handleUnlockFailed?: (params: IAdBreakParams) => void; unlockOptionsHandler: EventPromiseHandler; initiateAndAwaitPayment: ReturnType; showUnlockWithCurrencyModal: ReturnType; showUnloginModal: ReturnType; hasSubscription?: () => boolean; }; } ) => { // registerUseUnloginCommand(type, 'JOLI_COIN', { // httpClient: httpClient, // showUnloginModal: showUnloginModal // }); registerUsePaymentCommand(type, 'JOLI_COIN', { httpClient: httpClient, initiateAndAwaitPayment: initiateAndAwaitPayment }); registerUseJolicoinCommand(type, 'JOLI_COIN', { showUnlockWithCurrencyModal }); const commands = [`Rewards.${type}.usePayment`, `Rewards.${type}.useJolicoin`]; return async (params: IAdBreakParams) => { try { const unlockOptions = await unlockOptionsHandler.getData(); const supportSubscription = checkIfSupportSubscription(unlockOptions, hasSubscription); if (supportSubscription) { // Use currency handler for balance and quantity calculation const handler = CURRENCY_HANDLERS['JOLI_COIN']; const newBalance = await handler.fetchBalance(httpClient); const currentUser = handler.getCurrentUser(unlockOptions); const newUser = handler.createUpdatedUser(newBalance?.balance ?? 0, currentUser.enableAutoDeduct); if (!handler.isEnough(unlockOptions, newUser)) { handleUnlockFailed?.(params); return false; } } else { let result = true; for (const command of commands) { const commandResult = await rewardsCommands.executeCommand(command as RewardsCommandType); result = result && commandResult.result !== 'FAILED'; if (commandResult.result !== 'CONTINUE') { break; } } if (!result) { handleUnlockFailed?.(params); return false; } } // success const config = CURRENCY_CONFIG[currencyType]; const unlockWithCurrency = await httpClient.post(config.unlockEndpoint, { data: { type: 'GAME_REWARD', reqId: `${uuidv4()}-${context.mpType}-${Date.now()}`, gameInfo: { gameId: context.mpId } } }); console.log('-----unlockWithCurrency request result-----', unlockWithCurrency); if (unlockWithCurrency.code == 'SUCCESS') { try { params.adBreakDone?.({ breakType: params.type, breakName: 'name' in params ? params.name ?? '' : '', breakFormat: 'reward', breakStatus: 'viewed' }); if ('adViewed' in params) { params.adViewed?.(); } refreshBalanceCache(httpClient); } catch (e) { console.error('-----unlockWithJolicoin adBreakDone error-----', e); } handleUnlockSuccess?.({ quantity: unlockWithCurrency.data.quantity, balance: unlockWithCurrency.data.balance }); return true; } handleUnlockFailed?.(params); return false; } catch (e) { console.info(`JolicoinRewardHandler error:`, e); if (e instanceof Error && e.message == 'CANCEL') { // Cancel should terminate the reward handler, invoke unlock failed throw e; } handleUnlockFailed?.(params); return false; } finally { unlockOptionsHandler.clearCache(); } }; }; // 向后兼容的 jolicoin 处理器 export const createCommonJolicoinRewardHandler = ( type: 'JOLI_COIN' | 'ADS-JOLI_COIN', httpClient: IHttpClient, config: { handlers: { handleUnlockSuccess?: (data: { quantity: number; balance: number }) => void; handleUnlockFailed?: (params: IAdBreakParams) => void; unlockOptionsHandler: EventPromiseHandler; initiateAndAwaitPayment: ReturnType; showUnlockWithCurrencyModal: ReturnType; showUnloginModal: ReturnType; hasSubscription?: () => boolean; }; } ) => { return createCommonCurrencyRewardHandler(type, httpClient, 'JOLI_COIN', config); };