您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds button enabling item ordering by SRS level.
// ==UserScript== // @name WaniKani SRS Reorder Button // @namespace towe.wk.srsreorder // @author Towe // @description Adds button enabling item ordering by SRS level. // @include *://www.wanikani.com/review/session // @version 1.2.0 // @grant none // ==/UserScript== /* Settings */ const questionTypeOrder = 1; // 1 - reading first, 2 - meaning first, 3 - random const itemTypeOrder = 1; // 1 - rad->kan->voc, 2 - voc->kan->rad, 3 - random const ascendingSRS = true; // low-level items first const priotitizeSRS = true; // SRS order more important than item type order const force1x1 = true; // meaning and reading directly next to each other const sortOnStartup = false; // sort items on startup const hotkey = 'Digit3' // keyboard shortcut (key code) /* Utilities */ const $ = window.$; function getTypePriority(item) { if (item.rad) { return 1; } else if (item.kan) { return 2; } else { return 3; } } function itemComparator(itemA, itemB) { const srsOrder = ascendingSRS ? itemA.srs - itemB.srs : itemB.srs - itemA.srs; const typeOrder = itemTypeOrder === 3 ? 0 : (getTypePriority(itemA) - getTypePriority(itemB)) * (3 - itemTypeOrder * 2); return priotitizeSRS ? srsOrder || typeOrder : typeOrder || srsOrder; } function showCounters(items) { const itemsByLevels = [0, 0, 0, 0, 0, 0, 0, 0]; for (let i = 0; i < items.length; ++i) { ++itemsByLevels[items[i].srs - 1]; } const $srsCounters = $('<div id="srsCounters" style="background-color:rgba(255,255,255,0.9);border-radius:8px;color:black;font-weight:bold;margin-top:5px;text-shadow:none"></div>'); for (let level = 1; level <= itemsByLevels.length; ++level) { const color = level < 5 ? 'DD0093' : level < 7 ? '882D9E' : level < 8 ? '294DDB' : '0093DD'; if (level > 1) { $srsCounters.append(', '); } $srsCounters.append($('<span style="color:#' + color + ';margin:0">' + itemsByLevels[level - 1] + '</span>')); } $('#srsCounters').remove(); $('div#stats').append($srsCounters); } /* Event handlers */ const usedUIDs = []; function reorderQuestionTypes() { const item = $.jStorage.get('currentItem'); const newUID = (item.rad ? 'r' : item.kan ? 'k' : 'v') + item.id; if (usedUIDs.includes(newUID)) { return; } usedUIDs.push(newUID); const requestedType = ['reading', 'meaning'][item.rad ? 1 : questionTypeOrder - 1]; if ($.jStorage.get("questionType") !== requestedType) { $.jStorage.set('questionType', requestedType); $.jStorage.set('currentItem', item); } } function updateCounters() { const items = $.jStorage.get('activeQueue').concat($.jStorage.get('reviewQueue')); showCounters(items); return items; } function reorderBySrs() { const items = updateCounters(); items.sort(itemComparator); $.jStorage.set('activeQueue', items.slice(0, 10)); $.jStorage.set('reviewQueue', items.slice(10).reverse()); if (questionTypeOrder !== 3) { $.jStorage.listenKeyChange('currentItem', reorderQuestionTypes); } $.jStorage.listenKeyChange('currentItem', updateCounters); $.jStorage.set('currentItem', items[0]); if (force1x1) { try { unsafeWindow.Math.random = function() { return 0; }; } catch (e) { Math.random = function() { return 0; }; } } } /* Initialization */ $(function() { const $button = $('<div style="background-color: #A000f0; color: #FFFFFF; cursor: pointer; display: inline-block; font-size: 0.8125em; padding: 10px; vertical-align: bottom;">Sort by SRS</div>'); $('footer').prepend($button.click(reorderBySrs)); document.addEventListener('keydown', function(e) { if (e.code === hotkey) { reorderBySrs(); e.preventDefault(); } }); if (sortOnStartup) { const observer = new MutationObserver(function() { reorderBySrs(); observer.disconnect(); }); observer.observe(document.getElementById('loading'), { attributes: true }); } });