Files
ncd-fe/packages/pl-hooks/lib/normalizers/status.ts
nicole mikołajczyk bbf0325146 pl-hooks: migrate from eslint
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
2026-02-24 14:01:33 +01:00

99 lines
2.4 KiB
TypeScript

import {
type Account as BaseAccount,
type Status as BaseStatus,
type MediaAttachment,
mentionSchema,
} from 'pl-api';
import * as v from 'valibot';
type StatusApprovalStatus = Exclude<BaseStatus['approval_status'], null>;
type StatusVisibility =
| 'public'
| 'unlisted'
| 'private'
| 'direct'
| 'group'
| 'mutuals_only'
| 'local';
const normalizeStatus = ({
account,
accounts,
reblog,
poll,
group,
quote,
...status
}: BaseStatus & { accounts?: Array<BaseAccount> }) => {
// Sort the replied-to mention to the top
let mentions = status.mentions.toSorted((a, _b) => {
if (a.id === status.in_reply_to_account_id) {
return -1;
} else {
return 0;
}
});
// Add self to mentions if it's a reply to self
const isSelfReply = account.id === status.in_reply_to_account_id;
const hasSelfMention = status.mentions.some((mention) => account.id === mention.id);
if (isSelfReply && !hasSelfMention) {
const selfMention = v.parse(mentionSchema, account);
mentions = [selfMention, ...mentions];
}
// Normalize event
let event: BaseStatus['event'] &
({
banner: MediaAttachment | null;
links: Array<MediaAttachment>;
} | null) = null;
let media_attachments = status.media_attachments;
if (status.event) {
const firstAttachment = status.media_attachments[0];
let banner: MediaAttachment | null = null;
if (firstAttachment?.description === 'Banner' && firstAttachment.type === 'image') {
banner = firstAttachment;
media_attachments = media_attachments.slice(1);
}
const links = media_attachments.filter((attachment) => attachment.mime_type === 'text/html');
media_attachments = media_attachments.filter(
(attachment) => attachment.mime_type !== 'text/html',
);
event = {
...status.event,
banner,
links,
};
}
return {
account_id: account.id,
account_ids: accounts?.map((account) => account.id) || [account.id],
reblog_id: reblog?.id || null,
poll_id: poll?.id || null,
group_id: group?.id || null,
expectsCard: false,
showFiltered: null as null | boolean,
...status,
mentions,
filtered: status.filtered?.map((result) => result.filter.title),
event,
media_attachments,
};
};
type Status = ReturnType<typeof normalizeStatus>;
export {
type StatusApprovalStatus,
type StatusVisibility,
normalizeStatus,
type Status as NormalizedStatus,
};