mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-09 01:20:09 +00:00
## Summary Adds the linter, turns on the recommended and a few extra rules, fixes existing violations. Doesn't prohibit `../../...` imports yet, that'll be it's own PR. ## Changes - **What**: Consistent and fixable imports - **Dependencies**: The plugin and parser ## Review Focus How do you feel about the recommended rules? What about the extra ones? [Any more](https://github.com/un-ts/eslint-plugin-import-x?tab=readme-ov-file#rules) you'd want to turn on? ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5955-Lint-Add-eslint-import-plugin-2856d73d3650819985c0fb9ca3fa94b0) by [Unito](https://www.unito.io)
248 lines
7.9 KiB
TypeScript
248 lines
7.9 KiB
TypeScript
import { toRaw } from 'vue'
|
|
import { fromZodError } from 'zod-validation-error'
|
|
|
|
import { useErrorHandling } from '@/composables/useErrorHandling'
|
|
import { LGraphCanvas, LiteGraph } from '@/lib/litegraph/src/litegraph'
|
|
import { useSettingStore } from '@/platform/settings/settingStore'
|
|
import { paletteSchema } from '@/schemas/colorPaletteSchema'
|
|
import type { Colors, Palette } from '@/schemas/colorPaletteSchema'
|
|
import { app } from '@/scripts/app'
|
|
import { downloadBlob, uploadFile } from '@/scripts/utils'
|
|
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
|
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
|
|
|
const THEME_PROPERTY_MAP = {
|
|
NODE_BOX_OUTLINE_COLOR: 'node-component-border',
|
|
NODE_DEFAULT_BGCOLOR: 'node-component-surface',
|
|
NODE_DEFAULT_BOXCOLOR: 'node-component-header-icon',
|
|
NODE_DEFAULT_COLOR: 'node-component-header-surface',
|
|
NODE_TITLE_COLOR: 'node-component-header',
|
|
WIDGET_BGCOLOR: 'node-component-widget-input-surface',
|
|
WIDGET_TEXT_COLOR: 'node-component-widget-input'
|
|
} as const satisfies Partial<Record<keyof Colors['litegraph_base'], string>>
|
|
|
|
export const useColorPaletteService = () => {
|
|
const colorPaletteStore = useColorPaletteStore()
|
|
const settingStore = useSettingStore()
|
|
const nodeDefStore = useNodeDefStore()
|
|
const { wrapWithErrorHandling, wrapWithErrorHandlingAsync } =
|
|
useErrorHandling()
|
|
|
|
/**
|
|
* Validates the palette against the zod schema.
|
|
*
|
|
* @param data - The palette to validate.
|
|
* @returns The validated palette.
|
|
*/
|
|
const validateColorPalette = (data: unknown): Palette => {
|
|
const result = paletteSchema.safeParse(data)
|
|
if (result.success) return result.data
|
|
|
|
const error = fromZodError(result.error)
|
|
throw new Error(`Invalid color palette against zod schema:\n${error}`)
|
|
}
|
|
|
|
const persistCustomColorPalettes = async () => {
|
|
await settingStore.set(
|
|
'Comfy.CustomColorPalettes',
|
|
colorPaletteStore.customPalettes
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Deletes a custom color palette.
|
|
*
|
|
* @param colorPaletteId - The ID of the color palette to delete.
|
|
*/
|
|
const deleteCustomColorPalette = async (colorPaletteId: string) => {
|
|
colorPaletteStore.deleteCustomPalette(colorPaletteId)
|
|
await persistCustomColorPalettes()
|
|
}
|
|
|
|
/**
|
|
* Adds a custom color palette.
|
|
*
|
|
* @param colorPalette - The palette to add.
|
|
*/
|
|
const addCustomColorPalette = async (colorPalette: Palette) => {
|
|
validateColorPalette(colorPalette)
|
|
colorPaletteStore.addCustomPalette(colorPalette)
|
|
await persistCustomColorPalettes()
|
|
}
|
|
|
|
/**
|
|
* Sets the colors of node slots and links.
|
|
*
|
|
* @param linkColorPalette - The palette to set.
|
|
*/
|
|
const loadLinkColorPalette = (linkColorPalette: Colors['node_slot']) => {
|
|
const types = Object.fromEntries(
|
|
Array.from(nodeDefStore.nodeDataTypes).map((type) => [type, ''])
|
|
)
|
|
Object.assign(
|
|
app.canvas.default_connection_color_byType,
|
|
types,
|
|
linkColorPalette
|
|
)
|
|
Object.assign(LGraphCanvas.link_type_colors, types, linkColorPalette)
|
|
}
|
|
|
|
function validThemeProp(
|
|
propertyMaybe: unknown
|
|
): propertyMaybe is keyof typeof THEME_PROPERTY_MAP {
|
|
return (
|
|
(propertyMaybe as keyof typeof THEME_PROPERTY_MAP) in THEME_PROPERTY_MAP
|
|
)
|
|
}
|
|
|
|
function loadLitegraphForVueNodes(
|
|
palette: Colors['litegraph_base'],
|
|
colorPaletteId: string
|
|
) {
|
|
if (!palette) return
|
|
const rootStyle = document.getElementById('vue-app')?.style
|
|
if (!rootStyle) return
|
|
|
|
for (const themeVar of Object.keys(THEME_PROPERTY_MAP)) {
|
|
if (!validThemeProp(themeVar)) {
|
|
continue
|
|
}
|
|
const cssVar = THEME_PROPERTY_MAP[themeVar]
|
|
if (colorPaletteId === 'dark' || colorPaletteId === 'light') {
|
|
rootStyle.removeProperty(`--${cssVar}`)
|
|
continue
|
|
}
|
|
const valueMaybe = palette[themeVar]
|
|
if (valueMaybe) {
|
|
rootStyle.setProperty(`--${cssVar}`, valueMaybe)
|
|
} else {
|
|
rootStyle.removeProperty(`--${cssVar}`)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads the LiteGraph color palette.
|
|
*
|
|
* @param liteGraphColorPalette - The palette to set.
|
|
*/
|
|
const loadLiteGraphColorPalette = (palette: Colors['litegraph_base']) => {
|
|
// Sets the colors of the LiteGraph objects
|
|
app.canvas.node_title_color = palette.NODE_TITLE_COLOR
|
|
app.canvas.default_link_color = palette.LINK_COLOR
|
|
const backgroundImage = settingStore.get('Comfy.Canvas.BackgroundImage')
|
|
if (backgroundImage) {
|
|
app.canvas.clear_background_color = 'transparent'
|
|
} else {
|
|
app.canvas.background_image = palette.BACKGROUND_IMAGE
|
|
app.canvas.clear_background_color = palette.CLEAR_BACKGROUND_COLOR
|
|
}
|
|
app.canvas._pattern = undefined
|
|
|
|
for (const [key, value] of Object.entries(palette)) {
|
|
if (Object.prototype.hasOwnProperty.call(LiteGraph, key)) {
|
|
if (key === 'NODE_DEFAULT_SHAPE' && typeof value === 'string') {
|
|
console.warn(
|
|
`litegraph_base.NODE_DEFAULT_SHAPE only accepts [${[
|
|
LiteGraph.BOX_SHAPE,
|
|
LiteGraph.ROUND_SHAPE,
|
|
LiteGraph.CARD_SHAPE
|
|
].join(', ')}] but got ${value}`
|
|
)
|
|
LiteGraph.NODE_DEFAULT_SHAPE = LiteGraph.ROUND_SHAPE
|
|
} else {
|
|
;(LiteGraph as any)[key] = value
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads the Comfy color palette.
|
|
*
|
|
* @param comfyColorPalette - The palette to set.
|
|
*/
|
|
const loadComfyColorPalette = (comfyColorPalette: Colors['comfy_base']) => {
|
|
if (!comfyColorPalette) return
|
|
const rootStyle = document.documentElement.style
|
|
for (const [key, value] of Object.entries(comfyColorPalette)) {
|
|
rootStyle.setProperty('--' + key, value)
|
|
}
|
|
const backgroundImage = settingStore.get('Comfy.Canvas.BackgroundImage')
|
|
if (backgroundImage) {
|
|
rootStyle.setProperty(
|
|
'--bg-img',
|
|
`url('${backgroundImage}') no-repeat center /cover`
|
|
)
|
|
} else {
|
|
rootStyle.removeProperty('--bg-img')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads the color palette.
|
|
*
|
|
* @param colorPaletteId - The ID of the color palette to load.
|
|
*/
|
|
const loadColorPalette = async (colorPaletteId: string) => {
|
|
const colorPalette = colorPaletteStore.palettesLookup[colorPaletteId]
|
|
if (!colorPalette) {
|
|
throw new Error(`Color palette ${colorPaletteId} not found`)
|
|
}
|
|
|
|
const completedPalette = colorPaletteStore.completePalette(colorPalette)
|
|
loadLinkColorPalette(completedPalette.colors.node_slot)
|
|
loadLiteGraphColorPalette(completedPalette.colors.litegraph_base)
|
|
loadLitegraphForVueNodes(
|
|
completedPalette.colors.litegraph_base,
|
|
colorPaletteId
|
|
)
|
|
loadComfyColorPalette(completedPalette.colors.comfy_base)
|
|
app.canvas.setDirty(true, true)
|
|
|
|
colorPaletteStore.activePaletteId = colorPaletteId
|
|
}
|
|
|
|
/**
|
|
* Exports a color palette.
|
|
*
|
|
* @param colorPaletteId - The ID of the color palette to export.
|
|
*/
|
|
const exportColorPalette = (colorPaletteId: string) => {
|
|
const colorPalette = colorPaletteStore.palettesLookup[colorPaletteId]
|
|
if (!colorPalette) {
|
|
throw new Error(`Color palette ${colorPaletteId} not found`)
|
|
}
|
|
downloadBlob(
|
|
colorPalette.id + '.json',
|
|
new Blob([JSON.stringify(toRaw(colorPalette), null, 2)], {
|
|
type: 'application/json'
|
|
})
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Imports a color palette.
|
|
*
|
|
* @returns The imported palette.
|
|
*/
|
|
const importColorPalette = async () => {
|
|
const file = await uploadFile('application/json')
|
|
const text = await file.text()
|
|
const palette = JSON.parse(text)
|
|
await addCustomColorPalette(palette)
|
|
return palette
|
|
}
|
|
|
|
return {
|
|
getActiveColorPalette: () => colorPaletteStore.completedActivePalette,
|
|
addCustomColorPalette: wrapWithErrorHandlingAsync(addCustomColorPalette),
|
|
deleteCustomColorPalette: wrapWithErrorHandlingAsync(
|
|
deleteCustomColorPalette
|
|
),
|
|
loadColorPalette: wrapWithErrorHandlingAsync(loadColorPalette),
|
|
exportColorPalette: wrapWithErrorHandling(exportColorPalette),
|
|
importColorPalette: wrapWithErrorHandlingAsync(importColorPalette)
|
|
}
|
|
}
|