Web漫画アンテナ 既読対応

マイリストのページで既読漫画の背景色を変えます

  1. // ==UserScript==
  2. // @name Web漫画アンテナ 既読対応
  3. // @namespace
  4. // @description マイリストのページで既読漫画の背景色を変えます
  5. // @version 0.17
  6. // @author kiyo
  7. // @match https://webcomics.jp/mylist
  8. // @match https://webcomics.jp/mylist*
  9. // @grant none
  10. // @namespace
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. const myStorage = JSON.parse(localStorage._supportRead || "{}");
  15. const readColor= "#c5c5c6";
  16. const nowDate = new Date();
  17.  
  18. const timeToMsec = (num, unit) => {
  19. // サイト内の時間表示が切り上げなので-1しておく(24時に更新した作品が時間により日付が前後してしまうのを回避)
  20. num = num - 1;
  21. switch (unit) {
  22. case "時間前":
  23. return num * 60 * 60 * 1000;
  24. case "分前":
  25. return num * 60 * 1000;
  26. case "秒前":
  27. return num * 1000;
  28. default:
  29. console.error(`timeToMsec Error: ${num}${unit}`);
  30. }
  31. }
  32. const dateToStr = (year, month, day) => `${year}${("0"+month).slice(-2)}${("0"+day).slice(-2)}`;
  33. const calcAgoDate = (nowDate, num, unit) => {
  34. let ago = timeToMsec(parseInt(num), unit);
  35. //console.log(ago, num, unit);
  36. const agoDate = new Date(nowDate - ago);
  37. const year = agoDate.getFullYear();
  38. const month = agoDate.getMonth() + 1;
  39. const day = agoDate.getDate();
  40. return dateToStr(year, month, day);
  41. }
  42.  
  43. const e = {
  44. entry: document.querySelectorAll(".entry"),
  45. thumb: document.querySelectorAll(".entry > .entry-thumb > a > img"),
  46. date: document.querySelectorAll(".entry > .entry-date"),
  47. title: document.querySelectorAll(".entry > .entry-title > [href]")
  48. };
  49.  
  50. //function test(){console.log(this.i +","+ this.mangaId +","+ this.date);};
  51. function handleEvent(){
  52. const {i, mangaId, date} = this;
  53. e.entry[i].style.background = readColor;
  54. // 重複チェック&追加
  55. if (!(mangaId in myStorage)) {
  56. myStorage[mangaId] = [date];
  57. } else if (!(myStorage[mangaId].some(val => val === date))) {
  58. myStorage[mangaId].push(date);
  59. }
  60. // 10MB(10485760文字)以上になったら先頭から削除
  61. if (JSON.stringify(myStorage).length > 10485760) myStorage[mangaId].shift();
  62. // localStorageに入れる
  63. localStorage._supportRead = JSON.stringify(myStorage);
  64. }
  65.  
  66. for (let i = 0, len = e.entry.length; i < len; i++) {
  67. const mangaId = e.thumb[i].src.split("/").slice(-1)[0].replace(".jpg", "");
  68. // 24時間以内の更新だと表記が変わる
  69. const dateText = e.date[i].textContent;
  70. const date = /^\d+時間前|^\d+分前|^\d+秒前/.test(dateText)
  71. ? calcAgoDate(nowDate, dateText.match(/^\d+/)[0], dateText.match(/時間前|分前|秒前/)[0]) : dateText.replace(/\//g, "");
  72. if (mangaId in myStorage && myStorage[mangaId].some(val => val === date)) e.entry[i].style.background = readColor;
  73.  
  74. e.title[i].addEventListener("click", {i, mangaId, date, handleEvent});
  75. e.title[i].addEventListener("auxclick", {i, mangaId, date, handleEvent});
  76. if (e.entry[i].querySelector(".entry-text > [href]")) {
  77. e.entry[i].querySelector(".entry-text > [href]").addEventListener("click", {i, mangaId, date, handleEvent});
  78. e.entry[i].querySelector(".entry-text > [href]").addEventListener("auxclick", {i, mangaId, date, handleEvent});
  79. }
  80. }
  81. })();