您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
See what level you are at for each stage (Apprentice/Guru/Master/Englightened/Burned).
// ==UserScript== // @name WaniKani Levels By Stage // @version 0.0.2 // @description See what level you are at for each stage (Apprentice/Guru/Master/Englightened/Burned). // @author hitechbunny // @include https://www.wanikani.com/ // @include https://www.wanikani.com/dashboard // @run-at document-end // @grant none // @namespace https://greasyfork.org/users/149329 // ==/UserScript== (function() { 'use strict'; // Hook into App Store try { $('.app-store-menu-item').remove(); $('<li class="app-store-menu-item"><a href="https://community.wanikani.com/t/there-are-so-many-user-scripts-now-that-discovering-them-is-hard/20709">App Store</a></li>').insertBefore($('.navbar .dropdown-menu .nav-header:contains("Account")')); window.appStoreRegistry = window.appStoreRegistry || {}; window.appStoreRegistry[GM_info.script.uuid] = GM_info; localStorage.appStoreRegistry = JSON.stringify(appStoreRegistry); } catch (e) {} var api_key; var cached_json = localStorage.getItem('level-progress-cache'); if (cached_json) { render(JSON.parse(cached_json)); } get_api_key().then(function() { ajax_retry('https://wanikanitools-golang.curiousattemptbunny.com/level/progress?api_key='+api_key).then(function(json) { localStorage.setItem('level-progress-cache', JSON.stringify(json)); render(json); }); }); function render(json) { console.log(json); if (!json.stage_levels) { return; } var html = '<section class="srs-progress">'+ ' <ul>'; ['Apprentice', 'Guru', 'Master', 'Enlightened', 'Burned'].forEach(function(stage) { html += '<li style="box-shadow: initial; padding-top: 10px; padding-bottom: 6px;">'+ '<span style="font-size: 16px; display: initial;">Level '+(json.stage_levels[stage].level == 60 ? 60 : json.stage_levels[stage].level + 1) +'</span><br>'+ '<span style="display: initial; font-weight: initial; font-size: 16px;">'+(json.stage_levels[stage].percentage_next_level*100).toFixed(0)+'%</span>'+ '</li>'; }); html += ' </ul>'+ '</section>'; var previous = $('.srs-progress')[1]; if (previous) { $(previous).remove(); } $(html).insertAfter('.srs-progress'); } //------------------------------------------------------------------- // Fetch a document from the server. //------------------------------------------------------------------- function ajax_retry(url, options) { //console.log(url, retries, timeout); options = options || {}; var retries = options.retries || 3; var timeout = options.timeout || 3000; var headers = options.headers || {}; var method = options.method || 'GET'; var data = options.data || undefined; var cache = options.cache || false; function action(resolve, reject) { $.ajax({ url: url, method: method, timeout: timeout, headers: headers, data: data, cache: cache }) .done(function(data, status){ //console.log(status, data); if (status === 'success') { resolve(data); } else { //console.log("done (reject)", status, data); reject(); } }) .fail(function(xhr, status, error){ //console.log(status, error); if ((status === 'error' || status === 'timeout') && --retries > 0) { //console.log("fail", status, error); action(resolve, reject); } else { reject(); } }); } return new Promise(action); } function get_api_key() { return new Promise(function(resolve, reject) { api_key = localStorage.getItem('apiKey_v2'); if (typeof api_key === 'string' && api_key.length == 36) return resolve(); // status_div.html('Fetching API key...'); ajax_retry('/settings/account').then(function(page) { // --[ SUCCESS ]---------------------- // Make sure what we got is a web page. if (typeof page !== 'string') {return reject();} // Extract the user name. page = $(page); // Extract the API key. api_key = page.find('#user_api_key_v2').attr('value'); if (typeof api_key !== 'string' || api_key.length !== 36) { return reject(new Error('generate_apikey')); } localStorage.setItem('apiKey_v2', api_key); resolve(); },function(result) { // --[ FAIL ]------------------------- reject(new Error('Failed to fetch API key!')); }); }); } })();