mirror of
https://github.com/fluencelabs/fluent-pad
synced 2025-04-25 08:52:14 +00:00
79 lines
2.3 KiB
TypeScript
79 lines
2.3 KiB
TypeScript
import _ from 'lodash';
|
|
import { useEffect, useState } from 'react';
|
|
|
|
import { getUpdatedDocFromText, initDoc, SyncClient } from '../app/sync';
|
|
import { withErrorHandlingAsync } from './util';
|
|
import { addEntry, getHistory, registerTextState } from 'src/_aqua/app';
|
|
|
|
const broadcastUpdates = _.debounce((text: string, syncClient: SyncClient) => {
|
|
let doc = syncClient.getDoc();
|
|
if (doc) {
|
|
let newDoc = getUpdatedDocFromText(doc, text);
|
|
syncClient.syncDoc(newDoc);
|
|
}
|
|
}, 100);
|
|
|
|
export const CollaborativeEditor = () => {
|
|
const [text, setText] = useState<string | null>(null);
|
|
const [syncClient, setSyncClient] = useState(new SyncClient());
|
|
|
|
useEffect(() => {
|
|
syncClient.handleDocUpdate = (doc) => {
|
|
setText(doc.text.toString());
|
|
};
|
|
|
|
syncClient.handleSendChanges = (changes: string) => {
|
|
withErrorHandlingAsync(async () => {
|
|
const res = await addEntry(changes);
|
|
if (res.ret_code !== 0) {
|
|
throw new Error(
|
|
`Failed to add message to history service, code=${res.ret_code}, message=${res.err_msg}`,
|
|
);
|
|
}
|
|
});
|
|
};
|
|
|
|
registerTextState({
|
|
notifyTextUpdate: (changes, isAuthorized) => {
|
|
if (changes) {
|
|
syncClient.receiveChanges(changes);
|
|
}
|
|
}
|
|
})
|
|
|
|
syncClient.start();
|
|
|
|
// don't block
|
|
withErrorHandlingAsync(async () => {
|
|
const res = await getHistory();
|
|
for (let e of res.entries) {
|
|
syncClient.receiveChanges(e.body);
|
|
}
|
|
|
|
if (syncClient.getDoc() === undefined) {
|
|
syncClient.syncDoc(initDoc());
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
syncClient.stop();
|
|
};
|
|
}, []);
|
|
|
|
const handleTextUpdate = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
const newText = e.target.value;
|
|
setText(newText);
|
|
broadcastUpdates(newText, syncClient);
|
|
};
|
|
|
|
return (
|
|
<textarea
|
|
spellCheck={false}
|
|
className="code-editor"
|
|
disabled={text === null}
|
|
value={text ?? ''}
|
|
onChange={handleTextUpdate}
|
|
/>
|
|
);
|
|
};
|