Skip to content

Instantly share code, notes, and snippets.

@KTZgraph
Created February 19, 2023 17:01
Show Gist options
  • Save KTZgraph/05b710142902bc78ba9a71a8a2004955 to your computer and use it in GitHub Desktop.
Save KTZgraph/05b710142902bc78ba9a71a8a2004955 to your computer and use it in GitHub Desktop.
[DRAFT] skróty działają, baza też, p-f/commit/ac3920cff50a9c830ad340c5c337a00d79724c26
// TODO https://quilljs.com/docs/modules/keyboard/#key-bindings
// todo zapis pliku https://stackoverflow.com/questions/42843355/quilljs-downlaod-docx
// TODO pdf https://codesandbox.io/s/quill-text-forked-6vrbe1
// TODO docx https://stackblitz.com/edit/quill-to-word-demo?file=src%2Fapp%2Fapp.component.ts https://github.com/andrewraygilbert/quill-to-word#readme
// TODO zpaisanie do jsona https://github.com/quilljs/quill/issues/83
// TODO do htmla https://codesandbox.io/s/github/acanimal/react-quill-with-markdown
import React, { useCallback, useEffect, useRef, useState } from "react";
// https://www.youtube.com/watch?v=iRaelG7v0OU
// npm i quill
import Quill from "quill";
import "quill/dist/quill.snow.css";
import { io } from "socket.io-client";
import "./QuillEditor.scss";
const BACKEND_SOCKET_URL = "http://localhost:3001";
const SAVE_INTERVAL_MS = 5000;
const TOOLBAR_OPTIONS = [
// https://youtu.be/iRaelG7v0OU?t=1226
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ font: [] }],
[{ list: "ordered" }, { list: "bullet" }],
["bold", "italic", "underline"],
[{ color: [] }, { background: [] }],
[{ script: "sub" }, { script: "super" }],
[{ align: [] }],
["image", "blockquote", "code-block"],
["clean"],
];
const QuillEditor = ({ currentTableNoteId }) => {
console.log("QuillEditor currentTableNoteId: ", currentTableNoteId);
const [socketInstance, setSocketInstance] = useState();
const [quillInstance, setQuillInstance] = useState();
console.log("socketInstance: ", socketInstance);
// do zapisywanie pliku do bazy https://youtu.be/iRaelG7v0OU?t=2665
useEffect(() => {
if (socketInstance == null || quillInstance == null) return;
// co kilka sekund zapisujemy dokuemny
const interval = setInterval(() => {
console.log("na froniec save-document");
console.log("quillInstance.getContents()", quillInstance.getContents());
socketInstance.emit("save-document", {
tableId: currentTableNoteId,
data: quillInstance.getContents(),
});
}, SAVE_INTERVAL_MS);
// czyszczenie
return () => {
clearInterval(interval);
};
}, [socketInstance, quillInstance]);
// use efekt żeby NIE edytować tylko jednego dokuemntau - podział na pokoje https://youtu.be/iRaelG7v0OU?t=2097
useEffect(() => {
if (!currentTableNoteId) return;
if (socketInstance == null || quillInstance == null) return;
socketInstance.once("load-document", (document) => {
console.log("document z bakcendu", document);
quillInstance.setContents(document);
quillInstance.enable();
});
socketInstance.emit("get-document", currentTableNoteId);
}, [socketInstance, quillInstance, currentTableNoteId]);
// odbieranie zdarzeń receive-changes- zmiany zrobione przez drugiego usera
useEffect(() => {
if (socketInstance == null || quillInstance == null) return;
const handler = (delta) => {
quillInstance.updateContents(delta);
};
socketInstance.on("receive-changes", handler);
return () => {
socketInstance.off("receive-changes", handler); // usuwanie listenera
};
}, [socketInstance, quillInstance]);
//WYSYŁANIE danych do zmian quila https://youtu.be/iRaelG7v0OU?t=1559
useEffect(() => {
// BUG za pierwszym razem socket i quil sa undefined
if (socketInstance == null || quillInstance == null) return;
const handler = (delta, oldDelta, source) => {
if (source !== "user") return; //śledzę zmiany robione tylko przez usera
console.log("Handler: =========");
socketInstance.emit("send-changes", delta);
};
quillInstance.on("text-change", handler);
// usuwanie listenera
return () => {
quillInstance.off("text-change", handler);
};
}, [socketInstance, quillInstance]);
// const wrapperRef = useRef();
// ---------------- use effect do połączenia się z socketem
useEffect(() => {
// https://youtu.be/iRaelG7v0OU?t=1398
// const socket = io("BACKEND_SOCKET_URL");
const socket = io.connect(BACKEND_SOCKET_URL);
setSocketInstance(socket);
// czyszczenie
return () => {
socket.disconnect();
};
}, []);
// połączenie z socketem
// ---------------- instancja Quil -----------------
const wrapperRef = useCallback((wrapper) => {
if (wrapper === null) return;
wrapper.innerHTML = ""; //czyszczenkie na poczatku bo useCallback nie ma cleanup jak useEffect
const editor = document.createElement("div");
wrapper.append(editor);
// tylko raz
const quill = new Quill(editor, {
theme: "snow",
modules: {
toolbar: TOOLBAR_OPTIONS,
// https://codepen.io/devui-design/pen/mdJWwvE
keyboard: {
bindings: {
// nadpisanie skrótu
underline: {
//BUG mu byś tutaj bo potrzebne this i nadpisuje sktróy do pordkreślenia
key: "u",
ctrlKey: true,
shiftKey: false,
handler: function (range, context) {
const selection = this.quill.getSelection();
this.quill.insertText(range.index, "ü", "user"); //wysyał na backend
this.quill.setSelection({
...selection,
index: selection.index + 1,
});
},
},
},
},
},
});
// dodanie bindingów
quill.keyboard.addBinding(
{
key: "S",
ctrlKey: true,
shiftKey: true,
},
function (range, context) {
const selection = quill.getSelection();
quill.insertText(selection.index, "ẞ", "user"); //wysyał na backend, BUG bez user nie zapisuje do bazy
// jedyny sposób żeby wziać kursor przesunąć - bez "user" ładnie się sam przesuwa; ale wtedy nie wysyał znaku na backend
quill.setSelection({
...selection,
index: selection.index + 1,
});
}
);
quill.keyboard.addBinding(
{ key: "s", ctrlKey: true },
function (range, context) {
const selection = quill.getSelection();
quill.insertText(selection.index, "ß", "user"); //wysyał na backend
quill.setSelection({
...selection,
index: selection.index + 1,
});
}
);
quill.keyboard.addBinding(
{ key: "u", ctrlKey: true, shiftKey: true },
function (range, context) {
const selection = quill.getSelection();
quill.insertText(range.index, "Ü", "user"); //wysyał na backend
quill.setSelection({
...selection,
index: selection.index + 1,
});
}
);
quill.keyboard.addBinding(
{ key: "O", ctrlKey: true, shiftKey: true },
function (range, context) {
const selection = quill.getSelection();
quill.insertText(range.index, "Ö", "user");
quill.setSelection({
...selection,
index: selection.index + 1,
});
}
);
quill.keyboard.addBinding(
{ key: "o", ctrlKey: true },
function (range, context) {
const selection = quill.getSelection();
quill.insertText(range.index, "ö", "user"); //wysyał na backend
quill.setSelection({
...selection,
index: selection.index + 1,
});
}
);
quill.keyboard.addBinding(
{ key: "A", ctrlKey: true, shiftKey: true },
function (range, context) {
const selection = quill.getSelection();
quill.insertText(range.index, "Ä", "user"); //wysyał na backend
quill.setSelection({
...selection,
index: selection.index + 1,
});
}
);
quill.keyboard.addBinding(
{ key: "a", ctrlKey: true },
function (range, context) {
const selection = quill.getSelection();
quill.insertText(range.index, "ä", "user"); //wysyał na backend
quill.setSelection({
...selection,
index: selection.index + 1,
});
}
);
// disable edytor zanim załaduje się dokuemnt
quill.disable();
quill.setText("Ładowanie dokumentu...");
// zapisywanie quil do statnu
setQuillInstance(quill); //https://youtu.be/iRaelG7v0OU?t=1544
}, []);
if (!currentTableNoteId) return;
return (
<div id="quill-container" ref={wrapperRef} className="quill-editor">
QuillEditor
</div>
);
};
export default QuillEditor;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment