import { useTokenValidation } from '#layers/composables/useTokenValidation' interface ReqCheckSpec { schemeFormat: string setupUrl: string gameNo: string locale: string } export const useCheckPCSpec = (tm: (key: string) => string) => { const { handleTokenValidation } = useTokenValidation() // Store const modalStore = useModalStore() const { handleOpenConfirm } = modalStore const isButtonDisabled = ref(false) // 버튼 비활성화 여부 /** * PC사양 프로그램이 미설치일 경우 설치 안내 모달을 표시합니다. * @param {string} setupUrl 설치 프로그램 URL */ const showInstallGuideModal = (setupUrl: string) => { isButtonDisabled.value = false handleOpenConfirm({ contentText: tm('Download_Alert_InstallGuide'), confirmButtonText: tm('Download_Text_Download'), modalName: 'modal-download', confirmButtonEvent: () => { location.href = String(setupUrl) }, }) } /** * iframe을 생성합니다. * @returns {iframe} 생성된 iframe */ const createHiddenIframe = () => { const iframe = document.createElement('iframe') iframe.src = 'about:blank' iframe.id = 'hiddenIframe' iframe.style.display = 'none' document.body.appendChild(iframe) return iframe } /** * Firefox 브라우저에서 URI를 열기 위한 함수입니다. * @param {string} uri URI * @param {Function} successCb 성공 콜백 * @param {Function} failCb 실패 콜백 */ const openUriUsingFirefox = ( uri: string, successCb: Function, failCb: Function ) => { let iframe = document.querySelector( '#hiddenIframe' ) as HTMLIFrameElement | null if (!iframe) { iframe = createHiddenIframe() as HTMLIFrameElement } try { iframe.contentWindow!.location.href = uri successCb() } catch (e) { if ((e as any).name === 'NS_ERROR_UNKNOWN_PROTOCOL') { failCb() } } } /** * Chrome 브라우저에서 URI를 열기 위한 함수입니다. * @param {string} uri 사양 프로그램 URI * @param {Function} successCb 성공 콜백 * @param {Function} failCb 실패 콜백 */ const openUriWithTimeoutHack = ( uri: string, successCb: Function, failCb: Function ) => { let called = false const timeout = setTimeout(() => { if (!called) { called = true window.removeEventListener('blur', onBlur) failCb() } }, 1000) const onBlur = () => { if (!called) { called = true clearTimeout(timeout) window.removeEventListener('blur', onBlur) successCb() } } window.addEventListener('blur', onBlur) window.location.href = uri } /** * PC사양 프로그램이 설치되어 있는지 여부를 확인합니다. * @param {string }uri 사양 프로그램 URI * @param {string} setupUrl 설치 프로그램 URL */ const checkPCSpecProgramInstalled = (uri: string, setupUrl: string) => { const device = useDevice() const successCallback = () => { isButtonDisabled.value = false } if (typeof (navigator as any).msLaunchUri === 'function') { ;(navigator as any).msLaunchUri( uri, successCallback, showInstallGuideModal(setupUrl) ) } else if (device.isFirefox) { // 파이어폭스 브라우저일 경우 openUriUsingFirefox(uri, successCallback, () => showInstallGuideModal(setupUrl) ) } else if (device.isChrome || device.isEdge) { // 크롬 / 엣지 브라우저일 경우 openUriWithTimeoutHack(uri, successCallback, () => showInstallGuideModal(setupUrl) ) } else { // 기타 미지원 브라우저일 경우 showInstallGuideModal(setupUrl) } } /** * 시스템 사양 체크를 시작합니다. * 최종 호출 함수입니다. * @param {ReqCheckSpec} req {schemeFormat:스킴 포맷, setupUrl:셋업 링크, gameNo:게임넘버, locale:언어} */ const checkPCSpec = async (req: ReqCheckSpec) => { const accessToken = useCookie('SUAT') const validateTokenResult = await handleTokenValidation( accessToken.value || '' ) if (validateTokenResult === false) { return } const localeValue: string = req.locale === 'ja' ? 'jp' : req.locale const uri = `${req.schemeFormat}${accessToken.value}/${req.gameNo}/${localeValue}` checkPCSpecProgramInstalled(uri, req.setupUrl) isButtonDisabled.value = true } return { isButtonDisabled, checkPCSpec, } }