Ports the button, buttongroup, and popup as ComfyUI is removing the ability to call these soon. Fixes #600.
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "rgthree-comfy"
|
||||
description = "Making ComfyUI more comfortable."
|
||||
version = "1.0.2511081814"
|
||||
version = "1.0.2511082218"
|
||||
license = { file = "LICENSE" }
|
||||
dependencies = []
|
||||
|
||||
|
||||
+175
-31
@@ -1,14 +1,12 @@
|
||||
import {app} from "scripts/app.js";
|
||||
import {ComfyButtonGroup} from "scripts/ui/components/buttonGroup.js";
|
||||
import {ComfyButton} from "scripts/ui/components/button.js";
|
||||
import {iconGear, iconStarFilled, logoRgthreeAsync} from "rgthree/common/media/svgs.js";
|
||||
import {createElement, empty, query} from "rgthree/common/utils_dom.js";
|
||||
import {$el, empty} from "rgthree/common/utils_dom.js";
|
||||
import {SERVICE as BOOKMARKS_SERVICE} from "./services/bookmarks_services.js";
|
||||
import {SERVICE as CONFIG_SERVICE} from "./services/config_service.js";
|
||||
import {ComfyPopup} from "scripts/ui/components/popup.js";
|
||||
import {RgthreeConfigDialog} from "./config.js";
|
||||
import {wait} from "rgthree/common/shared_utils.js";
|
||||
|
||||
let rgthreeButtonGroup: ComfyButtonGroup | null = null;
|
||||
let rgthreeButtonGroup: RgthreeComfyButtonGroup | null = null;
|
||||
|
||||
function addRgthreeTopBarButtons() {
|
||||
if (!CONFIG_SERVICE.getFeatureValue("comfy_top_bar_menu.enabled")) {
|
||||
@@ -23,30 +21,33 @@ function addRgthreeTopBarButtons() {
|
||||
|
||||
const buttons = [];
|
||||
|
||||
const rgthreeButton = new ComfyButton({
|
||||
icon: "rgthree",
|
||||
const rgthreeButton = new RgthreeComfyButton({
|
||||
icon: "<svg></svg>",
|
||||
tooltip: "rgthree-comfy",
|
||||
primary: true,
|
||||
// content: 'rgthree-comfy',
|
||||
app,
|
||||
// app,
|
||||
enabled: true,
|
||||
classList: "comfyui-button comfyui-menu-mobile-collapse primary",
|
||||
});
|
||||
buttons.push(rgthreeButton);
|
||||
rgthreeButton.iconElement.style.width = "1.2rem";
|
||||
logoRgthreeAsync().then((t) => { rgthreeButton.iconElement.innerHTML = t;});
|
||||
logoRgthreeAsync().then((t) => {
|
||||
rgthreeButton.setIcon(t);
|
||||
});
|
||||
|
||||
rgthreeButton.withPopup(
|
||||
new ComfyPopup(
|
||||
{target: rgthreeButton.element, classList: "rgthree-top-menu"},
|
||||
createElement("menu", {
|
||||
new RgthreeComfyPopup(
|
||||
{target: rgthreeButton.element},
|
||||
$el("menu.rgthree-menu.rgthree-top-menu", {
|
||||
children: [
|
||||
createElement("li", {
|
||||
child: createElement("button.rgthree-button-reset", {
|
||||
$el("li", {
|
||||
child: $el("button.rgthree-button-reset", {
|
||||
html: iconGear + "Settings (rgthree-comfy)",
|
||||
onclick: () => new RgthreeConfigDialog().show(),
|
||||
}),
|
||||
}),
|
||||
createElement("li", {
|
||||
child: createElement("button.rgthree-button-reset", {
|
||||
$el("li", {
|
||||
child: $el("button.rgthree-button-reset", {
|
||||
html: iconStarFilled + "Star on Github",
|
||||
onclick: () => window.open("https://github.com/rgthree/rgthree-comfy", "_blank"),
|
||||
}),
|
||||
@@ -58,29 +59,29 @@ function addRgthreeTopBarButtons() {
|
||||
);
|
||||
|
||||
if (CONFIG_SERVICE.getFeatureValue("comfy_top_bar_menu.button_bookmarks.enabled")) {
|
||||
const bookmarksListEl = createElement("menu");
|
||||
const bookmarksListEl = $el("menu.rgthree-menu.rgthree-top-menu");
|
||||
bookmarksListEl.appendChild(
|
||||
createElement("li.rgthree-message", {
|
||||
child: createElement("span", {text: "No bookmarks in current workflow."}),
|
||||
$el("li.rgthree-message", {
|
||||
child: $el("span", {text: "No bookmarks in current workflow."}),
|
||||
}),
|
||||
);
|
||||
const bookmarksButton = new ComfyButton({
|
||||
const bookmarksButton = new RgthreeComfyButton({
|
||||
icon: "bookmark",
|
||||
tooltip: "Workflow Bookmarks (rgthree-comfy)",
|
||||
app,
|
||||
// app,
|
||||
});
|
||||
const bookmarksPopup = new ComfyPopup(
|
||||
{target: bookmarksButton.element, classList: "rgthree-top-menu"},
|
||||
const bookmarksPopup = new RgthreeComfyPopup(
|
||||
{target: bookmarksButton.element, modal: false},
|
||||
bookmarksListEl,
|
||||
);
|
||||
bookmarksPopup.addEventListener("open", () => {
|
||||
bookmarksPopup.onOpen(() => {
|
||||
const bookmarks = BOOKMARKS_SERVICE.getCurrentBookmarks();
|
||||
empty(bookmarksListEl);
|
||||
if (bookmarks.length) {
|
||||
for (const b of bookmarks) {
|
||||
bookmarksListEl.appendChild(
|
||||
createElement("li", {
|
||||
child: createElement("button.rgthree-button-reset", {
|
||||
$el("li", {
|
||||
child: $el("button.rgthree-button-reset", {
|
||||
text: `[${b.shortcutKey}] ${b.title}`,
|
||||
onclick: () => {
|
||||
b.canvasToBookmark();
|
||||
@@ -91,18 +92,18 @@ function addRgthreeTopBarButtons() {
|
||||
}
|
||||
} else {
|
||||
bookmarksListEl.appendChild(
|
||||
createElement("li.rgthree-message", {
|
||||
child: createElement("span", {text: "No bookmarks in current workflow."}),
|
||||
$el("li.rgthree-message", {
|
||||
child: $el("span", {text: "No bookmarks in current workflow."}),
|
||||
}),
|
||||
);
|
||||
}
|
||||
bookmarksPopup.update();
|
||||
// bookmarksPopup.update();
|
||||
});
|
||||
bookmarksButton.withPopup(bookmarksPopup, "hover");
|
||||
buttons.push(bookmarksButton);
|
||||
}
|
||||
|
||||
rgthreeButtonGroup = new ComfyButtonGroup(...buttons);
|
||||
rgthreeButtonGroup = new RgthreeComfyButtonGroup(...buttons);
|
||||
app.menu?.settingsGroup.element.before(rgthreeButtonGroup.element);
|
||||
}
|
||||
|
||||
@@ -118,3 +119,146 @@ app.registerExtension({
|
||||
}) as EventListener);
|
||||
},
|
||||
});
|
||||
|
||||
// The following are rough hacks since ComfyUI took away their button/buttongroup/popup
|
||||
// functionality. TODO: Find a better spot to add rgthree controls to the UI, I suppose.
|
||||
|
||||
class RgthreeComfyButtonGroup {
|
||||
element = $el("div.rgthree-comfybar-top-button-group");
|
||||
buttons: RgthreeComfyButton[];
|
||||
|
||||
constructor(...buttons: RgthreeComfyButton[]) {
|
||||
this.buttons = buttons;
|
||||
this.update();
|
||||
}
|
||||
|
||||
insert(button: RgthreeComfyButton, index: number) {
|
||||
this.buttons.splice(index, 0, button);
|
||||
this.update();
|
||||
}
|
||||
|
||||
append(button: RgthreeComfyButton) {
|
||||
this.buttons.push(button);
|
||||
this.update();
|
||||
}
|
||||
|
||||
remove(indexOrButton: RgthreeComfyButton | number) {
|
||||
if (typeof indexOrButton !== "number") {
|
||||
indexOrButton = this.buttons.indexOf(indexOrButton);
|
||||
}
|
||||
if (indexOrButton > -1) {
|
||||
const btn = this.buttons.splice(indexOrButton, 1);
|
||||
this.update();
|
||||
return btn;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
update() {
|
||||
this.element.replaceChildren(...this.buttons.map((b) => b["element"] ?? b));
|
||||
}
|
||||
}
|
||||
|
||||
interface RgthreeComfyButtonOptions {
|
||||
icon?: string;
|
||||
primary?: boolean;
|
||||
overIcon?: string;
|
||||
iconSize?: number;
|
||||
content?: string | HTMLElement;
|
||||
tooltip?: string;
|
||||
enabled?: boolean;
|
||||
action?: (e: Event, btn: RgthreeComfyButton) => void;
|
||||
classList?: string;
|
||||
visibilitySetting?: {id: string; showValue: any};
|
||||
// app?: ComfyApp;
|
||||
}
|
||||
|
||||
class RgthreeComfyButton {
|
||||
element = $el("button.rgthree-comfybar-top-button.rgthree-button-reset.rgthree-button");
|
||||
iconElement = $el("span.rgthree-button-icon");
|
||||
constructor(opts: RgthreeComfyButtonOptions) {
|
||||
opts.icon && this.setIcon(opts.icon);
|
||||
opts.tooltip && this.element.setAttribute("title", opts.tooltip);
|
||||
opts.primary && this.element.classList.add("-primary");
|
||||
}
|
||||
|
||||
setIcon(iconOrMarkup: string) {
|
||||
const markup = iconOrMarkup.startsWith("<")
|
||||
? iconOrMarkup
|
||||
: `<i class="mdi mdi-${iconOrMarkup}"></i>`;
|
||||
this.iconElement.innerHTML = markup;
|
||||
if (!this.iconElement.parentElement) {
|
||||
this.element.appendChild(this.iconElement);
|
||||
}
|
||||
}
|
||||
|
||||
withPopup(popup: RgthreeComfyPopup, trigger: "click" | "hover") {
|
||||
if (trigger === "click") {
|
||||
this.element.addEventListener("click", () => {
|
||||
popup.open();
|
||||
});
|
||||
}
|
||||
if (trigger === "hover") {
|
||||
this.element.addEventListener("pointerenter", () => {
|
||||
popup.open();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface RgthreeComfyPopupOptions {
|
||||
target: HTMLElement;
|
||||
classList?: string;
|
||||
modal?: boolean;
|
||||
}
|
||||
|
||||
class RgthreeComfyPopup {
|
||||
element: HTMLElement;
|
||||
target?: HTMLElement;
|
||||
onOpenFn: (() => Promise<void> | void) | null = null;
|
||||
opts: RgthreeComfyPopupOptions;
|
||||
|
||||
onWindowClickBound = this.onWindowClick.bind(this);
|
||||
|
||||
constructor(opts: RgthreeComfyPopupOptions, element: HTMLElement) {
|
||||
this.element = element;
|
||||
this.opts = opts;
|
||||
opts.target && (this.target = opts.target);
|
||||
opts.modal && this.element.classList.add("-modal");
|
||||
}
|
||||
|
||||
async open() {
|
||||
if (!this.target) {
|
||||
throw new Error("No target for RgthreeComfyPopup");
|
||||
}
|
||||
if (this.onOpenFn) {
|
||||
await this.onOpenFn();
|
||||
}
|
||||
await wait(16);
|
||||
const rect = this.target.getBoundingClientRect();
|
||||
this.element.setAttribute("state", "measuring");
|
||||
document.body.appendChild(this.element);
|
||||
this.element.style.position = "fixed";
|
||||
this.element.style.left = `${rect.left}px`;
|
||||
this.element.style.top = `${rect.top + rect.height}px`;
|
||||
this.element.setAttribute("state", "open");
|
||||
if (this.opts.modal) {
|
||||
document.body.classList.add("rgthree-modal-menu-open");
|
||||
}
|
||||
window.addEventListener("click", this.onWindowClickBound);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.element.remove();
|
||||
document.body.classList.remove("rgthree-modal-menu-open");
|
||||
window.removeEventListener("click", this.onWindowClickBound);
|
||||
}
|
||||
|
||||
onOpen(fn: (() => void) | null) {
|
||||
this.onOpenFn = fn;
|
||||
}
|
||||
|
||||
onWindowClick() {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
color: inherit;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
}
|
||||
|
||||
$borderRadius: 0.33rem;
|
||||
|
||||
:not(#fakeid) .rgthree-button {
|
||||
--padding-top: 7px;
|
||||
--padding-bottom: 9px;
|
||||
@@ -16,7 +18,7 @@
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: $borderRadius;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
font-family: system-ui, sans-serif;
|
||||
@@ -39,7 +41,7 @@
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: $borderRadius;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
@@ -103,4 +105,52 @@
|
||||
&[disabled]::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group {
|
||||
font-size: 0;
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
|
||||
.rgthree-comfybar-top-button {
|
||||
margin: 0;
|
||||
flex: 1 1;
|
||||
height: 36px;
|
||||
padding: 0 12px;
|
||||
border-radius: 0;
|
||||
background: var(--p-button-secondary-background);
|
||||
color: var(--p-button-secondary-color);
|
||||
|
||||
&.-primary {
|
||||
background: var(--p-button-primary-background);
|
||||
color: var(--p-button-primary-color);
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.rgthree-comfybar-top-button:first-of-type,
|
||||
.rgthree-comfybar-top-button:first-of-type::before,
|
||||
.rgthree-comfybar-top-button:first-of-type::after {
|
||||
border-top-left-radius: 0.33rem;
|
||||
border-bottom-left-radius: 0.33rem;
|
||||
|
||||
}
|
||||
.rgthree-comfybar-top-button:last-of-type,
|
||||
.rgthree-comfybar-top-button:last-of-type::before,
|
||||
.rgthree-comfybar-top-button:last-of-type::after {
|
||||
border-top-right-radius: 0.33rem;
|
||||
border-bottom-right-radius: 0.33rem;
|
||||
}
|
||||
}
|
||||
@@ -50,59 +50,73 @@
|
||||
color: var(--content-fg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
* {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
menu {
|
||||
|
||||
> li:not(#fakeid) {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
> li:not(#fakeid) {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
> button {
|
||||
cursor: pointer;
|
||||
padding: 8px 12px 8px 8px;
|
||||
width: 100%;
|
||||
text-align: start;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
|
||||
> button {
|
||||
cursor: pointer;
|
||||
padding: 8px 12px 8px 8px;
|
||||
width: 100%;
|
||||
text-align: start;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--comfy-input-bg);
|
||||
}
|
||||
|
||||
svg {
|
||||
height: 16px;
|
||||
width: auto;
|
||||
margin-inline-end: 0.6em;
|
||||
|
||||
&.github-star {
|
||||
fill: rgb(227, 179, 65);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--comfy-input-bg);
|
||||
}
|
||||
|
||||
&.rgthree-message {
|
||||
// ComfyUI's code has strange behavior that that always puts the popupat to if its less than
|
||||
// 30px... we'll force our message to be at least 32px tall so it won't do that unless it's
|
||||
// actually on the bottom.
|
||||
min-height: 32px;
|
||||
> span {
|
||||
padding: 8px 12px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
svg {
|
||||
height: 16px;
|
||||
width: auto;
|
||||
margin-inline-end: 0.6em;
|
||||
|
||||
&.github-star {
|
||||
fill: rgb(227, 179, 65);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.rgthree-message {
|
||||
// ComfyUI's code has strange behavior that that always puts the popupat to if its less than
|
||||
// 30px... we'll force our message to be at least 32px tall so it won't do that unless it's
|
||||
// actually on the bottom.
|
||||
min-height: 32px;
|
||||
> span {
|
||||
padding: 8px 12px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.-modal::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
inset: 0;
|
||||
background: #0001;
|
||||
}
|
||||
}
|
||||
|
||||
body.rgthree-modal-menu-open > *:not(.rgthree-menu):not(.rgthree-top-messages-container) {
|
||||
filter: blur(2px);
|
||||
}
|
||||
|
||||
|
||||
+124
-27
@@ -1,12 +1,10 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
import { ComfyButtonGroup } from "../../scripts/ui/components/buttonGroup.js";
|
||||
import { ComfyButton } from "../../scripts/ui/components/button.js";
|
||||
import { iconGear, iconStarFilled, logoRgthreeAsync } from "../../rgthree/common/media/svgs.js";
|
||||
import { createElement, empty } from "../../rgthree/common/utils_dom.js";
|
||||
import { $el, empty } from "../../rgthree/common/utils_dom.js";
|
||||
import { SERVICE as BOOKMARKS_SERVICE } from "./services/bookmarks_services.js";
|
||||
import { SERVICE as CONFIG_SERVICE } from "./services/config_service.js";
|
||||
import { ComfyPopup } from "../../scripts/ui/components/popup.js";
|
||||
import { RgthreeConfigDialog } from "./config.js";
|
||||
import { wait } from "../../rgthree/common/shared_utils.js";
|
||||
let rgthreeButtonGroup = null;
|
||||
function addRgthreeTopBarButtons() {
|
||||
var _a, _b, _c;
|
||||
@@ -21,26 +19,27 @@ function addRgthreeTopBarButtons() {
|
||||
return;
|
||||
}
|
||||
const buttons = [];
|
||||
const rgthreeButton = new ComfyButton({
|
||||
icon: "rgthree",
|
||||
const rgthreeButton = new RgthreeComfyButton({
|
||||
icon: "<svg></svg>",
|
||||
tooltip: "rgthree-comfy",
|
||||
app,
|
||||
primary: true,
|
||||
enabled: true,
|
||||
classList: "comfyui-button comfyui-menu-mobile-collapse primary",
|
||||
});
|
||||
buttons.push(rgthreeButton);
|
||||
rgthreeButton.iconElement.style.width = "1.2rem";
|
||||
logoRgthreeAsync().then((t) => { rgthreeButton.iconElement.innerHTML = t; });
|
||||
rgthreeButton.withPopup(new ComfyPopup({ target: rgthreeButton.element, classList: "rgthree-top-menu" }, createElement("menu", {
|
||||
logoRgthreeAsync().then((t) => {
|
||||
rgthreeButton.setIcon(t);
|
||||
});
|
||||
rgthreeButton.withPopup(new RgthreeComfyPopup({ target: rgthreeButton.element }, $el("menu.rgthree-menu.rgthree-top-menu", {
|
||||
children: [
|
||||
createElement("li", {
|
||||
child: createElement("button.rgthree-button-reset", {
|
||||
$el("li", {
|
||||
child: $el("button.rgthree-button-reset", {
|
||||
html: iconGear + "Settings (rgthree-comfy)",
|
||||
onclick: () => new RgthreeConfigDialog().show(),
|
||||
}),
|
||||
}),
|
||||
createElement("li", {
|
||||
child: createElement("button.rgthree-button-reset", {
|
||||
$el("li", {
|
||||
child: $el("button.rgthree-button-reset", {
|
||||
html: iconStarFilled + "Star on Github",
|
||||
onclick: () => window.open("https://github.com/rgthree/rgthree-comfy", "_blank"),
|
||||
}),
|
||||
@@ -48,23 +47,22 @@ function addRgthreeTopBarButtons() {
|
||||
],
|
||||
})), "click");
|
||||
if (CONFIG_SERVICE.getFeatureValue("comfy_top_bar_menu.button_bookmarks.enabled")) {
|
||||
const bookmarksListEl = createElement("menu");
|
||||
bookmarksListEl.appendChild(createElement("li.rgthree-message", {
|
||||
child: createElement("span", { text: "No bookmarks in current workflow." }),
|
||||
const bookmarksListEl = $el("menu.rgthree-menu.rgthree-top-menu");
|
||||
bookmarksListEl.appendChild($el("li.rgthree-message", {
|
||||
child: $el("span", { text: "No bookmarks in current workflow." }),
|
||||
}));
|
||||
const bookmarksButton = new ComfyButton({
|
||||
const bookmarksButton = new RgthreeComfyButton({
|
||||
icon: "bookmark",
|
||||
tooltip: "Workflow Bookmarks (rgthree-comfy)",
|
||||
app,
|
||||
});
|
||||
const bookmarksPopup = new ComfyPopup({ target: bookmarksButton.element, classList: "rgthree-top-menu" }, bookmarksListEl);
|
||||
bookmarksPopup.addEventListener("open", () => {
|
||||
const bookmarksPopup = new RgthreeComfyPopup({ target: bookmarksButton.element, modal: false }, bookmarksListEl);
|
||||
bookmarksPopup.onOpen(() => {
|
||||
const bookmarks = BOOKMARKS_SERVICE.getCurrentBookmarks();
|
||||
empty(bookmarksListEl);
|
||||
if (bookmarks.length) {
|
||||
for (const b of bookmarks) {
|
||||
bookmarksListEl.appendChild(createElement("li", {
|
||||
child: createElement("button.rgthree-button-reset", {
|
||||
bookmarksListEl.appendChild($el("li", {
|
||||
child: $el("button.rgthree-button-reset", {
|
||||
text: `[${b.shortcutKey}] ${b.title}`,
|
||||
onclick: () => {
|
||||
b.canvasToBookmark();
|
||||
@@ -74,16 +72,15 @@ function addRgthreeTopBarButtons() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
bookmarksListEl.appendChild(createElement("li.rgthree-message", {
|
||||
child: createElement("span", { text: "No bookmarks in current workflow." }),
|
||||
bookmarksListEl.appendChild($el("li.rgthree-message", {
|
||||
child: $el("span", { text: "No bookmarks in current workflow." }),
|
||||
}));
|
||||
}
|
||||
bookmarksPopup.update();
|
||||
});
|
||||
bookmarksButton.withPopup(bookmarksPopup, "hover");
|
||||
buttons.push(bookmarksButton);
|
||||
}
|
||||
rgthreeButtonGroup = new ComfyButtonGroup(...buttons);
|
||||
rgthreeButtonGroup = new RgthreeComfyButtonGroup(...buttons);
|
||||
(_c = app.menu) === null || _c === void 0 ? void 0 : _c.settingsGroup.element.before(rgthreeButtonGroup.element);
|
||||
}
|
||||
app.registerExtension({
|
||||
@@ -98,3 +95,103 @@ app.registerExtension({
|
||||
}));
|
||||
},
|
||||
});
|
||||
class RgthreeComfyButtonGroup {
|
||||
constructor(...buttons) {
|
||||
this.element = $el("div.rgthree-comfybar-top-button-group");
|
||||
this.buttons = buttons;
|
||||
this.update();
|
||||
}
|
||||
insert(button, index) {
|
||||
this.buttons.splice(index, 0, button);
|
||||
this.update();
|
||||
}
|
||||
append(button) {
|
||||
this.buttons.push(button);
|
||||
this.update();
|
||||
}
|
||||
remove(indexOrButton) {
|
||||
if (typeof indexOrButton !== "number") {
|
||||
indexOrButton = this.buttons.indexOf(indexOrButton);
|
||||
}
|
||||
if (indexOrButton > -1) {
|
||||
const btn = this.buttons.splice(indexOrButton, 1);
|
||||
this.update();
|
||||
return btn;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
update() {
|
||||
this.element.replaceChildren(...this.buttons.map((b) => { var _a; return (_a = b["element"]) !== null && _a !== void 0 ? _a : b; }));
|
||||
}
|
||||
}
|
||||
class RgthreeComfyButton {
|
||||
constructor(opts) {
|
||||
this.element = $el("button.rgthree-comfybar-top-button.rgthree-button-reset.rgthree-button");
|
||||
this.iconElement = $el("span.rgthree-button-icon");
|
||||
opts.icon && this.setIcon(opts.icon);
|
||||
opts.tooltip && this.element.setAttribute("title", opts.tooltip);
|
||||
opts.primary && this.element.classList.add("-primary");
|
||||
}
|
||||
setIcon(iconOrMarkup) {
|
||||
const markup = iconOrMarkup.startsWith("<")
|
||||
? iconOrMarkup
|
||||
: `<i class="mdi mdi-${iconOrMarkup}"></i>`;
|
||||
this.iconElement.innerHTML = markup;
|
||||
if (!this.iconElement.parentElement) {
|
||||
this.element.appendChild(this.iconElement);
|
||||
}
|
||||
}
|
||||
withPopup(popup, trigger) {
|
||||
if (trigger === "click") {
|
||||
this.element.addEventListener("click", () => {
|
||||
popup.open();
|
||||
});
|
||||
}
|
||||
if (trigger === "hover") {
|
||||
this.element.addEventListener("pointerenter", () => {
|
||||
popup.open();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
class RgthreeComfyPopup {
|
||||
constructor(opts, element) {
|
||||
this.onOpenFn = null;
|
||||
this.onWindowClickBound = this.onWindowClick.bind(this);
|
||||
this.element = element;
|
||||
this.opts = opts;
|
||||
opts.target && (this.target = opts.target);
|
||||
opts.modal && this.element.classList.add("-modal");
|
||||
}
|
||||
async open() {
|
||||
if (!this.target) {
|
||||
throw new Error("No target for RgthreeComfyPopup");
|
||||
}
|
||||
if (this.onOpenFn) {
|
||||
await this.onOpenFn();
|
||||
}
|
||||
await wait(16);
|
||||
const rect = this.target.getBoundingClientRect();
|
||||
this.element.setAttribute("state", "measuring");
|
||||
document.body.appendChild(this.element);
|
||||
this.element.style.position = "fixed";
|
||||
this.element.style.left = `${rect.left}px`;
|
||||
this.element.style.top = `${rect.top + rect.height}px`;
|
||||
this.element.setAttribute("state", "open");
|
||||
if (this.opts.modal) {
|
||||
document.body.classList.add("rgthree-modal-menu-open");
|
||||
}
|
||||
window.addEventListener("click", this.onWindowClickBound);
|
||||
}
|
||||
close() {
|
||||
this.element.remove();
|
||||
document.body.classList.remove("rgthree-modal-menu-open");
|
||||
window.removeEventListener("click", this.onWindowClickBound);
|
||||
}
|
||||
onOpen(fn) {
|
||||
this.onOpenFn = fn;
|
||||
}
|
||||
onWindowClick() {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
+66
-14
@@ -139,7 +139,7 @@
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.33rem;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
font-family: system-ui, sans-serif;
|
||||
@@ -161,7 +161,7 @@
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.33rem;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
@@ -212,6 +212,46 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group {
|
||||
font-size: 0;
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button {
|
||||
margin: 0;
|
||||
flex: 1 1;
|
||||
height: 36px;
|
||||
padding: 0 12px;
|
||||
border-radius: 0;
|
||||
background: var(--p-button-secondary-background);
|
||||
color: var(--p-button-secondary-color);
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button.-primary {
|
||||
background: var(--p-button-primary-background);
|
||||
color: var(--p-button-primary-color);
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button::before, :not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button::after {
|
||||
border-radius: 0;
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button svg {
|
||||
fill: currentColor;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:first-of-type,
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:first-of-type::before,
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:first-of-type::after {
|
||||
border-top-left-radius: 0.33rem;
|
||||
border-bottom-left-radius: 0.33rem;
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:last-of-type,
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:last-of-type::before,
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:last-of-type::after {
|
||||
border-top-right-radius: 0.33rem;
|
||||
border-bottom-right-radius: 0.33rem;
|
||||
}
|
||||
|
||||
.rgthree-dialog {
|
||||
outline: 0;
|
||||
border: 0;
|
||||
@@ -381,21 +421,21 @@ body.rgthree-dialog-open > *:not(.rgthree-dialog):not(.rgthree-top-messages-cont
|
||||
color: var(--content-fg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.rgthree-top-menu * {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
.rgthree-top-menu menu {
|
||||
.rgthree-top-menu > li:not(#fakeid) {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) > button {
|
||||
.rgthree-top-menu > li:not(#fakeid) > button {
|
||||
cursor: pointer;
|
||||
padding: 8px 12px 8px 8px;
|
||||
width: 100%;
|
||||
@@ -405,21 +445,21 @@ body.rgthree-dialog-open > *:not(.rgthree-dialog):not(.rgthree-top-messages-cont
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) > button:hover {
|
||||
.rgthree-top-menu > li:not(#fakeid) > button:hover {
|
||||
background-color: var(--comfy-input-bg);
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) > button svg {
|
||||
.rgthree-top-menu > li:not(#fakeid) > button svg {
|
||||
height: 16px;
|
||||
width: auto;
|
||||
margin-inline-end: 0.6em;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) > button svg.github-star {
|
||||
.rgthree-top-menu > li:not(#fakeid) > button svg.github-star {
|
||||
fill: rgb(227, 179, 65);
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid).rgthree-message {
|
||||
.rgthree-top-menu > li:not(#fakeid).rgthree-message {
|
||||
min-height: 32px;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid).rgthree-message > span {
|
||||
.rgthree-top-menu > li:not(#fakeid).rgthree-message > span {
|
||||
padding: 8px 12px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
@@ -427,6 +467,18 @@ body.rgthree-dialog-open > *:not(.rgthree-dialog):not(.rgthree-top-messages-cont
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
}
|
||||
.rgthree-top-menu.-modal::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.0666666667);
|
||||
}
|
||||
|
||||
body.rgthree-modal-menu-open > *:not(.rgthree-menu):not(.rgthree-top-messages-container) {
|
||||
filter: blur(2px);
|
||||
}
|
||||
|
||||
.rgthree-dialog.-settings {
|
||||
width: 100%;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.33rem;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
font-family: system-ui, sans-serif;
|
||||
@@ -38,7 +38,7 @@
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.33rem;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
@@ -88,3 +88,43 @@
|
||||
:not(#fakeid) .rgthree-button[disabled]::before, :not(#fakeid) .rgthree-button[disabled]::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group {
|
||||
font-size: 0;
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button {
|
||||
margin: 0;
|
||||
flex: 1 1;
|
||||
height: 36px;
|
||||
padding: 0 12px;
|
||||
border-radius: 0;
|
||||
background: var(--p-button-secondary-background);
|
||||
color: var(--p-button-secondary-color);
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button.-primary {
|
||||
background: var(--p-button-primary-background);
|
||||
color: var(--p-button-primary-color);
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button::before, :not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button::after {
|
||||
border-radius: 0;
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button svg {
|
||||
fill: currentColor;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:first-of-type,
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:first-of-type::before,
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:first-of-type::after {
|
||||
border-top-left-radius: 0.33rem;
|
||||
border-bottom-left-radius: 0.33rem;
|
||||
}
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:last-of-type,
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:last-of-type::before,
|
||||
:not(#fakeid) .rgthree-comfybar-top-button-group .rgthree-comfybar-top-button:last-of-type::after {
|
||||
border-top-right-radius: 0.33rem;
|
||||
border-bottom-right-radius: 0.33rem;
|
||||
}
|
||||
|
||||
+24
-12
@@ -43,21 +43,21 @@
|
||||
color: var(--content-fg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.rgthree-top-menu * {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
.rgthree-top-menu menu {
|
||||
.rgthree-top-menu > li:not(#fakeid) {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) > button {
|
||||
.rgthree-top-menu > li:not(#fakeid) > button {
|
||||
cursor: pointer;
|
||||
padding: 8px 12px 8px 8px;
|
||||
width: 100%;
|
||||
@@ -67,21 +67,21 @@
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) > button:hover {
|
||||
.rgthree-top-menu > li:not(#fakeid) > button:hover {
|
||||
background-color: var(--comfy-input-bg);
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) > button svg {
|
||||
.rgthree-top-menu > li:not(#fakeid) > button svg {
|
||||
height: 16px;
|
||||
width: auto;
|
||||
margin-inline-end: 0.6em;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid) > button svg.github-star {
|
||||
.rgthree-top-menu > li:not(#fakeid) > button svg.github-star {
|
||||
fill: rgb(227, 179, 65);
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid).rgthree-message {
|
||||
.rgthree-top-menu > li:not(#fakeid).rgthree-message {
|
||||
min-height: 32px;
|
||||
}
|
||||
.rgthree-top-menu menu > li:not(#fakeid).rgthree-message > span {
|
||||
.rgthree-top-menu > li:not(#fakeid).rgthree-message > span {
|
||||
padding: 8px 12px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
@@ -89,3 +89,15 @@
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
}
|
||||
.rgthree-top-menu.-modal::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.0666666667);
|
||||
}
|
||||
|
||||
body.rgthree-modal-menu-open > *:not(.rgthree-menu):not(.rgthree-top-messages-container) {
|
||||
filter: blur(2px);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user