Skip to content

Instantly share code, notes, and snippets.

@jvaill
Created July 14, 2020 05:16
Show Gist options
  • Save jvaill/a7ceeb0bc9714d067912fe6d345e712c to your computer and use it in GitHub Desktop.
Save jvaill/a7ceeb0bc9714d067912fe6d345e712c to your computer and use it in GitHub Desktop.
import { schema } from "prosemirror-schema-basic";
import { EditorState } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import { Step } from "prosemirror-transform";
import { collab, sendableSteps, getVersion, receiveTransaction } from "prosemirror-collab";
import { undo, redo, history } from "prosemirror-history";
import { keymap } from "prosemirror-keymap";
import { baseKeymap } from "prosemirror-commands";
import placeholder from "./editorPlugins/placeholder";
const seedlingName = "my seedling doc";
const db = firebase.firestore();
const docRef = db.collection("seedlings").doc(seedlingName);
const changesRef = docRef.collection("changes");
const state = EditorState.create({
schema,
plugins: [
history(),
keymap({ "Mod-z": undo, "Mod-y": redo }),
keymap(baseKeymap),
placeholder("Share your story..."),
collab({ version: 0 }),
]
});
const view = new EditorView(
{
mount: document.getElementById("editor"),
},
{
state,
dispatchTransaction(transaction) {
let newState = view.state.apply(transaction)
view.updateState(newState)
const sendable = sendableSteps(newState)
if (sendable) {
sendSteps(sendable.version, sendable.steps, sendable.clientID);
}
},
},
);
let isSending = false;
const sendSteps = async (version, steps, clientId) => {
if (isSending) {
return;
}
isSending = true;
await db.runTransaction(async transaction => {
const changeRef = changesRef.doc(version.toString().padStart(10, "0"));
const change = await transaction.get(changeRef);
if (change.exists) {
return;
}
transaction.set(changeRef, {
cId: clientId,
s: steps.map(step => step.toJSON()),
});
});
isSending = false;
};
changesRef
.orderBy(firebase.firestore.FieldPath.documentId(), "asc")
.onSnapshot(snapshot => {
const steps = [];
const clientIds = [];
snapshot
.docChanges()
.forEach(change => {
if (change.type !== "added") {
return;
}
const { s: changeStepsJSON, cId: clientId } = change.doc.data();
changeStepsJSON.forEach(stepJson => {
const step = Step.fromJSON(schema, stepJson);
steps.push(step);
clientIds.push(clientId);
});
});
view.dispatch(receiveTransaction(view.state, steps, clientIds));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment