Basic Quill collab integration

This commit is contained in:
Kurt Berglund 2016-11-12 12:02:03 -08:00
Родитель 92d09dd983
Коммит 5c7f36ad8c
8 изменённых файлов: 119 добавлений и 34 удалений

3
server/.vscode/settings.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
{
"typescript.tsdk": "./node_modules/typescript/lib"
}

Просмотреть файл

@ -89,7 +89,8 @@ gulp.task("collab", function() {
debug: true,
entries: ['src/collab/collab.ts'],
cache: {},
packageCache: {}
packageCache: {},
standalone: 'collab'
})
.plugin(tsify)
.bundle()

Просмотреть файл

@ -2,35 +2,71 @@ import * as io from 'socket.io-client';
import * as Quill from 'quill';
import * as $ from 'jquery';
let socket = io();
socket.on('user connect', (msg) => {
$("#console").append('<div>New user connected</div>');
});
socket.on('user disconnect', (msg) => {
$("#console").append('<div>User disconnected</div>');
});
// Implement and register module
Quill.register('modules/counter', function(quill, options) {
Quill.register('modules/counter', (quill, options) => {
var container = document.querySelector(options.container);
quill.on('text-change', function() {
quill.on('text-change', (delta: Quill.DeltaStatic, oldContents: Quill.DeltaStatic, source: String) => {
var text = quill.getText();
// There are a couple issues with counting words
// this way but we'll fix these later
container.innerHTML = text.split(/\s+/).length;
socket.emit('chat message', text);
container.innerHTML = text.split(/\s+/).length;
});
});
var editor = new Quill('#editor', {
modules: {
toolbar: '#toolbar',
counter: {
container: '#counter'
}
},
theme: 'snow'
});
export function connect(id: string) {
let socket = io();
let editor = null;
let suppressChange = false;
socket.emit('join', id, (opsDocument: any[]) => {
editor = new Quill('#editor', {
modules: {
toolbar: '#toolbar',
counter: {
container: '#counter'
}
},
theme: 'snow'
});
(<any> window).myQuillEditor = editor;
// Seed the editor with the previous document
for (let ops of opsDocument) {
editor.updateContents(<Quill.DeltaStatic>(<any> { ops: ops.deltas }));
}
// Listen for future updates
editor.on('text-change', (delta: Quill.DeltaStatic, oldContents: Quill.DeltaStatic, source: String) => {
// If we are processing an append don't handle the text change event
if (suppressChange) {
return;
}
var contents = editor.getContents();
socket.emit('append', {
room: id,
ops: delta.ops
});
});
});
socket.on('user connect', (msg) => {
// $("#console").append('<div>New user connected</div>');
});
socket.on('user disconnect', (msg) => {
// $("#console").append('<div>User disconnected</div>');
});
socket.on('append', (ops) => {
let delta = {
ops: ops
};
suppressChange = true;
editor.updateContents(<Quill.DeltaStatic>(<any> delta));
suppressChange = false;
})
}

Просмотреть файл

@ -82,11 +82,11 @@ class Collection<T> {
});
}
create(document: T): Promise<T> {
create(document: T, disableAutomaticIdGeneration = true): Promise<T> {
let collectionUrl = getCollectionUrl(this.name);
return this._collectionP.then(() => {
return createDocument(collectionUrl, document, { disableAutomaticIdGeneration: true });
return createDocument(collectionUrl, document, { disableAutomaticIdGeneration: disableAutomaticIdGeneration });
});
}

18
server/src/db/deltas.ts Normal file
Просмотреть файл

@ -0,0 +1,18 @@
import * as connection from './connection';
import { Promise } from 'es6-promise';
import * as _ from 'lodash';
import * as moment from 'moment';
const collectionName = 'deltas'
var collection = connection.getOrCreateCollection(collectionName);
export function append(id: string, deltas: any[]): Promise<any> {
let now = moment.now();
return collection.create({ document: id, deltas: deltas, ts: now, }, false);
}
export function get(id: string): Promise<any> {
let opsP = collection.query("SELECT * FROM deltas WHERE deltas.document=@id ORDER BY deltas.ts", [{ name: "@id", value: id }]);
return opsP;
}

Просмотреть файл

@ -1,10 +1,34 @@
import socketIo = require('socket.io');
import * as deltasDB from './db/deltas';
var io = socketIo();
interface IAppendOperation {
room: string;
ops: any[];
}
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
console.log(`message: ` + msg);
socket.on('join', (room, response) => {
console.log(`Join of room ${room} requested`);
socket.join(room);
deltasDB.get(room).then(
(deltas) => {
console.log('Recieved deltas');
response(deltas);
},
(error) => {
console.log("error getting existing deltas");
});
});
socket.on('append', (append: IAppendOperation) => {
console.log('Append received');
console.log(JSON.stringify(append, null, 2));
deltasDB.append(append.room, append.ops);
socket.to(append.room).broadcast.emit('append', append.ops);
});
socket.on('disconnect', () => {

Просмотреть файл

@ -3,11 +3,12 @@ import { defaultPartials } from './partials';
var router = express.Router();
router.get('/', (req: express.Request, response: express.Response) => {
router.get('/:id', (req: express.Request, response: express.Response) => {
response.render(
'collab',
{
partials: defaultPartials
partials: defaultPartials,
id: req.params['id']
});
});

Просмотреть файл

@ -14,7 +14,6 @@
<!-- Create the editor container -->
<div id="editor">
<p>Hello World!</p>
</div>
<div id="counter"></div>
<div id="console"></div>
@ -22,6 +21,9 @@
{{$scripts}}
<!-- Include the Quill library -->
<script src="/dist/collab/collab.js"></script>
<script src="/dist/collab/collab.js"></script>
<script>
collab.connect("{{id}}");
</script>
{{/scripts}}
{{/layout}}