mirror of
https://github.com/meowarex/TidaLuna-Plugins.git
synced 2026-06-18 03:43:10 +10:00
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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,14 +415,17 @@ function observeTrackTitle(): void {
|
||||
// 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();
|
||||
// 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();
|
||||
}
|
||||
|
||||
// Create unhide button if it doesn't exist
|
||||
if (!document.querySelector('.unhide-ui-button')) {
|
||||
createUnhideUIButton();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { ReactiveStore } from "@luna/core";
|
||||
import { LunaSettings, LunaSwitchSetting } from "@luna/ui";
|
||||
import React from "react";
|
||||
|
||||
export const settings = await ReactiveStore.getPluginStorage("OLEDTheme", {
|
||||
qualityColorMatchedSeekBar: true,
|
||||
oledFriendlyButtons: true,
|
||||
});
|
||||
|
||||
export const Settings = () => {
|
||||
const [qualityColorMatchedSeekBar, setQualityColorMatchedSeekBar] = React.useState(settings.qualityColorMatchedSeekBar);
|
||||
const [oledFriendlyButtons, setOledFriendlyButtons] = React.useState(settings.oledFriendlyButtons);
|
||||
|
||||
return (
|
||||
<LunaSettings>
|
||||
<LunaSwitchSetting
|
||||
title="Quality Color Matched Seek Bar"
|
||||
desc="Apply Tidals Default color styling for the seek bar for color matching with song quality"
|
||||
checked={qualityColorMatchedSeekBar}
|
||||
onChange={(_, checked) => {
|
||||
console.log("Quality Color Matched Seek Bar:", checked ? "enabled" : "disabled");
|
||||
setQualityColorMatchedSeekBar((settings.qualityColorMatchedSeekBar = checked));
|
||||
// Update styles immediately when setting changes
|
||||
if ((window as any).updateOLEDThemeStyles) {
|
||||
(window as any).updateOLEDThemeStyles();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<LunaSwitchSetting
|
||||
title="OLED Friendly Buttons"
|
||||
desc="Remove button styling from OLED theme to keep buttons with original Tidal appearance"
|
||||
checked={oledFriendlyButtons}
|
||||
onChange={(_, checked) => {
|
||||
console.log("OLED Friendly Buttons:", checked ? "enabled" : "disabled");
|
||||
setOledFriendlyButtons((settings.oledFriendlyButtons = checked));
|
||||
// Update styles immediately when setting changes
|
||||
if ((window as any).updateOLEDThemeStyles) {
|
||||
(window as any).updateOLEDThemeStyles();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</LunaSettings>
|
||||
);
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import { LunaUnload, Tracer, ftch } from "@luna/core";
|
||||
import { settings, Settings } from "./Settings";
|
||||
|
||||
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";
|
||||
|
||||
@@ -8,23 +10,110 @@ const themeUrl = "https://raw.githubusercontent.com/ItzzExcel/neptune-projects/r
|
||||
// clean up resources
|
||||
export const unloads = new Set<LunaUnload>();
|
||||
|
||||
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) {
|
||||
appliedStyleElement.parentNode.removeChild(appliedStyleElement);
|
||||
}
|
||||
|
||||
let modifiedStyle = originalStyle;
|
||||
|
||||
// Remove SeekBar coloring if Quality Color Matched Seek Bar is enabled
|
||||
if (settings.qualityColorMatchedSeekBar) {
|
||||
modifiedStyle = modifiedStyle.replace(/\[class\^="_progressBarWrapper"\]\s*\{[^}]*\}/g, '');
|
||||
trace.msg.log("OLED theme applied with SeekBar coloring removed");
|
||||
} else {
|
||||
trace.msg.log("OLED theme applied with original SeekBar coloring");
|
||||
}
|
||||
|
||||
// Remove button styling if OLED Friendly Buttons is enabled
|
||||
if (settings.oledFriendlyButtons) {
|
||||
// First, let's debug what we're working with
|
||||
const originalRuleCount = (modifiedStyle.match(/\{[^}]*\}/g) || []).length;
|
||||
trace.msg.log(`Original CSS has ${originalRuleCount} rules`);
|
||||
|
||||
// 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 (i.e., if it's NOT a button rule)
|
||||
return !isButtonRule;
|
||||
});
|
||||
|
||||
modifiedStyle = filteredRules.join('} ') + (filteredRules.length > 0 ? '}' : '');
|
||||
|
||||
const filteredRuleCount = (modifiedStyle.match(/\{[^}]*\}/g) || []).length;
|
||||
const removedRuleCount = originalRuleCount - filteredRuleCount;
|
||||
trace.msg.log(`OLED Friendly Buttons enabled: Removed ${removedRuleCount} button-related CSS rules, ${filteredRuleCount} rules remaining`);
|
||||
} else {
|
||||
trace.msg.log("OLED Friendly Buttons disabled: Button styling preserved from original theme");
|
||||
}
|
||||
|
||||
appliedStyleElement = document.createElement("style");
|
||||
appliedStyleElement.type = "text/css";
|
||||
appliedStyleElement.textContent = modifiedStyle;
|
||||
document.head.appendChild(appliedStyleElement);
|
||||
};
|
||||
|
||||
// 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
|
||||
const style = await ftch.text(themeUrl).catch((error: Error) => {
|
||||
originalStyle = await ftch.text(themeUrl).catch((error: Error) => {
|
||||
trace.msg.err(`Failed to fetch theme CSS: ${error.message}`);
|
||||
return null;
|
||||
});
|
||||
|
||||
// Apply the OLED theme if CSS was fetched successfully
|
||||
if (style) {
|
||||
const styleElement = document.createElement("style");
|
||||
styleElement.type = "text/css";
|
||||
styleElement.textContent = style;
|
||||
document.head.appendChild(styleElement);
|
||||
if (originalStyle) {
|
||||
applyThemeStyles();
|
||||
|
||||
// Add cleanup to unloads
|
||||
unloads.add(() => {
|
||||
if (styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement);
|
||||
if (appliedStyleElement && appliedStyleElement.parentNode) {
|
||||
appliedStyleElement.parentNode.removeChild(appliedStyleElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
declare module "*.css" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
Reference in New Issue
Block a user