您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Displays your level for each SRS stage.
当前为
// ==UserScript== // @name Wanikani: Levels by SRS // @namespace http://tampermonkey.net/ // @version 1.0.2 // @description Displays your level for each SRS stage. // @author Kumirei // @match https://www.wanikani.com/dashboard // @match https://www.wanikani.com // @grant none // ==/UserScript== (function() { //check that the Wanikani Framework is installed var script_name = 'Levels By SRS'; 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's installed then do the stuffs else { wkof.include('Menu,Settings,ItemData'); wkof.ready('Menu,Settings,ItemData') .then(load_settings) .then(install_menu) .then(add_css) .then(fetch_and_update); } // Fetches items and updates display function fetch_and_update() { fetch_items() .then(process_items) .then(update_display); } // Fetches the relevant items function fetch_items() { var [promise, resolve] = new_promise(); var config = { wk_items: { options: {assignments: true}, filters: {level: "1..+0"} } }; wkof.ItemData.get_items(config).then(resolve); return promise; } // Retreives the levels by srs function process_items(data) { // Sort by level var levels = {}; for (var i=0; i<data.length; i++) { var item = data[i]; var level = item.data.level; if (!levels[level]) levels[level] = []; levels[level].push(item); } // Go through items level by level var srs_levels = {Ini: 0, App: 0, Gur: 0, Mas: 0, Enl: 0, Bur: 0}; for (i=1; i<wkof.user.level+1; i++) { // Get counts for level var by_srs = {Ini: 0, App: 0, Gur: 0, Mas: 0, Enl: 0, Bur: 0, total: 0}; for (var j=0; j<levels[i].length; j++) { item = levels[i][j]; if (item.assignments) by_srs[item.assignments.srs_stage_name.slice(0, 3)]++; by_srs.total++; } // Check if srs_level should be increased var types = ['Ini', 'App', 'Gur', 'Mas', 'Enl', 'Bur']; var cumulative = 0; for (j=0; j<types.length; j++) { var count = by_srs[types[j]]; if (1-cumulative/by_srs.total >= wkof.settings.levels_by_srs.threshold/100 && i == srs_levels[types[j]]+1) { srs_levels[types[j]]++; } cumulative += count; } } return srs_levels; } // Updates the display element function update_display(srs_levels) { var types = ['App', 'Gur', 'Mas', 'Enl', 'Bur']; // If the element doesn't already exist, create it var display = $('#levels_by_srs'); if (!display.length) { display = $('<div id="levels_by_srs"'+(is_dark_theme() ? ' class="dark_theme"' : '')+'></div>'); for (var i=0; i<types.length; i++) display.append('<div class="'+types[i]+'"><span class="level_label">Level: </span><span class="value"></span></div>'); $('.srs-progress').after(display); } // Update for (i=0; i<types.length; i++) $(display).find('.'+types[i]+' span.value')[0].innerText = srs_levels[types[i]]; } // Load stored settings or set defaults function load_settings() { var defaults = {threshold: 90}; return wkof.Settings.load('levels_by_srs', defaults); } // Installs the options button in the menu function install_menu() { var config = { name: 'levels_by_srs', submenu: 'Settings', title: 'Levels By SRS', on_click: open_settings }; wkof.Menu.insert_script_link(config); } // Create the options function open_settings(items) { var config = { script_id: 'levels_by_srs', title: 'Levels By SRS', on_save: fetch_and_update, content: { threshold: { type: 'number', label: 'Threshold', hover_tip: 'Percentage to consider level done', default: 90, } } } var dialog = new wkof.Settings(config); dialog.open(); } // Adds the script's CSS to the page function add_css() { $('head').append('<style id="levels_by_srs_CSS">'+ '#levels_by_srs {'+ ' background: #434343;'+ ' border-radius: 0 0 3px 3px;'+ ' height: 30px;'+ ' line-height: 30px;'+ ' color: rgb(240, 240, 240);'+ ' font-size: 16px;'+ '}'+ '#levels_by_srs > div {'+ ' width: calc(20% - 1px);'+ ' display: inline-block;'+ ' text-align: center;'+ '}'+ '#levels_by_srs .level_label {'+ ' font-weight: bold;'+ '}'+ '.dashboard > .container > .row > .span12 > section.srs-progress {'+ ' margin-bottom: 0 !important;'+ '}'+ '.srs-progress > ul > li {'+ ' border-radius: 0 !important;'+ '}'+ '#levels_by_srs.dark_theme {'+ ' background: #232629;'+ ' box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7), 2px 2px 2px rgba(0, 0, 0, 0.7);'+ ' margin: 0 3px 3px 3px;'+ '}'+ '#levels_by_srs.dark_theme > div:not(:last-child) {'+ ' border-right: 1px solid #31363b;'+ '}'+ '</style>'); } // Returns a promise and a resolve function function new_promise() { var resolve, promise = new Promise((res, rej)=>{resolve = res;}); return [promise, resolve]; } // Handy little function that rfindley wrote. Checks whether the theme is dark. function is_dark_theme() { // Grab the <html> background color, average the RGB. If less than 50% bright, it's dark theme. return $('body').css('background-color').match(/\((.*)\)/)[1].split(',').slice(0,3).map(str => Number(str)).reduce((a, i) => a+i)/(255*3) < 0.5; } })();