Wanikani: Level Duration 2

Displays the number of days you have spent on the current level.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Wanikani: Level Duration 2
// @namespace    Wanikani: Level Duration
// @version      2.8.1
// @description  Displays the number of days you have spent on the current level.
// @author       Kumirei
// @include      /^https://(www|preview).wanikani.com*/
// @grant        none
// ==/UserScript==
/*jshint esversion: 8 */

(function(wkof) {
    let header = document.getElementsByClassName('global-header')[0];
    if (!header) return;

    // Make sure that WKOF is installed
    var script_name = 'Level Duration';
    if (!window.wkof) {
        if (confirm(script_name+' requires Wanikani Open Framework.\nDo you want to be forwarded to the installation instructions?')) {
            window.location.href = 'https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549';
        }
        return;
    }
    // If it is installed run the script
    else {
        wkof.include('Menu,Settings,Apiv2');
        wkof.ready('Menu,Settings,Apiv2')
            .then(load_settings)
            .then(install_menu)
            .then(install_css)
            .then(fetch_date)
            .then(install_display);
    }

    let date, level_duration;

    //------------------------------------------------------//
    //--------------------SET UP IN WKOF--------------------//
    //------------------------------------------------------//

    function load_settings() {
        var defaults = {
            format: "long",
        };
        return wkof.Settings.load('level_duration', defaults);
    }

    function install_menu() {
        var config = {
            name: 'level_duration_settings',
            submenu: 'Settings',
            title: 'Level Duration',
            on_click: open_settings
        };
        wkof.Menu.insert_script_link(config);
    }

    function open_settings(items) {
        var config = {
            script_id: 'level_duration',
            title: 'Level Duration',
            on_save: update_display,
            content: {
                format: {
                    type: 'list',
                    label: 'Format',
                    default: 'long',
                    hover_tip: 'Select how you want the duration to display',
                    size: 6,
                    content: {
                        long: format_date('long'),
                        decimal_long: format_date('decimal_long'),
                        decimal: format_date('decimal'),
                        short: format_date('short'),
                        japanese: format_date('japanese'),
                        japanese_custom: format_date('japanese_custom') + ' (FangSong font)',
                    },
                },
            },
        };
        let dialog = new wkof.Settings(config);
        dialog.open();
    }

    //------------------------------------------------------//
    //----------------------RUN SCRIPT----------------------//
    //------------------------------------------------------//

    function install_css() {
        document.getElementsByTagName('head')[0].insertAdjacentHTML('beforeend', `
<style id="LevelDurationCSS">
    .global-header {padding-bottom: 14px;}
    #level-duration {
        color: #999 !important;
        text-shadow: 0 1px 0 #ffffff;
        font-size: 14px;
        margin-top: 4px;
        line-height: 0;
        text-align: center;
    }
    #level-duration-old {
        text-align: center;
        color: #999 !important;
        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        text-shadow: 0 1px 0 #ffffff;
        margin-top: -2px;
    }
    #level-duration.japanese_custom,
    #wkof_ds #level_duration_format option[name="japanese_custom"] {
        font-family: FangSong;
    }
</style>
`);
    }

    // Fetch the level's unlock date
    function fetch_date() {
        return wkof.Apiv2.fetch_endpoint('/level_progressions').then(data => {date = data.data.pop().data.unlocked_at;});
    }

    // Installs the display element and set it up to update every 15 minutes
    function install_display() {
        level_duration = document.createElement('div');
        level_duration.id = 'level-duration';
        level_duration.innerHTML = '<span></span>';
        update_display(level_duration, date);
        let target = document.querySelector('.sitemap .sitemap__section-header[aria-controls="sitemap__levels"').parentElement;
        let old_target = document.querySelector('.dropdown.levels');
        if (old_target) { // Support for old header script
            level_duration.id = 'level-duration-old';
            target = old_target;
        }
        target.append(level_duration);
        setInterval(update_display, 1000*60*15); // Update every 15 minutes
    }

    // Clears the element and inserts new info
    function update_display() {
        let text = format_date();
        level_duration.children[0].innerText = text;
        level_duration.className = wkof.settings.level_duration.format;
    }

    // Returns the date in the user's preferred format
    function format_date(format) {
        let msday = 1000*60*60*24;
        let diff = Date.now()-Date.parse(date);
        let days = Math.floor(diff/msday);
        let hours = Math.floor(diff/msday*24%24);
        let day_text, hour_text = '';
        switch (format || wkof.settings.level_duration.format) {
            case ('long'):
                day_text = days + ' day'+(days==1?'':'s');
                hour_text = ' ' + hours + ' hour'+(hours==1?'':'s');
                if (days >= 100) hour_text = ''; // Otherwise the text gets too long
                break;
            case ('decimal_long'):
                day_text = (days+hours/24).toFixed(1) + ' days on level';
                break;
            case ('decimal'):
                day_text = (days+hours/24).toFixed(1) + ' days';
                break;
            case ('short'):
                day_text = days + 'd';
                hour_text = ' ' + hours + 'h';
                break;
            case ('japanese'):
                day_text = days + '日';
                hour_text = hours + '時';
                break;
            case ('japanese_custom'):
                day_text = days + '日';
                hour_text = hours + '時';
                break;
        }
        return day_text + hour_text;
    }
})(window.wkof);