mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 12:17:24 +00:00
Render internal links to card.
This commit is contained in:
@@ -67,6 +67,7 @@ export interface ResourceDetails {
|
|||||||
author: User;
|
author: User;
|
||||||
views: number;
|
views: number;
|
||||||
downloads: number;
|
downloads: number;
|
||||||
|
related: Resource[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Storage {
|
export interface Storage {
|
||||||
|
@@ -27,10 +27,6 @@ class Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
if (import.meta.env.MODE === 'development') {
|
|
||||||
this.baseUrl = 'http://localhost:3000';
|
|
||||||
this.apiBaseUrl = 'http://localhost:3000/api';
|
|
||||||
}
|
|
||||||
axios.defaults.validateStatus = _ => true
|
axios.defaults.validateStatus = _ => true
|
||||||
axios.interceptors.request.use((config) => {
|
axios.interceptors.request.use((config) => {
|
||||||
if (app.token) {
|
if (app.token) {
|
||||||
|
@@ -123,7 +123,7 @@ export default function ResourcePage() {
|
|||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<div key={"article"} className="tab-content p-2">
|
<div key={"article"} className="tab-content p-2">
|
||||||
<Article article={resource.article}/>
|
<Article resource={resource} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label className="tab transition-all">
|
<label className="tab transition-all">
|
||||||
@@ -221,9 +221,67 @@ function DeleteResourceDialog({resourceId, uploaderId}: { resourceId: number, up
|
|||||||
const context = createContext<() => void>(() => {
|
const context = createContext<() => void>(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
function Article({article}: { article: string }) {
|
function Article({ resource }: { resource: ResourceDetails }) {
|
||||||
return <article>
|
const articleRef = useRef<HTMLDivElement>(null)
|
||||||
<Markdown>{article}</Markdown>
|
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (articleRef.current) {
|
||||||
|
console.log("render")
|
||||||
|
for (let child of articleRef.current.children) {
|
||||||
|
console.log("child", child)
|
||||||
|
if (child.tagName === "P" && child.children.length === 1 && child.children[0].tagName === "A") {
|
||||||
|
const href = (child.children[0] as HTMLAnchorElement).href as string
|
||||||
|
console.log("href", href)
|
||||||
|
console.log("origin", window.location.origin)
|
||||||
|
if (href.startsWith(window.location.origin) || href.startsWith("/")) {
|
||||||
|
console.log("href starts with origin")
|
||||||
|
let path = href
|
||||||
|
if (path.startsWith(window.location.origin)) {
|
||||||
|
path = path.substring(window.location.origin.length)
|
||||||
|
}
|
||||||
|
if (path.startsWith("/resources/")) {
|
||||||
|
const content = child.children[0].innerHTML
|
||||||
|
const id = path.substring("/resources/".length)
|
||||||
|
for (let r of resource.related) {
|
||||||
|
if (r.id.toString() === id) {
|
||||||
|
child.children[0].classList.add("hidden")
|
||||||
|
let div = document.createElement("div")
|
||||||
|
div.innerHTML = `
|
||||||
|
${child.innerHTML}
|
||||||
|
<div class="card card-border max-w-72 sm:max-w-full border-base-300 my-2 sm:card-side">
|
||||||
|
${r.image ? `
|
||||||
|
<figure>
|
||||||
|
<img
|
||||||
|
class="w-full h-40 sm:h-full sm:w-32 object-cover"
|
||||||
|
src="${network.getImageUrl(r.image!.id)}"
|
||||||
|
alt="Cover" />
|
||||||
|
</figure>
|
||||||
|
` : ""}
|
||||||
|
<div class="card-body" style="padding: 1rem">
|
||||||
|
<h3>${r.title}</h4>
|
||||||
|
<p class="text-sm">${content}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
child.appendChild(div)
|
||||||
|
}
|
||||||
|
(child as HTMLParagraphElement).onclick = (e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
e.preventDefault()
|
||||||
|
navigate(`/resources/${r.id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [resource])
|
||||||
|
|
||||||
|
return <article ref={articleRef}>
|
||||||
|
<Markdown>{resource.article}</Markdown>
|
||||||
</article>
|
</article>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,4 +5,12 @@ import tailwindcss from '@tailwindcss/vite'
|
|||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), tailwindcss(),],
|
plugins: [react(), tailwindcss(),],
|
||||||
|
server: {
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'http://localhost:3000',
|
||||||
|
changeOrigin: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
@@ -91,7 +91,7 @@ func parseResourceIfPresent(line string, host string) *model.ResourceView {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if parsed.Hostname() != host {
|
if parsed.IsAbs() && parsed.Hostname() != host {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
path := parsed.Path
|
path := parsed.Path
|
||||||
|
Reference in New Issue
Block a user