spanish-quizzer

An app to quiz you on Spanish vocabulary and verb conjugations
git clone https://git.ashermorgan.net/spanish-quizzer/
Log | Files | Refs | README

reference.js (7514B)


      1 // reference-tables component
      2 const referenceTables = Vue.component("referenceTables", {
      3     props: {
      4         data: {
      5             type: Object,
      6             default: {},
      7         }
      8     },
      9     data: function() {
     10         return {
     11             category: "Choose a category",
     12             conjugationColors: true,
     13             tableTheme: null,
     14             table: null,
     15         }
     16     },
     17     watch: {
     18         category: function(value) {
     19             // Update table
     20             this.table.setData({
     21                 headers: this.tableData[value][0],
     22                 body: this.tableData[value].slice(1),
     23                 bodyClasses: value === "verbs" && this.conjugationColors ? this.conjugationColorClasses : null,
     24             });
     25             this.table.sort(0, true);
     26         },
     27         tableTheme: function(value) {
     28             // Update table theme
     29             this.table.theme = value;
     30         },
     31         conjugationColors: function(value) {
     32             // Update table body classes
     33             this.table.setData({
     34                 bodyClasses: this.category === "verbs" && value ? this.conjugationColorClasses : null,
     35             });
     36         }
     37     },
     38     computed: {
     39         /**
     40          * The color classes for verb conjugation cells
     41          */
     42         conjugationColorClasses: function() {
     43             let result = [];
     44             for (let row in this.tableData.verbs) {
     45                 result.push([]);
     46                 for (let column = 0; column < this.tableData.verbs[row].length; column++) {
     47                     // Check if cell is a type cell
     48                     if (!this.tableData.verbs[0][column].includes("Type")) {
     49                         if (column > 0) {
     50                             // Cell isn't a type cell, use color class of previous cell
     51                             result[row].push(result[row][column-1]);
     52                         }
     53                         else {
     54                             // Cell is in the first column
     55                             result[row].push("normal");
     56                         }
     57                     }
     58 
     59                     // Get color class
     60                     else if (this.tableData.verbs[row][column].includes("Irregular")) {
     61                         result[row].push("irregular");
     62                     }
     63                     else if (this.tableData.verbs[row][column].includes("Regular")) {
     64                         result[row].push("regular");
     65                     }
     66                     else if (this.tableData.verbs[row][column].includes("Stem Changing") || this.tableData.verbs[row][column].includes("Orthographic")) {
     67                         result[row].push("nonregular");
     68                     }
     69                     else {
     70                         result[row].push("normal");
     71                     }
     72                 }
     73             }
     74             return result.slice(1);
     75         },
     76         /**
     77          * The data used by the table
     78          */
     79         tableData: function() {
     80             return {...{"Choose a category":[]}, ...this.data};
     81         },
     82     },
     83     methods: {
     84         /**
     85          * Search for a string in the table
     86          * @param {Object} args - The event args (optional)
     87          */
     88         search: function(args) {
     89             if (args) args.target.blur();
     90             this.$refs.search.blur();
     91             this.table.search(this.$refs.search.value);
     92         },
     93 
     94         /**
     95          * Set the table height.
     96          */
     97         setTableHeight: function() {
     98             this.$refs.referenceTable.style.height = `${window.innerHeight - this.$refs.referenceTable.offsetTop - 10}px`;
     99         },
    100 
    101         /**
    102          * Get the language code that matches a label.
    103          * @param {String} label - The label.
    104          * @returns {String} - The language code ("en", "es", etc.)
    105          */
    106         getLang: function(label) {
    107             if (label.toLowerCase().includes("english") || label.toLowerCase().includes("type") || label.toLowerCase().includes("category")) {
    108                 return "en";
    109             }
    110             else {
    111                 return "es";
    112             }
    113         },
    114 
    115         /**
    116          * Read a peice of text.
    117          * @param {String} text - The text to read.
    118          * @param {String} label - The language of the text.
    119          */
    120         Read: function(text, label)
    121         {
    122             var msg = new SpeechSynthesisUtterance(text);
    123             msg.lang = this.getLang(label);
    124             window.speechSynthesis.speak(msg);
    125         },
    126 
    127         /**
    128          * Handle a keyup event (implements keyboard shortcuts).
    129          * @param {object} e - The event args.
    130          */
    131         keyup: function(e) {
    132             if (this._inactive || e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) return;
    133             if (e.keyCode === 13 && this.$refs.search === document.activeElement) this.search();
    134             if (this.$refs.search === document.activeElement) return;
    135             if (e.key === "h" || e.key == "/") {
    136                 try {
    137                     this.$refs.search.focus();
    138                 } catch {}
    139             }
    140             if (e.key === "c") this.category = "verbs"
    141             if (e.key === "v") this.category = "vocab";
    142             if (e.key === ",") this.$router.push({name:"settings", params:{referer:this.$route.name}});
    143         },
    144     },
    145     mounted: function() {
    146         // Generate table
    147         this.table = new DataTable(".referenceTable", {
    148             sortable: true,
    149             unsortable: false,
    150             bodyEventHandlers: {
    151                 click: (row, column, args) => {
    152                     this.Read(this.tableData[this.category][row + 1][column], this.tableData[this.category][0][column]);
    153                 }
    154             }
    155         });
    156 
    157         // Set table height
    158         this.setTableHeight();
    159 
    160         // Add onresize handler
    161         window.addEventListener("resize", this.setTableHeight);
    162 
    163         // Add keyup handler
    164         window.addEventListener("keyup", this.keyup);
    165     },
    166     destroyed: function() {
    167         // Remove onresize handler
    168         window.removeEventListener("resize", this.setTableHeight);
    169 
    170         // Remove keyup handler
    171         window.removeEventListener("keyup", this.keyup);
    172     },
    173     activated: function() {
    174         // Update settings
    175         let settings = getSettings();
    176         this.conjugationColors = settings.conjugationColors;
    177         this.tableTheme = settings.darkTheme ? "basic-dark" : "basic-light";
    178     },
    179     template: `
    180     <div>
    181         <div class="referenceTableControls">
    182             <select aria-label="Vocab Set" v-model="category">
    183                 <option>Choose a category</option>
    184                 <option value="verbs">Conjugations</option>
    185                 <option value="vocab">Vocab</option>
    186             </select>
    187             <div>
    188                 <input type="text" ref="search" aria-label="Search" placeholder="Search" autocomplete="off" autocorrect="off">
    189                 <button @click="search">Search</button>
    190             </div>
    191         </div>
    192 
    193         <div class="referenceTable" ref="referenceTable">
    194         </div>
    195     </div>
    196     `
    197 });
    198 
    199 
    200 
    201 // reference-page component
    202 const referencePage = Vue.component("referencePage", {
    203     template: `
    204         <div class="referencePage">
    205             <page-header icon1="arrow-left" label1="Back" @click1="$emit('back');"
    206                 icon2="settings" label2="Settings" @click2="$router.push({name:'settings', params:{referer:$route.name}})"></page-header>
    207             <main>
    208                 <reference-tables :data="this.$root.$data.data"></reference-tables>
    209             </main>
    210         </div>
    211     `,
    212 });