Initial curated chimera source from a8ae5b1db07fb49926c94585e2718e5130330974
This commit is contained in:
commit
c737a37f71
531 files changed
+119270
No files matched your search
@@ -0,0 +1,77 @@
|
||||
(function installDestinationSelector() {
|
||||
'use strict';
|
||||
|
||||
let options = [];
|
||||
let requiredBytes = 0;
|
||||
|
||||
const esc = value => String(value == null ? '' : value).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
||||
const bytes = value => value == null ? 'unknown' : value >= 1024 ** 3 ? `${(value / 1024 ** 3).toFixed(1)} GB` : value >= 1024 ** 2 ? `${(value / 1024 ** 2).toFixed(1)} MB` : `${Math.max(0, value)} B`;
|
||||
const age = value => value == null ? 'unknown age' : value < 60_000 ? 'just now' : value < 3_600_000 ? `${Math.ceil(value / 60_000)} min old` : `${Math.ceil(value / 3_600_000)} h old`;
|
||||
const reason = code => ({
|
||||
'offline-volume': 'offline',
|
||||
'install-capability-disabled': 'install disabled by adapter',
|
||||
'missing-mountpoint': 'mountpoint unavailable',
|
||||
'capacity-unknown': 'capacity unknown',
|
||||
'insufficient-capacity': 'not enough free space',
|
||||
'stale-capacity-telemetry': 'capacity telemetry stale',
|
||||
'stale-capability-telemetry': 'capability telemetry stale',
|
||||
'compatibility-incompatible': 'blocked by applicable compatibility evidence',
|
||||
}[code] || code);
|
||||
|
||||
function selected() {
|
||||
const select = document.getElementById('install-destination-volume');
|
||||
return options.find(item => item.volumeId === select?.value) || null;
|
||||
}
|
||||
|
||||
function expertOpen() {
|
||||
return document.getElementById('install-expert-destination')?.open === true;
|
||||
}
|
||||
|
||||
function renderStatus() {
|
||||
const status = document.getElementById('install-destination-status');
|
||||
const option = selected();
|
||||
if (!status) return;
|
||||
if (option) {
|
||||
status.className = `install-destination-status ${option.eligible ? 'is-eligible' : 'is-ineligible'}`;
|
||||
status.innerHTML = `<strong>${esc(option.eligible ? 'Eligible destination' : 'Destination unavailable')}</strong><span>Required ${esc(bytes(requiredBytes))} · free ${esc(bytes(option.freeBytes))} · projected ${esc(bytes(option.projectedFreeBytes))} · evidence ${esc(age(option.capacityAgeMs))}${option.reasons.length ? ` · ${esc(option.reasons.map(reason).join(', '))}` : ''}</span>`;
|
||||
const raw = document.getElementById('install-ftp-path');
|
||||
if (option.compatibility) status.insertAdjacentHTML('beforeend', window.chimeraCompatibilityGuidance?.markup?.(option.compatibility) || '');
|
||||
if (raw && option.suggestedRemotePath) raw.value = option.suggestedRemotePath;
|
||||
} else {
|
||||
status.className = 'install-destination-status is-ineligible';
|
||||
status.innerHTML = '<strong>No eligible semantic destination</strong><span>Refresh console storage evidence or use the Expert raw-path override.</span>';
|
||||
}
|
||||
if (typeof updateInstallConfirmState === 'function') updateInstallConfirmState('pfs');
|
||||
}
|
||||
|
||||
async function load({ titleId, required = 0, legacyPath = '' } = {}) {
|
||||
requiredBytes = Math.max(0, Number(required) || 0);
|
||||
const packet = await window.pork.installDestinations({ titleId, requiredBytes });
|
||||
options = Array.isArray(packet?.destinations) ? packet.destinations : [];
|
||||
const select = document.getElementById('install-destination-volume');
|
||||
const raw = document.getElementById('install-ftp-path');
|
||||
if (raw) raw.value = legacyPath || '';
|
||||
if (!select) return packet;
|
||||
select.innerHTML = '<option value="">Select a destination volume</option>' + options.map(option => {
|
||||
const suffix = option.eligible ? `${bytes(option.freeBytes)} free` : option.reasons.map(reason).join(', ');
|
||||
return `<option value="${esc(option.volumeId)}"${option.eligible ? '' : ' disabled'}>${esc(option.deviceName)} · ${esc(option.volumeKey)} · ${esc(suffix)}</option>`;
|
||||
}).join('');
|
||||
const preferred = options.find(option => option.eligible);
|
||||
select.value = preferred?.volumeId || '';
|
||||
renderStatus();
|
||||
return packet;
|
||||
}
|
||||
|
||||
function selection() {
|
||||
const option = selected();
|
||||
if (option?.eligible) return { destinationVolumeId: option.volumeId, remotePath: option.suggestedRemotePath, expertRawPath: false };
|
||||
const raw = document.getElementById('install-ftp-path')?.value?.trim() || '';
|
||||
return expertOpen() && raw ? { destinationVolumeId: null, remotePath: raw, expertRawPath: true } : null;
|
||||
}
|
||||
|
||||
document.getElementById('install-destination-volume')?.addEventListener('change', renderStatus);
|
||||
document.getElementById('install-expert-destination')?.addEventListener('toggle', renderStatus);
|
||||
document.getElementById('install-ftp-path')?.addEventListener('input', renderStatus);
|
||||
|
||||
window.chimeraInstallDestination = Object.freeze({ load, selection, isReady: () => Boolean(selection()) });
|
||||
})();
|
||||
Reference in new issue
Block a user