From 50cf64ceac8486621f6d414c8e1849500182258d Mon Sep 17 00:00:00 2001 From: XangelMusic Date: Mon, 26 Jan 2026 04:04:38 +0800 Subject: [PATCH 1/3] fix: Moved HyperChat Settings button to YouTube Chat menu --- src/assets/outline.svg | 18 +++++++++ src/components/HyperchatButton.svelte | 21 +--------- src/components/SettingsButton.svelte | 57 +++++++++++++++++++++++++++ src/scripts/chat-injector.ts | 21 +++++++++- src/vite-env.d.ts | 6 +++ 5 files changed, 101 insertions(+), 22 deletions(-) create mode 100644 src/assets/outline.svg create mode 100644 src/components/SettingsButton.svelte create mode 100644 src/vite-env.d.ts diff --git a/src/assets/outline.svg b/src/assets/outline.svg new file mode 100644 index 00000000..2ccc0a80 --- /dev/null +++ b/src/assets/outline.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/components/HyperchatButton.svelte b/src/components/HyperchatButton.svelte index 669da916..e4eb7334 100644 --- a/src/components/HyperchatButton.svelte +++ b/src/components/HyperchatButton.svelte @@ -1,8 +1,7 @@ + +
+
+
+ {@html outline} +
+
+
HyperChat Settings
+
+ + \ No newline at end of file diff --git a/src/scripts/chat-injector.ts b/src/scripts/chat-injector.ts index d7b38259..b713d57a 100644 --- a/src/scripts/chat-injector.ts +++ b/src/scripts/chat-injector.ts @@ -1,4 +1,5 @@ import HcButton from '../components/HyperchatButton.svelte'; +import HcSettings from '../components/SettingsButton.svelte'; import { getFrameInfoAsync, isValidFrameInfo, frameIsReplay, checkInjected } from '../ts/chat-utils'; import { isLiveTL } from '../ts/chat-constants'; import { hcEnabled, autoLiveChat } from '../ts/storage'; @@ -23,11 +24,27 @@ const chatLoaded = async (): Promise => { console.error('Failed to find #primary-content'); return; } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const hcButton = new HcButton({ + new HcButton({ target: ytcPrimaryContent }); + // Inject HC settings + const injectSettings = (): void => { + // Prevent duplicates + if (document.getElementById('hc-settings')) return; + const ytcItemMenu = document.querySelector('tp-yt-paper-listbox#items'); + if (!ytcItemMenu) return; + + new HcSettings({ + target: ytcItemMenu + }); + }; + + new MutationObserver(injectSettings).observe(document.body, { + childList: true, + subtree: true + }); + // Everything past this point will only run if HC is enabled if (!hyperChatEnabled) return; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 00000000..79ebb242 --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1,6 @@ +/// + +declare module '*.svg?raw' { + const content: string; + export default content; +} From 07288948a792c228f162992212f648fd6b03981c Mon Sep 17 00:00:00 2001 From: XangelMusic Date: Tue, 27 Jan 2026 04:11:35 +0800 Subject: [PATCH 2/3] fix: destroy function set to Settings button --- src/components/SettingsButton.svelte | 22 +++++++++++++--- src/scripts/chat-injector.ts | 38 ++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/components/SettingsButton.svelte b/src/components/SettingsButton.svelte index 2bbc808c..46af98a7 100644 --- a/src/components/SettingsButton.svelte +++ b/src/components/SettingsButton.svelte @@ -2,10 +2,25 @@ import { createPopup } from '../ts/chat-utils'; import { isLiveTL } from '../ts/chat-constants'; import outline from '../assets/outline.svg?raw'; + import { onDestroy, onMount } from "svelte"; + + let instanceTracker = 0; const openSettings = () => { createPopup(chrome.runtime.getURL(`${isLiveTL ? 'hyperchat/' : ''}options.html${document.documentElement.getAttribute('dark') === '' ? '?dark' : ''}`)); }; + + const instanceLog = (n: number, state: string): void => { + console.log('[HyperChat] Settings button ' + state + '. Instances:', n) + } + + onMount(() => { + instanceLog(++instanceTracker, 'created'); + }); + + onDestroy(() => { + instanceLog(--instanceTracker, 'destroyed'); + });
@@ -25,10 +40,11 @@ padding: 0px 36px 0px 16px; cursor: pointer; min-height: 36px; + } - &:hover { - background-color: var(--yt-spec-10-percent-layer); - } + .button:hover { + background-color: var(--yt-spec-additive-background); + border-radius: 8px; } .button-label { diff --git a/src/scripts/chat-injector.ts b/src/scripts/chat-injector.ts index b713d57a..8c0b0cae 100644 --- a/src/scripts/chat-injector.ts +++ b/src/scripts/chat-injector.ts @@ -5,6 +5,7 @@ import { isLiveTL } from '../ts/chat-constants'; import { hcEnabled, autoLiveChat } from '../ts/storage'; // const isFirefox = navigator.userAgent.includes('Firefox'); +let hcSettings: HcSettings | null = null; const hcWarning = 'An existing HyperChat button has been detected. This ' + 'usually means both LiveTL and standalone HyperChat are enabled. ' + @@ -30,20 +31,37 @@ const chatLoaded = async (): Promise => { // Inject HC settings const injectSettings = (): void => { - // Prevent duplicates - if (document.getElementById('hc-settings')) return; + const destroyButton = (): void => { + if (hcSettings !== null) { + try { + hcSettings.$destroy(); + } catch (_) {} + } + } + const ytcItemMenu = document.querySelector('tp-yt-paper-listbox#items'); - if (!ytcItemMenu) return; + if (ytcItemMenu) { + // Prevent duplicates + if (document.getElementById('hc-settings')) return; - new HcSettings({ - target: ytcItemMenu - }); + destroyButton(); + hcSettings = new HcSettings({ + target: ytcItemMenu + }); + + return; + } + + destroyButton(); }; - new MutationObserver(injectSettings).observe(document.body, { - childList: true, - subtree: true - }); + const chatApp = document.querySelector('yt-live-chat-app'); + if (chatApp) { + new MutationObserver(injectSettings).observe(chatApp, { + childList: true, + subtree: true + }); + } // Everything past this point will only run if HC is enabled if (!hyperChatEnabled) return; From 5327616ce9198ee5a60c637a515c32571185e6b7 Mon Sep 17 00:00:00 2001 From: XangelMusic Date: Tue, 27 Jan 2026 13:24:44 +0800 Subject: [PATCH 3/3] fix: SettingsButton styles --- src/components/SettingsButton.svelte | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/components/SettingsButton.svelte b/src/components/SettingsButton.svelte index 46af98a7..610d2162 100644 --- a/src/components/SettingsButton.svelte +++ b/src/components/SettingsButton.svelte @@ -4,22 +4,16 @@ import outline from '../assets/outline.svg?raw'; import { onDestroy, onMount } from "svelte"; - let instanceTracker = 0; - const openSettings = () => { createPopup(chrome.runtime.getURL(`${isLiveTL ? 'hyperchat/' : ''}options.html${document.documentElement.getAttribute('dark') === '' ? '?dark' : ''}`)); }; - const instanceLog = (n: number, state: string): void => { - console.log('[HyperChat] Settings button ' + state + '. Instances:', n) - } - onMount(() => { - instanceLog(++instanceTracker, 'created'); + console.debug('[HyperChat] Settings button created'); }); onDestroy(() => { - instanceLog(--instanceTracker, 'destroyed'); + console.debug('[HyperChat] Settings button destroyed'); }); @@ -50,10 +44,10 @@ .button-label { color: var(--yt-spec-text-primary); white-space: nowrap; - font-family: sans-serif; + font-family: "Roboto", "Arial", sans-serif; font-size: 1.4rem; line-height: 2rem; - font-weight: 100; + font-weight: 400; -webkit-font-smoothing: var(--paper-font-subhead_-_-webkit-font-smoothing); } @@ -67,7 +61,8 @@ } .button-icon { - flex: none; + display: flex; + justify-content: center; fill: var(--yt-spec-text-primary); } \ No newline at end of file