if (!window.mySocket) { const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; window.mySocket = new WebSocket(`${wsProtocol}//${window.location.host}/user`); window.mySocket.onopen = function(event) { console.log('WebSocket is open now.'); }; window.mySocket.onmessage = async function(event) { try { const data = JSON.parse(event.data); if (data.status === "error") { if (data.message === "File Is Different") { ChangeModal("Error", "A file with the same name already exists but has a different hash value. This may indicate that the file is different, despite having the same name. Please verify the file or consider renaming it before proceeding.") toggleModal(); } else { ChangeModal("Error", "There was an issue with your upload. Please try again later or contact support if the problem persists.") toggleModal(); } } else { if (data.action === "UploadNewFile") { if (data.response.Done === false) { const file = window.fileIdMap[data.responseID]; addNewUploadElement(file); const fileChunks = await splitFile(file, file.chunkSize); await uploadChunks(file.name, file.size, fileChunks, data.response.Chunk, data.response.ID); } else { ChangeModal("Error", "File already uploaded.") toggleModal(); } } } } catch (error) { console.error('Error parsing message data:', error); } }; window.mySocket.onerror = function(event) { console.error('WebSocket error observed:', event); }; window.mySocket.onclose = function(event) { console.log('WebSocket is closed now.'); }; } function generateUniqueId() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } async function handleFile(file){ const chunkSize = 2 * 1024 * 1024; const chunks = Math.ceil(file.size / chunkSize); const fileId = generateUniqueId(); const startChunk = await file.slice(0, chunkSize).arrayBuffer(); const endChunk = await file.slice((chunks-1) * chunkSize, file.size).arrayBuffer(); const startChunkHash = await hash(startChunk) const endChunkHash = await hash(endChunk) const data = JSON.stringify({ "action": "UploadNewFile", "name": file.name, "size": file.size, "chunk": chunks, "startHash": startChunkHash, "endHash": endChunkHash, "requestID": fileId, }); file.chunkSize = chunkSize; window.fileIdMap = window.fileIdMap || {}; window.fileIdMap[fileId] = file; window.mySocket.send(data) } function addNewUploadElement(file){ const newDiv = document.createElement('div'); newDiv.innerHTML = `
0%
${ file.name }
Starting...
`; document.getElementById('FileUploadBoxItem').appendChild(newDiv); document.getElementById('uploadBox').classList.remove('hidden'); } function convertFileSize(sizeInBytes) { if (sizeInBytes < 1024) { return sizeInBytes + ' B'; } else if (sizeInBytes < 1024 * 1024) { return (sizeInBytes / 1024).toFixed(2) + ' KB'; } else if (sizeInBytes < 1024 * 1024 * 1024) { return (sizeInBytes / (1024 * 1024)).toFixed(2) + ' MB'; } else { return (sizeInBytes / (1024 * 1024 * 1024)).toFixed(2) + ' GB'; } } async function splitFile(file, chunkSize) { const fileSize = file.size; const chunks = Math.ceil(fileSize / chunkSize); const fileChunks = []; for (let i = 0; i < chunks; i++) { const start = i * chunkSize; const end = Math.min(fileSize, start + chunkSize); const chunk = file.slice(start, end); fileChunks.push(chunk); } return fileChunks; } async function hash(arrayBuffer) { const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer); const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray .map((bytes) => bytes.toString(16).padStart(2, '0')) .join(''); return hashHex; } async function uploadChunks(name, size, chunks, chunkArray, FileID) { let byteUploaded = 0 let progress1 = document.getElementById(`progress-${name}-1`); let progress2 = document.getElementById(`progress-${name}-2`); let progress3 = document.getElementById(`progress-${name}-3`); let isFailed = false for (let index = 0; index < chunks.length; index++) { const percentComplete = Math.round((index + 1) / chunks.length * 100); const chunk = chunks[index]; if (!(chunkArray["chunk_"+index])) { const formData = new FormData(); formData.append('name', name); formData.append('chunk', chunk); formData.append('index', index); formData.append('done', false); progress1.style.strokeDashoffset = 100 - percentComplete; progress2.innerText = `${percentComplete}%`; const startTime = performance.now(); try { const request = await fetch(`/file/${FileID}`, { method: 'POST', body: formData }); console.log(request.status) if (request.status !== 202) { ChangeModal("Error", "There was an issue with your upload. Please try again later or contact support if the problem persists.") toggleModal(); isFailed = true break } } catch (error) { ChangeModal("Error", "There was an issue with your upload. Please try again later or contact support if the problem persists.") toggleModal(); isFailed = true break } const endTime = performance.now(); const totalTime = (endTime - startTime) / 1000; const uploadSpeed = chunk.size / totalTime / 1024 / 1024; byteUploaded += chunk.size progress3.innerText = `Uploading... ${uploadSpeed.toFixed(2)} MB/s`; } else { progress1.style.strokeDashoffset = 100 - percentComplete; progress2.innerText = `${percentComplete}%`; progress3.innerText = `Fixing Missing Byte`; byteUploaded += chunk.size } } if (isFailed) { progress3.innerText = `Upload Failed`; } else { progress3.innerText = `Done`; } } function ChangeModal(title, content) { const modalContainer = document.getElementById('modalContainer'); const modalTitle = modalContainer.querySelector('#modal h2'); const modalContent = modalContainer.querySelector('.prose'); modalTitle.textContent = title; modalContent.innerHTML = content; }