Refactor: Move DOM/UI helpers

This commit is contained in:
2026-03-20 22:57:37 -07:00
parent bf8661190a
commit b076bd66e6

83
src/app/dom.js Normal file
View File

@@ -0,0 +1,83 @@
export const ELEMENT_IDS = [
'setup-screen', 'main-screen', 'setup-key', 'setup-save',
'btn-settings', 'modal-settings', 'modal-key', 'modal-save', 'btn-close-modal',
'sel-model', 'inp-prompt', 'inp-frames', 'inp-fps', 'sel-size', 'sel-ratio',
'btn-generate', 'progress-area', 'progress-bar', 'progress-text', 'frames-preview',
'result-area', 'result-gif', 'btn-download'
];
const camelize = (id) => id.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
export function grabElements(ids = ELEMENT_IDS) {
const el = {};
for (const id of ids) {
const key = camelize(id);
el[key] = document.getElementById(id);
if (!el[key]) console.warn(`vibegif: missing element #${id}`);
}
return el;
}
export function show(node) {
if (!node) return;
node.classList.remove('hidden');
node.style.display = '';
}
export function hide(node) {
if (!node) return;
node.classList.add('hidden');
node.style.display = '';
}
export function setProgress(el, pct, text) {
show(el.progressArea);
if (el.progressBar) el.progressBar.style.width = `${Math.max(0, Math.min(100, pct))}%`;
if (el.progressText) el.progressText.textContent = text || '';
}
export function resetProgress(el) {
hide(el.progressArea);
if (el.progressBar) el.progressBar.style.width = '0%';
if (el.progressText) el.progressText.textContent = '';
if (el.framesPreview) el.framesPreview.innerHTML = '';
}
export function addFramePreview(el, src, index) {
if (!el.framesPreview) return;
const img = document.createElement('img');
img.src = src;
img.className = 'w-16 h-16 rounded-lg border border-neutral-200 object-cover';
img.title = `frame ${index + 1}`;
el.framesPreview.appendChild(img);
}
export function showResult(el, blobUrl) {
if (el.resultArea) {
el.resultArea.classList.remove('hidden');
el.resultArea.style.display = 'flex';
}
if (el.resultGif) el.resultGif.src = blobUrl;
if (el.btnDownload) el.btnDownload.href = blobUrl;
}
export function hideResult(el) {
if (!el.resultArea) return;
el.resultArea.classList.add('hidden');
el.resultArea.style.display = '';
}
export function setGenerating(el, active) {
if (!el.btnGenerate) return;
el.btnGenerate.disabled = !!active;
el.btnGenerate.style.opacity = active ? '0.5' : '1';
el.btnGenerate.style.cursor = active ? 'not-allowed' : 'pointer';
}
export function syncSizeByModel(el) {
if (!el.selModel || !el.selSize) return;
const isGemini = el.selModel.value.startsWith('google/');
const opt05 = el.selSize.querySelector('option[value="0.5K"]');
if (opt05) opt05.disabled = !isGemini;
if (!isGemini && el.selSize.value === '0.5K') el.selSize.value = '1K';
}