Added Settings for Clean-View + Fixed Bugs with Player Bar song title

This commit is contained in:
2025-06-01 20:00:11 +10:00
parent e95aba7b88
commit f87f00e6a5
4 changed files with 112 additions and 317 deletions
+40
View File
@@ -0,0 +1,40 @@
import { ReactiveStore } from "@luna/core";
import { LunaSettings, LunaSwitchSetting } from "@luna/ui";
import React from "react";
export const settings = await ReactiveStore.getPluginStorage("CleanView", {
hideUIEnabled: false,
playerBarVisible: true,
});
export const Settings = () => {
const [hideUIEnabled, setHideUIEnabled] = React.useState(settings.hideUIEnabled);
const [playerBarVisible, setPlayerBarVisible] = React.useState(settings.playerBarVisible);
return (
<LunaSettings>
<LunaSwitchSetting
title="Hide UI Feature"
desc="Enable hide/unhide UI functionality with toggle buttons"
checked={hideUIEnabled}
onChange={(_, checked) => {
console.log("Hide UI Feature:", checked ? "enabled" : "disabled");
setHideUIEnabled((settings.hideUIEnabled = checked));
}}
/>
<LunaSwitchSetting
title="Player Bar Visibility in Hide UI Mode"
desc="Keep player bar visible when UI is hidden"
checked={playerBarVisible}
onChange={(_, checked) => {
console.log("Player Bar Visibility:", checked ? "visible" : "hidden");
setPlayerBarVisible((settings.playerBarVisible = checked));
// Update styles immediately when setting changes
if ((window as any).updateCleanViewStyles) {
(window as any).updateCleanViewStyles();
}
}}
/>
</LunaSettings>
);
};
+64 -4
View File
@@ -1,7 +1,8 @@
import { LunaUnload, Tracer, ftch } from "@luna/core";
import { settings, Settings } from "./Settings";
export const { trace } = Tracer("[Clean View]");
export { Settings };
// clean up resources
export const unloads = new Set<LunaUnload>();
@@ -25,6 +26,15 @@ const styles = `
margin: -40px;
}
/* Only prevent specific text elements in player bar from being affected by margin adjustments */
[data-test="footer-player"] [class*="_trackTitle"],
[data-test="footer-player"] [class*="_artistName"],
[data-test="footer-player"] [class*="_trackInfo"],
[data-test="footer-player"] [class*="_trackContainer"] {
margin-top: 0 !important;
transform: none !important;
}
[class*="_nowPlayingContainer"] {
padding-left: 6%;
padding-top: 20px !important;
@@ -153,13 +163,54 @@ const updateButtonStates = function(): void {
const unhideButton = document.querySelector('.unhide-ui-button') as HTMLElement;
if (hideButton) {
hideButton.style.display = isCleanView ? 'none' : 'flex';
hideButton.style.display = (settings.hideUIEnabled && !isCleanView) ? 'flex' : 'none';
}
if (unhideButton) {
unhideButton.style.display = isCleanView ? 'flex' : 'none';
unhideButton.style.display = (settings.hideUIEnabled && isCleanView) ? 'flex' : 'none';
}
};
// Function to get dynamic styles including player bar visibility
const getDynamicStyles = function(): string {
let dynamicStyles = styles;
// Add player bar hiding with hover reveal if setting is disabled
if (!settings.playerBarVisible) {
dynamicStyles += `
/* Hide player bar when setting is disabled, but show on hover */
[data-test="footer-player"] {
opacity: 0 !important;
transition: opacity 0.3s ease-in-out !important;
pointer-events: auto !important;
}
[data-test="footer-player"]:hover {
opacity: 1 !important;
}
/* Also show player bar when hovering over the bottom area */
body:has([data-test="footer-player"]:hover) [data-test="footer-player"],
body [data-test="footer-player"]:hover {
opacity: 1 !important;
}
`;
}
return dynamicStyles;
};
// Function to update styles when settings change
const updateCleanViewStyles = function(): void {
if (isCleanView && appliedStyle) {
// Remove old styles and apply new ones with updated settings
appliedStyle.remove();
appliedStyle = ApplyCSS(getDynamicStyles());
}
};
// Make this function available globally so Settings can call it
(window as any).updateCleanViewStyles = updateCleanViewStyles;
const toggleCleanView = function(): void {
if (isCleanView) {
if (appliedStyle) {
@@ -167,7 +218,7 @@ const toggleCleanView = function(): void {
appliedStyle = null;
}
} else {
appliedStyle = ApplyCSS(styles);
appliedStyle = ApplyCSS(getDynamicStyles());
// Debug: Log bottom-left buttons to help identify selectors
//debugBottomLeftButtons();
}
@@ -194,6 +245,9 @@ const toggleCleanView = function(): void {
const createHideUIButton = function(): void {
setTimeout(() => {
// Only create button if Hide UI is enabled in settings
if (!settings.hideUIEnabled) return;
// Look for the fullscreen button's parent container
const fullscreenButton = document.querySelector('[data-test="request-fullscreen"]');
if (!fullscreenButton || !fullscreenButton.parentElement) {
@@ -254,6 +308,9 @@ const createHideUIButton = function(): void {
const createUnhideUIButton = function(): void {
setTimeout(() => {
// Only create button if Hide UI is enabled in settings
if (!settings.hideUIEnabled) return;
// Check if our button already exists
if (document.querySelector('.unhide-ui-button')) return;
@@ -358,6 +415,8 @@ function observeTrackTitle(): void {
// Also observe for the buttons to appear so we can add our buttons
function observeForButtons(): void {
const observer = new MutationObserver(() => {
// Only observe for buttons if Hide UI is enabled
if (settings.hideUIEnabled) {
const fullscreenButton = document.querySelector('[data-test="request-fullscreen"]');
if (fullscreenButton && !document.querySelector('.hide-ui-button')) {
createHideUIButton();
@@ -367,6 +426,7 @@ function observeForButtons(): void {
if (!document.querySelector('.unhide-ui-button')) {
createUnhideUIButton();
}
}
});
observer.observe(document.body, {
-301
View File
@@ -1,301 +0,0 @@
/*
{
"name": "Abyss Neptune",
"author": "@itzzexcel",
"description": "Abyss Neptune: ShadowX Theme from Spicetify to TIDAL (17/Jan/2025)"
}
*/
::-webkit-scrollbar {
display: none;
}
:root {
--wave-color-solid-accent-fill: white;
--wave-color-solid-rainbow-yellow-fill: white;
--wave-color-solid-contrast-fill: white;
--wave-color-solid-base-brighter: black;
--wave-text-body-medium: white !important;
--track-vibrant-color: white !important;
--wave-color-opacity-contrast-fill-ultra-thin: #fffafa1a !important;
--wave-color-solid-rainbow-yellow-darkest: #fffafa1a !important;
--wave-color-solid-accent-dark: rgb(128, 128, 128);
}
/* Credits to https://github.com/surfbryce for the fonts */
@font-face {
font-family: "AbyssFont";
font-weight: 400;
src: url("https://excel.lexploits.top/extra/tidal/LyricsRegular.woff2") format("woff2");
}
@font-face {
font-family: "AbyssFont";
font-weight: 500;
src: url("https://excel.lexploits.top/extra/tidal/LyricsMedium.woff2") format("woff2");
}
@font-face {
font-family: "AbyssFont";
font-weight: 600;
src: url("https://excel.lexploits.top/extra/tidal/LyricsSemibold.woff2") format("woff2");
}
@font-face {
font-family: "AbyssFont";
font-weight: 700;
src: url("https://excel.lexploits.top/extra/tidal/LyricsBold.woff2") format("woff2");
}
[class^="followingButton"],
[title="Unfollow"],
[title="Follow"],
[title="Unfollow"]>span,
[title="Follow"]>span {
background-color: var(--wave-color-solid-rainbow-yellow-fill) !important;
color: var(--wave-color-solid-base-brighter);
}
[class^="_wave-badge-color-max"] {
color: black !important;
background-color: var(--wave-color-solid-accent-fill);
border-radius: 3px;
}
[data-test="main-layout-sidebar-wrapper"] {
border-right: rgb(25, 25, 25) 1px solid;
}
[class^="_wave-badge"] {
background-color: var(--wave-color-solid-accent-fill);
border-radius: 4px;
color: black;
}
[class^="_progressBarWrapper"] {
color: var(--wave-color-solid-accent-fill) !important;
}
[class^="_sidebarItem"]>span {
color: var(--wave-color-solid-accent-dark);
}
[data-test="main-layout-header"] {
border-left: 0 !important;
}
[class^="_sidebarItem"]:hover span {
color: var(--wave-color-solid-contrast-fill);
}
[class^="_sidebarItem"] [class^="active"]>span {
color: var(--wave-color-solid-accent-dark) !important;
}
[class^="_active"] {
color: var(--wave-color-solid-accent-fill) !important;
}
[class^="ReactVirtualized__Grid"] {
border-radius: 10px;
margin: 5px;
}
[data-test="media-table"]>div>div>div {
border: 1px solid rgb(25, 25, 25) !important;
}
[class^="ReactVirtualized__Grid__innerScrollContainer"] {
border: none;
margin: 5px;
}
[class^="button"]>span {
color: black;
}
[class^="_explicitBadge"] {
color: var(--wave-color-solid-accent-fill);
}
[class^="viewAllButton"] {
border-radius: 4px;
display: grid;
place-items: center;
}
[data-test="current-media-imagery"] {
border: 0 !important;
margin: none;
}
[class^="_imageBorder"] {
display: none;
}
[class^="_headerButtons"]>button,
[class^="_headerButtons"]>button>span,
[data-test="toggle-picture-in-picture"] {
background-color: var(--wave-color-solid-accent-fill) !important;
color: black;
}
[class^="_container"]>[class^="_navigationArrows"] {
color: black;
background-color: var(--wave-color-solid-accent-fill) !important;
border-radius: 4px;
}
[class^="_buttons"]>button>span {
color: black !important;
}
[class^="_container"]>button {
border: 0px none;
}
[data-test="feed-sidebar"] {
margin-top: 10px;
}
[data-test="footer-player"] {
width: calc(100% - 20px);
bottom: 10px;
left: 10px;
border: 1px solid rgb(25, 25, 25);
border-radius: 4px !important;
position: absolute !important;
}
[class^="_tooltipContainer"]>button {
background-color: var(--wave-color-solid-accent-fill);
color: black;
}
[class^="_tooltipContainer"]>button:hover {
background-color: lightgray !important;
}
[class^="_tableRow"]:hover>*,
[data-test-is-playing="true"]>* {
color: var(--wave-color-solid-accent-fill) !important;
}
[class^="_tableRow"]>*,
[data-test-is-playing="false"]>* {
color: lightgray !important;
}
[class*="coverColumn"] {
padding-left: 5px !important;
}
[class^="actionList"] {
background-color: transparent;
margin: 0px;
border-radius: 5px;
}
button[data-test="request-fullscreen"],
button[data-test="close-now-playing"],
button[data-test="play-all"],
button[data-test="shuffle-all"] {
color: black;
background-color: var(--wave-color-solid-accent-fill);
border-radius: 12px;
}
button[data-test="request-fullscreen"]:hover,
button[data-test="close-now-playing"]:hover {
color: black;
background-color: lightgray !important;
}
.neptune-switch-checkbox:checked+.neptune-switch {
background-color: rgba(255, 255, 255, 0.1);
}
[data-test="navigation-arrows"]>button {
background-color: var(--wave-color-solid-accent-fill) !important;
color: black !important;
border-radius: 5px;
}
[data-test="navigation-arrows"]>button:disabled {
background-color: lightgray !important;
opacity: 1;
}
[data-test="main-layout-header"],
[data-test="feed-sidebar"],
[data-test="stream-metadata"],
[data-test="footer-player"] {
background-color: rgba(0, 0, 0, 0.8) !important;
backdrop-filter: blur(10px);
border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin) !important;
}
[data-wave-color=textUrl] {
color: var(--wave-color-solid-accent-fill);
}
[class^="_smallHeader"] {
margin-top: 7.5px;
}
[data-test="play-all"]>div>*,
[data-test="shuffle-all"]>div>*,
[data-test="play-all"],
[data-test="shuffle-all"] {
color: var(--wave-color-solid-accent-fill) !important;
background-color: transparent !important;
}
[class^="__NEPTUNE_PAGE"],
[data-test="main"] {
margin-top: 35px;
}
[data-test="button-desktop-release-notes"],
[data-test="button-release-notes"] {
background-color: white;
}
[data-test="button-desktop-release-notes"]:hover,
[data-test="button-release-notes"]:hover {
background-color: lightgray !important;
transition: none !important;
}
#playQueueSidebar {
top: 50px !important;
border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin);
margin: 2px;
margin-right: -14px !important;
background-color: rgba(0, 0, 0, 0.8) !important;
backdrop-filter: blur(10px);
}
[class^="_bottomGradient"] {
visibility: hidden;
}
[data-test="settings-page"] {
padding-bottom: 60px !important;
}
[data-test="query-suggestions"],
[data-test="recent-searches-container"] {
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(10px);
}
[data-test="contextmenu"] {
border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin) !important;
}
[class^="_dataContainer_"]::before {
background-image: var(--img);
filter: blur(10px) brightness(0.4);
}
-4
View File
@@ -1,4 +0,0 @@
declare module "*.css" {
const content: string;
export default content;
}