fix: Bug - Files lose host on reload

Persist large uploads under app data on publish and restore, and re-announce hosted attachments after reload so peers can download again.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-13 22:04:41 +02:00
co-authored by Cursor
parent 95259e8943
commit f0d79aa627
7 changed files with 210 additions and 9 deletions
@@ -13,6 +13,7 @@ import {
} from '../../domain/logic/attachment-blob.rules';
import { isBlobObjectUrl, needsBlobObjectUrlForInlineDisplay } from '../../domain/logic/attachment-display-url.rules';
import { mergeAttachmentLocalPaths } from '../../domain/logic/attachment-persistence.rules';
import { isAttachmentMedia } from '../../domain/logic/attachment.logic';
import { AttachmentRuntimeStore } from './attachment-runtime.store';
@Injectable({ providedIn: 'root' })
@@ -118,7 +119,7 @@ export class AttachmentPersistenceService {
}
async tryRestoreAttachmentFromLocal(attachment: Attachment): Promise<boolean> {
const restored = await this.ensureInlineDisplayObjectUrl(attachment);
const restored = await this.ensurePersistedUploadHost(attachment);
if (restored) {
attachment.requestError = undefined;
@@ -127,6 +128,41 @@ export class AttachmentPersistenceService {
return restored;
}
async ensurePersistedUploadHost(attachment: Attachment): Promise<boolean> {
const existingPath = await this.attachmentStorage.resolveExistingPath(attachment);
if (existingPath) {
return this.hydrateAttachmentFromStoredPath(attachment, existingPath);
}
if (!attachment.filePath?.trim() || !this.attachmentStorage.canCopyFiles()) {
return false;
}
const savedPath = await this.persistUploadCopyFromSourcePath(attachment, attachment.filePath);
if (!savedPath) {
attachment.filePath = undefined;
void this.persistAttachmentMeta(attachment);
return false;
}
return this.hydrateAttachmentFromStoredPath(attachment, savedPath);
}
private async hydrateAttachmentFromStoredPath(attachment: Attachment, diskPath: string): Promise<boolean> {
attachment.savedPath = diskPath;
if (isAttachmentMedia(attachment)) {
return this.ensureInlineDisplayObjectUrl(attachment);
}
attachment.available = true;
void this.persistAttachmentMeta(attachment);
return true;
}
async ensureInlineDisplayObjectUrl(attachment: Attachment): Promise<boolean> {
if (!needsBlobObjectUrlForInlineDisplay(attachment.objectUrl)) {
return true;