Remove Chat from Streamed.su

Removes the live chat and "Enter theater mode" button from streamed.su streaming pages, centering the video content

  1. // ==UserScript==
  2. // @name Remove Chat from Streamed.su
  3. // @namespace https://x.com/officebeats
  4. // @version 0.12
  5. // @description Removes the live chat and "Enter theater mode" button from streamed.su streaming pages, centering the video content
  6. // @author oB3ATS
  7. // @match https://streamed.su/*
  8. // @grant none
  9. // @run-at document-end
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. console.log('Remove Chat from Streamed.su v0.12 started on', window.location.href);
  17.  
  18. // Inject CSS to center the video and stream links
  19. function injectCSS() {
  20. const style = document.createElement('style');
  21. style.textContent = `
  22. /* Center the flex container after chat removal */
  23. .w-full.h-screen.flex {
  24. justify-content: center;
  25. }
  26. /* Ensure video container stays responsive and centered */
  27. .md\\:w-3\\/4.transition-transform {
  28. width: auto;
  29. max-width: 75%;
  30. margin: 0 auto;
  31. }
  32. /* Center the iframe within its container */
  33. iframe.w-full.h-fit.aspect-video {
  34. display: block;
  35. margin: 0 auto;
  36. }
  37. `;
  38. document.head.appendChild(style);
  39. console.log('CSS injected to center video and stream links');
  40. }
  41.  
  42. // Function to remove chat elements
  43. function removeChat() {
  44. let chatElement = document.querySelector('div[class="md:w-1/4 h-full flex flex-col gap-2 transition-all translate-x-0"]');
  45. if (chatElement) {
  46. console.log('Found chat with exact class match:', chatElement);
  47. chatElement.remove();
  48. return true;
  49. }
  50.  
  51. chatElement = document.querySelector('div[class*="md:w-1/4"][class*="h-full"][class*="flex"]');
  52. if (chatElement) {
  53. console.log('Found chat with partial class match:', chatElement);
  54. chatElement.remove();
  55. return true;
  56. }
  57.  
  58. console.log('Chat not found at this time');
  59. return false;
  60. }
  61.  
  62. // Function to remove "Enter theater mode" button
  63. function removeTheaterModeButton() {
  64. let button = document.querySelector('button.ring-offset-background.inline-flex.w-full.mt-2');
  65. if (button && button.textContent.trim() === 'Enter theater mode') {
  66. console.log('Found "Enter theater mode" button:', button);
  67. button.remove(); // Remove only the button, not the parent div
  68. return true;
  69. }
  70.  
  71. console.log('Theater mode button not found at this time');
  72. return false;
  73. }
  74.  
  75. // Delayed execution to avoid SvelteKit rendering conflicts
  76. setTimeout(() => {
  77. // Inject CSS first
  78. injectCSS();
  79.  
  80. // Initial removal attempts
  81. let chatRemoved = removeChat();
  82. let buttonRemoved = removeTheaterModeButton();
  83. if (chatRemoved) console.log('Chat removed immediately');
  84. else console.log('Chat not found initially');
  85. if (buttonRemoved) console.log('Theater mode button removed immediately');
  86. else console.log('Theater mode button not found initially, setting up observer');
  87.  
  88. // Persistent MutationObserver to catch dynamic additions
  89. const observer = new MutationObserver((mutations) => {
  90. mutations.forEach((mutation) => {
  91. if (mutation.addedNodes.length) {
  92. console.log('DOM nodes added, checking for elements');
  93. if (removeChat()) console.log('Chat removed after DOM update');
  94. if (removeTheaterModeButton()) console.log('Theater mode button removed after DOM update');
  95. }
  96. });
  97. });
  98.  
  99. observer.observe(document.documentElement || document.body, {
  100. childList: true,
  101. subtree: true
  102. });
  103.  
  104. // Fallback interval check
  105. const checkInterval = setInterval(() => {
  106. let chatSuccess = removeChat();
  107. let buttonSuccess = removeTheaterModeButton();
  108. if (chatSuccess && buttonSuccess) {
  109. clearInterval(checkInterval);
  110. console.log('Both chat and theater mode button removed, stopping checks');
  111. }
  112. }, 1000);
  113.  
  114. window.addEventListener('unload', () => {
  115. observer.disconnect();
  116. clearInterval(checkInterval);
  117. console.log('Script cleanup on page unload');
  118. });
  119. }, 1000); // 1-second delay to allow SvelteKit rendering
  120.  
  121. // Log errors for debugging
  122. window.addEventListener('error', (e) => {
  123. console.log('Page error detected:', e.message);
  124. });
  125. })();