From 20677380b9f222c1a11c36b0ada309d461023f2d Mon Sep 17 00:00:00 2001 From: claude-bot Date: Wed, 6 May 2026 04:58:12 +0900 Subject: [PATCH] Fix launch cache sanitization and progress layout --- app/assets/css/launcher.css | 18 ++++++++++++++++ app/assets/js/distromanager.js | 35 ++++++++++++++++++++++++++++++++ app/assets/js/scripts/landing.js | 10 +++++++++ app/assets/js/scripts/uicore.js | 19 ++++++++++++++++- 4 files changed, 81 insertions(+), 1 deletion(-) diff --git a/app/assets/css/launcher.css b/app/assets/css/launcher.css index 68855e2..beeada8 100644 --- a/app/assets/css/launcher.css +++ b/app/assets/css/launcher.css @@ -2547,6 +2547,12 @@ input:checked + .toggleSwitchSlider:before { align-items: flex-end; justify-content: flex-end; } +#landingContainer > #lower > #right .bot_wrapper { + width: 100%; + display: flex; + flex-direction: column; + align-items: flex-end; +} /******************************************************************************* * * @@ -3554,6 +3560,8 @@ input:checked + .toggleSwitchSlider:before { top: 0; display: inline-flex; align-items: center; + justify-content: flex-end; + max-width: 100%; } /* The launch button. */ @@ -3589,11 +3597,18 @@ input:checked + .toggleSwitchSlider:before { position: relative; top: 12px; display: none; + align-items: center; + justify-content: flex-end; + width: 100%; + max-width: 100%; + overflow: hidden; } /* Left side of launch details container, displays percentage and a divider. */ #launch_details_left { display: flex; + align-items: center; + flex: 0 0 auto; } /* Span which displays percentage complete. */ @@ -3612,6 +3627,8 @@ input:checked + .toggleSwitchSlider:before { display: flex; flex-direction: column; justify-content: center; + min-width: 0; + overflow: hidden; } /* Button which opens the server selection view. */ @@ -3650,6 +3667,7 @@ input:checked + .toggleSwitchSlider:before { /* Span which displays information about the status of the launch process. */ #launch_details_text { + display: block; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; diff --git a/app/assets/js/distromanager.js b/app/assets/js/distromanager.js index 574d64d..3bd592c 100644 --- a/app/assets/js/distromanager.js +++ b/app/assets/js/distromanager.js @@ -7,6 +7,10 @@ const DEFAULT_REMOTE_DISTRO_URL = 'https://cdn.mysticred.space/launcher/distribu let remoteDistroUrl = DEFAULT_REMOTE_DISTRO_URL let activeApi = createApi(remoteDistroUrl) +function distributionsDiffer(left, right){ + return JSON.stringify(left) !== JSON.stringify(right) +} + function sanitizeServer(rawServer){ const nextServer = { ...rawServer @@ -51,6 +55,37 @@ function buildDistribution(api, rawDistribution){ } function patchDistributionApi(api){ + const originalPullRemote = api.pullRemote.bind(api) + const originalPullLocal = api.pullLocal.bind(api) + const originalWriteDistributionToDisk = api.writeDistributionToDisk.bind(api) + + api.writeDistributionToDisk = async function(distribution){ + const sanitizedDistribution = sanitizeDistribution(distribution) + await originalWriteDistributionToDisk(sanitizedDistribution) + } + + api.pullRemote = async function(){ + const response = await originalPullRemote() + if(response?.data != null){ + response.data = sanitizeDistribution(response.data) + } + return response + } + + api.pullLocal = async function(){ + const rawDistribution = await originalPullLocal() + if(rawDistribution == null){ + return rawDistribution + } + + const sanitizedDistribution = sanitizeDistribution(rawDistribution) + if(distributionsDiffer(rawDistribution, sanitizedDistribution)){ + await originalWriteDistributionToDisk(sanitizedDistribution) + } + + return sanitizedDistribution + } + api.getDistribution = async function(){ if(this.rawDistribution == null || this.distribution == null){ const rawDistribution = await this.loadDistribution() diff --git a/app/assets/js/scripts/landing.js b/app/assets/js/scripts/landing.js index 3e60981..74db9dd 100644 --- a/app/assets/js/scripts/landing.js +++ b/app/assets/js/scripts/landing.js @@ -125,6 +125,10 @@ async function logoutSelectedAccount(){ * @param {boolean} loading True if the loading area should be shown, otherwise false. */ function toggleLaunchArea(loading){ + if(typeof syncLaunchDetailWidths === 'function'){ + syncLaunchDetailWidths() + } + if(loading){ launch_details.style.display = 'flex' launch_content.style.display = 'none' @@ -132,6 +136,12 @@ function toggleLaunchArea(loading){ launch_details.style.display = 'none' launch_content.style.display = 'inline-flex' } + + window.requestAnimationFrame(() => { + if(typeof syncLaunchDetailWidths === 'function'){ + syncLaunchDetailWidths() + } + }) } /** diff --git a/app/assets/js/scripts/uicore.js b/app/assets/js/scripts/uicore.js index fd0f380..1c3a65f 100644 --- a/app/assets/js/scripts/uicore.js +++ b/app/assets/js/scripts/uicore.js @@ -41,6 +41,7 @@ const UI_SCALE_MULTIPLIER = 1.5 let responsiveLayoutFrame = null let lastAppliedZoomFactor = null +let lastLaunchContentWidth = 0 function clamp(value, min, max){ return Math.min(Math.max(value, min), max) @@ -58,19 +59,35 @@ function syncLaunchDetailWidths(){ return } - const launchContentWidth = launchContent.getBoundingClientRect().width + const measuredLaunchContentWidth = Math.ceil(launchContent.getBoundingClientRect().width) + if(measuredLaunchContentWidth > 0){ + lastLaunchContentWidth = measuredLaunchContentWidth + } + + const launchContentWidth = lastLaunchContentWidth > 0 + ? lastLaunchContentWidth + : Math.ceil(launchDetails.parentElement?.getBoundingClientRect().width ?? 0) + + if(launchContentWidth <= 0){ + return + } + 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.width = `${Math.ceil(launchContentWidth)}px` launchDetails.style.maxWidth = `${Math.ceil(launchContentWidth)}px` launchProgress.style.width = `${progressWidth}px` + launchDetailsRight.style.width = `${progressWidth}px` launchDetailsRight.style.maxWidth = `${progressWidth}px` launchProgressLabel.style.width = `${labelWidth}px` launchProgressLabel.style.minWidth = `${labelWidth}px` launchProgressLabel.style.maxWidth = `${labelWidth}px` } +window.syncLaunchDetailWidths = syncLaunchDetailWidths + function applyResponsiveLayout(){ const currentWindow = remote.getCurrentWindow() const contentBounds = currentWindow.getContentBounds()