From d09cb474162f76bdd0ed41587b3c1c3ba1bdfe4c Mon Sep 17 00:00:00 2001 From: Mikolaj Trzcinski Date: Tue, 10 Dec 2024 15:23:51 +0100 Subject: [PATCH] [#70043] Copy comments on commit --- src/comments/ycomments.js | 45 ++++++++++++++++++++++++++++++++++ src/components/Resolved.jsx | 2 +- src/myst-git/MystEditorGit.jsx | 12 ++++++++- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/comments/ycomments.js b/src/comments/ycomments.js index e02e5f3..52dd109 100644 --- a/src/comments/ycomments.js +++ b/src/comments/ycomments.js @@ -564,4 +564,49 @@ export class YComments { newLine: transaction.state.doc.lineAt(newPos).number, }; } + + encodeState() { + const positions = this.positions().syncedPositions.toJSON(); + const suggestions = this.suggestions.toJSON(); + const resolved = this.resolver().resolvedComments.toJSON(); + const lineAuthors = {}; + const text = {}; + const allComments = [...this.comments.peek(), ...this.resolver().resolved()]; + for (const { commentId } of allComments) { + const lineData = this.lineAuthors(commentId); + lineAuthors[commentId] = lineData.lineAuthors.toJSON(); + const commentText = this.getTextForComment(commentId); + text[commentId] = commentText.toString(); + } + + return { positions, suggestions, resolved, lineAuthors, text }; + } + + applyState({ positions, suggestions, resolved, lineAuthors, text }) { + this.ydoc.transact(() => { + for (const id in positions) { + this.positions().syncedPositions.set(id, positions[id]); + } + for (const id in suggestions) { + this.suggestions.set(id, suggestions[id]); + } + for (const id in resolved) { + this.resolver().resolvedComments.set(id, resolved[id]); + } + for (const id in lineAuthors) { + const lineData = this.lineAuthors(id); + lineAuthors[id].forEach((line) => { + const map = new Y.Map(); + if (line.author) { + map.set("author", line.author); + } + lineData.lineAuthors.push([map]); + }); + } + for (const id in text) { + const commentText = this.getTextForComment(id); + commentText.insert(0, text[id]); + } + }); + } } diff --git a/src/components/Resolved.jsx b/src/components/Resolved.jsx index 487f71c..a887f5a 100644 --- a/src/components/Resolved.jsx +++ b/src/components/Resolved.jsx @@ -78,7 +78,7 @@ const ResolvedComments = ({ ycomments }) => { useEffect(() => { setResolvedComments(ycomments.resolver().resolved().sort(dateComparator)); ycomments.resolver().onUpdate((comments) => setResolvedComments(comments.sort(dateComparator))); - }, []); + }, [ycomments]); return ( diff --git a/src/myst-git/MystEditorGit.jsx b/src/myst-git/MystEditorGit.jsx index e265dd5..3d820d6 100644 --- a/src/myst-git/MystEditorGit.jsx +++ b/src/myst-git/MystEditorGit.jsx @@ -140,6 +140,7 @@ const MystEditorGit = ({ const changeHistory = useSignal(initialHistory); const toast = useSignal(null); const commitSummary = useSignal(null); + const commentStateToApply = useRef(null); useEffect(() => { window.myst_editor[props.id].state = mystState.current; @@ -166,6 +167,7 @@ const MystEditorGit = ({ try { commitSummary.value = null; const { hash, webUrl } = await commitChanges(message); + commentStateToApply.current = window.myst_editor[props.id].ycomments.encodeState(); toast.value = { text: "Changes have been commited. ", link: { text: "See in Gitlab", href: webUrl } }; switchCommit({ hash, message: summary }, true); } catch (error) { @@ -310,6 +312,14 @@ const MystEditorGit = ({ }; doc.on("afterTransaction", handleChange); + // This is done to keep this signal effect from running in a cycle when some singals are updated in applyState. + queueMicrotask(() => { + if (commentStateToApply.current != null) { + window.myst_editor[props.id].ycomments.applyState(commentStateToApply.current); + commentStateToApply.current = null; + } + }); + return () => doc.off("afterTransaction", handleChange); }); @@ -385,7 +395,7 @@ const MystEditorGit = ({ )} - {commitSummary.value && } + {commitSummary.value && } {room.value && }