// SPDX-FileCopyrightText: 2021 Luke Granger-Brown // // SPDX-License-Identifier: Apache-2.0 document.body.classList.add('has-js'); if (document.body.classList.contains('upload-page')) { const uploadListEl = document.body.querySelector('.upload-list'); const inputFileEl = document.body.querySelector('#file'); const expiryEl = document.body.querySelector('#expiry'); const uploadFile = (file, expiry) => { const progressEl = document.createElement('li'); progressEl.classList.add('upload-list-element'); uploadListEl.appendChild(progressEl); const bgEl = document.createElement('div'); bgEl.classList.add('upload-list-background'); progressEl.appendChild(bgEl); const bgFilenameEl = document.createElement('span'); bgFilenameEl.classList.add('upload-list-filename'); bgFilenameEl.textContent = file.name; bgEl.appendChild(bgFilenameEl); const bgSpacerNode = document.createTextNode(' '); bgEl.appendChild(bgSpacerNode); const bgPercentEl = document.createElement('span'); bgPercentEl.classList.add('upload-list-progress'); bgPercentEl.textContent = file.size == 0 ? '(unknown)' : '(0%)'; bgEl.appendChild(bgPercentEl); const barEl = document.createElement('div'); barEl.classList.add('upload-list-bar'); progressEl.appendChild(barEl); const barContainerEl = document.createElement('div'); barContainerEl.classList.add('upload-list-bar-container'); barEl.appendChild(barContainerEl); const barFilenameEl = document.createElement('span'); barFilenameEl.classList.add('upload-list-filename'); barFilenameEl.textContent = file.name; barContainerEl.appendChild(barFilenameEl); const barSpacerNode = document.createTextNode(' '); barContainerEl.appendChild(barSpacerNode); const barPercentEl = document.createElement('span'); barPercentEl.classList.add('upload-list-progress'); barPercentEl.textContent = file.size == 0 ? '(unknown)' : '(0%)'; barContainerEl.appendChild(barPercentEl); const setPercentText = (txt) => { barPercentEl.textContent = txt; bgPercentEl.textContent = txt; }; const setPercentPercent = (loaded, total) => { const pct = Math.floor((loaded * 1000) / total) / 10; setPercentText(`(${pct}%)`); barEl.style.width = `${pct}%`; }; const hdrs = new Headers(); hdrs.set('Content-Type', file.type); hdrs.set('Accept', 'application/json'); const xhr = new XMLHttpRequest(); xhr.upload.addEventListener('progress', (ev) => { if (!ev.lengthComputable) { setPercentText(`(unknown: ${ev.loaded} bytes)`); } else { setPercentPercent(ev.loaded, ev.total); } }); xhr.upload.addEventListener('load', (ev) => { setPercentPercent(1, 1); }); xhr.addEventListener('error', (ev) => { setPercentText(`(error: ${ev.message})`); }); xhr.addEventListener('abort', (ev) => { setPercentText(`(aborted)`); }); xhr.addEventListener('load', (ev) => { if (ev.status < 200 || ev.status >= 300) { setPercentText(`(error: HTTP status ${ev.status} - ${ev.message})`); return; } const respJSON = xhr.response; while (progressEl.firstChild) { progressEl.removeChild(progressEl.firstChild); } progressEl.classList.add('uploaded'); const linkEl = document.createElement('a'); linkEl.setAttribute('href', respJSON.display_url); linkEl.textContent = file.name; progressEl.appendChild(linkEl); }); xhr.responseType = 'json'; xhr.open('PUT', `/upload/${encodeURIComponent(file.name)}`); xhr.setRequestHeader('Content-Type', file.type); xhr.setRequestHeader('Accept', 'application/json'); if (expiry !== "") { xhr.setRequestHeader('Fup-Expiry', expiry); } xhr.send(file); }; inputFileEl.addEventListener('change', (ev) => { for (let i = 0; i < inputFileEl.files.length; i++) { const file = inputFileEl.files[i]; uploadFile(file, expiryEl.value); } inputFileEl.value = null; }); document.body.addEventListener('dragenter', (e) => { e.preventDefault(); e.stopPropagation(); document.body.classList.add('dragging-over'); }, false); document.body.addEventListener('dragover', (e) => { e.preventDefault(); e.stopPropagation(); document.body.classList.add('dragging-over'); }, false); document.body.addEventListener('dragleave', (e) => { e.preventDefault(); e.stopPropagation(); document.body.classList.remove('dragging-over'); }, false); document.body.addEventListener('drop', (e) => { e.preventDefault(); e.stopPropagation(); document.body.classList.remove('dragging-over'); const dt = e.dataTransfer; const files = dt.files; for (const f of files) { uploadFile(f, expiryEl.value); } }, false); document.body.addEventListener('paste', (e) => { e.preventDefault(); const clipboardData = e.clipboardData || window.clipboardData; for (const item of clipboardData.items) { if (item.kind === 'file') { uploadFile(item.getAsFile(), expiryEl.value); } else if (item.kind === 'string') { item.getAsString((data) => { // This is a hack, we should do something... more sensible. const uploadData = new Blob([data], { type: 'text/plain' }); uploadData.name = 'clipboard.txt'; uploadFile(uploadData, expiryEl.value); }); } } }); }