commit f53680008a8bf6c68aeaf6d6345f8fc894c065ec
parent 7ae260318028a0fc36318e62fe4e5e2538ab53fd
Author: AsherMorgan <59518073+AsherMorgan@users.noreply.github.com>
Date: Sun, 1 Nov 2020 14:07:06 -0800
Fix broken keyboard shortcuts (resolves #20).
Diffstat:
2 files changed, 60 insertions(+), 34 deletions(-)
diff --git a/js/quizzer.js b/js/quizzer.js
@@ -47,7 +47,7 @@ let quizzer = Vue.component("quizzer", {
// Update prompts
this.prompts = this.startingPrompts;
this.index = this.startingIndex - 1;
-
+
// Reset quizzer
this.Reset();
}
@@ -56,10 +56,27 @@ let quizzer = Vue.component("quizzer", {
methods: {
/**
+ * Handles keyup events and implements quizzer keyboard shortcuts.
+ */
+ keyup: function(e) {
+ // Check if Quizzer is active
+ if (!this.active) {
+ return;
+ }
+
+ if (e.keyCode === 13 && e.ctrlKey) {
+ this.Reset();
+ }
+ else if (e.keyCode === 13 && !e.ctrlKey) {
+ this.Enter();
+ }
+ },
+
+ /**
* Give the user the next prompt and reset the quizzer.
*/
Reset: function() {
- // Check is Quizzer is active
+ // Check if Quizzer is active
if (!this.active) {
return;
}
@@ -71,7 +88,7 @@ let quizzer = Vue.component("quizzer", {
this.$refs.input.focus();
}
catch { }
-
+
// Get new prompt
this.index++;
if (this.index === this.prompts.length) {
@@ -95,7 +112,7 @@ let quizzer = Vue.component("quizzer", {
if (this.settings.inputType !== "Text") {
// Create recognition object
var recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.msSpeechRecognition)();
-
+
// Set language
if (this.prompt[2].toLowerCase().includes("english")) {
recognition.lang = 'en-US';
@@ -127,7 +144,7 @@ let quizzer = Vue.component("quizzer", {
* Process the user's responce.
*/
Submit: function() {
- // Check is Quizzer is active
+ // Check if Quizzer is active
if (!this.active) {
return;
}
@@ -185,11 +202,11 @@ let quizzer = Vue.component("quizzer", {
* Process an incorrect responce and then reset the quizzer.
*/
Continue: function() {
- // Check is Quizzer is active
+ // Check if Quizzer is active
if (!this.active) {
return;
}
-
+
// Repeat prompt
switch (this.settings.repeatPrompts)
{
@@ -219,16 +236,16 @@ let quizzer = Vue.component("quizzer", {
// Reset quizzer
this.Reset();
},
-
+
/**
* Calls Submit or Continue depending on the value of responceActive.
*/
Enter: function() {
- // Check is Quizzer is active
+ // Check if Quizzer is active
if (!this.active) {
return;
}
-
+
if (this.responceActive) {
this.Submit();
}
@@ -252,32 +269,41 @@ let quizzer = Vue.component("quizzer", {
}
}
},
-
+
+ created: function() {
+ // Add keyup handler
+ window.addEventListener("keyup", this.keyup);
+ },
+
+ destroyed: function() {
+ // Remove keyup handler
+ window.removeEventListener("keyup", this.keyup);
+ },
+
template: `
<div>
<p id="quizzerProgress">{{ index }} / {{ prompts.length }}</p>
-
+
<section>
<label id="quizzerPromptType" for="quizzerPrompt">{{ prompt[0] }}</label>
<span id="quizzerPrompt" :lang="getLang(prompt[0])" @click="Read(prompt[1], prompt[0]);">{{ settings.promptType === "Audio" ? "Click to hear again" : prompt[1] }}</span>
</section>
-
+
<section>
<label id="quizzerInputType" for="quizzerInput">{{ prompt[2] }}</label>
<input id="quizzerInput" ref="input" type="text" v-model="responce" :readonly="!responceActive || settings.inputType === 'Voice'"
- @keyup.ctrl.enter.exact="Reset();" @keyup.enter.exact="Enter();" :lang="getLang(prompt[2])"
- autocomplete="off" spellcheck="false" autocorrect="off" placeholder="Type the answer">
+ :lang="getLang(prompt[2])" autocomplete="off" spellcheck="false" autocorrect="off" placeholder="Type the answer">
</section>
-
+
<div id="quizzerButtons">
<button v-if="responceActive" :disabled="settings.inputType === 'Voice'" @click="Submit();">Submit</button>
<button v-else @click="Continue();">Continue</button>
<button @click="Reset();">Skip</button>
</div>
-
+
<div id="quizzerFeedback" ref="feedback" v-show="!responceActive" class="bad">
<span v-if="settings.onMissedPrompt === 'Correct me'">
- The correct answer is
+ The correct answer is
<span id="quizzerFeedbackTerm" @click="Read(prompt[3], prompt[2]);">{{ prompt[3].toLowerCase() }}</span>.
</span>
<span v-if="settings.onMissedPrompt === 'Tell me'">
diff --git a/js/settings.js b/js/settings.js
@@ -94,7 +94,7 @@ let settings = Vue.component("settings", {
getTenseSubjects: function(index) {
// Set default filters
let filters = {"All Subjects":true, "Yo":true, "Tú":true, "Él":true, "Nosotros":true, "Ellos":true}
-
+
if (this.verbFilters[index].tense === "Present Participles") {
// Override filters
filters["Yo"] = false;
@@ -102,7 +102,7 @@ let settings = Vue.component("settings", {
filters["Él"] = false;
filters["Nosotros"] = false;
filters["Ellos"] = false;
-
+
// Reset subject
this.verbFilters[index].subject = "All Subjects";
}
@@ -126,7 +126,7 @@ let settings = Vue.component("settings", {
filters["Nouns"] = false;
filters["Verbs"] = false;
break;
-
+
case "Adjectives":
filters["Nouns"] = false;
filters["Verbs"] = false;
@@ -145,18 +145,18 @@ let settings = Vue.component("settings", {
filters["Nouns"] = false;
filters["Verbs"] = false;
break;
-
+
case "Colors":
filters["Nouns"] = false;
filters["Verbs"] = false;
break;
-
+
case "Days":
case "Months":
filters["Adjectives"] = false;
filters["Verbs"] = false;
break;
-
+
case "Weather":
case "Professions":
filters["Adjectives"] = false;
@@ -166,7 +166,7 @@ let settings = Vue.component("settings", {
case "Clothes":
filters["Verbs"] = false;
break;
-
+
case "Nature":
case "House":
case "Vacation":
@@ -215,7 +215,7 @@ let settings = Vue.component("settings", {
alert("Your custom vocabulary set must contain at least one term.");
return;
}
-
+
// Start quizzer
this.$emit("start-session", prompts, promptIndex, this.settings);
},
@@ -309,7 +309,7 @@ let settings = Vue.component("settings", {
}
catch { return; }
if (!parsedSettings) { return; }
-
+
// Load settings
if (parsedSettings.promptType && ["Text", "Audio", "Both"].includes(parsedSettings.promptType)) {
this.settings.promptType = parsedSettings.promptType;
@@ -327,9 +327,9 @@ let settings = Vue.component("settings", {
destroyed: function() {
// Remove keyup handler
- window.removeEventListener("keydown", this.keyup);
+ window.removeEventListener("keyup", this.keyup);
},
-
+
template: `
<div class="settings" ref="container">
<div class="verbSettings" v-show="category === 'verbs'">
@@ -339,7 +339,7 @@ let settings = Vue.component("settings", {
Verb Filters
<button @click="AddFilter();">Add Filter</button>
</h2>
-
+
<div v-for="(filter, index) in verbFilters" class="filter">
<select v-model="filter.tense">
<option>All Tenses</option>
@@ -539,7 +539,7 @@ function ApplyVerbFilter(terms, filterInfo) {
filters.push({ tense: filter.tense.toLowerCase(), type: filter.type, subject: filter.subject, direction: filter.direction });
}
}
-
+
// Expand "All Subjects" filters
for (let filter of filters) {
if (filter.subject.toLowerCase() === "all subjects" && filter.tense !== "present participles") {
@@ -691,7 +691,7 @@ function ApplyVerbFilter(terms, filterInfo) {
throw `Unrecognized subject: ${filter.subject}.`;
}
break;
-
+
default:
throw `Unrecognized tense: ${filter.tense}.`;
}
@@ -731,13 +731,13 @@ function Shuffle(items) {
var currentIndex = items.length;
var temp;
var randomIndex;
-
+
// While there are more elements to shuffle
while (0 !== currentIndex) {
// Pick a remaining element
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
-
+
// Swap the two elements
temp = items[currentIndex];
items[currentIndex] = items[randomIndex];