mirror of
https://github.com/meowarex/TidaLuna-Plugins.git
synced 2026-06-18 03:43:10 +10:00
Flow Refactor
This commit is contained in:
@@ -8,6 +8,12 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Define a typed onChange signature for the switch
|
||||||
|
type SwitchChangeHandler = (
|
||||||
|
event: React.ChangeEvent<HTMLInputElement> | null,
|
||||||
|
checked: boolean,
|
||||||
|
) => void;
|
||||||
|
|
||||||
export type ColoramaMode =
|
export type ColoramaMode =
|
||||||
| "single"
|
| "single"
|
||||||
| "gradient-experimental"
|
| "gradient-experimental"
|
||||||
@@ -60,9 +66,12 @@ export const Settings = () => {
|
|||||||
const [activeEndpoint, setActiveEndpoint] = React.useState<
|
const [activeEndpoint, setActiveEndpoint] = React.useState<
|
||||||
"single" | "start" | "end"
|
"single" | "start" | "end"
|
||||||
>("single");
|
>("single");
|
||||||
const AnySwitch = LunaSwitchSetting as unknown as React.ComponentType<
|
const AnySwitch = LunaSwitchSetting as unknown as React.ComponentType<{
|
||||||
Record<string, unknown>
|
title: string;
|
||||||
>;
|
desc?: string;
|
||||||
|
checked: boolean;
|
||||||
|
onChange: SwitchChangeHandler;
|
||||||
|
}>;
|
||||||
|
|
||||||
// Helper for HEX normalization
|
// Helper for HEX normalization
|
||||||
const normalizeToRGB = (
|
const normalizeToRGB = (
|
||||||
@@ -133,19 +142,19 @@ export const Settings = () => {
|
|||||||
if (!hexColorRegex.test(trimmed)) return;
|
if (!hexColorRegex.test(trimmed)) return;
|
||||||
if (mode === "single") {
|
if (mode === "single") {
|
||||||
const next = normalizeToRGB(trimmed);
|
const next = normalizeToRGB(trimmed);
|
||||||
settings.singleColor = next;
|
|
||||||
setSingleColor(next);
|
setSingleColor(next);
|
||||||
|
settings.singleColor = next;
|
||||||
if (updateInput) setCustomInput(next);
|
if (updateInput) setCustomInput(next);
|
||||||
} else if (mode === "gradient-experimental") {
|
} else if (mode === "gradient-experimental") {
|
||||||
const norm = normalizeToRGB(trimmed);
|
const next = normalizeToRGB(trimmed);
|
||||||
if (activeEndpoint === "end") {
|
if (activeEndpoint === "end") {
|
||||||
settings.gradientEnd = norm;
|
setGradientEnd(next);
|
||||||
setGradientEnd(norm);
|
settings.gradientEnd = next;
|
||||||
} else {
|
} else {
|
||||||
settings.gradientStart = norm;
|
setGradientStart(next);
|
||||||
setGradientStart(norm);
|
settings.gradientStart = next;
|
||||||
}
|
}
|
||||||
if (updateInput) setCustomInput(norm);
|
if (updateInput) setCustomInput(next);
|
||||||
}
|
}
|
||||||
requestApply();
|
requestApply();
|
||||||
};
|
};
|
||||||
@@ -500,21 +509,20 @@ export const Settings = () => {
|
|||||||
key={color}
|
key={color}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
const next = normalizeToRGB(color);
|
||||||
if (mode === "single") {
|
if (mode === "single") {
|
||||||
const next = normalizeToRGB(color);
|
|
||||||
settings.singleColor = next;
|
|
||||||
setSingleColor(next);
|
setSingleColor(next);
|
||||||
|
settings.singleColor = next;
|
||||||
} else if (mode === "gradient-experimental") {
|
} else if (mode === "gradient-experimental") {
|
||||||
const next = normalizeToRGB(color);
|
|
||||||
if (activeEndpoint === "end") {
|
if (activeEndpoint === "end") {
|
||||||
settings.gradientEnd = next;
|
|
||||||
setGradientEnd(next);
|
setGradientEnd(next);
|
||||||
|
settings.gradientEnd = next;
|
||||||
} else {
|
} else {
|
||||||
settings.gradientStart = next;
|
|
||||||
setGradientStart(next);
|
setGradientStart(next);
|
||||||
|
settings.gradientStart = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCustomInput(normalizeToRGB(color));
|
setCustomInput(next);
|
||||||
requestApply();
|
requestApply();
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
@@ -610,8 +618,8 @@ export const Settings = () => {
|
|||||||
value={singleAlpha}
|
value={singleAlpha}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const value = Number(e.target.value);
|
const value = Number(e.target.value);
|
||||||
settings.singleAlpha = value;
|
|
||||||
setSingleAlpha(value);
|
setSingleAlpha(value);
|
||||||
|
settings.singleAlpha = value;
|
||||||
requestApply();
|
requestApply();
|
||||||
}}
|
}}
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
@@ -653,8 +661,8 @@ export const Settings = () => {
|
|||||||
value={gradientStartAlpha}
|
value={gradientStartAlpha}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const value = Number(e.target.value);
|
const value = Number(e.target.value);
|
||||||
settings.gradientStartAlpha = value;
|
|
||||||
setGradientStartAlpha(value);
|
setGradientStartAlpha(value);
|
||||||
|
settings.gradientStartAlpha = value;
|
||||||
requestApply();
|
requestApply();
|
||||||
}}
|
}}
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
@@ -692,8 +700,8 @@ export const Settings = () => {
|
|||||||
value={gradientEndAlpha}
|
value={gradientEndAlpha}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const value = Number(e.target.value);
|
const value = Number(e.target.value);
|
||||||
settings.gradientEndAlpha = value;
|
|
||||||
setGradientEndAlpha(value);
|
setGradientEndAlpha(value);
|
||||||
|
settings.gradientEndAlpha = value;
|
||||||
requestApply();
|
requestApply();
|
||||||
}}
|
}}
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
@@ -727,8 +735,8 @@ export const Settings = () => {
|
|||||||
value={gradientAngle}
|
value={gradientAngle}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const value = Number(e.target.value);
|
const value = Number(e.target.value);
|
||||||
settings.gradientAngle = value;
|
|
||||||
setGradientAngle(value);
|
setGradientAngle(value);
|
||||||
|
settings.gradientAngle = value;
|
||||||
requestApply();
|
requestApply();
|
||||||
}}
|
}}
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
@@ -762,8 +770,8 @@ export const Settings = () => {
|
|||||||
value={gradientAngle}
|
value={gradientAngle}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const value = Number(e.target.value);
|
const value = Number(e.target.value);
|
||||||
settings.gradientAngle = value;
|
|
||||||
setGradientAngle(value);
|
setGradientAngle(value);
|
||||||
|
settings.gradientAngle = value;
|
||||||
requestApply();
|
requestApply();
|
||||||
}}
|
}}
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
@@ -794,7 +802,7 @@ export const Settings = () => {
|
|||||||
title="Exclude Inactive"
|
title="Exclude Inactive"
|
||||||
desc="Apply color/gradient only to the currently active lyric line"
|
desc="Apply color/gradient only to the currently active lyric line"
|
||||||
checked={excludeInactive}
|
checked={excludeInactive}
|
||||||
onChange={(_: unknown, checked: boolean) => {
|
onChange={(_event: React.ChangeEvent<HTMLInputElement> | null, checked: boolean) => {
|
||||||
settings.excludeInactive = checked;
|
settings.excludeInactive = checked;
|
||||||
setExcludeInactive(checked);
|
setExcludeInactive(checked);
|
||||||
requestApply();
|
requestApply();
|
||||||
|
|||||||
@@ -41,25 +41,39 @@ const onMouseUp = (): void => {
|
|||||||
if (selection?.toString().length > 0) {
|
if (selection?.toString().length > 0) {
|
||||||
const selectedSpans: HTMLSpanElement[] = [];
|
const selectedSpans: HTMLSpanElement[] = [];
|
||||||
const range = selection.getRangeAt(0);
|
const range = selection.getRangeAt(0);
|
||||||
const container = range.commonAncestorContainer;
|
let container: Node | null = range.commonAncestorContainer;
|
||||||
|
|
||||||
// If the container is NOT an element and a document, adjust it.
|
// Normalize container: if it's a text node, use its parent element/node
|
||||||
|
if (container && container.nodeType === Node.TEXT_NODE) {
|
||||||
|
container = (container.parentElement ?? container.parentNode) as Node | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If parent has data-current, treat as single-line copy case
|
||||||
if (
|
if (
|
||||||
container.nodeType !== Node.ELEMENT_NODE &&
|
container &&
|
||||||
container.nodeType !== Node.DOCUMENT_NODE
|
container.nodeType === Node.ELEMENT_NODE &&
|
||||||
|
(container as Element).hasAttribute("data-current")
|
||||||
) {
|
) {
|
||||||
// Get the parent element if it's a text node
|
const text_ = selection.toString().trim();
|
||||||
const parentElement = container.parentElement;
|
SetClipboard(text_);
|
||||||
if (parentElement?.hasAttribute("data-current")) {
|
trace.msg.log("Copied to clipboard!");
|
||||||
const text_ = selection.toString().trim();
|
return;
|
||||||
SetClipboard(text_);
|
}
|
||||||
trace.msg.log("Copied to clipboard!");
|
|
||||||
return;
|
// Ensure we have an Element or Document before querying
|
||||||
}
|
if (
|
||||||
|
!container ||
|
||||||
|
(container.nodeType !== Node.ELEMENT_NODE &&
|
||||||
|
container.nodeType !== Node.DOCUMENT_NODE)
|
||||||
|
) {
|
||||||
|
isSelecting = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all the spans inside the container.
|
// Get all the spans inside the container.
|
||||||
const spans = (container as Element).getElementsByTagName("span");
|
const spans = (container as Element | Document).getElementsByTagName(
|
||||||
|
"span",
|
||||||
|
);
|
||||||
for (const span of spans) {
|
for (const span of spans) {
|
||||||
if (selection.containsNode(span, true)) {
|
if (selection.containsNode(span, true)) {
|
||||||
selectedSpans.push(span as HTMLSpanElement);
|
selectedSpans.push(span as HTMLSpanElement);
|
||||||
|
|||||||
@@ -400,8 +400,7 @@ document.addEventListener(
|
|||||||
const eventX = event.clientX;
|
const eventX = event.clientX;
|
||||||
const eventY = event.clientY;
|
const eventY = event.clientY;
|
||||||
|
|
||||||
// Prevent default immediately if we plan to handle it
|
// Allow native context menu by default; we'll show our custom menu only if needed
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
// Wait to see if the built-in context menu appears
|
// Wait to see if the built-in context menu appears
|
||||||
contextMenuTimeout = window.setTimeout(() => {
|
contextMenuTimeout = window.setTimeout(() => {
|
||||||
|
|||||||
@@ -31,11 +31,17 @@ const getQualityColor = (audioQuality: string): string => {
|
|||||||
return QUALITY_COLORS.MAX;
|
return QUALITY_COLORS.MAX;
|
||||||
} else if (quality?.includes("LOSSLESS")) {
|
} else if (quality?.includes("LOSSLESS")) {
|
||||||
return QUALITY_COLORS.HIGH;
|
return QUALITY_COLORS.HIGH;
|
||||||
} else {
|
} else if (quality?.includes("HIGH")) {
|
||||||
|
return QUALITY_COLORS.HIGH;
|
||||||
|
} else if (quality?.includes("LOW")) {
|
||||||
return QUALITY_COLORS.LOW;
|
return QUALITY_COLORS.LOW;
|
||||||
}
|
}
|
||||||
|
return QUALITY_COLORS.LOW;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Interval tracking for quality monitoring
|
||||||
|
let qualityMonitoringIntervalId: number | null = null;
|
||||||
|
|
||||||
// Function to Reset Seek Bar Color (if setting gets disabled while playing)
|
// Function to Reset Seek Bar Color (if setting gets disabled while playing)
|
||||||
const resetSeekBarColor = async (): Promise<void> => {
|
const resetSeekBarColor = async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
@@ -82,17 +88,16 @@ const applyQualityColors = async (): Promise<void> => {
|
|||||||
|
|
||||||
// Function to monitor track changes using track ID
|
// Function to monitor track changes using track ID
|
||||||
const setupQualityMonitoring = (): void => {
|
const setupQualityMonitoring = (): void => {
|
||||||
|
if (qualityMonitoringIntervalId != null) return;
|
||||||
let lastTrackId: string | null = null;
|
let lastTrackId: string | null = null;
|
||||||
const interval = setInterval(() => {
|
qualityMonitoringIntervalId = window.setInterval(() => {
|
||||||
if (!settings.qualityColorMatchedSeekBar) return;
|
if (!settings.qualityColorMatchedSeekBar) return;
|
||||||
const currentTrackId = PlayState.playbackContext?.actualProductId;
|
const currentTrackId = PlayState.playbackContext?.actualProductId;
|
||||||
if (currentTrackId && currentTrackId !== lastTrackId) {
|
if (currentTrackId && currentTrackId !== lastTrackId) {
|
||||||
//trace.msg.log(`[OLED Theme] Track ID changed: ${lastTrackId} -> ${currentTrackId}`);
|
|
||||||
lastTrackId = currentTrackId;
|
lastTrackId = currentTrackId;
|
||||||
applyQualityColors();
|
applyQualityColors();
|
||||||
}
|
}
|
||||||
}, 250);
|
}, 250);
|
||||||
unloads.add(() => clearInterval(interval));
|
|
||||||
|
|
||||||
// Initial color application (if a track is already loaded)
|
// Initial color application (if a track is already loaded)
|
||||||
const currentTrackId = PlayState.playbackContext?.actualProductId;
|
const currentTrackId = PlayState.playbackContext?.actualProductId;
|
||||||
@@ -102,6 +107,13 @@ const setupQualityMonitoring = (): void => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const stopQualityMonitoring = (): void => {
|
||||||
|
if (qualityMonitoringIntervalId != null) {
|
||||||
|
window.clearInterval(qualityMonitoringIntervalId);
|
||||||
|
qualityMonitoringIntervalId = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Function to apply theme styles based on current settings
|
// Function to apply theme styles based on current settings
|
||||||
const applyThemeStyles = (): void => {
|
const applyThemeStyles = (): void => {
|
||||||
// Choose the appropriate CSS file based on settings
|
// Choose the appropriate CSS file based on settings
|
||||||
@@ -126,8 +138,9 @@ const applyThemeStyles = (): void => {
|
|||||||
);
|
);
|
||||||
setupQualityMonitoring();
|
setupQualityMonitoring();
|
||||||
} else {
|
} else {
|
||||||
// If disabling, reset the seek bar color
|
// If disabling, reset the seek bar color and stop monitoring
|
||||||
resetSeekBarColor();
|
resetSeekBarColor();
|
||||||
|
stopQualityMonitoring();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the selected theme using StyleTag
|
// Apply the selected theme using StyleTag
|
||||||
@@ -145,3 +158,8 @@ window.updateOLEDThemeStyles = applyThemeStyles;
|
|||||||
|
|
||||||
// Apply the OLED theme initially
|
// Apply the OLED theme initially
|
||||||
applyThemeStyles();
|
applyThemeStyles();
|
||||||
|
|
||||||
|
// Ensure interval is cleared on unload
|
||||||
|
unloads.add(() => {
|
||||||
|
stopQualityMonitoring();
|
||||||
|
});
|
||||||
|
|||||||
@@ -145,7 +145,7 @@
|
|||||||
|
|
||||||
[data-test="current-media-imagery"] {
|
[data-test="current-media-imagery"] {
|
||||||
border: 0 !important;
|
border: 0 !important;
|
||||||
margin: none;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class^="_imageBorder"] {
|
[class^="_imageBorder"] {
|
||||||
|
|||||||
@@ -120,7 +120,7 @@
|
|||||||
|
|
||||||
[data-test="current-media-imagery"] {
|
[data-test="current-media-imagery"] {
|
||||||
border: 0 !important;
|
border: 0 !important;
|
||||||
margin: none;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class^="_imageBorder"] {
|
[class^="_imageBorder"] {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export const Settings = () => {
|
|||||||
title="Lyrics Glow Effect"
|
title="Lyrics Glow Effect"
|
||||||
desc="Enable glowing effect for lyrics & Font Stytling Changes"
|
desc="Enable glowing effect for lyrics & Font Stytling Changes"
|
||||||
checked={lyricsGlowEnabled}
|
checked={lyricsGlowEnabled}
|
||||||
onChange={(_event: unknown, checked: boolean) => {
|
onChange={(_: void, checked: boolean) => {
|
||||||
setLyricsGlowEnabled((settings.lyricsGlowEnabled = checked));
|
setLyricsGlowEnabled((settings.lyricsGlowEnabled = checked));
|
||||||
// Update styles immediately when setting changes
|
// Update styles immediately when setting changes
|
||||||
if ((window as any).updateRadiantLyricsStyles) {
|
if ((window as any).updateRadiantLyricsStyles) {
|
||||||
@@ -77,7 +77,7 @@ export const Settings = () => {
|
|||||||
title="Track Title Glow"
|
title="Track Title Glow"
|
||||||
desc="Apply glow to the track title"
|
desc="Apply glow to the track title"
|
||||||
checked={trackTitleGlow}
|
checked={trackTitleGlow}
|
||||||
onChange={(_event: unknown, checked: boolean) => {
|
onChange={(_: void, checked: boolean) => {
|
||||||
setTrackTitleGlow((settings.trackTitleGlow = checked));
|
setTrackTitleGlow((settings.trackTitleGlow = checked));
|
||||||
if ((window as any).updateRadiantLyricsStyles) {
|
if ((window as any).updateRadiantLyricsStyles) {
|
||||||
(window as any).updateRadiantLyricsStyles();
|
(window as any).updateRadiantLyricsStyles();
|
||||||
@@ -88,7 +88,7 @@ export const Settings = () => {
|
|||||||
title="Hide UI Feature"
|
title="Hide UI Feature"
|
||||||
desc="Enable hide/unhide UI functionality with toggle buttons"
|
desc="Enable hide/unhide UI functionality with toggle buttons"
|
||||||
checked={hideUIEnabled}
|
checked={hideUIEnabled}
|
||||||
onChange={(_event: unknown, checked: boolean) => {
|
onChange={(_: void, checked: boolean) => {
|
||||||
setHideUIEnabled((settings.hideUIEnabled = checked));
|
setHideUIEnabled((settings.hideUIEnabled = checked));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -96,7 +96,7 @@ export const Settings = () => {
|
|||||||
title="Player Bar Visibility in Hide UI Mode"
|
title="Player Bar Visibility in Hide UI Mode"
|
||||||
desc="Keep player bar visible when UI is hidden"
|
desc="Keep player bar visible when UI is hidden"
|
||||||
checked={playerBarVisible}
|
checked={playerBarVisible}
|
||||||
onChange={(_event: unknown, checked: boolean) => {
|
onChange={(_: void, checked: boolean) => {
|
||||||
console.log("Player Bar Visibility:", checked ? "visible" : "hidden");
|
console.log("Player Bar Visibility:", checked ? "visible" : "hidden");
|
||||||
setPlayerBarVisible((settings.playerBarVisible = checked));
|
setPlayerBarVisible((settings.playerBarVisible = checked));
|
||||||
// Update styles immediately when setting changes
|
// Update styles immediately when setting changes
|
||||||
@@ -109,7 +109,7 @@ export const Settings = () => {
|
|||||||
title="Cover Everywhere"
|
title="Cover Everywhere"
|
||||||
desc="Apply the spinning Cover Art background to the entire app, not just the Now Playing view, Heavily Inspired by Cover-Theme by @Inrixia"
|
desc="Apply the spinning Cover Art background to the entire app, not just the Now Playing view, Heavily Inspired by Cover-Theme by @Inrixia"
|
||||||
checked={spinningCoverEverywhere}
|
checked={spinningCoverEverywhere}
|
||||||
onChange={(_event: unknown, checked: boolean) => {
|
onChange={(_: void, checked: boolean) => {
|
||||||
console.log(
|
console.log(
|
||||||
"Spinning Cover Everywhere:",
|
"Spinning Cover Everywhere:",
|
||||||
checked ? "enabled" : "disabled",
|
checked ? "enabled" : "disabled",
|
||||||
@@ -127,7 +127,7 @@ export const Settings = () => {
|
|||||||
title="Performance Mode | Experimental"
|
title="Performance Mode | Experimental"
|
||||||
desc="Performance mode: Reduces blur effects & uses smaller image sizes, to optimize GPU usage"
|
desc="Performance mode: Reduces blur effects & uses smaller image sizes, to optimize GPU usage"
|
||||||
checked={performanceMode}
|
checked={performanceMode}
|
||||||
onChange={(_event: unknown, checked: boolean) => {
|
onChange={(_: void, checked: boolean) => {
|
||||||
console.log("Performance Mode:", checked ? "enabled" : "disabled");
|
console.log("Performance Mode:", checked ? "enabled" : "disabled");
|
||||||
setPerformanceMode((settings.performanceMode = checked));
|
setPerformanceMode((settings.performanceMode = checked));
|
||||||
// Update background animations immediately when setting changes
|
// Update background animations immediately when setting changes
|
||||||
@@ -143,7 +143,7 @@ export const Settings = () => {
|
|||||||
title="Background Cover Spin" // Cheers @Max/n0201 for the idea <3
|
title="Background Cover Spin" // Cheers @Max/n0201 for the idea <3
|
||||||
desc="Enable the spinning cover art background animation"
|
desc="Enable the spinning cover art background animation"
|
||||||
checked={spinningArtEnabled}
|
checked={spinningArtEnabled}
|
||||||
onChange={(_event: unknown, checked: boolean) => {
|
onChange={(_: void, checked: boolean) => {
|
||||||
console.log(
|
console.log(
|
||||||
"Background Cover Spin:",
|
"Background Cover Spin:",
|
||||||
checked ? "enabled" : "disabled",
|
checked ? "enabled" : "disabled",
|
||||||
@@ -262,7 +262,7 @@ export const Settings = () => {
|
|||||||
title="Settings Affect Now Playing"
|
title="Settings Affect Now Playing"
|
||||||
desc="Apply background settings to Now Playing view"
|
desc="Apply background settings to Now Playing view"
|
||||||
checked={settingsAffectNowPlaying}
|
checked={settingsAffectNowPlaying}
|
||||||
onChange={(_event: unknown, checked: boolean) => {
|
onChange={(_: void, checked: boolean) => {
|
||||||
console.log(
|
console.log(
|
||||||
"Settings Affect Now Playing:",
|
"Settings Affect Now Playing:",
|
||||||
checked ? "enabled" : "disabled",
|
checked ? "enabled" : "disabled",
|
||||||
|
|||||||
@@ -38,30 +38,30 @@ const updateRadiantLyricsTextGlow = function (): void {
|
|||||||
// Function to update styles when settings change
|
// Function to update styles when settings change
|
||||||
const updateRadiantLyricsStyles = function (): void {
|
const updateRadiantLyricsStyles = function (): void {
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
// Apply only base styles (button hiding), NOT separated lyrics styles
|
// Apply only base styles (button hiding) and optional player bar hiding
|
||||||
// to avoid affecting lyrics scrolling behavior
|
|
||||||
baseStyleTag.css = baseStyles;
|
baseStyleTag.css = baseStyles;
|
||||||
|
|
||||||
// Apply player bar styles based on setting
|
|
||||||
if (!settings.playerBarVisible) {
|
if (!settings.playerBarVisible) {
|
||||||
playerBarStyleTag.css = playerBarHidden;
|
playerBarStyleTag.css = playerBarHidden;
|
||||||
} else {
|
} else {
|
||||||
playerBarStyleTag.remove();
|
playerBarStyleTag.remove();
|
||||||
}
|
}
|
||||||
|
// Ensure lyrics glow styles are not applied when hidden
|
||||||
|
lyricsGlowStyleTag.remove();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update lyrics glow based on setting (only if UI is not hidden to avoid interference)
|
// Update lyrics glow based on setting (only when UI is visible)
|
||||||
const lyricsContainer = document.querySelector('[class^="_lyricsContainer"]');
|
const lyricsContainer = document.querySelector('[class^="_lyricsContainer"]');
|
||||||
if (lyricsContainer && !isHidden) {
|
if (lyricsContainer) {
|
||||||
if (settings.lyricsGlowEnabled) {
|
if (settings.lyricsGlowEnabled) {
|
||||||
lyricsContainer.classList.remove("lyrics-glow-disabled");
|
(lyricsContainer as HTMLElement).classList.remove("lyrics-glow-disabled");
|
||||||
lyricsGlowStyleTag.css = lyricsGlow;
|
lyricsGlowStyleTag.css = lyricsGlow;
|
||||||
updateRadiantLyricsTextGlow();
|
updateRadiantLyricsTextGlow();
|
||||||
} else {
|
} else {
|
||||||
lyricsContainer.classList.add("lyrics-glow-disabled");
|
(lyricsContainer as HTMLElement).classList.add("lyrics-glow-disabled");
|
||||||
lyricsGlowStyleTag.remove();
|
lyricsGlowStyleTag.remove();
|
||||||
}
|
}
|
||||||
} else if (!isHidden) {
|
} else {
|
||||||
observePromise<HTMLElement>(unloads, '[class^="_lyricsContainer"]')
|
observePromise<HTMLElement>(unloads, '[class^="_lyricsContainer"]')
|
||||||
.then((el) => {
|
.then((el) => {
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
@@ -95,6 +95,16 @@ const updateRadiantLyricsStyles = function (): void {
|
|||||||
var isHidden = false;
|
var isHidden = false;
|
||||||
let unhideButtonAutoFadeTimeout: number | null = null;
|
let unhideButtonAutoFadeTimeout: number | null = null;
|
||||||
|
|
||||||
|
// Helper to safely create a one-off timeout that clears previous if any
|
||||||
|
const safelySetAutoFadeTimeout = (
|
||||||
|
existingId: number | null,
|
||||||
|
fn: () => void,
|
||||||
|
delay: number,
|
||||||
|
): number => {
|
||||||
|
if (existingId != null) window.clearTimeout(existingId);
|
||||||
|
return window.setTimeout(fn, delay);
|
||||||
|
};
|
||||||
|
|
||||||
const updateButtonStates = function (): void {
|
const updateButtonStates = function (): void {
|
||||||
const hideButton = document.querySelector(".hide-ui-button") as HTMLElement;
|
const hideButton = document.querySelector(".hide-ui-button") as HTMLElement;
|
||||||
const unhideButton = document.querySelector(
|
const unhideButton = document.querySelector(
|
||||||
@@ -120,7 +130,7 @@ const updateButtonStates = function (): void {
|
|||||||
}
|
}
|
||||||
if (unhideButton) {
|
if (unhideButton) {
|
||||||
// Clear any existing auto-fade timeout
|
// Clear any existing auto-fade timeout
|
||||||
if (unhideButtonAutoFadeTimeout) {
|
if (unhideButtonAutoFadeTimeout != null) {
|
||||||
window.clearTimeout(unhideButtonAutoFadeTimeout);
|
window.clearTimeout(unhideButtonAutoFadeTimeout);
|
||||||
unhideButtonAutoFadeTimeout = null;
|
unhideButtonAutoFadeTimeout = null;
|
||||||
}
|
}
|
||||||
@@ -137,11 +147,15 @@ const updateButtonStates = function (): void {
|
|||||||
unhideButton.style.pointerEvents = "auto";
|
unhideButton.style.pointerEvents = "auto";
|
||||||
|
|
||||||
// Set up auto-fade after 2 seconds
|
// Set up auto-fade after 2 seconds
|
||||||
unhideButtonAutoFadeTimeout = window.setTimeout(() => {
|
unhideButtonAutoFadeTimeout = safelySetAutoFadeTimeout(
|
||||||
if (isHidden && unhideButton && !unhideButton.matches(":hover")) {
|
unhideButtonAutoFadeTimeout,
|
||||||
unhideButton.classList.add("auto-faded");
|
() => {
|
||||||
}
|
if (isHidden && unhideButton && !unhideButton.matches(":hover")) {
|
||||||
}, 2000);
|
unhideButton.classList.add("auto-faded");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
2000,
|
||||||
|
);
|
||||||
}, 50);
|
}, 50);
|
||||||
} else {
|
} else {
|
||||||
// Smooth fade out for Unhide UI button
|
// Smooth fade out for Unhide UI button
|
||||||
@@ -771,7 +785,7 @@ unloads.add(() => {
|
|||||||
cleanUpDynamicArt();
|
cleanUpDynamicArt();
|
||||||
|
|
||||||
// Clean up auto-fade timeout
|
// Clean up auto-fade timeout
|
||||||
if (unhideButtonAutoFadeTimeout) {
|
if (unhideButtonAutoFadeTimeout != null) {
|
||||||
window.clearTimeout(unhideButtonAutoFadeTimeout);
|
window.clearTimeout(unhideButtonAutoFadeTimeout);
|
||||||
unhideButtonAutoFadeTimeout = null;
|
unhideButtonAutoFadeTimeout = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,22 +9,19 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "AbyssFont";
|
font-family: "AbyssFont";
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
src: url("https://excel.lexploits.top/extra/tidal/LyricsMedium.woff2")
|
src: url("https://excel.lexploits.top/extra/tidal/LyricsMedium.woff2") format("woff2");
|
||||||
format("woff2");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "AbyssFont";
|
font-family: "AbyssFont";
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
src: url("https://excel.lexploits.top/extra/tidal/LyricsSemibold.woff2")
|
src: url("https://excel.lexploits.top/extra/tidal/LyricsSemibold.woff2") format("woff2");
|
||||||
format("woff2");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "AbyssFont";
|
font-family: "AbyssFont";
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
src: url("https://excel.lexploits.top/extra/tidal/LyricsBold.woff2")
|
src: url("https://excel.lexploits.top/extra/tidal/LyricsBold.woff2") format("woff2");
|
||||||
format("woff2");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enhanced lyrics styling with glow effects */
|
/* Enhanced lyrics styling with glow effects */
|
||||||
|
|||||||
Reference in New Issue
Block a user