Setup basic logging system to gather usage events serverside for debugging
and hopefully difficulty analysis later on. Initially always enabled while
in private testing.
// show an open card
this.turned.push(target);
put(target, '.turn');
// show an open card
this.turned.push(target);
put(target, '.turn');
+ this.log('pick', target.id, target.index);
}
else if (this.turned.length < 2) {
return; // keep open
}
else if (this.turned.length < 2) {
return; // keep open
this.turned = [];
if (Array.from(this.form.children).every(card => card.classList.contains('good'))) {
put(this.form, '.good');
this.turned = [];
if (Array.from(this.form.children).every(card => card.classList.contains('good'))) {
put(this.form, '.good');
.map(e => e.toString())
}
.map(e => e.toString())
}
- cards.shuffle().forEach(word => {
+ cards.shuffle().forEach((word, seq) => {
let ref = Math.abs(word);
put(this.form,
let ref = Math.abs(word);
put(this.form,
- 'figure>img[src=$]<', `/data/word/32/${ref}.jpg`,
- {onclick: e => this.turn(e), id: ref, className: word < 0 ? 'mirror' : ''}
+ 'figure>img[src=$]<', `/data/word/32/${ref}.jpg`, {
+ onclick: e => this.turn(e),
+ id: ref,
+ className: word < 0 ? 'mirror' : '',
+ index: seq,
+ }
let answers = [word[0], this.words[0][0], this.words[1][0], this.words[2][0]]
.shuffle()
let answers = [word[0], this.words[0][0], this.words[1][0], this.words[2][0]]
.shuffle()
+ this.log('ask', word[2], answers);
answers.forEach(suggest => {
let label = suggest.replace(/\/.*/, '');
let option = put(form, 'li', label, {onclick: () => {
answers.forEach(suggest => {
let label = suggest.replace(/\/.*/, '');
let option = put(form, 'li', label, {onclick: () => {
+ this.log('pick', suggest, null, word[0]);
if (suggest != word[0]) {
// incorrect
put(option, '.wrong');
if (suggest != word[0]) {
// incorrect
put(option, '.wrong');
+ log(...args) {
+ this.history.push([new Date().toISOString(), ...args]);
+ }
+
+ stop(...args) {
+ this.log(...args);
+ window.onbeforeunload = null;
+ fetch('/word/report', {method: 'POST', body: JSON.stringify(this.history)});
+ }
+
constructor(dataurl) {
this.load(dataurl);
constructor(dataurl) {
this.load(dataurl);
+ this.history = [];
+ window.onbeforeunload = e => {
+ this.stop('abort');
+ };
--- /dev/null
+<:
+my $db = eval {
+ require Shiar_Sheet::DB;
+ Shiar_Sheet::DB->connect;
+} or Abort('Database error', 501, $@);
+
+$db->insert(report => {
+ agent => $ENV{HTTP_USER_AGENT},
+ page => $ENV{HTTP_REFERER},
+ address => $ENV{REMOTE_ADDR},
+ history => $PLP::read->($ENV{CONTENT_LENGTH}),
+});
this.form.querySelectorAll('li[onclick]').forEach(answer => {
answer.removeAttribute('onclick');
});
this.form.querySelectorAll('li[onclick]').forEach(answer => {
answer.removeAttribute('onclick');
});
console.log(this.question, answer);
let match = this.question.dataset.id == answer.dataset.id;
put(answer, match ? '.good' : '.wrong');
console.log(this.question, answer);
let match = this.question.dataset.id == answer.dataset.id;
put(answer, match ? '.good' : '.wrong');
+ this.log('pick', answer.dataset.id, answer.index, this.question.dataset.id);
let answers = put(this.form, 'ul');
this.words
let answers = put(this.form, 'ul');
this.words
+ .forEach((answer, seq) => {
let label = answer[0].replace(/\/.*/, ''); // primary form
put(answers, 'li[data-id=$][onclick=""]',
let label = answer[0].replace(/\/.*/, ''); // primary form
put(answers, 'li[data-id=$][onclick=""]',
- answer[2], label, {onclick: e => this.verify(e)}
+ answer[2], label, {
+ onclick: e => this.verify(e),
+ index: seq,
+ }
)
});
this.words.shuffle();
)
});
this.words.shuffle();