Better Statsbar (LeetCode)

Show the total number of questions per difficulty in LeetCode's statsbar.

Pada tanggal 08 Januari 2019. Lihat %(latest_version_link).

  1. // ==UserScript==
  2. // @name Better Statsbar (LeetCode)
  3. // @description Show the total number of questions per difficulty in LeetCode's statsbar.
  4. // @namespace https://greatest.deepsurf.us/en/users/128831-marvinyan
  5. // @match https://leetcode.com/problemset/algorithms/
  6. // @grant GM.getValue
  7. // @grant GM.setValue
  8. // @grant GM_getValue
  9. // @grant GM_setValue
  10. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  11. // @require https://greatest.deepsurf.us/scripts/374849-library-onelementready-es6/code/Library%20%7C%20onElementReady%20ES6.js?version=649483
  12. // @version 0.0.1.20190108010704
  13. // ==/UserScript==
  14.  
  15. (() => {
  16. const LC_ALGO_API = 'https://leetcode.com/api/problems/algorithms/';
  17. const CACHE_DURATION_MS = 10 * 1000; // Optional rate limit (default: 10s)
  18. const CURRENT_TIME_MS = new Date().getTime();
  19.  
  20. const getData = async url => {
  21. const lastCheck = await GM.getValue('lastCheck', Number.MAX_VALUE);
  22. const cachedJsonStr = await GM.getValue('cachedJsonStr', null);
  23. const timeSinceCheck = CURRENT_TIME_MS - lastCheck;
  24.  
  25. return new Promise(resolve => {
  26. if (timeSinceCheck < CACHE_DURATION_MS && cachedJsonStr !== null) {
  27. resolve(cachedJsonStr);
  28. } else {
  29. const xhr = new XMLHttpRequest();
  30. xhr.open('GET', url, true);
  31. xhr.onload = () => {
  32. if (xhr.status >= 200 && xhr.status < 300) {
  33. GM.setValue('lastCheck', CURRENT_TIME_MS);
  34. GM.setValue('cachedJsonStr', xhr.responseText);
  35. resolve(xhr.responseText);
  36. }
  37. };
  38. xhr.send();
  39. }
  40. });
  41. };
  42.  
  43. const parseData = response => {
  44. const counts = [0, 0, 0];
  45. const questions = JSON.parse(response).stat_status_pairs;
  46.  
  47. questions.forEach(q => {
  48. counts[q.difficulty.level - 1]++;
  49. });
  50.  
  51. return counts;
  52. };
  53.  
  54. const updateStatsBar = counts => {
  55. const statsBar = $('#welcome > span > span');
  56.  
  57. let $totalSolvedSpan = $(statsBar[0]).closest('span');
  58. const newText = $totalSolvedSpan.text().replace('/', ' / ');
  59. $totalSolvedSpan.text(newText);
  60.  
  61. for (let i = 1; i < statsBar.length; i++) {
  62. statsBar[i].append(` / ${counts[i - 1]}`);
  63. }
  64. };
  65.  
  66. const run = async () => {
  67. const data = await getData(LC_ALGO_API);
  68. const counts = parseData(data);
  69. updateStatsBar(counts);
  70. };
  71.  
  72. waitForKeyElements('#welcome', run);
  73. })();