mirror of
https://github.com/meowarex/TidaLuna-Plugins.git
synced 2026-06-18 03:43:10 +10:00
Merge pull request #13 from meowarex/dev
Switch to Use StyleTags Properly & Patch HideUI
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
import { LunaUnload, Tracer, ftch } from "@luna/core";
|
import { LunaUnload, Tracer, ftch } from "@luna/core";
|
||||||
|
import { StyleTag } from "@luna/lib";
|
||||||
import { settings, Settings } from "./Settings";
|
import { settings, Settings } from "./Settings";
|
||||||
|
|
||||||
// Import CSS directly using Luna's file:// syntax
|
// Import CSS files directly using Luna's file:// syntax
|
||||||
import styles from "file://styles.css?minify";
|
import baseStyles from "file://styles.css?minify";
|
||||||
|
import separatedLyrics from "file://separated-lyrics.css?minify";
|
||||||
|
import playerBarHidden from "file://player-bar-hidden.css?minify";
|
||||||
|
|
||||||
export const { trace } = Tracer("[Clean View]");
|
export const { trace } = Tracer("[Clean View]");
|
||||||
export { Settings };
|
export { Settings };
|
||||||
@@ -10,28 +13,12 @@ export { Settings };
|
|||||||
// clean up resources
|
// clean up resources
|
||||||
export const unloads = new Set<LunaUnload>();
|
export const unloads = new Set<LunaUnload>();
|
||||||
|
|
||||||
const themeUrl = "https://raw.githubusercontent.com/itzzexcel/neptune-projects/refs/heads/main/plugins/plugins/not-actual-fullscreen/src/separated-lyrics.css";
|
// StyleTag instances for different CSS modules
|
||||||
|
const lyricsStyleTag = new StyleTag("CleanView-lyrics", unloads);
|
||||||
function ApplyCSS(style: string): HTMLStyleElement {
|
const baseStyleTag = new StyleTag("CleanView-base", unloads);
|
||||||
const styleElement = document.createElement("style");
|
const playerBarStyleTag = new StyleTag("CleanView-player-bar", unloads);
|
||||||
styleElement.type = "text/css";
|
|
||||||
styleElement.textContent = style;
|
|
||||||
document.head.appendChild(styleElement);
|
|
||||||
return styleElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function HttpGet(url: string): Promise<string | null> {
|
|
||||||
try {
|
|
||||||
const content = await ftch.text(url);
|
|
||||||
return content;
|
|
||||||
} catch (error) {
|
|
||||||
trace.msg.err(`Failed to fetch URL: ${error instanceof Error ? error.message : String(error)}`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var isCleanView = false;
|
var isCleanView = false;
|
||||||
var appliedStyle: HTMLStyleElement | null = null;
|
|
||||||
var currentTrackSrc: string | null = null; // Track current album art to prevent unnecessary updates
|
var currentTrackSrc: string | null = null; // Track current album art to prevent unnecessary updates
|
||||||
|
|
||||||
const updateButtonStates = function(): void {
|
const updateButtonStates = function(): void {
|
||||||
@@ -46,41 +33,19 @@ const updateButtonStates = function(): void {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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
|
// Function to update styles when settings change
|
||||||
const updateCleanViewStyles = function(): void {
|
const updateCleanViewStyles = function(): void {
|
||||||
if (isCleanView && appliedStyle) {
|
if (isCleanView) {
|
||||||
// Remove old styles and apply new ones with updated settings
|
// Apply all clean view styles
|
||||||
appliedStyle.remove();
|
lyricsStyleTag.css = separatedLyrics;
|
||||||
appliedStyle = ApplyCSS(getDynamicStyles());
|
baseStyleTag.css = baseStyles;
|
||||||
|
|
||||||
|
// Apply player bar styles based on setting
|
||||||
|
if (!settings.playerBarVisible) {
|
||||||
|
playerBarStyleTag.css = playerBarHidden;
|
||||||
|
} else {
|
||||||
|
playerBarStyleTag.css = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,37 +53,21 @@ const updateCleanViewStyles = function(): void {
|
|||||||
(window as any).updateCleanViewStyles = updateCleanViewStyles;
|
(window as any).updateCleanViewStyles = updateCleanViewStyles;
|
||||||
|
|
||||||
const toggleCleanView = function(): void {
|
const toggleCleanView = function(): void {
|
||||||
if (isCleanView) {
|
// Toggle the state first
|
||||||
if (appliedStyle) {
|
|
||||||
appliedStyle.remove();
|
|
||||||
appliedStyle = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
appliedStyle = ApplyCSS(getDynamicStyles());
|
|
||||||
// Debug: Log bottom-left buttons to help identify selectors
|
|
||||||
//debugBottomLeftButtons();
|
|
||||||
}
|
|
||||||
isCleanView = !isCleanView;
|
isCleanView = !isCleanView;
|
||||||
|
|
||||||
|
if (isCleanView) {
|
||||||
|
// Apply clean view styles
|
||||||
|
updateCleanViewStyles();
|
||||||
|
} else {
|
||||||
|
// Remove all clean view styles
|
||||||
|
lyricsStyleTag.remove();
|
||||||
|
baseStyleTag.remove();
|
||||||
|
playerBarStyleTag.remove();
|
||||||
|
}
|
||||||
updateButtonStates();
|
updateButtonStates();
|
||||||
};
|
};
|
||||||
|
|
||||||
// const debugBottomLeftButtons = function(): void {
|
|
||||||
// setTimeout(() => {
|
|
||||||
// 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 {
|
const createHideUIButton = function(): void {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Only create button if Hide UI is enabled in settings
|
// Only create button if Hide UI is enabled in settings
|
||||||
@@ -412,10 +361,6 @@ const cleanUpDynamicArt = function (): void {
|
|||||||
currentTrackSrc = null; // Reset current track source
|
currentTrackSrc = null; // Reset current track source
|
||||||
};
|
};
|
||||||
|
|
||||||
// STYLES FOR THE LYRICS - Added Top-level async since Luna plugins are modules <3
|
|
||||||
const style = await HttpGet(themeUrl);
|
|
||||||
const styleElement = style ? ApplyCSS(style) : null;
|
|
||||||
|
|
||||||
// Initialize the button creation and observers
|
// Initialize the button creation and observers
|
||||||
observeForButtons();
|
observeForButtons();
|
||||||
observeTrackTitle();
|
observeTrackTitle();
|
||||||
@@ -423,14 +368,6 @@ onTrackChanged(1);
|
|||||||
|
|
||||||
// Add cleanup to unloads
|
// Add cleanup to unloads
|
||||||
unloads.add(() => {
|
unloads.add(() => {
|
||||||
if (styleElement && styleElement.parentNode) {
|
|
||||||
styleElement.parentNode.removeChild(styleElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appliedStyle && appliedStyle.parentNode) {
|
|
||||||
appliedStyle.parentNode.removeChild(appliedStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanUpDynamicArt();
|
cleanUpDynamicArt();
|
||||||
|
|
||||||
// Clean up our custom buttons
|
// Clean up our custom buttons
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
[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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lyrics text styling */
|
||||||
|
[class^="_lyricsText"] {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class^="_lyricsText"] > div > span {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class^="_lyricsText"] > div > span[data-current="true"] {
|
||||||
|
font-weight: 600;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smooth scrolling for lyrics */
|
||||||
|
[class^="_lyricsContainer"] {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enhanced lyrics visibility */
|
||||||
|
[class^="_lyricsText"] > div {
|
||||||
|
padding: 8px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class^="_lyricsText"] > div:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { LunaUnload, Tracer } from "@luna/core";
|
import { LunaUnload, Tracer } from "@luna/core";
|
||||||
|
import { StyleTag } from "@luna/lib";
|
||||||
|
|
||||||
// Import CSS directly using Luna's file:// syntax
|
// Import CSS directly using Luna's file:// syntax
|
||||||
import unlockSelection from "file://styles.css?minify";
|
import unlockSelection from "file://styles.css?minify";
|
||||||
@@ -8,13 +9,8 @@ export const { trace } = Tracer("[Copy Lyrics]");
|
|||||||
// clean up resources
|
// clean up resources
|
||||||
export const unloads = new Set<LunaUnload>();
|
export const unloads = new Set<LunaUnload>();
|
||||||
|
|
||||||
function ApplyCSS(style: string): HTMLStyleElement {
|
// StyleTag for lyrics selection styling
|
||||||
const styleElement = document.createElement("style");
|
const lyricsStyleTag = new StyleTag("Copy-Lyrics", unloads, unlockSelection);
|
||||||
styleElement.type = "text/css";
|
|
||||||
styleElement.textContent = style;
|
|
||||||
document.head.appendChild(styleElement);
|
|
||||||
return styleElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
function SetClipboard(text: string): void {
|
function SetClipboard(text: string): void {
|
||||||
const textarea = document.createElement("textarea");
|
const textarea = document.createElement("textarea");
|
||||||
@@ -33,8 +29,6 @@ function SetClipboard(text: string): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const styleElement = ApplyCSS(unlockSelection);
|
|
||||||
|
|
||||||
let isSelecting = false;
|
let isSelecting = false;
|
||||||
|
|
||||||
const onMouseDown = function (): void {
|
const onMouseDown = function (): void {
|
||||||
@@ -117,10 +111,6 @@ document.addEventListener("mouseup", onMouseUp);
|
|||||||
|
|
||||||
// Add cleanup to unloads
|
// Add cleanup to unloads
|
||||||
unloads.add(() => {
|
unloads.add(() => {
|
||||||
if (styleElement.parentNode) {
|
|
||||||
styleElement.parentNode.removeChild(styleElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove event listeners
|
// Remove event listeners
|
||||||
document.removeEventListener("click", onClickHooked, true);
|
document.removeEventListener("click", onClickHooked, true);
|
||||||
document.removeEventListener("mousedown", onMouseDown);
|
document.removeEventListener("mousedown", onMouseDown);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { LunaUnload, Tracer } from "@luna/core";
|
import { LunaUnload, Tracer } from "@luna/core";
|
||||||
|
import { StyleTag } from "@luna/lib";
|
||||||
import { settings, Settings } from "./Settings";
|
import { settings, Settings } from "./Settings";
|
||||||
|
|
||||||
// Import CSS files directly using Luna's file:// syntax
|
// Import CSS files directly using Luna's file:// syntax
|
||||||
@@ -13,16 +14,11 @@ export { Settings };
|
|||||||
// clean up resources
|
// clean up resources
|
||||||
export const unloads = new Set<LunaUnload>();
|
export const unloads = new Set<LunaUnload>();
|
||||||
|
|
||||||
let appliedStyleElement: HTMLStyleElement | null = null;
|
// StyleTag instance for theme management
|
||||||
|
const themeStyleTag = new StyleTag("OLED-Theme", unloads);
|
||||||
|
|
||||||
// Function to apply theme styles based on current settings
|
// Function to apply theme styles based on current settings
|
||||||
const applyThemeStyles = function(): void {
|
const applyThemeStyles = function(): void {
|
||||||
|
|
||||||
// Remove existing style element if it exists
|
|
||||||
if (appliedStyleElement && appliedStyleElement.parentNode) {
|
|
||||||
appliedStyleElement.parentNode.removeChild(appliedStyleElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choose the appropriate CSS file based on settings
|
// Choose the appropriate CSS file based on settings
|
||||||
let selectedStyle: string;
|
let selectedStyle: string;
|
||||||
|
|
||||||
@@ -39,21 +35,12 @@ const applyThemeStyles = function(): void {
|
|||||||
selectedStyle = selectedStyle.replace(/\[class\^="_progressBarWrapper"\]\s*\{[^}]*\}/g, '');
|
selectedStyle = selectedStyle.replace(/\[class\^="_progressBarWrapper"\]\s*\{[^}]*\}/g, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
appliedStyleElement = document.createElement("style");
|
// Apply the selected theme using StyleTag
|
||||||
appliedStyleElement.type = "text/css";
|
themeStyleTag.css = selectedStyle;
|
||||||
appliedStyleElement.textContent = selectedStyle;
|
|
||||||
document.head.appendChild(appliedStyleElement);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make this function available globally so Settings can call it
|
// Make this function available globally so Settings can call it
|
||||||
(window as any).updateOLEDThemeStyles = applyThemeStyles;
|
(window as any).updateOLEDThemeStyles = applyThemeStyles;
|
||||||
|
|
||||||
// Apply the OLED theme
|
// Apply the OLED theme initially
|
||||||
applyThemeStyles();
|
applyThemeStyles();
|
||||||
|
|
||||||
// Add cleanup to unloads
|
|
||||||
unloads.add(() => {
|
|
||||||
if (appliedStyleElement && appliedStyleElement.parentNode) {
|
|
||||||
appliedStyleElement.parentNode.removeChild(appliedStyleElement);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user