Skip to content

Commit

Permalink
fix: Make button clickable and QOL on textbox
Browse files Browse the repository at this point in the history
Signed-off-by: Colton Wolkins (Laptop) <colton@indicio.tech>
  • Loading branch information
TheTechmage committed Jun 13, 2024
1 parent 3d458fd commit c51ced7
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 88 deletions.
2 changes: 1 addition & 1 deletion src/app/wyvern/server-chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ function Chatbox({ sendMessage, serverName, text, setText }) {
}}>
<div className="min-h-12 bg-slate-500 flex items-center">
<Editor onSubmit={sendMessage} />
<Button type="submit" gradientDuoTone="purpleToBlue">Send</Button>
</div>
</form>
)
//<Button type="submit" gradientDuoTone="purpleToBlue">Send</Button>
}

export default function Chat({ serverId }) {
Expand Down
230 changes: 143 additions & 87 deletions src/components/editor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState, useCallback, useMemo } from 'react'
import { Node as SNode, Transforms, Text, createEditor, Descendant } from 'slate'
import { Button } from 'flowbite-react';

import { Slate, Editable, withReact } from 'slate-react'
import { withHistory } from 'slate-history'
Expand All @@ -8,54 +9,103 @@ import { css } from '@emotion/css'
import Prism from 'prismjs'
import 'prismjs/components/prism-markdown'

