mirror of
https://github.com/monochrome-music/monochrome.git
synced 2026-10-19 01:30:46 -05:00
feat(settings): add disable blur effects preference
Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
This commit is contained in:
1 parent
5588719727
commit
5b1e6ef9b2
6 files changed
+133
No files matched your search
+14
@@ -114,6 +114,10 @@
|
||||
<script>
|
||||
(() => {
|
||||
try {
|
||||
if (localStorage.getItem('disable-blur-effects') === 'true') {
|
||||
document.documentElement.classList.add('disable-blur-effects');
|
||||
}
|
||||
|
||||
const theme = localStorage.getItem('monochrome-theme');
|
||||
const css = localStorage.getItem('custom_theme_css');
|
||||
const palette = localStorage.getItem('monochrome-custom-theme');
|
||||
@@ -3211,6 +3215,16 @@
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Disable Blur Effects</span>
|
||||
<span class="description">Turn off visual blur effects throughout the app</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="disable-blur-effects-toggle" />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Dynamic Colors</span>
|
||||
|
||||
@@ -10,6 +10,17 @@ import {
|
||||
SVG_GLOBE,
|
||||
} from './icons.js';
|
||||
import { sidePanelManager } from './side-panel.js';
|
||||
import { disableBlurEffectsSettings } from './storage.js';
|
||||
|
||||
function applyBlurEffectsPreferenceToLyrics() {
|
||||
// am-lyrics renders its blur styles inside a shadow root.
|
||||
const disabled = disableBlurEffectsSettings.isEnabled();
|
||||
document.querySelectorAll('am-lyrics').forEach((element) => {
|
||||
element.toggleAttribute('no-blur', disabled);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('disable-blur-effects-changed', applyBlurEffectsPreferenceToLyrics);
|
||||
|
||||
const loadAmLyrics = () => {
|
||||
const images = Array.from(document.images).filter((img) => !img.complete);
|
||||
@@ -1213,6 +1224,7 @@ async function renderLyricsComponent(container, track, audioPlayer, lyricsManage
|
||||
amLyrics.setAttribute('hover-background-color', 'color-mix(in srgb, var(--primary) 16%, transparent)');
|
||||
amLyrics.setAttribute('autoscroll', '');
|
||||
amLyrics.setAttribute('interpolate', '');
|
||||
amLyrics.toggleAttribute('no-blur', disableBlurEffectsSettings.isEnabled());
|
||||
if (trackIsJapanese(track)) amLyrics.setAttribute('lang', 'ja');
|
||||
amLyrics.style.height = '100%';
|
||||
amLyrics.style.width = '100%';
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
fullscreenCoverClickSettings,
|
||||
lyricsSettings,
|
||||
backgroundSettings,
|
||||
disableBlurEffectsSettings,
|
||||
dynamicColorSettings,
|
||||
cardSettings,
|
||||
artistBannerSettings,
|
||||
@@ -5882,6 +5883,16 @@ export async function initializeSettings(scrobbler, player, api, ui) {
|
||||
});
|
||||
}
|
||||
|
||||
// Disable Blur Effects Toggle
|
||||
disableBlurEffectsSettings.apply();
|
||||
const disableBlurEffectsToggle = document.getElementById('disable-blur-effects-toggle');
|
||||
if (disableBlurEffectsToggle) {
|
||||
disableBlurEffectsToggle.checked = disableBlurEffectsSettings.isEnabled();
|
||||
disableBlurEffectsToggle.addEventListener('change', (e) => {
|
||||
disableBlurEffectsSettings.setEnabled(e.target.checked);
|
||||
});
|
||||
}
|
||||
|
||||
// Dynamic Color Toggle
|
||||
const dynamicColorToggle = document.getElementById('dynamic-color-toggle');
|
||||
if (dynamicColorToggle) {
|
||||
|
||||
@@ -564,6 +564,34 @@ export const backgroundSettings = {
|
||||
},
|
||||
};
|
||||
|
||||
export const disableBlurEffectsSettings = {
|
||||
STORAGE_KEY: 'disable-blur-effects',
|
||||
ROOT_CLASS: 'disable-blur-effects',
|
||||
|
||||
isEnabled() {
|
||||
try {
|
||||
return localStorage.getItem(this.STORAGE_KEY) === 'true';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
apply() {
|
||||
const enabled = this.isEnabled();
|
||||
const root = typeof document === 'undefined' ? null : document.documentElement;
|
||||
root?.classList.toggle(this.ROOT_CLASS, enabled);
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.dispatchEvent(new CustomEvent('disable-blur-effects-changed', { detail: { enabled } }));
|
||||
}
|
||||
},
|
||||
|
||||
setEnabled(enabled) {
|
||||
localStorage.setItem(this.STORAGE_KEY, enabled ? 'true' : 'false');
|
||||
this.apply();
|
||||
},
|
||||
};
|
||||
|
||||
export const dynamicColorSettings = {
|
||||
STORAGE_KEY: 'dynamic-color-enabled',
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
lastFMStorage,
|
||||
nowPlayingSettings,
|
||||
gaplessPlaybackSettings,
|
||||
disableBlurEffectsSettings,
|
||||
exponentialVolumeSettings,
|
||||
audioEffectsSettings,
|
||||
silenceRemovalSettings,
|
||||
@@ -15,6 +16,7 @@ import {
|
||||
describe('storage.js', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
document.documentElement.classList.remove(disableBlurEffectsSettings.ROOT_CLASS);
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
@@ -93,6 +95,41 @@ describe('storage.js', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('disableBlurEffectsSettings', () => {
|
||||
test('defaults to disabled and applies its persisted state to the document', () => {
|
||||
expect(disableBlurEffectsSettings.isEnabled()).toBe(false);
|
||||
expect(document.documentElement.classList.contains(disableBlurEffectsSettings.ROOT_CLASS)).toBe(false);
|
||||
|
||||
disableBlurEffectsSettings.setEnabled(true);
|
||||
expect(localStorage.getItem(disableBlurEffectsSettings.STORAGE_KEY)).toBe('true');
|
||||
expect(document.documentElement.classList.contains(disableBlurEffectsSettings.ROOT_CLASS)).toBe(true);
|
||||
|
||||
disableBlurEffectsSettings.setEnabled(false);
|
||||
expect(localStorage.getItem(disableBlurEffectsSettings.STORAGE_KEY)).toBe('false');
|
||||
expect(document.documentElement.classList.contains(disableBlurEffectsSettings.ROOT_CLASS)).toBe(false);
|
||||
});
|
||||
|
||||
test('restores the document class from a persisted preference', () => {
|
||||
localStorage.setItem(disableBlurEffectsSettings.STORAGE_KEY, 'true');
|
||||
disableBlurEffectsSettings.apply();
|
||||
|
||||
expect(document.documentElement.classList.contains(disableBlurEffectsSettings.ROOT_CLASS)).toBe(true);
|
||||
});
|
||||
|
||||
test('notifies blur consumers when the preference changes', () => {
|
||||
let detail;
|
||||
const onChange = (event) => {
|
||||
detail = event.detail;
|
||||
};
|
||||
window.addEventListener('disable-blur-effects-changed', onChange);
|
||||
|
||||
disableBlurEffectsSettings.setEnabled(true);
|
||||
|
||||
expect(detail).toEqual({ enabled: true });
|
||||
window.removeEventListener('disable-blur-effects-changed', onChange);
|
||||
});
|
||||
});
|
||||
|
||||
describe('silence removal and crossfade settings', () => {
|
||||
test('defaults to silence removal on and crossfade off', () => {
|
||||
expect(silenceRemovalSettings.isEnabled()).toBe(true);
|
||||
|
||||
+31
@@ -12004,3 +12004,34 @@ body.sidebar-collapsed #sidebar-nav-donate {
|
||||
line-height: 1.45;
|
||||
color: var(--muted-foreground);
|
||||
}
|
||||
|
||||
/* Disable Blur Effects preference */
|
||||
:root.disable-blur-effects,
|
||||
:root.disable-blur-effects *,
|
||||
:root.disable-blur-effects *::before,
|
||||
:root.disable-blur-effects *::after {
|
||||
/* stylelint-disable-next-line property-no-vendor-prefix */
|
||||
-webkit-backdrop-filter: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
/* Keep the album background's existing color treatment while removing its blur. */
|
||||
:root.disable-blur-effects #page-background {
|
||||
filter: brightness(0.4) !important;
|
||||
}
|
||||
|
||||
:root.disable-blur-effects[data-theme='white'] #page-background {
|
||||
filter: brightness(1.6) opacity(0.35) !important;
|
||||
}
|
||||
|
||||
/* Preserve the visualizer's saturation and brightness when its CSS blur is disabled. */
|
||||
:root.disable-blur-effects #fullscreen-cover-overlay:not(.ui-hidden) #visualizer-container {
|
||||
filter: saturate(0.9) brightness(0.8) !important;
|
||||
}
|
||||
|
||||
:root.disable-blur-effects .synced-line,
|
||||
:root.disable-blur-effects .synced-line.active,
|
||||
:root.disable-blur-effects .synced-line.upcoming,
|
||||
:root.disable-blur-effects .synced-line.past {
|
||||
filter: none !important;
|
||||
}
|
||||
Reference in new issue
Block a user