您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
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.1.0 // @include https://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 needToRegisterFilters = true; var settingsLoadedPromise = promise(); var filterNamePrefix = 'additionalFilters_'; var recentLessonsFilterName = filterNamePrefix + 'recentLessons'; var leechTrainingFilterName = filterNamePrefix + 'leechTraining'; var timeUntilReviewFilterName = filterNamePrefix + 'timeUntilReview'; var supportedFilters = [recentLessonsFilterName, leechTrainingFilterName, timeUntilReviewFilterName]; var defaultSettings = {}; defaultSettings[recentLessonsFilterName] = true; defaultSettings[leechTrainingFilterName] = true; defaultSettings[timeUntilReviewFilterName] = true; var recentLessonsHoverTip = 'Only include 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 timeUntilReviewSummaryHoverTip = 'Only include items that have at least X% of their SRS interval remaining.'; var timeUntilReviewHoverTip = timeUntilReviewSummaryHoverTip + '\nValid values are from 0 to 100. Examples:\n "75": At least 75% of an item\'s SRS interval must be remaining.'; var msToHoursDivisor = 3600000; var nowForTimeUntilReview; var regularSrsIntervals = [0, 4, 8, 23, 47, 167, 335, 719, 2879]; var acceleratedSrsIntervals = [0, 2, 4, 8, 23, 167, 335, 719, 2879]; var acceleratedLevels = [1, 2]; 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 }; settings[timeUntilReviewFilterName] = { type: 'checkbox', label: 'Time Until Review', hover_tip: timeUntilReviewSummaryHoverTip }; 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(); if (wkof.settings[settingsScriptId][timeUntilReviewFilterName]) registerTimeUntilReviewFilter(); needToRegisterFilters = false; } // BEGIN Recent Lessons function registerRecentLessonsFilter() { wkof.ItemData.registry.sources.wk_items.filters[recentLessonsFilterName] = { type: 'number', label: 'Recent Lessons', default: 24, placeholder: '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: '1', 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 // BEGIN Time Until Review function registerTimeUntilReviewFilter() { wkof.ItemData.registry.sources.wk_items.filters[timeUntilReviewFilterName] = { type: 'number', label: 'Time Until Review', default: 50, placeholder: '50', prepare: timeUntilReviewPrepare, filter_value_map: timeUntilReviewValueMap, filter_func: timeUntilReviewFilter, set_options: function(options) { options.assignments = true; }, hover_tip: timeUntilReviewHoverTip }; } function timeUntilReviewPrepare() { // Only set "now" once so that all items use the same value when filtering. nowForTimeUntilReview = Date.now(); } function timeUntilReviewValueMap(percentage) { if (percentage < 0) return 0; if (percentage > 100) return 100; return percentage; } function timeUntilReviewFilter(percentage, item) { if (item.assignments === undefined) return false; var srsStage = item.assignments.srs_stage; if (srsStage === 0) return false; if (srsStage === 9) return true; var level = item.assignments.level; var reviewAvailableAt = item.assignments.available_at; return isAtLeastMinimumHoursUntilReview(srsStage, level, reviewAvailableAt, percentage); } function isAtLeastMinimumHoursUntilReview(srsStage, level, reviewAvailableAt, percentage) { var hoursUntilReview = (new Date(reviewAvailableAt).getTime() - nowForTimeUntilReview) / msToHoursDivisor; var srsInvervals = acceleratedLevels.includes(level) ? acceleratedSrsIntervals : regularSrsIntervals; var minimumHoursUntilReview = srsInvervals[srsStage] * percentage / 100; return minimumHoursUntilReview <= hoursUntilReview; } // END Time Until Review })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址