// initUploadTable — сборка слоя 1 (выбор файлов/папки/архива). // Состояние (files/fileMeta/overNames) живёт внутри модуля. import { addFiles as addFilesToState, makeFilesChangeHandler } from './on_files_change.js'; import { makeFolderChangeHandler } from './on_folder_change.js'; import { render } from './render.js'; import { setStatus } from './set_status.js'; import { rmFile } from './rm_file.js'; // cfg: {allowedExt, maxFileBytes, maxSessionBytes, estMbSec} // els: {fileInput, folderInput, tableBody, countEl, uploadBtnEl, onStatus(cls, text)} // returns api (см. README.md) export function initUploadTable(cfg, els) { const state = { files: [], // File[] fileMeta: new Map(), // имя -> {size, mtime} для дедупа/суффиксов overNames: new Set(), // имена файлов сверх лимита (не участвуют) busy: false, // идёт загрузка/обработка — список заблокирован proc: null, // {phase, procState, procExtractRate} — задаёт слой 3 }; const onFilesChange = makeFilesChangeHandler({ state, cfg, els, onStatus: els.onStatus }); const onFolderChange = makeFolderChangeHandler({ state, cfg, els, onStatus: els.onStatus }); els.fileInput.addEventListener('change', onFilesChange); els.folderInput.addEventListener('change', onFolderChange); // Делегирование кликов по кнопкам «✕» (удалить строку) els.tableBody.addEventListener('click', e => { const btn = e.target.closest('.remove-btn'); if (btn) rmFile(state, els, cfg, Number(btn.dataset.idx)); }); return { state, // доступ для слоя 3 (установить state.proc для render) addFiles(files) { return addFilesToState(state, cfg, files, els, els.onStatus); }, getFiles() { // ТОЛЬКО учитываемые (без over): [{name, size, file}] return state.files.filter(f => !state.overNames.has(f.name)) .map(f => ({ name: f.name, size: f.size, file: f })); }, getOverNames() { return state.overNames; }, setStatus(idx, html) { setStatus(idx, html); }, render() { render(state, els, cfg); }, clear() { state.files = []; state.fileMeta = new Map(); state.overNames = new Set(); if (els.fileInput) els.fileInput.value = ''; render(state, els, cfg); }, setBusy(b) { state.busy = b; if (els.fileInput) els.fileInput.disabled = b; }, _rm(i) { rmFile(state, els, cfg, i); }, }; }