Skip to the content

Capsid menu

app/components/post-mentions.tsx

52 lines and 3 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.

Functions

The functions of post-mentions.tsx
FunctionLinesComplexityCoveredCRAPMutation
Mention10 to 396No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
PostMentions42 to 571No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code
<anonymous:51>51 to 531No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code

Imports

It imports app/lib/long-date.mjs, app/lib/webmention/urls.mjs. Imported by app/routes/blog.$slug.tsx.

Source

import { longDateUTC } from "~/lib/long-date.mjs";
import { safeHttpHref } from "~/lib/webmention/urls.mjs";

import type { Route } from "../routes/+types/blog.$slug";

/**
 * Mention text is third party: rendered as escaped React children, never `dangerouslySetInnerHTML`,
 * and the one `href` is re-parsed by `safeHttpHref`.
 */
function Mention({
  mention,
}: {
  mention: Route.ComponentProps["loaderData"]["mentions"][number];
}) {
  /* A row whose URLs both fail still renders as text: dropping it would hide something the admin approved. */
  const href = safeHttpHref(mention.authorUrl) ?? safeHttpHref(mention.sourceUrl);

  /* Falls back to the source URL, a fact, never an invented name attributed to a real person. */
  const name = mention.authorName ?? mention.sourceUrl;
  const decided = longDateUTC(mention.decidedAt);

  return (
    <li>
      {href ? (
        <a href={href} rel="nofollow ugc noopener noreferrer">
          {name}
        </a>
      ) : (
        <span>{name}</span>
      )}
      {mention.excerpt ? <p className="post-mention-excerpt">{mention.excerpt}</p> : null}
      {decided ? (
        <time className="post-mention-date" dateTime={new Date(mention.decidedAt!).toISOString()}>
          {decided}
        </time>
      ) : null}
    </li>
  );
}

/** Approved webmentions, each a `Mention`. */
export function PostMentions({
  mentions,
}: {
  mentions: Route.ComponentProps["loaderData"]["mentions"];
}) {
  return (
    <section className="post-mentions" aria-labelledby="mentions-heading">
      <h2 id="mentions-heading">Mentions</h2>
      <ul>
        {mentions.map((mention) => (
          <Mention key={mention.id} mention={mention} />
        ))}
      </ul>
    </section>
  );
}