(function () { function qs(id) { return document.getElementById(id); } function humanSize(bytes) { if (!bytes && bytes !== 0) return ''; var units = ['B', 'KB', 'MB', 'GB']; var i = 0; var n = bytes; while (n >= 1024 && i < units.length - 1) { n /= 1024; i++; } return (Math.round(n * 10) / 10) + ' ' + units[i]; } function buildThumbLi(filename) { var imgUrl = 'img/' + encodeURIComponent(filename); var title = filename; return ( "
  • " + " " + " " + title + "" + " " + "
    " + "
  • " ); } function setStatus(text) { var el = qs('upload-status'); if (el) el.textContent = text || ''; } function init() { var dropzone = qs('dropzone'); var fileInput = qs('file-input'); var previewWrap = qs('upload-preview'); var previewImg = qs('preview-img'); var previewMeta = qs('preview-meta'); var uploadBtn = qs('upload-btn'); if (!dropzone || !fileInput || !uploadBtn) return; var selectedFile = null; function showPreview(file) { selectedFile = file; uploadBtn.disabled = !file; setStatus(''); if (!file) { if (previewWrap) previewWrap.style.display = 'none'; return; } if (previewWrap) previewWrap.style.display = 'block'; if (previewMeta) previewMeta.textContent = file.name + ' · ' + humanSize(file.size); var reader = new FileReader(); reader.onload = function (e) { if (previewImg) previewImg.src = e.target.result; }; reader.readAsDataURL(file); } function isImageFile(file) { return file && file.type && file.type.indexOf('image/') === 0; } function onFiles(files) { if (!files || !files.length) return; var f = files[0]; if (!isImageFile(f)) { setStatus('이미지 파일만 업로드 가능합니다.'); return; } showPreview(f); } dropzone.addEventListener('dragover', function (e) { e.preventDefault(); dropzone.classList.add('dragover'); }); dropzone.addEventListener('dragleave', function () { dropzone.classList.remove('dragover'); }); dropzone.addEventListener('drop', function (e) { e.preventDefault(); dropzone.classList.remove('dragover'); onFiles(e.dataTransfer.files); }); fileInput.addEventListener('change', function () { onFiles(fileInput.files); }); uploadBtn.addEventListener('click', function () { if (!selectedFile) return; uploadBtn.disabled = true; setStatus('업로드 중...'); var fd = new FormData(); fd.append('image', selectedFile); fetch('api/upload_image.php', { method: 'POST', body: fd, credentials: 'same-origin' }) .then(function (r) { return r.json(); }) .then(function (data) { if (!data || !data.ok) { throw new Error((data && data.error) ? data.error : '업로드 실패'); } // Add immediately to current gallery var filename = data.filename; if (window.dreamgirlGallery && typeof window.dreamgirlGallery.appendImage === 'function') { window.dreamgirlGallery.appendImage(buildThumbLi(filename)); } else { // fallback: append to DOM var ul = document.querySelector('#thumbs ul.thumbs'); if (ul) ul.insertAdjacentHTML('beforeend', buildThumbLi(filename)); } // keep in-memory list (doesn't persist; list_images.php handles persistence) if (window.DREAMGIRL_IMAGES && window.DREAMGIRL_IMAGES.push) { window.DREAMGIRL_IMAGES.push(filename); } setStatus('업로드 완료: ' + filename); // reset selectedFile = null; if (fileInput) fileInput.value = ''; if (previewWrap) previewWrap.style.display = 'none'; }) .catch(function (err) { setStatus('에러: ' + (err && err.message ? err.message : '업로드 실패')); }) .finally(function () { uploadBtn.disabled = false; }); }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();