Wanikani: True Level

Don't level up until you finish all lessons from previous levels

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Wanikani: True Level
// @namespace    http://tampermonkey.net/
// @version      1.0.1
// @description  Don't level up until you finish all lessons from previous levels
// @author       Kumirei
// @include      /^https://(www|preview).wanikani.com/(dashboard)?/
// @grant        none
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

;(async (wkof) => {
    // Script info
    const script_id = 'true_level'
    const script_name = 'True Level'

    // Initiate WKOF
    await confirm_wkof()
    wkof.include('ItemData')
    wkof.ready('ItemData').then(install_filter).then(update_counts)

    // Global variable
    let lowestLessonLevel = 99

    function install_filter() {
        wkof.ItemData.registry.sources.wk_items.filters.lowest_level_lessons = {
            type: 'checkbox',
            default: true,
            label: 'Lowest Level Lessons',
            filter_func: (filter_value, item) =>
                !filter_value ||
                (item.data.level === lowestLessonLevel &&
                    item.assignments?.srs_stage === 0 &&
                    item.assignments.unlocked_at),
            hover_tip: 'Get only lessons from the lowest available level',
            set_options: (options) => {
                options.assignments = true
            },
        }
    }

    async function update_counts() {
        const items = await wkof.ItemData.get_items('assignments')
        let lessons = items.filter((item) => item.assignments?.srs_stage === 0 && item.assignments.unlocked_at)
        lowestLessonLevel = lessons.reduce((lowest, item) => Math.min(lowest, item.data.level), lowestLessonLevel)
        const count = lessons.filter((item) => item.data.level === lowestLessonLevel).length
        // Update counts
        const counts = [
            '.navigation-shortcut--lessons span',
            '#lessons-summary #lesson-queue-count',
            '.lessons-and-reviews__lessons-button span',
        ]
        counts
            .map((selector) => document.querySelector('.navigation-shortcut--lessons span'))
            .filter((a) => a)
            .forEach((elem) => (elem.textContent = count))
        document.querySelector('.navigation-shortcut--lessons')?.setAttribute('data-count', count)
        document.querySelector('.lessons-and-reviews__lessons-button')?.setAttribute('class', getClass(count))
        // Update level
        const levelElem = document.querySelector('.user-summary__attributes > li:first-child a')
        if (levelElem) levelElem.textContent = `Level ${lowestLessonLevel}`
        // TODO: Update progress
        //$('.dashboard-progress .progress-component h1').text(`Level ${lowestLessonLevel} Progress`)
        setTimeout(update_counts, (60 - new Date().getMinutes()) * 1000 * 60 + 1000) // Update counts within a minute of top of the hour
    }

    function getClass(count) {
        const threshhold = [500, 250, 100, 50, 25, 1, 0].filter((t) => t <= count)[0]
        return `lessons-and-reviews__button lessons-and-reviews__lessons-button lessons-and-reviews__lessons-button--${threshhold}`
    }

    // Makes sure that WKOF is installed
    async function confirm_wkof() {
        if (!wkof) {
            let response = confirm(
                `${script_name} requires WaniKani Open Framework.\nClick "OK" to be forwarded to installation instructions.`,
            )
            if (response) {
                window.location.href =
                    'https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549'
            }
        }
    }
})(window.wkof)