Skip to content

Commit

Permalink
Fixed slate not confirming state with fugue
Browse files Browse the repository at this point in the history
  • Loading branch information
GuilhermeF03 committed Jun 7, 2024
1 parent 515e509 commit ee8ce53
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 45 deletions.
4 changes: 2 additions & 2 deletions code/client/src/domain/editor/fugue/Fugue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { FugueTree } from '@domain/editor/fugue/FugueTree';
import { generateReplicaId, nodeInsert } from './utils';
import { type FugueNode, type NodeInsert } from '@domain/editor/fugue/types';
import { Cursor, Selection } from '@domain/editor/cursor';
import { isEmpty, last, range } from 'lodash';
import {isEmpty, last, range} from 'lodash';
import { Id } from '@notespace/shared/src/document/types/types';
import {
BlockStyleOperation,
Expand Down Expand Up @@ -260,7 +260,7 @@ export class Fugue {
columnCounter = 0,
inBounds = false;

const lineRootNode = this.tree.getLineRoot(start.line);
const lineRootNode = this.tree.getLineRoot(start.line === 0 ? 0 : start.line - 1);

for (const node of this.tree.traverse(lineRootNode, returnDeleted)) {
// start condition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import markdownHandlers from '@domain/editor/slate/operations/markdown/operation
/**
* Handles input events
* @param editor
* @param syncEditor
* @param fugue
* @param communication
*/
function getEventHandlers(editor: Editor, fugue: Fugue, communication: Communication) {
function getEventHandlers(
editor: Editor,
fugue: Fugue,
communication: Communication
) {
// domain operations
const markdownOperations = markdownDomainOperations(fugue, communication);
const inputOperations = inputDomainOperations(fugue, communication);
Expand Down
22 changes: 17 additions & 5 deletions code/client/src/domain/editor/slate/operations/input/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ const hotkeys: Record<string, string> = {
u: 'underline',
};

export default (editor: Editor, domainOperations: InputDomainOperations, onFormat: (mark: InlineStyle) => void) => {
export default (
editor: Editor,
domainOperations: InputDomainOperations,
onFormat: (mark: InlineStyle) => void) => {

function onInput(e: InputEvent) {
const key = getKeyFromInputEvent(e);
if (!key) return;
Expand Down Expand Up @@ -84,7 +88,9 @@ export default (editor: Editor, domainOperations: InputDomainOperations, onForma
* Handles enter key press
* @param cursor
*/
const onEnter = (cursor: Cursor) => domainOperations.insertLineBreak(cursor);
const onEnter = (cursor: Cursor) => {
domainOperations.insertLineBreak(cursor);
}

/**
* Handles backspace key press
Expand All @@ -99,17 +105,23 @@ export default (editor: Editor, domainOperations: InputDomainOperations, onForma
* Handles delete key press
* Deletes the character after the cursor
*/
const onDelete = ({ line, column }: Cursor) => domainOperations.deleteCharacter({ line, column });
const onDelete = ({ line, column }: Cursor) => {
domainOperations.deleteCharacter({ line, column });
}

/**
* Handles ctrl + backspace
*/
const onCtrlBackspace = (cursor: Cursor) => domainOperations.deleteWord(cursor, true);
const onCtrlBackspace = (cursor: Cursor) => {
domainOperations.deleteWord(cursor, true);
}

/**
* Handles ctrl + delete
*/
const onCtrlDelete = (cursor: Cursor) => domainOperations.deleteWord(cursor, false);
const onCtrlDelete = (cursor: Cursor) => {
domainOperations.deleteWord(cursor, false);
}

/**
* Handles paste events
Expand Down
9 changes: 9 additions & 0 deletions code/client/src/ui/pages/document/Document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ function Document() {
const communication = useCommunication();
const services = useDocumentService();
const fugue = useFugue();

const { publishError } = useError();
const { id } = useParams();
const [loaded, setLoaded] = useState(false);
Expand Down Expand Up @@ -39,6 +40,14 @@ function Document() {
};
}, [fugue, id, http, socket, publishError, services, setTitle, navigate]);

useEffect(() => {
console.log(fugue);
}, [fugue]);

useEffect(() => {
console.log("Loading document");
}, []);

if (!loaded) return null;

return <Editor title={title} fugue={fugue} communication={communication} />;
Expand Down
88 changes: 54 additions & 34 deletions code/client/src/ui/pages/document/components/editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import getEventHandlers from '@domain/editor/slate/operations/getEventHandlers';
import getFugueOperations from '@domain/editor/fugue/operations/fugue/operations';
import './Editor.scss';
import { useCallback, useEffect } from 'react';
import {isEqual} from "lodash";

type SlateEditorProps = {
title: string;
Expand All @@ -28,53 +29,72 @@ type SlateEditorProps = {
const initialValue: Descendant[] = [descendant('paragraph', '')];

function Editor({ title, fugue, communication }: SlateEditorProps) {
const editor = useEditor(withHistory, withReact, getMarkdownPlugin(fugue, communication));
const [editor, setEditor] = useEditor(withHistory, withReact, getMarkdownPlugin(fugue, communication));
const fugueOperations = getFugueOperations(fugue);
const { cursors } = useCursors(communication);
const { renderElement, renderLeaf } = useRenderers(editor, fugue, communication);
const decorate = useDecorate(editor, cursors);

const updateEditor = useCallback((newValue: Descendant[]) => {
setEditor(prevState => {
prevState.children = newValue;
return prevState
});
},[setEditor]);

const syncEditor = useCallback((slate ?: Descendant[]) => {
console.log("Syncing editor")
if(slate) {
updateEditor(slate);
return;
}
updateEditor(toSlate(fugue));
}, [fugue, updateEditor]);

const { onInput, onShortcut, onCut, onPaste, onSelectionChange, onFormat, onBlur } = getEventHandlers(
editor,
fugue,
communication
editor,
fugue,
communication
);

const refreshEditor = useCallback(() => {
editor.children = toSlate(fugue);
editor.onChange();
}, [editor, fugue]);

useEffect(() => {
refreshEditor();
}, [refreshEditor]);
syncEditor();
}, [syncEditor]);

useHistory(editor, fugue, communication);
useEvents(fugueOperations, communication, refreshEditor);
useEvents(fugueOperations, communication, syncEditor);

return (
<div className="editor">
<div className="container">
<Slate editor={editor} initialValue={initialValue} onChange={() => onSelectionChange()}>
<Title title={title} placeholder="Untitled" communication={communication} />
<Toolbar onApplyMark={onFormat} />
<Editable
className="editable"
data-testid={'editor'}
placeholder={'Start writing...'}
spellCheck={false}
renderElement={renderElement}
renderLeaf={renderLeaf}
decorate={decorate}
onDragStart={e => e.preventDefault()}
onDOMBeforeInput={onInput}
onCut={onCut}
onPaste={e => onPaste(e.nativeEvent)}
onKeyDown={e => onShortcut(e.nativeEvent)}
onBlur={onBlur}
/>
</Slate>
<div className="editor">
<div className="container">
<Slate editor={editor} onChange={() => {
const slate = toSlate(fugue);
if(!isEqual(slate, editor.children)) { // Prevents overwriting the editor with the same value
syncEditor(slate);
}
onSelectionChange();
}} initialValue={initialValue}
>
<Title title={title} placeholder="Untitled" communication={communication} />
<Toolbar onApplyMark={onFormat} />
<Editable
className="editable"
data-testid={'editor'}
placeholder={'Start writing...'}
spellCheck={false}
renderElement={renderElement}
renderLeaf={renderLeaf}
decorate={decorate}
onDragStart={e => e.preventDefault()}
onDOMBeforeInput={onInput}
onCut={onCut}
onPaste={e => onPaste(e.nativeEvent)}
onKeyDown={e => onShortcut(e.nativeEvent)}
onBlur={onBlur}
/>
</Slate>
</div>
</div>
</div>
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { type Editor } from 'slate';
import { useMemo } from 'react';
import { useState} from 'react';
import { buildEditor } from '@domain/editor/slate/utils/slate';

function useEditor(...plugins: Array<(editor: Editor) => Editor>): Editor {
return useMemo(() => buildEditor(...plugins), []); // eslint-disable-line react-hooks/exhaustive-deps
function useEditor(...plugins: Array<(editor: Editor) => Editor>) {
return useState(() => buildEditor(...plugins)); // eslint-disable-line react-hooks/exhaustive-deps
}

export default useEditor;
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { FugueDomainOperations } from '@domain/editor/fugue/operations/fugue/typ
*/
function useEvents(fugueOperations: FugueDomainOperations, { socket }: Communication, onDone: () => void) {
function onOperation(operations: Operation[]) {
console.log('operations', operations);
fugueOperations.applyOperations(operations);
onDone();
}
Expand Down

0 comments on commit ee8ce53

Please sign in to comment.