Erome Sort by views + Infinite Scroll

Sort by views. Infinite scroll. Only videos mode. Hide photos. Tags below title

  1. // ==UserScript==
  2. // @name Erome Sort by views + Infinite Scroll
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @license MIT
  6. // @description Sort by views. Infinite scroll. Only videos mode. Hide photos. Tags below title
  7. // @author ricaroal
  8. // @match *://*.erome.com/*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=erome.com
  10. // @run-at document-idle
  11. // @grant none
  12.  
  13. // ==/UserScript==
  14. /* globals $ LazyLoad */
  15.  
  16. $(document).ready(function() {
  17. // CSS que deseas añadir
  18. var css = `
  19. .album .album-bottom-right, .album .album-bottom-views {
  20. text-shadow: 3px 0 #000, -3px 0 #000, 0 3px #000, 0 -3px #000,
  21. 1px 1px #000, -1px -1px #000, 1px -1px #000, -1px 1px #000;
  22. font-size: 20px;
  23. font-weight: bold;
  24. }
  25.  
  26. #tabs {
  27. display:none;
  28. }
  29.  
  30. .page-content h1 {
  31. margin-bottom:30px;
  32. }
  33. `;
  34. // Añadir el CSS al documento
  35. var style = $('<style></style>').text(css);
  36. $('head').append(style);
  37. });
  38.  
  39. $("#tabs").first().css("display", "flex");
  40. $(".page-content h1").first().css("margin-bottom", "10px");
  41.  
  42. const etiquetasBottom = $(".mt-10");
  43. const userprofileTop = $(".user-profile");
  44. if (etiquetasBottom.length && userprofileTop.length) {
  45. etiquetasBottom.insertAfter(userprofileTop);
  46. }
  47. const spanElement = $('<span>Tags: </span>');
  48. $('p.mt-10').prepend(spanElement);
  49. $('p.mt-10').css('font-size', '20px');
  50.  
  51. if ($('.user-profile').length === 0) {
  52. const orderByViews = $('<button id="order-by-views">Order by views</button>').css({
  53. 'float': 'right',
  54. 'color': '#eb6395',
  55. 'background-color': 'black',
  56. 'padding': '7px',
  57. 'font-size': '17px'
  58. });
  59. $('h1').append(orderByViews);
  60. }
  61.  
  62.  
  63. setInterval(function() {
  64. $('div#page .page-content.row').addClass('albumes');
  65. }, 1000);
  66.  
  67.  
  68.  
  69. $(document).ready(function() {
  70. // Function to convert formatted views to complete numbers
  71. function convertViews(views) {
  72. if (views.includes('K')) {
  73. return parseFloat(views.replace('K', '').replace(',', '.')) * 1000;
  74. }
  75. return parseInt(views.replace(',', ''));
  76. }
  77.  
  78. // Event listener for the button
  79. $('#order-by-views').click(function() {
  80.  
  81. // MODIFICACION SCRIPT
  82. // Select all albumes divs
  83. const albumesDivs = $('.albumes');
  84. // If there are no albumes divs or only one, no need to merge
  85. if (albumesDivs.length <= 1) {
  86. return;
  87. }
  88. // Get the first albumes div
  89. const mainAlbumesDiv = albumesDivs.first();
  90. // Loop through all albumes divs except the first one
  91. albumesDivs.slice(1).each(function() {
  92. // Get all album divs inside the current albumes div
  93. const albumDivs = $(this).find('.album');
  94. // Append each album div to the first albumes div
  95. albumDivs.appendTo(mainAlbumesDiv);
  96. // Remove the current albumes div
  97. $(this).remove();
  98. });
  99. // MODIFICACION SCRIPT
  100.  
  101. // Iterate over each span element with the class 'album-bottom-views' and convert views
  102. $('.album-bottom-views').each(function() {
  103. const $this = $(this);
  104. const viewsText = $this.text().trim().replace(/[^\d,K]/g, ''); // Extract the views text
  105. const completeViews = convertViews(viewsText); // Convert views to complete number
  106. $this.html('<i class="fa fa-eye"></i>' + completeViews.toLocaleString()); // Update the span content
  107. });
  108.  
  109. // Get all child divs with the class 'album' and sort them based on the number of views
  110. const $albums = $('.albumes').children('.album').sort(function(a, b) {
  111. const viewsA = convertViews($(a).find('.album-bottom-views').text().trim().replace(/[^\d,k]/g, ''));
  112. const viewsB = convertViews($(b).find('.album-bottom-views').text().trim().replace(/[^\d,k]/g, ''));
  113. return viewsB - viewsA; // Sort in descending order
  114. });
  115.  
  116. // Append the sorted albums back to the parent container
  117. $('.albumes').append($albums);
  118. });
  119. });
  120.  
  121.  
  122. (function disableDisclaimer() {
  123. if (!$('#disclaimer').length) return;
  124. $.ajax({ type: 'POST', url: '/user/disclaimer', async: true });
  125. $('#disclaimer').remove();
  126. $('body').css('overflow', 'visible');
  127. })();
  128.  
  129. const PINK = '#eb6395';
  130. const GREY = '#a09f9d';
  131.  
  132. function isActiveColor(condition) { return condition ? PINK : GREY; };
  133.  
  134. function togglePhotoElements() {
  135. document.querySelectorAll('.media-group > div:last-child:not(.video)').forEach(a => {
  136. $(a.parentElement).toggle(config.showPhotos);
  137. });
  138. $('#togglePhotos').css('backgroundColor', isActiveColor(config.showPhotos));
  139. $('#togglePhotos').text(!config.showPhotos ? 'show photos' : 'hide photos');
  140. }
  141.  
  142. function hidePhotoOnlyAlbums() {
  143. $('div[id^=album]').filter((_, e) => !$(e).find('.album-videos').length).toggle(config.showPhotoAlbums);
  144. $('#togglePhotoAlbums').css('color', isActiveColor(!config.showPhotoAlbums));
  145. window.dispatchEvent(new Event('scroll'));
  146. }
  147.  
  148. function infiniteScrollAndLazyLoading() {
  149. if (!document.querySelector('.pagination')) return;
  150.  
  151. const url = new URL(window.location.href);
  152.  
  153. const nextPageUrl = () => {
  154. url.searchParams.set('page', nextPage);
  155. return url.href;
  156. }
  157.  
  158. let nextPage = parseInt(url.searchParams.get('page')) || 2;
  159. const limit = parseInt($('.pagination li:last-child()').prev().text()) || 50;
  160.  
  161. const infinite = $('#page').infiniteScroll({ path: nextPageUrl, append: '.page-content', scrollThreshold: 800 });
  162.  
  163. $('#page').on('append.infiniteScroll', () => {
  164. hidePhotoOnlyAlbums();
  165. new LazyLoad();
  166. nextPage++;
  167. if (nextPage > limit) infinite.destroy();
  168. });
  169. }
  170.  
  171. /******************************************* STATE ***********************************************/
  172.  
  173. const config = {
  174. showPhotos: true,
  175. showPhotoAlbums: false
  176. }
  177.  
  178. function sync() {
  179. Object.assign(config, JSON.parse(localStorage.getItem("config")));
  180. }
  181.  
  182. function save() {
  183. localStorage.setItem("config", JSON.stringify(config));
  184. }
  185.  
  186. //=================================================================================================
  187.  
  188. const IS_ALBUM_PAGE = /^\/a\//.test(window.location.pathname);
  189.  
  190. function pageAction() {
  191. sync();
  192. if (IS_ALBUM_PAGE) {
  193. togglePhotoElements();
  194. } else {
  195. hidePhotoOnlyAlbums();
  196. }
  197. }
  198.  
  199. if (IS_ALBUM_PAGE) {
  200. $('#user_name').parent().append('<button id="togglePhotos" class="btn btn-pink">show/hide photos</button>');
  201. $('#togglePhotos').on('click', () => {
  202. config.showPhotos = !config.showPhotos;
  203. togglePhotoElements();
  204. save();
  205. });
  206. } else {
  207. infiniteScrollAndLazyLoading();
  208. $('.navbar-nav').append('<li><a href="#" id="togglePhotoAlbums">video only</span></a></li>');
  209. $('#togglePhotoAlbums').on('click', () => {
  210. config.showPhotoAlbums = !config.showPhotoAlbums;
  211. hidePhotoOnlyAlbums();
  212. save();
  213. });
  214. }
  215.  
  216. window.addEventListener('focus', pageAction);
  217. pageAction();