Refine install list and responsive scaling
This commit is contained in:
@@ -3293,6 +3293,7 @@ input:checked + .toggleSwitchSlider:before {
|
||||
font-weight: 900;
|
||||
text-shadow: 0px 0px 20px #949494;
|
||||
margin-left: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Wrapper container for the mojang status bar. */
|
||||
@@ -3463,6 +3464,7 @@ input:checked + .toggleSwitchSlider:before {
|
||||
line-height: 36px;
|
||||
display: flex;
|
||||
transition: 0.25s ease;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* * *
|
||||
@@ -3488,6 +3490,7 @@ input:checked + .toggleSwitchSlider:before {
|
||||
padding: 0px;
|
||||
transition: 0.25s ease;
|
||||
outline: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#launch_button:hover,
|
||||
#launch_button:focus {
|
||||
@@ -3543,6 +3546,7 @@ input:checked + .toggleSwitchSlider:before {
|
||||
line-height: 30px;
|
||||
padding: 0px;
|
||||
transition: 0.25s ease;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#server_selection_button:hover,
|
||||
#server_selection_button:focus {
|
||||
@@ -4150,8 +4154,8 @@ input:checked + .toggleSwitchSlider:before {
|
||||
}
|
||||
|
||||
.launcherCardGrid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
@@ -4163,9 +4167,9 @@ input:checked + .toggleSwitchSlider:before {
|
||||
|
||||
.launcherListItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 18px;
|
||||
padding: 22px 24px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 20px;
|
||||
@@ -4188,6 +4192,13 @@ input:checked + .toggleSwitchSlider:before {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.launcherListItemTop {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.launcherListTitleRow {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
@@ -4206,6 +4217,9 @@ input:checked + .toggleSwitchSlider:before {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
color: #ffffff;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.launcherListMeta {
|
||||
@@ -4228,6 +4242,22 @@ input:checked + .toggleSwitchSlider:before {
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
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 {
|
||||
@@ -4241,6 +4271,7 @@ input:checked + .toggleSwitchSlider:before {
|
||||
background: rgba(15, 15, 15, 0.56);
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 18px 50px rgba(0, 0, 0, 0.18);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.launcherCard[selected="true"] {
|
||||
@@ -4264,6 +4295,9 @@ input:checked + .toggleSwitchSlider:before {
|
||||
margin: 0;
|
||||
font-size: 26px;
|
||||
color: #ffffff;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.launcherCardMeta {
|
||||
@@ -4283,6 +4317,7 @@ input:checked + .toggleSwitchSlider:before {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.launcherCardDescription,
|
||||
@@ -4428,6 +4463,7 @@ input:checked + .toggleSwitchSlider:before {
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, opacity 0.2s ease, border-color 0.2s ease, background 0.2s ease;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.launcherPrimaryButton {
|
||||
|
||||
@@ -4,15 +4,8 @@ const ConfigManager = require('./assets/js/configmanager')
|
||||
const ProfileAssetManager = require('./assets/js/profileassetmanager')
|
||||
|
||||
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 latestCatalog = null
|
||||
let expandedProfileId = null
|
||||
|
||||
function describeProfileKind(kind){
|
||||
switch(kind){
|
||||
@@ -74,98 +67,123 @@ function buildDetailText(profile){
|
||||
}
|
||||
}
|
||||
|
||||
function renderDetailPanel(profile){
|
||||
const installedIds = new Set(
|
||||
ConfigManager.getInstalledLibraryProfiles().map((installedProfile) => installedProfile.id)
|
||||
)
|
||||
const installed = installedIds.has(profile.id)
|
||||
function toggleExpandedProfile(profileId){
|
||||
expandedProfileId = expandedProfileId === profileId ? null : profileId
|
||||
}
|
||||
|
||||
installDetailTitle.textContent = profile.name
|
||||
installDetailSummary.textContent = profile.description || '설명이 없습니다.'
|
||||
installDetailMeta.innerHTML = ''
|
||||
installDetailMeta.appendChild(createInstallBadge(describeProfileKind(profile.kind)))
|
||||
async function installProfile(profile){
|
||||
const installedProfile = await CatalogManager.installProfile(profile.id)
|
||||
await ProfileAssetManager.prefetchProfileAssets(installedProfile)
|
||||
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){
|
||||
installDetailMeta.appendChild(createInstallBadge('라이브러리 보유'))
|
||||
badgeRow.appendChild(createInstallBadge('설치됨'))
|
||||
}
|
||||
if(!profile.launchReady){
|
||||
installDetailMeta.appendChild(createInstallBadge('실행 준비 필요'))
|
||||
badgeRow.appendChild(createInstallBadge('실행 준비 필요'))
|
||||
}
|
||||
if(profile.kind === 'server-pack' && profile.hostReady){
|
||||
installDetailMeta.appendChild(createInstallBadge('로컬 호스팅 가능'))
|
||||
badgeRow.appendChild(createInstallBadge('호스팅 가능'))
|
||||
}
|
||||
|
||||
installDetailInfo.innerHTML = ''
|
||||
installDetailInfo.appendChild(createInfoLine('프로필 ID', profile.id))
|
||||
installDetailInfo.appendChild(createInfoLine('종류', describeProfileKind(profile.kind)))
|
||||
installDetailInfo.appendChild(createInfoLine('실행 준비', profile.launchReady ? '완료' : '추가 설정 필요'))
|
||||
const infoBlock = document.createElement('div')
|
||||
infoBlock.className = 'launcherInfoBlock'
|
||||
infoBlock.appendChild(createInfoLine('프로필 ID', profile.id))
|
||||
infoBlock.appendChild(createInfoLine('종류', describeProfileKind(profile.kind)))
|
||||
infoBlock.appendChild(createInfoLine('실행 준비', profile.launchReady ? '완료' : '추가 설정 필요'))
|
||||
|
||||
if(profile.defaultServerAddress){
|
||||
installDetailInfo.appendChild(createInfoLine('기본 주소', profile.defaultServerAddress))
|
||||
infoBlock.appendChild(createInfoLine('기본 주소', profile.defaultServerAddress))
|
||||
}
|
||||
if(profile.kind === 'map' && profile.worldDirectoryName){
|
||||
installDetailInfo.appendChild(createInfoLine('월드 폴더', profile.worldDirectoryName))
|
||||
infoBlock.appendChild(createInfoLine('월드 폴더', profile.worldDirectoryName))
|
||||
}
|
||||
if(profile.kind === 'server-pack'){
|
||||
installDetailInfo.appendChild(createInfoLine('로컬 호스팅', profile.hostReady ? '가능' : '관리자 설정 필요'))
|
||||
infoBlock.appendChild(createInfoLine('로컬 호스팅', profile.hostReady ? '가능' : '관리자 설정 필요'))
|
||||
}
|
||||
if(profile.launchIssues.length > 0){
|
||||
installDetailInfo.appendChild(createInfoLine('확인 필요', profile.launchIssues.join(' / ')))
|
||||
infoBlock.appendChild(createInfoLine('확인 필요', profile.launchIssues.join(' / ')))
|
||||
} else if(profile.hostIssues.length > 0){
|
||||
installDetailInfo.appendChild(createInfoLine('호스팅 참고', profile.hostIssues.join(' / ')))
|
||||
infoBlock.appendChild(createInfoLine('호스팅 참고', profile.hostIssues.join(' / ')))
|
||||
}
|
||||
|
||||
installDetailBody.textContent = buildDetailText(profile)
|
||||
installDetailAddButton.disabled = installed || !profile.launchReady
|
||||
installDetailAddButton.textContent = installed ? '이미 라이브러리에 있음' : '라이브러리에 추가'
|
||||
installDetailAddButton.onclick = async () => {
|
||||
try {
|
||||
const installedProfile = await CatalogManager.installProfile(profile.id)
|
||||
await ProfileAssetManager.prefetchProfileAssets(installedProfile)
|
||||
if(installedProfile.kind === 'server-pack' && installedProfile.hostReady){
|
||||
await ProfileAssetManager.ensureServerBundleInstalled(installedProfile)
|
||||
}
|
||||
if(typeof refreshSelectedProfileButton === 'function'){
|
||||
refreshSelectedProfileButton()
|
||||
}
|
||||
renderDetailPanel(profile)
|
||||
await renderInstallView()
|
||||
if(typeof refreshLibraryView === 'function'){
|
||||
await refreshLibraryView()
|
||||
}
|
||||
const bodyGroup = document.createElement('div')
|
||||
bodyGroup.className = 'launcherFieldGroup'
|
||||
|
||||
const bodyLabel = document.createElement('label')
|
||||
bodyLabel.className = 'launcherFieldLabel'
|
||||
bodyLabel.textContent = '자세한 내용'
|
||||
|
||||
const body = document.createElement('div')
|
||||
body.className = 'launcherDetailBody'
|
||||
body.textContent = buildDetailText(profile)
|
||||
|
||||
bodyGroup.appendChild(bodyLabel)
|
||||
bodyGroup.appendChild(body)
|
||||
|
||||
const actions = document.createElement('div')
|
||||
actions.className = 'launcherCardActions'
|
||||
|
||||
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} 프로필을 라이브러리에 추가했습니다.`)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
const message = error instanceof Error ? error.message : '프로필 설치 중 오류가 발생했습니다.'
|
||||
showInstallMessage('설치 실패', message)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function renderEmptyDetailPanel(){
|
||||
installDetailTitle.textContent = '프로필을 선택하세요'
|
||||
installDetailSummary.textContent = '아래 목록에서 모드팩, 맵, 서버팩을 고르면 자세한 설명과 설치 조건을 볼 수 있습니다.'
|
||||
installDetailMeta.innerHTML = ''
|
||||
installDetailInfo.innerHTML = ''
|
||||
installDetailBody.textContent = '관리자가 등록한 프로필 상세 설명이 여기에 표시됩니다.'
|
||||
installDetailAddButton.disabled = true
|
||||
installDetailAddButton.textContent = '라이브러리에 추가'
|
||||
installDetailAddButton.onclick = null
|
||||
}
|
||||
const openLibraryButton = document.createElement('button')
|
||||
openLibraryButton.className = 'launcherSecondaryButton'
|
||||
openLibraryButton.textContent = '라이브러리 열기'
|
||||
openLibraryButton.addEventListener('click', async (event) => {
|
||||
event.stopPropagation()
|
||||
if(typeof refreshLibraryView === 'function'){
|
||||
await refreshLibraryView()
|
||||
}
|
||||
switchView(getCurrentView(), VIEWS.library)
|
||||
})
|
||||
|
||||
function selectProfile(profileId){
|
||||
selectedProfileId = profileId
|
||||
if(latestCatalog == null){
|
||||
renderEmptyDetailPanel()
|
||||
return
|
||||
}
|
||||
actions.appendChild(installButton)
|
||||
actions.appendChild(openLibraryButton)
|
||||
|
||||
const profile = latestCatalog.profiles.find((entry) => entry.id === profileId)
|
||||
if(profile == null){
|
||||
renderEmptyDetailPanel()
|
||||
return
|
||||
}
|
||||
detailSection.appendChild(badgeRow)
|
||||
detailSection.appendChild(infoBlock)
|
||||
detailSection.appendChild(bodyGroup)
|
||||
detailSection.appendChild(actions)
|
||||
|
||||
renderDetailPanel(profile)
|
||||
return detailSection
|
||||
}
|
||||
|
||||
async function renderInstallView(){
|
||||
@@ -173,11 +191,14 @@ async function renderInstallView(){
|
||||
|
||||
try {
|
||||
const catalog = await CatalogManager.loadCatalog()
|
||||
latestCatalog = catalog
|
||||
const installedIds = new Set(
|
||||
ConfigManager.getInstalledLibraryProfiles().map((profile) => profile.id)
|
||||
)
|
||||
|
||||
if(expandedProfileId != null && !catalog.profiles.some((profile) => profile.id === expandedProfileId)){
|
||||
expandedProfileId = null
|
||||
}
|
||||
|
||||
if(catalog.sourceError != null){
|
||||
const warningCard = document.createElement('article')
|
||||
warningCard.className = 'launcherCard'
|
||||
@@ -186,12 +207,18 @@ async function renderInstallView(){
|
||||
}
|
||||
|
||||
for(const profile of catalog.profiles){
|
||||
const installed = installedIds.has(profile.id)
|
||||
const expanded = expandedProfileId === profile.id
|
||||
|
||||
const row = document.createElement('article')
|
||||
row.className = 'launcherListItem'
|
||||
if(profile.id === selectedProfileId){
|
||||
if(expanded){
|
||||
row.setAttribute('selected', 'true')
|
||||
}
|
||||
|
||||
const top = document.createElement('div')
|
||||
top.className = 'launcherListItemTop'
|
||||
|
||||
const main = document.createElement('div')
|
||||
main.className = 'launcherListItemMain'
|
||||
|
||||
@@ -208,15 +235,13 @@ async function renderInstallView(){
|
||||
const meta = document.createElement('div')
|
||||
meta.className = 'launcherListMeta'
|
||||
meta.appendChild(createInstallBadge(describeProfileKind(profile.kind)))
|
||||
if(installedIds.has(profile.id)){
|
||||
if(installed){
|
||||
meta.appendChild(createInstallBadge('설치됨'))
|
||||
}
|
||||
if(profile.kind === 'server-pack' && profile.hostReady){
|
||||
meta.appendChild(createInstallBadge('호스팅 가능'))
|
||||
}
|
||||
|
||||
textGroup.appendChild(title)
|
||||
|
||||
const description = document.createElement('p')
|
||||
description.className = 'launcherListDescription'
|
||||
description.textContent = profile.description || '설명이 없습니다.'
|
||||
@@ -226,36 +251,23 @@ async function renderInstallView(){
|
||||
|
||||
const detailButton = document.createElement('button')
|
||||
detailButton.className = 'launcherSecondaryButton'
|
||||
detailButton.textContent = '자세히 보기'
|
||||
detailButton.textContent = expanded ? '간단히 보기' : '자세히 보기'
|
||||
detailButton.addEventListener('click', async (event) => {
|
||||
event.stopPropagation()
|
||||
selectProfile(profile.id)
|
||||
toggleExpandedProfile(profile.id)
|
||||
await renderInstallView()
|
||||
})
|
||||
|
||||
const installButton = document.createElement('button')
|
||||
installButton.className = 'launcherPrimaryButton'
|
||||
installButton.textContent = installedIds.has(profile.id) ? '설치됨' : '라이브러리에 추가'
|
||||
installButton.disabled = installedIds.has(profile.id) || !profile.launchReady
|
||||
installButton.textContent = installed ? '설치됨' : '라이브러리에 추가'
|
||||
installButton.disabled = installed || !profile.launchReady
|
||||
installButton.addEventListener('click', async (event) => {
|
||||
event.stopPropagation()
|
||||
try {
|
||||
const installedProfile = await CatalogManager.installProfile(profile.id)
|
||||
await ProfileAssetManager.prefetchProfileAssets(installedProfile)
|
||||
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 installProfile(profile)
|
||||
expandedProfileId = profile.id
|
||||
await renderInstallView()
|
||||
if(typeof refreshLibraryView === 'function'){
|
||||
await refreshLibraryView()
|
||||
}
|
||||
showInstallMessage('추가 완료', `${profile.name} 프로필을 라이브러리에 추가했습니다.`)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
@@ -264,37 +276,39 @@ async function renderInstallView(){
|
||||
}
|
||||
})
|
||||
|
||||
actions.appendChild(detailButton)
|
||||
actions.appendChild(installButton)
|
||||
|
||||
textGroup.appendChild(title)
|
||||
titleRow.appendChild(textGroup)
|
||||
titleRow.appendChild(meta)
|
||||
main.appendChild(titleRow)
|
||||
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 () => {
|
||||
selectProfile(profile.id)
|
||||
toggleExpandedProfile(profile.id)
|
||||
await renderInstallView()
|
||||
})
|
||||
|
||||
installCatalogList.appendChild(row)
|
||||
}
|
||||
|
||||
if(catalog.profiles.length === 0){
|
||||
renderEmptyDetailPanel()
|
||||
return
|
||||
const emptyCard = document.createElement('article')
|
||||
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) {
|
||||
console.error(error)
|
||||
latestCatalog = null
|
||||
renderEmptyDetailPanel()
|
||||
|
||||
const errorCard = document.createElement('article')
|
||||
errorCard.className = 'launcherCard'
|
||||
@@ -307,14 +321,6 @@ document.getElementById('installBackButton').addEventListener('click', () => {
|
||||
switchView(getCurrentView(), VIEWS.landing)
|
||||
})
|
||||
|
||||
document.getElementById('installDetailOpenLibraryButton').addEventListener('click', async () => {
|
||||
if(typeof refreshLibraryView === 'function'){
|
||||
await refreshLibraryView()
|
||||
}
|
||||
switchView(getCurrentView(), VIEWS.library)
|
||||
})
|
||||
|
||||
window.refreshInstallView = renderInstallView
|
||||
renderEmptyDetailPanel()
|
||||
renderInstallView()
|
||||
})()
|
||||
|
||||
@@ -35,6 +35,69 @@ remote.getCurrentWebContents().on('devtools-opened', () => {
|
||||
webFrame.setZoomLevel(0)
|
||||
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.
|
||||
let updateCheckListener
|
||||
if(!isDev){
|
||||
@@ -174,20 +237,10 @@ document.addEventListener('readystatechange', function () {
|
||||
})
|
||||
|
||||
} else if(document.readyState === 'complete'){
|
||||
|
||||
//266.01
|
||||
//170.8
|
||||
//53.21
|
||||
// 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
|
||||
|
||||
queueResponsiveLayout()
|
||||
setTimeout(() => {
|
||||
queueResponsiveLayout()
|
||||
}, 150)
|
||||
}
|
||||
|
||||
}, false)
|
||||
@@ -210,4 +263,4 @@ document.addEventListener('keydown', function (e) {
|
||||
let window = remote.getCurrentWindow()
|
||||
window.toggleDevTools()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user