From 2a69153d0d7cdbb49646dc8531fdad6b10eae48b Mon Sep 17 00:00:00 2001 From: meowarex Date: Sun, 1 Jun 2025 01:15:14 +1000 Subject: [PATCH] Improved Hide UI --- plugins/clean-view-luna/src/index.ts | 324 +++++++++++++++++++++++---- 1 file changed, 281 insertions(+), 43 deletions(-) diff --git a/plugins/clean-view-luna/src/index.ts b/plugins/clean-view-luna/src/index.ts index a20d5ea..b02e275 100644 --- a/plugins/clean-view-luna/src/index.ts +++ b/plugins/clean-view-luna/src/index.ts @@ -7,16 +7,16 @@ export const { trace } = Tracer("[Clean View]"); export const unloads = new Set(); const styles = ` -[data-test="footer-player"], [class*="tabItems"] { +[class*="tabItems"] { opacity: 0 !important; transition: opacity 0.3s ease-in-out; } [class*="_imageContainer"] { - margin-top: 140px; + margin-top: 40px !important; } -[data-test="footer-player"]:hover, [class*="_tabItems"]:hover { +[class*="_tabItems"]:hover { opacity: 1 !important; } @@ -27,6 +27,51 @@ const styles = ` [class*="_nowPlayingContainer"] { padding-left: 6%; + padding-top: 20px !important; +} + +/* Move main content areas up */ +[class*="_trackTitleContainer"], +[class*="_artistContainer"], +[class*="_albumContainer"] { + margin-top: -20px !important; +} + +/* Move album art and lyrics content up */ +[class*="_lyricsContainer"], +[class*="_mediaContainer"] { + margin-top: -30px !important; +} + +/* Move play queue content up to fill button space */ +[class*="_playQueueContainer"], +[class*="_queueContainer"], +[data-test="play-queue"], +#playQueueSidebar { + margin-top: -40px !important; + padding-top: 10px !important; +} + +/* Move play queue list content up - more aggressive */ +[class*="_playQueueList"], +[class*="_queueList"], +[class*="_trackList"] { + margin-top: -60px !important; + padding-top: 0px !important; +} + +/* Target specific play queue elements more aggressively */ +#playQueueSidebar > div, +#playQueueSidebar > div > div { + margin-top: -40px !important; + padding-top: 0px !important; +} + +/* Override any existing padding in queue content area */ +[class*="_queueContent"], +[class*="_playQueueContent"] { + margin-top: -50px !important; + padding-top: 20px !important; } [class^="_bar"] { @@ -36,6 +81,47 @@ const styles = ` [class^="_bar"]>* { opacity: 0; } + +/* Hide bottom left controls completely - no hover reveal */ +[data-test="add-to-playlist"], +[data-test="remove-from-playlist"], +[data-test="like-toggle"], +[data-test="dislike-toggle"], +[data-test="favorite-toggle"], +[data-test="heart-button"], +[data-test="playlist-add"], +[class*="_trackActions"], +[class*="_bottomLeftControls"], +[class*="_actionButtons"], +[class*="_favoriteButton"], +[class*="_addToPlaylist"], +[class*="_lowerLeft"], +[class*="_bottomActions"], +[class*="_mediaControls"] > div:first-child, +button[title*="Add to"], +button[title*="Remove from"], +button[title*="Like"], +button[title*="Favorite"], +button[title*="Heart"], +button[aria-label*="Add to"], +button[aria-label*="Remove from"], +button[aria-label*="Like"], +button[aria-label*="Favorite"], +button[aria-label*="Heart"], +/* Target buttons in bottom left area specifically */ +[class*="_nowPlayingContainer"] button[class*="_button"]:not(.unhide-ui-button), +[class*="_nowPlayingContainer"] [class*="_iconButton"]:not(.unhide-ui-button), +/* Additional catch-all for bottom left area buttons */ +[class*="_nowPlayingContainer"] > div > div:first-child button:not(.unhide-ui-button), +[class*="_nowPlayingContainer"] > div:first-child button:not(.unhide-ui-button) { + display: none !important; +} + +/* Keep the Unhide button always visible with special styling */ +.unhide-ui-button { + opacity: 1 !important; + display: flex !important; +} `; const themeUrl = "https://raw.githubusercontent.com/itzzexcel/neptune-projects/refs/heads/main/plugins/plugins/not-actual-fullscreen/src/separated-lyrics.css"; @@ -62,33 +148,168 @@ var isCleanView = false; var appliedStyle: HTMLStyleElement | null = null; var currentTrackSrc: string | null = null; // Track current album art to prevent unnecessary updates -const toggleCleanButton = function(callback: () => void, icon: string, customIndex: number = 2): void { +const updateButtonStates = function(): void { + const hideButton = document.querySelector('.hide-ui-button') as HTMLElement; + const unhideButton = document.querySelector('.unhide-ui-button') as HTMLElement; + + if (hideButton) { + hideButton.style.display = isCleanView ? 'none' : 'flex'; + } + if (unhideButton) { + unhideButton.style.display = isCleanView ? 'flex' : 'none'; + } +}; + +const toggleCleanView = function(): void { + if (isCleanView) { + if (appliedStyle) { + appliedStyle.remove(); + appliedStyle = null; + } + } else { + appliedStyle = ApplyCSS(styles); + // Debug: Log bottom-left buttons to help identify selectors + debugBottomLeftButtons(); + } + isCleanView = !isCleanView; + updateButtonStates(); +}; + +const debugBottomLeftButtons = function(): void { setTimeout(() => { - const iconHolder = document.querySelector("[class*=\"_moreContainer\""); - if (!iconHolder) return; - - const button = document.createElement("button"); - button.style.width = "40px"; - button.style.border = "none"; - button.classList.add("xcl_customButton"); - - const buttonIcon = document.createElement("img"); - buttonIcon.src = icon; - buttonIcon.style.width = "100%"; - buttonIcon.style.height = "100%"; - button.onclick = callback; - - button.appendChild(buttonIcon); - - const children = Array.from(iconHolder.children); - if (customIndex <= children.length) { - iconHolder.insertBefore(button, children[customIndex - 1]); - } else { - iconHolder.appendChild(button); + const nowPlayingContainer = document.querySelector('[class*="_nowPlayingContainer"]'); + if (nowPlayingContainer) { + const buttons = nowPlayingContainer.querySelectorAll('button'); + trace.msg.log(`Found ${buttons.length} buttons in now playing container:`); + buttons.forEach((button, index) => { + const classes = button.className; + const dataTest = button.getAttribute('data-test'); + const title = button.getAttribute('title'); + const ariaLabel = button.getAttribute('aria-label'); + trace.msg.log(`Button ${index}: classes="${classes}", data-test="${dataTest}", title="${title}", aria-label="${ariaLabel}"`); + }); } }, 1000); }; +const createHideUIButton = function(): void { + setTimeout(() => { + // Look for the fullscreen button's parent container + const fullscreenButton = document.querySelector('[data-test="request-fullscreen"]'); + if (!fullscreenButton || !fullscreenButton.parentElement) { + // Retry if fullscreen button not found yet + setTimeout(() => createHideUIButton(), 1000); + return; + } + + // Check if our button already exists + if (document.querySelector('.hide-ui-button')) return; + + const buttonContainer = fullscreenButton.parentElement; + + // Create our hide UI button + const hideUIButton = document.createElement("button"); + hideUIButton.className = 'hide-ui-button'; + hideUIButton.setAttribute('aria-label', 'Hide UI'); + hideUIButton.setAttribute('title', 'Hide UI'); + hideUIButton.textContent = 'Hide UI'; + + // Style to match Tidal's buttons + hideUIButton.style.cssText = ` + background-color: var(--wave-color-solid-accent-fill); + color: black; + border: none; + border-radius: 12px; + height: 40px; + padding: 0 12px; + margin-left: 8px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: background-color 0.2s ease; + font-size: 12px; + font-weight: 600; + white-space: nowrap; + `; + + // Add hover effect + hideUIButton.addEventListener('mouseenter', () => { + hideUIButton.style.backgroundColor = 'lightgray'; + }); + + hideUIButton.addEventListener('mouseleave', () => { + hideUIButton.style.backgroundColor = 'var(--wave-color-solid-accent-fill)'; + }); + + hideUIButton.onclick = toggleCleanView; + + // Insert after the fullscreen button + buttonContainer.insertBefore(hideUIButton, fullscreenButton.nextSibling); + + trace.msg.log("Hide UI button added next to fullscreen button"); + updateButtonStates(); + }, 1000); +}; + +const createUnhideUIButton = function(): void { + setTimeout(() => { + // Check if our button already exists + if (document.querySelector('.unhide-ui-button')) return; + + // Create our unhide UI button and position it on the left side above player + const unhideUIButton = document.createElement("button"); + unhideUIButton.className = 'unhide-ui-button'; + unhideUIButton.setAttribute('aria-label', 'Unhide UI'); + unhideUIButton.setAttribute('title', 'Unhide UI'); + unhideUIButton.textContent = 'Unhide'; + + // Style for bottom-left positioning with blur and transparency + unhideUIButton.style.cssText = ` + position: fixed; + bottom: 120px; + left: 20px; + background-color: rgba(255, 255, 255, 0.2); + color: white; + border: 1px solid rgba(255, 255, 255, 0.3); + border-radius: 12px; + height: 50px; + padding: 0 16px; + cursor: pointer; + display: none; + align-items: center; + justify-content: center; + transition: all 0.3s ease; + font-size: 14px; + font-weight: 600; + white-space: nowrap; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + z-index: 9999; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + `; + + // Add hover effect + unhideUIButton.addEventListener('mouseenter', () => { + unhideUIButton.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'; + unhideUIButton.style.transform = 'scale(1.05)'; + }); + + unhideUIButton.addEventListener('mouseleave', () => { + unhideUIButton.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'; + unhideUIButton.style.transform = 'scale(1)'; + }); + + unhideUIButton.onclick = toggleCleanView; + + // Append to body instead of a specific container + document.body.appendChild(unhideUIButton); + + trace.msg.log("Unhide UI button added to bottom-left above player bar"); + updateButtonStates(); + }, 1500); // Slight delay after hide button +}; + function observeTrackTitle(): void { // Observe track title changes const trackTitleElement = document.querySelector('[class^="_trackTitleContainer"]'); @@ -129,11 +350,33 @@ function observeTrackTitle(): void { // Set up a periodic check as fallback const periodicCheck = setInterval(() => { onTrackChanged(); - }, 100); // Check every 3 seconds + }, 100); // Check every 100ms unloads.add(() => clearInterval(periodicCheck)); } +// Also observe for the buttons to appear so we can add our buttons +function observeForButtons(): void { + const observer = new MutationObserver(() => { + const fullscreenButton = document.querySelector('[data-test="request-fullscreen"]'); + if (fullscreenButton && !document.querySelector('.hide-ui-button')) { + createHideUIButton(); + } + + // Create unhide button if it doesn't exist + if (!document.querySelector('.unhide-ui-button')) { + createUnhideUIButton(); + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true + }); + + unloads.add(() => observer.disconnect()); +} + const onTrackChanged = function (method: number = 0): void { if (method === 1) { setTimeout(() => { @@ -237,18 +480,8 @@ const cleanUpDynamicArt = function (): void { const style = await HttpGet(themeUrl); const styleElement = style ? ApplyCSS(style) : null; -const toggleCleanButtonInstance = toggleCleanButton(() => { - if (isCleanView) { - if (appliedStyle) { - appliedStyle.remove(); - appliedStyle = null; - } - } else { - appliedStyle = ApplyCSS(styles); - } - isCleanView = !isCleanView; -}, "https://lexploits.top/favicon.ico", 2); - +// Initialize the button creation and observers +observeForButtons(); observeTrackTitle(); onTrackChanged(1); @@ -264,11 +497,16 @@ unloads.add(() => { cleanUpDynamicArt(); - // Clean up custom buttons - const customButtons = document.getElementsByClassName("xcl_customButton"); - Array.from(customButtons).forEach(element => { - element.remove(); - }); + // Clean up our custom buttons + const hideButton = document.querySelector('.hide-ui-button'); + if (hideButton && hideButton.parentNode) { + hideButton.parentNode.removeChild(hideButton); + } + + const unhideButton = document.querySelector('.unhide-ui-button'); + if (unhideButton && unhideButton.parentNode) { + unhideButton.parentNode.removeChild(unhideButton); + } // Clean up spin animation const spinAnimationStyle = document.querySelector('#spinAnimation');