From ecd452140389e4779b51e9f447fa8196f3368d10 Mon Sep 17 00:00:00 2001 From: Max Leiter Date: Sat, 12 Nov 2022 17:11:05 -0800 Subject: [PATCH] refactor getting html for files and previews --- .../app/(posts)/components/preview/index.tsx | 49 +- .../app/(posts)/components/preview/marked.css | 1011 ----------------- client/app/(posts)/post/[id]/page.tsx | 1 - client/app/styles/globals.css | 6 +- client/app/styles/syntax.css | 11 +- client/lib/constants.ts | 6 +- client/lib/server/get-html-from-drift-file.ts | 6 +- client/package.json | 2 + client/pages/api/file/get-html.ts | 49 +- client/pages/api/file/html/[id].ts | 5 +- client/pages/api/post/[id].ts | 1 - client/pages/api/welcome.ts | 2 - client/pnpm-lock.yaml | 9 + 13 files changed, 70 insertions(+), 1088 deletions(-) delete mode 100644 client/app/(posts)/components/preview/marked.css diff --git a/client/app/(posts)/components/preview/index.tsx b/client/app/(posts)/components/preview/index.tsx index 142c20d2..df973ce4 100644 --- a/client/app/(posts)/components/preview/index.tsx +++ b/client/app/(posts)/components/preview/index.tsx @@ -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(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, diff --git a/client/app/(posts)/components/preview/marked.css b/client/app/(posts)/components/preview/marked.css deleted file mode 100644 index bec7757f..00000000 --- a/client/app/(posts)/components/preview/marked.css +++ /dev/null @@ -1,1011 +0,0 @@ -[data-color-mode*="light"], -[data-color-mode*="light"] body, -.markdown-body[theme*="light"] { - --color-prettylights-syntax-comment: #6e7781; - --color-prettylights-syntax-constant: #0550ae; - --color-prettylights-syntax-entity: #8250df; - --color-prettylights-syntax-storage-modifier-import: #24292f; - --color-prettylights-syntax-entity-tag: #116329; - --color-prettylights-syntax-keyword: #cf222e; - --color-prettylights-syntax-string: #0a3069; - --color-prettylights-syntax-variable: #953800; - --color-prettylights-syntax-brackethighlighter-unmatched: #82071e; - --color-prettylights-syntax-invalid-illegal-text: #f6f8fa; - --color-prettylights-syntax-invalid-illegal-bg: #82071e; - --color-prettylights-syntax-carriage-return-text: #f6f8fa; - --color-prettylights-syntax-carriage-return-bg: #cf222e; - --color-prettylights-syntax-string-regexp: #116329; - --color-prettylights-syntax-markup-list: #3b2300; - --color-prettylights-syntax-markup-heading: #0550ae; - --color-prettylights-syntax-markup-italic: #24292f; - --color-prettylights-syntax-markup-bold: #24292f; - --color-prettylights-syntax-markup-deleted-text: #82071e; - --color-prettylights-syntax-markup-deleted-bg: #ffebe9; - --color-prettylights-syntax-markup-inserted-text: #116329; - --color-prettylights-syntax-markup-inserted-bg: #dafbe1; - --color-prettylights-syntax-markup-changed-text: #953800; - --color-prettylights-syntax-markup-changed-bg: #ffd8b5; - --color-prettylights-syntax-markup-ignored-text: #eaeef2; - --color-prettylights-syntax-markup-ignored-bg: #0550ae; - --color-prettylights-syntax-meta-diff-range: #8250df; - --color-prettylights-syntax-brackethighlighter-angle: #57606a; - --color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f; - --color-prettylights-syntax-constant-other-reference-link: #0a3069; - --color-fg-default: #24292f; - --color-fg-muted: #57606a; - --color-fg-subtle: #6e7781; - --color-canvas-default: #ffffff; - --color-canvas-subtle: #f6f8fa; - --color-border-default: #d0d7de; - --color-border-muted: hsla(210, 18%, 87%, 1); - --color-neutral-muted: rgba(175, 184, 193, 0.2); - --color-accent-fg: #0969da; - --color-accent-emphasis: #0969da; - --color-attention-subtle: #fff8c5; - --color-danger-fg: #cf222e; -} -[data-color-mode*="dark"], -[data-color-mode*="dark"] body, -.markdown-body[theme*="dark"] { - --color-prettylights-syntax-comment: #8b949e; - --color-prettylights-syntax-constant: #79c0ff; - --color-prettylights-syntax-entity: #d2a8ff; - --color-prettylights-syntax-storage-modifier-import: #c9d1d9; - --color-prettylights-syntax-entity-tag: #7ee787; - --color-prettylights-syntax-keyword: #ff7b72; - --color-prettylights-syntax-string: #a5d6ff; - --color-prettylights-syntax-variable: #ffa657; - --color-prettylights-syntax-brackethighlighter-unmatched: #f85149; - --color-prettylights-syntax-invalid-illegal-text: #f0f6fc; - --color-prettylights-syntax-invalid-illegal-bg: #8e1519; - --color-prettylights-syntax-carriage-return-text: #f0f6fc; - --color-prettylights-syntax-carriage-return-bg: #b62324; - --color-prettylights-syntax-string-regexp: #7ee787; - --color-prettylights-syntax-markup-list: #f2cc60; - --color-prettylights-syntax-markup-heading: #1f6feb; - --color-prettylights-syntax-markup-italic: #c9d1d9; - --color-prettylights-syntax-markup-bold: #c9d1d9; - --color-prettylights-syntax-markup-deleted-text: #ffdcd7; - --color-prettylights-syntax-markup-deleted-bg: #67060c; - --color-prettylights-syntax-markup-inserted-text: #aff5b4; - --color-prettylights-syntax-markup-inserted-bg: #033a16; - --color-prettylights-syntax-markup-changed-text: #ffdfb6; - --color-prettylights-syntax-markup-changed-bg: #5a1e02; - --color-prettylights-syntax-markup-ignored-text: #c9d1d9; - --color-prettylights-syntax-markup-ignored-bg: #1158c7; - --color-prettylights-syntax-meta-diff-range: #d2a8ff; - --color-prettylights-syntax-brackethighlighter-angle: #8b949e; - --color-prettylights-syntax-sublimelinter-gutter-mark: #484f58; - --color-prettylights-syntax-constant-other-reference-link: #a5d6ff; - --color-fg-default: #c9d1d9; - --color-fg-muted: #8b949e; - --color-fg-subtle: #484f58; - --color-canvas-default: #0d1117; - --color-canvas-subtle: #161b22; - --color-border-default: #30363d; - --color-border-muted: #21262d; - --color-neutral-muted: rgba(110, 118, 129, 0.4); - --color-accent-fg: #58a6ff; - --color-accent-emphasis: #1f6feb; - --color-attention-subtle: rgba(187, 128, 9, 0.15); - --color-danger-fg: #f85149; -} - -.markdown-body { - display: block; - -webkit-text-size-adjust: 100%; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, - sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; - font-size: 16px; - line-height: 1.5; - word-wrap: break-word; - color: var(--color-fg-default); - background-color: var(--color-canvas-default); -} - -.markdown-body details, -.markdown-body figcaption, -.markdown-body figure { - display: block; -} - -.markdown-body summary { - display: list-item; -} - -.markdown-body [hidden] { - display: none !important; -} - -.markdown-body a { - background-color: transparent; - color: var(--color-accent-fg); - text-decoration: none; -} - -.markdown-body a:active, -.markdown-body a:hover { - outline-width: 0; -} - -.markdown-body abbr[title] { - border-bottom: none; - text-decoration: underline dotted; -} - -.markdown-body b, -.markdown-body strong { - font-weight: 600; -} - -.markdown-body dfn { - font-style: italic; -} - -.markdown-body h1 { - margin: 0.67em 0; - font-weight: 600; - padding-bottom: 0.3em; - font-size: 2em; - border-bottom: 1px solid var(--color-border-muted); -} - -.markdown-body mark { - background-color: var(--color-attention-subtle); - color: var(--color-text-primary); -} - -.markdown-body small { - font-size: 90%; -} - -.markdown-body sub, -.markdown-body sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -.markdown-body sub { - bottom: -0.25em; -} - -.markdown-body sup { - top: -0.5em; -} - -.markdown-body img { - border-style: none; - max-width: 100%; - box-sizing: content-box; - background-color: var(--color-canvas-default); -} - -.markdown-body code, -.markdown-body kbd, -.markdown-body pre, -.markdown-body samp { - font-family: monospace, monospace; - font-size: 1em; -} - -.markdown-body figure { - margin: 1em 40px; -} - -.markdown-body hr { - box-sizing: content-box; - overflow: hidden; - background: transparent; - border-bottom: 1px solid var(--color-border-muted); - height: 0.25em; - padding: 0; - margin: 24px 0; - background-color: var(--color-border-default); - border: 0; -} - -.markdown-body input { - font: inherit; - margin: 0; - overflow: visible; - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -.markdown-body [type="button"], -.markdown-body [type="reset"], -.markdown-body [type="submit"] { - -webkit-appearance: button; -} - -.markdown-body [type="button"]::-moz-focus-inner, -.markdown-body [type="reset"]::-moz-focus-inner, -.markdown-body [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; -} - -.markdown-body [type="button"]:-moz-focusring, -.markdown-body [type="reset"]:-moz-focusring, -.markdown-body [type="submit"]:-moz-focusring { - outline: 1px dotted ButtonText; -} - -.markdown-body [type="checkbox"], -.markdown-body [type="radio"] { - box-sizing: border-box; - padding: 0; -} - -.markdown-body [type="number"]::-webkit-inner-spin-button, -.markdown-body [type="number"]::-webkit-outer-spin-button { - height: auto; -} - -.markdown-body [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; -} - -.markdown-body [type="search"]::-webkit-search-cancel-button, -.markdown-body [type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -.markdown-body ::-webkit-input-placeholder { - color: inherit; - opacity: 0.54; -} - -.markdown-body ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; -} - -.markdown-body a:hover { - text-decoration: underline; -} - -.markdown-body hr::before { - display: table; - content: ""; -} - -.markdown-body hr::after { - display: table; - clear: both; - content: ""; -} - -.markdown-body table { - border-spacing: 0; - border-collapse: collapse; - display: block; - width: max-content; - max-width: 100%; - overflow: auto; -} - -.markdown-body td, -.markdown-body th { - padding: 0; -} - -.markdown-body details summary { - cursor: pointer; -} - -.markdown-body details:not([open]) > *:not(summary) { - display: none !important; -} - -.markdown-body kbd { - display: inline-block; - padding: 3px 5px; - font: 11px ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, - Liberation Mono, monospace; - line-height: 10px; - color: var(--color-fg-default); - vertical-align: middle; - background-color: var(--color-canvas-subtle); - border: solid 1px var(--color-neutral-muted); - border-bottom-color: var(--color-neutral-muted); - border-radius: 6px; - box-shadow: inset 0 -1px 0 var(--color-neutral-muted); -} - -.markdown-body h1, -.markdown-body h2, -.markdown-body h3, -.markdown-body h4, -.markdown-body h5, -.markdown-body h6 { - margin-top: 24px; - margin-bottom: 16px; - font-weight: 600; - line-height: 1.25; -} - -.markdown-body h2 { - font-weight: 600; - padding-bottom: 0.3em; - font-size: 1.5em; - border-bottom: 1px solid var(--color-border-muted); -} - -.markdown-body h3 { - font-weight: 600; - font-size: 1.25em; -} - -.markdown-body h4 { - font-weight: 600; - font-size: 1em; -} - -.markdown-body h5 { - font-weight: 600; - font-size: 0.875em; -} - -.markdown-body h6 { - font-weight: 600; - font-size: 0.85em; - color: var(--color-fg-muted); -} - -.markdown-body p { - margin-top: 0; - margin-bottom: 10px; -} - -.markdown-body blockquote { - margin: 0; - padding: 0 1em; - color: var(--color-fg-muted); - border-left: 0.25em solid var(--color-border-default); -} - -.markdown-body ul, -.markdown-body ol { - margin-top: 0; - margin-bottom: 0; - padding-left: 2em; -} - -.markdown-body ol ol, -.markdown-body ul ol { - list-style-type: lower-roman; -} - -.markdown-body ul ul ol, -.markdown-body ul ol ol, -.markdown-body ol ul ol, -.markdown-body ol ol ol { - list-style-type: lower-alpha; -} - -.markdown-body dd { - margin-left: 0; -} - -.markdown-body tt, -.markdown-body code { - font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, - Liberation Mono, monospace; - font-size: 12px; -} - -.markdown-body pre { - margin-top: 0; - margin-bottom: 0; - font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, - Liberation Mono, monospace; - font-size: 12px; - word-wrap: normal; -} - -.markdown-body .octicon { - display: inline-block; - overflow: visible !important; - vertical-align: text-bottom; - fill: currentColor; -} - -.markdown-body ::placeholder { - color: var(--color-fg-subtle); - opacity: 1; -} - -.markdown-body input::-webkit-outer-spin-button, -.markdown-body input::-webkit-inner-spin-button { - margin: 0; - -webkit-appearance: none; - appearance: none; -} - -.markdown-body .token.comment, -.markdown-body .token.prolog, -.markdown-body .token.doctype, -.markdown-body .token.cdata { - color: var(--color-prettylights-syntax-comment); -} -.markdown-body .token.namespace { - opacity: 0.7; -} -.markdown-body .token.tag, -.markdown-body .token.selector, -.markdown-body .token.constant, -.markdown-body .token.symbol, -.markdown-body .token.deleted { - color: var(--color-prettylights-syntax-entity-tag); -} -.markdown-body .token.maybe-class-name { - color: var(--color-prettylights-syntax-variable); -} -.markdown-body .token.property-access, -.markdown-body .token.operator, -.markdown-body .token.boolean, -.markdown-body .token.number, -.markdown-body .token.selector .markdown-body .token.class, -.markdown-body .token.attr-name, -.markdown-body .token.string, -.markdown-body .token.char, -.markdown-body .token.builtin { - color: var(--color-prettylights-syntax-constant); -} - -.markdown-body .token.deleted { - color: var(--color-prettylights-syntax-markup-deleted-text); -} -.markdown-body .token.property { - color: var(--color-prettylights-syntax-constant); -} -.markdown-body .token.punctuation { - color: var(--color-prettylights-syntax-markup-bold); -} -.markdown-body .token.function { - color: var(--color-prettylights-syntax-entity); -} -.markdown-body .code-line .token.deleted { - background-color: var(--color-prettylights-syntax-markup-deleted-bg); -} -.markdown-body .token.inserted { - color: var(--color-prettylights-syntax-markup-inserted-text); -} -.markdown-body .code-line .token.inserted { - background-color: var(--color-prettylights-syntax-markup-inserted-bg); -} - -.markdown-body .token.variable { - color: var(--color-prettylights-syntax-constant); -} -.markdown-body .token.entity, -.markdown-body .token.url, -.language-css .markdown-body .token.string, -.style .markdown-body .token.string { - color: var(--color-prettylights-syntax-string); -} -.markdown-body .token.color, -.markdown-body .token.atrule, -.markdown-body .token.attr-value, -.markdown-body .token.function, -.markdown-body .token.class-name { - color: var(--color-prettylights-syntax-string); -} -.markdown-body .token.rule, -.markdown-body .token.regex, -.markdown-body .token.important, -.markdown-body .token.keyword { - color: var(--color-prettylights-syntax-keyword); -} -.markdown-body .token.coord { - color: var(--color-prettylights-syntax-meta-diff-range); -} -.markdown-body .token.important, -.markdown-body .token.bold { - font-weight: bold; -} -.markdown-body .token.italic { - font-style: italic; -} -.markdown-body .token.entity { - cursor: help; -} - -.markdown-body [data-catalyst] { - display: block; -} - -.markdown-body g-emoji { - font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 1em; - font-style: normal !important; - font-weight: 400; - line-height: 1; - vertical-align: -0.075em; -} - -.markdown-body g-emoji img { - width: 1em; - height: 1em; -} - -.markdown-body::before { - display: table; - content: ""; -} - -.markdown-body::after { - display: table; - clear: both; - content: ""; -} - -.markdown-body > *:first-child { - margin-top: 0 !important; -} - -.markdown-body > *:last-child { - margin-bottom: 0 !important; -} - -.markdown-body a:not([href]) { - color: inherit; - text-decoration: none; -} - -.markdown-body .absent { - color: var(--color-danger-fg); -} - -.markdown-body a.anchor { - float: left; - padding-right: 4px; - margin-left: -20px; - line-height: 1; -} - -.markdown-body a.anchor:focus { - outline: none; -} - -.markdown-body p, -.markdown-body blockquote, -.markdown-body ul, -.markdown-body ol, -.markdown-body dl, -.markdown-body table, -.markdown-body pre, -.markdown-body details { - margin-top: 0; - margin-bottom: 16px; -} - -.markdown-body blockquote > :first-child { - margin-top: 0; -} - -.markdown-body blockquote > :last-child { - margin-bottom: 0; -} - -.markdown-body sup > a::before { - content: "["; -} - -.markdown-body sup > a::after { - content: "]"; -} - -.markdown-body .octicon-video { - border: 1px solid #d0d7de !important; - border-radius: 6px !important; - display: block; -} - -.markdown-body .octicon-video summary { - border-bottom: 1px solid #d0d7de !important; - padding: 8px 16px !important; - cursor: pointer; -} - -.markdown-body .octicon-video > video { - display: block !important; - max-width: 100% !important; - padding: 2px; - box-sizing: border-box; - border-bottom-right-radius: 6px !important; - border-bottom-left-radius: 6px !important; -} - -.markdown-body details.octicon-video:not([open]) > *:not(summary) { - display: none !important; -} - -.markdown-body details.octicon-video:not([open]) > summary { - border-bottom: 0 !important; -} - -.markdown-body h1 .octicon-link, -.markdown-body h2 .octicon-link, -.markdown-body h3 .octicon-link, -.markdown-body h4 .octicon-link, -.markdown-body h5 .octicon-link, -.markdown-body h6 .octicon-link { - color: var(--color-fg-default); - vertical-align: middle; - visibility: hidden; -} - -.markdown-body h1:hover .anchor, -.markdown-body h2:hover .anchor, -.markdown-body h3:hover .anchor, -.markdown-body h4:hover .anchor, -.markdown-body h5:hover .anchor, -.markdown-body h6:hover .anchor { - text-decoration: none; -} - -.markdown-body h1:hover .anchor .octicon-link, -.markdown-body h2:hover .anchor .octicon-link, -.markdown-body h3:hover .anchor .octicon-link, -.markdown-body h4:hover .anchor .octicon-link, -.markdown-body h5:hover .anchor .octicon-link, -.markdown-body h6:hover .anchor .octicon-link { - visibility: visible; -} - -.markdown-body h1 tt, -.markdown-body h1 code, -.markdown-body h2 tt, -.markdown-body h2 code, -.markdown-body h3 tt, -.markdown-body h3 code, -.markdown-body h4 tt, -.markdown-body h4 code, -.markdown-body h5 tt, -.markdown-body h5 code, -.markdown-body h6 tt, -.markdown-body h6 code { - padding: 0 0.2em; - font-size: inherit; -} - -.markdown-body ul.no-list, -.markdown-body ol.no-list { - padding: 0; - list-style-type: none; -} - -.markdown-body ol[type="1"] { - list-style-type: decimal; -} - -.markdown-body ol[type="a"] { - list-style-type: lower-alpha; -} - -.markdown-body ol[type="i"] { - list-style-type: lower-roman; -} - -.markdown-body div > ol:not([type]) { - list-style-type: decimal; -} - -.markdown-body ul ul, -.markdown-body ul ol, -.markdown-body ol ol, -.markdown-body ol ul { - margin-top: 0; - margin-bottom: 0; -} - -.markdown-body li > p { - margin-top: 16px; -} - -.markdown-body li + li { - margin-top: 0.25em; -} - -.markdown-body dl { - padding: 0; -} - -.markdown-body dl dt { - padding: 0; - margin-top: 16px; - font-size: 1em; - font-style: italic; - font-weight: 600; -} - -.markdown-body dl dd { - padding: 0 16px; - margin-bottom: 16px; -} - -.markdown-body table th { - font-weight: 600; -} - -.markdown-body table th, -.markdown-body table td { - padding: 6px 13px; - border: 1px solid var(--color-border-default); -} - -.markdown-body table tr { - background-color: var(--color-canvas-default); - border-top: 1px solid var(--color-border-muted); -} - -.markdown-body table tr:nth-child(2n) { - background-color: var(--color-canvas-subtle); -} - -.markdown-body table img { - background-color: transparent; - vertical-align: middle; -} - -.markdown-body img[align="right"] { - padding-left: 20px; -} - -.markdown-body img[align="left"] { - padding-right: 20px; -} - -.markdown-body .emoji { - max-width: none; - vertical-align: text-top; - background-color: transparent; -} - -.markdown-body span.frame { - display: block; - overflow: hidden; -} - -.markdown-body span.frame > span { - display: block; - float: left; - width: auto; - padding: 7px; - margin: 13px 0 0; - overflow: hidden; - border: 1px solid var(--color-border-default); -} - -.markdown-body span.frame span img { - display: block; - float: left; -} - -.markdown-body span.frame span span { - display: block; - padding: 5px 0 0; - clear: both; - color: var(--color-fg-default); -} - -.markdown-body span.align-center { - display: block; - overflow: hidden; - clear: both; -} - -.markdown-body span.align-center > span { - display: block; - margin: 13px auto 0; - overflow: hidden; - text-align: center; -} - -.markdown-body span.align-center span img { - margin: 0 auto; - text-align: center; -} - -.markdown-body span.align-right { - display: block; - overflow: hidden; - clear: both; -} - -.markdown-body span.align-right > span { - display: block; - margin: 13px 0 0; - overflow: hidden; - text-align: right; -} - -.markdown-body span.align-right span img { - margin: 0; - text-align: right; -} - -.markdown-body span.float-left { - display: block; - float: left; - margin-right: 13px; - overflow: hidden; -} - -.markdown-body span.float-left span { - margin: 13px 0 0; -} - -.markdown-body span.float-right { - display: block; - float: right; - margin-left: 13px; - overflow: hidden; -} - -.markdown-body span.float-right > span { - display: block; - margin: 13px auto 0; - overflow: hidden; - text-align: right; -} - -.markdown-body code, -.markdown-body tt { - padding: 0.2em 0.4em; - margin: 0; - font-size: 85%; - background-color: var(--color-neutral-muted); - border-radius: 6px; -} - -.markdown-body code br, -.markdown-body tt br { - display: none; -} - -.markdown-body del code { - text-decoration: inherit; -} - -.markdown-body pre code { - font-size: 100%; -} - -.markdown-body pre > code { - padding: 0; - margin: 0; - word-break: normal; - white-space: pre; - background: transparent; - border: 0; -} - -.markdown-body pre { - position: relative; - font-size: 85%; - line-height: 1.45; - background-color: var(--color-canvas-subtle); - border-radius: 6px; -} - -.markdown-body pre code, -.markdown-body pre tt { - display: inline; - max-width: auto; - padding: 0; - margin: 0; - overflow: visible; - line-height: inherit; - word-wrap: normal; - background-color: transparent; - border: 0; -} - -.markdown-body pre > code { - padding: 16px; - overflow: auto; - display: block; -} - -.markdown-body .csv-data td, -.markdown-body .csv-data th { - padding: 5px; - overflow: hidden; - font-size: 12px; - line-height: 1; - text-align: left; - white-space: nowrap; -} - -.markdown-body .csv-data .blob-num { - padding: 10px 8px 9px; - text-align: right; - background: var(--color-canvas-default); - border: 0; -} - -.markdown-body .csv-data tr { - border-top: 0; -} - -.markdown-body .csv-data th { - font-weight: 600; - background: var(--color-canvas-subtle); - border-top: 0; -} - -.markdown-body .footnotes { - font-size: 12px; - color: var(--color-fg-muted); - border-top: 1px solid var(--color-border-default); -} - -.markdown-body .footnotes ol { - padding-left: 16px; -} - -.markdown-body .footnotes li { - position: relative; -} - -.markdown-body .footnotes li:target::before { - position: absolute; - top: -8px; - right: -8px; - bottom: -8px; - left: -24px; - pointer-events: none; - content: ""; - border: 2px solid var(--color-accent-emphasis); - border-radius: 6px; -} - -.markdown-body .footnotes li:target { - color: var(--color-fg-default); -} - -.markdown-body .footnotes .data-footnote-backref g-emoji { - font-family: monospace; -} - -.markdown-body .task-list-item { - list-style-type: none; -} - -.markdown-body .task-list-item label { - font-weight: 400; -} - -.markdown-body .task-list-item.enabled label { - cursor: pointer; -} - -.markdown-body .task-list-item + .task-list-item { - margin-top: 3px; -} - -.markdown-body .task-list-item .handle { - display: none; -} - -.markdown-body .task-list-item-checkbox, -.markdown-body input[type="checkbox"] { - margin: 0 0.2em 0.25em -1.6em; - vertical-align: middle; -} - -.markdown-body .contains-task-list:dir(rtl) .task-list-item-checkbox, -.markdown-body .contains-task-list:dir(rtl) input[type="checkbox"] { - margin: 0 -1.6em 0.25em 0.2em; -} - -.markdown-body ::-webkit-calendar-picker-indicator { - filter: invert(50%); -} diff --git a/client/app/(posts)/post/[id]/page.tsx b/client/app/(posts)/post/[id]/page.tsx index ce48e274..deac6394 100644 --- a/client/app/(posts)/post/[id]/page.tsx +++ b/client/app/(posts)/post/[id]/page.tsx @@ -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() } diff --git a/client/app/styles/globals.css b/client/app/styles/globals.css index f4bae343..920afdb1 100644 --- a/client/app/styles/globals.css +++ b/client/app/styles/globals.css @@ -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, diff --git a/client/app/styles/syntax.css b/client/app/styles/syntax.css index 42a27295..04a2e0da 100644 --- a/client/app/styles/syntax.css +++ b/client/app/styles/syntax.css @@ -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); } + diff --git a/client/lib/constants.ts b/client/lib/constants.ts index 5c6fb8cc..af05d8e1 100644 --- a/client/lib/constants.ts +++ b/client/lib/constants.ts @@ -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 = [ diff --git a/client/lib/server/get-html-from-drift-file.ts b/client/lib/server/get-html-from-drift-file.ts index c7eb0b5e..111a29b6 100644 --- a/client/lib/server/get-html-from-drift-file.ts +++ b/client/lib/server/get-html-from-drift-file.ts @@ -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 } diff --git a/client/package.json b/client/package.json index faaf27bd..f624a90f 100644 --- a/client/package.json +++ b/client/package.json @@ -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", diff --git a/client/pages/api/file/get-html.ts b/client/pages/api/file/get-html.ts index df56f784..dd1ca0d8 100644 --- a/client/pages/api/file/get-html.ts +++ b/client/pages/api/file/get-html.ts @@ -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 } ) diff --git a/client/pages/api/file/html/[id].ts b/client/pages/api/file/html/[id].ts index 1cfe62a6..387a72e1 100644 --- a/client/pages/api/file/html/[id].ts +++ b/client/pages/api/file/html/[id].ts @@ -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) diff --git a/client/pages/api/post/[id].ts b/client/pages/api/post/[id].ts index 415be598..db440a4d 100644 --- a/client/pages/api/post/[id].ts +++ b/client/pages/api/post/[id].ts @@ -17,7 +17,6 @@ async function handleGet(req: NextApiRequest, res: NextApiResponse) { 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" }) } diff --git a/client/pages/api/welcome.ts b/client/pages/api/welcome.ts index 2d5ad8d4..bc640747 100644 --- a/client/pages/api/welcome.ts +++ b/client/pages/api/welcome.ts @@ -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" diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index f8113873..8750300b 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -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