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
@@ -4,7 +4,10 @@ import {
inject
} from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { take } from 'rxjs';
import { RealtimeSessionFacade } from '../../../../core/realtime';
import { selectCurrentUserId } from '../../../../store/users/users.selectors';
import { DatabaseService } from '../../../../infrastructure/persistence';
import { yieldToAttachmentHydrationLoop } from '../../domain/logic/attachment-blob.rules';
import {
@@ -32,6 +35,7 @@ export class AttachmentManagerService {
private readonly webrtc = inject(RealtimeSessionFacade);
private readonly router = inject(Router);
private readonly store = inject(Store);
private readonly database = inject(DatabaseService);
private readonly runtimeStore = inject(AttachmentRuntimeStore);
private readonly persistence = inject(AttachmentPersistenceService);
@@ -45,9 +49,10 @@ export class AttachmentManagerService {
effect(() => {
if (this.database.isReady() && !this.isDatabaseInitialised) {
this.isDatabaseInitialised = true;
void this.persistence.initFromDatabase().then(() => {
void this.persistence.initFromDatabase().then(async () => {
if (this.watchedRoomId) {
void this.restoreLocalAttachmentsForRoom(this.watchedRoomId);
await this.restoreLocalAttachmentsForRoom(this.watchedRoomId);
await this.announceHostedAttachments();
}
});
}
@@ -68,7 +73,10 @@ export class AttachmentManagerService {
this.webrtc.onPeerConnected.subscribe(() => {
if (this.watchedRoomId) {
void this.restoreLocalAttachmentsForRoom(this.watchedRoomId);
void this.restoreLocalAttachmentsForRoom(this.watchedRoomId).then(async () => {
await this.announceHostedAttachments();
});
void this.requestAutoDownloadsForRoom(this.watchedRoomId);
}
});
@@ -324,6 +332,15 @@ export class AttachmentManagerService {
return getWatchedAttachmentRoomIdFromUrl(url);
}
private async announceHostedAttachments(): Promise<void> {
const currentUserId = await new Promise<string | null>((resolve) => {
this.store.select(selectCurrentUserId).pipe(take(1))
.subscribe((userId) => resolve(userId));
});
await this.transfer.reannounceHostedAttachments(currentUserId);
}
private isRoomWatched(roomId: string | null | undefined): boolean {
return !!roomId && roomId === this.watchedRoomId;
}