diff --git a/src/api/activity.js b/src/api/activity.js index 68000dd..b959833 100644 --- a/src/api/activity.js +++ b/src/api/activity.js @@ -70,7 +70,7 @@ export const apiGetActivityResource = async (activityType) => { return response } catch (error) { console.error('Failed to get activity resource:', error) - console.error('error:' + error.response.errorMsg) + console.error('error:' + (error.response?.errorMsg || error.errorMsg || error.message || '')) throw error } } @@ -82,7 +82,7 @@ export const getDailyRechargeInfo = async () => { return response } catch (error) { console.error('Failed to get daily recharge info:', error) - console.error('error:' + error.response.errorMsg) + console.error('error:' + (error.response?.errorMsg || error.errorMsg || error.message || '')) throw error } } @@ -94,7 +94,7 @@ export const claimDailyRechargeTask1 = async (data) => { return response } catch (error) { console.error('Failed to claim daily recharge task1 reward:', error) - console.error('error:' + error.response.errorMsg) + console.error('error:' + (error.response?.errorMsg || error.errorMsg || error.message || '')) throw error } } @@ -106,7 +106,7 @@ export const claimDailyRechargeTask2 = async (data) => { return response } catch (error) { console.error('Failed to claim daily recharge task2 reward:', error) - console.error('error:' + error.response.errorMsg) + console.error('error:' + (error.response?.errorMsg || error.errorMsg || error.message || '')) throw error } } diff --git a/src/views/Activities/DailyRecharge/index.vue b/src/views/Activities/DailyRecharge/index.vue index 238ec6f..a71c812 100644 --- a/src/views/Activities/DailyRecharge/index.vue +++ b/src/views/Activities/DailyRecharge/index.vue @@ -334,7 +334,7 @@ justify-content: flex-start; class="reward-showcase-vap-wrap" :key="mainRewardRenderKey" :class="{ - 'reward-showcase-vap-wrap-playable': isIosDevice && mainReward?.sourceUrl, + 'reward-showcase-vap-wrap-playable': isIosDevice && mainRewardVapSourceUrl, }" @click="handleMainRewardPreviewClick" > @@ -782,7 +782,7 @@ const mainReward = computed(() => { return selectedRewardList.value[0] || null }) const mainRewardVapSourceUrl = computed(() => { - return normalizeVapSourceUrl(mainReward.value?.sourceUrl) + return getRewardVapSourceUrl(mainReward.value) }) const shouldPlayMainRewardVap = computed(() => { return ( @@ -813,8 +813,35 @@ const getRewardDisplayText = (reward) => { return formatRewardDisplay(reward.type, reward) } +const isEmptySourceValue = (value) => { + if (typeof value !== 'string' && typeof value !== 'number') { + return true + } + + return ['', 'null', 'undefined'].includes(String(value || '').trim().toLowerCase()) +} + +const getRewardRawSourceUrl = (reward = {}) => { + const sourceCandidates = [ + reward.sourceUrl, + reward.mp4Url, + reward.vapUrl, + reward.animationUrl, + reward.resourceUrl, + reward.dynamicUrl, + reward.url, + reward?.source?.url, + reward?.resource?.url, + reward?.extValues?.sourceUrl, + reward?.extValues?.mp4Url, + reward?.extValues?.vapUrl, + ] + + return sourceCandidates.find((value) => !isEmptySourceValue(value)) || '' +} + const normalizeVapSourceUrl = (sourceUrl = '') => { - const resolvedUrl = resolveProtectedAssetUrl(sourceUrl || '').trim() + const resolvedUrl = String(resolveProtectedAssetUrl(sourceUrl || '') || '').trim() if (!resolvedUrl) { return '' } @@ -846,6 +873,19 @@ const normalizeVapSourceUrl = (sourceUrl = '') => { return `https://${resolvedUrl}` } +const isValidVapSourceUrl = (sourceUrl = '') => { + if (!sourceUrl) { + return false + } + + return /^https?:\/\/.+\.mp4(?:[?#].*)?$/i.test(sourceUrl) || /^\/oss\/.+\.mp4(?:[?#].*)?$/i.test(sourceUrl) +} + +const getRewardVapSourceUrl = (reward = {}) => { + const sourceUrl = normalizeVapSourceUrl(getRewardRawSourceUrl(reward)) + return isValidVapSourceUrl(sourceUrl) ? sourceUrl : '' +} + const getRewardRenderKey = (reward, index) => { return [ selectedRewardLevel.value, @@ -853,14 +893,14 @@ const getRewardRenderKey = (reward, index) => { reward?.type || '', reward?.detailType || '', reward?.cover || '', - reward?.sourceUrl || '', + getRewardVapSourceUrl(reward) || '', ].join('-') } const getRewardVapUrls = (rewardTopList) => { return (rewardTopList || []) .flatMap((rewardTop) => rewardTop?.propsGroup?.activityRewardProps || []) - .map((reward) => normalizeVapSourceUrl(reward?.sourceUrl)) + .map((reward) => getRewardVapSourceUrl(reward)) .filter(Boolean) } @@ -1063,7 +1103,6 @@ const handleRewardVapError = (error, sourceUrl = '') => { if (normalizedSourceUrl) { failedRewardVapUrls.value = new Set([...failedRewardVapUrls.value, normalizedSourceUrl]) } - showError(error?.message || t('active_game_vap_playback_failed')) } const handleMainRewardPreviewClick = () => { @@ -1125,18 +1164,64 @@ const getDailyRechargeTaskInfo = async () => { levelList: Array.isArray(res.body.levelList) ? res.body.levelList : [], } selectedRewardLevel.value = currentLevel.value + return true } + + throw new Error('Invalid daily recharge task info response') } const getActivityRewards = async () => { const res = await apiGetActivityResource('DAILY_RECHARGE_TASK2') if (res.status && res.body) { activityRewards.value = Array.isArray(res.body) ? appendExtraRewards(res.body) : [] + failedRewardVapUrls.value = new Set() + rewardVapPreloadStarted = false + return true } + + throw new Error('Invalid daily recharge activity reward response') +} + +const delay = (duration) => { + return new Promise((resolve) => { + window.setTimeout(resolve, duration) + }) +} + +const runWithRetry = async (runner, retryCount = 1, retryDelay = 600) => { + let lastError = null + + for (let attempt = 0; attempt <= retryCount; attempt += 1) { + try { + return await runner() + } catch (error) { + lastError = error + if (attempt < retryCount) { + await delay(retryDelay) + } + } + } + + throw lastError } const initData = async () => { - await Promise.all([getDailyRechargeTaskInfo(), getActivityRewards()]) + const [taskResult, rewardResult] = await Promise.allSettled([ + runWithRetry(getDailyRechargeTaskInfo, 2, 800), + runWithRetry(getActivityRewards, 1, 800), + ]) + + if (taskResult.status === 'rejected') { + console.error('Failed to initialize daily recharge task info:', taskResult.reason) + } + + if (rewardResult.status === 'rejected') { + console.error('Failed to initialize daily recharge activity rewards:', rewardResult.reason) + } + + if (taskResult.status === 'rejected' && rewardResult.status === 'rejected') { + throw taskResult.reason || rewardResult.reason + } } const preloadCriticalImages = async () => { @@ -1190,8 +1275,8 @@ const startPageInitialization = async () => { } const connectToAppHandler = async () => { - const result = await connectToApp(() => { - void startPageInitialization() + const result = await connectToApp(async () => { + await startPageInitialization() }) if (!result?.success) {