Files
web-temp/layers/composables/useCheckPCSpec.ts
2025-11-06 15:27:36 +09:00

172 lines
4.5 KiB
TypeScript

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<HTMLIFrameElement>} 생성된 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,
}
}