Skip to content

Commit a1df778

Browse files
committed
show if file transfer is being accepted, and add guard clauses for out of order packets
1 parent f5efab0 commit a1df778

File tree

3 files changed

+72
-6
lines changed

3 files changed

+72
-6
lines changed

src/components/pages/NodeFilesPage.vue

+38-3
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,22 @@
6868
</div>
6969

7070
<!-- incoming file transfer offer -->
71-
<div v-if="fileTransfer.direction === 'incoming' && fileTransfer.status === 'offering'" class="flex space-x-1">
72-
<TextButton @click="acceptFileTransfer(fileTransfer)" class="bg-green-500 hover:bg-green-400">Accept</TextButton>
73-
<TextButton @click="rejectFileTransfer(fileTransfer)" class="bg-red-500 hover:bg-red-400">Reject</TextButton>
71+
<div v-if="fileTransfer.direction === 'incoming' && fileTransfer.status === 'offering'">
72+
<div v-if="!isAcceptingFileTransfer(fileTransfer.id)" class="flex space-x-1">
73+
<TextButton @click="acceptFileTransfer(fileTransfer)" class="bg-green-500 hover:bg-green-400">Accept</TextButton>
74+
<TextButton @click="rejectFileTransfer(fileTransfer)" class="bg-red-500 hover:bg-red-400">Reject</TextButton>
75+
</div>
76+
<div v-else class="flex text-gray-500 space-x-1">
77+
<div class="my-auto">
78+
<svg class="animate-spin size-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
79+
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
80+
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
81+
</svg>
82+
</div>
83+
<div class="my-auto">
84+
Accepting
85+
</div>
86+
</div>
7487
</div>
7588

