Refine install list and responsive scaling
Some checks failed
Build / release (macos-latest) (push) Has been cancelled
Build / release (ubuntu-latest) (push) Has been cancelled
Build / release (windows-latest) (push) Has been cancelled
Windows Smoke Test / windows-smoke (push) Has been cancelled

This commit is contained in:
2026-05-04 15:22:09 +09:00
parent bc6bef0c46
commit 010dbc30a4
6 changed files with 243 additions and 162 deletions

View File

@@ -3293,6 +3293,7 @@ input:checked + .toggleSwitchSlider:before {
font-weight: 900; font-weight: 900;
text-shadow: 0px 0px 20px #949494; text-shadow: 0px 0px 20px #949494;
margin-left: 12px; margin-left: 12px;
white-space: nowrap;
} }
/* Wrapper container for the mojang status bar. */ /* Wrapper container for the mojang status bar. */
@@ -3463,6 +3464,7 @@ input:checked + .toggleSwitchSlider:before {
line-height: 36px; line-height: 36px;
display: flex; display: flex;
transition: 0.25s ease; transition: 0.25s ease;
white-space: nowrap;
} }
/* * * /* * *
@@ -3488,6 +3490,7 @@ input:checked + .toggleSwitchSlider:before {
padding: 0px; padding: 0px;
transition: 0.25s ease; transition: 0.25s ease;
outline: none; outline: none;
white-space: nowrap;
} }
#launch_button:hover, #launch_button:hover,
#launch_button:focus { #launch_button:focus {
@@ -3543,6 +3546,7 @@ input:checked + .toggleSwitchSlider:before {
line-height: 30px; line-height: 30px;
padding: 0px; padding: 0px;
transition: 0.25s ease; transition: 0.25s ease;
white-space: nowrap;
} }
#server_selection_button:hover, #server_selection_button:hover,
#server_selection_button:focus { #server_selection_button:focus {
@@ -4150,8 +4154,8 @@ input:checked + .toggleSwitchSlider:before {
} }
.launcherCardGrid { .launcherCardGrid {
display: grid; display: flex;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); flex-direction: column;
gap: 16px; gap: 16px;
} }
@@ -4163,9 +4167,9 @@ input:checked + .toggleSwitchSlider:before {
.launcherListItem { .launcherListItem {
display: flex; display: flex;
align-items: center; flex-direction: column;
justify-content: space-between; align-items: stretch;
gap: 20px; gap: 18px;
padding: 22px 24px; padding: 22px 24px;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 20px; border-radius: 20px;
@@ -4188,6 +4192,13 @@ input:checked + .toggleSwitchSlider:before {
gap: 8px; gap: 8px;
} }
.launcherListItemTop {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 20px;
}
.launcherListTitleRow { .launcherListTitleRow {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
@@ -4206,6 +4217,9 @@ input:checked + .toggleSwitchSlider:before {
margin: 0; margin: 0;
font-size: 24px; font-size: 24px;
color: #ffffff; color: #ffffff;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
.launcherListMeta { .launcherListMeta {
@@ -4228,6 +4242,22 @@ input:checked + .toggleSwitchSlider:before {
justify-content: flex-end; justify-content: flex-end;
gap: 10px; gap: 10px;
flex-wrap: wrap; flex-wrap: wrap;
flex-shrink: 0;
}
.launcherExpandableDetail {
display: flex;
flex-direction: column;
gap: 14px;
padding-top: 18px;
border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.launcherExpandableMeta {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
} }
.launcherCard { .launcherCard {
@@ -4241,6 +4271,7 @@ input:checked + .toggleSwitchSlider:before {
background: rgba(15, 15, 15, 0.56); background: rgba(15, 15, 15, 0.56);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
box-shadow: 0 18px 50px rgba(0, 0, 0, 0.18); box-shadow: 0 18px 50px rgba(0, 0, 0, 0.18);
width: 100%;
} }
.launcherCard[selected="true"] { .launcherCard[selected="true"] {
@@ -4264,6 +4295,9 @@ input:checked + .toggleSwitchSlider:before {
margin: 0; margin: 0;
font-size: 26px; font-size: 26px;
color: #ffffff; color: #ffffff;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
.launcherCardMeta { .launcherCardMeta {
@@ -4283,6 +4317,7 @@ input:checked + .toggleSwitchSlider:before {
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.08em; letter-spacing: 0.08em;
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
white-space: nowrap;
} }
.launcherCardDescription, .launcherCardDescription,
@@ -4428,6 +4463,7 @@ input:checked + .toggleSwitchSlider:before {
font-weight: 600; font-weight: 600;
cursor: pointer; cursor: pointer;
transition: transform 0.2s ease, opacity 0.2s ease, border-color 0.2s ease, background 0.2s ease; transition: transform 0.2s ease, opacity 0.2s ease, border-color 0.2s ease, background 0.2s ease;
white-space: nowrap;
} }
.launcherPrimaryButton { .launcherPrimaryButton {

View File

@@ -4,15 +4,8 @@ const ConfigManager = require('./assets/js/configmanager')
const ProfileAssetManager = require('./assets/js/profileassetmanager') const ProfileAssetManager = require('./assets/js/profileassetmanager')
const installCatalogList = document.getElementById('installCatalogList') const installCatalogList = document.getElementById('installCatalogList')
const installDetailTitle = document.getElementById('installDetailTitle')
const installDetailSummary = document.getElementById('installDetailSummary')
const installDetailMeta = document.getElementById('installDetailMeta')
const installDetailInfo = document.getElementById('installDetailInfo')
const installDetailBody = document.getElementById('installDetailBody')
const installDetailAddButton = document.getElementById('installDetailAddButton')
let selectedProfileId = null let expandedProfileId = null
let latestCatalog = null
function describeProfileKind(kind){ function describeProfileKind(kind){
switch(kind){ switch(kind){
@@ -74,98 +67,123 @@ function buildDetailText(profile){
} }
} }
function renderDetailPanel(profile){ function toggleExpandedProfile(profileId){
const installedIds = new Set( expandedProfileId = expandedProfileId === profileId ? null : profileId
ConfigManager.getInstalledLibraryProfiles().map((installedProfile) => installedProfile.id) }
)
const installed = installedIds.has(profile.id)
installDetailTitle.textContent = profile.name async function installProfile(profile){
installDetailSummary.textContent = profile.description || '설명이 없습니다.' const installedProfile = await CatalogManager.installProfile(profile.id)
installDetailMeta.innerHTML = '' await ProfileAssetManager.prefetchProfileAssets(installedProfile)
installDetailMeta.appendChild(createInstallBadge(describeProfileKind(profile.kind))) if(installedProfile.kind === 'server-pack' && installedProfile.hostReady){
await ProfileAssetManager.ensureServerBundleInstalled(installedProfile)
}
if(typeof refreshSelectedProfileButton === 'function'){
refreshSelectedProfileButton()
}
if(typeof refreshServerStatus === 'function'){
refreshServerStatus(true)
}
if(typeof refreshLibraryView === 'function'){
await refreshLibraryView()
}
}
function createExpandedDetail(profile, installed){
const detailSection = document.createElement('div')
detailSection.className = 'launcherExpandableDetail'
detailSection.addEventListener('click', (event) => {
event.stopPropagation()
})
const badgeRow = document.createElement('div')
badgeRow.className = 'launcherExpandableMeta'
badgeRow.appendChild(createInstallBadge(describeProfileKind(profile.kind)))
if(installed){ if(installed){
installDetailMeta.appendChild(createInstallBadge('라이브러리 보유')) badgeRow.appendChild(createInstallBadge('설치됨'))
} }
if(!profile.launchReady){ if(!profile.launchReady){
installDetailMeta.appendChild(createInstallBadge('실행 준비 필요')) badgeRow.appendChild(createInstallBadge('실행 준비 필요'))
} }
if(profile.kind === 'server-pack' && profile.hostReady){ if(profile.kind === 'server-pack' && profile.hostReady){
installDetailMeta.appendChild(createInstallBadge('로컬 호스팅 가능')) badgeRow.appendChild(createInstallBadge('호스팅 가능'))
} }
installDetailInfo.innerHTML = '' const infoBlock = document.createElement('div')
installDetailInfo.appendChild(createInfoLine('프로필 ID', profile.id)) infoBlock.className = 'launcherInfoBlock'
installDetailInfo.appendChild(createInfoLine('종류', describeProfileKind(profile.kind))) infoBlock.appendChild(createInfoLine('프로필 ID', profile.id))
installDetailInfo.appendChild(createInfoLine('실행 준비', profile.launchReady ? '완료' : '추가 설정 필요')) infoBlock.appendChild(createInfoLine('종류', describeProfileKind(profile.kind)))
infoBlock.appendChild(createInfoLine('실행 준비', profile.launchReady ? '완료' : '추가 설정 필요'))
if(profile.defaultServerAddress){ if(profile.defaultServerAddress){
installDetailInfo.appendChild(createInfoLine('기본 주소', profile.defaultServerAddress)) infoBlock.appendChild(createInfoLine('기본 주소', profile.defaultServerAddress))
} }
if(profile.kind === 'map' && profile.worldDirectoryName){ if(profile.kind === 'map' && profile.worldDirectoryName){
installDetailInfo.appendChild(createInfoLine('월드 폴더', profile.worldDirectoryName)) infoBlock.appendChild(createInfoLine('월드 폴더', profile.worldDirectoryName))
} }
if(profile.kind === 'server-pack'){ if(profile.kind === 'server-pack'){
installDetailInfo.appendChild(createInfoLine('로컬 호스팅', profile.hostReady ? '가능' : '관리자 설정 필요')) infoBlock.appendChild(createInfoLine('로컬 호스팅', profile.hostReady ? '가능' : '관리자 설정 필요'))
} }
if(profile.launchIssues.length > 0){ if(profile.launchIssues.length > 0){
installDetailInfo.appendChild(createInfoLine('확인 필요', profile.launchIssues.join(' / '))) infoBlock.appendChild(createInfoLine('확인 필요', profile.launchIssues.join(' / ')))
} else if(profile.hostIssues.length > 0){ } else if(profile.hostIssues.length > 0){
installDetailInfo.appendChild(createInfoLine('호스팅 참고', profile.hostIssues.join(' / '))) infoBlock.appendChild(createInfoLine('호스팅 참고', profile.hostIssues.join(' / ')))
} }
installDetailBody.textContent = buildDetailText(profile) const bodyGroup = document.createElement('div')
installDetailAddButton.disabled = installed || !profile.launchReady bodyGroup.className = 'launcherFieldGroup'
installDetailAddButton.textContent = installed ? '이미 라이브러리에 있음' : '라이브러리에 추가'
installDetailAddButton.onclick = async () => { const bodyLabel = document.createElement('label')
try { bodyLabel.className = 'launcherFieldLabel'
const installedProfile = await CatalogManager.installProfile(profile.id) bodyLabel.textContent = '자세한 내용'
await ProfileAssetManager.prefetchProfileAssets(installedProfile)
if(installedProfile.kind === 'server-pack' && installedProfile.hostReady){ const body = document.createElement('div')
await ProfileAssetManager.ensureServerBundleInstalled(installedProfile) body.className = 'launcherDetailBody'
} body.textContent = buildDetailText(profile)
if(typeof refreshSelectedProfileButton === 'function'){
refreshSelectedProfileButton() bodyGroup.appendChild(bodyLabel)
} bodyGroup.appendChild(body)
renderDetailPanel(profile)
await renderInstallView() const actions = document.createElement('div')
if(typeof refreshLibraryView === 'function'){ actions.className = 'launcherCardActions'
await refreshLibraryView()
} const installButton = document.createElement('button')
installButton.className = 'launcherPrimaryButton'
installButton.textContent = installed ? '설치됨' : '라이브러리에 추가'
installButton.disabled = installed || !profile.launchReady
installButton.addEventListener('click', async (event) => {
event.stopPropagation()
try {
await installProfile(profile)
await renderInstallView()
showInstallMessage('추가 완료', `${profile.name} 프로필을 라이브러리에 추가했습니다.`) showInstallMessage('추가 완료', `${profile.name} 프로필을 라이브러리에 추가했습니다.`)
} catch (error) { } catch (error) {
console.error(error) console.error(error)
const message = error instanceof Error ? error.message : '프로필 설치 중 오류가 발생했습니다.' const message = error instanceof Error ? error.message : '프로필 설치 중 오류가 발생했습니다.'
showInstallMessage('설치 실패', message) showInstallMessage('설치 실패', message)
} }
} })
}
function renderEmptyDetailPanel(){ const openLibraryButton = document.createElement('button')
installDetailTitle.textContent = '프로필을 선택하세요' openLibraryButton.className = 'launcherSecondaryButton'
installDetailSummary.textContent = '아래 목록에서 모드팩, 맵, 서버팩을 고르면 자세한 설명과 설치 조건을 볼 수 있습니다.' openLibraryButton.textContent = '라이브러리 열기'
installDetailMeta.innerHTML = '' openLibraryButton.addEventListener('click', async (event) => {
installDetailInfo.innerHTML = '' event.stopPropagation()
installDetailBody.textContent = '관리자가 등록한 프로필 상세 설명이 여기에 표시됩니다.' if(typeof refreshLibraryView === 'function'){
installDetailAddButton.disabled = true await refreshLibraryView()
installDetailAddButton.textContent = '라이브러리에 추가' }
installDetailAddButton.onclick = null switchView(getCurrentView(), VIEWS.library)
} })
function selectProfile(profileId){ actions.appendChild(installButton)
selectedProfileId = profileId actions.appendChild(openLibraryButton)
if(latestCatalog == null){
renderEmptyDetailPanel()
return
}
const profile = latestCatalog.profiles.find((entry) => entry.id === profileId) detailSection.appendChild(badgeRow)
if(profile == null){ detailSection.appendChild(infoBlock)
renderEmptyDetailPanel() detailSection.appendChild(bodyGroup)
return detailSection.appendChild(actions)
}
renderDetailPanel(profile) return detailSection
} }
async function renderInstallView(){ async function renderInstallView(){
@@ -173,11 +191,14 @@ async function renderInstallView(){
try { try {
const catalog = await CatalogManager.loadCatalog() const catalog = await CatalogManager.loadCatalog()
latestCatalog = catalog
const installedIds = new Set( const installedIds = new Set(
ConfigManager.getInstalledLibraryProfiles().map((profile) => profile.id) ConfigManager.getInstalledLibraryProfiles().map((profile) => profile.id)
) )
if(expandedProfileId != null && !catalog.profiles.some((profile) => profile.id === expandedProfileId)){
expandedProfileId = null
}
if(catalog.sourceError != null){ if(catalog.sourceError != null){
const warningCard = document.createElement('article') const warningCard = document.createElement('article')
warningCard.className = 'launcherCard' warningCard.className = 'launcherCard'
@@ -186,12 +207,18 @@ async function renderInstallView(){
} }
for(const profile of catalog.profiles){ for(const profile of catalog.profiles){
const installed = installedIds.has(profile.id)
const expanded = expandedProfileId === profile.id
const row = document.createElement('article') const row = document.createElement('article')
row.className = 'launcherListItem' row.className = 'launcherListItem'
if(profile.id === selectedProfileId){ if(expanded){
row.setAttribute('selected', 'true') row.setAttribute('selected', 'true')
} }
const top = document.createElement('div')
top.className = 'launcherListItemTop'
const main = document.createElement('div') const main = document.createElement('div')
main.className = 'launcherListItemMain' main.className = 'launcherListItemMain'
@@ -208,15 +235,13 @@ async function renderInstallView(){
const meta = document.createElement('div') const meta = document.createElement('div')
meta.className = 'launcherListMeta' meta.className = 'launcherListMeta'
meta.appendChild(createInstallBadge(describeProfileKind(profile.kind))) meta.appendChild(createInstallBadge(describeProfileKind(profile.kind)))
if(installedIds.has(profile.id)){ if(installed){
meta.appendChild(createInstallBadge('설치됨')) meta.appendChild(createInstallBadge('설치됨'))
} }
if(profile.kind === 'server-pack' && profile.hostReady){ if(profile.kind === 'server-pack' && profile.hostReady){
meta.appendChild(createInstallBadge('호스팅 가능')) meta.appendChild(createInstallBadge('호스팅 가능'))
} }
textGroup.appendChild(title)
const description = document.createElement('p') const description = document.createElement('p')
description.className = 'launcherListDescription' description.className = 'launcherListDescription'
description.textContent = profile.description || '설명이 없습니다.' description.textContent = profile.description || '설명이 없습니다.'
@@ -226,36 +251,23 @@ async function renderInstallView(){
const detailButton = document.createElement('button') const detailButton = document.createElement('button')
detailButton.className = 'launcherSecondaryButton' detailButton.className = 'launcherSecondaryButton'
detailButton.textContent = '자세히 보기' detailButton.textContent = expanded ? '간단히 보기' : '자세히 보기'
detailButton.addEventListener('click', async (event) => { detailButton.addEventListener('click', async (event) => {
event.stopPropagation() event.stopPropagation()
selectProfile(profile.id) toggleExpandedProfile(profile.id)
await renderInstallView() await renderInstallView()
}) })
const installButton = document.createElement('button') const installButton = document.createElement('button')
installButton.className = 'launcherPrimaryButton' installButton.className = 'launcherPrimaryButton'
installButton.textContent = installedIds.has(profile.id) ? '설치됨' : '라이브러리에 추가' installButton.textContent = installed ? '설치됨' : '라이브러리에 추가'
installButton.disabled = installedIds.has(profile.id) || !profile.launchReady installButton.disabled = installed || !profile.launchReady
installButton.addEventListener('click', async (event) => { installButton.addEventListener('click', async (event) => {
event.stopPropagation() event.stopPropagation()
try { try {
const installedProfile = await CatalogManager.installProfile(profile.id) await installProfile(profile)
await ProfileAssetManager.prefetchProfileAssets(installedProfile) expandedProfileId = profile.id
if(installedProfile.kind === 'server-pack' && installedProfile.hostReady){
await ProfileAssetManager.ensureServerBundleInstalled(installedProfile)
}
if(typeof refreshSelectedProfileButton === 'function'){
refreshSelectedProfileButton()
}
if(typeof refreshServerStatus === 'function'){
refreshServerStatus(true)
}
selectProfile(profile.id)
await renderInstallView() await renderInstallView()
if(typeof refreshLibraryView === 'function'){
await refreshLibraryView()
}
showInstallMessage('추가 완료', `${profile.name} 프로필을 라이브러리에 추가했습니다.`) showInstallMessage('추가 완료', `${profile.name} 프로필을 라이브러리에 추가했습니다.`)
} catch (error) { } catch (error) {
console.error(error) console.error(error)
@@ -264,37 +276,39 @@ async function renderInstallView(){
} }
}) })
actions.appendChild(detailButton) textGroup.appendChild(title)
actions.appendChild(installButton)
titleRow.appendChild(textGroup) titleRow.appendChild(textGroup)
titleRow.appendChild(meta) titleRow.appendChild(meta)
main.appendChild(titleRow) main.appendChild(titleRow)
main.appendChild(description) main.appendChild(description)
row.appendChild(main)
row.appendChild(actions) actions.appendChild(detailButton)
actions.appendChild(installButton)
top.appendChild(main)
top.appendChild(actions)
row.appendChild(top)
if(expanded){
row.appendChild(createExpandedDetail(profile, installed))
}
row.addEventListener('click', async () => { row.addEventListener('click', async () => {
selectProfile(profile.id) toggleExpandedProfile(profile.id)
await renderInstallView() await renderInstallView()
}) })
installCatalogList.appendChild(row) installCatalogList.appendChild(row)
} }
if(catalog.profiles.length === 0){ if(catalog.profiles.length === 0){
renderEmptyDetailPanel() const emptyCard = document.createElement('article')
return emptyCard.className = 'launcherCard'
emptyCard.innerHTML = '<h3 class="launcherCardTitle">등록된 프로필이 없습니다</h3><p class="launcherCardDescription">관리자가 카탈로그에 프로필을 추가하면 여기에 표시됩니다.</p>'
installCatalogList.appendChild(emptyCard)
} }
const selectedProfileStillExists = catalog.profiles.some((profile) => profile.id === selectedProfileId)
if(!selectedProfileStillExists){
selectedProfileId = catalog.profiles[0].id
}
selectProfile(selectedProfileId)
} catch (error) { } catch (error) {
console.error(error) console.error(error)
latestCatalog = null
renderEmptyDetailPanel()
const errorCard = document.createElement('article') const errorCard = document.createElement('article')
errorCard.className = 'launcherCard' errorCard.className = 'launcherCard'
@@ -307,14 +321,6 @@ document.getElementById('installBackButton').addEventListener('click', () => {
switchView(getCurrentView(), VIEWS.landing) switchView(getCurrentView(), VIEWS.landing)
}) })
document.getElementById('installDetailOpenLibraryButton').addEventListener('click', async () => {
if(typeof refreshLibraryView === 'function'){
await refreshLibraryView()
}
switchView(getCurrentView(), VIEWS.library)
})
window.refreshInstallView = renderInstallView window.refreshInstallView = renderInstallView
renderEmptyDetailPanel()
renderInstallView() renderInstallView()
})() })()

View File

@@ -35,6 +35,69 @@ remote.getCurrentWebContents().on('devtools-opened', () => {
webFrame.setZoomLevel(0) webFrame.setZoomLevel(0)
webFrame.setVisualZoomLevelLimits(1, 1) webFrame.setVisualZoomLevelLimits(1, 1)
const BASE_WINDOW_WIDTH = 1400
const BASE_WINDOW_HEIGHT = 860
let responsiveLayoutFrame = null
function clamp(value, min, max){
return Math.min(Math.max(value, min), max)
}
function syncLaunchDetailWidths(){
const launchContent = document.getElementById('launch_content')
const launchDetails = document.getElementById('launch_details')
const launchButton = document.getElementById('launch_button')
const launchProgress = document.getElementById('launch_progress')
const launchDetailsRight = document.getElementById('launch_details_right')
const launchProgressLabel = document.getElementById('launch_progress_label')
if(!launchContent || !launchDetails || !launchButton || !launchProgress || !launchDetailsRight || !launchProgressLabel){
return
}
const launchContentWidth = launchContent.getBoundingClientRect().width
const launchButtonWidth = launchButton.getBoundingClientRect().width
const labelWidth = Math.max(64, Math.ceil(launchButtonWidth * 0.48))
const progressWidth = Math.max(220, Math.floor(launchContentWidth - labelWidth - 48))
launchDetails.style.maxWidth = `${Math.ceil(launchContentWidth)}px`
launchProgress.style.width = `${progressWidth}px`
launchDetailsRight.style.maxWidth = `${progressWidth}px`
launchProgressLabel.style.width = `${labelWidth}px`
launchProgressLabel.style.minWidth = `${labelWidth}px`
launchProgressLabel.style.maxWidth = `${labelWidth}px`
}
function applyResponsiveLayout(){
const scale = clamp(
Math.min(window.innerWidth / BASE_WINDOW_WIDTH, window.innerHeight / BASE_WINDOW_HEIGHT),
0.72,
1.45
)
webFrame.setZoomFactor(scale)
document.documentElement.style.setProperty('--launcher-scale', scale.toFixed(3))
window.requestAnimationFrame(() => {
syncLaunchDetailWidths()
})
}
function queueResponsiveLayout(){
if(responsiveLayoutFrame != null){
cancelAnimationFrame(responsiveLayoutFrame)
}
responsiveLayoutFrame = requestAnimationFrame(() => {
responsiveLayoutFrame = null
applyResponsiveLayout()
})
}
window.addEventListener('resize', () => {
queueResponsiveLayout()
})
// Initialize auto updates in production environments. // Initialize auto updates in production environments.
let updateCheckListener let updateCheckListener
if(!isDev){ if(!isDev){
@@ -174,20 +237,10 @@ document.addEventListener('readystatechange', function () {
}) })
} else if(document.readyState === 'complete'){ } else if(document.readyState === 'complete'){
queueResponsiveLayout()
//266.01 setTimeout(() => {
//170.8 queueResponsiveLayout()
//53.21 }, 150)
// Bind progress bar length to length of bot wrapper
//const targetWidth = document.getElementById("launch_content").getBoundingClientRect().width
//const targetWidth2 = document.getElementById("server_selection").getBoundingClientRect().width
//const targetWidth3 = document.getElementById("launch_button").getBoundingClientRect().width
document.getElementById('launch_details').style.maxWidth = 266.01
document.getElementById('launch_progress').style.width = 170.8
document.getElementById('launch_details_right').style.maxWidth = 170.8
document.getElementById('launch_progress_label').style.width = 53.21
} }
}, false) }, false)

View File

@@ -13,24 +13,6 @@
<div id="installCatalogNotice" class="launcherNotice"> <div id="installCatalogNotice" class="launcherNotice">
<span><%- lang('install.notice') %></span> <span><%- lang('install.notice') %></span>
</div> </div>
<div id="installProfileDetails" class="launcherNotice">
<div class="launcherEditorHeader">
<div>
<span id="installDetailTitle" class="launcherEditorTitle">프로필을 선택하세요</span>
<span id="installDetailSummary" class="launcherEditorDescription">아래 목록에서 모드팩, 맵, 서버팩을 고르면 자세한 설명과 설치 조건을 볼 수 있습니다.</span>
</div>
<div id="installDetailMeta" class="launcherPageActions"></div>
</div>
<div id="installDetailInfo" class="launcherInfoBlock"></div>
<div class="launcherFieldGroup">
<label class="launcherFieldLabel">자세한 내용</label>
<div id="installDetailBody" class="launcherDetailBody">관리자가 등록한 프로필 상세 설명이 여기에 표시됩니다.</div>
</div>
<div id="installDetailActions" class="launcherCardActions">
<button id="installDetailAddButton" class="launcherPrimaryButton" disabled>라이브러리에 추가</button>
<button id="installDetailOpenLibraryButton" class="launcherSecondaryButton">라이브러리 열기</button>
</div>
</div>
<div id="installCatalogList" class="launcherListContainer"></div> <div id="installCatalogList" class="launcherListContainer"></div>
</div> </div>
<script src="./assets/js/scripts/install.js"></script> <script src="./assets/js/scripts/install.js"></script>

View File

@@ -227,8 +227,10 @@ let win
function createWindow() { function createWindow() {
win = new BrowserWindow({ win = new BrowserWindow({
width: 980, width: 1400,
height: 552, height: 860,
minWidth: 1120,
minHeight: 700,
icon: getPlatformIcon('Icon'), icon: getPlatformIcon('Icon'),
frame: false, frame: false,
webPreferences: { webPreferences: {

View File

@@ -228,8 +228,10 @@ let win
function createWindow() { function createWindow() {
win = new BrowserWindow({ win = new BrowserWindow({
width: 980, width: 1400,
height: 552, height: 860,
minWidth: 1120,
minHeight: 700,
icon: getPlatformIcon('Icon'), icon: getPlatformIcon('Icon'),
frame: false, frame: false,
webPreferences: { webPreferences: {