/** * The link provider for this site's own pages, read from the database * instead of fetched. * * @module */ import type { RichContent } from "../../../shared/dump.ts"; import type { RichContentProvider } from "./provider.ts"; import { getDump } from "../../services/dump-service.ts"; import { getUserByUsername } from "../../services/user-service.ts"; import { getPlaylistById } from "../../services/playlist-service.ts"; import { PUBLIC_URL, THEME_COLOR } from "../../config.ts"; import { isSelfUrl } from "../../lib/self-url.ts"; const DUMP_RE = /^\/dumps\/([^/]+)$/; const USER_RE = /^\/users\/([^/]+)$/; const PLAYLIST_RE = /^\/playlists\/([^/]+)$/; /** * Internal links carry gerbeur's own branding, so an art-less one still gets a * recognizable placeholder instead of a generic tint. */ const SELF_BRANDING = { siteName: "gerbeur", faviconUrl: `${PUBLIC_URL}/apple-touch-icon.png`, accentColor: THEME_COLOR, } as const; /** * The provider for links to this site's dump, user and playlist pages, read * from the database. Its `fetch` rejects with the services' `APIException` (404) for a * page that doesn't exist or is private. */ export const selfProvider: RichContentProvider = { name: "self", matches(url: string): boolean { try { return isSelfUrl(new URL(url)); } catch { return false; } }, fetch(url: string): Promise { const { pathname } = new URL(url); const dumpMatch = pathname.match(DUMP_RE); if (dumpMatch) { const dump = getDump(dumpMatch[1]); let thumbnailUrl: string | undefined; if (dump.kind === "file" && dump.fileMime?.startsWith("image/")) { thumbnailUrl = `${PUBLIC_URL}/api/files/${dump.id}`; } else if (dump.richContent?.thumbnailUrl) { thumbnailUrl = dump.richContent.thumbnailUrl; } return Promise.resolve({ type: "generic", url, ...SELF_BRANDING, title: dump.title, description: dump.comment, thumbnailUrl, }); } const userMatch = pathname.match(USER_RE); if (userMatch) { const user = getUserByUsername(userMatch[1]); const thumbnailUrl = user.avatarMime ? `${PUBLIC_URL}/api/avatars/${user.id}` : undefined; return Promise.resolve({ type: "generic", url, ...SELF_BRANDING, title: user.username, description: user.description, thumbnailUrl, }); } const playlistMatch = pathname.match(PLAYLIST_RE); if (playlistMatch) { const playlist = getPlaylistById(playlistMatch[1]); const thumbnailUrl = playlist.imageMime ? `${PUBLIC_URL}/api/playlists/${playlist.id}/image` : undefined; return Promise.resolve({ type: "generic", url, ...SELF_BRANDING, title: playlist.title, description: playlist.description, thumbnailUrl, }); } // Should not reach here if matches() is correct return Promise.resolve({ type: "generic", url }); }, };