fix. gnb더보기 정상동작 하지않는 이슈 수정
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
import { onClickOutside, useWindowSize } from '@vueuse/core'
|
||||
import { useGameDataStore } from '#layers/stores/useGameDataStore'
|
||||
import type {
|
||||
GameDataMenu,
|
||||
@@ -9,6 +8,9 @@ import type {
|
||||
PlatformTransformType,
|
||||
} from '#layers/types/api/gameData'
|
||||
|
||||
const MORE_WIDTH = 72
|
||||
const START_WIDTH_MARGIN = 40
|
||||
|
||||
const route = useRoute()
|
||||
const { tm } = useI18n()
|
||||
const { width } = useWindowSize()
|
||||
@@ -21,21 +23,22 @@ const modalStore = useModalStore()
|
||||
const { gameData } = storeToRefs(gameDataStore)
|
||||
const { isPassedStoveGnb } = storeToRefs(scrollStore)
|
||||
|
||||
const navAreaRef = ref<HTMLElement>()
|
||||
const startRef = ref<HTMLElement>()
|
||||
const navAreaRef = ref<HTMLElement | null>(null)
|
||||
const startRef = ref<HTMLElement | null>(null)
|
||||
|
||||
const gnbData = gameData.value?.gnb
|
||||
const isMenuOpen = ref(false)
|
||||
const navWidth = ref(0)
|
||||
const startWidth = ref(0)
|
||||
const officialItemWidths = ref<number[]>([])
|
||||
const overflowNam = ref<number>(0)
|
||||
// const { width: navWidth } = useElementSize(navAreaRef)
|
||||
const { width: startWidth } = useElementSize(startRef)
|
||||
|
||||
const gnbData = computed(() => gameData.value?.gnb)
|
||||
const gnb1depthButtonData = computed(
|
||||
() => gnbData?.buttons[0]?.button_json as GameDataResourceGroup
|
||||
() => gnbData.value?.buttons[0]?.button_json as GameDataResourceGroup
|
||||
)
|
||||
const gnb2depthButtonData = computed(
|
||||
() => gnbData?.buttons[1]?.button_json as GameDataResourceGroupSet
|
||||
() => gnbData.value?.buttons[1]?.button_json as GameDataResourceGroupSet
|
||||
)
|
||||
const currentPath = computed(() => formatPathWithoutLocale(route.path))
|
||||
const supportedPlatforms = computed(
|
||||
@@ -72,20 +75,10 @@ const isNavItemActive = (gnbItem: GameDataMenu): boolean => {
|
||||
|
||||
// navAreaRef의 넓이를 구하는 함수
|
||||
const calculateNavWidth = () => {
|
||||
if (!navAreaRef.value || !gnbData) return 0
|
||||
if (!navAreaRef.value || !gnbData.value) return 0
|
||||
|
||||
const navAreaWidth = navAreaRef.value.offsetWidth
|
||||
const moreWidth = 72 // 더보기 버튼 넓이 + 마진
|
||||
return navAreaWidth + moreWidth
|
||||
}
|
||||
|
||||
// startRef의 넓이를 구하는 함수
|
||||
const calculateStartWidth = () => {
|
||||
if (!startRef.value || !gnbData) return 0
|
||||
|
||||
const startWidth = startRef.value.offsetWidth
|
||||
const headerRightPadding = 40 // 헤더 오른쪽 마진
|
||||
return startWidth + headerRightPadding
|
||||
navWidth.value = navAreaWidth + MORE_WIDTH
|
||||
}
|
||||
|
||||
// official 자식들의 넓이를 구하는 함수
|
||||
@@ -104,24 +97,20 @@ const calculateOfficialItemWidths = () => {
|
||||
}
|
||||
|
||||
officialItemWidths.value = widths
|
||||
|
||||
// 해상도 체크 및 오버플로우 계산
|
||||
calculateOverflow()
|
||||
}
|
||||
|
||||
// 오버플로우 계산 함수
|
||||
const calculateOverflow = () => {
|
||||
if (!navAreaRef.value || !startRef.value) return
|
||||
|
||||
const totalNavWidth = navWidth.value + startWidth.value
|
||||
const screenWidth = width.value
|
||||
|
||||
// 모바일(1024px 미만)에서는 overflowNam을 0으로 설정
|
||||
if (screenWidth < 1024) {
|
||||
if (breakpoints.value.isMobile) {
|
||||
overflowNam.value = 0
|
||||
return
|
||||
}
|
||||
|
||||
const screenWidth = width.value
|
||||
const totalNavWidth = navWidth.value + startWidth.value + START_WIDTH_MARGIN
|
||||
|
||||
// 해상도가 navWidth + startWidth보다 작은 경우
|
||||
if (screenWidth < totalNavWidth) {
|
||||
let removedCount = 0
|
||||
@@ -211,7 +200,10 @@ const handleStartClick = () => {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
|
||||
const stopClickOutside = onClickOutside(navAreaRef, () => handleMenuClose())
|
||||
watchEffect(() => {
|
||||
if (!startWidth.value) return // 0, null, undefined면 스킵
|
||||
calculateOverflow()
|
||||
})
|
||||
|
||||
// 화면 크기 변경 시 오버플로우 재계산
|
||||
watch(width, () => {
|
||||
@@ -221,20 +213,13 @@ watch(width, () => {
|
||||
onMounted(() => {
|
||||
overflowNam.value = 0
|
||||
|
||||
// 초기 계산 시도
|
||||
nextTick(() => {
|
||||
if (navAreaRef.value && startRef.value) {
|
||||
navWidth.value = calculateNavWidth()
|
||||
startWidth.value = calculateStartWidth()
|
||||
calculateOfficialItemWidths()
|
||||
}
|
||||
calculateNavWidth()
|
||||
calculateOfficialItemWidths()
|
||||
calculateOverflow()
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (stopClickOutside) {
|
||||
stopClickOutside()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -252,8 +237,11 @@ onBeforeUnmount(() => {
|
||||
<AtomsIconsMenuBoldLine class="mx-auto" />
|
||||
<span class="sr-only">menu open</span>
|
||||
</button>
|
||||
<div :class="['nav-wrap', { 'is-open': isMenuOpen }]">
|
||||
<div ref="navAreaRef" class="nav-area">
|
||||
<div
|
||||
:class="['nav-wrap', { 'is-open': isMenuOpen }]"
|
||||
@click="handleMenuClose"
|
||||
>
|
||||
<div ref="navAreaRef" class="nav-area" @click.stop>
|
||||
<div class="nav-logo">
|
||||
<AtomsLocaleLink to="/brand" @click="handleMenuClose">
|
||||
<img
|
||||
@@ -378,39 +366,42 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div ref="startRef" class="btn-start">
|
||||
<ClientOnly>
|
||||
<component
|
||||
:is="
|
||||
breakpoints.isDesktop ? 'BlocksButtonLauncher' : 'AtomsButton'
|
||||
"
|
||||
type="custom"
|
||||
platform="pc"
|
||||
:background-color="
|
||||
getColorCodeFromData(gnb1depthButtonData?.btn_info, 'btn')
|
||||
"
|
||||
:text-color="
|
||||
getColorCodeFromData(gnb1depthButtonData?.btn_info, 'txt')
|
||||
"
|
||||
@click="handleStartClick"
|
||||
>
|
||||
{{ gnb1depthButtonData?.btn_info?.txt_btn_name }}
|
||||
</component>
|
||||
|
||||
<div
|
||||
v-if="breakpoints.isDesktop && gnb2depthButtonData"
|
||||
class="nav-2depth"
|
||||
>
|
||||
<ul>
|
||||
<li v-for="(item, key) in gnb2depthButtonData" :key="key">
|
||||
<BlocksButtonLauncher type="custom" :platform="key">
|
||||
{{ item.btn_info?.txt_btn_name }}
|
||||
</BlocksButtonLauncher>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
<ClientOnly>
|
||||
<div ref="startRef" class="btn-start">
|
||||
<template v-if="gnb1depthButtonData">
|
||||
<component
|
||||
:is="
|
||||
breakpoints.isDesktop
|
||||
? 'BlocksButtonLauncher'
|
||||
: 'AtomsButton'
|
||||
"
|
||||
type="custom"
|
||||
platform="pc"
|
||||
:background-color="
|
||||
getColorCodeFromData(gnb1depthButtonData?.btn_info, 'btn')
|
||||
"
|
||||
:text-color="
|
||||
getColorCodeFromData(gnb1depthButtonData?.btn_info, 'txt')
|
||||
"
|
||||
@click="handleStartClick"
|
||||
>
|
||||
{{ gnb1depthButtonData?.btn_info?.txt_btn_name }}
|
||||
</component>
|
||||
<div
|
||||
v-if="breakpoints.isDesktop && gnb2depthButtonData"
|
||||
class="nav-2depth"
|
||||
>
|
||||
<ul>
|
||||
<li v-for="(item, key) in gnb2depthButtonData" :key="key">
|
||||
<BlocksButtonLauncher type="custom" :platform="key">
|
||||
{{ item.btn_info?.txt_btn_name }}
|
||||
</BlocksButtonLauncher>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</ClientOnly>
|
||||
<button class="btn-close" @click="handleMenuClose">
|
||||
<AtomsIconsCloseLine
|
||||
size="24"
|
||||
|
||||
@@ -67,7 +67,11 @@ const cache = new LRUCache({
|
||||
* @param finalLocale - 최종 언어
|
||||
* @param baseDomain - 기본 도메인
|
||||
*/
|
||||
function setFinalLocaleCookie(event: any, finalLocale: string, baseDomain: string) {
|
||||
function setFinalLocaleCookie(
|
||||
event: any,
|
||||
finalLocale: string,
|
||||
baseDomain: string
|
||||
) {
|
||||
setCookie(event, 'LOCALE', finalLocale.toLowerCase(), {
|
||||
domain: baseDomain,
|
||||
path: '/',
|
||||
@@ -95,7 +99,6 @@ function fnLocaleMiddleware(event: any, finalLocale: string) {
|
||||
// 쿼리스트링 포함 시 순수 경로만 추출
|
||||
arrPath = path.split('?')[0].split('/')
|
||||
queryString = path.split('?')[1]
|
||||
|
||||
} else {
|
||||
arrPath = path.split('/')
|
||||
queryString = ''
|
||||
@@ -134,7 +137,7 @@ export default defineEventHandler(async event => {
|
||||
if (event.node.res.headersSent || event.node.res.writableEnded) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// const runType = `${config.public.runType}`
|
||||
// console.log("🚀 ~ baseDomain:", config.public.baseDomain)
|
||||
// const url = getRequestURL(event)
|
||||
@@ -235,9 +238,14 @@ export default defineEventHandler(async event => {
|
||||
if (event.node.res.headersSent || event.node.res.writableEnded) {
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 언어 코드 추출
|
||||
finalLocale = ssrGetFinalLocale(event?.node.req.url, event.node.req.headers, initLangCodes, initDefaultLocale)
|
||||
|
||||
// 2. 언어 코드 추출
|
||||
finalLocale = ssrGetFinalLocale(
|
||||
event?.node.req.url,
|
||||
event.node.req.headers,
|
||||
initLangCodes,
|
||||
initDefaultLocale
|
||||
)
|
||||
|
||||
const path = event?.node.req.url || ''
|
||||
let queryStringF = ''
|
||||
@@ -255,17 +263,17 @@ export default defineEventHandler(async event => {
|
||||
console.error('쿼리스트링 파싱 에러:', e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 테스트용 500 에러 발생
|
||||
if (test500) {
|
||||
throw new Error('테스트용 500 에러 발생')
|
||||
}
|
||||
|
||||
|
||||
// 미리보기 API 호출 처리
|
||||
if (fValue === 'preview') {
|
||||
cleanHost = 'samplegame.onstove.com'
|
||||
}
|
||||
|
||||
|
||||
const queryParams: Record<string, string> = {
|
||||
game_domain: cleanHost || '',
|
||||
lang_code: finalLocale,
|
||||
@@ -283,7 +291,7 @@ export default defineEventHandler(async event => {
|
||||
event.context.gameData = response.value
|
||||
event.context.googleAnalyticsId = response.value?.ga_code
|
||||
|
||||
// console.log('🚀 ~ gameData:', response.value)
|
||||
console.log('🚀 ~ gameData:', response.value)
|
||||
|
||||
// 점검 데이터 조회
|
||||
let inspectionData
|
||||
@@ -305,7 +313,6 @@ export default defineEventHandler(async event => {
|
||||
)
|
||||
inspectionData = inspectionResponse?.value?.inspection
|
||||
cache.set(cacheKey, inspectionData) // 캐시에 저장
|
||||
// console.log("🚀 ~ inspectionData:", inspectionData)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +353,10 @@ export default defineEventHandler(async event => {
|
||||
// 허용된 IP 목록 확인
|
||||
if (!inspectionData?.ip_filter_list?.includes(clientIP)) {
|
||||
// 허용되지 않은 IP인 경우 점검 페이지로 이동
|
||||
if (!event.node.res.headersSent && !event.node.res.writableEnded) {
|
||||
if (
|
||||
!event.node.res.headersSent &&
|
||||
!event.node.res.writableEnded
|
||||
) {
|
||||
event.node.res.statusCode = 302
|
||||
event.node.res.setHeader('Location', inspectionPath)
|
||||
event.node.res.end()
|
||||
@@ -412,7 +422,7 @@ export default defineEventHandler(async event => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('gameData load error:', error)
|
||||
|
||||
|
||||
// 500 에러 발생 시 /error 페이지로 리다이렉트
|
||||
if (!event.node.res.headersSent && !event.node.res.writableEnded) {
|
||||
// 언어 코드 추출 시도
|
||||
@@ -429,7 +439,7 @@ export default defineEventHandler(async event => {
|
||||
}
|
||||
// finalLocale이 undefined인 경우 기본값으로 'ko' 설정
|
||||
|
||||
console.log("🚀 ~ 여기도 타? error:", error)
|
||||
console.log('🚀 ~ 여기도 타? error:', error)
|
||||
throw createError({
|
||||
statusCode: error.statusCode,
|
||||
statusMessage: error.statusMessage,
|
||||
|
||||
Reference in New Issue
Block a user