if (error.syscall !== 'listen')
throw error;
- let bind = typeof port === 'string'
+ const bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
},
mounted: function() {
$(".modal").modal();
- if (assessment.mode != "secure")
- return;
- window.addEventListener("keydown", e => {
- // Ignore F12 (avoid accidental window resize due to devtools)
- // NOTE: in Chromium at least, fullscreen mode exit with F11 cannot be prevented.
- // Workaround: disable key at higher level. Possible xbindkey config:
- // "false"
- // m:0x10 + c:95
- // Mod2 + F11
- if (e.keyCode == 123)
- e.preventDefault();
- }, false);
+ if (assessment.mode != "open")
+ {
+ window.addEventListener("keydown", e => {
+ // Ignore F12 (avoid accidental window resize due to devtools)
+ // NOTE: in Chromium at least, fullscreen mode exit with F11 cannot be prevented.
+ // Workaround: disable key at higher level. Possible xbindkey config:
+ // "false"
+ // m:0x10 + c:95
+ // Mod2 + F11
+ if (e.keyCode == 123)
+ e.preventDefault();
+ }, false);
+ }
window.addEventListener("blur", () => {
- this.trySendCurrentAnswer();
- document.location.href= "/noblur";
+ if (!socket)
+ return;
+ if (assessment.mode == "secure")
+ {
+ this.trySendCurrentAnswer();
+ document.location.href= "/noblur";
+ }
+ else if (assessment.mode == "exam")
+ socket.emit(message.studentBlur, {number:this.student.number});
}, false);
+ if (assessment.mode == "exam")
+ {
+ window.addEventListener("focus", () => {
+ if (!socket)
+ return;
+ socket.emit(message.studentFocus, {number:this.student.number});
+ }, false);
+ }
window.addEventListener("resize", e => {
- this.trySendCurrentAnswer();
- document.location.href= "/fullscreen";
+ if (!socket)
+ return;
+ if (assessment.mode == "secure")
+ {
+ this.trySendCurrentAnswer();
+ document.location.href= "/fullscreen";
+ }
+ else if (assessment.mode == "exam")
+ {
+ if (checkWindowSize())
+ socket.emit(message.studentFullscreen, {number:this.student.number});
+ else
+ socket.emit(message.studentResize, {number:this.student.number});
+ }
}, false);
},
methods: {
socket = io.connect("/", {
query: "aid=" + this.assessment._id + "&secret=" + s.secret
});
+ socket.on(message.studentBlur, m => {
+ const sIdx = this.students.findIndex( item => { return item.number == m.number; });
+ Vue.set(this.students, sIdx, Object.assign({},this.students[sIdx],{blur: true}));
+ //this.students[sIdx].blur = true;
+ });
+ socket.on(message.studentFocus, m => {
+ const sIdx = this.students.findIndex( item => { return item.number == m.number; });
+ this.students[sIdx].blur = false;
+ });
+ socket.on(message.studentResize, m => {
+ const sIdx = this.students.findIndex( item => { return item.number == m.number; });
+ Vue.set(this.students, sIdx, Object.assign({},this.students[sIdx],{resize: true}));
+ //this.students[sIdx].resize = true;
+ });
+ socket.on(message.studentFullscreen, m => {
+ const sIdx = this.students.findIndex( item => { return item.number == m.number; });
+ this.students[sIdx].resize = false;
+ });
+ socket.on(message.studentDisconnect, m => {
+ const sIdx = this.students.findIndex( item => { return item.number == m.number; });
+ Vue.set(this.students, sIdx, Object.assign({},this.students[sIdx],{disco: true}));
+ //this.students[sIdx].disco = true;
+ });
+ socket.on(message.studentConnect, m => {
+ const sIdx = this.students.findIndex( item => { return item.number == m.number; });
+ this.students[sIdx].disco = false;
+ });
socket.on(message.newAnswer, m => {
let paperIdx = this.assessment.papers.findIndex( item => {
return item.number == m.number;
},
endMonitoring: function() {
// In the end, send answers to students
+ // TODO: disable this button until everyone finished (need ability to mark absents)
socket.emit(
message.allAnswers,
{ answers: JSON.stringify(this.assessment.questions.map( q => { return q.answer; })) }
// Next 2 to monitor students disconnections
studentConnect: "student connect",
studentDisconnect: "student disconnect",
+ // And blur + onResize events (sockets only)
+ studentBlur: "student blur",
+ studentFocus: "student focus",
+ studentResize: "student resize",
+ studentFullscreen: "student fullscreen",
};
-try { module.exports = message; } catch (err) {} //for server
+try { module.exports = message; } catch (err) { } //for server
+.blur {
+ background-color: lightsalmon;
+}
+.resize {
+ font-style: italic;
+ color: darkred;
+}
+.disconnect {
+ background-color: grey;
+}
+
/* TODO: factor this piece of code from assessment (and course, and here...) */
.question {
margin: 20px 5px;
width: auto;
margin: 10px auto;
}
+
table.in-question th, table.in-question td {
- padding: 3px;
+ padding: 7px;
border-bottom: 1px solid grey;
}
+
+/*table { border: none; border-collapse: collapse; }*/
+table.in-question td { border-left: 1px solid grey; }
+table.in-question td:first-child { border-left: none; }
socket.on(message.newAnswer, m => { //got answer from student client
socket.broadcast.to(aid + "_teacher").emit(message.newAnswer, m);
});
+ socket.on(message.studentBlur, m => {
+ socket.broadcast.to(aid + "_teacher").emit(message.studentBlur, m);
+ });
+ socket.on(message.studentFocus, m => {
+ socket.broadcast.to(aid + "_teacher").emit(message.studentFocus, m);
+ });
+ socket.on(message.studentResize, m => {
+ socket.broadcast.to(aid + "_teacher").emit(message.studentResize, m);
+ });
+ socket.on(message.studentFullscreen, m => {
+ socket.broadcast.to(aid + "_teacher").emit(message.studentFullscreen, m);
+ });
socket.on("disconnect", () => { //notify monitor + server
AssessmentEntity.setDiscoTime(ObjectId(aid), number);
socket.broadcast.to(aid + "_teacher").emit(message.studentDisconnect, {number: number});
block content
.container#monitor
.row
- .col.s12.m10.offset-m1.l8.offset-l2.xl6.offset-xl3
+ .col.s12.m10.offset-m1
h4= examName
#stage0(v-show="stage==0")
.card
th(v-for="(q,i) in assessment.questions") Q.{{ (i+1) }}
tbody
tr.assessment(v-for="s in studentList(group)")
- td {{ s.name }}
+ td(:class="{blur:!!s.blur,resize:!!s.resize,disconnect:!!s.disco}") {{ s.name }}
td(v-for="(q,i) in assessment.questions" :style="{backgroundColor: getColor(s.number,i)}" @click="seeDetails(s.number,i)")
h4.title(@click="toggleDisplay('assessment')") Assessment
div(v-show="display=='assessment'")