feat: Extend theme detection to include dracula, gruvbox, and monokai, and synchronize themes with the popout viewer.

This commit is contained in:
AEmotionStudio
2026-01-03 04:03:51 -08:00
parent 44423cd6bd
commit e2965f7a38
7 changed files with 208 additions and 6 deletions
+12
View File
@@ -180,6 +180,12 @@ export class StateManager {
detectedTheme = 'github';
} else if (classes.includes('theme-light') || classes.includes('light-theme')) {
detectedTheme = 'light';
} else if (classes.includes('theme-dracula') || classes.includes('dracula-theme')) {
detectedTheme = 'dracula';
} else if (classes.includes('theme-gruvbox') || classes.includes('gruvbox-theme')) {
detectedTheme = 'gruvbox';
} else if (classes.includes('theme-monokai') || classes.includes('monokai-theme')) {
detectedTheme = 'monokai';
}
}
@@ -279,6 +285,12 @@ export class StateManager {
if (window.infoPanelManager && window.infoPanelManager.uiManager) {
window.infoPanelManager.uiManager.updateTheme(this.state.currentTheme);
}
// Notify Pop-Out Manager (if it exists on the main glass instance)
const magnifyGlass = (window as any).comfyUIMagnifyGlass;
if (magnifyGlass && magnifyGlass.popOutManager) {
magnifyGlass.popOutManager.updateTheme(this.state.currentTheme);
}
}
loadSettings(): void {
+33 -3
View File
@@ -13,7 +13,7 @@ import { Logger } from '../shared/logger';
*/
interface PopOutMessage {
type: 'frame' | 'config' | 'info' | 'close' | 'ping' | 'pong';
data?: string | PopOutConfig | PopOutInfo;
data?: string | Partial<PopOutConfig> | PopOutInfo;
timestamp?: number;
}
@@ -22,6 +22,7 @@ interface PopOutConfig {
borderColor: string;
borderWidth: number;
glassShape: string;
theme?: string;
}
/**
@@ -59,6 +60,7 @@ export class PopOutManager {
private lastPongTime: number = 0;
private pingInterval: number | null = null;
private viewerUrl: string;
private currentTheme: string = 'dark'; // Default theme
/** Throttle frame sending to ~30fps */
private lastFrameTime: number = 0;
@@ -138,6 +140,8 @@ export class PopOutManager {
if (!this.isOpen) {
this.isOpen = true;
Logger.debug('[PopOut] Viewer tab connected');
// Send current theme immediately upon connection
this.sendConfig({ theme: this.currentTheme });
}
break;
case 'close':
@@ -230,15 +234,41 @@ export class PopOutManager {
/**
* Send configuration to the pop-out viewer.
*/
sendConfig(config: PopOutConfig): void {
/**
* Send configuration to the pop-out viewer.
*/
sendConfig(config: Partial<PopOutConfig>): void {
if (!this.channel) return;
// Merge with current theme if not provided
const finalConfig = {
theme: this.currentTheme,
...config
};
// Update local theme cache if provided in config
if (config.theme) {
this.currentTheme = config.theme;
}
this.sendMessage({
type: 'config',
data: config
data: finalConfig
});
}
/**
* Update the viewer theme.
* @param theme - Theme name (e.g. 'dark', 'light')
*/
updateTheme(theme: string): void {
if (this.currentTheme === theme) return;
this.currentTheme = theme;
this.sendConfig({ theme });
Logger.debug(`[PopOut] Theme updated to: ${theme}`);
}
/**
* Send inspector info to the pop-out viewer.
* @param info - Inspector panel information
+10
View File
@@ -103,6 +103,12 @@ class StateManager {
detectedTheme = "github";
} else if (classes.includes("theme-light") || classes.includes("light-theme")) {
detectedTheme = "light";
} else if (classes.includes("theme-dracula") || classes.includes("dracula-theme")) {
detectedTheme = "dracula";
} else if (classes.includes("theme-gruvbox") || classes.includes("gruvbox-theme")) {
detectedTheme = "gruvbox";
} else if (classes.includes("theme-monokai") || classes.includes("monokai-theme")) {
detectedTheme = "monokai";
}
}
if (detectedTheme === "dark") {
@@ -172,6 +178,10 @@ class StateManager {
if (window.infoPanelManager && window.infoPanelManager.uiManager) {
window.infoPanelManager.uiManager.updateTheme(this.state.currentTheme);
}
const magnifyGlass = window.comfyUIMagnifyGlass;
if (magnifyGlass && magnifyGlass.popOutManager) {
magnifyGlass.popOutManager.updateTheme(this.state.currentTheme);
}
}
loadSettings() {
Object.keys(DEFAULT_PANEL_SETTINGS).forEach((key) => {
File diff suppressed because one or more lines are too long
+24 -1
View File
@@ -10,6 +10,8 @@ class PopOutManager {
__publicField(this, "lastPongTime", 0);
__publicField(this, "pingInterval", null);
__publicField(this, "viewerUrl");
__publicField(this, "currentTheme", "dark");
// Default theme
/** Throttle frame sending to ~30fps */
__publicField(this, "lastFrameTime", 0);
__publicField(this, "FRAME_INTERVAL", 33);
@@ -72,6 +74,7 @@ class PopOutManager {
if (!this.isOpen) {
this.isOpen = true;
Logger.debug("[PopOut] Viewer tab connected");
this.sendConfig({ theme: this.currentTheme });
}
break;
case "close":
@@ -146,16 +149,36 @@ class PopOutManager {
Logger.error("[PopOut] Failed to send frame:", e);
}
}
/**
* Send configuration to the pop-out viewer.
*/
/**
* Send configuration to the pop-out viewer.
*/
sendConfig(config) {
if (!this.channel) return;
const finalConfig = {
theme: this.currentTheme,
...config
};
if (config.theme) {
this.currentTheme = config.theme;
}
this.sendMessage({
type: "config",
data: config
data: finalConfig
});
}
/**
* Update the viewer theme.
* @param theme - Theme name (e.g. 'dark', 'light')
*/
updateTheme(theme) {
if (this.currentTheme === theme) return;
this.currentTheme = theme;
this.sendConfig({ theme });
Logger.debug(`[PopOut] Theme updated to: ${theme}`);
}
/**
* Send inspector info to the pop-out viewer.
* @param info - Inspector panel information
File diff suppressed because one or more lines are too long
+127
View File
@@ -32,6 +32,129 @@
--radius-sm: 6px;
--radius-md: 10px;
--radius-lg: 14px;
--radius-lg: 14px;
}
/* Light Theme Overrides */
[data-theme="light"] {
--bg-primary: #f9f9fb;
--bg-secondary: #ffffff;
--bg-tertiary: #f3f4f6;
--bg-elevated: #e5e7eb;
--border-subtle: rgba(0, 0, 0, 0.05);
--border-default: rgba(0, 0, 0, 0.1);
--border-accent: rgba(99, 102, 241, 0.3);
--text-primary: #111827;
--text-secondary: #4b5563;
--text-tertiary: #9ca3af;
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
}
/* Solarized Theme */
[data-theme="solarized"] {
--bg-primary: #002b36;
--bg-secondary: #073642;
--bg-tertiary: #073642;
--bg-elevated: #002b36;
--border-subtle: rgba(88, 110, 117, 0.3);
--border-default: rgba(88, 110, 117, 0.5);
--text-primary: #839496;
--text-secondary: #586e75;
--text-tertiary: #586e75;
--accent-blue: #268bd2;
--accent-cyan: #2aa198;
--accent-green: #859900;
}
/* Arc Theme */
[data-theme="arc"] {
--bg-primary: #383c4a;
--bg-secondary: #404552;
--bg-tertiary: #2f343f;
--bg-elevated: #4b5162;
--border-subtle: rgba(0, 0, 0, 0.2);
--border-default: rgba(0, 0, 0, 0.3);
--text-primary: #d3dae3;
--text-secondary: #a0a8b9;
--text-tertiary: #7c818c;
--accent-blue: #5294e2;
}
/* Nord Theme */
[data-theme="nord"] {
--bg-primary: #2e3440;
--bg-secondary: #3b4252;
--bg-tertiary: #434c5e;
--bg-elevated: #4c566a;
--border-subtle: rgba(0, 0, 0, 0.2);
--border-default: rgba(236, 239, 244, 0.1);
--text-primary: #d8dee9;
--text-secondary: #e5e9f0;
--text-tertiary: #4c566a;
--accent-blue: #81a1c1;
--accent-cyan: #88c0d0;
--accent-green: #a3be8c;
}
/* GitHub Theme */
[data-theme="github"] {
--bg-primary: #ffffff;
--bg-secondary: #f6f8fa;
--bg-tertiary: #ffffff;
--bg-elevated: #f6f8fa;
--border-subtle: rgba(27, 31, 35, 0.05);
--border-default: rgba(27, 31, 35, 0.1);
--text-primary: #24292e;
--text-secondary: #586069;
--text-tertiary: #6a737d;
--accent-blue: #0366d6;
}
/* Gruvbox Theme */
[data-theme="gruvbox"] {
--bg-primary: #282828;
--bg-secondary: #3c3836;
--bg-tertiary: #504945;
--bg-elevated: #665c54;
--border-subtle: rgba(168, 153, 132, 0.2);
--border-default: rgba(168, 153, 132, 0.4);
--text-primary: #ebdbb2;
--text-secondary: #a89984;
--text-tertiary: #928374;
--accent-blue: #83a598;
--accent-green: #b8bb26;
}
/* Dracula Theme */
[data-theme="dracula"] {
--bg-primary: #282a36;
--bg-secondary: #44475a;
--bg-tertiary: #44475a;
--bg-elevated: #6272a4;
--border-subtle: rgba(189, 147, 249, 0.2);
--border-default: rgba(98, 114, 164, 0.5);
--text-primary: #f8f8f2;
--text-secondary: #6272a4;
--text-tertiary: #6272a4;
--accent-blue: #8be9fd;
--accent-green: #50fa7b;
}
/* Monokai Theme */
[data-theme="monokai"] {
--bg-primary: #272822;
--bg-secondary: #3e3d32;
--bg-tertiary: #3e3d32;
--bg-elevated: #49483e;
--border-subtle: rgba(255, 255, 255, 0.1);
--border-default: rgba(255, 255, 255, 0.2);
--text-primary: #f8f8f2;
--text-secondary: #75715e;
--text-tertiary: #75715e;
--accent-blue: #66d9ef;
--accent-green: #a6e22e;
}
* {
@@ -621,6 +744,10 @@
} else {
canvas.style.borderRadius = 'var(--radius-lg)';
}
if (config.theme) {
document.documentElement.setAttribute('data-theme', config.theme);
}
}
function handleInfo(info) {