mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 12:17:24 +00:00
Improve article rendering
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
article {
|
article {
|
||||||
& {
|
& {
|
||||||
color: var(--color-base-content)
|
color: var(--color-base-content);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@@ -92,9 +92,6 @@ article {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, system-ui;
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, system-ui;
|
||||||
}
|
}
|
||||||
.line-break {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
iframe{
|
iframe{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@@ -238,7 +238,8 @@ function Article({resource}: { resource: ResourceDetails }) {
|
|||||||
|
|
||||||
return <article>
|
return <article>
|
||||||
<Markdown components={{
|
<Markdown components={{
|
||||||
"p": ({node, ...props}) => {
|
p: ({node, ...props}) => {
|
||||||
|
console.log(props.children)
|
||||||
if (typeof props.children === "object" && (props.children as ReactElement).type === "strong") {
|
if (typeof props.children === "object" && (props.children as ReactElement).type === "strong") {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const child = (props.children as ReactElement).props.children.toString() as string
|
const child = (props.children as ReactElement).props.children.toString() as string
|
||||||
@@ -250,46 +251,17 @@ function Article({resource}: { resource: ResourceDetails }) {
|
|||||||
return !(s.startsWith("width") || s.startsWith("height") || s.startsWith("class") || s.startsWith("style"));
|
return !(s.startsWith("width") || s.startsWith("height") || s.startsWith("class") || s.startsWith("style"));
|
||||||
})
|
})
|
||||||
html = splits.join(" ")
|
html = splits.join(" ")
|
||||||
return <div className={`w-full max-w-xl rounded-xl overflow-clip ${html.includes("youtube") ? "aspect-video" : "h-48 sm:h-64"}`} dangerouslySetInnerHTML={{
|
return <div
|
||||||
__html: html
|
className={`w-full max-w-xl rounded-xl overflow-clip ${html.includes("youtube") ? "aspect-video" : "h-48 sm:h-64"}`}
|
||||||
}}></div>
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: html
|
||||||
|
}}></div>
|
||||||
}
|
}
|
||||||
} else if (typeof props.children === "object" && (props.children as ReactElement).type === "a") {
|
// @ts-ignore
|
||||||
|
} else if (typeof props.children === "object" && props.children.props && props.children.props.href) {
|
||||||
const a = props.children as ReactElement
|
const a = props.children as ReactElement
|
||||||
const childProps = a.props as any
|
const childProps = a.props as any
|
||||||
const href = childProps.href as string
|
const href = childProps.href as string
|
||||||
if (href.startsWith(window.location.origin) || href.startsWith("/")) {
|
|
||||||
let path = href
|
|
||||||
if (path.startsWith(window.location.origin)) {
|
|
||||||
path = path.substring(window.location.origin.length)
|
|
||||||
}
|
|
||||||
const content = childProps.children?.toString()
|
|
||||||
if (path.startsWith("/resources/")) {
|
|
||||||
const id = path.substring("/resources/".length)
|
|
||||||
for (const r of resource.related) {
|
|
||||||
if (r.id.toString() === id) {
|
|
||||||
return <div className="card card-border w-full border-base-300 my-3 sm:card-side cursor-pointer"
|
|
||||||
onClick={() => {
|
|
||||||
navigate(`/resources/${r.id}`)
|
|
||||||
}}>
|
|
||||||
{r.image ? <figure>
|
|
||||||
<img
|
|
||||||
className="w-full h-40 max-h-72 sm:h-full sm:w-48 md:w-58 lg:w-72 object-cover"
|
|
||||||
src={network.getImageUrl(r.image!.id)}
|
|
||||||
style={{
|
|
||||||
boxShadow: "0 0 0 rgba(0, 0, 0)",
|
|
||||||
}}
|
|
||||||
alt="Cover"/>
|
|
||||||
</figure> : null}
|
|
||||||
<div className="card-body" style={{padding: "1rem"}}>
|
|
||||||
<h3>{r.title}</h3>
|
|
||||||
<p className="text-sm">{content}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (childProps.children?.length === 2) {
|
if (childProps.children?.length === 2) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -304,12 +276,12 @@ function Article({resource}: { resource: ResourceDetails }) {
|
|||||||
return <a
|
return <a
|
||||||
className={"inline-block card card-border border-base-300 no-underline bg-base-200 hover:shadow transition-shadow my-2"}
|
className={"inline-block card card-border border-base-300 no-underline bg-base-200 hover:shadow transition-shadow my-2"}
|
||||||
target={"_blank"} href={href}>
|
target={"_blank"} href={href}>
|
||||||
<figure className={"max-h-96"}>
|
<figure className={"max-h-96"}>
|
||||||
{img}
|
{img}
|
||||||
</figure>
|
</figure>
|
||||||
<div className={"card-body text-base-content text-lg"}>
|
<div className={"card-body text-base-content text-lg"}>
|
||||||
{second}
|
{second}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,6 +300,55 @@ function Article({resource}: { resource: ResourceDetails }) {
|
|||||||
}
|
}
|
||||||
return <p {...props}>{props.children}</p>
|
return <p {...props}>{props.children}</p>
|
||||||
},
|
},
|
||||||
|
a: ({node, ...props}) => {
|
||||||
|
const href = props.href as string
|
||||||
|
|
||||||
|
if (href.startsWith(window.location.origin) || href.startsWith("/")) {
|
||||||
|
let path = href
|
||||||
|
if (path.startsWith(window.location.origin)) {
|
||||||
|
path = path.substring(window.location.origin.length)
|
||||||
|
}
|
||||||
|
const content = props.children?.toString()
|
||||||
|
if (path.startsWith("/resources/")) {
|
||||||
|
const id = path.substring("/resources/".length)
|
||||||
|
for (const r of resource.related ?? []) {
|
||||||
|
if (r.id.toString() === id) {
|
||||||
|
return <span className={"inline-flex max-w-full"}>
|
||||||
|
<span
|
||||||
|
className={"m-2 max-w-full cursor-pointer inline-flex min-w-0 flex-col h-80 border border-base-300 rounded-xl no-underline"}
|
||||||
|
onClick={() => {
|
||||||
|
navigate(`/resources/${r.id}`, {replace: true})
|
||||||
|
}}>
|
||||||
|
{r.image && <img style={{
|
||||||
|
aspectRatio: r.image.width / r.image.height,
|
||||||
|
maxHeight: "100%",
|
||||||
|
}} className={"h-full min-h-0 object-cover min-w-0"} alt={"cover"}
|
||||||
|
src={network.getImageUrl(r.image?.id)}/>}
|
||||||
|
<span className={"inline-flex flex-col p-4"}>
|
||||||
|
<span style={{
|
||||||
|
maxWidth: "100%",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
lineBreak: "anywhere",
|
||||||
|
fontSize: "1.2rem",
|
||||||
|
fontWeight: "bold",
|
||||||
|
lineHeight: "1.5rem",
|
||||||
|
color: "var(--color-base-content)"
|
||||||
|
}}>{r.title}</span>
|
||||||
|
<span className={"h-2"}></span>
|
||||||
|
<span style={{
|
||||||
|
color: "var(--color-base-content)",
|
||||||
|
lineBreak: "anywhere",
|
||||||
|
}}>{content}</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return <a target={"_blank"} {...props}></a>
|
||||||
|
},
|
||||||
}}>{resource.article}</Markdown>
|
}}>{resource.article}</Markdown>
|
||||||
</article>
|
</article>
|
||||||
}
|
}
|
||||||
@@ -399,7 +420,8 @@ function CloudflarePopup({file}: { file: RFile }) {
|
|||||||
window.open(link, "_blank");
|
window.open(link, "_blank");
|
||||||
}}></Turnstile>
|
}}></Turnstile>
|
||||||
</div>
|
</div>
|
||||||
<p className={"text-xs text-base-content/80 m-2"}>{t("Please check your network if the verification takes too long or the captcha does not appear.")}</p>
|
<p
|
||||||
|
className={"text-xs text-base-content/80 m-2"}>{t("Please check your network if the verification takes too long or the captcha does not appear.")}</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user