Skip to content

Commit

Permalink
refactor file transfer callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
liamcottle committed Dec 14, 2024
1 parent 40250c0 commit bad6cdd
Showing 1 changed file with 154 additions and 138 deletions.
292 changes: 154 additions & 138 deletions src/js/Connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);

}

Expand Down

0 comments on commit bad6cdd

Please sign in to comment.