diff --git a/src/i18n/resources/en.json b/src/i18n/resources/en.json index f0a120f3..8db7a7fc 100644 --- a/src/i18n/resources/en.json +++ b/src/i18n/resources/en.json @@ -212,7 +212,15 @@ }, "album-color-theme": { "description": "Applies a dynamic theme and visual effects based on the album color palette", - "name": "Album Color Theme" + "name": "Album Color Theme", + "menu": { + "color-mix-ratio": { + "label": "Color mix ratio", + "submenu": { + "percent": "{{ratio}}%" + } + } + } }, "ambient-mode": { "description": "Applies a lighting effect by casting gentle colors from the video, into your screen’s background", diff --git a/src/plugins/album-color-theme/index.ts b/src/plugins/album-color-theme/index.ts index 4921a228..ce02f5f7 100644 --- a/src/plugins/album-color-theme/index.ts +++ b/src/plugins/album-color-theme/index.ts @@ -8,6 +8,7 @@ import { t } from '@/i18n'; const COLOR_KEY = '--ytmusic-album-color'; const DARK_COLOR_KEY = '--ytmusic-album-color-dark'; +const RATIO_KEY = '--ytmusic-album-color-ratio'; export default createPlugin< unknown, @@ -24,17 +25,46 @@ export default createPlugin< sidebarSmall: HTMLElement | null; ytmusicAppLayout: HTMLElement | null; - getColor(key: string, alpha?: number): string; + getMixedColor(color: string, key: string, alpha?: number, ratioMultiply?: number): string; updateColor(): void; + }, + { + enabled: boolean; + ratio: number; } >({ name: () => t('plugins.album-color-theme.name'), description: () => t('plugins.album-color-theme.description'), - restartNeeded: true, + restartNeeded: false, config: { enabled: false, + ratio: 0.5, }, stylesheets: [style], + menu: async ({ getConfig, setConfig }) => { + const ratioList = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]; + + const config = await getConfig(); + + return [ + { + label: t('plugins.album-color-theme.menu.color-mix-ratio.label'), + submenu: ratioList.map((ratio) => ({ + label: t( + 'plugins.album-color-theme.menu.color-mix-ratio.submenu.percent', + { + ratio: ratio * 100, + }, + ), + type: 'radio', + checked: config.ratio === ratio, + click() { + setConfig({ ratio }); + }, + })), + }, + ]; + }, renderer: { playerPage: null, navBarBackground: null, @@ -44,7 +74,7 @@ export default createPlugin< sidebarSmall: null, ytmusicAppLayout: null, - start() { + async start({ getConfig }) { this.playerPage = document.querySelector('#player-page'); this.navBarBackground = document.querySelector( '#nav-bar-background', @@ -59,6 +89,9 @@ export default createPlugin< '#mini-guide-background', ); this.ytmusicAppLayout = document.querySelector('#layout'); + + const config = await getConfig(); + document.documentElement.style.setProperty(RATIO_KEY, `${~~(config.ratio * 100)}%`); }, onPlayerApiReady(playerApi) { const fastAverageColor = new FastAverageColor(); @@ -97,28 +130,62 @@ export default createPlugin< this.updateColor(); }); }, - getColor(key: string, alpha = 1) { - return `rgba(var(${key}), ${alpha})`; + onConfigChange(config) { + document.documentElement.style.setProperty(RATIO_KEY, `${~~(config.ratio * 100)}%`); + }, + getMixedColor(color: string, key: string, alpha = 1, ratioMultiply) { + const keyColor = `rgba(var(${key}), ${alpha})`; + + let colorRatio = `var(${RATIO_KEY}, 50%)`; + let originalRatio = `calc(100% - var(${RATIO_KEY}, 50%))`; + if (ratioMultiply) { + colorRatio = `calc(var(${RATIO_KEY}, 50%) * ${ratioMultiply})`; + originalRatio = `calc(100% - calc(var(${RATIO_KEY}, 50%) * ${ratioMultiply}))`; + } + return `color-mix(in srgb, ${color} ${originalRatio}, ${keyColor} ${colorRatio})`; }, updateColor() { - const change = (element: HTMLElement | null, color: string) => { - if (element) { - element.style.backgroundColor = color; - } + const variableMap = { + '--ytmusic-color-black1': '#212121', + '--ytmusic-color-black2': '#181818', + '--ytmusic-color-black3': '#030303', + '--ytmusic-color-black4': '#030303', + '--ytmusic-color-blackpure': '#000', + '--dark-theme-background-color': '#212121', + '--yt-spec-base-background': '#0f0f0f', + '--yt-spec-raised-background': '#212121', + '--yt-spec-menu-background': '#282828', + '--yt-spec-static-brand-black': '#212121', + '--yt-spec-static-overlay-background-solid': '#000', + '--yt-spec-static-overlay-background-heavy': 'rgba(0,0,0,0.8)', + '--yt-spec-static-overlay-background-medium': 'rgba(0,0,0,0.6)', + '--yt-spec-static-overlay-background-medium-light': 'rgba(0,0,0,0.3)', + '--yt-spec-static-overlay-background-light': 'rgba(0,0,0,0.1)', + '--yt-spec-general-background-a': '#181818', + '--yt-spec-general-background-b': '#0f0f0f', + '--yt-spec-general-background-c': '#030303', + '--yt-spec-snackbar-background': '#030303', + '--yt-spec-filled-button-text': '#030303', + '--yt-spec-black-1': '#282828', + '--yt-spec-black-2': '#1f1f1f', + '--yt-spec-black-3': '#161616', + '--yt-spec-black-4': '#0d0d0d', + '--yt-spec-black-pure': '#000', + '--yt-spec-black-pure-alpha-5': 'rgba(0,0,0,0.05)', + '--yt-spec-black-pure-alpha-10': 'rgba(0,0,0,0.1)', + '--yt-spec-black-pure-alpha-15': 'rgba(0,0,0,0.15)', + '--yt-spec-black-pure-alpha-30': 'rgba(0,0,0,0.3)', + '--yt-spec-black-pure-alpha-60': 'rgba(0,0,0,0.6)', + '--yt-spec-black-pure-alpha-80': 'rgba(0,0,0,0.8)', + '--yt-spec-black-1-alpha-98': 'rgba(40,40,40,0.98)', + '--yt-spec-black-1-alpha-95': 'rgba(40,40,40,0.95)', }; + Object.entries(variableMap).map(([variable, color]) => { + document.documentElement.style.setProperty(variable, this.getMixedColor(color, COLOR_KEY), 'important'); + }); - change(this.playerPage, this.getColor(DARK_COLOR_KEY)); - change(this.navBarBackground, this.getColor(COLOR_KEY)); - change(this.ytmusicPlayerBar, this.getColor(COLOR_KEY)); - change(this.playerBarBackground, this.getColor(COLOR_KEY)); - change(this.sidebarBig, this.getColor(COLOR_KEY)); - - if (this.ytmusicAppLayout?.hasAttribute('player-page-open')) { - change(this.sidebarSmall, this.getColor(DARK_COLOR_KEY)); - } - - const ytRightClickList = document.querySelector('tp-yt-paper-listbox'); - change(ytRightClickList, this.getColor(COLOR_KEY)); + document.body.style.setProperty('background', this.getMixedColor('#030303', COLOR_KEY), 'important'); + document.documentElement.style.setProperty('--ytmusic-background', this.getMixedColor('#030303', DARK_COLOR_KEY), 'important'); }, }, }); diff --git a/src/plugins/album-color-theme/style.css b/src/plugins/album-color-theme/style.css index 0c19951f..59ced5a6 100644 --- a/src/plugins/album-color-theme/style.css +++ b/src/plugins/album-color-theme/style.css @@ -65,3 +65,17 @@ ytmusic-player-bar { .volume-slider.ytmusic-player-bar, .expand-volume-slider.ytmusic-player-bar { --paper-slider-container-color: rgba(255, 255, 255, 0.5) !important; } + +/* fix background image */ +ytmusic-fullbleed-thumbnail-renderer img { + mask: linear-gradient(to bottom, #000 0%, #000 50%, transparent 100%); +} +.background-gradient.style-scope { + background: var(--ytmusic-background) !important; +} +ytmusic-browse-response[has-background]:not([disable-gradient]) .background-gradient.ytmusic-browse-response { + background: unset !important; +} +#background.immersive-background.style-scope.ytmusic-browse-response { + opacity: 0.6; +} diff --git a/src/plugins/blur-nav-bar/style.css b/src/plugins/blur-nav-bar/style.css index 22f32a13..5bc199c5 100644 --- a/src/plugins/blur-nav-bar/style.css +++ b/src/plugins/blur-nav-bar/style.css @@ -1,10 +1,18 @@ #nav-bar-background, -#header.ytmusic-item-section-renderer, -ytmusic-tabs { +#header.ytmusic-item-section-renderer { background: rgba(0, 0, 0, 0.3) !important; backdrop-filter: blur(8px) !important; } +ytmusic-tabs { + top: calc(var(--ytmusic-nav-bar-height) + var(--menu-bar-height, 36px)); + backdrop-filter: blur(8px) !important; +} + +ytmusic-tabs.stuck { + background: rgba(0, 0, 0, 0.3) !important; +} + #nav-bar-divider { display: none !important; } diff --git a/src/plugins/in-app-menu/titlebar.css b/src/plugins/in-app-menu/titlebar.css index fb54346e..56e8d514 100644 --- a/src/plugins/in-app-menu/titlebar.css +++ b/src/plugins/in-app-menu/titlebar.css @@ -1,5 +1,5 @@ :root { - --titlebar-background-color: #030303; + --titlebar-background-color: var(--ytmusic-color-black3); --menu-bar-height: 32px; }