import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '../context/useAuth'; import { getDownloadInfo } from '../api/download'; import { createLaunchTicket } from '../api/auth'; import './DownloadSection.css'; export default function DownloadSection() { const [info, setInfo] = useState(null); const [ready, setReady] = useState(false); const [loadError, setLoadError] = useState(false); const [launched, setLaunched] = useState(false); const [launching, setLaunching] = useState(false); const { user } = useAuth(); const navigate = useNavigate(); const loadInfo = () => { setReady(false); setLoadError(false); getDownloadInfo() .then((data) => { setInfo(data); setReady(true); }) .catch(() => { setLoadError(true); setReady(true); }); }; // eslint-disable-next-line react-hooks/set-state-in-effect -- initial data fetch on mount useEffect(() => { loadInfo(); }, []); const handlePlay = async () => { if (!user) { navigate('/login'); return; } setLaunching(true); // JWT를 URL에 직접 노출하지 않고, 일회용 티켓을 발급받아 전달 try { const ticket = await createLaunchTicket(); window.location.href = 'a301://launch?token=' + encodeURIComponent(ticket); } catch { // 티켓 발급 실패 시 로그인 유도 navigate('/login'); return; } // 런처가 실행되지 않았을 수 있으므로 안내 표시 setLaunched(true); setLaunching(false); }; const handleDownloadLauncher = () => { if (info?.launcherUrl) { const a = document.createElement('a'); a.href = info.launcherUrl; a.download = 'launcher.exe'; document.body.appendChild(a); a.click(); document.body.removeChild(a); } }; if (!ready) { return (

One of the plans

불러오는 중...

); } return (

One of the plans

{info ? ( <>

{info.version} · {info.fileSize}

{info.launcherUrl && ( )} {launched ? (

게임이 실행되지 않나요? 런처를 다운로드한 뒤 한 번 실행해주세요.

) : (

처음이거나 게임이 실행되지 않으면 런처를 다운로드해주세요.

)} ) : ( <>

{loadError ? '서버에 연결할 수 없습니다.' : '런처 준비 중입니다. 잠시 후 다시 확인해주세요.'}

{loadError && ( )} )}
); }