refactor getting html for files and previews
This commit is contained in:
parent
c41cf7c5ef
commit
ecd4521403
13 changed files with 70 additions and 1088 deletions
|
@ -1,7 +1,7 @@
|
|||
import { memo, useEffect, useState } from "react"
|
||||
import styles from "./preview.module.css"
|
||||
import "@styles/markdown.css"
|
||||
import "./marked.css"
|
||||
import "@styles/syntax.css"
|
||||
|
||||
type Props = {
|
||||
height?: number | string
|
||||
|
@ -20,35 +20,34 @@ const MarkdownPreview = ({
|
|||
const [isLoading, setIsLoading] = useState<boolean>(true)
|
||||
useEffect(() => {
|
||||
async function fetchPost() {
|
||||
if (fileId) {
|
||||
const resp = await fetch(`/api/file/html/${fileId}`, {
|
||||
method: "GET"
|
||||
})
|
||||
if (resp.ok) {
|
||||
const res = await resp.text()
|
||||
setPreview(res)
|
||||
setIsLoading(false)
|
||||
}
|
||||
} else if (content) {
|
||||
const urlQuery = new URLSearchParams({
|
||||
title: title || "",
|
||||
content
|
||||
})
|
||||
// POST to avoid query string length limit
|
||||
const method = fileId ? "GET" : "POST"
|
||||
const path = fileId ? `/api/file/html/${fileId}` : "/api/file/get-html"
|
||||
const body = fileId
|
||||
? undefined
|
||||
: JSON.stringify({
|
||||
title: title || "",
|
||||
content: initial
|
||||
})
|
||||
|
||||
const resp = await fetch(`/api/file/get-html?${urlQuery}`, {
|
||||
method: "GET"
|
||||
})
|
||||
const resp = await fetch(path, {
|
||||
method: method,
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body
|
||||
})
|
||||
|
||||
if (resp.ok) {
|
||||
const res = await resp.text()
|
||||
setPreview(res)
|
||||
setIsLoading(false)
|
||||
}
|
||||
if (resp.ok) {
|
||||
const res = await resp.text()
|
||||
setPreview(res)
|
||||
}
|
||||
|
||||
setIsLoading(false)
|
||||
}
|
||||
fetchPost()
|
||||
}, [content, fileId, title])
|
||||
}, [initial, fileId, title])
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading ? (
|
||||
|
@ -60,7 +59,7 @@ const MarkdownPreview = ({
|
|||
)
|
||||
}
|
||||
|
||||
export default MarkdownPreview
|
||||
export default memo(MarkdownPreview)
|
||||
|
||||
export const StaticPreview = ({
|
||||
content,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,6 @@ const getPost = async (id: string) => {
|
|||
const post = await getPostById(id, true)
|
||||
const user = await getCurrentUser()
|
||||
|
||||
console.log("post is", post)
|
||||
if (!post) {
|
||||
return notFound()
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
@import "./syntax.css";
|
||||
@import "./inter.css";
|
||||
|
||||
:root {
|
||||
|
@ -71,7 +70,7 @@
|
|||
--article-color: #212121;
|
||||
--header-bg: rgba(255, 255, 255, 0.8);
|
||||
--gray-alpha: rgba(19, 20, 21, 0.5);
|
||||
--selection: rgba(0, 0, 0, 0.99);
|
||||
--selection: var(0, 0, 0, .6);
|
||||
}
|
||||
|
||||
* {
|
||||
|
@ -80,7 +79,8 @@
|
|||
|
||||
::selection {
|
||||
text-shadow: none;
|
||||
background: var(--selection);
|
||||
background: var(--fg) !important;
|
||||
color: var(--bg) !important;
|
||||
}
|
||||
|
||||
html,
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
.keyword {
|
||||
font-weight: bold;
|
||||
color: var(--keyword);
|
||||
color: var(--darker-gray);
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.punctuation,
|
||||
.token.string,
|
||||
.token.number,
|
||||
.token.builtin,
|
||||
.token.variable {
|
||||
color: var(--token);
|
||||
}
|
||||
|
||||
.token.string,
|
||||
.token.number,
|
||||
.token.boolean {
|
||||
color: var(--darker-gray);
|
||||
}
|
||||
|
||||
.token.comment {
|
||||
color: var(--comment);
|
||||
}
|
||||
|
@ -22,3 +26,4 @@
|
|||
.token.attr-name {
|
||||
color: var(--name);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ export const codeFileExtensions = [
|
|||
"cxx",
|
||||
"go",
|
||||
"h",
|
||||
"m",
|
||||
"ha",
|
||||
"hpp",
|
||||
"htm",
|
||||
"html",
|
||||
|
@ -93,6 +95,7 @@ export const codeFileExtensions = [
|
|||
"rb",
|
||||
"rs",
|
||||
"s",
|
||||
"sh",
|
||||
"sass",
|
||||
"scala",
|
||||
"scss",
|
||||
|
@ -109,7 +112,8 @@ export const codeFileExtensions = [
|
|||
"xml",
|
||||
"y",
|
||||
"yaml",
|
||||
"zig"
|
||||
"fish",
|
||||
|
||||
]
|
||||
|
||||
export const allowedFileExtensions = [
|
||||
|
|
|
@ -26,20 +26,16 @@ export async function getHtmlFromFile({
|
|||
}
|
||||
const type = fileType()
|
||||
let contentToRender: string = content || ""
|
||||
|
||||
if (!renderAsMarkdown.includes(type)) {
|
||||
contentToRender = `
|
||||
|
||||
~~~${type}
|
||||
${content}
|
||||
~~~
|
||||
|
||||
`
|
||||
} else {
|
||||
contentToRender = "\n" + content
|
||||
}
|
||||
|
||||
const html = markdown(contentToRender, {
|
||||
})
|
||||
const html = markdown(contentToRender)
|
||||
return html
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"@mdx-js/react": "^2.1.5",
|
||||
"@next-auth/prisma-adapter": "^1.0.5",
|
||||
"@prisma/client": "^4.6.1",
|
||||
"@types/prismjs": "^1.26.0",
|
||||
"@wcj/markdown-to-html": "^2.1.2",
|
||||
"bcrypt": "^5.1.0",
|
||||
"client-zip": "2.2.1",
|
||||
|
@ -33,6 +34,7 @@
|
|||
"next-mdx-remote": "^4.2.0",
|
||||
"next-themes": "npm:@wits/next-themes@0.2.7",
|
||||
"prism-react-renderer": "^1.3.5",
|
||||
"prismjs": "^1.29.0",
|
||||
"rc-table": "7.24.1",
|
||||
"react": "18.2.0",
|
||||
"react-datepicker": "4.8.0",
|
||||
|
|
|
@ -1,47 +1,28 @@
|
|||
import { withMethods } from "@lib/api-middleware/with-methods"
|
||||
import { getHtmlFromFile } from "@lib/server/get-html-from-drift-file"
|
||||
import { parseQueryParam } from "@lib/server/parse-query-param"
|
||||
import { prisma } from "@lib/server/prisma"
|
||||
import { NextApiRequest, NextApiResponse } from "next"
|
||||
|
||||
export default withMethods(
|
||||
["GET"],
|
||||
["POST"],
|
||||
async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const query = req.query
|
||||
const fileId = parseQueryParam(query.fileId)
|
||||
const content = parseQueryParam(query.content)
|
||||
const title = parseQueryParam(query.title) || "Untitled"
|
||||
const body = req.body
|
||||
const content = parseQueryParam(body.content)
|
||||
const title = parseQueryParam(body.title) || "Untitled"
|
||||
|
||||
if (fileId && (content || title)) {
|
||||
return res.status(400).json({ error: "Too many arguments" })
|
||||
if (!content || !title) {
|
||||
return res.status(400).json({ error: "Missing arguments" })
|
||||
}
|
||||
|
||||
if (fileId) {
|
||||
const file = await prisma.file.findUnique({
|
||||
where: {
|
||||
id: fileId
|
||||
}
|
||||
})
|
||||
const renderedHTML = await getHtmlFromFile({
|
||||
title,
|
||||
content
|
||||
})
|
||||
|
||||
if (!file) {
|
||||
return res.status(404).json({ error: "File not found" })
|
||||
}
|
||||
|
||||
return res.json(file.html)
|
||||
} else {
|
||||
if (!content || !title) {
|
||||
return res.status(400).json({ error: "Missing arguments" })
|
||||
}
|
||||
|
||||
const renderedHTML = await getHtmlFromFile({
|
||||
title,
|
||||
content
|
||||
})
|
||||
|
||||
res.setHeader("Content-Type", "text/plain")
|
||||
res.status(200).write(renderedHTML)
|
||||
res.end()
|
||||
return
|
||||
}
|
||||
res.setHeader("Content-Type", "text/plain")
|
||||
res.setHeader("Cache-Control", "public, max-age=4800")
|
||||
res.status(200).write(renderedHTML)
|
||||
res.end()
|
||||
return
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { NextApiRequest, NextApiResponse } from "next"
|
||||
import { prisma } from "@lib/server/prisma"
|
||||
import { parseQueryParam } from "@lib/server/parse-query-param"
|
||||
import { withMethods } from "@lib/api-middleware/with-methods"
|
||||
|
||||
const getRawFile = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const file = await prisma.file.findUnique({
|
||||
|
@ -17,6 +18,6 @@ const getRawFile = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
res.setHeader("Cache-Control", "public, max-age=4800")
|
||||
res.status(200).write(file.html)
|
||||
res.end()
|
||||
|
||||
}
|
||||
export default getRawFile
|
||||
|
||||
export default withMethods(["GET"], getRawFile)
|
||||
|
|
|
@ -17,7 +17,6 @@ async function handleGet(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||
const id = parseQueryParam(req.query.id)
|
||||
const files = req.query.files ? parseQueryParam(req.query.files) : true
|
||||
|
||||
console.log("post id is", id)
|
||||
if (!id) {
|
||||
return res.status(400).json({ error: "Missing id" })
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
// a nextjs api handerl
|
||||
|
||||
import config from "@lib/config"
|
||||
import { getHtmlFromMarkdown } from "@lib/remark-plugins"
|
||||
import { getHtmlFromFile } from "@lib/server/get-html-from-drift-file"
|
||||
import markdown from "@wcj/markdown-to-html"
|
||||
|
||||
import { NextApiRequest, NextApiResponse } from "next"
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ specifiers:
|
|||
'@types/jsonwebtoken': ^8.5.9
|
||||
'@types/marked': ^4.0.7
|
||||
'@types/node': 17.0.23
|
||||
'@types/prismjs': ^1.26.0
|
||||
'@types/react': 18.0.9
|
||||
'@types/react-datepicker': 4.4.1
|
||||
'@types/react-dom': 18.0.3
|
||||
|
@ -38,6 +39,7 @@ specifiers:
|
|||
prettier: 2.6.2
|
||||
prism-react-renderer: ^1.3.5
|
||||
prisma: ^4.6.1
|
||||
prismjs: ^1.29.0
|
||||
rc-table: 7.24.1
|
||||
react: 18.2.0
|
||||
react-datepicker: 4.8.0
|
||||
|
@ -71,6 +73,7 @@ dependencies:
|
|||
'@mdx-js/react': 2.1.5_react@18.2.0
|
||||
'@next-auth/prisma-adapter': 1.0.5_2pl3b2nwmjya7el2zbe6cwkney
|
||||
'@prisma/client': 4.6.1_prisma@4.6.1
|
||||
'@types/prismjs': 1.26.0
|
||||
'@wcj/markdown-to-html': 2.1.2
|
||||
bcrypt: 5.1.0
|
||||
client-zip: 2.2.1
|
||||
|
@ -85,6 +88,7 @@ dependencies:
|
|||
next-mdx-remote: 4.2.0_biqbaboplfbrettd7655fr4n2y
|
||||
next-themes: /@wits/next-themes/0.2.7_hsmqkug4agizydugca45idewda
|
||||
prism-react-renderer: 1.3.5_react@18.2.0
|
||||
prismjs: 1.29.0
|
||||
rc-table: 7.24.1_biqbaboplfbrettd7655fr4n2y
|
||||
react: 18.2.0
|
||||
react-datepicker: 4.8.0_biqbaboplfbrettd7655fr4n2y
|
||||
|
@ -4381,6 +4385,11 @@ packages:
|
|||
dependencies:
|
||||
'@prisma/engines': 4.6.1
|
||||
|
||||
/prismjs/1.29.0:
|
||||
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/process-nextick-args/2.0.1:
|
||||
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||
dev: true
|
||||
|
|
Loading…
Reference in a new issue