mirror of
https://github.com/meowarex/TidaLuna-Plugins.git
synced 2026-06-18 03:43:10 +10:00
Merged Obsidian into RL + Added Conditional Settings Visability
This commit is contained in:
Submodule
+1
Submodule Reference/BetterLyrics added at d6393c6739
Submodule
+1
Submodule Reference/applemusic-like-lyrics added at 48fb050d2f
@@ -7,6 +7,12 @@ export const settings = await ReactiveStore.getPluginStorage("RadiantLyrics", {
|
|||||||
trackTitleGlow: false,
|
trackTitleGlow: false,
|
||||||
hideUIEnabled: true,
|
hideUIEnabled: true,
|
||||||
playerBarVisible: false,
|
playerBarVisible: false,
|
||||||
|
floatingPlayerBar: true,
|
||||||
|
playerBarTint: 5,
|
||||||
|
playerBarTintColor: "#000000" as string,
|
||||||
|
playerBarTintCustomColors: [] as string[],
|
||||||
|
playerBarRadius: 5,
|
||||||
|
playerBarSpacing: 10,
|
||||||
CoverEverywhere: true,
|
CoverEverywhere: true,
|
||||||
performanceMode: false,
|
performanceMode: false,
|
||||||
spinningArt: true,
|
spinningArt: true,
|
||||||
@@ -64,6 +70,27 @@ export const Settings = () => {
|
|||||||
const [backgroundRadius, setBackgroundRadius] = React.useState(
|
const [backgroundRadius, setBackgroundRadius] = React.useState(
|
||||||
settings.backgroundRadius,
|
settings.backgroundRadius,
|
||||||
);
|
);
|
||||||
|
const [floatingPlayerBar, setFloatingPlayerBar] = React.useState(
|
||||||
|
settings.floatingPlayerBar,
|
||||||
|
);
|
||||||
|
const [playerBarTint, setPlayerBarTint] = React.useState(
|
||||||
|
settings.playerBarTint,
|
||||||
|
);
|
||||||
|
const [playerBarTintColor, setPlayerBarTintColor] = React.useState(
|
||||||
|
settings.playerBarTintColor,
|
||||||
|
);
|
||||||
|
const [playerBarRadius, setPlayerBarRadius] = React.useState(
|
||||||
|
settings.playerBarRadius,
|
||||||
|
);
|
||||||
|
const [playerBarSpacing, setPlayerBarSpacing] = React.useState(
|
||||||
|
settings.playerBarSpacing,
|
||||||
|
);
|
||||||
|
const [showTintColorPicker, setShowTintColorPicker] = React.useState(false);
|
||||||
|
const [isTintAnimatingIn, setIsTintAnimatingIn] = React.useState(false);
|
||||||
|
const [shouldRenderTintPicker, setShouldRenderTintPicker] = React.useState(false);
|
||||||
|
const [tintCustomInput, setTintCustomInput] = React.useState(settings.playerBarTintColor);
|
||||||
|
const [tintCustomColors, setTintCustomColors] = React.useState(settings.playerBarTintCustomColors);
|
||||||
|
const [tintHoveredColorIndex, setTintHoveredColorIndex] = React.useState<number | null>(null);
|
||||||
const [stickyLyricsFeature, setStickyLyricsFeature] = React.useState(
|
const [stickyLyricsFeature, setStickyLyricsFeature] = React.useState(
|
||||||
settings.stickyLyricsFeature,
|
settings.stickyLyricsFeature,
|
||||||
);
|
);
|
||||||
@@ -103,6 +130,23 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{(lyricsGlowEnabled || trackTitleGlow) && (
|
||||||
|
<LunaNumberSetting
|
||||||
|
title="Text Glow"
|
||||||
|
desc="Adjust the glow size of lyrics (0-100, default: 20)"
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
step={1}
|
||||||
|
value={textGlow}
|
||||||
|
onNumber={(value: number) => {
|
||||||
|
setTextGlow((settings.textGlow = value));
|
||||||
|
// Update variables immediately when setting changes
|
||||||
|
if ((window as any).updateRadiantLyricsTextGlow) {
|
||||||
|
(window as any).updateRadiantLyricsTextGlow();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<AnySwitch
|
<AnySwitch
|
||||||
title="Sticky Lyrics"
|
title="Sticky Lyrics"
|
||||||
desc="Adds a dropdown to the Lyrics tab that auto-switches to Play Queue when lyrics aren't available"
|
desc="Adds a dropdown to the Lyrics tab that auto-switches to Play Queue when lyrics aren't available"
|
||||||
@@ -122,6 +166,7 @@ export const Settings = () => {
|
|||||||
setHideUIEnabled((settings.hideUIEnabled = checked));
|
setHideUIEnabled((settings.hideUIEnabled = checked));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{hideUIEnabled && (
|
||||||
<AnySwitch
|
<AnySwitch
|
||||||
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"
|
||||||
@@ -135,6 +180,306 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
<AnySwitch
|
||||||
|
title="Floating Player Bar"
|
||||||
|
desc="Floating rounded player bar with backdrop blur"
|
||||||
|
checked={floatingPlayerBar}
|
||||||
|
onChange={(_: unknown, checked: boolean) => {
|
||||||
|
setFloatingPlayerBar((settings.floatingPlayerBar = checked));
|
||||||
|
if ((window as any).updateRadiantLyricsStyles) {
|
||||||
|
(window as any).updateRadiantLyricsStyles();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{floatingPlayerBar && (
|
||||||
|
<>
|
||||||
|
<LunaNumberSetting
|
||||||
|
title="Floating Bar Corner Radius"
|
||||||
|
desc="Adjust the corner rounding of the player bar (0-50, default: 5)"
|
||||||
|
min={0}
|
||||||
|
max={50}
|
||||||
|
step={1}
|
||||||
|
value={playerBarRadius}
|
||||||
|
onNumber={(value: number) => {
|
||||||
|
setPlayerBarRadius((settings.playerBarRadius = value));
|
||||||
|
(window as any).updateRadiantLyricsPlayerBarTint?.();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<LunaNumberSetting
|
||||||
|
title="Floating Bar Spacing"
|
||||||
|
desc="Adjust the spacing of the player bar from the edges (0-50, default: 10)"
|
||||||
|
min={0}
|
||||||
|
max={50}
|
||||||
|
step={1}
|
||||||
|
value={playerBarSpacing}
|
||||||
|
onNumber={(value: number) => {
|
||||||
|
setPlayerBarSpacing((settings.playerBarSpacing = value));
|
||||||
|
(window as any).updateRadiantLyricsPlayerBarTint?.();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{(() => {
|
||||||
|
const closeTintColorPicker = () => {
|
||||||
|
setIsTintAnimatingIn(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowTintColorPicker(false);
|
||||||
|
setShouldRenderTintPicker(false);
|
||||||
|
}, 200);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openTintColorPicker = () => {
|
||||||
|
setShowTintColorPicker(true);
|
||||||
|
setShouldRenderTintPicker(true);
|
||||||
|
setTimeout(() => setIsTintAnimatingIn(true), 10);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateTintColor = (color: string) => {
|
||||||
|
setPlayerBarTintColor(color);
|
||||||
|
setTintCustomInput(color);
|
||||||
|
settings.playerBarTintColor = color;
|
||||||
|
(window as any).updateRadiantLyricsPlayerBarTint?.();
|
||||||
|
};
|
||||||
|
|
||||||
|
const addTintCustomColor = () => {
|
||||||
|
if (tintCustomInput) {
|
||||||
|
const trimmedInput = tintCustomInput.trim().toLowerCase();
|
||||||
|
const hexColorRegex = /^#([0-9a-f]{6}|[0-9a-f]{3})$/i;
|
||||||
|
if (
|
||||||
|
hexColorRegex.test(trimmedInput) &&
|
||||||
|
!tintColorPresets.includes(trimmedInput) &&
|
||||||
|
!tintCustomColors.includes(trimmedInput)
|
||||||
|
) {
|
||||||
|
const newCustomColors = [...tintCustomColors, trimmedInput];
|
||||||
|
setTintCustomColors(newCustomColors);
|
||||||
|
settings.playerBarTintCustomColors = newCustomColors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeTintCustomColor = (colorToRemove: string) => {
|
||||||
|
const newCustomColors = tintCustomColors.filter(
|
||||||
|
(color) => color !== colorToRemove,
|
||||||
|
);
|
||||||
|
setTintCustomColors(newCustomColors);
|
||||||
|
settings.playerBarTintCustomColors = newCustomColors;
|
||||||
|
if (playerBarTintColor === colorToRemove) {
|
||||||
|
updateTintColor("#000000");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const tintColorPresets = [
|
||||||
|
"#000000", "#111111", "#222222", "#333333", "#444444",
|
||||||
|
"#555555", "#666666", "#888888", "#aaaaaa", "#cccccc",
|
||||||
|
"#ffffff", "#0d1117", "#1a1a2e", "#16213e", "#0f3460",
|
||||||
|
"#1b1b2f", "#162447", "#1f4068", "#e94560",
|
||||||
|
];
|
||||||
|
|
||||||
|
const allTintColors = [...tintColorPresets, ...tintCustomColors];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ position: "relative" }}>
|
||||||
|
<LunaNumberSetting
|
||||||
|
title="Player Bar Tint"
|
||||||
|
desc="Tint color & opacity (0-10, default: 5)"
|
||||||
|
min={0}
|
||||||
|
max={10}
|
||||||
|
step={1}
|
||||||
|
value={playerBarTint}
|
||||||
|
onNumber={(value: number) => {
|
||||||
|
setPlayerBarTint((settings.playerBarTint = value));
|
||||||
|
(window as any).updateRadiantLyricsPlayerBarTint?.();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* Color swatch — positioned just left of the value box */}
|
||||||
|
<button
|
||||||
|
onClick={() => showTintColorPicker ? closeTintColorPicker() : openTintColorPicker()}
|
||||||
|
style={{
|
||||||
|
width: "28px",
|
||||||
|
height: "28px",
|
||||||
|
border: "1px solid rgba(255,255,255,0.15)",
|
||||||
|
borderRadius: "6px",
|
||||||
|
cursor: "pointer",
|
||||||
|
background: playerBarTintColor,
|
||||||
|
position: "absolute",
|
||||||
|
right: "135px",
|
||||||
|
top: "50%",
|
||||||
|
transform: "translateY(-50%)",
|
||||||
|
overflow: "hidden",
|
||||||
|
zIndex: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ position: "absolute", inset: 0, background: "rgba(0,0,0,0.1)", backdropFilter: "blur(2px)" }} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Color Picker Modal */}
|
||||||
|
{shouldRenderTintPicker && (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "fixed",
|
||||||
|
top: 0, left: 0, right: 0, bottom: 0,
|
||||||
|
background: "rgba(0,0,0,0.6)",
|
||||||
|
zIndex: 1000,
|
||||||
|
opacity: isTintAnimatingIn ? 1 : 0,
|
||||||
|
transition: "opacity 0.2s ease",
|
||||||
|
}}
|
||||||
|
onClick={closeTintColorPicker}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "fixed",
|
||||||
|
top: "50%",
|
||||||
|
left: "50%",
|
||||||
|
background: "rgba(20,20,20,0.98)",
|
||||||
|
backdropFilter: "blur(20px)",
|
||||||
|
WebkitBackdropFilter: "blur(20px)",
|
||||||
|
border: "1px solid rgba(255,255,255,0.15)",
|
||||||
|
borderRadius: "16px",
|
||||||
|
padding: "20px",
|
||||||
|
minWidth: "320px",
|
||||||
|
maxWidth: "90vw",
|
||||||
|
maxHeight: "90vh",
|
||||||
|
zIndex: 1001,
|
||||||
|
boxShadow: "0 20px 40px rgba(0,0,0,0.7)",
|
||||||
|
opacity: isTintAnimatingIn ? 1 : 0,
|
||||||
|
transform: isTintAnimatingIn
|
||||||
|
? "translate(-50%, -50%) scale(1)"
|
||||||
|
: "translate(-50%, -50%) scale(0.9)",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ marginBottom: "12px", color: "#fff", fontWeight: "bold", fontSize: "14px" }}>
|
||||||
|
Choose Tint Color
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: "8px", marginBottom: "16px" }}>
|
||||||
|
{allTintColors.map((color, index) => {
|
||||||
|
const isCustomColor = tintCustomColors.includes(color);
|
||||||
|
const isHovered = tintHoveredColorIndex === index;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
kwey={index}
|
||||||
|
style={{ position: "relative", width: "32px", height: "32px", cursor: "pointer" }}
|
||||||
|
onMouseEnter={() => setTintHoveredColorIndex(index)}
|
||||||
|
onMouseLeave={() => setTintHoveredColorIndex(null)}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onClick={() => { updateTintColor(color); closeTintColorPicker(); }}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
borderRadius: "6px",
|
||||||
|
border: playerBarTintColor === color
|
||||||
|
? "2px solid #fff"
|
||||||
|
: "1px solid rgba(255,255,255,0.2)",
|
||||||
|
background: color,
|
||||||
|
cursor: "pointer",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{isCustomColor && (
|
||||||
|
<button
|
||||||
|
onClick={(e) => { e.stopPropagation(); removeTintCustomColor(color); }}
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: "-4px", right: "-4px",
|
||||||
|
width: "16px", height: "16px",
|
||||||
|
borderRadius: "50%",
|
||||||
|
border: "1px solid rgba(255,255,255,0.8)",
|
||||||
|
background: "rgba(0,0,0,0.8)",
|
||||||
|
color: "#fff",
|
||||||
|
cursor: "pointer",
|
||||||
|
fontSize: "10px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
opacity: isHovered ? 1 : 0,
|
||||||
|
transition: "opacity 0.2s ease",
|
||||||
|
zIndex: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ marginBottom: "12px" }}>
|
||||||
|
<div style={{ color: "rgba(255,255,255,0.7)", fontSize: "12px", marginBottom: "6px" }}>
|
||||||
|
Add Custom Color
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "flex", gap: "8px", alignItems: "center" }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={tintCustomInput}
|
||||||
|
onChange={(e) => setTintCustomInput(e.target.value)}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
updateTintColor(tintCustomInput);
|
||||||
|
addTintCustomColor();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
placeholder="#000000"
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
padding: "8px 12px",
|
||||||
|
borderRadius: "6px",
|
||||||
|
border: "1px solid rgba(255,255,255,0.2)",
|
||||||
|
background: "rgba(255,255,255,0.1)",
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: "14px",
|
||||||
|
fontFamily: "monospace",
|
||||||
|
boxSizing: "border-box",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={() => { updateTintColor(tintCustomInput); addTintCustomColor(); }}
|
||||||
|
style={{
|
||||||
|
width: "32px", height: "32px",
|
||||||
|
borderRadius: "6px",
|
||||||
|
border: "1px solid rgba(255,255,255,0.3)",
|
||||||
|
background: "rgba(255,255,255,0.15)",
|
||||||
|
color: "#fff",
|
||||||
|
cursor: "pointer",
|
||||||
|
fontSize: "16px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
transition: "all 0.2s ease",
|
||||||
|
}}
|
||||||
|
onMouseEnter={(e) => { e.currentTarget.style.background = "rgba(255,255,255,0.25)"; }}
|
||||||
|
onMouseLeave={(e) => { e.currentTarget.style.background = "rgba(255,255,255,0.15)"; }}
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={closeTintColorPicker}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
padding: "8px",
|
||||||
|
borderRadius: "6px",
|
||||||
|
border: "1px solid rgba(255,255,255,0.2)",
|
||||||
|
background: "rgba(255,255,255,0.1)",
|
||||||
|
color: "#fff",
|
||||||
|
cursor: "pointer",
|
||||||
|
fontSize: "12px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Done
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
<AnySwitch
|
<AnySwitch
|
||||||
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"
|
||||||
@@ -153,6 +498,7 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{CoverEverywhere && (
|
||||||
<AnySwitch
|
<AnySwitch
|
||||||
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"
|
||||||
@@ -169,6 +515,8 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{CoverEverywhere && (
|
||||||
<AnySwitch
|
<AnySwitch
|
||||||
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"
|
||||||
@@ -190,24 +538,11 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{CoverEverywhere && (
|
||||||
<LunaNumberSetting
|
<LunaNumberSetting
|
||||||
title="Text Glow"
|
|
||||||
desc="Adjust the glow size of lyrics (0-100, default: 20)"
|
|
||||||
min={0}
|
|
||||||
max={100}
|
|
||||||
step={1}
|
|
||||||
value={textGlow}
|
|
||||||
onNumber={(value: number) => {
|
|
||||||
setTextGlow((settings.textGlow = value));
|
|
||||||
// Update variables immediately when setting changes
|
|
||||||
if ((window as any).updateRadiantLyricsTextGlow) {
|
|
||||||
(window as any).updateRadiantLyricsTextGlow();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<LunaNumberSetting
|
|
||||||
title="Background Scale"
|
title="Background Scale"
|
||||||
desc="Adjust the scale of the background cover (1=10% - 50=500%)"
|
desc="Adjust the scale of the background cover (1=10% - 50=500%, default: 15)"
|
||||||
min={1}
|
min={1}
|
||||||
max={50}
|
max={50}
|
||||||
step={1}
|
step={1}
|
||||||
@@ -225,9 +560,11 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{CoverEverywhere && (
|
||||||
<LunaNumberSetting
|
<LunaNumberSetting
|
||||||
title="Background Radius"
|
title="Background Radius"
|
||||||
desc="Adjust the cover art corner radius (0-100%, 100% = circle)"
|
desc="Adjust the cover art corner radius (0-100%, default: 25)"
|
||||||
min={0}
|
min={0}
|
||||||
max={100}
|
max={100}
|
||||||
step={1}
|
step={1}
|
||||||
@@ -245,6 +582,8 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{CoverEverywhere && (
|
||||||
<LunaNumberSetting
|
<LunaNumberSetting
|
||||||
title="Background Contrast"
|
title="Background Contrast"
|
||||||
desc="Adjust the contrast of the spinning background (0-200, default: 120)"
|
desc="Adjust the contrast of the spinning background (0-200, default: 120)"
|
||||||
@@ -265,6 +604,8 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{CoverEverywhere && (
|
||||||
<LunaNumberSetting
|
<LunaNumberSetting
|
||||||
title="Background Blur"
|
title="Background Blur"
|
||||||
desc="Adjust the blur amount of the spinning background (0-200, default: 80)"
|
desc="Adjust the blur amount of the spinning background (0-200, default: 80)"
|
||||||
@@ -286,6 +627,8 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{CoverEverywhere && (
|
||||||
<LunaNumberSetting
|
<LunaNumberSetting
|
||||||
title="Background Brightness"
|
title="Background Brightness"
|
||||||
desc="Adjust the brightness of the spinning background (0-100, default: 40)"
|
desc="Adjust the brightness of the spinning background (0-100, default: 40)"
|
||||||
@@ -307,6 +650,8 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{CoverEverywhere && spinningArt && (
|
||||||
<LunaNumberSetting
|
<LunaNumberSetting
|
||||||
title="Spin Speed"
|
title="Spin Speed"
|
||||||
desc="Adjust the rotation speed in seconds (10-120, default: 45) - Lower values = Faster rotation"
|
desc="Adjust the rotation speed in seconds (10-120, default: 45) - Lower values = Faster rotation"
|
||||||
@@ -328,6 +673,8 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{CoverEverywhere && (
|
||||||
<AnySwitch
|
<AnySwitch
|
||||||
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"
|
||||||
@@ -346,6 +693,7 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</LunaSettings>
|
</LunaSettings>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/* Floating Rounded Player Bar from Obsidian <3 */
|
||||||
|
|
||||||
|
/* MARKER: Floating Player Bar CSS*/
|
||||||
|
|
||||||
|
[data-test="footer-player"] {
|
||||||
|
position: absolute !important;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin) !important;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Marker: Core Setup
|
// MARKER: Core Setup
|
||||||
import { LunaUnload, Tracer, ftch } from "@luna/core";
|
import { LunaUnload, Tracer, ftch } from "@luna/core";
|
||||||
import { StyleTag, PlayState, observePromise, observe } from "@luna/lib";
|
import { StyleTag, PlayState, observePromise, observe } from "@luna/lib";
|
||||||
import { settings, Settings } from "./Settings";
|
import { settings, Settings } from "./Settings";
|
||||||
@@ -13,6 +13,7 @@ import baseStyles from "file://styles.css?minify";
|
|||||||
import playerBarHidden from "file://player-bar-hidden.css?minify";
|
import playerBarHidden from "file://player-bar-hidden.css?minify";
|
||||||
import lyricsGlow from "file://lyrics-glow.css?minify";
|
import lyricsGlow from "file://lyrics-glow.css?minify";
|
||||||
import coverEverywhereCss from "file://cover-everywhere.css?minify";
|
import coverEverywhereCss from "file://cover-everywhere.css?minify";
|
||||||
|
import floatingPlayerBarCss from "file://floating-player-bar.css?minify";
|
||||||
|
|
||||||
// Core tracer and exports
|
// Core tracer and exports
|
||||||
export const { trace } = Tracer("[Radiant Lyrics]");
|
export const { trace } = Tracer("[Radiant Lyrics]");
|
||||||
@@ -27,12 +28,72 @@ const lyricsStyleTag = new StyleTag("RadiantLyrics-lyrics", unloads);
|
|||||||
const baseStyleTag = new StyleTag("RadiantLyrics-base", unloads);
|
const baseStyleTag = new StyleTag("RadiantLyrics-base", unloads);
|
||||||
const playerBarStyleTag = new StyleTag("RadiantLyrics-player-bar", unloads);
|
const playerBarStyleTag = new StyleTag("RadiantLyrics-player-bar", unloads);
|
||||||
const lyricsGlowStyleTag = new StyleTag("RadiantLyrics-lyrics-glow", unloads);
|
const lyricsGlowStyleTag = new StyleTag("RadiantLyrics-lyrics-glow", unloads);
|
||||||
|
const floatingPlayerBarStyleTag = new StyleTag("RadiantLyrics-floating-player-bar", unloads);
|
||||||
|
|
||||||
// Apply lyrics glow styles if enabled
|
// Apply lyrics glow styles if enabled
|
||||||
if (settings.lyricsGlowEnabled) {
|
if (settings.lyricsGlowEnabled) {
|
||||||
lyricsGlowStyleTag.css = lyricsGlow;
|
lyricsGlowStyleTag.css = lyricsGlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARKER: Floating Player Bar
|
||||||
|
|
||||||
|
// Hex color to RGB
|
||||||
|
// (i'm deranged and love Hexadecimal)
|
||||||
|
const hexToRgb = (hex: string): { r: number; g: number; b: number } => {
|
||||||
|
const cleaned = (hex || "#000000").replace("#", "");
|
||||||
|
return {
|
||||||
|
r: parseInt(cleaned.substring(0, 2), 16) || 0,
|
||||||
|
g: parseInt(cleaned.substring(2, 4), 16) || 0,
|
||||||
|
b: parseInt(cleaned.substring(4, 6), 16) || 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Apply Settings to Floating Player Bar using inline styles because idk.. CSS is hard (Change my mind!)
|
||||||
|
const applyPlayerBarTintToElement = (): void => {
|
||||||
|
const footerPlayer = document.querySelector('[data-test="footer-player"]') as HTMLElement;
|
||||||
|
if (!footerPlayer) return;
|
||||||
|
// Always apply tint regardless of floating state
|
||||||
|
const alpha = settings.playerBarTint / 10;
|
||||||
|
const { r, g, b } = hexToRgb(settings.playerBarTintColor);
|
||||||
|
footerPlayer.style.setProperty("background-color", `rgba(${r}, ${g}, ${b}, ${alpha})`, "important");
|
||||||
|
if (settings.floatingPlayerBar) {
|
||||||
|
footerPlayer.style.setProperty("border-radius", `${settings.playerBarRadius}px`, "important");
|
||||||
|
const spacing = settings.playerBarSpacing;
|
||||||
|
footerPlayer.style.setProperty("bottom", `${spacing}px`, "important");
|
||||||
|
footerPlayer.style.setProperty("left", `${spacing}px`, "important");
|
||||||
|
footerPlayer.style.setProperty("width", `calc(100% - ${spacing * 2}px)`, "important");
|
||||||
|
} else {
|
||||||
|
footerPlayer.style.removeProperty("border-radius");
|
||||||
|
footerPlayer.style.removeProperty("bottom");
|
||||||
|
footerPlayer.style.removeProperty("left");
|
||||||
|
footerPlayer.style.removeProperty("width");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Apply/update the floating player bar stylesheet + tint
|
||||||
|
const applyFloatingPlayerBar = (): void => {
|
||||||
|
if (settings.floatingPlayerBar) {
|
||||||
|
floatingPlayerBarStyleTag.css = floatingPlayerBarCss;
|
||||||
|
} else {
|
||||||
|
floatingPlayerBarStyleTag.remove();
|
||||||
|
}
|
||||||
|
applyPlayerBarTintToElement();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Alias for settings callback
|
||||||
|
const updateRadiantLyricsPlayerBarTint = applyFloatingPlayerBar;
|
||||||
|
|
||||||
|
// Apply floating player bar styles if enabled
|
||||||
|
if (settings.floatingPlayerBar) {
|
||||||
|
floatingPlayerBarStyleTag.css = floatingPlayerBarCss;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply Tint and Observe in case doesn't exist yet (ik this isnt the best way to do it but.. make a PR i dare ya!)
|
||||||
|
applyPlayerBarTintToElement();
|
||||||
|
observe<HTMLElement>(unloads, '[data-test="footer-player"]', () => {
|
||||||
|
applyPlayerBarTintToElement();
|
||||||
|
});
|
||||||
|
|
||||||
// Apply base styles always (contains global fixes and conditional UI hiding styles)
|
// Apply base styles always (contains global fixes and conditional UI hiding styles)
|
||||||
baseStyleTag.css = baseStyles;
|
baseStyleTag.css = baseStyles;
|
||||||
|
|
||||||
@@ -56,6 +117,9 @@ const updateRadiantLyricsStyles = function (): void {
|
|||||||
playerBarStyleTag.remove();
|
playerBarStyleTag.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle Floating Player Bar
|
||||||
|
applyFloatingPlayerBar();
|
||||||
|
|
||||||
// Update lyrics glow based on setting (Always apply if enabled, even when UI is hidden)
|
// Update lyrics glow based on setting (Always apply if enabled, even when UI is hidden)
|
||||||
const lyricsContainer = document.querySelector('[class^="_lyricsContainer"]');
|
const lyricsContainer = document.querySelector('[class^="_lyricsContainer"]');
|
||||||
if (lyricsContainer) {
|
if (lyricsContainer) {
|
||||||
@@ -96,7 +160,7 @@ const updateRadiantLyricsStyles = function (): void {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Marker: UI Visibility Control
|
// MARKER: UI Visibility Control
|
||||||
// UI state shared across features
|
// UI state shared across features
|
||||||
var isHidden = false;
|
var isHidden = false;
|
||||||
let unhideButtonAutoFadeTimeout: number | null = null;
|
let unhideButtonAutoFadeTimeout: number | null = null;
|
||||||
@@ -303,7 +367,7 @@ const createUnhideUIButton = function (): void {
|
|||||||
}, 1500);
|
}, 1500);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Marker: Background Rendering
|
// MARKER: Background Rendering
|
||||||
// Variable setup
|
// Variable setup
|
||||||
let globalSpinningBgStyleTag: StyleTag | null = null;
|
let globalSpinningBgStyleTag: StyleTag | null = null;
|
||||||
let globalBackgroundContainer: HTMLElement | null = null;
|
let globalBackgroundContainer: HTMLElement | null = null;
|
||||||
@@ -790,6 +854,7 @@ const updateRadiantLyricsNowPlayingBackground = function (): void {
|
|||||||
(window as any).updateRadiantLyricsNowPlayingBackground =
|
(window as any).updateRadiantLyricsNowPlayingBackground =
|
||||||
updateRadiantLyricsNowPlayingBackground;
|
updateRadiantLyricsNowPlayingBackground;
|
||||||
(window as any).updateRadiantLyricsTextGlow = updateRadiantLyricsTextGlow;
|
(window as any).updateRadiantLyricsTextGlow = updateRadiantLyricsTextGlow;
|
||||||
|
(window as any).updateRadiantLyricsPlayerBarTint = updateRadiantLyricsPlayerBarTint;
|
||||||
|
|
||||||
const cleanUpDynamicArt = function (): void {
|
const cleanUpDynamicArt = function (): void {
|
||||||
// Clean up cached Now Playing elements
|
// Clean up cached Now Playing elements
|
||||||
@@ -861,6 +926,16 @@ updateCoverArtBackground(1);
|
|||||||
unloads.add(() => {
|
unloads.add(() => {
|
||||||
cleanUpDynamicArt();
|
cleanUpDynamicArt();
|
||||||
|
|
||||||
|
// Clean up floating player bar inline styles
|
||||||
|
const footerPlayer = document.querySelector('[data-test="footer-player"]') as HTMLElement;
|
||||||
|
if (footerPlayer) {
|
||||||
|
footerPlayer.style.removeProperty("background-color");
|
||||||
|
footerPlayer.style.removeProperty("border-radius");
|
||||||
|
footerPlayer.style.removeProperty("bottom");
|
||||||
|
footerPlayer.style.removeProperty("left");
|
||||||
|
footerPlayer.style.removeProperty("width");
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up HideUI button auto-fade timeout
|
// Clean up HideUI button auto-fade timeout
|
||||||
if (unhideButtonAutoFadeTimeout != null) {
|
if (unhideButtonAutoFadeTimeout != null) {
|
||||||
window.clearTimeout(unhideButtonAutoFadeTimeout);
|
window.clearTimeout(unhideButtonAutoFadeTimeout);
|
||||||
|
|||||||
Reference in New Issue
Block a user