Youtube Interface Modification

將聊天室與直播位置切換

  1. // ==UserScript==
  2. // @name Youtube Interface Modification
  3. // @namespace https://github.com/RutsuLun
  4. // @version 1.7
  5. // @description 將聊天室與直播位置切換
  6. // @author Rutsu Lun
  7. // @match https://www.youtube.com/*
  8. // @icon https://www.google.com/s2/favicons?domain=youtube.com
  9. // @license Only Share
  10. // @grant GM.registerMenuCommand
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. GM.registerMenuCommand('呼叫', Lun_createBtnList);
  15. GM.registerMenuCommand('介面', Lun_loayoutSwitch);
  16. GM.registerMenuCommand('emoji調整', Lun_removeEmojiTag);
  17. GM.registerMenuCommand('移除愛心', hideShitHard);
  18. // GM.registerMenuCommand('表符', Lun_emojiMenuChenge);
  19. })();
  20.  
  21. const btnListSetting = [
  22. { id: 'Lun_loayoutSwitch', name: '介面', method: Lun_loayoutSwitch, },
  23. { id: 'Lun_emojiMenuChenge', name: '表符', method: Lun_removeEmojiTag, },
  24. { id: 'Lun_emojiMenuChenge', name: '移除愛心', method: hideShitHard, },
  25. ]
  26. const btnListCss = 'position: absolute;top: 0;left: 0;'
  27.  
  28. function Lun_loayoutSwitch() {
  29. document.getElementById('columns').style.cssText == '' ? document.getElementById('columns').style.cssText = 'flex-direction: row-reverse;' : document.getElementById('columns').style.cssText = '';
  30. document.querySelector('ytd-player').style.cssText += 'border-radius: 0;'
  31. }
  32.  
  33. function Lun_removeEmojiTag() {
  34. const iframe = document.getElementById('chatframe');
  35. if (iframe.contentDocument) {
  36. var iframeDocument = iframe.contentDocument;
  37. var category = iframeDocument.getElementById('category-buttons');
  38. var search = iframeDocument.getElementById('search-panel');
  39. var emoji = iframeDocument.querySelector('yt-emoji-picker-renderer');
  40. category.style.cssText += 'display:none;'
  41. search.style.cssText += 'display:none;'
  42. emoji.style.cssText += 'margin: -5px -24px !important'
  43. }
  44. }
  45.  
  46. function Lun_emojiMenuChenge() {
  47. const iframe = document.getElementById('chatframe');
  48. if (iframe.contentDocument) {
  49. var iframeDocument = iframe.contentDocument;
  50. var targetElement = iframeDocument.querySelector('yt-emoji-picker-renderer[floating-emoji-picker]');
  51. targetElement.style.cssText = 'min-height: 400px';
  52. }
  53. }
  54.  
  55. function hideShitHard() {
  56. const iframe = document.getElementById('chatframe');
  57. if (iframe.contentDocument) {
  58. var iframeDocument = iframe.contentDocument;
  59. var targetElement = iframeDocument.querySelector('#reaction-control-panel');
  60. targetElement.style.cssText = 'display:none;'
  61. }
  62. }
  63.  
  64. function Lun_createBtnList() {
  65. const chat = document.getElementById('secondary');
  66. if (chat && document.querySelector('Lun_btnList') == null) {
  67. const btnList = document.createElement('span');
  68. btnList.id = 'Lun_btnList';
  69. btnList.style = btnListCss;
  70. chat.append(btnList);
  71. btnListSetting.forEach(b => {
  72. let btn = document.createElement('button');
  73. btn.id = b.id;
  74. btn.innerText = b.name;
  75. btnList.append(btn);
  76. btn.addEventListener('click', b.method);
  77. });
  78. }
  79. }
  80.  
  81. const main = function () {
  82. // Lun_emojiMenuChenge();
  83. console.log('載入完畢');
  84. Lun_createBtnList();
  85. }
  86.  
  87. const injectScript = function (frameWindow) {
  88. main()
  89. }
  90.  
  91. const retrieveChatFrameWindow = function () {
  92. if (window.location.pathname === "/live_chat" || window.location.pathname === "/live_chat_replay") return window;
  93. for (let i = 0; i < window.frames.length; i++) {
  94. try {
  95. if (window.frames[i].location) {
  96. let pathname = window.frames[i].location.pathname;
  97. if (pathname === "/live_chat" || pathname === "/live_chat_replay") return frames[i];
  98. }
  99. } catch (ex) { }
  100. }
  101. }
  102.  
  103. const tryBrowserIndependentExecution = function () {
  104. let destinationFrameWindow = retrieveChatFrameWindow();
  105. if (!destinationFrameWindow || !destinationFrameWindow.document || destinationFrameWindow.document.readyState != "complete") {
  106. setTimeout(tryBrowserIndependentExecution, 1000);
  107. return;
  108. }
  109. if (destinationFrameWindow.channelResolverInitialized) return;
  110. injectScript(destinationFrameWindow);
  111. destinationFrameWindow.channelResolverInitialized = true;
  112. }
  113.  
  114. const getPopup = () => {
  115. let pop = document.querySelector('ytd-popup-container')
  116. if (pop == null) {
  117. setTimeout(getPopup, 1000);
  118. console.log(pop)
  119. } else {
  120. pop.remove();
  121. }
  122. }
  123.  
  124. if (ytInitialPlayerResponse.videoDetails.isLiveContent) {
  125. console.log('直播')
  126. tryBrowserIndependentExecution();
  127. } else {
  128. console.log('正常影片')
  129. }