Render thumb #id as an inline post thumbnail in DText
- New PostThumb component fetches the post through the e621 client (cached 30 minutes, no retries) and renders its preview image linked to the in-app post page, with the post id underneath - Falls back to an external e621 link while loading or when the post cannot be fetched
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
import { effectiveCredentials, fetchPost } from "@/lib/e621";
|
||||||
|
import { useE621 } from "@/store/e621";
|
||||||
|
|
||||||
|
export function PostThumb({ postId }: { postId: number }) {
|
||||||
|
const credentials = useE621((state) => state.credentials);
|
||||||
|
|
||||||
|
const query = useQuery({
|
||||||
|
queryKey: ["e621", "post-thumb", postId, credentials?.username ?? ""],
|
||||||
|
queryFn: ({ signal }) =>
|
||||||
|
fetchPost(effectiveCredentials(credentials), postId, signal),
|
||||||
|
staleTime: 30 * 60_000,
|
||||||
|
gcTime: 60 * 60_000,
|
||||||
|
retry: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const preview = query.data?.preview.url;
|
||||||
|
|
||||||
|
if (preview) {
|
||||||
|
return (
|
||||||
|
<span className="my-1 inline-block align-top">
|
||||||
|
<Link
|
||||||
|
to={`/online/view/${postId}`}
|
||||||
|
title={`Post #${postId}`}
|
||||||
|
className="group inline-block"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={preview}
|
||||||
|
alt={`Post #${postId}`}
|
||||||
|
loading="lazy"
|
||||||
|
className="max-h-40 rounded border border-ctp-surface0 transition group-hover:border-ctp-surface2"
|
||||||
|
/>
|
||||||
|
<span className="mt-0.5 block text-center font-mono text-[10px] text-ctp-overlay0">
|
||||||
|
#{postId}
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href={`https://e621.net/posts/${postId}`}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="text-ctp-blue hover:underline"
|
||||||
|
>
|
||||||
|
thumb #{postId}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
|
|
||||||
import { Spoiler } from "@/components/Spoiler";
|
import { Spoiler } from "@/components/Spoiler";
|
||||||
|
import { PostThumb } from "@/features/online/PostThumb";
|
||||||
|
|
||||||
export const DEFAULT_E621_BASE_URL = "https://e621.net";
|
export const DEFAULT_E621_BASE_URL = "https://e621.net";
|
||||||
|
|
||||||
@@ -51,7 +52,6 @@ const ENTITY_PATHS: Record<string, string> = {
|
|||||||
takedown: "/takedowns/{id}",
|
takedown: "/takedowns/{id}",
|
||||||
record: "/user_feedbacks/{id}",
|
record: "/user_feedbacks/{id}",
|
||||||
ticket: "/tickets/{id}",
|
ticket: "/tickets/{id}",
|
||||||
thumb: "/posts/{id}",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const LINK_RE = new RegExp(
|
const LINK_RE = new RegExp(
|
||||||
@@ -159,11 +159,13 @@ function linkify(text: string, keyPrefix: string, baseUrl: string): ReactNode[]
|
|||||||
} else if (match[11] !== undefined) {
|
} else if (match[11] !== undefined) {
|
||||||
nodes.push(<span key={key} id={match[11]} />);
|
nodes.push(<span key={key} id={match[11]} />);
|
||||||
} else if (match[12] !== undefined && match[13] !== undefined) {
|
} else if (match[12] !== undefined && match[13] !== undefined) {
|
||||||
const path = ENTITY_PATHS[match[12]]?.replace("{id}", match[13]);
|
if (match[12] === "thumb") {
|
||||||
const label = `${match[12]} #${match[13]}`;
|
nodes.push(<PostThumb key={key} postId={Number(match[13])} />);
|
||||||
nodes.push(
|
} else {
|
||||||
path ? anchor(key, `${baseUrl}${path}`, label) : label,
|
const path = ENTITY_PATHS[match[12]]?.replace("{id}", match[13]);
|
||||||
);
|
const label = `${match[12]} #${match[13]}`;
|
||||||
|
nodes.push(path ? anchor(key, `${baseUrl}${path}`, label) : label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lastIndex = regex.lastIndex;
|
lastIndex = regex.lastIndex;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user