Youtube Interface Modification

Youtube聊天室與直播位置切換

当前为 2024-01-15 提交的版本,查看 最新版本

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