Files
MajoorWaldi-ComfyUI-Majoor-…/js/features/viewer/viewerShell.js
T
Ewald f56d6284da fix: MFV popup dark theme, gen info panel, reset zoom + popout polish
- FloatingViewer.impl.js: add missing _resetMfvZoom() method (was called
  from floatingViewerLoader/Mode but never defined on the class)
- viewerShell.js: return genInfoTitle + genInfoTitleLeft from createViewerStageShell
- ViewerRuntime.js: destructure genInfoTitle + genInfoTitleLeft (were undefined
  => gen info body was never populated)
- floatingViewerPopout.js: inject document.documentElement.style.cssText as
  :root{...} in popup head so ComfyUI CSS vars are available; set body
  background to #0d0d0d; remove broken history.replaceState (Chrome blocks
  it from about:blank)
- __init__.py: remove unused FailureSeverity/StageStatus imports
2026-04-11 19:06:23 +02:00

300 lines
9.0 KiB
JavaScript

import { createIconButton } from "../../components/buttons.js";
import { createFilmstrip } from "./filmstrip.js";
import { VIEWER_INFO_PANEL_WIDTH } from "./viewerThemeStyles.js";
export function createViewerOverlayRoot() {
const overlay = document.createElement("div");
overlay.className = "mjr-viewer-overlay mjr-assets-manager";
overlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(180deg, rgba(6, 8, 12, 0.94), rgba(5, 7, 10, 0.985));
z-index: 10000;
pointer-events: auto;
display: none;
flex-direction: column;
box-sizing: border-box;
overflow: hidden;
`;
overlay.tabIndex = -1;
overlay.setAttribute("role", "dialog");
return overlay;
}
export function createViewerStageShell({
state,
buildAssetViewURL,
onNavigate,
onCompare,
}) {
const contentRow = document.createElement("div");
contentRow.className = "mjr-viewer-content-row";
contentRow.style.cssText = `
flex: 1;
display: flex;
min-height: 0;
overflow: hidden;
min-width: 0;
`;
const content = document.createElement("div");
content.className = "mjr-viewer-content";
content.style.cssText = `
flex: 1;
min-width: 0;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
isolation: isolate;
`;
const singleView = document.createElement("div");
singleView.className = "mjr-viewer-single";
singleView.style.cssText = `
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
`;
const abView = document.createElement("div");
abView.className = "mjr-viewer-ab";
abView.style.cssText = `
width: 100%;
height: 100%;
display: none;
position: relative;
`;
const sideView = document.createElement("div");
sideView.className = "mjr-viewer-sidebyside";
sideView.style.cssText = `
width: 100%;
height: 100%;
display: none;
flex-direction: row;
gap: 2px;
`;
content.appendChild(singleView);
content.appendChild(abView);
content.appendChild(sideView);
const overlayLayer = document.createElement("div");
overlayLayer.className = "mjr-viewer-overlay-layer";
overlayLayer.style.cssText = `
position: absolute;
inset: 0;
pointer-events: none;
z-index: 50;
`;
const gridCanvas = document.createElement("canvas");
gridCanvas.className = "mjr-viewer-grid-canvas";
gridCanvas.style.cssText = `
position: absolute;
inset: 0;
width: 100%;
height: 100%;
display: none;
`;
const probeTooltip = document.createElement("div");
probeTooltip.className = "mjr-viewer-probe";
probeTooltip.style.cssText = `
position: absolute;
display: none;
padding: 7px 10px;
border-radius: 10px;
background: rgba(11, 14, 19, 0.78);
border: 1px solid rgba(255, 255, 255, 0.12);
color: rgba(255, 255, 255, 0.92);
font-size: 11px;
line-height: 1.2;
white-space: pre;
max-width: 280px;
transform: translate3d(0,0,0);
box-shadow: 0 18px 34px rgba(0,0,0,0.28);
`;
const loupeWrap = document.createElement("div");
loupeWrap.className = "mjr-viewer-loupe";
loupeWrap.style.cssText = `
position: absolute;
display: none;
width: 120px;
height: 120px;
border-radius: 14px;
overflow: hidden;
border: 1px solid rgba(255,255,255,0.14);
box-shadow: 0 18px 34px rgba(0,0,0,0.34);
background: rgba(9,12,16,0.72);
transform: translate3d(0,0,0);
`;
const loupeCanvas = document.createElement("canvas");
loupeCanvas.width = 120;
loupeCanvas.height = 120;
loupeCanvas.style.cssText =
"width:100%; height:100%; display:block; image-rendering: pixelated;";
loupeWrap.appendChild(loupeCanvas);
overlayLayer.appendChild(gridCanvas);
overlayLayer.appendChild(probeTooltip);
overlayLayer.appendChild(loupeWrap);
content.appendChild(overlayLayer);
const genInfoOverlay = document.createElement("div");
genInfoOverlay.className = "mjr-viewer-geninfo mjr-viewer-geninfo--right";
genInfoOverlay.style.cssText = `
position: absolute;
top: 16px;
right: 16px;
bottom: 16px;
width: ${VIEWER_INFO_PANEL_WIDTH};
display: none;
flex-direction: column;
overflow: hidden;
background: rgba(12, 15, 20, 0.9);
border-left: 1px solid rgba(255,255,255,0.12);
pointer-events: auto;
backdrop-filter: blur(10px);
z-index: 10001;
`;
const genInfoHeader = document.createElement("div");
genInfoHeader.style.cssText = `
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 10px 12px;
border-bottom: 1px solid rgba(255,255,255,0.10);
color: rgba(255,255,255,0.92);
`;
const genInfoTitle = document.createElement("div");
genInfoTitle.textContent = "Generation Info";
genInfoTitle.style.cssText = "font-size: 13px; font-weight: 600;";
genInfoHeader.appendChild(genInfoTitle);
const genInfoBody = document.createElement("div");
genInfoBody.style.cssText = `
flex: 1;
overflow: auto;
padding: 14px;
color: rgba(255,255,255,0.92);
`;
genInfoOverlay.appendChild(genInfoHeader);
genInfoOverlay.appendChild(genInfoBody);
const genInfoOverlayLeft = document.createElement("div");
genInfoOverlayLeft.className = "mjr-viewer-geninfo mjr-viewer-geninfo--left";
genInfoOverlayLeft.style.cssText = `
position: absolute;
top: 16px;
left: 16px;
bottom: 16px;
width: ${VIEWER_INFO_PANEL_WIDTH};
display: none;
flex-direction: column;
overflow: hidden;
background: rgba(12, 15, 20, 0.9);
border-right: 1px solid rgba(255,255,255,0.12);
pointer-events: auto;
backdrop-filter: blur(10px);
z-index: 10001;
`;
const genInfoHeaderLeft = genInfoHeader.cloneNode(true);
genInfoHeaderLeft.replaceChildren();
const genInfoTitleLeft = document.createElement("div");
genInfoTitleLeft.textContent = "Generation Info (A)";
genInfoTitleLeft.style.cssText = "font-size: 13px; font-weight: 600;";
genInfoHeaderLeft.appendChild(genInfoTitleLeft);
const genInfoBodyLeft = document.createElement("div");
genInfoBodyLeft.style.cssText = `
flex: 1;
overflow: auto;
padding: 14px;
color: rgba(255,255,255,0.92);
`;
genInfoOverlayLeft.appendChild(genInfoHeaderLeft);
genInfoOverlayLeft.appendChild(genInfoBodyLeft);
contentRow.appendChild(content);
const footer = document.createElement("div");
footer.className = "mjr-viewer-footer";
footer.style.cssText = `
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 20px;
background: rgba(13, 16, 22, 0.78);
border-top: 1px solid rgba(255, 255, 255, 0.1);
color: white;
gap: 14px 20px;
flex-wrap: wrap;
`;
const prevBtn = createIconButton("<", "Previous (Left Arrow)");
prevBtn.classList.add("mjr-viewer-nav-btn", "mjr-viewer-nav-btn--prev");
prevBtn.style.fontSize = "24px";
const indexInfo = document.createElement("span");
indexInfo.className = "mjr-viewer-index";
indexInfo.style.cssText = "font-size: 14px; font-weight: 500;";
const nextBtn = createIconButton(">", "Next (Right Arrow)");
nextBtn.classList.add("mjr-viewer-nav-btn", "mjr-viewer-nav-btn--next");
nextBtn.style.fontSize = "24px";
const navBar = document.createElement("div");
navBar.className = "mjr-viewer-nav";
navBar.style.cssText = "display:flex; align-items:center; gap:20px;";
navBar.appendChild(prevBtn);
navBar.appendChild(indexInfo);
navBar.appendChild(nextBtn);
const playerBarHost = document.createElement("div");
playerBarHost.className = "mjr-viewer-playerbar";
playerBarHost.style.cssText = "display:none; width: 100%;";
footer.appendChild(navBar);
footer.appendChild(playerBarHost);
const filmstrip = createFilmstrip({
state,
buildAssetViewURL,
onNavigate,
onCompare,
});
return {
contentRow,
content,
singleView,
abView,
sideView,
overlayLayer,
gridCanvas,
probeTooltip,
loupeWrap,
loupeCanvas,
genInfoOverlay,
genInfoTitle,
genInfoBody,
genInfoOverlayLeft,
genInfoTitleLeft,
genInfoBodyLeft,
footer,
prevBtn,
indexInfo,
nextBtn,
navBar,
playerBarHost,
filmstrip,
};
}