mirror of
https://github.com/meowarex/TidaLuna-Plugins.git
synced 2026-08-26 22:37:45 +10:00
Cover Everywhere (Stock Support)
This commit is contained in:
@@ -15,13 +15,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Hide Tidal now-playing background color */
|
/* Hide Tidal now-playing background color */
|
||||||
[data-test="new-now-playing"] > [class*="_background_"] {
|
body.rl-backdrop-active [data-test="new-now-playing"] > [class*="_background_"] {
|
||||||
/* biome-ignore lint: Must override native album-art-derived background */
|
/* biome-ignore lint: Must override native album-art-derived background */
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure now-playing container is transparent */
|
/* Ensure now-playing container is transparent */
|
||||||
[class*="_nowPlayingContainer"] {
|
body.rl-backdrop-active [class*="_nowPlayingContainer"] {
|
||||||
/* biome-ignore lint: Must override any inline background styles */
|
/* biome-ignore lint: Must override any inline background styles */
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,105 @@
|
|||||||
/* Cover-art backdrop container styles
|
/* Cover-art backdrop container styles
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Stock backdrop projected app wide */
|
||||||
|
.rl-stock-background-container {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
z-index: -3;
|
||||||
|
pointer-events: none;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rl-stock-rotator {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
width: 100vmax;
|
||||||
|
height: 100vmax;
|
||||||
|
margin-left: -50vmax;
|
||||||
|
margin-top: -50vmax;
|
||||||
|
will-change: transform;
|
||||||
|
animation: rl-stock-spin 33s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tidal lays 40% of the container & then scales it 4x which is actually kinda smart (i should have thought of this..)*/
|
||||||
|
.rl-stock-overscan {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
width: 40vmax;
|
||||||
|
height: 40vmax;
|
||||||
|
margin-left: -20vmax;
|
||||||
|
margin-top: -20vmax;
|
||||||
|
transform: scale(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rl-stock-art {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
filter: blur(28px) saturate(1.3);
|
||||||
|
transform: scale(1.26);
|
||||||
|
opacity: 0;
|
||||||
|
/* Crossfade between the two layers on track change (again.. NOT AUDIO CROSSFADE) */
|
||||||
|
transition: opacity 600ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rl-stock-art.rl-stock-art-active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rl-stock-scrim {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
/* Both Tidal gradients */
|
||||||
|
background:
|
||||||
|
radial-gradient(
|
||||||
|
120% 100% at 50% 38%,
|
||||||
|
rgba(0, 0, 0, 0) 0%,
|
||||||
|
rgba(0, 0, 0, 0.12) 62%,
|
||||||
|
rgba(0, 0, 0, 0.28) 100%
|
||||||
|
),
|
||||||
|
linear-gradient(
|
||||||
|
rgba(0, 0, 0, 0.34) 0%,
|
||||||
|
rgba(0, 0, 0, 0.42) 24%,
|
||||||
|
rgba(0, 0, 0, 0.5) 45%,
|
||||||
|
rgba(0, 0, 0, 0.62) 72%,
|
||||||
|
rgba(0, 0, 0, 0.76) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tidal stops its spin while paused */
|
||||||
|
.rl-stock-paused .rl-stock-rotator {
|
||||||
|
animation-play-state: paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rl-stock-spin {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.rl-stock-rotator {
|
||||||
|
/* biome-ignore lint: Accessibility override needs priority */
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.global-background-container {
|
.global-background-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|||||||
@@ -727,6 +727,9 @@ const setLayerRunning = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const syncBackdropActivity = (): void => {
|
const syncBackdropActivity = (): void => {
|
||||||
|
// Stock backdrop keeps current (no shader loop)
|
||||||
|
if (stockContainer) applyStockCoverEverywhere();
|
||||||
|
|
||||||
const nowPlaying = kawarpLayers.nowPlaying;
|
const nowPlaying = kawarpLayers.nowPlaying;
|
||||||
const global = kawarpLayers.global;
|
const global = kawarpLayers.global;
|
||||||
const nowPlayingVisible = nowPlaying?.isVisible() ?? false;
|
const nowPlayingVisible = nowPlaying?.isVisible() ?? false;
|
||||||
@@ -858,10 +861,15 @@ function updateCoverArtBackground(method: number = 0): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Teardown <3
|
// Teardown <3
|
||||||
|
document.body.classList.toggle("rl-backdrop-active", settings.backdropEnabled);
|
||||||
if (!settings.backdropEnabled) {
|
if (!settings.backdropEnabled) {
|
||||||
cleanUpDynamicArt();
|
cleanUpDynamicArt();
|
||||||
|
// Cover Everywhere still applies (Stock Tidal Backdrop)
|
||||||
|
if (settings.CoverEverywhere) applyStockCoverEverywhere();
|
||||||
|
else cleanUpStockCoverEverywhere();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
cleanUpStockCoverEverywhere();
|
||||||
|
|
||||||
const coverArtImageSrc = getCoverArtSrc();
|
const coverArtImageSrc = getCoverArtSrc();
|
||||||
if (!coverArtImageSrc) {
|
if (!coverArtImageSrc) {
|
||||||
@@ -875,6 +883,77 @@ function updateCoverArtBackground(method: number = 0): void {
|
|||||||
syncBackdropActivity();
|
syncBackdropActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARKER: Stock Backdrop (Cover Everywhere without the shader)
|
||||||
|
|
||||||
|
const STOCK_MARKUP =
|
||||||
|
'<div class="rl-stock-rotator"><div class="rl-stock-overscan">' +
|
||||||
|
'<img class="rl-stock-art" alt=""><img class="rl-stock-art" alt="">' +
|
||||||
|
'</div></div><div class="rl-stock-scrim"></div>';
|
||||||
|
const STOCK_ART_RES = "320x320";
|
||||||
|
|
||||||
|
let stockBgStyleTag: StyleTag | null = null;
|
||||||
|
let stockContainer: HTMLElement | null = null;
|
||||||
|
|
||||||
|
const applyStockCoverEverywhere = (): void => {
|
||||||
|
// Same sheet the shader uses
|
||||||
|
stockBgStyleTag ??= new StyleTag(
|
||||||
|
"RadiantLyrics-stock-backdrop",
|
||||||
|
unloads,
|
||||||
|
coverEverywhereCss,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!stockContainer?.isConnected) {
|
||||||
|
// Sweep first
|
||||||
|
cleanUpStockContainers();
|
||||||
|
stockContainer = document.createElement("div");
|
||||||
|
stockContainer.className = "rl-stock-background-container";
|
||||||
|
stockContainer.innerHTML = STOCK_MARKUP;
|
||||||
|
document.body.appendChild(stockContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
const source = document.querySelector<HTMLImageElement>(
|
||||||
|
'[data-test="footer-player"] [data-test="current-media-imagery"] img',
|
||||||
|
);
|
||||||
|
const layers = [
|
||||||
|
...stockContainer.querySelectorAll<HTMLImageElement>(".rl-stock-art"),
|
||||||
|
];
|
||||||
|
// Which layer is showing lives in DOM (no state to track)
|
||||||
|
const shown =
|
||||||
|
layers.find((l) => l.classList.contains("rl-stock-art-active")) ?? layers[1];
|
||||||
|
const next = layers.find((l) => l !== shown);
|
||||||
|
|
||||||
|
const cover = source?.src.replace(/\d+x\d+/, STOCK_ART_RES);
|
||||||
|
if (next && cover && cover !== shown.src) {
|
||||||
|
next.src = cover;
|
||||||
|
// Swap only once decoded (otherwise the crossfade reveals a blank layer)
|
||||||
|
const reveal = () => {
|
||||||
|
next.classList.add("rl-stock-art-active");
|
||||||
|
shown.classList.remove("rl-stock-art-active");
|
||||||
|
};
|
||||||
|
if (next.complete) reveal();
|
||||||
|
else next.addEventListener("load", reveal, { once: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tidal halts its own spin while paused
|
||||||
|
stockContainer.classList.toggle(
|
||||||
|
"rl-stock-paused",
|
||||||
|
!reduxPlaybackIsPlaying(),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const cleanUpStockContainers = (): void => {
|
||||||
|
document
|
||||||
|
.querySelectorAll(".rl-stock-background-container")
|
||||||
|
.forEach((el) => el.remove());
|
||||||
|
};
|
||||||
|
|
||||||
|
const cleanUpStockCoverEverywhere = (): void => {
|
||||||
|
stockContainer = null;
|
||||||
|
cleanUpStockContainers();
|
||||||
|
stockBgStyleTag?.remove();
|
||||||
|
stockBgStyleTag = null;
|
||||||
|
};
|
||||||
|
|
||||||
const cleanUpGlobalBackground = function (): void {
|
const cleanUpGlobalBackground = function (): void {
|
||||||
// Release WebGL context before canvas is orphaned (otherwise death occurs)
|
// Release WebGL context before canvas is orphaned (otherwise death occurs)
|
||||||
disposeKawarpLayer("global");
|
disposeKawarpLayer("global");
|
||||||
@@ -912,10 +991,17 @@ const updateRadiantLyricsBackdrop = function (): void {
|
|||||||
document.body.classList.remove("performance-mode");
|
document.body.classList.remove("performance-mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gates the rules that hide Tidal now-playing background
|
||||||
|
document.body.classList.toggle("rl-backdrop-active", settings.backdropEnabled);
|
||||||
|
|
||||||
if (!settings.backdropEnabled) {
|
if (!settings.backdropEnabled) {
|
||||||
cleanUpDynamicArt();
|
cleanUpDynamicArt();
|
||||||
|
// Cover Everywhere still applies (Stock Tidal Backdrop)
|
||||||
|
if (settings.CoverEverywhere) applyStockCoverEverywhere();
|
||||||
|
else cleanUpStockCoverEverywhere();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
cleanUpStockCoverEverywhere();
|
||||||
|
|
||||||
if (!settings.CoverEverywhere) cleanUpGlobalBackground();
|
if (!settings.CoverEverywhere) cleanUpGlobalBackground();
|
||||||
|
|
||||||
@@ -965,6 +1051,8 @@ updateCoverArtBackground(1);
|
|||||||
// Cleanups
|
// Cleanups
|
||||||
unloads.add(() => {
|
unloads.add(() => {
|
||||||
cleanUpDynamicArt();
|
cleanUpDynamicArt();
|
||||||
|
cleanUpStockCoverEverywhere();
|
||||||
|
document.body.classList.remove("rl-backdrop-active");
|
||||||
|
|
||||||
// Clean up floating player bar inline styles
|
// Clean up floating player bar inline styles
|
||||||
const footerPlayer = document.querySelector(
|
const footerPlayer = document.querySelector(
|
||||||
|
|||||||
Reference in New Issue
Block a user