fix. 게임 스타트 버튼 platform, os 분기 로직 위치 이동
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { CSSProperties } from 'vue'
|
import type { CSSProperties } from 'vue'
|
||||||
|
import type { PlatformTransformType } from '#layers/types/api/gameData'
|
||||||
import type {
|
import type {
|
||||||
DownloadButtonType,
|
DownloadButtonType,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
@@ -21,8 +22,17 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const PLATFORM_LABEL_KEY: Record<PlatformTransformType, string> = {
|
||||||
|
pc: 'PC',
|
||||||
|
google_play: 'Google Play',
|
||||||
|
app_store: 'App Store',
|
||||||
|
} as const
|
||||||
|
|
||||||
const runtimeConfig = useRuntimeConfig()
|
const runtimeConfig = useRuntimeConfig()
|
||||||
|
const { tm } = useI18n()
|
||||||
|
const device = useDevice()
|
||||||
const gameDataStore = useGameDataStore()
|
const gameDataStore = useGameDataStore()
|
||||||
|
const modalStore = useModalStore()
|
||||||
const { isProcessing, validateLauncher } = useCheckGameStart()
|
const { isProcessing, validateLauncher } = useCheckGameStart()
|
||||||
|
|
||||||
const { gameData } = storeToRefs(gameDataStore)
|
const { gameData } = storeToRefs(gameDataStore)
|
||||||
@@ -42,15 +52,20 @@ const DUP_IMAGE_MAP: Record<Platform, string> = {
|
|||||||
} as const
|
} as const
|
||||||
|
|
||||||
const componentTag = computed(() => {
|
const componentTag = computed(() => {
|
||||||
if (props.type !== 'duplication' && props.platform === 'stove') {
|
if (props.platform === 'stove' && props.type !== 'duplication') {
|
||||||
return 'a'
|
return 'a'
|
||||||
}
|
}
|
||||||
return 'button'
|
return 'button'
|
||||||
})
|
})
|
||||||
const isDuplication = computed(() => props.type === 'duplication')
|
|
||||||
const isSingle = computed(() => props.type === 'single')
|
const isSingle = computed(() => props.type === 'single')
|
||||||
|
const supportedPlatforms = computed(
|
||||||
|
() =>
|
||||||
|
getSupportedPlatforms(
|
||||||
|
gameData.value?.platform_type,
|
||||||
|
gameData.value?.os_type
|
||||||
|
) as PlatformTransformType[]
|
||||||
|
)
|
||||||
const platformIcon = computed(() => PLATFORM_ICON_MAP[props.platform])
|
const platformIcon = computed(() => PLATFORM_ICON_MAP[props.platform])
|
||||||
|
|
||||||
const inlineStyle = computed<CSSProperties>(() => {
|
const inlineStyle = computed<CSSProperties>(() => {
|
||||||
const style: CSSProperties = {}
|
const style: CSSProperties = {}
|
||||||
|
|
||||||
@@ -66,18 +81,61 @@ const inlineStyle = computed<CSSProperties>(() => {
|
|||||||
return style
|
return style
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const highlight = (text: string) => `<span class="highlight">${text}</span>`
|
||||||
|
|
||||||
|
const tmWithGameName = (key: string): string => {
|
||||||
|
const raw = tm(key)
|
||||||
|
if (typeof raw !== 'string') return ''
|
||||||
|
|
||||||
|
const withName = raw.replace(
|
||||||
|
/%게임명%/g,
|
||||||
|
highlight(gameData.value?.game_name || '')
|
||||||
|
)
|
||||||
|
|
||||||
|
const platformLines = supportedPlatforms.value
|
||||||
|
.map(platform => highlight(PLATFORM_LABEL_KEY[platform] as string))
|
||||||
|
.filter(Boolean)
|
||||||
|
|
||||||
|
return platformLines.length
|
||||||
|
? `${withName}<br><br>${platformLines.join('<br>')}`
|
||||||
|
: withName
|
||||||
|
}
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
if (props.platform === 'pc') {
|
if (props.platform === 'stove') {
|
||||||
validateLauncher()
|
if (props.type === 'duplication') return
|
||||||
return
|
|
||||||
}
|
|
||||||
if (props.platform === 'stove' && !isDuplication.value) {
|
|
||||||
const stoveClientDownloadUrl = runtimeConfig.public.stoveClientDownloadUrl
|
const stoveClientDownloadUrl = runtimeConfig.public.stoveClientDownloadUrl
|
||||||
location.href = stoveClientDownloadUrl
|
location.href = stoveClientDownloadUrl
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = gameData.value?.market_json[props.platform]?.url
|
if (props.platform === 'pc') {
|
||||||
|
if (device.isDesktop && gameData.value?.platform_type !== '2') {
|
||||||
|
validateLauncher()
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
const target = device.isAndroid
|
||||||
|
? 'google_play'
|
||||||
|
: device.isApple
|
||||||
|
? 'app_store'
|
||||||
|
: null
|
||||||
|
|
||||||
|
if (!target || !supportedPlatforms.value.includes(target)) {
|
||||||
|
modalStore.handleOpenAlert({
|
||||||
|
contentText: tmWithGameName('Alert_Not_SupportedOS'),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = gameData.value?.market_json?.[target]?.url || ''
|
||||||
|
|
||||||
|
window.open(url, '_blank')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = gameData.value?.market_json[props.platform]?.url || ''
|
||||||
if (url) window.open(url, '_blank')
|
if (url) window.open(url, '_blank')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -100,14 +158,14 @@ const handleClick = () => {
|
|||||||
<span class="btn-content">
|
<span class="btn-content">
|
||||||
<component
|
<component
|
||||||
:is="platformIcon"
|
:is="platformIcon"
|
||||||
v-if="!isDuplication"
|
v-if="props.type !== 'duplication'"
|
||||||
class="icon-platform"
|
class="icon-platform"
|
||||||
/>
|
/>
|
||||||
<span class="text">
|
<span class="text">
|
||||||
<slot />
|
<slot />
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-if="type === 'default' && platform === 'pc'"
|
v-if="props.platform === 'pc' && props.type === 'default'"
|
||||||
class="icon-download"
|
class="icon-download"
|
||||||
>
|
>
|
||||||
<AtomsIconsDownloadLine />
|
<AtomsIconsDownloadLine />
|
||||||
|
|||||||
@@ -6,26 +6,18 @@ import type {
|
|||||||
GameDataMenuChildren,
|
GameDataMenuChildren,
|
||||||
GameDataResourceGroup,
|
GameDataResourceGroup,
|
||||||
GameDataResourceGroupSet,
|
GameDataResourceGroupSet,
|
||||||
PlatformTransformType,
|
|
||||||
} from '#layers/types/api/gameData'
|
} from '#layers/types/api/gameData'
|
||||||
|
|
||||||
const MORE_WIDTH = 72
|
const MORE_WIDTH = 72
|
||||||
const START_WIDTH_MARGIN = 40
|
const START_WIDTH_MARGIN = 40
|
||||||
const PLATFORM_LABEL_KEY: Record<PlatformTransformType, string> = {
|
|
||||||
pc: 'PC',
|
|
||||||
google_play: 'Google Play',
|
|
||||||
app_store: 'App Store',
|
|
||||||
} as const
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { tm } = useI18n()
|
const { tm } = useI18n()
|
||||||
const { width } = useWindowSize()
|
const { width } = useWindowSize()
|
||||||
const device = useDevice()
|
|
||||||
const gameDataStore = useGameDataStore()
|
const gameDataStore = useGameDataStore()
|
||||||
const pageDataStore = usePageDataStore()
|
const pageDataStore = usePageDataStore()
|
||||||
const scrollStore = useScrollStore()
|
const scrollStore = useScrollStore()
|
||||||
const breakpoints = useResponsiveBreakpoints()
|
const breakpoints = useResponsiveBreakpoints()
|
||||||
const modalStore = useModalStore()
|
|
||||||
|
|
||||||
const { gameData } = storeToRefs(gameDataStore)
|
const { gameData } = storeToRefs(gameDataStore)
|
||||||
const { pageLayoutType } = storeToRefs(pageDataStore)
|
const { pageLayoutType } = storeToRefs(pageDataStore)
|
||||||
@@ -55,16 +47,8 @@ const start1depthData = computed(
|
|||||||
const start2depthData = computed(
|
const start2depthData = computed(
|
||||||
() => gnbData.value?.buttons[1]?.button_json as GameDataResourceGroupSet
|
() => gnbData.value?.buttons[1]?.button_json as GameDataResourceGroupSet
|
||||||
)
|
)
|
||||||
const supportedPlatforms = computed(
|
|
||||||
() =>
|
console.log('start2depthData', start2depthData.value)
|
||||||
getSupportedPlatforms(
|
|
||||||
gameData.value?.platform_type,
|
|
||||||
gameData.value?.os_type
|
|
||||||
) as PlatformTransformType[]
|
|
||||||
)
|
|
||||||
const isStartPCVisible = computed(() => {
|
|
||||||
return device.isDesktop && gameData.value?.platform_type !== '2'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 자식 중 활성 링크 존재 여부 확인
|
// 자식 중 활성 링크 존재 여부 확인
|
||||||
const hasActiveChild = (children?: GameDataMenuChildren) => {
|
const hasActiveChild = (children?: GameDataMenuChildren) => {
|
||||||
@@ -158,52 +142,6 @@ const has2depthButton = (gnbItem: GameDataMenu) => {
|
|||||||
return gnbItem.children && Object.keys(gnbItem.children).length > 0
|
return gnbItem.children && Object.keys(gnbItem.children).length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlight = (text: string) => `<span class="highlight">${text}</span>`
|
|
||||||
|
|
||||||
const tmWithGameName = (key: string): string => {
|
|
||||||
const raw = tm(key)
|
|
||||||
if (typeof raw !== 'string') return ''
|
|
||||||
|
|
||||||
const withName = raw.replace(
|
|
||||||
/%게임명%/g,
|
|
||||||
highlight(gameData.value?.game_name || '')
|
|
||||||
)
|
|
||||||
|
|
||||||
const platformLines = supportedPlatforms.value
|
|
||||||
.map(platform => highlight(PLATFORM_LABEL_KEY[platform] as string))
|
|
||||||
.filter(Boolean)
|
|
||||||
|
|
||||||
return platformLines.length
|
|
||||||
? `${withName}<br><br>${platformLines.join('<br>')}`
|
|
||||||
: withName
|
|
||||||
}
|
|
||||||
|
|
||||||
const showNotSupportedOSAlert = () => {
|
|
||||||
return modalStore.handleOpenAlert({
|
|
||||||
contentText: tmWithGameName('Alert_Not_SupportedOS'),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleStartClick = () => {
|
|
||||||
if (isStartPCVisible.value) return
|
|
||||||
|
|
||||||
const target = device.isAndroid
|
|
||||||
? 'google_play'
|
|
||||||
: device.isApple
|
|
||||||
? 'app_store'
|
|
||||||
: null
|
|
||||||
|
|
||||||
if (!target || !supportedPlatforms.value.includes(target)) {
|
|
||||||
showNotSupportedOSAlert()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = gameData.value?.market_json?.[target]?.url || ''
|
|
||||||
if (!url) return showNotSupportedOSAlert()
|
|
||||||
|
|
||||||
window.open(url, '_blank')
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
overflowCount.value = 0
|
overflowCount.value = 0
|
||||||
isMounted.value = true
|
isMounted.value = true
|
||||||
@@ -263,14 +201,14 @@ onMounted(() => {
|
|||||||
<template v-if="hasGnbMenus">
|
<template v-if="hasGnbMenus">
|
||||||
<div class="official custom-theme-scrollbar">
|
<div class="official custom-theme-scrollbar">
|
||||||
<div
|
<div
|
||||||
v-for="(gnbItem, index) in gnbData?.menus"
|
v-for="(gnbItem, key) in gnbData?.menus"
|
||||||
:key="index"
|
:key="key"
|
||||||
class="nav-item group"
|
class="nav-item group"
|
||||||
:class="{
|
:class="{
|
||||||
'is-hidden':
|
'is-hidden':
|
||||||
breakpoints.isDesktop &&
|
breakpoints.isDesktop &&
|
||||||
overflowCount > 0 &&
|
overflowCount > 0 &&
|
||||||
Number(index) >=
|
Number(key) >=
|
||||||
Object.keys(gnbData?.menus).length - overflowCount,
|
Object.keys(gnbData?.menus).length - overflowCount,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
@@ -334,13 +272,13 @@ onMounted(() => {
|
|||||||
<div class="more-list">
|
<div class="more-list">
|
||||||
<div class="list-inner">
|
<div class="list-inner">
|
||||||
<div
|
<div
|
||||||
v-for="(gnbItem, index) in gnbData?.menus"
|
v-for="(gnbItem, key) in gnbData?.menus"
|
||||||
:key="index"
|
:key="key"
|
||||||
:class="{
|
:class="{
|
||||||
'is-hidden':
|
'is-hidden':
|
||||||
breakpoints.isDesktop &&
|
breakpoints.isDesktop &&
|
||||||
overflowCount > 0 &&
|
overflowCount > 0 &&
|
||||||
Number(index) >=
|
Number(key) >=
|
||||||
Object.keys(gnbData?.menus).length - overflowCount,
|
Object.keys(gnbData?.menus).length - overflowCount,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
@@ -424,10 +362,7 @@ onMounted(() => {
|
|||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<div ref="startRef" class="btn-start">
|
<div ref="startRef" class="btn-start">
|
||||||
<template v-if="start1depthData">
|
<template v-if="start1depthData">
|
||||||
<component
|
<BlocksButtonLauncher
|
||||||
:is="
|
|
||||||
isStartPCVisible ? 'BlocksButtonLauncher' : 'AtomsButton'
|
|
||||||
"
|
|
||||||
type="custom"
|
type="custom"
|
||||||
platform="pc"
|
platform="pc"
|
||||||
:background-color="
|
:background-color="
|
||||||
@@ -436,17 +371,16 @@ onMounted(() => {
|
|||||||
:text-color="
|
:text-color="
|
||||||
getColorCodeFromData(start1depthData?.btn_info, 'txt')
|
getColorCodeFromData(start1depthData?.btn_info, 'txt')
|
||||||
"
|
"
|
||||||
@click="handleStartClick"
|
|
||||||
>
|
>
|
||||||
{{ start1depthData?.btn_info?.txt_btn_name }}
|
{{ start1depthData?.btn_info?.txt_btn_name }}
|
||||||
</component>
|
</BlocksButtonLauncher>
|
||||||
<div
|
<div
|
||||||
v-if="breakpoints.isDesktop && start2depthData"
|
v-if="breakpoints.isDesktop && start2depthData"
|
||||||
class="nav-2depth"
|
class="nav-2depth"
|
||||||
>
|
>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(item, index) in start2depthData" :key="index">
|
<li v-for="(item, key) in start2depthData" :key="key">
|
||||||
<BlocksButtonLauncher type="custom" :platform="index">
|
<BlocksButtonLauncher type="custom" :platform="key">
|
||||||
{{ item.btn_info?.txt_btn_name }}
|
{{ item.btn_info?.txt_btn_name }}
|
||||||
</BlocksButtonLauncher>
|
</BlocksButtonLauncher>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -191,8 +191,8 @@ const handleMoveFocus = (target: 'pc' | 'mobile') => {
|
|||||||
:key="dIndex"
|
:key="dIndex"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="relative flex items-center justify-start w-full text-left text-[#999999] text-[14px] font-[400] leading-[24px] tracking-[-0.42px] md:text-[15px] md:tracking-[-0.45px]"
|
|
||||||
v-dompurify-html="tm(description as string)"
|
v-dompurify-html="tm(description as string)"
|
||||||
|
class="relative flex items-center justify-start w-full text-left text-[#999999] text-[14px] font-[400] leading-[24px] tracking-[-0.42px] md:text-[15px] md:tracking-[-0.45px]"
|
||||||
></p>
|
></p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user