61 lines
1.6 KiB
TypeScript
61 lines
1.6 KiB
TypeScript
|
import type { mastodon } from "masto";
|
||
|
import {
|
||
|
splitProps,
|
||
|
type Component,
|
||
|
type JSX,
|
||
|
createRenderEffect,
|
||
|
createMemo,
|
||
|
} from "solid-js";
|
||
|
import { resolveCustomEmoji } from "../../masto/toot.js";
|
||
|
import { makeAcctText, useDefaultSession } from "../../masto/clients";
|
||
|
|
||
|
function preventDefault(event: Event) {
|
||
|
event.preventDefault();
|
||
|
}
|
||
|
|
||
|
export type TootContentProps = {
|
||
|
source?: string;
|
||
|
emojis?: mastodon.v1.CustomEmoji[];
|
||
|
mentions: mastodon.v1.StatusMention[];
|
||
|
} & JSX.HTMLAttributes<HTMLDivElement>;
|
||
|
|
||
|
const TootContent: Component<TootContentProps> = (props) => {
|
||
|
const session = useDefaultSession();
|
||
|
const [managed, rest] = splitProps(props, ["source", "emojis", "mentions"]);
|
||
|
|
||
|
const clientFinder = createMemo(() =>
|
||
|
session() ? makeAcctText(session()!) : undefined,
|
||
|
);
|
||
|
|
||
|
return (
|
||
|
<div
|
||
|
ref={(ref) => {
|
||
|
createRenderEffect(() => {
|
||
|
ref.innerHTML = managed.source
|
||
|
? managed.emojis
|
||
|
? resolveCustomEmoji(managed.source, managed.emojis)
|
||
|
: managed.source
|
||
|
: "";
|
||
|
});
|
||
|
|
||
|
createRenderEffect(() => {
|
||
|
const finder = clientFinder();
|
||
|
for (const mention of props.mentions) {
|
||
|
const elements = ref.querySelectorAll<HTMLAnchorElement>(
|
||
|
`a[href='${mention.url}']`,
|
||
|
);
|
||
|
for (const e of elements) {
|
||
|
e.onclick = preventDefault;
|
||
|
e.dataset.action = "acct";
|
||
|
e.dataset.client = finder;
|
||
|
e.dataset.acctId = mention.id.toString();
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}}
|
||
|
{...rest}
|
||
|
></div>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export default TootContent;
|