YouTube - "Hide watched videos" button

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

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

  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.22.18.26
  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('[page-subtype="subscriptions"] ytd-section-list-renderer, [page-subtype="channels"] ytd-rich-grid-renderer, .ytd-search ytd-section-list-renderer').first();
  40. if (buttonContainerElement.length && !buttonContainerElement.find(buttonElement).length) {
  41. buttonElement.off('click').on('click', hideWatchedVideos);
  42. buttonContainerElement.prepend(buttonElement);
  43. }
  44. } else {
  45. buttonElement.remove();
  46. }
  47. };
  48.  
  49. const initialize = () => {
  50. buttonElement = buttonElement = jQuery(`
  51. <tp-yt-paper-button class="style-scope ytd-subscribe-button-renderer mt-hide-watched-button">
  52. Hide Watched
  53. </tp-yt-paper-button>
  54. `);
  55.  
  56. /*const observer = new MutationObserver(handleButtonPresence);
  57. observer.observe(document.body, { childList: true, subtree: true });
  58.  
  59. handleButtonPresence();*/
  60.  
  61. jQuery('head').append(`
  62. <style>
  63. .mt-hide-watched-button {
  64. border-radius: 8px !important;
  65. width: 100%;
  66. }
  67.  
  68. [page-subtype="channels"] .mt-hide-watched-button {
  69. margin-top: 24px;
  70. }
  71.  
  72. .ytd-search ytd-section-list-renderer .mt-hide-watched-button {
  73. margin: 12px 0;
  74. }
  75. </style>
  76. `);
  77.  
  78. setInterval(handleButtonPresence, 150);
  79. }
  80.  
  81. initialize();
  82.  
  83. const videosSelector = 'ytd-grid-video-renderer, ytd-video-renderer, ytd-rich-item-renderer';
  84. const urlPattern = /youtube.com\/((channel|c)\/(.*)\/videos|feed\/subscriptions|results)/;
  85. })();