New settings API (#1292)

* Add settings API

* Add playwright test

* Update README
This commit is contained in:
Chenlei Hu
2024-10-24 16:26:01 +02:00
committed by GitHub
parent 3553c8e0d4
commit 957a767ed0
9 changed files with 109 additions and 4 deletions

View File

@@ -193,7 +193,53 @@ https://github.com/user-attachments/assets/c142c43f-2fe9-4030-8196-b3bfd4c6977d
https://github.com/user-attachments/assets/5696a89d-4a47-4fcc-9e8c-71e1264943f2 https://github.com/user-attachments/assets/5696a89d-4a47-4fcc-9e8c-71e1264943f2
</details> </details>
### Node developers API ### Developer APIs
<details>
<summary>v1.3.22: New settings API</summary>
Legacy settings API.
```js
// Register a new setting
app.ui.settings.addSetting({
id: 'TestSetting',
name: 'Test Setting',
type: 'text',
defaultValue: 'Hello, world!'
})
// Get the value of a setting
const value = app.ui.settings.getSettingValue('TestSetting')
// Set the value of a setting
app.ui.settings.setSettingValue('TestSetting', 'Hello, universe!')
```
New settings API.
```js
// Register a new setting
app.registerExtension({
name: 'TestExtension1',
settings: [
{
id: 'TestSetting',
name: 'Test Setting',
type: 'text',
defaultValue: 'Hello, world!'
}
]
})
// Get the value of a setting
const value = app.extensionManager.setting.get('TestSetting')
// Set the value of a setting
app.extensionManager.setting.set('TestSetting', 'Hello, universe!')
```
</details>
<details> <details>
<summary>v1.3.7: Register commands and keybindings</summary> <summary>v1.3.7: Register commands and keybindings</summary>

View File

@@ -528,7 +528,7 @@ export class ComfyPage {
async setSetting(settingId: string, settingValue: any) { async setSetting(settingId: string, settingValue: any) {
return await this.page.evaluate( return await this.page.evaluate(
async ({ id, value }) => { async ({ id, value }) => {
await window['app'].ui.settings.setSettingValueAsync(id, value) await window['app'].extensionManager.setting.set(id, value)
}, },
{ id: settingId, value: settingValue } { id: settingId, value: settingValue }
) )
@@ -536,7 +536,7 @@ export class ComfyPage {
async getSetting(settingId: string) { async getSetting(settingId: string) {
return await this.page.evaluate(async (id) => { return await this.page.evaluate(async (id) => {
return await window['app'].ui.settings.getSettingValue(id) return await window['app'].extensionManager.setting.get(id)
}, settingId) }, settingId)
} }

View File

@@ -83,4 +83,23 @@ test.describe('Topbar commands', () => {
true true
) )
}) })
test('Should allow adding settings', async ({ comfyPage }) => {
await comfyPage.page.evaluate(() => {
window['app'].registerExtension({
name: 'TestExtension1',
settings: [
{
id: 'TestSetting',
name: 'Test Setting',
type: 'text',
defaultValue: 'Hello, world!'
}
]
})
})
expect(await comfyPage.getSetting('TestSetting')).toBe('Hello, world!')
await comfyPage.setSetting('TestSetting', 'Hello, universe!')
expect(await comfyPage.getSetting('TestSetting')).toBe('Hello, universe!')
})
}) })

View File