7689
<!-- action buttons -->
@@ -149,6 +162,11 @@ export default {
149162
}
150163
151164
},
165+
data() {
166+
return {
167+
isAcceptingFileTransferIds: [],
168+
};
169+
},
152170
methods: {
153171
hasPublicKey: (nodeId) => NodeUtils.hasPublicKey(nodeId),
154172
getNodeLongName: (nodeId) => NodeUtils.getNodeLongName(nodeId),
@@ -188,6 +206,20 @@ export default {
188206
setTimeout(() => URL.revokeObjectURL(objectUrl), 10000);
189207
190208
},
209+
isAcceptingFileTransfer(fileTransferId) {
210+
return this.isAcceptingFileTransferIds.includes(fileTransferId);
211+
},
212+
setIsAcceptingFileTransfer(fileTransferId, isAcceptingFileTransfer) {
213+
if(isAcceptingFileTransfer){
214+
// add to list of ids
215+
this.isAcceptingFileTransferIds.push(fileTransferId);
216+
} else {
217+
// remove from list of ids
218+
this.isAcceptingFileTransferIds = this.isAcceptingFileTransferIds.filter((existingFileTransferId) => {
219+
return existingFileTransferId !== fileTransferId;
220+
});
221+
}
222+
},
191223
async offerFileTransfer() {
192224
193225
// do nothing if file is not selected
@@ -207,9 +239,12 @@ export default {
207239
},
208240
async acceptFileTransfer(fileTransfer) {
209241
try {
242+
this.setIsAcceptingFileTransfer(fileTransfer.id, true);
210243
await FileTransferrer.acceptFileTransfer(fileTransfer);
211244
} catch(e) {
212245
DialogUtils.showErrorAlert(e);
246+
} finally {
247+
this.setIsAcceptingFileTransfer(fileTransfer.id, false);
213248
}
214249
},
215250
async rejectFileTransfer(fileTransfer) {

src/js/Connection.js

+30
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,12 @@ class Connection {
540540
return;
541541
}
542542

543+
// do nothing if file transfer not in offering state
544+
if(fileTransfer.status !== FileTransferrer.STATUS_OFFERING){
545+
console.log(`[FileTransfer] ${fileTransfer.id} accepted, but no longer in offering state`);
546+
return;
547+
}
548+
543549
console.log(`[FileTransfer] ${fileTransfer.id} accepted`);
544550

545551
// determine how many parts will be sent
@@ -568,6 +574,12 @@ class Connection {
568574
return;
569575
}
570576

577+
// do nothing if file transfer not in offering state
578+
if(fileTransfer.status !== FileTransferrer.STATUS_OFFERING){
579+
console.log(`[FileTransfer] ${fileTransfer.id} rejected, but no longer in offering state`);
580+
return;
581+
}
582+
571583
console.log(`[FileTransfer] ${fileTransfer.id} rejected`);
572584

573585
// update file transfer status
@@ -587,6 +599,12 @@ class Connection {
587599
return;
588600
}
589601

602+
// do nothing if file transfer in completed state
603+
if(fileTransfer.status === FileTransferrer.STATUS_COMPLETED){
604+
console.log(`[FileTransfer] ${fileTransfer.id} cancelled, but already in completed state`);
605+
return;
606+
}
607+
590608
console.log(`[FileTransfer] ${fileTransfer.id} cancelled`);
591609

592610
// remove cancelled file transfer if it was in offering state
@@ -633,6 +651,12 @@ class Connection {
633651
return;
634652
}
635653

654+
// do nothing if file transfer not in accepted or receiving state
655+
if(fileTransfer.status !== FileTransferrer.STATUS_ACCEPTED && fileTransfer.status !== FileTransferrer.STATUS_RECEIVING){
656+
console.log(`[FileTransfer] ${fileTransfer.id} received part ${filePart.partIndex + 1}/${filePart.totalParts}, but not in accepted or receiving state.`);
657+
return;
658+
}
659+
636660
console.log(`[FileTransfer] ${fileTransfer.id} received part ${filePart.partIndex + 1}/${filePart.totalParts}`);
637661

638662
// cache received data
@@ -673,6 +697,12 @@ class Connection {
673697
return;
674698
}
675699

700+
// do nothing if file transfer not in accepted or sending state
701+
if(fileTransfer.status !== FileTransferrer.STATUS_ACCEPTED && fileTransfer.status !== FileTransferrer.STATUS_SENDING){
702+
console.log(`[FileTransfer] ${fileTransfer.id} requested file parts ${requestFileParts.partIndexes}, but not in accepted or sending state.`);
703+
return;
704+
}
705+
676706
console.log(`[FileTransfer] ${fileTransfer.id} requested file parts ${requestFileParts.partIndexes}.`);
677707

678708
// send parts

src/js/FileTransferrer.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ class FileTransferrer {
88
static DIRECTION_OUTGOING = "outgoing";
99

1010
static STATUS_OFFERING = "offering";
11-
static STATUS_OFFERED = "offered";
1211
static STATUS_ACCEPTED = "accepted";
1312
static STATUS_REJECTED = "rejected";
1413
static STATUS_CANCELLED = "cancelled";
@@ -54,7 +53,6 @@ class FileTransferrer {
5453
this.log(`offerFileTransfer attempt ${attempt}`);
5554
await FileTransferAPI.sendFileTransferRequest(to, fileTransferId, fileName, fileSize);
5655
this.log(`offerFileTransfer attempt ${attempt} success`);
57-
fileTransfer.status = this.STATUS_OFFERED;
5856
return;
5957
} catch(e) {
6058
console.log(e);
@@ -105,7 +103,7 @@ class FileTransferrer {
105103
for(var attempt = 1; attempt <= this.MAX_PACKET_ATTEMPTS; attempt++){
106104
try {
107105
this.log(`rejectFileTransfer attempt ${attempt}`);
108-
await FileTransferAPI.acceptFileTransfer(fileTransfer.from, fileTransfer.id);
106+
await FileTransferAPI.rejectFileTransfer(fileTransfer.from, fileTransfer.id);
109107
fileTransfer.status = this.STATUS_ACCEPTED;
110108
return;
111109
} catch(e) {
@@ -154,6 +152,9 @@ class FileTransferrer {
154152
const end = start + partSize;
155153
const partData = fileTransfer.data.slice(start, end);
156154

155+
// update status
156+
fileTransfer.status = FileTransferrer.STATUS_SENDING;
157+
157158
// send part to remote node
158159
for(var attempt = 1; attempt <= this.MAX_PACKET_ATTEMPTS; attempt++){
159160
try {

0 commit comments

Comments
 (0)