Unread eComments

Shows unread comments on eRepublik articles

  1. // ==UserScript==
  2. // @name Unread eComments
  3. // @namespace http://www.erepublik.com
  4. // @description Shows unread comments on eRepublik articles
  5. // @include http://www.erepublik.com/*/article/*
  6. // @include https://www.erepublik.com/*/article/*
  7. // @version 0.0.6
  8. // @require https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @grant GM_listValues
  12. // @grant GM_deleteValue
  13. // ==/UserScript==
  14.  
  15. init();
  16.  
  17. function init() {
  18. start(true);
  19. observeNewComments();
  20. deleteOldValues();
  21. }
  22.  
  23. function deleteOldValues() {
  24. var maxArticles = 200;
  25. var storedValues = GM_listValues();
  26. console.log('Unread eComments: currently tracking ' + storedValues.length + ' article(s)');
  27. if(storedValues.length > maxArticles ){
  28. storedValues.sort(
  29. function sortFunction(a, b) {
  30. return getStoredData(a).registeredAt - getStoredData(b).registeredAt;
  31. }
  32. );
  33. var valuesToDelete = storedValues.length - maxArticles;
  34. console.log('Deleting comment info for ' + valuesToDelete + ' old article(s)');
  35. for(var i = 0; i < valuesToDelete; i++) {
  36. GM_deleteValue(storedValues[i]);
  37. }
  38. }
  39. }
  40.  
  41.  
  42. function start(isCountUnread) {
  43. var articleId = findArticleId();
  44. var commentsRead = getStoredData(articleId);
  45.  
  46. if(commentsRead.registeredAt <= 0) {
  47. commentsRead.registeredAt = Math.round(new Date().getTime() / 1000); // timestamp in seconds
  48. }
  49. if(isCountUnread) {
  50. countUnread(commentsRead);
  51. }
  52. scanComments(commentsRead);
  53. setStoredData(articleId, commentsRead);
  54. }
  55.  
  56.  
  57. function observeNewComments() {
  58. var target = document.querySelector('#loadMoreComments');
  59. var observer = new MutationObserver(function(mutations) {
  60. start(false);
  61. });
  62. var config = { childList: true };
  63. observer.observe(target, config);
  64. }
  65.  
  66. function scanComments(commentsRead) {
  67. var unreadComments = $('.comment-holder')
  68. .filter( function(index) {
  69. var commentId = $(this).attr('id').replace(/comment/, '');
  70. if(commentId in commentsRead.ids) {
  71. return false;
  72. } else {
  73. commentsRead.ids[commentId] = true;
  74. return true;
  75. }
  76. });
  77. unreadComments.css('background-color', '#e6f3f9');
  78. unreadComments.children('.comments-right')
  79. .children().andSelf()
  80. .css('background-color', '#e6f3f9');
  81. }
  82.  
  83. function countUnread(commentsRead) {
  84. var nbrOfComments = parseInt($('#comments_button_on>span').text().match(/\d+/), 10);
  85.  
  86. var unreadCount = nbrOfComments - commentsRead.commentsLastVisit;
  87. commentsRead.commentsLastVisit = nbrOfComments;
  88.  
  89. if(unreadCount > 0){
  90. $('#comments_button_on>span').append(' *** ' + unreadCount + ' ***');
  91. }
  92. }
  93.  
  94. function getStoredData(articleId) {
  95. var commentsRead = JSON.parse( GM_getValue(articleId, '{"registeredAt": 0, "commentsLastVisit": 0, "ids": {}}') );
  96.  
  97. if(!commentsRead) {
  98. console.log('The stored data is likely to be corrupted.');
  99. }
  100. return commentsRead;
  101. }
  102.  
  103. function setStoredData(articleId, commentsRead) {
  104. GM_setValue(articleId, JSON.stringify(commentsRead));
  105. }
  106.  
  107. function findArticleId() {
  108. var id = $('.post_content > h2 > a').attr('href').replace(/\/1\/20/, '');
  109. id = id.substring(id.lastIndexOf('-')+1);
  110. return id;
  111. }