@@ -169,6 +169,23 @@ export class ComfySettingsDialog extends ComfyDialog<HTMLDialogElement> {
this.#dispatchChange(id, value) this.#dispatchChange(id, value)
} }
/**
* Deprecated for external callers/extensions. Use `ComfyExtension.settings` field instead.
* Example:
* ```ts
* app.registerExtension({
* name: 'My Extension',
* settings: [
* {
* id: 'My.Setting',
* name: 'My Setting',
* type: 'text',
* defaultValue: 'Hello, world!'
* }
* ]
* })
* ```
*/
addSetting(params: SettingParams) { addSetting(params: SettingParams) {
const { const {
id, id,

View File

@@ -47,6 +47,7 @@ export const useExtensionStore = defineStore('extension', () => {
useKeybindingStore().loadExtensionKeybindings(extension) useKeybindingStore().loadExtensionKeybindings(extension)
useCommandStore().loadExtensionCommands(extension) useCommandStore().loadExtensionCommands(extension)
useMenuItemStore().loadExtensionMenuCommands(extension) useMenuItemStore().loadExtensionMenuCommands(extension)
useSettingStore().loadExtensionSettings(extension)
/* /*
* Extensions are currently stored in both extensionStore and app.extensions. * Extensions are currently stored in both extensionStore and app.extensions.

View File

@@ -16,6 +16,7 @@ import { buildTree } from '@/utils/treeUtil'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import type { TreeNode } from 'primevue/treenode' import type { TreeNode } from 'primevue/treenode'
import { CORE_SETTINGS } from '@/stores/coreSettings' import { CORE_SETTINGS } from '@/stores/coreSettings'
import { ComfyExtension } from '@/types/comfy'
export interface SettingTreeNode extends TreeNode { export interface SettingTreeNode extends TreeNode {
data?: SettingParams data?: SettingParams
@@ -68,6 +69,12 @@ export const useSettingStore = defineStore('setting', {
}) })
}, },
loadExtensionSettings(extension: ComfyExtension) {
extension.settings?.forEach((setting: SettingParams) => {
app.ui.settings.addSetting(setting)
})
},
async set<K extends keyof Settings>(key: K, value: Settings[K]) { async set<K extends keyof Settings>(key: K, value: Settings[K]) {
this.settingValues[key] = value this.settingValues[key] = value
await app.ui.settings.setSettingValueAsync(key, value) await app.ui.settings.setSettingValueAsync(key, value)

View File

@@ -4,6 +4,7 @@ import { useToastStore } from './toastStore'
import { useQueueSettingsStore } from './queueStore' import { useQueueSettingsStore } from './queueStore'
import { useCommandStore } from './commandStore' import { useCommandStore } from './commandStore'
import { useSidebarTabStore } from './workspace/sidebarTabStore' import { useSidebarTabStore } from './workspace/sidebarTabStore'
import { useSettingStore } from './settingStore'
interface WorkspaceState { interface WorkspaceState {
spinner: boolean spinner: boolean
@@ -30,6 +31,12 @@ export const useWorkspaceStore = defineStore('workspace', {
}, },
sidebarTab() { sidebarTab() {
return useSidebarTabStore() return useSidebarTabStore()
},
setting() {
return {
get: useSettingStore().get,
set: useSettingStore().set
}
} }
}, },
actions: { actions: {

View File

@@ -3,6 +3,7 @@ import { ComfyApp } from '../scripts/app'
import type { ComfyNodeDef } from '@/types/apiTypes' import type { ComfyNodeDef } from '@/types/apiTypes'
import type { Keybinding } from '@/types/keyBindingTypes' import type { Keybinding } from '@/types/keyBindingTypes'
import type { ComfyCommand } from '@/stores/commandStore' import type { ComfyCommand } from '@/stores/commandStore'
import { SettingParams } from './settingTypes'
export type Widgets = Record< export type Widgets = Record<
string, string,
@@ -43,6 +44,10 @@ export interface ComfyExtension {
* Menu commands to add to the menu bar * Menu commands to add to the menu bar
*/ */
menuCommands?: MenuCommandGroup[] menuCommands?: MenuCommandGroup[]
/**
* Settings to add to the settings menu
*/
settings?: SettingParams[]
/** /**
* Allows any initialisation, e.g. loading resources. Called after the canvas is created but before nodes are added * Allows any initialisation, e.g. loading resources. Called after the canvas is created but before nodes are added
* @param app The ComfyUI app instance * @param app The ComfyUI app instance

View File

@@ -37,9 +37,12 @@ export interface ExtensionManager {
unregisterSidebarTab(id: string): void unregisterSidebarTab(id: string): void
getSidebarTabs(): SidebarTabExtension[] getSidebarTabs(): SidebarTabExtension[]
// Toast
toast: ToastManager toast: ToastManager
command: CommandManager command: CommandManager
setting: {
get: (id: string) => any
set: (id: string, value: any) => void
}
} }
export interface CommandManager { export interface CommandManager {