YouTube - "Hide watched videos" button

Adds a button to hide all watched/upcoming videos from the subscription page

当前为 2022-11-24 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name YouTube - "Hide watched videos" button
  3. // @description Adds a button to hide all watched/upcoming videos from the subscription page
  4. // @version 2022.11.23.21.16
  5. // @author MetalTxus
  6. // @namespace https://github.com/jesuscc1993
  7.  
  8. // @icon https://www.youtube.com/favicon.ico
  9. // @match https://www.youtube.com/*
  10. // @require https://code.jquery.com/jquery-3.2.1.min.js
  11. // ==/UserScript==
  12.  
  13. /* globals jQuery */
  14.  
  15. (() => {
  16. 'use strict';
  17.  
  18. let buttonElement;
  19.  
  20. const shouldRender = () => {
  21. return !!location.href.match(urlPattern).length;
  22. }
  23.  
  24. const hideWatchedVideos = () => {
  25. const watchedVideos = jQuery('[id="progress"], [overlay-style="UPCOMING"]').parents(videosSelector);
  26. watchedVideos.css('display', 'none');
  27.  
  28. const leftVideosCount = jQuery(videosSelector).length - watchedVideos.length;
  29. buttonElement.text(`Hide watched (${watchedVideos.length} videos hid / ${leftVideosCount} videos left)`);
  30.  
  31. // remove headers from sections past the first one
  32. jQuery('ytd-item-section-renderer:not(:nth-child(1))').css('border', 'none');
  33. jQuery('ytd-item-section-renderer:not(:nth-child(1)) .grid-subheader').css('display', 'none');
  34. jQuery('ytd-item-section-renderer:not(:nth-child(1)) #contents.ytd-shelf-renderer').css('margin-top', 0);
  35. };
  36.  
  37. const handleButtonPresence = () => {
  38. if (shouldRender()) {
  39. const buttonContainerElement = jQuery(`
  40. [page-subtype="channels"] ytd-rich-grid-renderer,
  41. [page-subtype="subscriptions"] ytd-section-list-renderer,
  42. ytd-search ytd-section-list-renderer
  43. `).first();
  44. if (buttonContainerElement.length && !buttonContainerElement.find(buttonElement).length) {
  45. buttonElement.off('click').on('click', hideWatchedVideos);
  46. buttonContainerElement.prepend(buttonElement);
  47. }
  48. } else {
  49. buttonElement.remove();
  50. }
  51. };
  52.  
  53. const initialize = () => {
  54. buttonElement = buttonElement = jQuery(`
  55. <tp-yt-paper-button class="style-scope ytd-subscribe-button-renderer mt-hide-watched-button">
  56. Hide Watched
  57. </tp-yt-paper-button>
  58. `);
  59.  
  60. /*const observer = new MutationObserver(handleButtonPresence);
  61. observer.observe(document.body, { childList: true, subtree: true });
  62.  
  63. handleButtonPresence();*/
  64.  
  65. jQuery('head').append(`
  66. <style>
  67. .mt-hide-watched-button {
  68. border-radius: 8px !important;
  69. width: 100%;
  70. }
  71.  
  72. [page-subtype="channels"] .mt-hide-watched-button,
  73. [page-subtype="subscriptions"] .mt-hide-watched-button {
  74. margin-top: 24px;
  75. }
  76.  
  77. .ytd-search ytd-section-list-renderer .mt-hide-watched-button {
  78. margin: 12px 0;
  79. }
  80. </style>
  81. `);
  82.  
  83. setInterval(handleButtonPresence, 150);
  84. }
  85.  
  86. initialize();
  87.  
  88. const videosSelector = 'ytd-grid-video-renderer, ytd-video-renderer, ytd-rich-item-renderer';
  89. const urlPattern = /youtube.com\/((channel\/|c\/|@)(.*)\/videos|feed\/subscriptions|results)/;
  90. })();