From 14a8521940739d3192f2622222b5be85ae962e15 Mon Sep 17 00:00:00 2001 From: meowarex Date: Mon, 2 Jun 2025 11:26:43 +1000 Subject: [PATCH 1/4] WIP | Switch to Local CSS --- plugins/clean-view-luna/src/index.ts | 130 +--------- plugins/clean-view-luna/src/styles.css | 124 ++++++++++ plugins/copy-lyrics-luna/src/index.ts | 16 +- plugins/copy-lyrics-luna/src/styles.css | 9 + plugins/oled-theme-luna/src/index.ts | 35 +-- plugins/oled-theme-luna/src/theme.css | 301 ++++++++++++++++++++++++ 6 files changed, 453 insertions(+), 162 deletions(-) create mode 100644 plugins/clean-view-luna/src/styles.css create mode 100644 plugins/copy-lyrics-luna/src/styles.css create mode 100644 plugins/oled-theme-luna/src/theme.css diff --git a/plugins/clean-view-luna/src/index.ts b/plugins/clean-view-luna/src/index.ts index 7057710..a2a3dab 100644 --- a/plugins/clean-view-luna/src/index.ts +++ b/plugins/clean-view-luna/src/index.ts @@ -1,139 +1,15 @@ import { LunaUnload, Tracer, ftch } from "@luna/core"; import { settings, Settings } from "./Settings"; +// Import CSS directly using Luna's file:// syntax +import styles from "file://styles.css?minify"; + export const { trace } = Tracer("[Clean View]"); export { Settings }; // clean up resources export const unloads = new Set(); -const styles = ` -[class*="tabItems"] { - opacity: 0 !important; - transition: opacity 0.3s ease-in-out; -} - -[class*="_imageContainer"] { - margin-top: 40px !important; -} - -[class*="_tabItems"]:hover { - opacity: 1 !important; -} - -[data-test="header-container"] { - opacity: 0; - 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; -} - -/* 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"] { - background-color: transparent; -} - -[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"; function ApplyCSS(style: string): HTMLStyleElement { diff --git a/plugins/clean-view-luna/src/styles.css b/plugins/clean-view-luna/src/styles.css new file mode 100644 index 0000000..be53a08 --- /dev/null +++ b/plugins/clean-view-luna/src/styles.css @@ -0,0 +1,124 @@ +[class*="tabItems"] { + opacity: 0 !important; + transition: opacity 0.3s ease-in-out; +} + +[class*="_imageContainer"] { + margin-top: 40px !important; +} + +[class*="_tabItems"]:hover { + opacity: 1 !important; +} + +[data-test="header-container"] { + opacity: 0; + 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; +} + +/* 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"] { + background-color: transparent; +} + +[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; +} \ No newline at end of file diff --git a/plugins/copy-lyrics-luna/src/index.ts b/plugins/copy-lyrics-luna/src/index.ts index 5496f1a..9997d5a 100644 --- a/plugins/copy-lyrics-luna/src/index.ts +++ b/plugins/copy-lyrics-luna/src/index.ts @@ -1,23 +1,13 @@ import { LunaUnload, Tracer } from "@luna/core"; +// Import CSS directly using Luna's file:// syntax +import unlockSelection from "file://styles.css?minify"; + export const { trace } = Tracer("[Copy Lyrics]"); - // clean up resources export const unloads = new Set(); -const unlockSelection = ` -[class^="_lyricsText"]>div>span { - user-select: text; - cursor: text; -} - -::selection { - background: rgb(0, 0, 0); - color: rgb(255, 255, 255); -} -`; - function ApplyCSS(style: string): HTMLStyleElement { const styleElement = document.createElement("style"); styleElement.type = "text/css"; diff --git a/plugins/copy-lyrics-luna/src/styles.css b/plugins/copy-lyrics-luna/src/styles.css new file mode 100644 index 0000000..deb70db --- /dev/null +++ b/plugins/copy-lyrics-luna/src/styles.css @@ -0,0 +1,9 @@ +[class^="_lyricsText"]>div>span { + user-select: text; + cursor: text; +} + +::selection { + background: rgb(72, 0, 60); + color: rgb(255, 255, 255); +} \ No newline at end of file diff --git a/plugins/oled-theme-luna/src/index.ts b/plugins/oled-theme-luna/src/index.ts index fb0724b..531f76d 100644 --- a/plugins/oled-theme-luna/src/index.ts +++ b/plugins/oled-theme-luna/src/index.ts @@ -1,21 +1,20 @@ -import { LunaUnload, Tracer, ftch } from "@luna/core"; +import { LunaUnload, Tracer } from "@luna/core"; import { settings, Settings } from "./Settings"; +// Import CSS directly using Luna's file:// syntax.. Took me a while to figure out this existed +import originalStyle from "file://theme.css?minify"; + export const { trace } = Tracer("[OLED Theme]"); export { Settings }; -const themeUrl = "https://raw.githubusercontent.com/ItzzExcel/neptune-projects/refs/heads/main/themes/black-neptune-theme.css"; - // called when plugin is unloaded. // clean up resources export const unloads = new Set(); -let originalStyle: string | null = null; let appliedStyleElement: HTMLStyleElement | null = null; // Function to apply theme styles based on current settings const applyThemeStyles = function(): void { - if (!originalStyle) return; // Remove existing style element if it exists if (appliedStyleElement && appliedStyleElement.parentNode) { @@ -73,7 +72,7 @@ const applyThemeStyles = function(): void { /\[class[^=]*=["'][^"']*action/i.test(rule) || /\[class[^=]*=["'][^"']*control/i.test(rule); - // Return true to keep the rule (i.e., if it's NOT a button rule) + // Return true to keep the rule if it's NOT a button rule return !isButtonRule; }); @@ -89,20 +88,12 @@ const applyThemeStyles = function(): void { // Make this function available globally so Settings can call it (window as any).updateOLEDThemeStyles = applyThemeStyles; -// Added Top-level async since Luna plugins are modules <3 -originalStyle = await ftch.text(themeUrl).catch((error: Error) => { - trace.msg.err(`Failed to fetch theme CSS: ${error.message}`); - return null; -}); +// Apply the OLED theme +applyThemeStyles(); -// Apply the OLED theme if CSS was fetched successfully -if (originalStyle) { - applyThemeStyles(); - - // Add cleanup to unloads - unloads.add(() => { - if (appliedStyleElement && appliedStyleElement.parentNode) { - appliedStyleElement.parentNode.removeChild(appliedStyleElement); - } - }); -} \ No newline at end of file +// Add cleanup to unloads +unloads.add(() => { + if (appliedStyleElement && appliedStyleElement.parentNode) { + appliedStyleElement.parentNode.removeChild(appliedStyleElement); + } +}); \ No newline at end of file diff --git a/plugins/oled-theme-luna/src/theme.css b/plugins/oled-theme-luna/src/theme.css new file mode 100644 index 0000000..909948e --- /dev/null +++ b/plugins/oled-theme-luna/src/theme.css @@ -0,0 +1,301 @@ +/* +{ + "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); +} \ No newline at end of file From 5b8955f23fc214f074c7281df9355cb24b854ca3 Mon Sep 17 00:00:00 2001 From: meowarex Date: Mon, 2 Jun 2025 11:33:52 +1000 Subject: [PATCH 2/4] Refactor of CSS Rule Logic --- .../src/{theme.css => dark-theme.css} | 0 plugins/oled-theme-luna/src/index.ts | 63 +---- plugins/oled-theme-luna/src/oled-friendly.css | 215 ++++++++++++++++++ 3 files changed, 222 insertions(+), 56 deletions(-) rename plugins/oled-theme-luna/src/{theme.css => dark-theme.css} (100%) create mode 100644 plugins/oled-theme-luna/src/oled-friendly.css diff --git a/plugins/oled-theme-luna/src/theme.css b/plugins/oled-theme-luna/src/dark-theme.css similarity index 100% rename from plugins/oled-theme-luna/src/theme.css rename to plugins/oled-theme-luna/src/dark-theme.css diff --git a/plugins/oled-theme-luna/src/index.ts b/plugins/oled-theme-luna/src/index.ts index 531f76d..c73b219 100644 --- a/plugins/oled-theme-luna/src/index.ts +++ b/plugins/oled-theme-luna/src/index.ts @@ -1,8 +1,9 @@ import { LunaUnload, Tracer } from "@luna/core"; import { settings, Settings } from "./Settings"; -// Import CSS directly using Luna's file:// syntax.. Took me a while to figure out this existed -import originalStyle from "file://theme.css?minify"; +// Import CSS files directly using Luna's file:// syntax +import fullTheme from "file://dark-theme.css?minify"; +import oledFriendlyTheme from "file://oled-friendly.css?minify"; export const { trace } = Tracer("[OLED Theme]"); export { Settings }; @@ -21,67 +22,17 @@ const applyThemeStyles = function(): void { appliedStyleElement.parentNode.removeChild(appliedStyleElement); } - let modifiedStyle = originalStyle; + // Choose the appropriate CSS file based on OLED Friendly Buttons setting + let selectedStyle = settings.oledFriendlyButtons ? oledFriendlyTheme : fullTheme; // Remove SeekBar coloring if Quality Color Matched Seek Bar is enabled if (settings.qualityColorMatchedSeekBar) { - modifiedStyle = modifiedStyle.replace(/\[class\^="_progressBarWrapper"\]\s*\{[^}]*\}/g, ''); - } - - // Remove button styling if OLED Friendly Buttons is enabled - if (settings.oledFriendlyButtons) { - const originalRuleCount = (modifiedStyle.match(/\{[^}]*\}/g) || []).length; - - // Split CSS into individual rules and filter out button-related ones - const cssRules = modifiedStyle.split('}').filter(rule => rule.trim()); - const filteredRules = cssRules.filter(rule => { - const lowerRule = rule.toLowerCase(); - - // Check if this rule might affect buttons - const isButtonRule = - // Direct button selectors - lowerRule.includes('button') || - lowerRule.includes('[role="button"]') || - lowerRule.includes('[type="button"]') || - lowerRule.includes('[type="submit"]') || - lowerRule.includes('[type="reset"]') || - // Class-based button selectors - lowerRule.includes('btn') || - lowerRule.includes('_button') || - lowerRule.includes('-button') || - lowerRule.includes('button-') || - lowerRule.includes('button_') || - // Common button-related classes - lowerRule.includes('clickable') || - lowerRule.includes('action') || - lowerRule.includes('control') || - lowerRule.includes('icon') || - // Data attributes that might be buttons - lowerRule.includes('data-test') && lowerRule.includes('button') || - lowerRule.includes('aria-label') && lowerRule.includes('button') || - // Button states - lowerRule.includes(':hover') && (lowerRule.includes('button') || lowerRule.includes('btn')) || - lowerRule.includes(':focus') && (lowerRule.includes('button') || lowerRule.includes('btn')) || - lowerRule.includes(':active') && (lowerRule.includes('button') || lowerRule.includes('btn')) || - // Cursor pointer (often used on buttons) - lowerRule.includes('cursor') && lowerRule.includes('pointer') || - // Any class containing button-like patterns - /\[class[^=]*=["'][^"']*button/i.test(rule) || - /\[class[^=]*=["'][^"']*btn/i.test(rule) || - /\[class[^=]*=["'][^"']*click/i.test(rule) || - /\[class[^=]*=["'][^"']*action/i.test(rule) || - /\[class[^=]*=["'][^"']*control/i.test(rule); - - // Return true to keep the rule if it's NOT a button rule - return !isButtonRule; - }); - - modifiedStyle = filteredRules.join('} ') + (filteredRules.length > 0 ? '}' : ''); + selectedStyle = selectedStyle.replace(/\[class\^="_progressBarWrapper"\]\s*\{[^}]*\}/g, ''); } appliedStyleElement = document.createElement("style"); appliedStyleElement.type = "text/css"; - appliedStyleElement.textContent = modifiedStyle; + appliedStyleElement.textContent = selectedStyle; document.head.appendChild(appliedStyleElement); }; diff --git a/plugins/oled-theme-luna/src/oled-friendly.css b/plugins/oled-theme-luna/src/oled-friendly.css new file mode 100644 index 0000000..e513a80 --- /dev/null +++ b/plugins/oled-theme-luna/src/oled-friendly.css @@ -0,0 +1,215 @@ +/* +{ + "name": "Abyss Neptune - OLED Friendly", + "author": "@itzzexcel", + "description": "Abyss Neptune theme without button styling for OLED displays" +} +*/ + +::-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^="_explicitBadge"] { + color: var(--wave-color-solid-accent-fill); +} + +[data-test="current-media-imagery"] { + border: 0 !important; + margin: none; +} + +[class^="_imageBorder"] { + display: 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^="_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; +} + +.neptune-switch-checkbox:checked+.neptune-switch { + background-color: rgba(255, 255, 255, 0.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; +} + +[class^="__NEPTUNE_PAGE"], +[data-test="main"] { + margin-top: 35px; +} + +#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); +} \ No newline at end of file From f5ae59a18ea892623e2cc4e7eea008fc7b0584a9 Mon Sep 17 00:00:00 2001 From: meowarex Date: Mon, 2 Jun 2025 11:36:38 +1000 Subject: [PATCH 3/4] Update Workflows --- .github/workflows/{releaseMaster.yml => release.yml} | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename .github/workflows/{releaseMaster.yml => release.yml} (93%) diff --git a/.github/workflows/releaseMaster.yml b/.github/workflows/release.yml similarity index 93% rename from .github/workflows/releaseMaster.yml rename to .github/workflows/release.yml index cb7529f..2590582 100644 --- a/.github/workflows/releaseMaster.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,9 @@ -name: "[master] Release" +name: "[main] Release" on: push: + branches: + - main paths-ignore: - "**/*.md" - ".vscode/**" From 926f2ceb9e087073b36f9d76564d48114de54f1a Mon Sep 17 00:00:00 2001 From: meowarex Date: Mon, 2 Jun 2025 12:16:37 +1000 Subject: [PATCH 4/4] WIP | Light Theme --- plugins/oled-theme-luna/src/Settings.tsx | 15 + plugins/oled-theme-luna/src/index.ts | 15 +- plugins/oled-theme-luna/src/light-theme.css | 400 ++++++++++++++++++++ 3 files changed, 427 insertions(+), 3 deletions(-) create mode 100644 plugins/oled-theme-luna/src/light-theme.css diff --git a/plugins/oled-theme-luna/src/Settings.tsx b/plugins/oled-theme-luna/src/Settings.tsx index bb7fae6..1163f70 100644 --- a/plugins/oled-theme-luna/src/Settings.tsx +++ b/plugins/oled-theme-luna/src/Settings.tsx @@ -5,11 +5,13 @@ import React from "react"; export const settings = await ReactiveStore.getPluginStorage("OLEDTheme", { qualityColorMatchedSeekBar: true, oledFriendlyButtons: true, + lightMode: false, }); export const Settings = () => { const [qualityColorMatchedSeekBar, setQualityColorMatchedSeekBar] = React.useState(settings.qualityColorMatchedSeekBar); const [oledFriendlyButtons, setOledFriendlyButtons] = React.useState(settings.oledFriendlyButtons); + const [lightMode, setLightMode] = React.useState(settings.lightMode); return ( @@ -39,6 +41,19 @@ export const Settings = () => { } }} /> + { + console.log("Light Mode:", checked ? "enabled" : "disabled"); + setLightMode((settings.lightMode = checked)); + // Update styles immediately when setting changes + if ((window as any).updateOLEDThemeStyles) { + (window as any).updateOLEDThemeStyles(); + } + }} + /> ); }; \ No newline at end of file diff --git a/plugins/oled-theme-luna/src/index.ts b/plugins/oled-theme-luna/src/index.ts index c73b219..98ed1e9 100644 --- a/plugins/oled-theme-luna/src/index.ts +++ b/plugins/oled-theme-luna/src/index.ts @@ -2,8 +2,9 @@ import { LunaUnload, Tracer } from "@luna/core"; import { settings, Settings } from "./Settings"; // Import CSS files directly using Luna's file:// syntax -import fullTheme from "file://dark-theme.css?minify"; +import darkTheme from "file://dark-theme.css?minify"; import oledFriendlyTheme from "file://oled-friendly.css?minify"; +import lightTheme from "file://light-theme.css?minify"; export const { trace } = Tracer("[OLED Theme]"); export { Settings }; @@ -22,8 +23,16 @@ const applyThemeStyles = function(): void { appliedStyleElement.parentNode.removeChild(appliedStyleElement); } - // Choose the appropriate CSS file based on OLED Friendly Buttons setting - let selectedStyle = settings.oledFriendlyButtons ? oledFriendlyTheme : fullTheme; + // Choose the appropriate CSS file based on settings + let selectedStyle: string; + + if (settings.lightMode) { + // Light mode always uses the full light theme (OLED friendly doesn't apply to light theme) + selectedStyle = lightTheme; + } else { + // Dark mode - choose between full dark theme or OLED friendly version + selectedStyle = settings.oledFriendlyButtons ? oledFriendlyTheme : darkTheme; + } // Remove SeekBar coloring if Quality Color Matched Seek Bar is enabled if (settings.qualityColorMatchedSeekBar) { diff --git a/plugins/oled-theme-luna/src/light-theme.css b/plugins/oled-theme-luna/src/light-theme.css new file mode 100644 index 0000000..a49dbb8 --- /dev/null +++ b/plugins/oled-theme-luna/src/light-theme.css @@ -0,0 +1,400 @@ +/* +{ + "name": "Abyss Neptune - Light", + "author": "@itzzexcel", + "description": "Abyss Neptune Light Theme for TIDAL (17/Jan/2025)" +} +*/ + +::-webkit-scrollbar { + display: none; +} + +:root { + --wave-color-solid-accent-fill: #666666; + --wave-color-solid-rainbow-yellow-fill: #666666; + --wave-color-solid-contrast-fill: #666666; + --wave-color-solid-base-brighter: #666666; + --wave-text-body-medium: #333333 !important; + --track-vibrant-color: #666666 !important; + --wave-color-opacity-contrast-fill-ultra-thin: #c0c0c0 !important; + --wave-color-solid-rainbow-yellow-darkest: #c0c0c0 !important; + --wave-color-solid-accent-dark: #555555; +} + +/* 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: #333333 !important; + background-color: var(--wave-color-solid-accent-fill); + border-radius: 3px; +} + +[data-test="main-layout-sidebar-wrapper"] { + border-right: rgb(230, 230, 230) 1px solid; + background-color: rgba(250, 250, 250, 0.95) !important; +} + +[class^="_wave-badge"] { + background-color: var(--wave-color-solid-accent-fill); + border-radius: 4px; + color: #333333; +} + +[class^="_progressBarWrapper"] { + color: var(--wave-color-solid-accent-fill) !important; +} + +[class^="_sidebarItem"]>span { + color: #666666; +} + +[data-test="main-layout-header"] { + border-left: 0 !important; +} + +[class^="_sidebarItem"]:hover span { + color: #333333; +} + +[class^="_sidebarItem"] [class^="active"]>span { + color: #333333 !important; +} + +/* Sidebar icons and text - ensure grey colors */ +[data-test="main-layout-sidebar-wrapper"] svg, +[data-test="main-layout-sidebar-wrapper"] path, +[class^="_sidebarItem"] svg, +[class^="_sidebarItem"] path { + fill: #666666 !important; + color: #666666 !important; +} + +[data-test="main-layout-sidebar-wrapper"] span, +[class^="_sidebarItem"] span { + color: #666666 !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(230, 230, 230) !important; +} + +[class^="ReactVirtualized__Grid__innerScrollContainer"] { + border: none; + margin: 5px; +} + +[class^="button"]>span { + color: #333333; +} + +/* Override button span color specifically for play/shuffle buttons */ +button[data-test="play-all"] [class^="button"]>span, +button[data-test="shuffle-all"] [class^="button"]>span, +button[data-test="play-all"] span, +button[data-test="shuffle-all"] span { + color: white !important; +} + +[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: #333333; +} + +[class^="_container"]>[class^="_navigationArrows"] { + color: #333333; + background-color: var(--wave-color-solid-accent-fill) !important; + border-radius: 4px; +} + +[class^="_buttons"]>button>span { + color: #333333 !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 rgba(200, 200, 200, 0.7); + border-radius: 4px !important; + position: absolute !important; +} + +[class^="_tooltipContainer"]>button { + background-color: var(--wave-color-solid-accent-fill); + color: #333333; +} + +[class^="_tooltipContainer"]>button:hover { + background-color: #555555 !important; +} + +[class^="_tableRow"]:hover>*, +[data-test-is-playing="true"]>* { + color: #333333 !important; +} + +[class^="_tableRow"]>*, +[data-test-is-playing="false"]>* { + color: #333333 !important; +} + +/* Track list text - ensure all text is dark */ +[data-test="media-table"] *, +[class^="_trackTitle"], +[class^="_artistName"], +[class^="_albumTitle"], +[class^="_tableCell"] *, +[class^="_tableCellContent"] * { + color: #333333 !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: #333333; + 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: #333333; + background-color: #aaaaaa !important; +} + +.neptune-switch-checkbox:checked+.neptune-switch { + background-color: rgba(0, 0, 0, 0.1); +} + +[data-test="navigation-arrows"]>button { + background-color: var(--wave-color-solid-accent-fill) !important; + color: #333333 !important; + border-radius: 5px; +} + +[data-test="navigation-arrows"]>button:disabled { + background-color: #cccccc !important; + opacity: 1; +} + +[data-test="main-layout-header"] { + background-color: rgba(235, 235, 235, 0.95) !important; + backdrop-filter: blur(10px); + border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin) !important; +} + +[data-test="feed-sidebar"] { + background-color: rgba(225, 225, 225, 0.9) !important; + backdrop-filter: blur(10px); + border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin) !important; +} + +[data-test="stream-metadata"] { + background-color: rgba(230, 230, 230, 0.92) !important; + backdrop-filter: blur(10px); + border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin) !important; +} + +[data-test="footer-player"] { + background-color: rgba(255, 255, 255, 0.6) !important; + backdrop-filter: blur(15px); + border: 1px solid rgba(200, 200, 200, 0.7) !important; +} + +[data-wave-color=textUrl] { + color: var(--wave-color-solid-accent-fill); +} + +[class^="_smallHeader"] { + margin-top: 7.5px; +} + +/* Play and Shuffle buttons - ultra aggressive targeting */ +button[data-test="play-all"], +button[data-test="shuffle-all"], +div[data-test="play-all"], +div[data-test="shuffle-all"] { + background-color: #666666 !important; + color: white !important; + border-radius: 12px !important; +} + +/* Target all possible text and icon elements */ +button[data-test="play-all"] *, +button[data-test="shuffle-all"] *, +div[data-test="play-all"] *, +div[data-test="shuffle-all"] *, +[data-test="play-all"] span, +[data-test="shuffle-all"] span, +[data-test="play-all"] svg, +[data-test="shuffle-all"] svg, +[data-test="play-all"] path, +[data-test="shuffle-all"] path, +[data-test="play-all"] div, +[data-test="shuffle-all"] div, +[data-test="play-all"] button, +[data-test="shuffle-all"] button { + color: white !important; + fill: white !important; + background-color: transparent !important; +} + +/* Override any CSS variable usage */ +[data-test="play-all"], +[data-test="shuffle-all"] { + --wave-color-solid-accent-fill: white !important; + --wave-color-solid-contrast-fill: white !important; + --wave-text-body-medium: white !important; +} + +[class^="__NEPTUNE_PAGE"], +[data-test="main"] { + margin-top: 35px; +} + +[data-test="button-desktop-release-notes"], +[data-test="button-release-notes"] { + background-color: #333333; +} + +[data-test="button-desktop-release-notes"]:hover, +[data-test="button-release-notes"]:hover { + background-color: #555555 !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(220, 220, 220, 0.9) !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(227, 227, 227, 0.85); + 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(1.2); +} + +/* Player bar text colors - fix white text issues */ +[data-test="footer-player"] * { + color: #333333 !important; +} + +[data-test="footer-player"] [class*="trackTitle"], +[data-test="footer-player"] [class*="artistName"], +[data-test="footer-player"] [class*="trackInfo"], +[data-test="footer-player"] [class*="duration"], +[data-test="footer-player"] [class*="time"], +[data-test="footer-player"] [class*="timestamp"] { + color: #333333 !important; +} + +/* Main page background */ +body, +[data-test="main"], +[class^="__NEPTUNE_PAGE"] { + background-color: #f5f5f5 !important; +} \ No newline at end of file