FoundKey/packages/backend/src/remote/activitypub/renderer/person.ts
Johann150 3bdbbcadd9
adjust MFM to HTML conversion
Removed the misc/get-note-html module which was only used in one place.
Instead of it, the general MFM to HTML functionality has been improved to
take care of the use cases of that module as well.

Co-authored-by: Francis Dinh <normandy@biribiri.dev>
2022-09-07 14:42:39 +02:00

89 lines
2.7 KiB
TypeScript

import { URL } from 'node:url';
import config from '@/config/index.js';
import { ILocalUser } from '@/models/entities/user.js';
import { toHtml } from '@/mfm/to-html.js';
import { DriveFiles, UserProfiles } from '@/models/index.js';
import { getUserKeypair } from '@/misc/keypair-store.js';
import { IIdentifier } from '../models/identifier.js';
import renderImage from './image.js';
import renderKey from './key.js';
import { getEmojis } from './note.js';
import renderEmoji from './emoji.js';
import renderHashtag from './hashtag.js';
export async function renderPerson(user: ILocalUser) {
const id = `${config.url}/users/${user.id}`;
const isSystem = !!user.username.match(/\./);
const [avatar, banner, profile] = await Promise.all([
user.avatarId ? DriveFiles.findOneBy({ id: user.avatarId }) : Promise.resolve(undefined),
user.bannerId ? DriveFiles.findOneBy({ id: user.bannerId }) : Promise.resolve(undefined),
UserProfiles.findOneByOrFail({ userId: user.id }),
]);
const attachment: {
type: 'PropertyValue',
name: string,
value: string,
identifier?: IIdentifier
}[] = [];
if (profile.fields) {
for (const field of profile.fields) {
attachment.push({
type: 'PropertyValue',
name: field.name,
value: (field.value != null && field.value.match(/^https?:/))
? `<a href="${new URL(field.value).href}" rel="me nofollow noopener" target="_blank">${new URL(field.value).href}</a>`
: field.value,
});
}
}
const emojis = await getEmojis(user.emojis);
const apemojis = emojis.map(emoji => renderEmoji(emoji));
const hashtagTags = (user.tags || []).map(tag => renderHashtag(tag));
const tag = [
...apemojis,
...hashtagTags,
];
const keypair = await getUserKeypair(user.id);
const person = {
type: isSystem ? 'Application' : user.isBot ? 'Service' : 'Person',
id,
inbox: `${id}/inbox`,
outbox: `${id}/outbox`,
followers: `${id}/followers`,
following: `${id}/following`,
featured: `${id}/collections/featured`,
sharedInbox: `${config.url}/inbox`,
endpoints: { sharedInbox: `${config.url}/inbox` },
url: `${config.url}/@${user.username}`,
preferredUsername: user.username,
name: user.name,
summary: profile.description ? await toHtml(profile.description) : null,
icon: avatar ? renderImage(avatar) : null,
image: banner ? renderImage(banner) : null,
tag,
manuallyApprovesFollowers: user.isLocked,
discoverable: !!user.isExplorable,
publicKey: renderKey(user, keypair, '#main-key'),
isCat: user.isCat,
attachment: attachment.length ? attachment : undefined,
} as any;
if (profile.birthday) {
person['vcard:bday'] = profile.birthday;
}
if (profile.location) {
person['vcard:Address'] = profile.location;
}
return person;
}