Minor fixes
This commit is contained in:
@@ -240,6 +240,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Capacity Warning -->
|
||||
<div class="form-text text-danger d-none" id="capacityWarning">
|
||||
<i class="bi bi-exclamation-triangle-fill me-1"></i><span id="capacityWarningText"></span>
|
||||
</div>
|
||||
|
||||
<!-- Mode & Carrier Type toggles (aligned row) -->
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
@@ -541,6 +546,82 @@ const audioModeGroup = document.getElementById('audioModeGroup');
|
||||
const capacityPanel = document.getElementById('capacityPanel');
|
||||
const audioCapacityPanel = document.getElementById('audioCapacityPanel');
|
||||
|
||||
// Capacity tracking for client-side payload size validation
|
||||
let capacityBytes = { dct: 0, lsb: 0, audio_lsb: 0, audio_spread: 0 };
|
||||
|
||||
function checkCapacity() {
|
||||
const warning = document.getElementById('capacityWarning');
|
||||
const warningText = document.getElementById('capacityWarningText');
|
||||
const encodeBtn = document.getElementById('encodeBtn');
|
||||
if (!warning || !warningText || !encodeBtn) return;
|
||||
|
||||
// Determine payload size
|
||||
const isText = document.getElementById('payloadText')?.checked;
|
||||
let payloadSize = 0;
|
||||
if (isText) {
|
||||
const msg = document.getElementById('messageInput')?.value || '';
|
||||
if (msg) payloadSize = new Blob([msg]).size;
|
||||
} else {
|
||||
const file = document.getElementById('payloadFileInput')?.files[0];
|
||||
if (file) payloadSize = file.size;
|
||||
}
|
||||
|
||||
// Get active mode
|
||||
const mode = document.querySelector('input[name="embed_mode"]:checked')?.value || 'lsb';
|
||||
const cap = capacityBytes[mode] || 0;
|
||||
|
||||
// Update char percent to use real capacity
|
||||
if (isText) {
|
||||
const charPercent = document.getElementById('charPercent');
|
||||
if (charPercent) {
|
||||
const effectiveCap = cap > 0 ? cap : 250000;
|
||||
charPercent.textContent = Math.round((payloadSize / effectiveCap) * 100) + '%';
|
||||
}
|
||||
}
|
||||
|
||||
// Reset badge colors
|
||||
const badgeMap = {
|
||||
dct: 'dctCapacityBadge',
|
||||
lsb: 'lsbCapacityBadge',
|
||||
audio_lsb: 'lsbAudioCapacityBadge',
|
||||
audio_spread: 'spreadCapacityBadge'
|
||||
};
|
||||
|
||||
// Restore default badge colors
|
||||
const dctBadge = document.getElementById('dctCapacityBadge');
|
||||
const lsbBadge = document.getElementById('lsbCapacityBadge');
|
||||
const audioLsbBadge = document.getElementById('lsbAudioCapacityBadge');
|
||||
const spreadBadge = document.getElementById('spreadCapacityBadge');
|
||||
if (dctBadge) { dctBadge.classList.remove('bg-danger'); dctBadge.classList.add('bg-warning'); }
|
||||
if (lsbBadge) { lsbBadge.classList.remove('bg-danger'); lsbBadge.classList.add('bg-primary'); }
|
||||
if (audioLsbBadge) { audioLsbBadge.classList.remove('bg-danger'); audioLsbBadge.classList.add('bg-primary'); }
|
||||
if (spreadBadge) { spreadBadge.classList.remove('bg-danger'); spreadBadge.classList.add('bg-warning'); }
|
||||
|
||||
// No carrier or no payload — clear warning
|
||||
if (cap === 0 || payloadSize === 0) {
|
||||
warning.classList.add('d-none');
|
||||
encodeBtn.disabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (payloadSize > cap) {
|
||||
// Exceeds capacity — show warning, turn badge red, disable button
|
||||
const activeBadge = document.getElementById(badgeMap[mode]);
|
||||
if (activeBadge) {
|
||||
activeBadge.classList.remove('bg-primary', 'bg-warning');
|
||||
activeBadge.classList.add('bg-danger');
|
||||
}
|
||||
const needed = (payloadSize / 1024).toFixed(1);
|
||||
const available = (cap / 1024).toFixed(1);
|
||||
warningText.textContent = `Payload too large: ${needed} KB needed, only ${available} KB capacity in ${mode.replace('_', ' ').toUpperCase()} mode`;
|
||||
warning.classList.remove('d-none');
|
||||
encodeBtn.disabled = true;
|
||||
} else {
|
||||
warning.classList.add('d-none');
|
||||
encodeBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
carrierTypeRadios.forEach(radio => {
|
||||
radio.addEventListener('change', function() {
|
||||
const isAudio = this.value === 'audio';
|
||||
@@ -560,9 +641,17 @@ carrierTypeRadios.forEach(radio => {
|
||||
if (imageModeGroup) imageModeGroup.classList.toggle('d-none', isAudio);
|
||||
if (audioModeGroup) audioModeGroup.classList.toggle('d-none', !isAudio);
|
||||
|
||||
// Toggle capacity panels
|
||||
// Toggle capacity panels and reset capacity values
|
||||
if (capacityPanel) capacityPanel.classList.add('d-none');
|
||||
if (audioCapacityPanel) audioCapacityPanel.classList.add('d-none');
|
||||
if (isAudio) {
|
||||
capacityBytes.dct = 0;
|
||||
capacityBytes.lsb = 0;
|
||||
} else {
|
||||
capacityBytes.audio_lsb = 0;
|
||||
capacityBytes.audio_spread = 0;
|
||||
}
|
||||
checkCapacity();
|
||||
|
||||
// Select default mode for the active type and update hint
|
||||
if (isAudio) {
|
||||
@@ -621,7 +710,10 @@ audioCarrierInput?.addEventListener('change', function() {
|
||||
document.getElementById('audioInfo').textContent = info;
|
||||
document.getElementById('lsbAudioCapacityBadge').textContent = `LSB: ${(data.lsb_capacity / 1024).toFixed(1)} KB`;
|
||||
document.getElementById('spreadCapacityBadge').textContent = `Spread: ${(data.spread_capacity / 1024).toFixed(1)} KB`;
|
||||
capacityBytes.audio_lsb = data.lsb_capacity;
|
||||
capacityBytes.audio_spread = data.spread_capacity;
|
||||
document.getElementById('audioCapacityPanel')?.classList.remove('d-none');
|
||||
checkCapacity();
|
||||
if (data.duration) {
|
||||
document.getElementById('audioCarrierDuration').textContent = data.duration + 's duration';
|
||||
}
|
||||
@@ -763,6 +855,7 @@ function updatePayloadSection() {
|
||||
payloadFileInput.setAttribute('required', '');
|
||||
}
|
||||
updatePayloadSummary();
|
||||
checkCapacity();
|
||||
}
|
||||
|
||||
payloadTextRadio?.addEventListener('change', updatePayloadSection);
|
||||
@@ -786,6 +879,7 @@ payloadFileInput?.addEventListener('change', function() {
|
||||
} else {
|
||||
fileInfo?.classList.add('d-none');
|
||||
}
|
||||
checkCapacity();
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
@@ -795,7 +889,7 @@ payloadFileInput?.addEventListener('change', function() {
|
||||
messageInput?.addEventListener('input', function() {
|
||||
const count = this.value.length;
|
||||
document.getElementById('charCount').textContent = count.toLocaleString();
|
||||
document.getElementById('charPercent').textContent = Math.round((count / 250000) * 100) + '%';
|
||||
checkCapacity();
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
@@ -814,7 +908,10 @@ carrierInput?.addEventListener('change', function() {
|
||||
document.getElementById('carrierDimensions').textContent = `${data.width} x ${data.height}`;
|
||||
document.getElementById('lsbCapacityBadge').textContent = `LSB: ${data.lsb.capacity_kb} KB`;
|
||||
document.getElementById('dctCapacityBadge').textContent = `DCT: ${data.dct.capacity_kb} KB`;
|
||||
capacityBytes.lsb = Math.round(data.lsb.capacity_kb * 1024);
|
||||
capacityBytes.dct = Math.round(data.dct.capacity_kb * 1024);
|
||||
document.getElementById('capacityPanel')?.classList.remove('d-none');
|
||||
checkCapacity();
|
||||
}).catch(() => {});
|
||||
}
|
||||
});
|
||||
@@ -859,7 +956,7 @@ function updateOutputOptions(mode) {
|
||||
}
|
||||
|
||||
modeRadios.forEach(radio => {
|
||||
radio.addEventListener('change', () => updateOutputOptions(radio.value));
|
||||
radio.addEventListener('change', () => { updateOutputOptions(radio.value); checkCapacity(); });
|
||||
});
|
||||
|
||||
// Initialize output options based on initial mode
|
||||
|
||||
Reference in New Issue
Block a user