const Editor = ({ onSubmit }) => {
const [value, setValue] = useState(initialValue);

const renderLeaf = useCallback(props => <Leaf {...props} />, [])
function withMyPlugins(editor) {
const { insertText, insertData, normalizeNode, isVoid, isInline } = editor;
}

const editor = useMemo(() => withHistory(withReact(createEditor())), []);
Prism.languages.markdown.title[1].pattern = /\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m
Prism.languages.markdown.title[1].pattern = /(?<![^\n]\n?)#.+/m
//Prism.languages.markdown.title[1].pattern = /(^\s*)#.+/m
console.log("PRISM", Prism.languages.markdown);
function getTokenLength(token) {
if(typeof token === 'string')
return token.length;
else if(typeof token.content === 'string')
return token.content.length;
else
return token.content.reduce((l, t) => l + getTokenLength(t), 0);
}

const decorate = useCallback(([node, path]) => {
const ranges = [];
function decorateMarkdown([node, path]) {
const ranges = [];

if(!Text.isText(node)) {
return ranges;
if(!Text.isText(node)) {
return ranges;
}

const tokens = Prism.tokenize(node.text, Prism.languages.markdown);
let start = 0;

for(const token of tokens) {
const length = getTokenLength(token);
const end = start + length;
console.debug("current token debug:", token);

if(typeof token !== 'string') {
ranges.push({
[token.type]: true,
anchor: {path, offset: start},
focus: {path, offset: end},
});
}

const getLength = token => {
if(typeof token === 'string')
return token.length;
else if(typeof token.content === 'string')
return token.content.length;
else
return token.content.reduce((l, t) => l + getLength(t), 0);
}
start = end;
}
return ranges;
}

const tokens = Prism.tokenize(node.text, Prism.languages.markdown);
let start = 0;
function getTokenAtCursor(editor, textNode) {
const cursorPos = editor.selection.anchor.offset

for(const token of tokens) {
const length = getLength(token);
const end = start + length;
textNode = textNode.map(n => SNode.string(n)).join('\n');

const tokens = Prism.tokenize(textNode, Prism.languages.markdown);
let start = 0;

for(const token of tokens) {
const length = getTokenLength(token);
const end = start + length;
console.debug("Current Token DEBUG:", editor.selection, start, end, token);
if (start < cursorPos && end > cursorPos) {
if(typeof token !== 'string') {
ranges.push({
[token.type]: true,
anchor: {path, offset: start},
focus: {path, offset: end},
});
return token.type;
}

start = end;
}
return ranges;
}, []);

start = end;
}
return null;
}

const Editor = ({ onSubmit }) => {
const [value, setValue] = useState(initialValue);

const renderLeaf = useCallback(props => <Leaf {...props} />, [])

const editor = useMemo(() => withHistory(withReact(createEditor())), []);
//
Prism.languages.markdown.title[1].pattern = /\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m
Prism.languages.markdown.title[1].pattern = /(?<![^\n]\n?)#.+/m
//Prism.languages.markdown.code[1].pattern = /^```[\s\S]*?(^```$|\Z)/m
//Prism.languages.markdown.code[1].pattern = /^(```)([a-z0-9_+\-.#]+$)?/
//Prism.languages.markdown.title[1].pattern = /(^\s*)#.+/m
console.debug("PRISM", Prism.languages.markdown);

const decorate = useCallback(decorateMarkdown, []);

function submitMessage(event) {
event.preventDefault();
onSubmit(value.map(n => SNode.string(n)).join('\n'));
const newValue = [{type: 'paragraph', children: [{text: ""}]}];
//const point = { path: [0, 0], offset: 0 }
//editor.selection = { anchor: point, focus: point };
//editor.history = { redos: [], undos: [] };
//editor.children = newValue;
Transforms.select(editor, { offset: 0, path: [0, 0] });
editor.children.map(item => Transforms.delete(editor, { at: [0] }));
editor.children = newValue;
editor.onChange();
//setValue(newValue);
}

return (
<>
<div className="grow">
<Slate
editor={editor}
Expand All @@ -77,72 +127,78 @@ const Editor = ({ onSubmit }) => {
event.preventDefault();
return editor.insertText('\n')
}
if(event.key === 'Enter' && !event.shiftKey) {
const token = getTokenAtCursor(editor, value);
console.debug("Current Token:", token);
if (token === 'code') {
event.preventDefault();
return editor.insertText('\n')
}
submitMessage(event);
}
if(!event.ctrlKey) {
return;
}
if(event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
onSubmit(value.map(n => SNode.string(n)).join('\n'));
const newValue = [{type: 'paragraph', children: [{text: ""}]}];
//const point = { path: [0, 0], offset: 0 }
//editor.selection = { anchor: point, focus: point };
//editor.history = { redos: [], undos: [] };
//editor.children = newValue;
Transforms.select(editor, { offset: 0, path: [0, 0] });
editor.children.map(item => Transforms.delete(editor, { at: [0] }));
editor.children = newValue;
editor.onChange();
//setValue(newValue);
}
}}
/>
</Slate>
</div>
<Button type="submit" onClick={submitMessage} gradientDuoTone="purpleToBlue">Send</Button>
</>
);
};

const Leaf = ({ attributes, children, leaf }) => {
console.log("LEAF:", leaf);
let styles = css`
font-weight: ${leaf.bold && 'bold'};
font-style: ${leaf.italic && 'italic'};
text-decoration: ${leaf.underlined && 'underline'};
${leaf.title &&
css`
display: inline-block;
font-weight: bold;
font-size: 20px;
margin: 20px 0 10px 0;
`}
${leaf.list &&
css`
padding-left: 10px;
font-size: 20px;
line-height: 10px;
`}
${leaf.hr &&
css`
display: block;
text-align: center;
border-bottom: 2px solid #ddd;
`}
${leaf.blockquote &&
css`
display: inline-block;
border-left: 2px solid #ddd;
padding-left: 10px;
color: #aaa;
font-style: italic;
`}
${leaf.code &&
css`
font-family: monospace;
/* background-color: #eee; */
padding: 3px;
display: block;
`}
${leaf["code-snippet"] &&
css`
font-family: monospace;
`}
`;
if (leaf.code || leaf["code-snippet"])
styles += " dark:bg-slate-800";
return (
<span
{...attributes}
className={css`
font-weight: ${leaf.bold && 'bold'};
font-style: ${leaf.italic && 'italic'};
text-decoration: ${leaf.underlined && 'underline'};
${leaf.title &&
css`
display: inline-block;
font-weight: bold;
font-size: 20px;
margin: 20px 0 10px 0;
`}
${leaf.list &&
css`
padding-left: 10px;
font-size: 20px;
line-height: 10px;
`}
${leaf.hr &&
css`
display: block;
text-align: center;
border-bottom: 2px solid #ddd;
`}
${leaf.blockquote &&
css`
display: inline-block;
border-left: 2px solid #ddd;
padding-left: 10px;
color: #aaa;
font-style: italic;
`}
${leaf.code &&
css`
font-family: monospace;
background-color: #eee;
padding: 3px;
`}
`}
className={styles}
>
{children}
</span>
Expand Down

0 comments on commit c51ced7

Please sign in to comment.