Step 4: replace stacked sub-steps with single-slot wizard flow

- renderStep4 now renders 4-1/4-2/4-3 into one #subHost slot, replacing instead of stacking when 다음 is clicked
- 4-2 shows "다음" only after install completes so success message stays visible (previously auto-advanced and the message flashed)
- Drop the duplicate section-level "5단계로" button; 4-3's confirm button advances to step 5

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-10 21:10:01 +09:00
parent 44847b8a55
commit 2dc3bc0aed

View File

@@ -402,29 +402,30 @@ function renderStep4() {
section.className = 'page' section.className = 'page'
section.innerHTML = section.innerHTML =
'<h2>4단계. 유저 클라이언트 설정</h2>' + '<h2>4단계. 유저 클라이언트 설정</h2>' +
'<div class="subStep" id="sub41"></div>' + '<div class="subStep" id="subHost"></div>' +
'<div class="subStep" id="sub42" hidden></div>' + '<div class="actionRow"><button class="secondaryBtn" id="back">이전</button><span></span></div>'
'<div class="subStep" id="sub43" hidden></div>' +
'<div class="actionRow"><button class="secondaryBtn" id="back">이전</button><button class="primaryBtn" id="next" hidden>5단계로</button></div>'
pageHost.appendChild(section) pageHost.appendChild(section)
var subHost = section.querySelector('#subHost')
section.querySelector('#back').addEventListener('click', function () { section.querySelector('#back').addEventListener('click', function () {
if (state.mode === 'multi') renderStep3(); else renderStep2() if (state.mode === 'multi') renderStep3(); else renderStep2()
}) })
renderSubStep41(section.querySelector('#sub41'), pack, function () { function show41() {
section.querySelector('#sub42').hidden = false subHost.innerHTML = ''
renderSubStep42(section.querySelector('#sub42'), function () { renderSubStep41(subHost, pack, show42)
section.querySelector('#sub43').hidden = false }
renderSubStep43(section.querySelector('#sub43'), function () { function show42() {
var nextBtn = section.querySelector('#next') subHost.innerHTML = ''
nextBtn.hidden = false renderSubStep42(subHost, show43)
nextBtn.addEventListener('click', function () { }
function show43() {
subHost.innerHTML = ''
renderSubStep43(subHost, function () {
state.stepDone[4] = true state.stepDone[4] = true
renderStep5() renderStep5()
}) })
}) }
}) show41()
})
} }
function renderSubStep41(host, pack, done) { function renderSubStep41(host, pack, done) {
@@ -479,9 +480,13 @@ function renderSubStep42(host, done) {
'<h3>4-2. 모드/리소스팩 다운로드 및 launcher_profiles 갱신</h3>' + '<h3>4-2. 모드/리소스팩 다운로드 및 launcher_profiles 갱신</h3>' +
'<p class="formMessage">%appdata%\\.mc_custom 에 모드와 리소스팩을 설치하고, launcher_profiles.json에 프로필을 등록합니다.</p>' + '<p class="formMessage">%appdata%\\.mc_custom 에 모드와 리소스팩을 설치하고, launcher_profiles.json에 프로필을 등록합니다.</p>' +
'<button class="primaryBtn" id="run">설치 시작</button>' + '<button class="primaryBtn" id="run">설치 시작</button>' +
'<div class="formMessage" id="msg"></div>' '<div class="formMessage" id="msg"></div>' +
host.querySelector('#run').addEventListener('click', async function () { '<div class="actionRow"><span></span><button class="primaryBtn" id="next" hidden>다음</button></div>'
var runBtn = host.querySelector('#run')
var msg = host.querySelector('#msg') var msg = host.querySelector('#msg')
var nextBtn = host.querySelector('#next')
runBtn.addEventListener('click', async function () {
runBtn.disabled = true
msg.textContent = '설치 중...' msg.textContent = '설치 중...'
msg.classList.remove('error', 'success') msg.classList.remove('error', 'success')
try { try {
@@ -491,12 +496,14 @@ function renderSubStep42(host, done) {
}) })
msg.textContent = '클라이언트 설치 완료.' msg.textContent = '클라이언트 설치 완료.'
msg.classList.add('success') msg.classList.add('success')
done() nextBtn.hidden = false
} catch (err) { } catch (err) {
msg.textContent = '설치 실패: ' + err.message msg.textContent = '설치 실패: ' + err.message
msg.classList.add('error') msg.classList.add('error')
runBtn.disabled = false
} }
}) })
nextBtn.addEventListener('click', done)
} }
function renderSubStep43(host, done) { function renderSubStep43(host, done) {