initial integration with mdxeditor
This commit is contained in:
parent
43c06e39f5
commit
7d650ef424
3546
client/package-lock.json
generated
3546
client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -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",
|
||||||
|
@ -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, " ")}}></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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user