Skip to content

Commit

Permalink
Code Refactoring & Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
R1c4rdCo5t4 committed May 12, 2024
1 parent 5e8cec3 commit e8c94e8
Show file tree
Hide file tree
Showing 33 changed files with 168 additions and 118 deletions.
2 changes: 1 addition & 1 deletion code/client/src/domain/editor/hooks/useEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function useEvents(fugueOperations: FugueDomainOperations, { socket }: Communica
}

useSocketListeners(socket, {
operation: onOperation,
operations: onOperation,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default (fugue: Fugue, { socket }: Communication): HistoryDomainOperation
.flat()
.filter(operation => operation !== undefined && operation !== null);

socket.emit('operation', communicationOperations);
socket.emit('operations', communicationOperations);
};

function getOperation(operation: HistoryOperation) {
Expand Down
12 changes: 6 additions & 6 deletions code/client/src/domain/editor/operations/input/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,39 @@ export default (fugue: Fugue, { socket }: Communication): InputDomainOperations
function insertCharacter(char: string, cursor: Cursor, styles: InlineStyle[] = []) {
if (char.length !== 1) throw new Error('Invalid character');
const operations = fugue.insertLocal(cursor, nodeInsert(char, styles));
socket.emit('operation', operations);
socket.emit('operations', operations);
}

function insertLineBreak(cursor: Cursor) {
const operations = fugue.insertLocal(cursor, '\n');
const styleOperation = fugue.updateBlockStyleLocal(cursor.line + 1, 'paragraph', true);
socket.emit('operation', [styleOperation, ...operations]);
socket.emit('operations', [styleOperation, ...operations]);
}

function deleteCharacter(cursor: Cursor) {
// don't delete line if it's not a paragraph - this is to prevent deleting the block style & line simultaneously
if (cursor.column === 0 && fugue.getBlockStyle(cursor.line) !== 'paragraph') return;
const operations = fugue.deleteLocalByCursor(cursor);
if (operations) socket.emit('operation', operations);
if (operations) socket.emit('operations', operations);
}

function deleteSelection(selection: Selection) {
const operations = fugue.deleteLocal(selection);
socket.emit('operation', operations);
socket.emit('operations', operations);
}

function deleteWord(cursor: Cursor, reverse: boolean) {
const operations = fugue.deleteWordByCursor(cursor, reverse);
if (!operations) return;
socket.emit('operation', operations);
socket.emit('operations', operations);
}

function pasteText(start: Cursor, text: string) {
const chars = text.split('');
const lineNodes = chars.filter(char => char === '\n');
const insertOperations: Operation[] = fugue.insertLocal(start, ...text);
const styleOperations = lineNodes.map(() => fugue.updateBlockStyleLocal(start.line + 1, 'paragraph', true));
socket.emit('operation', [...styleOperations, ...insertOperations]);
socket.emit('operations', [...styleOperations, ...insertOperations]);
}

function updateSelection(range: BaseSelection, styles: InlineStyle[]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default (fugue: Fugue, { socket }: Communication): MarkdownDomainOperatio
operations.push(styleOperation);

// emit operations
socket.emit('operation', operations);
socket.emit('operations', operations);
}

/**
Expand All @@ -64,7 +64,7 @@ export default (fugue: Fugue, { socket }: Communication): MarkdownDomainOperatio
operations.push(...styleOperations);

// emit operations
socket.emit('operation', operations);
socket.emit('operations', operations);
}

function deleteBlockStyles(selection: Selection) {
Expand All @@ -75,7 +75,7 @@ export default (fugue: Fugue, { socket }: Communication): MarkdownDomainOperatio
if ((start === end && start.column === 0) || start.line !== end.line) {
const newSelection = start.column !== 0 ? { start: { line: start.line + 1, column: 0 }, end } : selection;
const operations = fugue.updateBlockStylesLocalBySelection('paragraph', newSelection);
socket.emit('operation', operations);
socket.emit('operations', operations);
}
}

Expand Down
2 changes: 1 addition & 1 deletion code/client/src/domain/editor/slate/hooks/useRenderers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function useRenderers(editor: Editor, fugue: Fugue, { socket }: Communication) {
const line = path[path.length - 1];
const updateBlockStyle = (style: BlockStyle) => {
const operation = fugue.updateBlockStyleLocal(line, style);
socket.emit('operation', [operation]);
socket.emit('operations', [operation]);
};
return getElementRenderer(type, props, updateBlockStyle);
},
Expand Down
15 changes: 7 additions & 8 deletions code/client/src/domain/workspace/WorkspaceContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,15 @@ import { useParams } from 'react-router-dom';

export type WorkspaceContextType = {
workspace?: Workspace;
filePath?: string;
setFilePath: (path: string) => void;
};

export const WorkspaceContext = createContext<WorkspaceContextType>({
workspace: undefined,
filePath: undefined,
setFilePath: () => {},
});

export function WorkspaceProvider({ children }: { children: React.ReactNode }) {
const [workspace, setWorkspace] = useState<Workspace | undefined>(undefined);
const [filePath, setFilePath] = useState<string | undefined>(undefined);
const { http } = useCommunication();
const { http, socket } = useCommunication();
const { publishError } = useError();
const { wid } = useParams();

Expand All @@ -30,8 +25,12 @@ export function WorkspaceProvider({ children }: { children: React.ReactNode }) {
const ws = await http.get(`/workspaces/${wid}`);
setWorkspace(ws);
}
socket.emit('joinWorkspace', wid);
getResources().catch(publishError);
}, [http, publishError, wid]);
return () => {
socket.emit('leaveWorkspace');
};
}, [wid, http, socket, publishError]);

return <WorkspaceContext.Provider value={{ workspace, filePath, setFilePath }}>{children}</WorkspaceContext.Provider>;
return <WorkspaceContext.Provider value={{ workspace }}>{children}</WorkspaceContext.Provider>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class OperationEmitter {
private readonly socket: Socket;
private readonly operationBuffer: Operation[] = [];
private readonly timeoutDuration;
private readonly chunkSize = 100;
private readonly chunkSize = 300;
private readonly maxBufferedOperations = 20;
private timeoutId: NodeJS.Timeout | null = null;

Expand All @@ -34,7 +34,7 @@ export class OperationEmitter {
if (this.operationBuffer.length > this.chunkSize) {
this.emitChunked();
} else {
this.socket.emit('operation', this.operationBuffer);
this.socket.emit('operations', this.operationBuffer);
}
this.operationBuffer.length = 0;
}
Expand All @@ -46,12 +46,12 @@ export class OperationEmitter {
let chunkIndex = 0;
const onAcknowledge = () => {
if (chunkIndex < chunks.length) {
this.socket.emit('operation', chunks[chunkIndex++]);
this.socket.emit('operations', chunks[chunkIndex++]);
return;
}
this.socket.off('ack', onAcknowledge);
};
this.socket.emit('operation', chunks[chunkIndex++]);
this.socket.emit('operations', chunks[chunkIndex++]);
this.socket.on('ack', onAcknowledge);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const operationEmitter = new OperationEmitter(socket, OPERATION_DELAY);

function emit(event: string, data: any) {
switch (event) {
case 'operation':
case 'operations':
operationEmitter.addOperation(...data);
break;
case 'cursorChange':
Expand Down
2 changes: 1 addition & 1 deletion code/client/src/services/documentServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function documentServices(http: HttpCommunication, wid: string) {
}

async function deleteDocument(id: string) {
await http.delete(`/workspace/${wid}/${id}`);
await http.delete(`/workspaces/${wid}/${id}`);
}

async function updateDocument(id: string, name: string) {
Expand Down
1 change: 0 additions & 1 deletion code/client/src/ui/components/header/Header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ header {
box-shadow: black 0 0 1px;
display: flex;
align-items: center;
z-index: 1;

p {
font-size: 2.5vh;
Expand Down
3 changes: 0 additions & 3 deletions code/client/src/ui/components/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import useWorkspace from '@domain/workspace/useWorkspace';
import { Link } from 'react-router-dom';
import './Header.scss';

function Header() {
const { filePath } = useWorkspace();
return (
<header>
<Link to="/">NoteSpace</Link>
<p>{filePath}</p>
</header>
);
}
Expand Down
17 changes: 14 additions & 3 deletions code/client/src/ui/components/sidebar/Sidebar.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.sidebar {
position: relative;
position: fixed;
top: 0;
left: 0;
height: 100vh;
Expand All @@ -11,9 +11,9 @@
overflow-y: scroll;
transition: 0.5s;
padding-top: 60px;
z-index: 2;
color: black;
box-shadow: black 0 0 1px;
box-shadow: black 0 7vh 1px;
z-index: 2;

ul {
margin: 0;
Expand Down Expand Up @@ -41,6 +41,7 @@
padding: 0;
margin: 0;
transition: transform 1s ease-in-out;
z-index: 5 !important;

.icon {
transition: opacity 1s ease-in-out;
Expand All @@ -54,4 +55,14 @@
button:hover {
color: dimgray;
}

.files {
li > * {
display: flex;
flex-direction: row;
align-items: center;
justify-content: left;
gap: 1vh;
}
}
}
26 changes: 19 additions & 7 deletions code/client/src/ui/components/sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { IoMenu } from 'react-icons/io5';
import { IoDocumentText, IoMenu } from 'react-icons/io5';
import { Link } from 'react-router-dom';
import './Sidebar.scss';
import { RiMenuFold2Line, RiMenuFoldLine } from 'react-icons/ri';
import useWorkspace from '@domain/workspace/useWorkspace.ts';
import useSidebarState from '@ui/components/sidebar/hooks/useSidebarState.ts';
import { FaFolder } from 'react-icons/fa6';
import { ResourceType } from '@notespace/shared/src/workspace/types/resource.ts';

function Sidebar() {
const { isOpen, isLocked, handleClick, handleMouseEnter, handleMouseLeave } = useSidebarState();
Expand Down Expand Up @@ -31,12 +33,22 @@ function Sidebar() {
<li>Recent</li>
<li>Workspaces</li>
<li>Settings</li>

{workspace?.resources.map(resource => (
<li key={resource.id}>
<Link to={`/workspaces/${resource.id}`}>{resource.name}</Link>
</li>
))}
{workspace && (
<>
<hr />
<h3>My Files</h3>
<div className="files">
{workspace?.resources.map(resource => (
<li key={resource.id}>
<Link to={`/workspaces/${workspace.id}/${resource.id}`}>
{resource.type === ResourceType.DOCUMENT ? <IoDocumentText /> : <FaFolder />}
{resource.name}
</Link>
</li>
))}
</div>
</>
)}
</ul>
</div>
);
Expand Down
25 changes: 12 additions & 13 deletions code/client/src/ui/pages/document/Document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,42 @@ import { useParams, useNavigate } from 'react-router-dom';
import { useCommunication } from '@/services/communication/context/useCommunication';
import useDocumentServices from '@/services/useDocumentServices';
import useError from '@domain/error/useError';
import useWorkspace from '@domain/workspace/useWorkspace';
import './Document.scss';

function Document() {
const communication = useCommunication();
const services = useDocumentServices();
const { http, socket } = communication;
const fugue = useFugue();
const { publishError } = useError();
const { wid, id } = useParams();
const [title, setTitle] = useState('');
const { id } = useParams();
const [loaded, setLoaded] = useState(false);
const { setFilePath } = useWorkspace();
const [title, setTitle] = useState('');
const { http, socket } = communication;
const navigate = useNavigate();

useEffect(() => {
setLoaded(false); // reset state to load new document (useful for when navigating between documents)

async function fetchDocument() {
if (!id) return;
const { content, name } = await services.getDocument(id);
fugue.applyOperations(content, true);
setTitle(name);
setLoaded(true);
setFilePath(`/documents/${title || 'Untitled'}`);
socket.emit('joinWorkspace', wid);
fugue.applyOperations(content, true);
socket.emit('joinDocument', id);
setLoaded(true);
}
console.log('fetching document');
fetchDocument().catch(e => {
publishError(e);
// navigate('/');
navigate('/');
});
return () => {
socket.emit('leaveDocument');
};
}, [fugue, id, http, socket, publishError, services, setFilePath, navigate, title, wid]);
}, [fugue, id, http, socket, publishError, services, setTitle, navigate]);

if (!loaded) return null;

return <div>{loaded && <Editor title={title} fugue={fugue} communication={communication} />}</div>;
return <Editor title={title} fugue={fugue} communication={communication} />;
}

export default Document;
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import './Editor.scss';
import { useCallback, useEffect } from 'react';

type SlateEditorProps = {
title?: string;
title: string;
fugue: Fugue;
communication: Communication;
};
Expand Down Expand Up @@ -55,7 +55,7 @@ function Editor({ title, fugue, communication }: SlateEditorProps) {
<div className="editor">
<div className="container">
<Slate editor={editor} initialValue={initialValue} onChange={onSelectionChange}>
<Title title={title || ''} placeholder={'Untitled'} communication={communication} />
<Title title={title} placeholder="Untitled" communication={communication} />
<Toolbar onApplyMark={onFormat} />
<Editable
className="editable"
Expand Down
Loading

0 comments on commit e8c94e8

Please sign in to comment.