fix: Bug - Sending files and attachment issues
Hydrate playable media after disk receive, relay file-announce to sibling devices via account_sync, bind DM attachments to pre-allocated message ids, and improve gallery retry/cancel UX with bounded parallel auto-downloads. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+40
-6
@@ -229,6 +229,10 @@ export class AttachmentTransferService {
|
||||
}
|
||||
|
||||
requestImageFromAnyPeer(messageId: string, attachment: Attachment): Promise<void> {
|
||||
if ((attachment.receivedBytes ?? 0) > 0 || this.hasPendingRequest(messageId, attachment.id)) {
|
||||
this.cancelRequest(messageId, attachment);
|
||||
}
|
||||
|
||||
return this.requestFromAnyPeer(messageId, attachment);
|
||||
}
|
||||
|
||||
@@ -456,22 +460,22 @@ export class AttachmentTransferService {
|
||||
}
|
||||
|
||||
cancelRequest(messageId: string, attachment: Attachment): void {
|
||||
const targetPeerId = attachment.uploaderPeerId;
|
||||
|
||||
if (!targetPeerId)
|
||||
return;
|
||||
|
||||
try {
|
||||
const requestKey = this.buildRequestKey(messageId, attachment.id);
|
||||
const assemblyKey = `${messageId}:${attachment.id}`;
|
||||
const pendingPeers = this.runtimeStore.getPendingRequestPeers(requestKey);
|
||||
|
||||
this.runtimeStore.deleteChunkBuffer(assemblyKey);
|
||||
this.runtimeStore.deleteChunkCount(assemblyKey);
|
||||
this.runtimeStore.deletePendingRequest(requestKey);
|
||||
void this.deleteDiskReceiveAssembly(assemblyKey);
|
||||
this.chunkAcks.cancelPendingForFile(messageId, attachment.id);
|
||||
|
||||
attachment.receivedBytes = 0;
|
||||
attachment.speedBps = 0;
|
||||
attachment.startedAtMs = undefined;
|
||||
attachment.lastUpdateMs = undefined;
|
||||
attachment.requestError = undefined;
|
||||
|
||||
if (attachment.objectUrl) {
|
||||
try {
|
||||
@@ -489,8 +493,21 @@ export class AttachmentTransferService {
|
||||
messageId,
|
||||
fileId: attachment.id
|
||||
};
|
||||
const peersToNotify = new Set<string>();
|
||||
|
||||
this.webrtc.sendToPeer(targetPeerId, fileCancelEvent);
|
||||
if (pendingPeers) {
|
||||
for (const peerId of pendingPeers) {
|
||||
peersToNotify.add(peerId);
|
||||
}
|
||||
}
|
||||
|
||||
if (attachment.uploaderPeerId) {
|
||||
peersToNotify.add(attachment.uploaderPeerId);
|
||||
}
|
||||
|
||||
for (const peerId of peersToNotify) {
|
||||
this.webrtc.sendToPeer(peerId, fileCancelEvent);
|
||||
}
|
||||
} catch { /* best-effort */ }
|
||||
}
|
||||
|
||||
@@ -997,6 +1014,23 @@ export class AttachmentTransferService {
|
||||
this.runtimeStore.touch();
|
||||
void this.persistence.persistAttachmentMeta(attachment);
|
||||
void this.announceLocalHost(attachment);
|
||||
void this.hydratePlayableMediaAfterDiskReceive(attachment);
|
||||
}
|
||||
|
||||
private async hydratePlayableMediaAfterDiskReceive(attachment: Attachment): Promise<void> {
|
||||
if (!this.isPlayableMedia(attachment) || !attachment.savedPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nativeUrl = await this.attachmentStorage.getFileUrl(attachment.savedPath);
|
||||
|
||||
if (nativeUrl) {
|
||||
attachment.objectUrl = nativeUrl;
|
||||
this.runtimeStore.touch();
|
||||
return;
|
||||
}
|
||||
|
||||
await this.persistence.ensureInlineDisplayObjectUrl(attachment);
|
||||
}
|
||||
|
||||
private async getOrCreateDiskReceiveAssembly(
|
||||
|
||||
Reference in New Issue
Block a user