refactor getting html for files and previews

This commit is contained in:
Max Leiter 2022-11-12 17:11:05 -08:00
parent c41cf7c5ef
commit ecd4521403
13 changed files with 70 additions and 1088 deletions

View file

@ -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

View file

@ -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()
}

View file

@ -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,

View file

@ -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);
}

View file

@ -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 = [

View file

@ -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
}

View file

@ -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",

View file

@ -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
}
)

View file

@ -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)

View file

@ -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" })
}

View file

@ -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"

View file

@ -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