From 7a963d040956f46af59a47e8b7bf237a93619adb Mon Sep 17 00:00:00 2001 From: claude-bot Date: Sun, 10 May 2026 19:51:17 +0900 Subject: [PATCH] Refine installer step 2/4-1 and bind server to 127.0.0.1 by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 2 (싱글/멀티): replace auto-advance with a card selection plus a "다음" button so the user can review their choice before moving on. Step 4-1 (모드 플랫폼): replace the "설치 / 건너뛰기" buttons with two cards — "권장 플랫폼 설치" and "기본 마인크래프트로 설치". Selection only records intent; the actual platform install fires in 4-2 along with mods/resourcepacks (already handled by installer:client install). Server: default HOST to 127.0.0.1 instead of 0.0.0.0 so the startup log prints a Ctrl+클릭으로 바로 열 수 있는 URL. Set HOST=0.0.0.0 externally when public exposure is needed. Co-Authored-By: Claude Opus 4.7 --- installer/renderer.js | 86 +++++++++++++++++++++++++++++++------------ src/server/app.ts | 4 +- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/installer/renderer.js b/installer/renderer.js index 121c4fc..6057e70 100644 --- a/installer/renderer.js +++ b/installer/renderer.js @@ -119,20 +119,36 @@ function renderStep2() { section.innerHTML = '

2단계. 싱글 / 멀티 선택

' + '
' + - '' + - '' + + '' + + '' + '
' + - '
' + '
' pageHost.appendChild(section) - section.querySelector('#single').addEventListener('click', function () { - state.mode = 'single' - state.stepDone[2] = true - renderStep4() + var nextBtn = section.querySelector('#next') + var modeButtons = section.querySelectorAll('[data-mode]') + + function applySelection(mode) { + state.mode = mode + modeButtons.forEach(function (btn) { + if (btn.getAttribute('data-mode') === mode) btn.classList.add('selected') + else btn.classList.remove('selected') + }) + nextBtn.disabled = false + } + + modeButtons.forEach(function (btn) { + btn.addEventListener('click', function () { + applySelection(btn.getAttribute('data-mode')) + }) }) - section.querySelector('#multi').addEventListener('click', function () { - state.mode = 'multi' + + if (state.mode === 'single' || state.mode === 'multi') applySelection(state.mode) + + nextBtn.addEventListener('click', function () { + if (!state.mode) return state.stepDone[2] = true - renderStep3() + if (state.mode === 'single') renderStep4() + else renderStep3() }) section.querySelector('#back').addEventListener('click', renderStep1) } @@ -413,25 +429,49 @@ function renderStep4() { function renderSubStep41(host, pack, done) { var platformType = pack ? pack.pack.platform.type : 'vanilla' - host.innerHTML = - '

4-1. 모드 플랫폼

' + - '

선택한 음악퀴즈의 플랫폼: ' + platformType + '

' + - (platformType === 'vanilla' - ? '

바닐라이므로 별도 설치는 필요 없습니다.

' - : '
') if (platformType === 'vanilla') { state.client.installPlatform = false + host.innerHTML = + '

4-1. 모드 플랫폼

' + + '

선택한 음악퀴즈의 플랫폼: vanilla

' + + '

바닐라이므로 별도 설치는 필요 없습니다.

' + + '
' host.querySelector('#next').addEventListener('click', done) return } - host.querySelector('#install').addEventListener('click', function () { - state.client.installPlatform = true - done() - }) - host.querySelector('#skip').addEventListener('click', function () { - state.client.installPlatform = false - done() + + host.innerHTML = + '

4-1. 모드 플랫폼

' + + '

선택한 음악퀴즈의 플랫폼: ' + platformType + '

' + + '
' + + '' + + '' + + '
' + + '
' + + var nextBtn = host.querySelector('#next') + var choiceButtons = host.querySelectorAll('[data-choice]') + + function applyChoice(choice) { + state.client.installPlatform = choice === 'install' + choiceButtons.forEach(function (btn) { + if (btn.getAttribute('data-choice') === choice) btn.classList.add('selected') + else btn.classList.remove('selected') + }) + nextBtn.disabled = false + } + + choiceButtons.forEach(function (btn) { + btn.addEventListener('click', function () { + applyChoice(btn.getAttribute('data-choice')) + }) }) + + if (typeof state.client.installPlatform === 'boolean') { + applyChoice(state.client.installPlatform ? 'install' : 'skip') + } + + nextBtn.addEventListener('click', done) } function renderSubStep42(host, done) { diff --git a/src/server/app.ts b/src/server/app.ts index 16a6e1b..4c47fa9 100644 --- a/src/server/app.ts +++ b/src/server/app.ts @@ -6,7 +6,9 @@ import { indexRouter } from './routes/index' import { opRouter } from './routes/op' const PORT = Number(process.env.PORT ?? 3000) -const HOST = process.env.HOST ?? '0.0.0.0' +// 터미널에서 Ctrl+클릭으로 바로 열 수 있도록 기본값은 127.0.0.1. +// 외부 노출이 필요할 때만 HOST=0.0.0.0 환경변수로 덮어씀. +const HOST = process.env.HOST ?? '127.0.0.1' const app = express()