Forward person when a programming group is created with them
Further, we remove the "check invitation" button and extract some methods to our new ProgrammingGroups object in JavaScript. Co-authored-by: Sebastian Serth <Sebastian.Serth@hpi.de>
This commit is contained in:
30
app/assets/javascripts/channels/pg_matching_channel.js
Normal file
30
app/assets/javascripts/channels/pg_matching_channel.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
$(document).on('turbolinks:load', function () {
|
||||||
|
|
||||||
|
if ($.isController('programming_groups') && window.location.pathname.includes('programming_groups/new')) {
|
||||||
|
const matching_page = $('#matching');
|
||||||
|
const exercise_id = matching_page.data('exercise-id');
|
||||||
|
|
||||||
|
App.pg_matching = App.cable.subscriptions.create({
|
||||||
|
channel: "PgMatchingChannel", exercise_id: exercise_id
|
||||||
|
}, {
|
||||||
|
connected() {
|
||||||
|
// Called when the subscription is ready for use on the server
|
||||||
|
},
|
||||||
|
|
||||||
|
disconnected() {
|
||||||
|
// Called when the subscription has been terminated by the server
|
||||||
|
},
|
||||||
|
|
||||||
|
received(data) {
|
||||||
|
// Called when there's incoming data on the websocket for this channel
|
||||||
|
switch (data.action) {
|
||||||
|
case 'invited':
|
||||||
|
if (!ProgrammingGroups.is_other_user(data.user)) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -1,25 +1,14 @@
|
|||||||
$(document).on('turbolinks:load', function () {
|
$(document).on('turbolinks:load', function () {
|
||||||
|
|
||||||
if (window.location.pathname.includes('/implement')) {
|
if (window.location.pathname.includes('/implement')) {
|
||||||
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 editor = $('#editor');
|
||||||
const exercise_id = editor.data('exercise-id');
|
const exercise_id = editor.data('exercise-id');
|
||||||
let session_id;
|
|
||||||
|
|
||||||
if ($.isController('exercises') && is_other_user(current_contributor)) {
|
if ($.isController('exercises') && ProgrammingGroups.is_other_user(current_contributor)) {
|
||||||
|
|
||||||
App.synchronized_editor = App.cable.subscriptions.create({
|
App.synchronized_editor = App.cable.subscriptions.create({
|
||||||
channel: "SynchronizedEditorChannel", exercise_id: exercise_id
|
channel: "SynchronizedEditorChannel", exercise_id: exercise_id
|
||||||
}, {
|
}, {
|
||||||
|
|
||||||
|
|
||||||
connected() {
|
connected() {
|
||||||
// Called when the subscription is ready for use on the server
|
// Called when the subscription is ready for use on the server
|
||||||
},
|
},
|
||||||
@ -33,19 +22,19 @@ $(document).on('turbolinks:load', function () {
|
|||||||
// Called when there's incoming data on the websocket for this channel
|
// Called when there's incoming data on the websocket for this channel
|
||||||
switch (data.action) {
|
switch (data.action) {
|
||||||
case 'session_id':
|
case 'session_id':
|
||||||
session_id = data.session_id;
|
ProgrammingGroups.session_id = data.session_id;
|
||||||
break;
|
break;
|
||||||
case 'editor_change':
|
case 'editor_change':
|
||||||
if (is_other_session(data.session_id)) {
|
if (ProgrammingGroups.is_other_session(data.session_id)) {
|
||||||
CodeOceanEditor.applyChanges(data.delta, data.active_file);
|
CodeOceanEditor.applyChanges(data.delta, data.active_file);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'connection_change':
|
case 'connection_change':
|
||||||
if (is_other_session(data.session_id) && data.status === 'connected') {
|
if (ProgrammingGroups.is_other_session(data.session_id) && data.status === 'connected') {
|
||||||
const message = {files: CodeOceanEditor.collectFiles(), session_id: session_id};
|
const message = {files: CodeOceanEditor.collectFiles(), session_id: ProgrammingGroups.session_id};
|
||||||
this.perform('current_content', message);
|
this.perform('current_content', message);
|
||||||
}
|
}
|
||||||
if (is_other_user(data.user)) {
|
if (ProgrammingGroups.is_other_user(data.user)) {
|
||||||
CodeOceanEditor.showPartnersConnectionStatus(data.status, data.user.displayname);
|
CodeOceanEditor.showPartnersConnectionStatus(data.status, data.user.displayname);
|
||||||
this.perform('connection_status');
|
this.perform('connection_status');
|
||||||
}
|
}
|
||||||
@ -58,13 +47,13 @@ $(document).on('turbolinks:load', function () {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'connection_status':
|
case 'connection_status':
|
||||||
if (is_other_user(data.user)) {
|
if (ProgrammingGroups.is_other_user(data.user)) {
|
||||||
CodeOceanEditor.showPartnersConnectionStatus(data.status, data.user.displayname);
|
CodeOceanEditor.showPartnersConnectionStatus(data.status, data.user.displayname);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'current_content':
|
case 'current_content':
|
||||||
case 'reset_content':
|
case 'reset_content':
|
||||||
if (is_other_session(data.session_id)) {
|
if (ProgrammingGroups.is_other_session(data.session_id)) {
|
||||||
CodeOceanEditor.setEditorContent(data);
|
CodeOceanEditor.setEditorContent(data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -76,7 +65,7 @@ $(document).on('turbolinks:load', function () {
|
|||||||
},
|
},
|
||||||
|
|
||||||
editor_change(delta, active_file) {
|
editor_change(delta, active_file) {
|
||||||
const message = {session_id: session_id, active_file: active_file, delta: delta}
|
const message = {session_id: ProgrammingGroups.session_id, active_file: active_file, delta: delta}
|
||||||
this.perform('editor_change', message);
|
this.perform('editor_change', message);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
var ProgrammingGroups = {
|
const ProgrammingGroups = {
|
||||||
|
session_id: null,
|
||||||
|
|
||||||
getStoredViewedPPInfo: function () {
|
getStoredViewedPPInfo: function () {
|
||||||
return localStorage.getItem('viewed_pp_info')
|
return localStorage.getItem('viewed_pp_info')
|
||||||
},
|
},
|
||||||
@ -7,10 +9,17 @@ var ProgrammingGroups = {
|
|||||||
localStorage.setItem('viewed_pp_info', 'true')
|
localStorage.setItem('viewed_pp_info', 'true')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
initializeEventHandler: function () {
|
initializeEventHandler: function () {
|
||||||
$('#dont_show_info_pp_modal_again').on('click', this.setStoredViewedPPInfo.bind(this));
|
$('#dont_show_info_pp_modal_again').on('click', this.setStoredViewedPPInfo.bind(this));
|
||||||
}
|
},
|
||||||
|
|
||||||
|
is_other_user: function (user) {
|
||||||
|
return !_.isEqual(current_user, user);
|
||||||
|
},
|
||||||
|
|
||||||
|
is_other_session: function (other_session_id) {
|
||||||
|
return this.session_id !== other_session_id;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).on('turbolinks:load', function () {
|
$(document).on('turbolinks:load', function () {
|
||||||
|
24
app/channels/pg_matching_channel.rb
Normal file
24
app/channels/pg_matching_channel.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class PgMatchingChannel < ApplicationCable::Channel
|
||||||
|
def subscribed
|
||||||
|
set_and_authorize_exercise
|
||||||
|
stream_from specific_channel
|
||||||
|
end
|
||||||
|
|
||||||
|
def unsubscribed
|
||||||
|
# Any cleanup needed when channel is unsubscribed
|
||||||
|
stop_all_streams
|
||||||
|
end
|
||||||
|
|
||||||
|
def specific_channel
|
||||||
|
"pg_matching_channel_exercise_#{@exercise.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_and_authorize_exercise
|
||||||
|
@exercise = Exercise.find(params[:exercise_id])
|
||||||
|
reject unless ExercisePolicy.new(current_user, @exercise).implement?
|
||||||
|
end
|
||||||
|
end
|
@ -42,7 +42,21 @@ class ProgrammingGroupsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
create_and_respond(object: @programming_group, path: proc { implement_exercise_path(@exercise) }) do
|
create_and_respond(object: @programming_group, path: proc { implement_exercise_path(@exercise) }) do
|
||||||
|
# Inform all other users in the programming group that they have been invited.
|
||||||
|
@programming_group.users.each do |user|
|
||||||
|
next if user == current_user
|
||||||
|
|
||||||
|
message = {
|
||||||
|
action: 'invited',
|
||||||
|
user: user.to_page_context,
|
||||||
|
}
|
||||||
|
ActionCable.server.broadcast("pg_matching_channel_exercise_#{@exercise.id}", message)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Just set the programming group id in the session for the creator of the group, so that the user can be redirected.
|
||||||
session[:pg_id] = @programming_group.id
|
session[:pg_id] = @programming_group.id
|
||||||
|
|
||||||
|
# Don't return a specific value from this block, so that the default is used.
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -6,4 +6,3 @@
|
|||||||
/.help-block.form-text = t('.hints.programming_partner_ids')
|
/.help-block.form-text = t('.hints.programming_partner_ids')
|
||||||
.actions.mb-0
|
.actions.mb-0
|
||||||
= render('shared/submit_button', f: f, object: @programming_group)
|
= render('shared/submit_button', f: f, object: @programming_group)
|
||||||
a.btn.btn-secondary.float-end href=new_exercise_programming_group_path(@exercise) == t('programming_groups.new.check_invitation')
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
h1 = t('programming_groups.new.create_programming_pair')
|
h1 = t('programming_groups.new.create_programming_pair')
|
||||||
.row
|
#matching.row data-exercise-id=@exercise.id
|
||||||
.col-md-6
|
.col-md-6
|
||||||
p
|
p
|
||||||
=> t('programming_groups.new.own_user_id')
|
=> t('programming_groups.new.own_user_id')
|
||||||
|
@ -597,7 +597,6 @@ de:
|
|||||||
new:
|
new:
|
||||||
close: Schließen
|
close: Schließen
|
||||||
create_programming_pair: Programmierpaar erstellen
|
create_programming_pair: Programmierpaar erstellen
|
||||||
check_invitation: "Einladung prüfen"
|
|
||||||
dont_show_modal_again: "Auf diesem Gerät nicht mehr anzeigen"
|
dont_show_modal_again: "Auf diesem Gerät nicht mehr anzeigen"
|
||||||
enter_partner_id: "Bitte gib hier die Nutzer-ID der Person ein, mit der du zusammen die Aufgabe '%{exercise_title}' lösen möchtest. Beachte jedoch, dass anschließend keiner die Zusammenarbeit beenden kann. Dein:e Teampartner:in kann sehen, was du in dieser Aufgabe schreibst und umgekehrt. Für die nächste Aufgabe kannst du dich erneuert entscheiden, ob und mit wem du zusammen arbeiten möchtest."
|
enter_partner_id: "Bitte gib hier die Nutzer-ID der Person ein, mit der du zusammen die Aufgabe '%{exercise_title}' lösen möchtest. Beachte jedoch, dass anschließend keiner die Zusammenarbeit beenden kann. Dein:e Teampartner:in kann sehen, was du in dieser Aufgabe schreibst und umgekehrt. Für die nächste Aufgabe kannst du dich erneuert entscheiden, ob und mit wem du zusammen arbeiten möchtest."
|
||||||
find_partner_title: "Finde eine:n Programmierpartner:in für die Aufgabe"
|
find_partner_title: "Finde eine:n Programmierpartner:in für die Aufgabe"
|
||||||
|
@ -597,7 +597,6 @@ en:
|
|||||||
new:
|
new:
|
||||||
close: Close
|
close: Close
|
||||||
create_programming_pair: Create Programming Pair
|
create_programming_pair: Create Programming Pair
|
||||||
check_invitation: "Check invitation"
|
|
||||||
dont_show_modal_again: "Don't display on this device anymore"
|
dont_show_modal_again: "Don't display on this device anymore"
|
||||||
enter_partner_id: "Please enter the user ID from the practice partner with whom you want to solve the exercise '%{exercise_title}'. However, note that no one can leave the pair afterward. Hence, your team partner can see what you write in this exercise and vice versa. For the next exercise, you can decide again whether and with whom you want to work together."
|
enter_partner_id: "Please enter the user ID from the practice partner with whom you want to solve the exercise '%{exercise_title}'. However, note that no one can leave the pair afterward. Hence, your team partner can see what you write in this exercise and vice versa. For the next exercise, you can decide again whether and with whom you want to work together."
|
||||||
find_partner_title: "Find a programming partner for the exercise"
|
find_partner_title: "Find a programming partner for the exercise"
|
||||||
|
Reference in New Issue
Block a user