TootList: mentions in toot links to profile page
All checks were successful
/ depoly (push) Successful in 1m17s

- bug: main toot in TootBottomSheet does not link
  profile
This commit is contained in:
thislight 2024-10-30 19:25:58 +08:00
parent 92cc451811
commit 31b27237cd
No known key found for this signature in database
GPG key ID: FCFE5192241CCD4E
5 changed files with 165 additions and 91 deletions

View file

@ -5,20 +5,13 @@ import {
type JSX,
Show,
createRenderEffect,
createSignal,
createEffect,
type Accessor,
createMemo,
} from "solid-js";
import tootStyle from "./toot.module.css";
import { formatRelative } from "date-fns";
import Img from "../material/Img.js";
import {
Body1,
Body2,
Caption,
Subheading,
Title,
} from "../material/typography.js";
import { Body1, Body2, Title } from "../material/typography.js";
import { css } from "solid-styled";
import {
BookmarkAddOutlined,
@ -32,7 +25,7 @@ import {
} from "@suid/icons-material";
import { useTimeSource } from "../platform/timesrc.js";
import { resolveCustomEmoji } from "../masto/toot.js";
import { Divider, IconButton } from "@suid/material";
import { Divider } from "@suid/material";
import cardStyle from "../material/cards.module.css";
import Button from "../material/Button.js";
import MediaAttachmentGrid from "./MediaAttachmentGrid.js";
@ -43,13 +36,24 @@ import { canShare, share } from "../platform/share";
import { makeAcctText, useDefaultSession } from "../masto/clients";
import { useNavigate } from "@solidjs/router";
function preventDefault(event: Event) {
event.preventDefault();
}
type TootContentViewProps = {
source?: string;
emojis?: mastodon.v1.CustomEmoji[];
mentions: mastodon.v1.StatusMention[];
} & JSX.HTMLAttributes<HTMLDivElement>;
const TootContentView: Component<TootContentViewProps> = (props) => {
const [managed, rest] = splitProps(props, ["source", "emojis"]);
const session = useDefaultSession();
const [managed, rest] = splitProps(props, ["source", "emojis", "mentions"]);
const clientFinder = createMemo(() =>
session() ? makeAcctText(session()!) : undefined,
);
return (
<div
ref={(ref) => {
@ -60,6 +64,21 @@ const TootContentView: Component<TootContentViewProps> = (props) => {
: 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.rel = "acct";
e.dataset.client = finder;
e.dataset.acctId = mention.id.toString();
}
}
});
}}
{...rest}
></div>
@ -212,16 +231,18 @@ function TootActionGroup<T extends mastodon.v1.Status>(
);
}
function TootAuthorGroup(props: {
status: mastodon.v1.Status;
now: Date;
onClick?: JSX.EventHandlerUnion<HTMLDivElement, MouseEvent>;
}) {
const toot = () => props.status;
function TootAuthorGroup(
props: {
status: mastodon.v1.Status;
now: Date;
} & JSX.HTMLElementTags["div"],
) {
const [managed, rest] = splitProps(props, ["status", "now"]);
const toot = () => managed.status;
const dateFnLocale = useDateFnLocale();
return (
<div class={tootStyle.tootAuthorGrp} onClick={props.onClick}>
<div class={tootStyle.tootAuthorGrp} {...rest}>
<Img src={toot().account.avatar} class={tootStyle.tootAvatar} />
<div class={tootStyle.tootAuthorNameGrp}>
<Body2
@ -236,7 +257,7 @@ function TootAuthorGroup(props: {
}}
/>
<time datetime={toot().createdAt}>
{formatRelative(toot().createdAt, props.now, {
{formatRelative(toot().createdAt, managed.now, {
locale: dateFnLocale(),
})}
</time>
@ -431,10 +452,17 @@ const RegularToot: Component<TootCardProps> = (props) => {
</span>
</div>
</Show>
<TootAuthorGroup status={toot()} now={now()} onClick={openProfile} />
<TootAuthorGroup
status={toot()}
now={now()}
data-rel="acct"
data-client={session() ? makeAcctText(session()!) : undefined}
data-acct-id={toot().account.id}
/>
<TootContentView
source={toot().content}
emojis={toot().emojis}
mentions={toot().mentions}
class={tootStyle.tootContent}
/>
<Show when={toot().card}>