-
Notifications
You must be signed in to change notification settings - Fork 459
Expand file tree
/
Copy pathclient.js
More file actions
112 lines (94 loc) · 3.14 KB
/
client.js
File metadata and controls
112 lines (94 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import ReconnectingWebSocket from 'reconnecting-websocket';
import sharedb from 'sharedb/lib/client';
import richText from 'rich-text';
import Quill from 'quill';
import QuillCursors from 'quill-cursors';
import tinycolor from 'tinycolor2';
import ObjectID from 'bson-objectid';
sharedb.types.register(richText.type);
Quill.register('modules/cursors', QuillCursors);
var connectionButton = document.getElementById('client-connection');
connectionButton.addEventListener('click', function() {
toggleConnection(connectionButton);
});
var nameInput = document.getElementById('name');
var colors = {};
var collection = 'examples';
var id = 'richtext';
var presenceId = new ObjectID().toString();
var socket = new ReconnectingWebSocket('ws://' + window.location.host, [], {
// ShareDB handles dropped messages, and buffering them while the socket
// is closed has undefined behavior
maxEnqueuedMessages: 0
});
var connection = new sharedb.Connection(socket);
var doc = connection.get(collection, id);
doc.subscribe(function(err) {
if (err) throw err;
initialiseQuill(doc);
});
function initialiseQuill(doc) {
var quill = new Quill('#editor', {
theme: 'snow',
modules: {
cursors: true,
toolbar: true,
}
});
var cursors = quill.getModule('cursors');
quill.setContents(doc.data);
quill.on('text-change', function(delta, oldDelta, source) {
if (source !== 'user') return;
doc.submitOp(delta);
});
doc.on('op', function(op, source) {
if (source) return;
quill.updateContents(op);
});
var presence = doc.connection.getDocPresence(collection, id);
presence.subscribe(function(error) {
if (error) throw error;
});
var localPresence = presence.create(presenceId);
quill.on('selection-change', function(range, oldRange, source) {
// We only need to send updates if the user moves the cursor
// themselves. Cursor updates as a result of text changes will
// automatically be handled by the remote client.
if (source !== 'user') return;
// Ignore blurring, so that we can see lots of users in the
// same window. In real use, you may want to clear the cursor.
if (!range) return;
// In this particular instance, we can send extra information
// on the presence object. This ability will vary depending on
// type.
range.name = nameInput.value;
localPresence.submit(range, function(error) {
if (error) throw error;
});
});
presence.on('receive', function(id, range) {
colors[id] = colors[id] || tinycolor.random().toHexString();
var name = (range && range.name) || 'Anonymous';
cursors.createCursor(id, name, colors[id]);
cursors.moveCursor(id, range);
});
return quill;
}
function toggleConnection(button) {
if (button.classList.contains('connected')) {
button.classList.remove('connected');
button.textContent = 'Connect';
disconnect();
} else {
button.classList.add('connected');
button.textContent = 'Disconnect';
connect();
}
}
function disconnect() {
doc.connection.close();
}
function connect() {
var socket = new ReconnectingWebSocket('ws://' + window.location.host);
doc.connection.bindToSocket(socket);
}