Last active
June 6, 2018 02:57
-
-
Save Fawers/6cf968d77e1796571d1d5762dc181f26 to your computer and use it in GitHub Desktop.
WaniKani Reorder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * 2018-04-25 | |
| * WaniKani Reorder - wkreorder | |
| * Reorder your review items on the fly | |
| * (Optimized for phones) | |
| * | |
| * With wk-reorder, you're able to - tada - reorder your review items by some criteria. | |
| * As of this script, you're able to reorder them by SRS level, and type. | |
| * The script works by getting your current queue, and applying a sort function to make it | |
| * show items in the order you want them to - either ascendingly or descendingly. | |
| * For this first version, there isn't a nice, clean UI from which you can select the | |
| * ordering, but you'll be presented a prompt asking to enter how you want to order it. | |
| * Type sorting order is radical, kanji, and then vocab items. | |
| * Example sorting strings: | |
| * ・ st | |
| * ・ Sorts by SRS level, and type (all ascending) | |
| * ・ t-s | |
| * ・ Sorts by type ascending, and SRS level descending | |
| * ・ -st | |
| * ・ Sorts by SRS level descending, and type ascending. | |
| * By default, readings will come first and meanings second. Radicals are meaning-only | |
| * items. | |
| */ | |
| // Item types | |
| var RADICAL = 'rad', | |
| KANJI = 'kan', | |
| VOCABULARY = 'voc'; | |
| // Question types | |
| var READING = 'reading', // N/A for radicals | |
| MEANING = 'meaning'; | |
| // Sorting regex | |
| var SORTING_PATTERN = /-?[st]/g; | |
| function WaniKaniReorder() { | |
| this.repeatCurrentItem = false; | |
| this.items = null; | |
| this.currentItem = null; | |
| this.currentQType = null; | |
| this.lastUpdated = 0; | |
| } | |
| WaniKaniReorder.prototype.init = function() { | |
| var aq = $.jStorage.get('activeQueue'), | |
| rq = $.jStorage.get('reviewQueue'); | |
| var sorting; | |
| this.items = aq.concat(rq); | |
| $.jStorage.listenKeyChange('currentItem', this.setItem.bind(this)); | |
| $.jStorage.listenKeyChange('wrongCount', this.flagWrongItem.bind(this)); | |
| sorting = (function() { | |
| var userInput; | |
| do { | |
| userInput = prompt( | |
| 'Tell me your sorting method.', 'ts').match(SORTING_PATTERN) || []; | |
| } while (userInput.length !== 2); | |
| return userInput; | |
| })(); | |
| this.sort(sorting); | |
| } | |
| WaniKaniReorder.prototype.setItem = function() { | |
| // since this method changes the current item, it triggers itself. | |
| // this.lastUpdated is here to prevent just that. | |
| var now = new Date().getTime(); | |
| if ((now - this.lastUpdated) <= 600) return; | |
| this.lastUpdated = now; | |
| // on the occasion of an item being answered wrongly, this.repeatCurrentItem | |
| // will be set to true. this section handles it, and also sets repeatCurrentItem | |
| // back to false. | |
| if (this.repeatCurrentItem) { | |
| $.jStorage.set('questionType', this.currentQType); | |
| $.jStorage.set('currentItem', this.currentItem); | |
| this.repeatCurrentItem = false; | |
| return; | |
| } | |
| if (!this.currentItem) { // first run | |
| this.currentItem = this.items.shift(); | |
| this.currentQType = this.currentItem[RADICAL] ? MEANING : READING; | |
| $.jStorage.set('questionType', this.currentQType); | |
| $.jStorage.set('currentItem', this.currentItem); | |
| return; | |
| } | |
| if (!this.currentItem[RADICAL]) { | |
| if (this.currentQType === READING) { | |
| this.currentQType = MEANING; | |
| } | |
| else { | |
| this.removeCurrentFromQueue(); | |
| this.currentItem = this.items.shift() || {}; | |
| this.currentQType = this.currentItem[RADICAL] ? MEANING : READING; | |
| } | |
| } | |
| else { | |
| this.removeCurrentFromQueue(); | |
| this.currentItem = this.items.shift() || {}; | |
| this.currentQType = this.currentItem[RADICAL] ? MEANING : READING; | |
| } | |
| $.jStorage.set('questionType', this.currentQType); | |
| $.jStorage.set('currentItem', this.currentItem); | |
| } | |
| WaniKaniReorder.prototype.flagWrongItem = function() { | |
| this.repeatCurrentItem = true; | |
| } | |
| WaniKaniReorder.prototype.removeCurrentFromQueue = function() { | |
| // because items are not actually removed from WaniKani's queue, | |
| // so we do it ourselves. | |
| // (context: WaniKani auto-removes items from its ACTIVE queue. it doesn't | |
| // "know" the user is answering items not present in ↑it↑.) | |
| var rq = $.jStorage.get('reviewQueue'); | |
| $.jStorage.set('reviewQueue', rq.filter((function(i) { | |
| return i.id !== this.currentItem.id; | |
| }).bind(this))); | |
| } | |
| WaniKaniReorder.prototype.sort = function(sortingOrder) { | |
| var SRSWeight = 0, | |
| typeWeight = 0; | |
| var badSortingOrder = function () { alert('Bad sorting order.'); throw new Error('Bad sorting order.'); }; | |
| sortingOrder.forEach(function(item, position) { | |
| var weight = position === 0 ? 10 : 1; | |
| if (item.indexOf('s') !== -1 && SRSWeight === 0) { | |
| SRSWeight = item[0] === '-' ? -weight : weight; | |
| } | |
| else if (item.indexOf('t') !== -1 && typeWeight === 0) { | |
| typeWeight = item[0] === '-' ? -weight : weight; | |
| } | |
| else { | |
| badSortingOrder(); | |
| } | |
| }); | |
| this.items.sort(function(a, b) { | |
| var itemOrder = 0, s, t; | |
| if (a.srs < b.srs) { | |
| s = -1; | |
| } | |
| else if (a.srs > b.srs) { | |
| s = 1; | |
| } | |
| else { | |
| s = 0; | |
| } | |
| if (a[RADICAL] && !b[RADICAL] || a[KANJI] && b[VOCABULARY]) { | |
| t = -1; | |
| } | |
| else if (b[RADICAL] && !a[RADICAL] || b[KANJI] && a[VOCABULARY]) { | |
| t = 1; | |
| } | |
| else { | |
| t = 0; | |
| } | |
| return s * SRSWeight + t * typeWeight; | |
| }); | |
| } | |
| wkr = new WaniKaniReorder(); | |
| wkr.init(); | |
| wkr.setItem(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| javascript:var RADICAL="rad",KANJI="kan",VOCABULARY="voc",READING="reading",MEANING="meaning",SORTING_PATTERN=/-?[st]/g;function WaniKaniReorder(){this.repeatCurrentItem=!1,this.items=null,this.currentItem=null,this.currentQType=null,this.lastUpdated=0}WaniKaniReorder.prototype.init=function(){var t,e=$.jStorage.get("activeQueue"),r=$.jStorage.get("reviewQueue");this.items=e.concat(r),$.jStorage.listenKeyChange("currentItem",this.setItem.bind(this)),$.jStorage.listenKeyChange("wrongCount",this.flagWrongItem.bind(this)),t=function(){for(var t;2!==(t=prompt("Tell me your sorting method.","ts").match(SORTING_PATTERN)||[]).length;);return t}(),this.sort(t)},WaniKaniReorder.prototype.setItem=function(){var t=(new Date).getTime();if(!(t-this.lastUpdated<=600)){if(this.lastUpdated=t,this.repeatCurrentItem)return $.jStorage.set("questionType",this.currentQType),$.jStorage.set("currentItem",this.currentItem),void(this.repeatCurrentItem=!1);if(!this.currentItem)return this.currentItem=this.items.shift(),this.currentQType=this.currentItem[RADICAL]?MEANING:READING,$.jStorage.set("questionType",this.currentQType),void $.jStorage.set("currentItem",this.currentItem);this.currentItem[RADICAL]?(this.removeCurrentFromQueue(),this.currentItem=this.items.shift()||{},this.currentQType=this.currentItem[RADICAL]?MEANING:READING):this.currentQType===READING?this.currentQType=MEANING:(this.removeCurrentFromQueue(),this.currentItem=this.items.shift()||{},this.currentQType=this.currentItem[RADICAL]?MEANING:READING),$.jStorage.set("questionType",this.currentQType),$.jStorage.set("currentItem",this.currentItem)}},WaniKaniReorder.prototype.flagWrongItem=function(){this.repeatCurrentItem=!0},WaniKaniReorder.prototype.removeCurrentFromQueue=function(){var t=$.jStorage.get("reviewQueue");$.jStorage.set("reviewQueue",t.filter(function(t){return t.id!==this.currentItem.id}.bind(this)))},WaniKaniReorder.prototype.sort=function(t){var n=0,s=0;t.forEach(function(t,e){var r=0===e?10:1;-1!==t.indexOf("s")&&0===n?n="-"===t[0]?-r:r:-1!==t.indexOf("t")&&0===s?s="-"===t[0]?-r:r:function(){throw alert("Bad sorting order."),new Error("Bad sorting order.")}()}),this.items.sort(function(t,e){var r,i;return r=t.srs<e.srs?-1:t.srs>e.srs?1:0,i=t[RADICAL]&&!e[RADICAL]||t[KANJI]&&e[VOCABULARY]?-1:e[RADICAL]&&!t[RADICAL]||e[KANJI]&&t[VOCABULARY]?1:0,r*n+i*s})},wkr=new WaniKaniReorder,wkr.init(),wkr.setItem(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment