-
Notifications
You must be signed in to change notification settings - Fork 2
/
tutorial.js
118 lines (101 loc) · 4.17 KB
/
tutorial.js
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
113
114
115
116
117
118
const username = "User-" + Math.round(Math.random() * 10000);
document.getElementById("username").innerHTML = username;
///////////////////////////////////////////////////////////////////////////////
// Connect and Open the Model
///////////////////////////////////////////////////////////////////////////////
// Connect anonymously using the generated display name
Convergence.connectAnonymously(CONVERGENCE_URL, username).then(domain => {
return domain.models().openAutoCreate({
collection: "convergence-tutorials",
id: "textarea",
ephemeral: true,
data: {
text: DEFAULT_TEXT_DATA
}
});
}).then(model => {
const rts = model.elementAt(["text"]);
bindTextarea(rts);
initSharedSelection(rts);
}).catch(error => {
console.error(error);
});
///////////////////////////////////////////////////////////////////////////////
// Text Editor
///////////////////////////////////////////////////////////////////////////////
const textarea = document.getElementById("textarea");
let textEditor;
// Bind the text area to the real time string
function bindTextarea(rts) {
// Set the initial data, and set the cursor to the beginning.
textarea.value = rts.value();
textarea.selectionStart = 0;
textarea.selectionEnd = 0;
// Create the editor utility passing callbacks to bind local events to
// the RealtimeString.
textEditor = new HtmlTextCollabExt.CollaborativeTextArea({
control: textarea,
onInsert: (index, value) => rts.insert(index, value),
onDelete: (index, length) => rts.remove(index, length),
onSelectionChanged: sendLocalSelection
});
// Listen to remote events and pass them to the editor utility
rts.on(Convergence.StringInsertEvent.NAME, (e) => textEditor.insertText(e.index, e.value));
rts.on(Convergence.StringRemoveEvent.NAME, (e) => textEditor.deleteText(e.index, e.value.length));
}
///////////////////////////////////////////////////////////////////////////////
// Share Selection Functions
///////////////////////////////////////////////////////////////////////////////
const colorAssigner = new ConvergenceColorAssigner.ColorAssigner();
let localSelectionReference;
function initSharedSelection(rts) {
// Create a local reference that will be used to send the local
// users selection and cursor.
localSelectionReference = rts.rangeReference("selection");
// Set and share the local selection.
sendLocalSelection();
localSelectionReference.share();
// Get all existing "selection" references from the RealTimeString
// and create remote selection cue for each.
const references = rts.references({key: "selection"});
references.forEach((reference) => {
if (!reference.isLocal()) {
addRemoteSelection(reference);
}
});
// Listen to the "reference" event which will be fired
// when a new remote user shares their selection.
rts.on("reference", (e) => {
if (e.reference.key() === "selection") {
addRemoteSelection(e.reference);
}
});
}
function sendLocalSelection() {
const selection = textEditor.selectionManager().getSelection();
localSelectionReference.set({start: selection.anchor, end: selection.target});
}
function addRemoteSelection(reference) {
const color = colorAssigner.getColorAsHex(reference.sessionId());
const remoteRange = reference.value();
// Gets the text editors SelectionManager.
const selectionManager = textEditor.selectionManager();
// Add a new collaborator to the text editor.
selectionManager.addCollaborator(
reference.sessionId(),
reference.user().displayName,
color,
{anchor: remoteRange.start, target: remoteRange.end});
// Monitor the events from the remote reference and update the
// remote users selection in the SelectionManager.
reference.on("cleared", () => selectionManager.removeCollaborator(reference.sessionId()) );
reference.on("disposed", () => selectionManager.removeCollaborator(reference.sessionId()) );
reference.on("set", (e) => {
const selection = reference.value();
const collaborator = selectionManager.getCollaborator(reference.sessionId());
collaborator.setSelection({anchor: selection.start, target: selection.end});
if (!e.synthetic) {
collaborator.flashCursorToolTip(2);
}
});
}