Clear history button
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { LiteGraph, LGraph, LGraphCanvas, LGraphNode, type LGraphNodeConstructor, type LGraphNodeExecutable, type SerializedLGraph, type SerializedLGraphGroup, type SerializedLGraphNode, type SerializedLLink, NodeMode, type Vector2, BuiltInSlotType, type INodeInputSlot, type NodeID, type NodeTypeSpec, type NodeTypeOpts, type SlotIndex, type UUID } from "@litegraph-ts/core";
|
import { LiteGraph, LGraph, LGraphCanvas, LGraphNode, type LGraphNodeConstructor, type LGraphNodeExecutable, type SerializedLGraph, type SerializedLGraphGroup, type SerializedLGraphNode, type SerializedLLink, NodeMode, type Vector2, BuiltInSlotType, type INodeInputSlot, type NodeID, type NodeTypeSpec, type NodeTypeOpts, type SlotIndex, type UUID } from "@litegraph-ts/core";
|
||||||
import type { LConnectionKind, INodeSlot } from "@litegraph-ts/core";
|
import type { LConnectionKind, INodeSlot } from "@litegraph-ts/core";
|
||||||
import ComfyAPI, { type ComfyAPIStatusResponse, type ComfyBoxPromptExtraData, type ComfyPromptRequest, type ComfyNodeID, type PromptID } from "$lib/api"
|
import ComfyAPI, { type ComfyAPIStatusResponse, type ComfyBoxPromptExtraData, type ComfyPromptRequest, type ComfyNodeID, type PromptID, type QueueItemType } from "$lib/api"
|
||||||
import { importA1111, parsePNGMetadata } from "$lib/pnginfo";
|
import { importA1111, parsePNGMetadata } from "$lib/pnginfo";
|
||||||
import EventEmitter from "events";
|
import EventEmitter from "events";
|
||||||
import type TypedEmitter from "typed-emitter";
|
import type TypedEmitter from "typed-emitter";
|
||||||
@@ -33,7 +33,7 @@ import { ComfyBackendNode } from "$lib/nodes/ComfyBackendNode";
|
|||||||
import { get, writable, type Writable } from "svelte/store";
|
import { get, writable, type Writable } from "svelte/store";
|
||||||
import { tick } from "svelte";
|
import { tick } from "svelte";
|
||||||
import uiState from "$lib/stores/uiState";
|
import uiState from "$lib/stores/uiState";
|
||||||
import { basename, download, graphToGraphVis, jsonToJsObject, promptToGraphVis, range, workflowToGraphVis } from "$lib/utils";
|
import { basename, capitalize, download, graphToGraphVis, jsonToJsObject, promptToGraphVis, range, workflowToGraphVis } from "$lib/utils";
|
||||||
import notify from "$lib/notify";
|
import notify from "$lib/notify";
|
||||||
import configState from "$lib/stores/configState";
|
import configState from "$lib/stores/configState";
|
||||||
import { blankGraph } from "$lib/defaultGraph";
|
import { blankGraph } from "$lib/defaultGraph";
|
||||||
@@ -312,7 +312,7 @@ export default class ComfyApp {
|
|||||||
|
|
||||||
const workflows = state.workflows as SerializedAppState[];
|
const workflows = state.workflows as SerializedAppState[];
|
||||||
await Promise.all(workflows.map(w => {
|
await Promise.all(workflows.map(w => {
|
||||||
return this.openWorkflow(w, defs).catch(error => {
|
return this.openWorkflow(w, defs, false).catch(error => {
|
||||||
console.error("Failed restoring previous workflow", error)
|
console.error("Failed restoring previous workflow", error)
|
||||||
notify(`Failed restoring previous workflow: ${error}`, { type: "error" })
|
notify(`Failed restoring previous workflow: ${error}`, { type: "error" })
|
||||||
})
|
})
|
||||||
@@ -509,6 +509,18 @@ export default class ComfyApp {
|
|||||||
this.api.init();
|
this.api.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async clearQueue(type: QueueItemType) {
|
||||||
|
queueState.update(s => { s.isInterrupting = true; return s; })
|
||||||
|
await this.api.clearItems(type)
|
||||||
|
.then(() => {
|
||||||
|
queueState.queueCleared(type);
|
||||||
|
notify(`${capitalize(type)} cleared.`);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
queueState.update(s => { s.isInterrupting = false; return s; })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private addKeyboardHandler() {
|
private addKeyboardHandler() {
|
||||||
window.addEventListener("keydown", (e) => {
|
window.addEventListener("keydown", (e) => {
|
||||||
this.shiftDown = e.shiftKey;
|
this.shiftDown = e.shiftKey;
|
||||||
@@ -557,9 +569,12 @@ export default class ComfyApp {
|
|||||||
setColor(BuiltInSlotType.ACTION, "lightseagreen")
|
setColor(BuiltInSlotType.ACTION, "lightseagreen")
|
||||||
}
|
}
|
||||||
|
|
||||||
async openWorkflow(data: SerializedAppState, refreshCombos: boolean | Record<string, ComfyNodeDef> = true): Promise<ComfyWorkflow> {
|
async openWorkflow(data: SerializedAppState,
|
||||||
|
refreshCombos: boolean | Record<string, ComfyNodeDef> = true,
|
||||||
|
warnMissingNodeTypes: boolean = true
|
||||||
|
): Promise<ComfyWorkflow> {
|
||||||
if (data.version !== COMFYBOX_SERIAL_VERSION) {
|
if (data.version !== COMFYBOX_SERIAL_VERSION) {
|
||||||
const mes = `Invalid ComfyBox saved data format: ${data.version}`
|
const mes = `Invalid ComfyBox saved data format: ${data.version} `
|
||||||
notify(mes, { type: "error" })
|
notify(mes, { type: "error" })
|
||||||
return Promise.reject(mes);
|
return Promise.reject(mes);
|
||||||
}
|
}
|
||||||
@@ -580,7 +595,7 @@ export default class ComfyApp {
|
|||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workflow.missingNodeTypes.size > 0) {
|
if (workflow.missingNodeTypes.size > 0 && warnMissingNodeTypes) {
|
||||||
modalState.pushModal({
|
modalState.pushModal({
|
||||||
svelteComponent: MissingNodeTypesModal,
|
svelteComponent: MissingNodeTypesModal,
|
||||||
svelteProps: {
|
svelteProps: {
|
||||||
@@ -681,7 +696,7 @@ export default class ComfyApp {
|
|||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error("Failed to load default graph", error)
|
console.error("Failed to load default graph", error)
|
||||||
notify(`Failed to load default graph: ${error}`, { type: "error" })
|
notify(`Failed to load default graph: ${error} `, { type: "error" })
|
||||||
state = structuredClone(blankGraph)
|
state = structuredClone(blankGraph)
|
||||||
}
|
}
|
||||||
await this.openWorkflow(state, defs)
|
await this.openWorkflow(state, defs)
|
||||||
@@ -737,7 +752,7 @@ export default class ComfyApp {
|
|||||||
else {
|
else {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const formattedDate = date.toISOString().replace(/:/g, '-').replace(/\.\d{3}/g, '').replace('T', '_').replace("Z", "");
|
const formattedDate = date.toISOString().replace(/:/g, '-').replace(/\.\d{3}/g, '').replace('T', '_').replace("Z", "");
|
||||||
filename = `workflow-${formattedDate}.json`
|
filename = `workflow - ${formattedDate}.json`
|
||||||
}
|
}
|
||||||
|
|
||||||
const indent = 2
|
const indent = 2
|
||||||
@@ -782,7 +797,7 @@ export default class ComfyApp {
|
|||||||
try {
|
try {
|
||||||
while (this.queueItems.length) {
|
while (this.queueItems.length) {
|
||||||
({ num, batchCount, workflow } = this.queueItems.pop());
|
({ num, batchCount, workflow } = this.queueItems.pop());
|
||||||
console.debug(`Queue get! ${num} ${batchCount} ${tag}`);
|
console.debug(`Queue get! ${num} ${batchCount} ${tag} `);
|
||||||
|
|
||||||
const thumbnails = []
|
const thumbnails = []
|
||||||
for (const node of workflow.graph.iterateNodesInOrderRecursive()) {
|
for (const node of workflow.graph.iterateNodesInOrderRecursive()) {
|
||||||
@@ -850,7 +865,7 @@ export default class ComfyApp {
|
|||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
const mes: string = error;
|
const mes: string = error;
|
||||||
notify(`Error queuing prompt:\n${mes}`, { type: "error" })
|
notify(`Error queuing prompt: \n${mes} `, { type: "error" })
|
||||||
console.error(graphToGraphVis(workflow.graph))
|
console.error(graphToGraphVis(workflow.graph))
|
||||||
console.error(promptToGraphVis(p))
|
console.error(promptToGraphVis(p))
|
||||||
console.error("Error queuing prompt", error, num, p)
|
console.error("Error queuing prompt", error, num, p)
|
||||||
|
|||||||
@@ -83,6 +83,18 @@
|
|||||||
changed = false;
|
changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function clearQueue() {
|
||||||
|
await app.clearQueue(mode);
|
||||||
|
|
||||||
|
if (mode === "queue") {
|
||||||
|
_queuedEntries = []
|
||||||
|
_runningEntries = []
|
||||||
|
}
|
||||||
|
|
||||||
|
_entries = [];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
function formatDate(date: Date): string {
|
function formatDate(date: Date): string {
|
||||||
const time = date.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true });
|
const time = date.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true });
|
||||||
const day = date.toLocaleString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' }).replace(',', '');
|
const day = date.toLocaleString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' }).replace(',', '');
|
||||||
@@ -173,16 +185,6 @@
|
|||||||
console.warn("[ComfyQueue] BUILDHISTORY", _entries, $queueCompleted)
|
console.warn("[ComfyQueue] BUILDHISTORY", _entries, $queueCompleted)
|
||||||
}
|
}
|
||||||
|
|
||||||
function showLightbox(images: string[], index: number, e: Event) {
|
|
||||||
e.preventDefault()
|
|
||||||
if (!images)
|
|
||||||
return
|
|
||||||
|
|
||||||
ImageViewer.instance.showModal(images, index);
|
|
||||||
|
|
||||||
e.stopPropagation()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function interrupt() {
|
async function interrupt() {
|
||||||
if ($queueState.isInterrupting)
|
if ($queueState.isInterrupting)
|
||||||
return
|
return
|
||||||
@@ -254,9 +256,9 @@
|
|||||||
<div class="queue-entries" bind:this={queueList}>
|
<div class="queue-entries" bind:this={queueList}>
|
||||||
{#if _entries.length > 0}
|
{#if _entries.length > 0}
|
||||||
{#if mode === "history" && displayMode === "grid"}
|
{#if mode === "history" && displayMode === "grid"}
|
||||||
<ComfyQueueGridDisplay entries={_entries} {showLightbox} {showPrompt} {mode} />
|
<ComfyQueueGridDisplay entries={_entries} {showPrompt} {clearQueue} {mode} />
|
||||||
{:else}
|
{:else}
|
||||||
<ComfyQueueListDisplay entries={_entries} {showLightbox} {showPrompt} {mode} />
|
<ComfyQueueListDisplay entries={_entries} {showPrompt} {clearQueue} {mode} />
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<div class="queue-empty">
|
<div class="queue-empty">
|
||||||
@@ -405,41 +407,8 @@
|
|||||||
.mode-button {
|
.mode-button {
|
||||||
height: calc($mode-buttons-height);
|
height: calc($mode-buttons-height);
|
||||||
padding: 0.2rem;
|
padding: 0.2rem;
|
||||||
border: 1px solid var(--panel-border-color);
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
margin: auto;
|
|
||||||
|
|
||||||
&.primary {
|
@include square-button;
|
||||||
background: var(--button-primary-background-fill);
|
|
||||||
&:hover {
|
|
||||||
background: var(--button-primary-background-fill-hover);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.secondary {
|
|
||||||
background: var(--button-secondary-background-fill);
|
|
||||||
&:hover {
|
|
||||||
background: var(--button-secondary-background-fill-hover);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.ternary {
|
|
||||||
background: var(--panel-background-fill);
|
|
||||||
&:hover {
|
|
||||||
background: var(--block-background-fill );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
filter: brightness(85%);
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
filter: brightness(50%)
|
|
||||||
}
|
|
||||||
&.selected {
|
|
||||||
filter: brightness(80%)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.dark) .mode-button {
|
:global(.dark) .mode-button {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { QueueItemType } from "$lib/api";
|
import type { QueueItemType } from "$lib/api";
|
||||||
import { truncateString } from "$lib/utils";
|
import { showLightbox } from "$lib/utils";
|
||||||
import type { QueueUIEntry } from "./ComfyQueue.svelte";
|
import type { QueueUIEntry } from "./ComfyQueue.svelte";
|
||||||
|
import queueState from "$lib/stores/queueState";
|
||||||
|
|
||||||
export let entries: QueueUIEntry[] = [];
|
export let entries: QueueUIEntry[] = [];
|
||||||
export let showPrompt: (entry: QueueUIEntry) => void;
|
export let showPrompt: (entry: QueueUIEntry) => void;
|
||||||
export let showLightbox: (images: string[], index: number, e: Event) => void;
|
export let clearQueue: () => Promise<void>;
|
||||||
export let mode: QueueItemType = "queue";
|
export let mode: QueueItemType = "queue";
|
||||||
|
|
||||||
let allEntries: [QueueUIEntry, string][] = []
|
let allEntries: [QueueUIEntry, string][] = []
|
||||||
@@ -34,10 +35,17 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="grid-wrapper">
|
<div class="grid-wrapper {mode}-mode">
|
||||||
<div class="grid-columns">
|
<div class="grid-columns">
|
||||||
<div>
|
<div>
|
||||||
<input type="range" bind:value={gridColumns} min={1} max={8} step={1} />
|
<input type="range" bind:value={gridColumns} min={1} max={8} step={1} />
|
||||||
|
<div class="button-wrapper">
|
||||||
|
<button class="clear-queue-button secondary"
|
||||||
|
on:click={clearQueue}
|
||||||
|
disabled={$queueState.isInterrupting}>
|
||||||
|
🗑️
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-entries">
|
<div class="grid-entries">
|
||||||
@@ -63,21 +71,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.grid-columns {
|
.grid-columns {
|
||||||
width: 100%;
|
|
||||||
height: $grid-columns-control-height;
|
height: $grid-columns-control-height;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: var(--spacing-lg) 0;
|
margin: 0.25rem 1rem;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: auto;
|
height: 100%;
|
||||||
padding: 0 1rem;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-wrapper {
|
||||||
|
padding: 0.25rem;
|
||||||
|
.clear-queue-button {
|
||||||
|
@include square-button;
|
||||||
|
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { QueueItemType } from "$lib/api";
|
import type { QueueItemType } from "$lib/api";
|
||||||
import { truncateString } from "$lib/utils";
|
import { showLightbox, truncateString } from "$lib/utils";
|
||||||
import type { QueueUIEntry } from "./ComfyQueue.svelte";
|
import type { QueueUIEntry } from "./ComfyQueue.svelte";
|
||||||
|
|
||||||
export let entries: QueueUIEntry[] = [];
|
export let entries: QueueUIEntry[] = [];
|
||||||
export let showPrompt: (entry: QueueUIEntry) => void;
|
export let showPrompt: (entry: QueueUIEntry) => void;
|
||||||
export let showLightbox: (images: string[], index: number, e: Event) => void;
|
export let clearQueue: () => void;
|
||||||
export let mode: QueueItemType = "queue";
|
export let mode: QueueItemType = "queue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ComfyAPIHistoryEntry, ComfyAPIHistoryItem, ComfyAPIHistoryResponse, ComfyAPIQueueResponse, ComfyAPIStatusResponse, ComfyBoxPromptExtraData, ComfyNodeID, PromptID } from "$lib/api";
|
import type { ComfyAPIHistoryEntry, ComfyAPIHistoryItem, ComfyAPIHistoryResponse, ComfyAPIQueueResponse, ComfyAPIStatusResponse, ComfyBoxPromptExtraData, ComfyNodeID, PromptID, QueueItemType } from "$lib/api";
|
||||||
import type { Progress, SerializedPromptInputsAll, SerializedPromptOutputs, WorkflowInstID } from "$lib/components/ComfyApp";
|
import type { Progress, SerializedPromptInputsAll, SerializedPromptOutputs, WorkflowInstID } from "$lib/components/ComfyApp";
|
||||||
import type { ComfyExecutionResult } from "$lib/nodes/ComfyWidgetNodes";
|
import type { ComfyExecutionResult } from "$lib/nodes/ComfyWidgetNodes";
|
||||||
import notify from "$lib/notify";
|
import notify from "$lib/notify";
|
||||||
@@ -17,6 +17,7 @@ type QueueStateOps = {
|
|||||||
progressUpdated: (progress: Progress) => void
|
progressUpdated: (progress: Progress) => void
|
||||||
getQueueEntry: (promptID: PromptID) => QueueEntry | null;
|
getQueueEntry: (promptID: PromptID) => QueueEntry | null;
|
||||||
afterQueued: (workflowID: WorkflowInstID, promptID: PromptID, number: number, prompt: SerializedPromptInputsAll, extraData: any) => void
|
afterQueued: (workflowID: WorkflowInstID, promptID: PromptID, number: number, prompt: SerializedPromptInputsAll, extraData: any) => void
|
||||||
|
queueCleared: (type: QueueItemType) => void;
|
||||||
onExecuted: (promptID: PromptID, nodeID: ComfyNodeID, output: ComfyExecutionResult) => QueueEntry | null
|
onExecuted: (promptID: PromptID, nodeID: ComfyNodeID, output: ComfyExecutionResult) => QueueEntry | null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,6 +364,25 @@ function onExecuted(promptID: PromptID, nodeID: ComfyNodeID, outputs: ComfyExecu
|
|||||||
return entry_;
|
return entry_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function queueCleared(type: QueueItemType) {
|
||||||
|
console.debug("[queueState] queueCleared", type)
|
||||||
|
|
||||||
|
store.update(s => {
|
||||||
|
if (type === "queue") {
|
||||||
|
s.queuePending.set([]);
|
||||||
|
s.queueRunning.set([]);
|
||||||
|
s.queueRemaining = 0;
|
||||||
|
s.runningNodeID = null;
|
||||||
|
s.progress = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s.queueCompleted.set([])
|
||||||
|
}
|
||||||
|
s.isInterrupting = false;
|
||||||
|
return s;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const queueStateStore: WritableQueueStateStore =
|
const queueStateStore: WritableQueueStateStore =
|
||||||
{
|
{
|
||||||
...store,
|
...store,
|
||||||
@@ -375,6 +395,7 @@ const queueStateStore: WritableQueueStateStore =
|
|||||||
executionCached,
|
executionCached,
|
||||||
executionError,
|
executionError,
|
||||||
afterQueued,
|
afterQueued,
|
||||||
|
queueCleared,
|
||||||
getQueueEntry,
|
getQueueEntry,
|
||||||
onExecuted
|
onExecuted
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { get } from "svelte/store";
|
|||||||
import type { ComfyNodeID } from "./api";
|
import type { ComfyNodeID } from "./api";
|
||||||
import { type SerializedPrompt } from "./components/ComfyApp";
|
import { type SerializedPrompt } from "./components/ComfyApp";
|
||||||
import workflowState from "./stores/workflowState";
|
import workflowState from "./stores/workflowState";
|
||||||
|
import { ImageViewer } from "./ImageViewer";
|
||||||
|
|
||||||
export function clamp(n: number, min: number, max: number): number {
|
export function clamp(n: number, min: number, max: number): number {
|
||||||
return Math.min(Math.max(n, min), max)
|
return Math.min(Math.max(n, min), max)
|
||||||
@@ -23,6 +24,10 @@ export function countNewLines(str: string): number {
|
|||||||
return str.split(/\r\n|\r|\n/).length
|
return str.split(/\r\n|\r|\n/).length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function capitalize(str: string) {
|
||||||
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
export function basename(filepath: string): string {
|
export function basename(filepath: string): string {
|
||||||
const filename = filepath.split('/').pop().split('\\').pop();
|
const filename = filepath.split('/').pop().split('\\').pop();
|
||||||
return filename.split('.').slice(0, -1).join('.');
|
return filename.split('.').slice(0, -1).join('.');
|
||||||
@@ -501,3 +506,13 @@ export function comfyBoxImageToComfyFile(image: ComfyBoxImageMetadata): ComfyIma
|
|||||||
export function comfyBoxImageToComfyURL(image: ComfyBoxImageMetadata): string {
|
export function comfyBoxImageToComfyURL(image: ComfyBoxImageMetadata): string {
|
||||||
return convertComfyOutputToComfyURL(image.comfyUIFile)
|
return convertComfyOutputToComfyURL(image.comfyUIFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function showLightbox(images: string[], index: number, e: Event) {
|
||||||
|
e.preventDefault()
|
||||||
|
if (!images)
|
||||||
|
return
|
||||||
|
|
||||||
|
ImageViewer.instance.showModal(images, index);
|
||||||
|
|
||||||
|
e.stopPropagation()
|
||||||
|
}
|
||||||
|
|||||||
@@ -81,6 +81,44 @@ body {
|
|||||||
--comfy-progress-bar-foreground: #B3D8A9
|
--comfy-progress-bar-foreground: #B3D8A9
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin square-button {
|
||||||
|
border: 1px solid var(--panel-border-color);
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
margin: auto;
|
||||||
|
|
||||||
|
&.primary {
|
||||||
|
background: var(--button-primary-background-fill);
|
||||||
|
&:hover {
|
||||||
|
background: var(--button-primary-background-fill-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.secondary {
|
||||||
|
background: var(--button-secondary-background-fill);
|
||||||
|
&:hover {
|
||||||
|
background: var(--button-secondary-background-fill-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ternary {
|
||||||
|
background: var(--panel-background-fill);
|
||||||
|
&:hover {
|
||||||
|
background: var(--block-background-fill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: brightness(85%);
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
filter: brightness(50%)
|
||||||
|
}
|
||||||
|
&.selected {
|
||||||
|
filter: brightness(80%)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@mixin disable-input {
|
@mixin disable-input {
|
||||||
-webkit-text-fill-color: var(--comfy-disabled-textbox-text-color);
|
-webkit-text-fill-color: var(--comfy-disabled-textbox-text-color);
|
||||||
background-color: var(--comfy-disabled-textbox-background-fill);
|
background-color: var(--comfy-disabled-textbox-background-fill);
|
||||||
|
|||||||
Reference in New Issue
Block a user