From bad6cdd6d8ba234397118e505862082dde732f4f Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sat, 14 Dec 2024 18:21:02 +1300 Subject: [PATCH] refactor file transfer callbacks --- src/js/Connection.js | 292 +++++++++++++++++++++++-------------------- 1 file changed, 154 insertions(+), 138 deletions(-) diff --git a/src/js/Connection.js b/src/js/Connection.js index a57da7d..a42efeb 100644 --- a/src/js/Connection.js +++ b/src/js/Connection.js @@ -478,197 +478,213 @@ class Connection { console.log("onFileTransferPacket", fileTransferPacket); if(fileTransferPacket.offerFileTransfer){ + await this.onOfferFileTransferPacket(meshPacket, fileTransferPacket.offerFileTransfer); + } else if(fileTransferPacket.acceptFileTransfer){ + await this.onAcceptFileTransferPacket(meshPacket, fileTransferPacket.acceptFileTransfer); + } else if(fileTransferPacket.rejectFileTransfer){ + await this.onRejectFileTransferPacket(meshPacket, fileTransferPacket.rejectFileTransfer); + } else if(fileTransferPacket.cancelFileTransfer){ + await this.onCancelFileTransferPacket(meshPacket, fileTransferPacket.cancelFileTransfer); + } else if(fileTransferPacket.completedFileTransfer){ + await this.onCompletedFileTransferPacket(meshPacket, fileTransferPacket.completedFileTransfer); + } else if(fileTransferPacket.filePart){ + await this.onFilePartPacket(meshPacket, fileTransferPacket.filePart); + } else if(fileTransferPacket.requestFileParts){ + await this.onRequestFilePartsPacket(meshPacket, fileTransferPacket.requestFileParts); + } else { + console.log("unhandled file transfer packet", fileTransferPacket); + } - const fileTransferOffer = fileTransferPacket.offerFileTransfer; + } - // find existing file transfer - let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { - return fileTransfer.id === fileTransferOffer.id; - }); + static async onOfferFileTransferPacket(meshPacket, fileTransferOffer) { - // create new file transfer if one doesn't already exist - if(!fileTransfer){ + // find existing file transfer + let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { + return fileTransfer.id === fileTransferOffer.id; + }); - fileTransfer = { - id: fileTransferOffer.id, - to: meshPacket.to, - from: meshPacket.from, - direction: "incoming", - status: "offering", - filename: fileTransferOffer.fileName, - filesize: fileTransferOffer.fileSize, - progress: 0, - chunks: {}, - }; + // create new file transfer if one doesn't already exist + if(!fileTransfer){ - GlobalState.fileTransfers.push(fileTransfer); + fileTransfer = { + id: fileTransferOffer.id, + to: meshPacket.to, + from: meshPacket.from, + direction: "incoming", + status: "offering", + filename: fileTransferOffer.fileName, + filesize: fileTransferOffer.fileSize, + progress: 0, + chunks: {}, + }; - console.log(`[FileTransfer] ${fileTransfer.id} offer received`); + GlobalState.fileTransfers.push(fileTransfer); - } + console.log(`[FileTransfer] ${fileTransfer.id} offer received`); - } else if(fileTransferPacket.acceptFileTransfer){ + } - const acceptFileTransfer = fileTransferPacket.acceptFileTransfer; + } - // find existing file transfer - let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { - return fileTransfer.id === acceptFileTransfer.fileTransferId; - }); + static async onAcceptFileTransferPacket(meshPacket, acceptFileTransfer) { - // do nothing if file transfer not found - if(!fileTransfer){ - return; - } + // find existing file transfer + let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { + return fileTransfer.id === acceptFileTransfer.fileTransferId; + }); - console.log(`[FileTransfer] ${fileTransfer.id} accepted`); + // do nothing if file transfer not found + if(!fileTransfer){ + return; + } - // determine how many parts will be sent - const maxAcceptablePartSize = acceptFileTransfer.maxAcceptablePartSize; - const totalParts = Math.ceil(fileTransfer.data.length / maxAcceptablePartSize); + console.log(`[FileTransfer] ${fileTransfer.id} accepted`); - // update file transfer status - fileTransfer.status = "accepted"; - fileTransfer.total_parts = totalParts; - fileTransfer.max_acceptable_part_size = maxAcceptablePartSize; + // determine how many parts will be sent + const maxAcceptablePartSize = acceptFileTransfer.maxAcceptablePartSize; + const totalParts = Math.ceil(fileTransfer.data.length / maxAcceptablePartSize); - // send first file part - await this.sendFilePart(fileTransfer, 0); + // update file transfer status + fileTransfer.status = "accepted"; + fileTransfer.total_parts = totalParts; + fileTransfer.max_acceptable_part_size = maxAcceptablePartSize; - } else if(fileTransferPacket.rejectFileTransfer){ + // send first file part + await this.sendFilePart(fileTransfer, 0); - const rejectFileTransfer = fileTransferPacket.rejectFileTransfer; + } - // find existing file transfer - let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { - return fileTransfer.id === rejectFileTransfer.fileTransferId; - }); + static async onRejectFileTransferPacket(meshPacket, rejectFileTransfer) { - // do nothing if file transfer not found - if(!fileTransfer){ - return; - } + // find existing file transfer + let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { + return fileTransfer.id === rejectFileTransfer.fileTransferId; + }); - console.log(`[FileTransfer] ${fileTransfer.id} rejected`); + // do nothing if file transfer not found + if(!fileTransfer){ + return; + } - // update file transfer status - fileTransfer.status = "rejected"; + console.log(`[FileTransfer] ${fileTransfer.id} rejected`); - } else if(fileTransferPacket.cancelFileTransfer){ + // update file transfer status + fileTransfer.status = "rejected"; - const cancelFileTransfer = fileTransferPacket.cancelFileTransfer; + } - // find existing file transfer - let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { - return fileTransfer.id === cancelFileTransfer.fileTransferId; - }); + static async onCancelFileTransferPacket(meshPacket, cancelFileTransfer) { - // do nothing if file transfer not found - if(!fileTransfer){ - return; - } + // find existing file transfer + let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { + return fileTransfer.id === cancelFileTransfer.fileTransferId; + }); - console.log(`[FileTransfer] ${fileTransfer.id} cancelled`); + // do nothing if file transfer not found + if(!fileTransfer){ + return; + } - // remove cancelled file transfer if it was in offering state - if(fileTransfer.status === "offering"){ - GlobalState.fileTransfers = GlobalState.fileTransfers.filter((existingFileTransfer) => { - return existingFileTransfer.id !== fileTransfer.id; - }); - return; - } + console.log(`[FileTransfer] ${fileTransfer.id} cancelled`); - // update file transfer status - fileTransfer.status = "cancelled"; + // remove cancelled file transfer if it was in offering state + if(fileTransfer.status === "offering"){ + GlobalState.fileTransfers = GlobalState.fileTransfers.filter((existingFileTransfer) => { + return existingFileTransfer.id !== fileTransfer.id; + }); + return; + } - } else if(fileTransferPacket.completedFileTransfer){ + // update file transfer status + fileTransfer.status = "cancelled"; - const completedFileTransfer = fileTransferPacket.completedFileTransfer; + } - // find existing file transfer - let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { - return fileTransfer.id === completedFileTransfer.fileTransferId; - }); + static async onCompletedFileTransferPacket(meshPacket, completedFileTransfer) { - // do nothing if file transfer not found - if(!fileTransfer){ - return; - } + // find existing file transfer + let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { + return fileTransfer.id === completedFileTransfer.fileTransferId; + }); - console.log(`[FileTransfer] ${fileTransfer.id} completed`); + // do nothing if file transfer not found + if(!fileTransfer){ + return; + } - // update file transfer status - fileTransfer.status = "complete"; + console.log(`[FileTransfer] ${fileTransfer.id} completed`); - } else if(fileTransferPacket.filePart){ + // update file transfer status + fileTransfer.status = "complete"; - const filePart = fileTransferPacket.filePart; + } - // find existing file transfer - let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { - return fileTransfer.id === filePart.fileTransferId; - }); + static async onFilePartPacket(meshPacket, filePart) { - // do nothing if file transfer not found - if(!fileTransfer){ - return; - } + // find existing file transfer + let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { + return fileTransfer.id === filePart.fileTransferId; + }); - console.log(`[FileTransfer] ${fileTransfer.id} received part ${filePart.partIndex + 1}/${filePart.totalParts}`); + // do nothing if file transfer not found + if(!fileTransfer){ + return; + } - // cache received data - fileTransfer.chunks[filePart.partIndex] = filePart.data; + console.log(`[FileTransfer] ${fileTransfer.id} received part ${filePart.partIndex + 1}/${filePart.totalParts}`); - // update file transfer status - fileTransfer.status = "receiving"; - fileTransfer.progress = Math.ceil((filePart.partIndex + 1) / filePart.totalParts * 100); + // cache received data + fileTransfer.chunks[filePart.partIndex] = filePart.data; - // check if complete - // todo, check if all chunks received, and request others if not? - if(filePart.partIndex === filePart.totalParts - 1){ - fileTransfer.status = "complete"; - fileTransfer.blob = new Blob(Object.values(fileTransfer.chunks), { - type: "application/octet-stream", - }); - await this.completeFileTransfer(fileTransfer); - return; - } + // update file transfer status + fileTransfer.status = "receiving"; + fileTransfer.progress = Math.ceil((filePart.partIndex + 1) / filePart.totalParts * 100); - // request next part - const nextFilePartIndex = filePart.partIndex + 1; - await this.requestFileParts(fileTransfer, [ - nextFilePartIndex, - ]); + // check if complete + // todo, check if all chunks received, and request others if not? + if(filePart.partIndex === filePart.totalParts - 1){ + fileTransfer.status = "complete"; + fileTransfer.blob = new Blob(Object.values(fileTransfer.chunks), { + type: "application/octet-stream", + }); + await this.completeFileTransfer(fileTransfer); + return; + } - } else if(fileTransferPacket.requestFileParts){ + // request next part + const nextFilePartIndex = filePart.partIndex + 1; + await this.requestFileParts(fileTransfer, [ + nextFilePartIndex, + ]); - const requestFileParts = fileTransferPacket.requestFileParts; + } - // find existing file transfer - let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { - return fileTransfer.id === requestFileParts.fileTransferId; - }); + static async onRequestFilePartsPacket(meshPacket, requestFileParts) { - // do nothing if file transfer not found - if(!fileTransfer){ - return; - } + // find existing file transfer + let fileTransfer = GlobalState.fileTransfers.find((fileTransfer) => { + return fileTransfer.id === requestFileParts.fileTransferId; + }); - console.log(`[FileTransfer] ${fileTransfer.id} requested file parts ${requestFileParts.partIndexes}.`); + // do nothing if file transfer not found + if(!fileTransfer){ + return; + } - // send parts - for(const partIndex of requestFileParts.partIndexes){ + console.log(`[FileTransfer] ${fileTransfer.id} requested file parts ${requestFileParts.partIndexes}.`); - console.log(`[FileTransfer] ${fileTransfer.id} sending part ${partIndex}`); + // send parts + for(const partIndex of requestFileParts.partIndexes){ - // send file part - await this.sendFilePart(fileTransfer, partIndex); + console.log(`[FileTransfer] ${fileTransfer.id} sending part ${partIndex}`); - // update file transfer progress - fileTransfer.status = "sending"; - fileTransfer.progress = Math.ceil((partIndex + 1) / fileTransfer.total_parts * 100); + // send file part + await this.sendFilePart(fileTransfer, partIndex); - } + // update file transfer progress + fileTransfer.status = "sending"; + fileTransfer.progress = Math.ceil((partIndex + 1) / fileTransfer.total_parts * 100); }