tutu/src/timelines/toots/TootContent.tsx

116 lines
2.9 KiB
TypeScript
Raw Normal View History

import type { mastodon } from "masto";
import {
splitProps,
type Component,
type JSX,
createRenderEffect,
createMemo,
2024-11-20 16:24:57 +08:00
Show,
} from "solid-js";
import { resolveCustomEmoji } from "../../masto/toot.js";
2024-11-20 16:26:05 +08:00
import { makeAcctText, useDefaultSession } from "../../masto/clients.js";
2024-11-20 15:51:14 +08:00
import "./TootContent.css";
2024-11-20 16:24:57 +08:00
import { Button } from "@suid/material";
2024-11-22 17:16:56 +08:00
import { createTranslator } from "~platform/i18n.js";
function preventDefault(event: Event) {
event.preventDefault();
}
2024-11-20 16:24:57 +08:00
export type TootContentProps = JSX.HTMLAttributes<HTMLDivElement> & {
source?: string;
emojis?: mastodon.v1.CustomEmoji[];
mentions: mastodon.v1.StatusMention[];
2024-11-20 16:24:57 +08:00
sensitive?: boolean;
spoilerText?: string;
reveal?: boolean;
onToggleReveal?: JSX.EventHandlerUnion<HTMLElement, Event>;
};
2024-11-20 15:51:14 +08:00
const TootContent: Component<TootContentProps> = (oprops) => {
2024-11-20 16:33:30 +08:00
const [t] = createTranslator(
(code) =>
import(`./i18n/${code}.json`) as Promise<{
default: {
cw: string;
};
}>,
);
const session = useDefaultSession();
2024-11-20 15:51:14 +08:00
const [props, rest] = splitProps(oprops, [
"source",
"emojis",
"mentions",
"class",
2024-11-20 16:24:57 +08:00
"sensitive",
"spoilerText",
"reveal",
"onToggleReveal",
2024-11-20 15:51:14 +08:00
]);
const clientFinder = createMemo(() =>
session() ? makeAcctText(session()!) : undefined,
);
2024-11-20 16:24:57 +08:00
const shouldRevealContent = () => {
return !props.sensitive || (props.sensitive && props.reveal);
};
return (
<div
ref={(ref) => {
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();
}
}
});
}}
2024-11-20 15:51:14 +08:00
class={`TootContent ${props.class || ""}`}
{...rest}
2024-11-20 16:24:57 +08:00
>
<Show when={props.sensitive}>
<div>
<span
ref={(ref) => {
createRenderEffect(() => {
ref.innerHTML = props.spoilerText
? props.emojis
? resolveCustomEmoji(props.spoilerText, props.emojis)
: props.spoilerText
: "";
});
}}
></span>
2024-11-20 16:33:30 +08:00
<Button onClick={props.onToggleReveal}>{t("cw")}</Button>
2024-11-20 16:24:57 +08:00
</div>
</Show>
<Show when={shouldRevealContent()}>
<div
class="content"
ref={(ref) =>
createRenderEffect(() => {
ref.innerHTML = props.source
? props.emojis
? resolveCustomEmoji(props.source, props.emojis)
: props.source
: "";
})
}
></div>
</Show>
</div>
);
};
2024-11-20 15:51:14 +08:00
export default TootContent;