commit 912507f5a8177fee5f925f8dca32ebb4c79e3ec7
parent 4fee5a0b49db290a36d1c2d63baa1874ad1007e3
Author: AsherMorgan <59518073+AsherMorgan@users.noreply.github.com>
Date: Sat, 20 Mar 2021 16:14:17 -0700
Add conjugationColors setting
Diffstat:
7 files changed, 219 insertions(+), 27 deletions(-)
diff --git a/css/reference.css b/css/reference.css
@@ -44,6 +44,32 @@
cursor: pointer;
}
+/* Cell colors */
+.referenceTable td.normal {
+ color: inherit;
+}
+.referenceTable td.irregular {
+ color: hsl(0, 100%, 45%);
+}
+.referenceTable td.nonregular {
+ color: hsl(40, 100%, 45%);
+}
+.referenceTable td.regular {
+ color: hsl(120, 100%, 25%);
+}
+.dark .referenceTable td.normal {
+ color: inherit;
+}
+.dark .referenceTable td.irregular {
+ color: hsl(0, 100%, 55%);
+}
+.dark .referenceTable td.nonregular {
+ color: hsl(40, 100%, 55%);
+}
+.dark .referenceTable td.regular {
+ color: hsl(120, 100%, 35%);
+}
+
/* Print styles */
@media print {
body, body.dark {
@@ -61,4 +87,7 @@
table {
border-collapse: collapse;
}
+ .referenceTable td {
+ color: #000000 !important;
+ }
}
diff --git a/js/global.js b/js/global.js
@@ -27,13 +27,16 @@ function getSettings() {
// Initialize settings
let settings = {
darkTheme: false,
+ conjugationColors: true,
+
promptType: "Text",
inputType: "Text",
+ multiplePrompts: "Show together",
+ removeDuplicates: false,
+
onMissedPrompt: "Correct me",
repeatPrompts: "Never",
- multiplePrompts: "Show together",
multipleAnswers: "Require all",
- removeDuplicates: false,
};
// Parse settings
@@ -54,27 +57,32 @@ function getSettings() {
}
catch { }
}
+ if ([true, false].includes(parsedSettings.conjugationColors)) {
+ settings.conjugationColors = parsedSettings.conjugationColors;
+ }
+
if (["Text", "Audio", "Both"].includes(parsedSettings.promptType)) {
settings.promptType = parsedSettings.promptType;
}
if (["Text", "Voice", "Either"].includes(parsedSettings.inputType)) {
settings.inputType = parsedSettings.inputType;
}
+ if (["Show together", "Show separately", "Show one"].includes(parsedSettings.multiplePrompts)) {
+ settings.multiplePrompts = parsedSettings.multiplePrompts;
+ }
+ if ([true, false].includes(parsedSettings.removeDuplicates)) {
+ settings.removeDuplicates = parsedSettings.removeDuplicates;
+ }
+
if (["Correct me", "Tell me", "Ignore it"].includes(parsedSettings.onMissedPrompt)) {
settings.onMissedPrompt = parsedSettings.onMissedPrompt;
}
if (["Never", "Immediately", "5 prompts later", "5 & 10 prompts later", "At the end"].includes(parsedSettings.repeatPrompts)) {
settings.repeatPrompts = parsedSettings.repeatPrompts;
}
- if (["Show together", "Show separately", "Show one"].includes(parsedSettings.multiplePrompts)) {
- settings.multiplePrompts = parsedSettings.multiplePrompts;
- }
if (["Require all", "Require any"].includes(parsedSettings.multipleAnswers)) {
settings.multipleAnswers = parsedSettings.multipleAnswers;
}
- if ([true, false].includes(parsedSettings.removeDuplicates)) {
- settings.removeDuplicates = parsedSettings.removeDuplicates;
- }
// Return parsed settings
return settings;
diff --git a/js/reference.js b/js/reference.js
@@ -9,10 +9,55 @@ const referenceTables = Vue.component("referenceTables", {
data: function() {
return {
category: "Choose a category",
- tableData: {...{"Choose a category":[]}, ...this.data},
query: "",
+ conjugationColors: true,
}
},
+ computed: {
+ /**
+ * The color classes for verb conjugation cells
+ */
+ conjugationColorClasses: function() {
+ let result = [];
+ for (let row in this.tableData.verbs) {
+ result.push([]);
+ for (let column = 0; column < this.tableData.verbs[row].length; column++) {
+ // Check if cell is a type cell
+ if (!this.tableData.verbs[0][column].includes("Type")) {
+ if (column > 0) {
+ // Cell isn't a type cell, use color class of previous cell
+ result[row].push(result[row][column-1]);
+ }
+ else {
+ // Cell is in the first column
+ result[row].push("normal");
+ }
+ }
+
+ // Get color class
+ else if (this.tableData.verbs[row][column].includes("Irregular")) {
+ result[row].push("irregular");
+ }
+ else if (this.tableData.verbs[row][column].includes("Regular")) {
+ result[row].push("regular");
+ }
+ else if (this.tableData.verbs[row][column].includes("Stem Changing") || this.tableData.verbs[row][column].includes("Orthographic")) {
+ result[row].push("nonregular");
+ }
+ else {
+ result[row].push("normal");
+ }
+ }
+ }
+ return result;
+ },
+ /**
+ * The data used by the table
+ */
+ tableData: function() {
+ return {...{"Choose a category":[]}, ...this.data};
+ },
+ },
methods: {
/**
* Set the table height.
@@ -79,6 +124,10 @@ const referenceTables = Vue.component("referenceTables", {
// Remove keyup handler
window.removeEventListener("keyup", this.keyup);
},
+ activated: function() {
+ // Update conjugationColors setting
+ this.conjugationColors = getSettings().conjugationColors;
+ },
template: `
<div>
<div class="referenceTableControls">
@@ -95,7 +144,8 @@ const referenceTables = Vue.component("referenceTables", {
<table>
<tr v-for="(row, rowIndex) in data[category]" v-show="rowIndex === 0 || row.join(',').toLowerCase().includes(query.toLowerCase())">
<th v-if="rowIndex === 0" v-for="column in row">{{ column }}</th>
- <td v-if="rowIndex !== 0" v-for="(column, columnIndex) in row" @click="Read(column, data[category][0][columnIndex])" :lang="getLang(data[category][0][columnIndex])">{{ column }}</td>
+ <td v-if="rowIndex !== 0" v-for="(column, columnIndex) in row" @click="Read(column, data[category][0][columnIndex])"
+ :lang="getLang(data[category][0][columnIndex])" :class="(conjugationColors && category === 'verbs') ? conjugationColorClasses[rowIndex][columnIndex] : 'normal'">{{ column }}</td>
</tr>
</table>
</div>
diff --git a/js/settingsPage.js b/js/settingsPage.js
@@ -31,6 +31,10 @@ const settingsInput = Vue.component("settingsInput", {
<input type="checkbox" id="settingsDarkTheme" v-model="value.darkTheme">
<label for="settingsDarkTheme">Dark Mode</label>
</div>
+ <div>
+ <input type="checkbox" id="settingsConjugationColors" v-model="value.conjugationColors">
+ <label for="settingsConjugationColors">Colored conjugations in reference tables</label>
+ </div>
</div>
<div class="quizzerPromptsSettings">
diff --git a/tests/index.html b/tests/index.html
@@ -21,6 +21,7 @@
<script src="../js/settingsPage.js"></script>
<script src="../js/filters.js"></script>
<script src="../js/quizzer.js"></script>
+ <script src="../js/reference.js"></script>
<!-- Setup tests -->
<script class="mocha-init">
@@ -35,6 +36,7 @@
<script src="test.settingsPage.js"></script>
<script src="test.filters.js"></script>
<script src="test.quizzer.js"></script>
+ <script src="test.reference.js"></script>
<!-- Run tests -->
<script class="mocha-exec">
diff --git a/tests/test.global.js b/tests/test.global.js
@@ -7,13 +7,16 @@ describe("Global.js", function() {
// Set localStorage settings
let expected = {
darkTheme: true,
+ conjugationColors: true,
+
promptType: "Audio",
inputType: "Voice",
+ multiplePrompts: "Show one",
+ removeDuplicates: true,
+
onMissedPrompt: "Tell me",
repeatPrompts: "5 prompts later",
- multiplePrompts: "Show one",
multipleAnswers: "Require any",
- removeDuplicates: true,
};
localStorage.setItem("settings", JSON.stringify(expected));
@@ -58,13 +61,19 @@ describe("Global.js", function() {
let settings = getSettings();
// Assert default settings loaded
- expect(settings.promptType).to.equal("Text");
- expect(settings.inputType).to.equal("Text");
- expect(settings.onMissedPrompt).to.equal("Correct me");
- expect(settings.repeatPrompts).to.equal("Never");
- expect(settings.multiplePrompts).to.equal("Show together");
- expect(settings.multipleAnswers).to.equal("Require all");
- expect(settings.removeDuplicates).to.equal(false);
+ expect(settings).to.deep.equal({
+ darkTheme: false,
+ conjugationColors: true,
+
+ promptType: "Text",
+ inputType: "Text",
+ multiplePrompts: "Show together",
+ removeDuplicates: false,
+
+ onMissedPrompt: "Correct me",
+ repeatPrompts: "Never",
+ multipleAnswers: "Require all",
+ });
// Restore original setting to localStorage
localStorage.setItem("settings", originalValue);
@@ -79,20 +88,23 @@ describe("Global.js", function() {
// Set settings
let settings = {
darkTheme : "A",
- promptType : "B",
- inputType : "C",
- onMissedPrompt : "D",
- repeatPrompts : "E",
- multiplePrompts : "F",
- multipleAnswers : "G",
- removeDuplicates : "H",
+ conjugationColors: "B",
+
+ promptType : "C",
+ inputType : "D",
+ multiplePrompts : "E",
+ removeDuplicates : "F",
+
+ onMissedPrompt : "G",
+ repeatPrompts : "H",
+ multipleAnswers : "I",
}
// Call setSettings
setSettings(settings);
// Assert localStorage setting updated
- expect(localStorage.getItem("settings")).to.equal(`{"darkTheme":"A","promptType":"B","inputType":"C","onMissedPrompt":"D","repeatPrompts":"E","multiplePrompts":"F","multipleAnswers":"G","removeDuplicates":"H"}`);
+ expect(localStorage.getItem("settings")).to.equal(JSON.stringify(settings));
// Restore original setting to localStorage
localStorage.setItem("settings", originalValue);
diff --git a/tests/test.reference.js b/tests/test.reference.js
@@ -0,0 +1,87 @@
+describe("ReferenceTables", function() {
+ let ReferenceTables;
+ beforeEach(function() {
+ // Create referenceTables component
+ ReferenceTables = new referenceTables();
+ });
+
+ describe("Initial state", function() {
+ it("Category should be 'Choose a category'", function() {
+ expect(ReferenceTables.category).to.equal("Choose a category");
+ });
+
+ it("Query should be empty", function() {
+ expect(ReferenceTables.query).to.equal("");
+ });
+
+ it("ConjugationColors should be true", function() {
+ expect(ReferenceTables.conjugationColors).to.be.true;
+ });
+ });
+
+ describe("ConjugationColorClasses property", function() {
+ it("Should produce correct color", function() {
+ // Set reference tables data
+ ReferenceTables.data = {verbs:[
+ // Test table headers
+ ["English", "Infinitive","Present Type","Present Yo","Present Tú","Present Él","Present Nosotros","Present Ellos","Preterite Type","Preterite Yo","Preterite Tú","Preterite Él","Preterite Nosotros","Preterite Ellos"],
+
+ // Test regular conjugations and orthographic conjugations
+ ["To read","Leer","Regular","Leo","Lees","Lee","Leemos","Leen","Orthographic","Leí","Leíste","Leyó","Leímos","Leyeron"],
+
+ // Test stem changing conjugations and irregular conjugations
+ ["To want","Querer","Stem Changing","Quiero","Quieres","Quiere","Queremos","Quieren","Irregular","Quise","Quisiste","Quiso","Quisimos","Quisieron"],
+
+ // Test irregular and stem changing conjugations
+ ["To have","Tener","Irregular, Stem Changing","Tengo","Tienes","Tiene","Tenemos","Tienen","Irregular","Tuve","Tuviste","Tuvo","Tuvimos","Tuvieron"],
+
+ // Test reflexive conjugations
+ ["To go to bed","Acostarse","Reflexive, Stem Changing","Me acuesto","Te acuestas","Se acuesta","Nos acostamos","Se acuestan","Reflexive, Regular","Me acosté","Te acostaste","Se acostó","Nos acostamos","Se acostaron"],
+ ]};
+
+ // Assert conjugationColorClasses is correct
+ expect(ReferenceTables.conjugationColorClasses).to.deep.equal([
+ // Test table headers
+ ["normal","normal","normal","normal","normal","normal","normal","normal","normal","normal","normal","normal","normal","normal"],
+
+ // Test regular conjugations and orthographic conjugations
+ ["normal","normal","regular","regular","regular","regular","regular","regular","nonregular","nonregular","nonregular","nonregular","nonregular","nonregular"],
+
+ // Test stem changing conjugations and irregular conjugations
+ ["normal","normal","nonregular","nonregular","nonregular","nonregular","nonregular","nonregular","irregular","irregular","irregular","irregular","irregular","irregular"],
+
+ // Test irregular and stem changing conjugations
+ ["normal","normal","irregular","irregular","irregular","irregular","irregular","irregular","irregular","irregular","irregular","irregular","irregular","irregular"],
+
+ // Test reflexive conjugations
+ ["normal","normal","nonregular","nonregular","nonregular","nonregular","nonregular","nonregular","regular","regular","regular","regular","regular","regular"],
+ ]);
+ });
+ });
+
+ describe("TableData property", function() {
+ it("Should be calculated correctly", function() {
+ // Set reference tables data
+ let data = {verbs:[
+ // Test table headers
+ ["English", "Infinitive","Present Type","Present Yo","Present Tú","Present Él","Present Nosotros","Present Ellos","Preterite Type","Preterite Yo","Preterite Tú","Preterite Él","Preterite Nosotros","Preterite Ellos"],
+
+ // Test regular conjugations and orthographic conjugations
+ ["To read","Leer","Regular","Leo","Lees","Lee","Leemos","Leen","Orthographic","Leí","Leíste","Leyó","Leímos","Leyeron"],
+
+ // Test stem changing conjugations and irregular conjugations
+ ["To want","Querer","Stem Changing","Quiero","Quieres","Quiere","Queremos","Quieren","Irregular","Quise","Quisiste","Quiso","Quisimos","Quisieron"],
+
+ // Test irregular and stem changing conjugations
+ ["To have","Tener","Irregular, Stem Changing","Tengo","Tienes","Tiene","Tenemos","Tienen","Irregular","Tuve","Tuviste","Tuvo","Tuvimos","Tuvieron"],
+
+ // Test reflexive conjugations
+ ["To go to bed","Acostarse","Reflexive, Stem Changing","Me acuesto","Te acuestas","Se acuesta","Nos acostamos","Se acuestan","Reflexive, Regular","Me acosté","Te acostaste","Se acostó","Nos acostamos","Se acostaron"],
+ ]};
+ ReferenceTables.data = data;
+
+ // Assert tableData is correct
+ expect(ReferenceTables.tableData).to.deep.equal({...{"Choose a category":[]}, ...data});
+ });
+ });
+});