YouTube Classic Live Chat Position

Bring back old layout of YouTube Live Chat

< 脚本 YouTube Classic Live Chat Position 的反馈

评价:好评 - 脚本运行良好

§
发布于:2025-10-31
编辑于:2025-10-31

Is this working in Theater mode or am I tripping? I swear it was working for a second and then BAM out of nowhere I cannot for the life of me get it to work no matter what I do, so weird. I reinstalled it disabled all other youtube extensions as well.

§
发布于:2025-10-31
编辑于:2025-10-31

Is this working in Theater mode or am I tripping? I swear it was working for a second and then BAM out of nowhere I cannot for the life of me get it to work no matter what I do, so weird. I reinstalled it disabled all other youtube extensions as well.

Okay I may have fixed it myself with deepseek, no clue why but maybe you can test if this one works vs your old version:


// ==UserScript==
// @name YouTube Classic Live Chat Position
// @namespace https://github.com/Amadeus-AI
// @description Bring back old layout of YouTube Live Chat with proper video sizing
// @icon https://www.youtube.com/s/desktop/3748dff5/img/favicon_48.png
// @version 1.0.1
// @author AmadeusAI
// @match *://*.youtube.com/*
// @run-at document-start
// @grant none
// @license MIT
// ==/UserScript==

(function() {
'use strict';

const CONFIG = {
maxTries: 30,
intervalTime: 150,
chatWidth: 400
};

// Optimized CSS for classic layout
const injectCSS = () => {
if (document.querySelector('#yt-classic-chat-css')) return;

const style = document.createElement('style');
style.id = 'yt-classic-chat-css';
style.textContent = `
/* Classic chat layout with proper video sizing */
ytd-watch-flexy[theater] #secondary.ytd-watch-flexy {
width: ${CONFIG.chatWidth}px !important;
min-width: ${CONFIG.chatWidth}px !important;
}

ytd-watch-flexy[theater] #primary.ytd-watch-flexy {
width: calc(100% - ${CONFIG.chatWidth}px) !important;
}

/* Chat container styling */
ytd-watch-flexy[theater] #chat-container,
ytd-watch-flexy[theater] ytd-live-chat-frame,
ytd-watch-flexy[theater] [role="complementary"] {
width: 100% !important;
max-width: none !important;
height: 100% !important;
}

/* Prevent modern YouTube layout interference */
ytd-watch-flexy[theater] #secondary-inner {
width: 100% !important;
max-width: none !important;
}

/* Video player container sizing */
ytd-watch-flexy[theater] #primary-inner {
width: 100% !important;
}

/* Ensure video scales correctly */
ytd-watch-flexy[theater] #player-wide-container {
width: 100% !important;
}
`;
document.head.appendChild(style);
};

// Optimized flag modification
const modifyFlags = () => {
const flagModifications = {
'web_watch_enable_fs_squeezeback_panels': false,
'web_watch_theater_chat': false,
'web_watch_theater_fixed_chat': false,
'web_watch_enable_single_column_grid_view': false,
'web_watch_flexy_comments_manager': false,
'web_watch_flexy_playlist_manager': false,
'web_modern_chat_restore': false
};

// Method 1: ytcfg (modern YouTube)
if (window.ytcfg?.get && window.ytcfg.set) {
try {
const flags = window.ytcfg.get('EXPERIMENT_FLAGS');
if (flags && typeof flags === 'object') {
Object.assign(flags, flagModifications);
return true;
}
} catch (e) {
// Silent fail for performance
}
}

// Method 2: yt.config_ (legacy support)
if (window.yt?.config_?.EXPERIMENT_FLAGS) {
Object.assign(window.yt.config_.EXPERIMENT_FLAGS, flagModifications);
return true;
}

return false;
};

// DOM manipulation for chat positioning
const fixChatPosition = () => {
const chatSelectors = [
'#chat-container',
'ytd-live-chat-frame',
'[role="complementary"]',
'#secondary-inner ytd-live-chat-frame'
];

for (const selector of chatSelectors) {
const element = document.querySelector(selector);
if (element) {
// Ensure proper containment
const secondaryInner = element.closest('#secondary-inner');
if (secondaryInner) {
secondaryInner.style.minWidth = `${CONFIG.chatWidth}px`;
secondaryInner.style.width = '100%';
}
break; // Only process first found element
}
}
};

// Main initialization function
const initialize = () => {
injectCSS();

if (modifyFlags()) {
fixChatPosition();
return true;
}

return false;
};

// Optimized initialization with limited retries
let tries = 0;
const initInterval = setInterval(() => {
if (initialize() || ++tries >= CONFIG.maxTries) {
clearInterval(initInterval);
}
}, CONFIG.intervalTime);

// SPA navigation handler (debounced)
let navTimeout;
let lastUrl = location.href;
new MutationObserver(() => {
const url = location.href;
if (url !== lastUrl) {
lastUrl = url;
clearTimeout(navTimeout);
navTimeout = setTimeout(() => {
tries = 0;
const navInterval = setInterval(() => {
if (initialize() || ++tries >= CONFIG.maxTries / 2) {
clearInterval(navInterval);
}
}, CONFIG.intervalTime);
}, 500); // Debounce to avoid excessive processing
}
}).observe(document, { subtree: true, childList: true });

// Listen for theater mode changes
new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.type === 'attributes' && mutation.attributeName === 'theater') {
setTimeout(initialize, 100);
break;
}
}
}).observe(document.documentElement, {
attributes: true,
attributeFilter: ['theater'],
subtree: true
});

})();

发布留言

登录以发布留言。