Skip to content

Commit f8e0f31

Browse files
committed
Handle dropouts in interactive experiments
1 parent fadd42c commit f8e0f31

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed

i18n/de.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
"statusYouLeft": "Sie haben den Chat verlassen",
5252
"statusParticipantJoined": "{user} ist dem Chat beigetreten",
5353
"statusParticipantLeft": "{user} hat den Chat verlassen"
54+
},
55+
"general": {
56+
"aborted": "Das Experiment kann leider nicht zu Ende geführt werden, weil eine*r der Teilnehmenden die Sitzung verlassen hat. Sie springen nun zum Ende des Experiments."
5457
}
5558
}
5659
}

i18n/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@
5252
"statusYouLeft": "You left",
5353
"statusParticipantJoined": "{user} joined",
5454
"statusParticipantLeft": "{user} left"
55+
},
56+
"general": {
57+
"aborted": "The experiment cannot be continued, because a collaborator has left the session. Please proceed to result submission."
5558
}
5659
}
5760
}

src/Socket.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,10 @@ export default class Socket extends EventEmitter {
228228

229229
this.roomChannel.on('presence_diff', (diff) => {
230230
Object.keys(diff.joins).forEach((id) => this.participants.push(id));
231-
Object.keys(diff.leaves).forEach((id) =>
232-
this.participants.splice(this.participants.indexOf(id), 1)
233-
);
231+
Object.keys(diff.leaves).forEach((id) => {
232+
this.participants.splice(this.participants.indexOf(id), 1);
233+
this.leaveHandler && this.leaveHandler();
234+
});
234235
});
235236

236237
setInterval(() => {

src/components/Experiment.vue

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,20 @@ export default {
135135
this.$magpie.experiment = this;
136136
window.$magpie = this.$magpie;
137137
138+
if (this.$magpie.socketUrl) {
139+
let previousParticipantCount = 0;
140+
this.$watch('$magpie.socket.participants', (val) => {
141+
if (val.length - previousParticipantCount < 0) {
142+
window.alert(this.$t('interactive.general.aborted'));
143+
const screens = this.$slots.default.filter(
144+
(c) => !!c.componentOptions
145+
);
146+
this.$magpie.nextScreen(screens.length - 1);
147+
}
148+
previousParticipantCount = val.length;
149+
});
150+
}
151+
138152
if (this.title) {
139153
document.title = this.title;
140154
}
@@ -185,6 +199,7 @@ export default {
185199
window.scrollTo(0, window.scrollY + expPos.top);
186200
}
187201
},
202+
188203
/**
189204
* The contents of this slot will be visible during the entire experiment
190205
* @slot title

0 commit comments

Comments
 (0)