// 设备检测函数 function detectDevice() { const userAgent = navigator.userAgent.toLowerCase(); const platform = navigator.platform.toLowerCase(); // 检测移动设备 const isMobile = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/.test(userAgent); // 检测平板设备 const isTablet = /ipad|android(?!.*mobile)/.test(userAgent) || (platform === 'macintel' && navigator.maxTouchPoints > 1); // 检测桌面设备 const isDesktop = !isMobile && !isTablet; // 添加设备类到body document.body.className = ''; if (isMobile) { document.body.classList.add('device-mobile'); } else if (isTablet) { document.body.classList.add('device-tablet'); } else { document.body.classList.add('device-desktop'); } } // 页面加载时检测设备 detectDevice(); // 窗口大小改变时重新检测设备 window.addEventListener('resize', detectDevice); // 页面加载完成后执行 document.addEventListener('DOMContentLoaded', function() { // 获取所有需要操作的DOM元素 const dropZone = document.getElementById('dropZone'); // 拖放区域 const fileInput = document.getElementById('fileInput'); // 文件输入框 const selectFilesBtn = document.getElementById('selectFilesBtn'); // 选择文件按钮 const fileList = document.getElementById('fileList'); // 文件列表容器 const processBtn = document.getElementById('processBtn'); // 处理按钮 const downloadBtn = document.getElementById('downloadBtn'); // 下载按钮 const downloadArea = document.getElementById('downloadArea'); // 下载区域 const progressArea = document.getElementById('progressArea'); // 进度区域 const progressFill = document.getElementById('progressFill'); // 进度条填充 const progressText = document.getElementById('progressText'); // 进度文本 const statusMessage = document.getElementById('statusMessage'); // 状态消息 const configCard = document.querySelector('.config-card'); // 配置卡片 // 初始化工具类 const fileProcessor = new FileProcessor(); const progressManager = new ProgressManager(progressFill, progressText, statusMessage); // 绑定事件监听器 selectFilesBtn.addEventListener('click', () => fileInput.click()); // 点击按钮触发文件选择 fileInput.addEventListener('change', handleFileSelect); // 文件选择改变时处理 // 为拖放区域绑定拖拽事件,阻止默认行为 ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { dropZone.addEventListener(eventName, preventDefaults, false); }); // 添加拖拽视觉反馈事件 dropZone.addEventListener('dragenter', () => { dropZone.classList.add('drag-over'); }); dropZone.addEventListener('dragover', () => { dropZone.classList.add('drag-over'); }); dropZone.addEventListener('dragleave', () => { dropZone.classList.remove('drag-over'); }); dropZone.addEventListener('drop', () => { dropZone.classList.remove('drag-over'); }); if (configCard) { setTimeout(() => configCard.classList.add('animated'), 700); } // 阻止拖拽事件的默认行为 function preventDefaults(e) { e.preventDefault(); // 阻止默认的拖拽行为 e.stopPropagation(); // 阻止事件冒泡 } // 监听拖放事件 dropZone.addEventListener('drop', handleDrop, false); // 处理拖放的文件 function handleDrop(e) { const files = e.dataTransfer.files; // 获取拖放的文件列表 handleFiles(files,this); // 调用文件处理函数 } // 处理通过文件选择对话框选择的文件 function handleFileSelect(e) { const files = e.target.files; // 获取选择的文件列表 handleFiles(files,this); // 调用文件处理函数 } // 格式化文件大小显示 function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; // 单位换算基数 const sizes = ['Bytes', 'KB', 'MB', 'GB']; // 单位数组 const i = Math.floor(Math.log(bytes) / Math.log(k)); // 计算单位级别 // 返回格式化后的大小字符串 return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } // 统一处理文件(去重并显示) /** * @param {FileList} files * */ async function handleFiles(files,inputer) { for (let i = 0; i < files.length; i++) { const file = files.item(i); try { const added = await fileProcessor.addFile(file); if (added) { renderFileItem(file); // 渲染文件显示项 progressManager.showStatus(t('STATUS_FILE_ADDED', {name: file.name}), 'green'); } else { progressManager.showStatus(t('STATUS_FILE_EXISTS', {name: file.name}), 'orange'); } } catch (error) { progressManager.showStatus(t('STATUS_FILE_ERROR', {name: file.name, error: error.message}), 'red'); } } inputer.value="" } // 渲染单个文件项到列表中 function renderFileItem(file) { // 计算文件哈希值用于删除操作 computeFileHash(file).then(hash => { const fileItem = document.createElement('div'); fileItem.className = 'file-item'; // 检查文件类型并添加相应标识 const fileName = file.name.toLowerCase(); let fileTypeBadge = ''; if (fileName.endsWith('.mcstructure')) { fileTypeBadge = 'MCSTRUCTURE'; } else if (fileName.endsWith('.nbt')) { fileTypeBadge = 'NBT→MCSTRUCTURE'; } else if (fileName.endsWith('.litematic')) { fileTypeBadge = 'LITEMATIC→MCSTRUCTURE'; } fileItem.innerHTML = `