mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 12:17:24 +00:00
Improve related resource rendering
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
|||||||
Storage,
|
Storage,
|
||||||
Comment,
|
Comment,
|
||||||
Tag,
|
Tag,
|
||||||
|
Resource,
|
||||||
} from "../network/models.ts";
|
} from "../network/models.ts";
|
||||||
import { network } from "../network/network.ts";
|
import { network } from "../network/network.ts";
|
||||||
import showToast from "../components/toast.ts";
|
import showToast from "../components/toast.ts";
|
||||||
@@ -397,8 +398,6 @@ function DeleteResourceDialog({
|
|||||||
const context = createContext<() => void>(() => { });
|
const context = createContext<() => void>(() => { });
|
||||||
|
|
||||||
function Article({ resource }: { resource: ResourceDetails }) {
|
function Article({ resource }: { resource: ResourceDetails }) {
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article>
|
<article>
|
||||||
<Markdown
|
<Markdown
|
||||||
@@ -502,25 +501,68 @@ function Article({ resource }: { resource: ResourceDetails }) {
|
|||||||
},
|
},
|
||||||
a: ({ node, ...props }) => {
|
a: ({ node, ...props }) => {
|
||||||
const href = props.href as string;
|
const href = props.href as string;
|
||||||
|
const origin = window.location.origin;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
href.startsWith(window.location.origin) ||
|
href.startsWith(origin) ||
|
||||||
href.startsWith("/")
|
href.startsWith("/")
|
||||||
) {
|
) {
|
||||||
let path = href;
|
let path = href;
|
||||||
if (path.startsWith(window.location.origin)) {
|
if (path.startsWith(origin)) {
|
||||||
path = path.substring(window.location.origin.length);
|
path = path.substring(origin.length);
|
||||||
}
|
}
|
||||||
const content = props.children?.toString();
|
const content = props.children?.toString();
|
||||||
if (path.startsWith("/resources/")) {
|
if (path.startsWith("/resources/")) {
|
||||||
const id = path.substring("/resources/".length);
|
const id = path.substring("/resources/".length);
|
||||||
for (const r of resource.related ?? []) {
|
for (const r of resource.related ?? []) {
|
||||||
if (r.id.toString() === id) {
|
if (r.id.toString() === id) {
|
||||||
|
return <RelatedResourceCard r={r} content={content} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return <a target={"_blank"} {...props}></a>;
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{resource.article.replaceAll("\n", " \n")}
|
||||||
|
</Markdown>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function RelatedResourceCard({ r, content }: { r: Resource, content?: string }) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [articleWidth, setArticleWidth] = useState<number | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const observer = new ResizeObserver((entries) => {
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.contentRect.width !== articleWidth) {
|
||||||
|
setArticleWidth(entry.contentRect.width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const articleElement = document.querySelector("article");
|
||||||
|
if (articleElement) {
|
||||||
|
observer.observe(articleElement);
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const imgHeight =
|
const imgHeight =
|
||||||
r.image && r.image.width > r.image.height ? 320 : 420;
|
r.image && r.image.width > r.image.height ? 320 : 420;
|
||||||
const imgWidth = r.image
|
let imgWidth = r.image
|
||||||
? (r.image.width / r.image.height) * imgHeight
|
? (r.image.width / r.image.height) * imgHeight
|
||||||
: undefined;
|
: undefined;
|
||||||
|
if (articleWidth && imgWidth && imgWidth > articleWidth) {
|
||||||
|
imgWidth = articleWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!articleWidth) {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className={"inline-flex max-w-full"}>
|
<span className={"inline-flex max-w-full"}>
|
||||||
@@ -539,6 +581,7 @@ function Article({ resource }: { resource: ResourceDetails }) {
|
|||||||
style={{
|
style={{
|
||||||
width: imgWidth,
|
width: imgWidth,
|
||||||
height: imgHeight,
|
height: imgHeight,
|
||||||
|
objectFit: "cover",
|
||||||
}}
|
}}
|
||||||
className={"h-full min-h-0 object-cover min-w-0"}
|
className={"h-full min-h-0 object-cover min-w-0"}
|
||||||
alt={"cover"}
|
alt={"cover"}
|
||||||
@@ -579,19 +622,6 @@ function Article({ resource }: { resource: ResourceDetails }) {
|
|||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <a target={"_blank"} {...props}></a>;
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{resource.article.replaceAll("\n", " \n")}
|
|
||||||
</Markdown>
|
|
||||||
</article>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function fileSizeToString(size: number) {
|
function fileSizeToString(size: number) {
|
||||||
if (size < 1024) {
|
if (size < 1024) {
|
||||||
|
Reference in New Issue
Block a user