mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
87 lines
2.6 KiB
TypeScript
87 lines
2.6 KiB
TypeScript
import { AppMiddleware } from '@/app.ts';
|
|
import { Conf } from '@/config.ts';
|
|
import { Stickynotes } from '@soapbox/stickynotes';
|
|
import { Storages } from '@/storages.ts';
|
|
import {
|
|
fetchProfile,
|
|
getHandle,
|
|
getPathParams,
|
|
getStatusInfo,
|
|
OpenGraphTemplateOpts,
|
|
PathParams,
|
|
} from '@/utils/og-metadata.ts';
|
|
import { getInstanceMetadata } from '@/utils/instance.ts';
|
|
import { metadataView } from '@/views/meta.ts';
|
|
|
|
const console = new Stickynotes('ditto:frontend');
|
|
|
|
/** Placeholder to find & replace with metadata. */
|
|
const META_PLACEHOLDER = '<!--server-generated-meta-->' as const;
|
|
|
|
/*
|
|
* TODO: implement caching for posts (LRUCache)
|
|
*/
|
|
|
|
async function buildTemplateOpts(params: PathParams, url: string): Promise<OpenGraphTemplateOpts> {
|
|
const store = await Storages.db();
|
|
const meta = await getInstanceMetadata(store);
|
|
const res: OpenGraphTemplateOpts = {
|
|
title: `View this page on ${meta.name}`,
|
|
type: 'article',
|
|
description: meta.about,
|
|
url,
|
|
site: meta.name,
|
|
image: {
|
|
url: Conf.local('/favicon.ico'),
|
|
w: 48,
|
|
h: 48,
|
|
},
|
|
};
|
|
try {
|
|
if (params.acct && !params.statusId) {
|
|
const key = /^[a-f0-9]{64}$/.test(params.acct) ? 'pubkey' : 'handle';
|
|
console.log(key);
|
|
const profile = await fetchProfile({ [key]: params.acct });
|
|
const handle = await getHandle(params.acct, profile);
|
|
res.type = 'profile';
|
|
res.title = `View @${handle}'s profile on Ditto`;
|
|
res.description = profile.meta.about || `@${handle}'s Nostr profile`;
|
|
if (profile.meta.picture) {
|
|
res.image = { url: profile.meta.picture, h: 150, w: 150 };
|
|
}
|
|
} else if (params.statusId) {
|
|
const { description, image, title } = await getStatusInfo(params.statusId);
|
|
res.description = description;
|
|
res.image = image;
|
|
res.title = title;
|
|
}
|
|
} catch (e) {
|
|
console.debug('Error getting OpenGraph metadata information:');
|
|
console.debug(e);
|
|
console.trace();
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
export const frontendController: AppMiddleware = async (c, next) => {
|
|
try {
|
|
const content = await Deno.readTextFile(new URL('../../public/index.html', import.meta.url));
|
|
if (content.includes(META_PLACEHOLDER)) {
|
|
const params = getPathParams(c.req.path);
|
|
if (params) {
|
|
try {
|
|
const meta = metadataView(await buildTemplateOpts(params, Conf.local(c.req.path)));
|
|
return c.html(content.replace(META_PLACEHOLDER, meta));
|
|
} catch (e) {
|
|
console.log(e);
|
|
return c.html(content);
|
|
}
|
|
}
|
|
}
|
|
return c.html(content);
|
|
} catch (e) {
|
|
console.log(e);
|
|
await next();
|
|
}
|
|
};
|