initial integration with mdxeditor

This commit is contained in:
Shoofle 2024-10-21 13:50:25 -04:00
parent 43c06e39f5
commit 7d650ef424
4 changed files with 3570 additions and 36 deletions

3546
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
"private": true, "private": true,
"dependencies": { "dependencies": {
"@libsql/client": "^0.11.0", "@libsql/client": "^0.11.0",
"@mdxeditor/editor": "^3.14.0",
"@react-sigma/core": "^4.0.3", "@react-sigma/core": "^4.0.3",
"@tanstack/react-query": "^5.56.2", "@tanstack/react-query": "^5.56.2",
"@testing-library/jest-dom": "^5.17.0", "@testing-library/jest-dom": "^5.17.0",

View File

@ -4,9 +4,11 @@ import { useParams, useNavigate } from 'react-router-dom';
import { apiUrl, fetchPage, fetchPageAtEdit, postPage, deletePage } from '../apiTools.jsx'; import { apiUrl, fetchPage, fetchPageAtEdit, postPage, deletePage } from '../apiTools.jsx';
import { useFixLinks } from '../clientStuff.jsx'; import { useFixLinks } from '../clientStuff.jsx';
import { useLoggedIn } from '../AuthProvider.jsx'; import { useLoggedIn } from '../AuthProvider.jsx';
import { MDXEditor, headingsPlugin, quotePlugin, linkPlugin, diffSourcePlugin } from '@mdxeditor/editor';
import './Pages.css'; import './Pages.css';
import 'highlight.js/styles/a11y-dark.min.css'; import 'highlight.js/styles/a11y-dark.min.css';
import '@mdxeditor/editor/style.css';
function Page({ editing, number, editid=null, linkClick=()=>{} }) { function Page({ editing, number, editid=null, linkClick=()=>{} }) {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
@ -22,15 +24,7 @@ function Page({ editing, number, editid=null, linkClick=()=>{} }) {
mutationFn: ({id, title, description, type}) => postPage({id, title, description, type}), mutationFn: ({id, title, description, type}) => postPage({id, title, description, type}),
onSettled: async (data, error, variables) => { onSettled: async (data, error, variables) => {
// Invalidate and refetch // Invalidate and refetch
await queryClient.invalidateQueries({ queryKey: ['page', variables.id, null] }) queryClient.invalidateQueries({ queryKey: ['page', variables.id, null] })
},
});
const deleteMutation = useMutation({ // for changing the value when we're done with it
mutationFn: (id) => deletePage(id),
onSettled: async (data, error, variables) => {
// Invalidate and refetch
await queryClient.invalidateQueries({ queryKey: ['pages'] })
}, },
}); });
@ -38,30 +32,27 @@ function Page({ editing, number, editid=null, linkClick=()=>{} }) {
let {id, title, description, html, lua, time, author, type} = fetchQuery.data || {}; let {id, title, description, html, lua, time, author, type} = fetchQuery.data || {};
const [verb, setVerb] = useState(false); const [verb, setVerb] = useState(false);
const [enteredText, setText] = useState("...");
if (!title) title = "[no title]"; if (!title) title = "[no title]";
if (!html) html = "[body missing]"; if (!html) html = "[body missing]";
if (!lua) lua = "[no definition]"; if (!lua) lua = "[no definition]";
if (!description) description = "[body missing]"; if (!description) description = "[body missing]";
useEffect(() => setVerb(type == 1), [type]) useEffect(() => {
setVerb(type == 1);
setText(description);
}, [type, description])
function submitChanges(e) { function submitChanges(e) {
const newTitle = document.querySelector('span').innerHTML; const newTitle = document.querySelector('span').innerHTML;
const newText = document.querySelector('pre').innerHTML.replace(/<br>/g, "\n");
postMutation.mutate({ postMutation.mutate({
id: number, id: number,
title: newTitle, title: newTitle,
description: newText, description: enteredText,
type: verb ? 1 : 0, type: verb ? 1 : 0,
}); });
navigate(`/${number}`, {replace: true}) navigate(`/${number}`, {replace: true})
} }
function submitDelete(e) {
e.preventDefault();
deleteMutation.mutate(number);
navigate(`/`);
}
return ( return (
<div className="main-column"> <div className="main-column">
@ -84,15 +75,22 @@ function Page({ editing, number, editid=null, linkClick=()=>{} }) {
{ readyToShow ? { readyToShow ?
( (
editing ? editing ?
<pre <MDXEditor
contentEditable="true" markdown={description}
dangerouslySetInnerHTML={{__html: description.replace(/\n/g, "<br>")}} /> plugins={[
headingsPlugin(),
quotePlugin(),
linkPlugin(),
diffSourcePlugin({ diffMarkdown: 'ahhhh do not look upon me!', viewMode: 'source' }),
]}
onChange={(md) => setText(md)}
/>
: :
( (
verb ? verb ?
<pre><code dangerouslySetInnerHTML={{__html: lua.replace(/\n/g, "<br>")}}></code></pre> <pre><code dangerouslySetInnerHTML={{__html: lua.replace(/\n/g, "<br>").replace(/ /g, "&nbsp;&nbsp;")}}></code></pre>
: :
<div <div
dangerouslySetInnerHTML={{__html: html}} dangerouslySetInnerHTML={{__html: html}}
onClick={linkClick} /> onClick={linkClick} />
) )
@ -117,12 +115,6 @@ function Page({ editing, number, editid=null, linkClick=()=>{} }) {
onClick={() => navigate(`/${number}/edit`)}> onClick={() => navigate(`/${number}/edit`)}>
Edit Page Edit Page
</button>)} </button>)}
{loggedIn && (
<button
disabled={deleteMutation.isPending}
onClick={submitDelete}>
{deleteMutation.isPending ? "Deleting..." : "Delete this page and entire edit history (no backsies)"}
</button>)}
</div> </div>
); );
} }

View File

@ -29,13 +29,13 @@ create table if not exists pages (
title / NAME = a short display name for an object, or the title of a page title / NAME = a short display name for an object, or the title of a page
description / TEXT? = the markdown description of an object, or the lua script of the source code of a verb description / TEXT? = the markdown description of an object, or the lua script of the source code of a verb
html / HTML_MARKDOWN? = the markdown for that object, rendered into html for display as a page html = the markdown for that object, rendered into html for display as a page
HTML_LUA? = the lua source code of the object, rendered into html with syntax highlighting? lua = the lua source code of the object, rendered into html with syntax highlighting
time = when this edit was saved time = when this edit was saved
author = the user id of whoever authored this revision author = the user id of whoever authored this revision
TYPE = whether this represents an object or a verb type = 0 for noun, 1 for verb
*/ */
@ -47,7 +47,8 @@ create table if not exists pages (
ATTRIBUTES? = json object of attached, script-controlled attributes. ATTRIBUTES? = json object of attached, script-controlled attributes.
CONTENTS = json array of objectss contained inside this one CONTENTS = json array of objectss contained inside this one
VERBS = json array of objecsts which are verbs on this one verbs = json array of objecsts which are verbs on this one
prepositions
*/ */