Leetcode Points

see monthly progress of leetcode points

  1. // ==UserScript==
  2. // @name Leetcode Points
  3. // @license MIT
  4. // @namespace https://github.com/pk2sd
  5. // @version 0.3
  6. // @description see monthly progress of leetcode points
  7. // @author https://leetcode.com/pK2015/
  8. // @match https://leetcode.com/store/
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=leetcode.com
  10. // @require https://code.jquery.com/jquery-3.6.0.min.js
  11. // @grant none
  12. // @run-at document-end
  13. // ==/UserScript==
  14.  
  15. $('document').ready(() => {
  16. $.ajax({
  17. url: 'https://leetcode.com/points/api/'
  18. }).done((response) => {
  19. parseDataAndAddSummary(response)
  20. })
  21.  
  22. let toTable = (map) => {
  23. let mapToTr = (totr) => {
  24. return Array.from(totr).sort((a, b) => {
  25. return parseInt(b[1]) - parseInt(a[1])
  26. }).map((entry) => {
  27. let key = entry[0]
  28. let value = entry[1]
  29. return '<tr>'
  30. + '<td style="padding-right: 2px">'
  31. + key
  32. + '</td>'
  33. + '<td>'
  34. + value
  35. + '</td>'
  36. + '</tr>'
  37. }).reduce((prev, cur) => prev + cur, '')
  38.  
  39. }
  40. return '<table>'
  41. + '<thead>'
  42. + '<tr>'
  43. + '<th>'
  44. + 'Activity'
  45. + '</th>'
  46. + '<th>'
  47. + 'Points'
  48. + '</th>'
  49. + '</tr>'
  50. + '</thead>'
  51. + '<tbody>'
  52. + mapToTr(map)
  53. + '</tbody>'
  54. + '</table>'
  55.  
  56.  
  57. }
  58. const curmonth = new Date().getMonth()
  59. const curyear = new Date().getFullYear()
  60. let points = null
  61. let construct = () => {
  62. const year = $('#years').find(":selected").attr('value') || curyear
  63. const month = $('#months').find(":selected").attr('value') || curmonth
  64. const npoints = points.scores.map(point => {
  65. return {...point, date: new Date(Date.parse(point.date))}
  66. }).filter(p => p.date.getMonth() == month && p.date.getFullYear() == year)
  67. const total = npoints.map(p => p.score).reduce((x,y) => x+y,0);
  68. const activityToPointsMap = npoints.reduce((map, curPoint) => {
  69. if(map.has(curPoint.description)){
  70. map.set(curPoint.description, map.get(curPoint.description) + curPoint.score)
  71. } else {
  72. map.set(curPoint.description, curPoint.score)
  73. }
  74. return map
  75. }, new Map())
  76.  
  77. $('#points_p').html('<h4> Total points: ' + total + '</h4><br/>' + (activityToPointsMap.size > 0 ? toTable(activityToPointsMap): ''))
  78. }
  79.  
  80. let parseDataAndAddSummary = (pointss) => {
  81. const months = [0,1,2,3,4,5,6,7,8,9,10,11]
  82. const years = Array.from(new Set(pointss.scores.map(point => new Date(Date.parse(point.date)).getFullYear())))
  83.  
  84. $('<p>', {id: 'points_p'}).prependTo('body')
  85. $('#points_p').css('display', 'flex')
  86. $('#points_p').css('align-items', 'center')
  87. $('#points_p').css('justify-content', 'center')
  88.  
  89. $('body').prepend(`<div id = "options_div">
  90. <label for="months"> Month </label>
  91. <select id="months">
  92. </select>
  93. <label for="years"> Year </label>
  94. <select id="years">
  95. </select>
  96. </div>`)
  97.  
  98.  
  99. months.forEach((m) => {
  100. let selected = m === curmonth
  101. $('#months').append(`
  102. <option value="${m}" ${selected ? "selected" : ""}>
  103. ${m + 1}
  104. </option>
  105. `
  106. )
  107. })
  108.  
  109. years.forEach((y) => {
  110. let selected = y === curyear
  111. $('#years').append(`
  112. <option value="${y}" ${selected ? "selected" : ""}>
  113. ${y}
  114. </option>
  115. `
  116. )
  117. })
  118. $('#months').change(construct)
  119. $('#years').change(construct)
  120. points = pointss
  121. construct()
  122.  
  123. }
  124. })