Additional filters for the WaniKani Open Framework
当前为
// ==UserScript==
// @name WaniKani Open Framework Additional Filters
// @namespace https://www.wanikani.com
// @description Additional filters for the WaniKani Open Framework
// @author seanblue
// @version 1.0.1
// @include *://www.wanikani.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
var wkofMinimumVersion = '1.0.18';
if (!window.wkof) {
alert('WaniKani Open Framework Additional Filters requires WaniKani Open Framework.\nYou will now be forwarded to installation instructions.');
window.location.href = 'https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549';
return;
}
if (!wkof.version || wkof.version.compare_to(wkofMinimumVersion) === 'older') {
alert('WaniKani Open Framework Additional Filters requires at least version ' + wkofMinimumVersion + ' of WaniKani Open Framework.');
return;
}
var settingsDialog;
var settingsScriptId = 'additionalFilters';
var settingsTitle = 'Additional Filters';
var filterNamePrefix = 'additionalFilters_';
var recentLessonsFilterName = filterNamePrefix + 'recentLessons';
var leechTrainingFilterName = filterNamePrefix + 'leechTraining';
var supportedFilters = [recentLessonsFilterName, leechTrainingFilterName];
var needToRegisterFilters = true;
var settingsLoadedPromise = promise();
var defaultSettings = {};
defaultSettings[recentLessonsFilterName] = true;
defaultSettings[leechTrainingFilterName] = true;
var recentLessonsHoverTip = 'Filter items to show lessons taken in the last X hours.';
var leechesSummaryHoverTip = 'Only include leeches. Formula: incorrect / currentStreak^1.5.';
var leechesHoverTip = leechesSummaryHoverTip + '\n * The higher the value, the fewer items will be included as leeches.\n * Setting the value to 1 will include items that have just been answered incorrectly for the first time.\n * Setting the value to 1.01 will exclude items that have just been answered incorrectly for the first time.';
var msToHoursDivisor = 3600000;
wkof.include('Menu, Settings');
wkof.ready('Menu').then(installMenu);
waitForItemDataRegistry().then(installSettings);
function promise(){var a,b,c=new Promise(function(d,e){a=d;b=e;});c.resolve=a;c.reject=b;return c;}
function waitForItemDataRegistry() {
return wkof.wait_state('wkof.ItemData.registry', 'ready');
}
function installMenu() {
loadSettings().then(function() {
addMenuItem();
});
}
function addMenuItem() {
wkof.Menu.insert_script_link({
script_id: settingsScriptId,
submenu: 'Settings',
title: settingsTitle,
on_click: function() { settingsDialog.open(); }
});
}
function installSettings() {
wkof.ItemData.pause_ready_event(true);
loadSettings().then(function() {
wkof.ItemData.pause_ready_event(false);
});
}
function loadSettings(postLoadAction) {
wkof.ready('Settings').then(function() {
if (settingsDialog) {
return;
}
var settings = {};
settings[recentLessonsFilterName] = { type: 'checkbox', label: 'Recent Lessons', hover_tip: recentLessonsHoverTip };
settings[leechTrainingFilterName] = { type: 'checkbox', label: 'Leech Training', hover_tip: leechesSummaryHoverTip };
settingsDialog = new wkof.Settings({
script_id: settingsScriptId,
title: settingsTitle,
on_save: saveSettings,
settings: settings
});
settingsDialog.load(defaultSettings).then(function() {
updateFiltersWhenReady();
settingsLoadedPromise.resolve();
});
});
return settingsLoadedPromise;
}
function saveSettings(){
settingsDialog.save().then(function() {
updateFiltersWhenReady();
});
}
function updateFiltersWhenReady() {
needToRegisterFilters = true;
waitForItemDataRegistry().then(registerFilters);
}
function registerFilters() {
if (!needToRegisterFilters)
return;
supportedFilters.forEach(function(filterName) {
delete wkof.ItemData.registry.sources.wk_items.filters[filterName];
});
if (wkof.settings[settingsScriptId][recentLessonsFilterName])
registerRecentLessonsFilter();
if (wkof.settings[settingsScriptId][leechTrainingFilterName])
registerLeechTrainingFilter();
needToRegisterFilters = false;
}
// BEGIN Recent Lessons
function registerRecentLessonsFilter() {
wkof.ItemData.registry.sources.wk_items.filters[recentLessonsFilterName] = {
type: 'number',
label: 'Recent Lessons (hours)',
default: 24,
filter_func: recentLessonsFilter,
set_options: function(options) { options.assignments = true; },
hover_tip: recentLessonsHoverTip
};
}
function recentLessonsFilter(filterValue, item) {
if (item.assignments === undefined)
return false;
var startedAt = item.assignments.started_at;
if (startedAt === null || startedAt === undefined)
return false;
var startedAtDate = new Date(startedAt);
var timeSinceStart = Date.now() - startedAtDate;
return (timeSinceStart / msToHoursDivisor) < filterValue;
}
// END Recent Lessons
// BEGIN Leeches
function registerLeechTrainingFilter() {
wkof.ItemData.registry.sources.wk_items.filters[leechTrainingFilterName] = {
type: 'number',
label: 'Leech Training',
default: 1,
placeholder: 'Leech Threshold',
filter_func: leechTrainingFilter,
set_options: function(options) { options.review_statistics = true; },
hover_tip: leechesHoverTip
};
}
function leechTrainingFilter(filterValue, item) {
if (item.review_statistics === undefined)
return false;
var reviewStats = item.review_statistics;
var meaningScore = getLeechScore(reviewStats.meaning_incorrect, reviewStats.meaning_current_streak);
var readingScore = getLeechScore(reviewStats.reading_incorrect, reviewStats.reading_current_streak);
return meaningScore >= filterValue || readingScore >= filterValue;
}
function getLeechScore(incorrect, currentStreak) {
return incorrect / Math.pow((currentStreak || 0.5), 1.5);
}
// END Leeches
})();