feat. 게임시작 로직 적용

This commit is contained in:
clkim
2025-10-16 17:09:07 +09:00
parent 6dff3787b6
commit 7b72319377
34 changed files with 334 additions and 282 deletions

View File

@@ -0,0 +1,85 @@
<script setup>
const {
isProcessing,
isShowCheckLauncher,
isShowDownloadLauncher,
validateLauncher,
downloadLauncher,
} = useCheckGameStart()
</script>
<template>
<AtomsButton
:class="$attrs?.class"
:disabled="isProcessing"
@click="validateLauncher"
>
<slot />
</AtomsButton>
<ClientOnly>
<Teleport to="#teleports">
<BlocksModalLayer
v-model:is-open="isShowCheckLauncher"
:is-show-dimmed="true"
:is-outside-close="false"
:modal-name="'launcher'"
area-class="max-w-[480px] pt-[56px] px-[24px] pb-[24px] rounded-[8px]"
close-class="absolute top-[16px] right-[24px]"
>
<span class="ico-loading"></span>
<!-- [TODO] i18n 적용 -->
<!-- <p class="text-check">{{ tm('Common_Message_Check_Client').txt }}</p> -->
<p class="text-check">pc 클라이언트 실행 ...</p>
<Transition name="fade">
<div v-if="isShowDownloadLauncher" class="client-area">
<!-- <p
v-dompurify-html="tm('Common_Message_Download_Client').txt"
class="text-info"
></p>
<button type="button" class="btn-download" @click="downloadLauncher">
{{ tm('Common_Message_Install').txt }}
</button>
<p
v-dompurify-html="tm('Common_Message_Download_Close').txt"
class="text-tip"
></p> -->
<p class="text-info">
PC 클라이언트가 실행되지 않나요?
<br />
다운로드 전이라면 다운로드 진행해주세요
</p>
<AtomsButtonVariant class="max-w-[300px]" @click="downloadLauncher">
다운로드
</AtomsButtonVariant>
<p
v-dompurify-html="
'*PC 클라이언트가 정상 실행되었다면 팝업을 닫아 주세요.'
"
class="text-tip"
></p>
</div>
</Transition>
</BlocksModalLayer>
</Teleport>
</ClientOnly>
</template>
<style scoped>
.ico-loading {
@apply block mx-auto mb-4 w-[80px] h-[80px] bg-[url('/images/common/stove_loading_light.png')] bg-contain bg-center bg-no-repeat;
}
.text-check {
@apply mb-6 text-center text-[20px] font-bold leading-[30px] tracking-[-0.6px] text-[#333333];
}
.client-area {
@apply pt-4 border-t border-[rgba(0,0,0,0.08)] text-center;
}
.text-info {
@apply mb-3 text-[14px] font-medium leading-[24px] tracking-[-0.42px] text-[#333333];
}
.text-tip {
@apply mt-4 text-[14px] leading-[20px] tracking-[-0.42px] text-[#999999];
}
</style>

View File

@@ -4,12 +4,12 @@ interface props {
contentText?: string
confirmButtonText?: string
isOutsideClose?: boolean
className?: string
modalName?: string
}
const props = withDefaults(defineProps<props>(), {
isShowDimmed: false,
isOutsideClose: true,
isOutsideClose: false,
})
const emit = defineEmits(['confirmButtonEvent'])
@@ -31,10 +31,10 @@ const handleOutsideClick = () => {
</script>
<template>
<Transition name="opacity-on">
<Transition name="fade">
<div
v-if="isOpen"
:class="['modal-wrap', { dimmed: props.isShowDimmed }, props.className]"
:class="['modal-wrap', { dimmed: props.isShowDimmed }, props.modalName]"
@click="handleOutsideClick"
>
<div class="modal-area" @click.stop>
@@ -57,3 +57,9 @@ const handleOutsideClick = () => {
</div>
</Transition>
</template>
<style scoped>
.modal-area {
@apply max-w-[312px] p-6 bg-white rounded-[20px];
}
</style>

View File

@@ -5,21 +5,21 @@ interface props {
confirmButtonText?: string
cancelButtonText?: string
isOutsideClose?: boolean
className?: string
modalName?: string
}
const props = withDefaults(defineProps<props>(), {
isShowDimmed: false,
isOutsideClose: true,
isOutsideClose: false,
})
const emit = defineEmits(['cancelButtonEvent', 'confirmButtonEvent'])
const isOpen = defineModel<boolean>('isOpen', { default: false })
const setButtonEvent = (event: () => void | void) => {
const setButtonEvent = (event?: () => void) => {
if (event) {
return event()
event()
}
isOpen.value = false
}
@@ -32,10 +32,10 @@ const handleOutsideClick = () => {
</script>
<template>
<Transition name="opacity-on">
<Transition name="fade">
<div
v-if="isOpen"
:class="['modal-wrap', { dimmed: props.isShowDimmed }, props.className]"
:class="['modal-wrap', { dimmed: props.isShowDimmed }, props.modalName]"
@click="handleOutsideClick"
>
<div class="modal-area" @click.stop>
@@ -64,3 +64,9 @@ const handleOutsideClick = () => {
</div>
</Transition>
</template>
<style scoped>
.modal-area {
@apply max-w-[312px] p-6 bg-white rounded-[20px];
}
</style>

View File

@@ -0,0 +1,50 @@
<script setup lang="ts">
interface props {
isShowDimmed?: boolean
isOutsideClose?: boolean
modalName?: string
areaClass?: string
closeClass?: string
}
const props = withDefaults(defineProps<props>(), {
isShowDimmed: false,
isOutsideClose: false,
})
const isOpen = defineModel<boolean>('isOpen', { default: false })
const handleCloseModal = () => {
isOpen.value = false
}
const handleOutsideClick = () => {
if (props.isOutsideClose) {
handleCloseModal()
}
}
</script>
<template>
<Transition name="fade">
<div
v-if="isOpen"
:class="['modal-wrap', { dimmed: props.isShowDimmed }, props.modalName]"
@click="handleOutsideClick"
>
<div :class="['modal-area', props.areaClass]" @click.stop>
<div class="modal-content">
<slot></slot>
</div>
<button
type="button"
:class="['modal-close', props.closeClass]"
@click="handleCloseModal"
>
<span class="sr-only">close</span>
<AtomsIconsCloseLine size="24" color="#333333" />
</button>
</div>
</div>
</Transition>
</template>

View File

@@ -4,12 +4,12 @@ import { getYouTubeEmbedUrl } from '#layers/utils/youtube'
interface Props {
youtubeUrl: string
isOutsideClose?: boolean
className?: string
modalName?: string
}
const props = withDefaults(defineProps<Props>(), {
youtubeUrl: '',
isOutsideClose: true,
isOutsideClose: false,
})
const emit = defineEmits(['closeButtonEvent'])
@@ -48,18 +48,11 @@ onUnmounted(() => {
</script>
<template>
<Transition
enter-active-class="transition duration-300 ease-out"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-active-class="transition duration-200 ease-in"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<Transition name="fade">
<div
v-if="isOpen"
class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-75"
:class="props.className"
:class="props.modalName"
@click="handleOutsideClick"
>
<div
@@ -72,11 +65,7 @@ onUnmounted(() => {
>
<!-- 헤더 -->
<div class="flex justify-end mb-3 md:mb-4">
<button
class="text-white rounded-full transition-colors"
aria-label="모달 닫기"
@click="handleCloseModal"
>
<button type="button" @click="handleCloseModal">
<AtomsIconsCloseLine />
</button>
</div>