Synchronized Editor: Store all events and allow multiple tabs
* This commit refactors the table used to store events. * We also use a UUID as session identifier in the synchronized editor to support multiple concurrent tabs opened by the same user. * Further, we renamed some methods to make them easier to distinguish.
This commit is contained in:

committed by
Sebastian Serth

parent
c42fb8fc09
commit
5dd6df9418
@@ -1,12 +1,26 @@
|
||||
$(document).on('turbolinks:load', function () {
|
||||
|
||||
if (window.location.pathname.includes('/implement')) {
|
||||
function generateUUID() {
|
||||
// We decided to use this function instead of crypto.randomUUID() because it also supports older browser versions
|
||||
// https://caniuse.com/?search=createObjectURL
|
||||
return URL.createObjectURL(new Blob()).slice(-36)
|
||||
}
|
||||
|
||||
function is_other_user(user) {
|
||||
return !_.isEqual(current_user, user);
|
||||
}
|
||||
|
||||
function is_other_session(other_session_id) {
|
||||
return session_id !== other_session_id;
|
||||
}
|
||||
|
||||
const editor = $('#editor');
|
||||
const exercise_id = editor.data('exercise-id');
|
||||
const current_user_id = editor.data('user-id');
|
||||
const current_contributor_id = editor.data('contributor-id');
|
||||
const session_id = generateUUID();
|
||||
|
||||
if ($.isController('exercises') && current_user_id !== current_contributor_id) {
|
||||
if ($.isController('exercises') && current_user.id !== current_contributor_id) {
|
||||
|
||||
App.synchronized_editor = App.cable.subscriptions.create({
|
||||
channel: "SynchronizedEditorChannel", exercise_id: exercise_id
|
||||
@@ -23,25 +37,29 @@ $(document).on('turbolinks:load', function () {
|
||||
|
||||
received(data) {
|
||||
// Called when there's incoming data on the websocket for this channel
|
||||
if (current_user_id !== data.current_user_id) {
|
||||
switch(data.command) {
|
||||
case 'editor_change':
|
||||
CodeOceanEditor.applyChanges(data.delta.data, data.active_file);
|
||||
break;
|
||||
case 'connection_change':
|
||||
CodeOceanEditor.showPartnersConnectionStatus(data.status, data.current_user_name);
|
||||
this.perform('send_hello');
|
||||
break;
|
||||
case 'hello':
|
||||
CodeOceanEditor.showPartnersConnectionStatus(data.status, data.current_user_name);
|
||||
break;
|
||||
}
|
||||
switch (data.action) {
|
||||
case 'editor_change':
|
||||
if (is_other_session(data.session_id)) {
|
||||
CodeOceanEditor.applyChanges(data.delta, data.active_file);
|
||||
}
|
||||
break;
|
||||
case 'connection_change':
|
||||
if (is_other_user(data.user)) {
|
||||
CodeOceanEditor.showPartnersConnectionStatus(data.status, data.user.displayname);
|
||||
this.perform('connection_status');
|
||||
}
|
||||
break;
|
||||
case 'connection_status':
|
||||
if (is_other_user(data.user)) {
|
||||
CodeOceanEditor.showPartnersConnectionStatus(data.status, data.user.displayname);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
send_changes(delta, active_file) {
|
||||
const delta_with_user_id = {command: 'editor_change', current_user_id: current_user_id, active_file: active_file, delta: delta}
|
||||
this.perform('send_changes', {delta_with_user_id: delta_with_user_id});
|
||||
editor_change(delta, active_file) {
|
||||
const message = {session_id: session_id, active_file: active_file, delta: delta.data}
|
||||
this.perform('editor_change', message);
|
||||
},
|
||||
|
||||
is_connected() {
|
||||
|
@@ -339,7 +339,7 @@ var CodeOceanEditor = {
|
||||
CodeOceanEditor.lastDeltaObject = null;
|
||||
return;
|
||||
}
|
||||
App.synchronized_editor?.send_changes(deltaObject, this.active_file);
|
||||
App.synchronized_editor?.editor_change(deltaObject, this.active_file);
|
||||
|
||||
// TODO: This is a workaround for a bug in Ace. Remove when upgrading Ace.
|
||||
this.handleUTF16Surrogates(deltaObject, session);
|
||||
|
Reference in New Issue
Block a user