Skip to content

Commit

Permalink
refactor(CollabEditor): get ydoc versions throught api and refetch af…
Browse files Browse the repository at this point in the history
…ter user done editing
  • Loading branch information
nonumpa committed Sep 7, 2023
1 parent faf31f5 commit 23fb1a5
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 20 deletions.
33 changes: 32 additions & 1 deletion components/Collaborate/CollabEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import useCurrentUser from 'lib/useCurrentUser';
import PlaceholderPlugin from './Placeholder';
import getConfig from 'next/config';
import CollabHistory from './CollabHistory';
import gql from 'graphql-tag';
import { useQuery } from '@apollo/react-hooks';

const {
publicRuntimeConfig: { PUBLIC_COLLAB_SERVER_URL },
Expand Down Expand Up @@ -81,6 +83,17 @@ const colors = [

const color = colors[Math.floor(Math.random() * colors.length)];

const YDOC_VERSIONS_QUERY = gql`
query GetYdocVersions($id: String!) {
GetYdoc(id: $id) {
versions {
createdAt
snapshot
}
}
}
`;

const Editor = ({ provider, currentUser, className, innerRef, onUnmount }) => {
useEffect(() => {
// console.log('editor mount');
Expand Down Expand Up @@ -139,6 +152,14 @@ const CollabEditor = ({ article }) => {
// onTranscribe setup provider for both Editor and CollabHistory to use.
// And, to avoid duplicated connection, provider will be destroyed(close connection) when Editor unmounted.
const [provider, setProvider] = useState(null);
const { loading, data: getYdocData, refetch } = useQuery(
YDOC_VERSIONS_QUERY,
{
variables: { id: article.id },
ssr: false, // No need to fetch on server
}
);
const versionList = getYdocData?.GetYdoc?.versions || [];

const onTranscribe = () => {
if (!currentUser) {
Expand Down Expand Up @@ -187,6 +208,10 @@ const CollabEditor = ({ article }) => {
// TODO: listen textChanged event?
article.text = text;
}

// refetch to get latest versionList
refetch({ id: article.id });

setShowEditor(false);
};

Expand Down Expand Up @@ -238,7 +263,13 @@ const CollabEditor = ({ article }) => {
{t`Edit`}
</Button>
) : (
isSynced && <CollabHistory ydoc={provider.document} />
isSynced &&
!loading && (
<CollabHistory
ydoc={provider.document}
versionList={versionList}
/>
)
)}
</>
)}
Expand Down
47 changes: 28 additions & 19 deletions components/Collaborate/CollabHistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ const useStyles = makeStyles(theme => ({

const renderVersion = (editorview, version, prevVersion) => {
const transaction = editorview.state.tr.setMeta(ySyncPluginKey, {
snapshot: Y.decodeSnapshot(version.snapshot),
snapshot: Y.decodeSnapshot(Buffer.from(version.snapshot, 'base64')),
prevSnapshot:
prevVersion == null
? Y.emptySnapshot
: Y.decodeSnapshot(prevVersion.snapshot),
: Y.decodeSnapshot(Buffer.from(prevVersion.snapshot, 'base64')),
});
editorview.dispatch(transaction);
};
Expand All @@ -74,28 +74,28 @@ const renderVersion = (editorview, version, prevVersion) => {
* Should render `Versions` after `editorLoaded`,
* `Versions` will default render latest version
* @param {EditorView} editorView
* @param {Y.Doc} ydoc
* @param {(version: Y.Snapshot, index: number) => void} onSelect - called when version selected
* @param {Array<{snapshot: string, createdAt: string}>} versionList
* @param {(version: {snapshot: string, createdAt: string}, index: number) => void} onSelect - called when version selected
*/
const Versions = ({ editorView, ydoc, onSelect }) => {
const versions = ydoc.getArray('versions');
const defaultVIdx = versions.length - 1;
const Versions = ({ editorView, versionList, onSelect }) => {
const defaultVIdx = versionList.length - 1;
const [selectedVersion, setSelectedVersion] = useState(null);

useEffect(() => {
if (defaultVIdx === -1) return;
// default select latest version
selectAndRender(defaultVIdx);
}, [defaultVIdx, selectAndRender]);

const selectAndRender = useCallback(
reverseIdx => {
setSelectedVersion(reverseIdx);
const version = versions.get(reverseIdx);
const prevVersion = reverseIdx > 0 ? versions.get(reverseIdx - 1) : null;
const version = versionList[reverseIdx];
const prevVersion = reverseIdx > 0 ? versionList[reverseIdx - 1] : null;
onSelect(version, reverseIdx);
renderVersion(editorView, version, prevVersion);
},
[versions, onSelect, editorView]
[editorView, versionList, onSelect]
);

const toggleChanged = (event, reverseIdx) => {
Expand All @@ -107,22 +107,22 @@ const Versions = ({ editorView, ydoc, onSelect }) => {
return (
<>
<Typography variant="h6">{t`Versions`}</Typography>
{versions.length > 0 ? (
{versionList.length > 0 ? (
<ToggleButtonGroup
orientation="vertical"
value={selectedVersion}
exclusive
onChange={toggleChanged}
style={{ overflow: 'auto' }}
>
{versions.map((v, i) => {
{versionList.map((v, i) => {
// list version in reverse order
const reverseIdx = versions.length - 1 - i;
const version = versions.get(reverseIdx);
const reverseIdx = versionList.length - 1 - i;
const version = versionList[reverseIdx];

return (
<ToggleButton key={reverseIdx} value={reverseIdx}>
{new Date(version.date).toLocaleString()}
{new Date(version.createdAt).toLocaleString()}
</ToggleButton>
);
})}
Expand All @@ -135,7 +135,7 @@ const Versions = ({ editorView, ydoc, onSelect }) => {
};

const CustomModalContent = forwardRef(function CustomModalContent(
{ ydoc, onClose },
{ ydoc, onClose, versionList },
ref
) {
const editor = useRef(ref);
Expand Down Expand Up @@ -169,8 +169,9 @@ const CustomModalContent = forwardRef(function CustomModalContent(
editorView={editor.current.view}
ydoc={ydoc}
onSelect={version =>
setVersionTitle(new Date(version.date).toLocaleString())
setVersionTitle(new Date(version.createdAt).toLocaleString())
}
versionList={versionList}
/>
)}
</Box>
Expand All @@ -189,7 +190,11 @@ const CustomModalContent = forwardRef(function CustomModalContent(
);
});

const CollabHistory = ({ ydoc }) => {
/**
* @param {Y.Doc} ydoc
* @param {Array<{snapshot: string, createdAt: string}>} versionList
*/
const CollabHistory = ({ ydoc, versionList }) => {
const [open, setOpen] = useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
Expand All @@ -207,7 +212,11 @@ const CollabHistory = ({ ydoc }) => {
{t`History`}
</Button>
<Modal open={open} onClose={handleClose}>
<CustomModalContent ydoc={ydoc} onClose={handleClose} />
<CustomModalContent
ydoc={ydoc}
versionList={versionList}
onClose={handleClose}
/>
</Modal>
</div>
</>
Expand Down

0 comments on commit 23fb1a5

Please sign in to comment.