Jpdb percentage bar

Adds a progress bar during jpdb reviews

当前为 2022-09-09 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Jpdb percentage bar
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3.6
  5. // @description Adds a progress bar during jpdb reviews
  6. // @author Calonca
  7. // @match https://jpdb.io/review
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
  10. // @grant GM_addStyle
  11. // @grant GM_setValue
  12. // @grant GM_getValue
  13. // @license GPLv2
  14. // @namespace https://greasyfork.org/users/956173-calonca
  15. // ==/UserScript==
  16.  
  17. let styleSheet = `
  18. .innerBar {
  19. width: 10%;
  20. height: 30px;
  21. background-color: #7baee9;
  22. text-align: center; /* To center it horizontally (if you want) */
  23. line-height: 30px; /* To center it vertically */
  24. color: white;
  25. }
  26. .outerBar {
  27. width: 100%;
  28. background-color: #a2a2a2;
  29. text-align: center; /* To center it horizontally (if you want) */
  30. }
  31. `;
  32.  
  33. const doneNumKey = "revsDone";
  34. let s = document.createElement("style");
  35. s.type = "text/css";
  36. s.innerHTML = styleSheet;
  37. (document.head || document.documentElement).appendChild(s);
  38.  
  39. (function() {
  40. 'use strict';
  41. if (GM_getValue(doneNumKey)==null){
  42. //Set values in first script usage
  43. GM_setValue(doneNumKey,0)
  44. }
  45.  
  46. function getPercentage(done, remaining){
  47. //return (((done+remaining)));
  48. return (100*(done/(Number(done)+Number(remaining)))).toFixed(2)+"%";
  49. }
  50.  
  51. function getDoneAndRemainingString(done, remaining){
  52. return "&nbspdone:&nbsp"+done+"&nbsp|&nbsp"+"remaining:&nbsp"+remaining;
  53. }
  54.  
  55. //Progress bar
  56. let outerBar = document.createElement("div");
  57. outerBar.className = "outerBar";
  58.  
  59. let innerBar = document.createElement("div");
  60. innerBar.className = "innerBar";
  61. outerBar.appendChild(innerBar);
  62.  
  63. function updateBar(){
  64. let percentage = getPercentage(GM_getValue(doneNumKey),revNum);
  65. innerBar.style.width = percentage;
  66. innerBar.innerHTML = getDoneAndRemainingString(GM_getValue(doneNumKey),revNum)+"&nbsp|&nbsp"+percentage;
  67. }
  68.  
  69. let learnNavItem = document.querySelectorAll(".nav-item")[0]
  70. let span = learnNavItem.childNodes[1];
  71. let revNum = span.textContent;
  72.  
  73. function onReset() {
  74. if (confirm("Do you want to reset the Progress Bar?")) {
  75. GM_setValue(doneNumKey,0);
  76. updateBar();
  77. }
  78. }
  79.  
  80. outerBar.onclick = onReset;
  81.  
  82. //Increase done review count on button click
  83. function increaseDone() {
  84. GM_setValue(doneNumKey,GM_getValue(doneNumKey)+1);
  85. }
  86. function afterShowingGradeButtons(){
  87. outerBar.onclick = null;
  88. document.getElementById("grade-3").addEventListener ("click", increaseDone , false);
  89. document.getElementById("grade-4").addEventListener ("click", increaseDone , false);
  90. document.getElementById("grade-5").addEventListener ("click", increaseDone , false);
  91. }
  92.  
  93. let showAnswerButton = document.getElementById("show-answer");
  94. if (showAnswerButton){
  95. waitForKeyElements (
  96. "#grade-3"
  97. , afterShowingGradeButtons
  98. );
  99. }
  100.  
  101. //Add elements to the document
  102. updateBar();
  103.  
  104. let elementAfter = document.getElementsByClassName("main-row")[0];
  105. if (elementAfter){//Doing review
  106. elementAfter.parentElement.insertBefore(outerBar,elementBefore);
  107. }else {//Continue or finish screen
  108. let parent = document.getElementsByClassName("container bugfix")[0];
  109. let importantText = document.getElementsByTagName('h5')[0]
  110. if (importantText.innerHTML == "Good job! You've finished all of your due cards!"){//Finish screen
  111. let resetText = document.createElement("h5");
  112. resetText.innerHTML = "Progress bar has been reset";
  113. parent.insertBefore(resetText,parent.childNodes[1]);
  114. GM_setValue(doneNumKey,0);
  115. }
  116. }
  117. })();
  118.  
  119.  
  120. //Put the function here instead of requires due to GreasyFolk rules, original can be found at https://gist.github.com/BrockA/2625891
  121. /*--- waitForKeyElements(): A utility function, for Greasemonkey scripts,
  122. that detects and handles AJAXed content.
  123.  
  124. Usage example:
  125.  
  126. waitForKeyElements (
  127. "div.comments"
  128. , commentCallbackFunction
  129. );
  130.  
  131. //--- Page-specific function to do what we want when the node is found.
  132. function commentCallbackFunction (jNode) {
  133. jNode.text ("This comment changed by waitForKeyElements().");
  134. }
  135.  
  136. IMPORTANT: This function requires your script to have loaded jQuery.
  137. */
  138. function waitForKeyElements (
  139. selectorTxt, /* Required: The jQuery selector string that
  140. specifies the desired element(s).
  141. */
  142. actionFunction, /* Required: The code to run when elements are
  143. found. It is passed a jNode to the matched
  144. element.
  145. */
  146. bWaitOnce, /* Optional: If false, will continue to scan for
  147. new elements even after the first match is
  148. found.
  149. */
  150. iframeSelector /* Optional: If set, identifies the iframe to
  151. search.
  152. */
  153. ) {
  154. var targetNodes, btargetsFound;
  155.  
  156. if (typeof iframeSelector == "undefined")
  157. targetNodes = $(selectorTxt);
  158. else
  159. targetNodes = $(iframeSelector).contents ()
  160. .find (selectorTxt);
  161.  
  162. if (targetNodes && targetNodes.length > 0) {
  163. btargetsFound = true;
  164. /*--- Found target node(s). Go through each and act if they
  165. are new.
  166. */
  167. targetNodes.each ( function () {
  168. var jThis = $(this);
  169. var alreadyFound = jThis.data ('alreadyFound') || false;
  170.  
  171. if (!alreadyFound) {
  172. //--- Call the payload function.
  173. var cancelFound = actionFunction (jThis);
  174. if (cancelFound)
  175. btargetsFound = false;
  176. else
  177. jThis.data ('alreadyFound', true);
  178. }
  179. } );
  180. }
  181. else {
  182. btargetsFound = false;
  183. }
  184.  
  185. //--- Get the timer-control variable for this selector.
  186. var controlObj = waitForKeyElements.controlObj || {};
  187. var controlKey = selectorTxt.replace (/[^\w]/g, "_");
  188. var timeControl = controlObj [controlKey];
  189.  
  190. //--- Now set or clear the timer as appropriate.
  191. if (btargetsFound && bWaitOnce && timeControl) {
  192. //--- The only condition where we need to clear the timer.
  193. clearInterval (timeControl);
  194. delete controlObj [controlKey]
  195. }
  196. else {
  197. //--- Set a timer, if needed.
  198. if ( ! timeControl) {
  199. timeControl = setInterval ( function () {
  200. waitForKeyElements ( selectorTxt,
  201. actionFunction,
  202. bWaitOnce,
  203. iframeSelector
  204. );
  205. },
  206. 300
  207. );
  208. controlObj [controlKey] = timeControl;
  209. }
  210. }
  211. waitForKeyElements.controlObj = controlObj;
  212. }