161 lines
4.4 KiB
Vue
161 lines
4.4 KiB
Vue
<script setup lang="ts">
|
|
import type {
|
|
PageDataResourceGroup,
|
|
PageDataResourceGroupBtnInfo,
|
|
} from '#layers/types/api/pageData'
|
|
import type { ButtonType } from '#layers/types/components/button'
|
|
|
|
interface Props {
|
|
resourcesData: PageDataResourceGroup[]
|
|
buttonSize?: string
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
buttonSize: 'size-extra-small md:size-medium',
|
|
})
|
|
|
|
const { locale, tm } = useI18n()
|
|
const device = useDevice()
|
|
const modalStore = useModalStore()
|
|
const scrollStore = useScrollStore()
|
|
const breakpoints = useResponsiveBreakpoints()
|
|
const { sendLog } = useAnalytics()
|
|
|
|
const buttonList = computed<PageDataResourceGroup[]>(
|
|
() => props.resourcesData ?? []
|
|
)
|
|
|
|
const getButtonType = (btnInfo?: PageDataResourceGroupBtnInfo): ButtonType => {
|
|
const btnType = btnInfo?.detail?.btn_type
|
|
const target = btnInfo?.detail?.action?.link_target
|
|
|
|
if (btnType === 'URL' && target) {
|
|
return target === '_blank' ? 'external' : 'internal'
|
|
}
|
|
|
|
if (btnType === 'DOWNLOAD') return 'download'
|
|
|
|
return 'action'
|
|
}
|
|
|
|
const isRunButtonVisible = (btnInfo: PageDataResourceGroupBtnInfo): boolean => {
|
|
if (breakpoints.value?.isDesktop) return true
|
|
|
|
const marketType = btnInfo?.detail?.market_type
|
|
|
|
switch (marketType) {
|
|
case 'pc':
|
|
return false
|
|
case 'google_play':
|
|
return device.isAndroid
|
|
case 'app_store':
|
|
return device.isApple
|
|
default:
|
|
return true
|
|
}
|
|
}
|
|
|
|
const downloadFile = async (url: string = '', osType: number = 0) => {
|
|
if (osType === 1 && breakpoints.value?.isMobile) {
|
|
modalStore.handleOpenAlert({ contentText: tm('Alert_Download_PC') })
|
|
return
|
|
}
|
|
|
|
const fileUrl = formatPathHost(url)
|
|
|
|
try {
|
|
const res = await $fetch<Blob>(fileUrl, {
|
|
method: 'GET',
|
|
responseType: 'blob',
|
|
timeout: 10000,
|
|
})
|
|
|
|
const blob = res
|
|
const blobUrl = URL.createObjectURL(blob)
|
|
|
|
const pathPart = fileUrl.split('/').pop() ?? 'download'
|
|
const a = document.createElement('a')
|
|
|
|
a.href = blobUrl
|
|
a.download = pathPart
|
|
document.body.appendChild(a)
|
|
a.click()
|
|
a.remove()
|
|
|
|
// 메모리 정리
|
|
URL.revokeObjectURL(blobUrl)
|
|
|
|
modalStore.handleOpenAlert({ contentText: tm('Alert_Download_Success') })
|
|
} catch (err) {
|
|
console.error(err)
|
|
modalStore.handleOpenAlert({ contentText: tm('Alert_Download_Error') })
|
|
}
|
|
}
|
|
|
|
const handleButtonClick = (button: PageDataResourceGroup) => {
|
|
sendLog(locale.value, button.tracking)
|
|
|
|
const btnDetail = button.btn_info?.detail
|
|
|
|
switch (btnDetail?.btn_type) {
|
|
case 'POP':
|
|
modalStore.handleOpenContent({
|
|
contentTitle: btnDetail?.title,
|
|
tabInfo: btnDetail?.tab_info,
|
|
})
|
|
return
|
|
case 'ANCHOR':
|
|
scrollStore.scrollToAnchor(btnDetail?.page_ver_tmpl_name_en ?? '')
|
|
return
|
|
case 'MOV':
|
|
modalStore.handleOpenYoutube({ youtubeUrl: btnDetail.url ?? '' })
|
|
return
|
|
case 'DOWNLOAD':
|
|
downloadFile(btnDetail?.file_path, btnDetail?.os_type)
|
|
return
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
v-if="buttonList.length"
|
|
v-motion-stagger
|
|
class="flex flex-wrap justify-center items-center gap-3 md:gap-4"
|
|
>
|
|
<template v-for="(button, index) in buttonList" :key="index">
|
|
<template v-if="button.btn_info?.detail?.btn_type === 'RUN'">
|
|
<BlocksButtonLauncher
|
|
v-if="isRunButtonVisible(button.btn_info)"
|
|
type="duplication"
|
|
:platform="button.btn_info?.detail?.market_type"
|
|
:background-color="getColorCodeFromData(button.btn_info, 'btn')"
|
|
:text-color="getColorCodeFromData(button.btn_info, 'txt')"
|
|
:use-game-font="button.btn_info?.use_game_font === 1"
|
|
@click="handleButtonClick(button)"
|
|
>
|
|
{{ button.btn_info?.txt_btn_name }}
|
|
</BlocksButtonLauncher>
|
|
</template>
|
|
|
|
<AtomsButton
|
|
v-else
|
|
:type="getButtonType(button.btn_info)"
|
|
:size="buttonSize"
|
|
:href="button.btn_info?.detail?.action?.url"
|
|
:target="button.btn_info?.detail?.action?.link_target"
|
|
:background-color="getColorCodeFromData(button.btn_info, 'btn')"
|
|
:text-color="getColorCodeFromData(button.btn_info, 'txt')"
|
|
:disabled="button.btn_info?.detail?.btn_type === 'DEACTIVE'"
|
|
:gradient="true"
|
|
:use-game-font="button.btn_info?.use_game_font === 1"
|
|
@click="handleButtonClick(button)"
|
|
>
|
|
{{ button.btn_info?.txt_btn_name }}
|
|
</AtomsButton>
|
|
</template>
|
|
</div>
|
|
</template>
|