您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show SRS and leech breakdown on dashboard
// ==UserScript== // @name WaniKani Dashboard SRS and Leech Breakdown // @namespace https://www.wanikani.com // @description Show SRS and leech breakdown on dashboard // @author seanblue // @version 1.0.0 // @include https://www.wanikani.com/dashboard // @include https://www.wanikani.com/ // @grant none // ==/UserScript== (function() { 'use strict'; if (!window.wkof) { let response = confirm('WaniKani Dashboard SRS and Leech Breakdown script requires WaniKani Open Framework.\n Click "OK" to be forwarded to installation instructions.'); if (response) { window.location.href = 'https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549'; } return; } let style = `<style> .srs-progress-details { position: relative; color: #fff; } .dashboard section.srs-progress span { margin-bottom: 0.2em; } .dashboard section.srs-progress .srs-progress-details .leech-count .leech-breakdown { background-color: black; font-size: 0.8em; font-weight: 100; opacity: 0.75; display: none; } .dashboard section.srs-progress li:hover .srs-progress-details .leech-count .leech-breakdown { display: inline; } .dashboard section.srs-progress .srs-progress-details .leech-count { background-color: black; position: absolute; right: -1.0em; bottom: -2.5em; padding-left: 0.3em; padding-right: 0.3em; font-size: 1em; opacity: 0.25; font-weight: 100; } .dashboard section.srs-progress li:hover .srs-progress-details .leech-count { opacity: 1.0; } </style>` $('head').append(style); const leechThreshold = 1; const config = { wk_items: { options: { review_statistics: true, assignments: true } } }; wkof.include('ItemData'); wkof.ready('ItemData').then(getItems).then(mapItemsToSrs).then(updatePage); function getItems(items) { return wkof.ItemData.get_items(config).then(filterToActiveAssignments); } function filterToActiveAssignments(items) { return items.filter(itemIsActiveAssignment); } function itemIsActiveAssignment(item) { let assignments = item.assignments; if (assignments === undefined) { return false; } let srsStage = getSrsStage(assignments); return srsStage >= 1 && srsStage <= 8; } function getSrsStage(assignments) { return assignments.srs_stage; } function mapItemsToSrs(items) { let itemsBySrs = [1, 2, 3, 4, 5, 6, 7, 8].reduce((result, srs) => { result[srs] = { total: 0, leech: 0 }; return result; }, {}); items.forEach(function(item) { let srsStage = getSrsStage(item.assignments); itemsBySrs[srsStage].total++; if (isLeech(item)) { itemsBySrs[srsStage].leech++; } }); return itemsBySrs; } function isLeech(item) { if (item.review_statistics === undefined) { return false; } let reviewStats = item.review_statistics; let meaningScore = getLeechScore(reviewStats.meaning_incorrect, reviewStats.meaning_current_streak); let readingScore = getLeechScore(reviewStats.reading_incorrect, reviewStats.reading_current_streak); return meaningScore >= leechThreshold || readingScore >= leechThreshold; } function getLeechScore(incorrect, currentStreak) { return incorrect / Math.pow((currentStreak || 0.5), 1.5); } function updatePage(itemsBySrs) { displayDetailedSection('apprentice', itemsBySrs, [1, 2, 3, 4]); displayDetailedSection('guru', itemsBySrs, [5, 6]); displaySimpleSection('master', itemsBySrs, 7); displaySimpleSection('enlightened', itemsBySrs, 8); displayEmptySection('burned'); } function displayDetailedSection(srsSectionId, itemsBySrs, srsLevelsArray) { let srsProgressDetailsSection = addFilledTotalBreakdownSection(srsSectionId, itemsBySrs, srsLevelsArray); addDetailedLeechSection(srsProgressDetailsSection, itemsBySrs, srsLevelsArray); } function displaySimpleSection(srsSectionId, itemsBySrs, srsLevel) { let srsProgressDetailsSection = addEmptyTotalBreakdownSection(srsSectionId); addSimpleLeechSection(srsProgressDetailsSection, itemsBySrs, srsLevel); } function displayEmptySection(srsSectionId) { addEmptyTotalBreakdownSection(srsSectionId); } function addFilledTotalBreakdownSection(srsSectionId, itemsBySrs, srsLevelsArray) { let totals = srsLevelsArray.map(srs => itemsBySrs[srs].total).join(' / '); return addTotalBreakdownSection(srsSectionId, `${totals}`); } function addEmptyTotalBreakdownSection(srsSectionId) { return addTotalBreakdownSection(srsSectionId, ' '); } function addTotalBreakdownSection(srsSectionId, sectionContent) { let section = $(`<div class="srs-progress-details">${sectionContent}</div>`); $(`#${srsSectionId} span`).after(section); return section; } function addDetailedLeechSection(srsProgressDetailsSection, itemsBySrs, srsLevelsArray) { let leechArray = srsLevelsArray.map(srsLevel => itemsBySrs[srsLevel].leech); let leechBreakdown = leechArray.join(' / '); let leechTotal = leechArray.reduce((total, val) => total + val, 0); let sectionContent = `<span class="leech-breakdown">(${leechBreakdown}) </span>${leechTotal}`; addLeechSection(srsProgressDetailsSection, sectionContent); } function addSimpleLeechSection(srsProgressDetailsSection, itemsBySrs, srsLevel) { addLeechSection(srsProgressDetailsSection, `${itemsBySrs[srsLevel].leech}`); } function addLeechSection(srsProgressDetailsSection, sectionContent) { let section = `<span class="leech-count">${sectionContent}</span>`; srsProgressDetailsSection.append(section); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址