v4: a new link between two dumps shows among their related dumps at once — it showed on the next load of the page: the backlink service recorded the link without telling anyone, and the dump page fetched its related dumps once, the socket then only editing or removing the ones it had. relinkBacklinks now sends dump_related_changed when a note or a comment gains or loses a link, naming the dump and those at the other end, and the page showing one of them fetches /related again. A link shows to those who may see both its ends, so each socket is told only of the dumps its user may see, and not at all without one at each end. A private dump that turns public sends it too, for the links it already had, which are new to everyone but its poster. The page also fetches its related dumps again on a reconnection, as it does its comments and playlists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
khannurien
2026-10-10 08:43:55 +00:00
parent dde0232acb
commit 350e945eb1
10 changed files with 221 additions and 8 deletions

View File

@@ -57,7 +57,7 @@ import {
VALIDATION,
} from "../../shared/validation.ts";
import { linkAttachments } from "./attachment-service.ts";
import { relinkBacklinks } from "./backlink-service.ts";
import { announceLinksNowPublic, relinkBacklinks } from "./backlink-service.ts";
import {
assertCategoriesExist,
attachCategoryIds,
@@ -96,7 +96,8 @@ function assertFileDumpText(title?: string, comment?: string): void {
* `broadcastDumpChange` for the dump itself, and, when it was deleted or
* changed visibility, the dumps of each playlist holding it, which moved for
* their viewers. A deletion passes the `holders` it read before the cascade
* took the dump out of them.
* took the dump out of them. A dump that turned public also joins the related
* dumps of those it is linked with.
*/
function announceDumpChange(
before: Dump | null,
@@ -106,6 +107,7 @@ function announceDumpChange(
broadcastDumpChange(before, after);
if (!before || (after && after.isPrivate === before.isPrivate)) return;
broadcastHoldersDumps(holders ?? playlistsHolding(before.id));
if (after && !after.isPrivate) announceLinksNowPublic(after.id);
}
/**