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!'));
});
});
}
})();