Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active December 8, 2021 20:25
Show Gist options
  • Save ryanflorence/e42942d9685a8faab17977dd4aba7df1 to your computer and use it in GitHub Desktop.
Save ryanflorence/e42942d9685a8faab17977dd4aba7df1 to your computer and use it in GitHub Desktop.
import type {
ActionFunction,
LinksFunction,
LoaderFunction,
MetaFunction
} from "@remix-run/react";
import {
Meta,
Links,
Scripts,
useRouteData,
useLiveReload,
} from "@remix-run/react";
import { json, redirect } from "@remix-run/node";
import { useSubmit } from "@remix-run/react";
import { useEffect, useState } from "react";
import { useThrottle } from "use-throttle";
import { processMarkdown } from "./md.server";
import { getSession, commitSession } from "./session";
import stylesUrl from "./styles/global.css";
export let meta: MetaFunction = () => {
return {
title: "CK HTML Editor",
description: "For real...",
};
};
export let links: LinksFunction = () => {
return [{ rel: "stylesheet", href: stylesUrl }];
};
export let action: ActionFunction = async ({ request }) => {
let body = new URLSearchParams(await request.text());
let md = body.get("md");
let html = await processMarkdown(md!);
let session = await getSession(request.headers.get("Cookie"));
session.set("html", html);
session.set("md", md);
return redirect("/", {
headers: {
"Set-Cookie": await commitSession(session),
},
});
};
export let loader: LoaderFunction = async ({ request }) => {
let session = await getSession(request.headers.get("Cookie"));
return json({ html: session.get("html"), md: session.get("md") });
};
export default function App() {
useLiveReload();
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<link rel="icon" href="/favicon.png" type="image/png" />
<Meta />
<Links />
</head>
<body>
<Page />
<Scripts />
</body>
</html>
);
}
function Page() {
let session = useRouteData();
let [md, setMd] = useState(session.md || "# Hey Cool\n\nThis is cool");
let throttledMd = useThrottle(md, 100);
let submit = useSubmit();
useEffect(() => {
submit({ md }, { method: "post", replace: true });
}, [throttledMd]);
return (
<>
<div
style={{
position: "absolute",
inset: 0,
display: "flex",
height: "100vh",
}}
>
<textarea
onChange={(event) => setMd(event.target.value)}
style={{
fontFamily: "Menlo",
lineHeight: "1.5",
width: "50%",
height: "100%",
boxSizing: "border-box",
padding: "2rem",
border: "none",
background: "#fcfcf8",
outline: "none",
}}
value={md}
/>
<div
dangerouslySetInnerHTML={{ __html: session.html }}
style={{
width: "50%",
height: "100%",
overflow: "auto",
boxSizing: "border-box",
padding: "2rem",
}}
/>
</div>
<button
style={{ position: "absolute", right: 10, top: 10 }}
onClick={() => {
navigator.clipboard.writeText(session.html);
}}
>
Copy HTML
</button>
</>
);
}
import { createMemorySessionStorage } from "@remix-run/node";
let { getSession, commitSession } = createMemorySessionStorage({
cookie: {
secrets: ["lol"],
name: "__session",
sameSite: "lax",
},
});
export { getSession, commitSession };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment