YouTube Comments Toggle Button

Add a toggle button for YouTube comments with a comments icon.

  1. // ==UserScript==
  2. // @name YouTube Comments Toggle Button
  3. // @namespace https://example.com/youtube-comments-toggle
  4. // @version 1.5
  5. // @description Add a toggle button for YouTube comments with a comments icon.
  6. // @match *://*.youtube.com/*
  7. // @match *://m.youtube.com/*
  8. // @license MIT
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. const commentsSelector = 'ytm-single-column-watch-next-results-renderer .single-column-watch-next-modern-panels ytm-comments-entry-point-header-renderer.modern-styling';
  16. var trytohide = true;
  17. function toggleComments() {
  18. const comments = document.querySelector(commentsSelector);
  19. if (comments) {
  20. const isHidden = comments.style.display === 'none';
  21. comments.style.display = isHidden ? '' : 'none';
  22. console.log(`Comments are now ${isHidden ? 'visible' : 'hidden'}.`);
  23. if (isHidden) {
  24. document.querySelector('#toggleButton1').style.backgroundColor = '#f2f1f0';
  25. document.querySelector('#toggleButton1').style.color = 'black';
  26. } else {
  27. document.querySelector('#toggleButton1').style.backgroundColor = 'black';
  28. document.querySelector('#toggleButton1').style.color = '#f2f1f0';
  29. }
  30. }
  31. }
  32.  
  33. const htmlPolicy = window.trustedTypes?.createPolicy('default', {
  34. createHTML: (html) => html,
  35. });
  36.  
  37. function addButtonToInterface() {
  38. if (document.querySelector('#comments-toggle-button')) return;
  39.  
  40. const buttonViewModel = document.createElement('button-view-model');
  41. buttonViewModel.id = 'comments-toggle-button';
  42. buttonViewModel.className = 'yt-spec-button-view-model slim_video_action_bar_renderer_button';
  43.  
  44. const buttonHTML = `
  45. <yt-button-shape class="yt-spec-button-shape-next__button-shape-wiz-class" >
  46. <button class="yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-leading" id='toggleButton1'>
  47. <div class="yt-spec-button-shape-next__icon">
  48. <c3-icon style="width: 24px; height: 24px;">
  49. <span class="yt-icon-shape yt-spec-icon-shape">
  50. <div style="width: 100%; height: 100%; display: block; fill: currentcolor; padding:3px">
  51. <!-- Comments Icon SVG -->
  52. <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 121.86 122.88" width="20" height="20">
  53. <title>comment</title>
  54. <path d="M30.28,110.09,49.37,91.78A3.84,3.84,0,0,1,52,90.72h60a2.15,2.15,0,0,0,2.16-2.16V9.82a2.16,2.16,0,0,0-.64-1.52A2.19,2.19,0,0,0,112,7.66H9.82A2.24,2.24,0,0,0,7.65,9.82V88.55a2.19,2.19,0,0,0,2.17,2.16H26.46a3.83,3.83,0,0,1,3.82,3.83v15.55ZM28.45,63.56a3.83,3.83,0,1,1,0-7.66h53a3.83,3.83,0,0,1,0,7.66Zm0-24.86a3.83,3.83,0,1,1,0-7.65h65a3.83,3.83,0,0,1,0,7.65ZM53.54,98.36,29.27,121.64a3.82,3.82,0,0,1-6.64-2.59V98.36H9.82A9.87,9.87,0,0,1,0,88.55V9.82A9.9,9.9,0,0,1,9.82,0H112a9.87,9.87,0,0,1,9.82,9.82V88.55A9.85,9.85,0,0,1,112,98.36Z"/>
  55. </svg>
  56. </div>
  57. </span>
  58. </c3-icon>
  59. </div>
  60. <div class="yt-spec-button-shape-next__button-text-content">Comments</div>
  61. <yt-touch-feedback-shape>
  62. <div class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response">
  63. <div class="yt-spec-touch-feedback-shape__stroke"></div>
  64. <div class="yt-spec-touch-feedback-shape__fill"></div>
  65. </div>
  66. </yt-touch-feedback-shape>
  67. </button>
  68. </yt-button-shape>
  69. `;
  70.  
  71. buttonViewModel.innerHTML = htmlPolicy ? htmlPolicy.createHTML(buttonHTML) : buttonHTML;
  72.  
  73. buttonViewModel.addEventListener('click', toggleComments);
  74.  
  75. const targetContainer = document.querySelector('.slim-video-action-bar-actions');
  76. if (targetContainer) {
  77. const firstButton = targetContainer.children[0];
  78. if (firstButton) {
  79. targetContainer.insertBefore(buttonViewModel, firstButton.nextSibling);
  80. } else {
  81. targetContainer.appendChild(buttonViewModel);
  82. }
  83. console.log('Toggle button added as the second button.');
  84. } else {
  85. console.warn('Target container not found.');
  86. }
  87. }
  88.  
  89. const observer = new MutationObserver(() => {
  90. addButtonToInterface();
  91. const comments = document.querySelector(commentsSelector);
  92. comments.style.display = 'none';
  93. });
  94.  
  95. observer.observe(document.body, { childList: true, subtree: true });
  96. setTimeout(()=>{trytohide = false}, 8000)
  97. addButtonToInterface();
  98. })();