MAL Public Score in MangaList

Adds new column with public score to the MangaList. WARNING! this script only works on Modern Lists, and, not the Classic ones (I think so)

目前为 2021-06-13 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name MAL Public Score in MangaList
  3. // @version 1.0.1
  4. // @author Jery
  5. // @icon https://www.google.com/s2/favicons?domain=myanimelist.net
  6. // @include https://myanimelist.net/mangalist/*
  7. // @grant GM_registerMenuCommand
  8. // @require http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
  9. // @namespace https://greasyfork.org/users/781076
  10. // @description Adds new column with public score to the MangaList. WARNING! this script only works on Modern Lists, and, not the Classic ones (I think so)
  11. // @description-2 This is a tweaked version of this script : https://greasyfork.org/en/scripts/396023 which could only show the scores in animelist
  12. // ==/UserScript==
  13. // If u wanna ask me somethin, then u can find me on MAL : https://myanimelist.net/profile/jery_js (just hit the comments!)
  14. // The 4 lines below are for adding 4 clickable buttons under the script in ur extension (like Tampermonkey or violentmonkey)
  15. GM_registerMenuCommand("Show public scores", activate_script, "p");
  16. GM_registerMenuCommand("Refresh public scores", refresh_public_score, "r");
  17. GM_registerMenuCommand("Show oldest public score timestamp", function(){alert("Oldest entry from: " + new Date(1*window.localStorage.getItem("oldest_entry_timestamp")));}, "o");
  18. GM_registerMenuCommand("Toggle manual activation", toggle_manual_activation, "t");
  19.  
  20. var $ = jQuery;
  21.  
  22. function activate_script() {
  23. add_public_score_column();
  24. make_public_score_column_sortable();
  25. populate_public_score_column();
  26. }
  27.  
  28. function refresh_public_score() {
  29. clear_store();
  30. populate_public_score_column();
  31. }
  32.  
  33. function toggle_manual_activation() {
  34. var is_manual_activation = window.localStorage.getItem("manual_activation");
  35. if (is_manual_activation == null || is_manual_activation === "false") {
  36. window.localStorage.setItem("manual_activation", true);
  37. } else {
  38. window.localStorage.setItem("manual_activation", false);
  39. }
  40. }
  41.  
  42. function clear_store() {
  43. var store = window.localStorage;
  44. store.clear();
  45. }
  46.  
  47. function add_public_score_column() {
  48. var public_score_column_header = $('<th class="header-title public-score click">Public score</th>');
  49. $('.header-title.score').before(public_score_column_header);
  50. $('.list-table tr td.score').before('<td class="data public-score"></td>');
  51. }
  52.  
  53. function populate_public_score_column() {
  54. function fetch_top_public_scores(limit) {
  55. var scores = {};
  56. $.get( "/topmanga.php?limit=" + limit, function( data ) {
  57. var scores = $( data ).find(".ranking-list").each(function(){
  58. var manga_id = $(this).find(".detail a[rel]").attr("href").match(/\/manga\/(\d+)\//)[1];
  59. var score = $(this).find(".js-top-ranking-score-col .text").text().trim();
  60. store_public_score(manga_id, score);
  61. });
  62. });
  63. }
  64. function fetch_top_500_public_scores() {
  65. var store = window.localStorage;
  66. if (store.getItem("fetch_top_500") == null) {
  67. for (var i = 0; i < 10; i++) {
  68. fetch_top_public_scores(i*50);
  69. }
  70. store.setItem("fetch_top_500", true);
  71. }
  72. }
  73. function get_public_score_for_manga(manga_id, set_score_callback) {
  74. var stored_score = get_stored_public_score(manga_id);
  75. if (stored_score == null) {
  76. fetch_public_score_for_manga(manga_id, function (fresh_score) {
  77. set_score_callback(fresh_score);
  78. });
  79. } else {
  80. set_score_callback(stored_score);
  81. }
  82. }
  83. function get_stored_public_score(manga_id) {
  84. var store = window.localStorage;
  85. var oldest_entry_timestamp = store.getItem("oldest_entry_timestamp");
  86. return store.getItem(manga_id);
  87. }
  88. function store_public_score(manga_id, score) {
  89. var store = window.localStorage;
  90. if (store.getItem("oldest_entry_timestamp") == null) {
  91. store.setItem("oldest_entry_timestamp", Date.now());
  92. }
  93. return store.setItem(manga_id, score);
  94. }
  95. function fetch_public_score_for_manga(manga_id, set_score_callback) {
  96. $.get( "/manga/" + manga_id, function( data ) {
  97. var score = $( data ).find(".score").text().trim();
  98. set_score_callback(score);
  99. store_public_score(manga_id, score);
  100. });
  101. }
  102.  
  103. function for_each_public_score_column_cell_do(callback) {
  104. $('.list-table td.data.public-score').each(function(){
  105. var cell = $(this);
  106. var url = cell.siblings('.title').find('a').attr('href');
  107. // "/manga/123/title" => "123"
  108. var manga_id = url.match(/\/manga\/(\d+)/)[1];
  109. callback(cell, manga_id);
  110. });
  111. }
  112.  
  113. fetch_top_500_public_scores();
  114.  
  115. for_each_public_score_column_cell_do(function(cell, manga_id){
  116. get_public_score_for_manga(manga_id, function (score) {
  117. cell.html('<a href="#" class="link">'+score+'</a>');
  118. });
  119. });
  120.  
  121. }
  122.  
  123. function make_public_score_column_sortable() {
  124. function getCellValue(row, index){ return $(row).children('td').eq(index).text() }
  125. function comparer(index) {
  126. return function(a, b) {
  127. var valA = getCellValue(a, index), valB = getCellValue(b, index)
  128. return $.isNumeric(valA) && $.isNumeric(valB) ? valA - valB : valA.toString().localeCompare(valB)
  129. }
  130. }
  131.  
  132. var table_header = $('.list-table th');
  133. // makes cursor change so that column appears to be clickable
  134. table_header.contents() .filter(function() { return this.nodeType == Node.TEXT_NODE; }).wrap('<a href="#"></a>');
  135. table_header.click(function() {
  136. var table = $(this).parents('table').eq(0);
  137. var rows = table.find('tr:gt(0)').toArray().sort(comparer($(this).index()));
  138. this.asc = !this.asc;
  139. // default sort order is descending
  140. if (this.asc){
  141. rows = rows.reverse();
  142. }
  143. for (var i = 0; i < rows.length; i++){
  144. table.append(rows[i]);
  145. }
  146. });
  147. }
  148.  
  149. $(function(){
  150. var is_manual_activation = window.localStorage.getItem("manual_activation");
  151. console.log("is_manual_activation: " + is_manual_activation);
  152. if (is_manual_activation == null || is_manual_activation === "false") {
  153. console.log("script is activated!");
  154. activate_script();
  155. }
  156. });