mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-05 15:40:10 +00:00
feat: Implement versioned default settings system
This commit is contained in:
@@ -762,7 +762,7 @@ export class ComfyPage {
|
||||
y: 625
|
||||
}
|
||||
})
|
||||
this.page.mouse.move(10, 10)
|
||||
await this.page.mouse.move(10, 10)
|
||||
await this.nextFrame()
|
||||
}
|
||||
|
||||
@@ -774,7 +774,7 @@ export class ComfyPage {
|
||||
},
|
||||
button: 'right'
|
||||
})
|
||||
this.page.mouse.move(10, 10)
|
||||
await this.page.mouse.move(10, 10)
|
||||
await this.nextFrame()
|
||||
}
|
||||
|
||||
@@ -1072,7 +1072,9 @@ export const comfyPageFixture = base.extend<{
|
||||
'Comfy.EnableTooltips': false,
|
||||
'Comfy.userId': userId,
|
||||
// Set tutorial completed to true to avoid loading the tutorial workflow.
|
||||
'Comfy.TutorialCompleted': true
|
||||
'Comfy.TutorialCompleted': true,
|
||||
// Set installed version for consistent test behavior.
|
||||
'Comfy.InstalledVersion': '1.22.1'
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
@@ -1083,7 +1085,7 @@ export const comfyPageFixture = base.extend<{
|
||||
},
|
||||
comfyMouse: async ({ comfyPage }, use) => {
|
||||
const comfyMouse = new ComfyMouse(comfyPage)
|
||||
use(comfyMouse)
|
||||
await use(comfyMouse)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ import { useSettingStore } from '@/stores/settingStore'
|
||||
import { useToastStore } from '@/stores/toastStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import { getCurrentVersion } from '@/utils/versioning'
|
||||
|
||||
const emit = defineEmits<{
|
||||
ready: []
|
||||
@@ -300,6 +301,13 @@ onMounted(async () => {
|
||||
CORE_SETTINGS.forEach((setting) => {
|
||||
settingStore.addSetting(setting)
|
||||
})
|
||||
if (!settingStore.get('Comfy.InstalledVersion')) {
|
||||
const currentVersion =
|
||||
Object.keys(settingStore.settingValues).length > 0
|
||||
? '0.0.1'
|
||||
: getCurrentVersion()
|
||||
await settingStore.set('Comfy.InstalledVersion', currentVersion)
|
||||
}
|
||||
// @ts-expect-error fixme ts strict error
|
||||
await comfyApp.setup(canvasRef.value)
|
||||
canvasStore.canvas = comfyApp.canvas
|
||||
|
||||
@@ -35,7 +35,10 @@ export const CORE_SETTINGS: SettingParams[] = [
|
||||
name: 'Action on link release (No modifier)',
|
||||
type: 'combo',
|
||||
options: Object.values(LinkReleaseTriggerAction),
|
||||
defaultValue: LinkReleaseTriggerAction.CONTEXT_MENU
|
||||
defaultValue: LinkReleaseTriggerAction.CONTEXT_MENU,
|
||||
defaultsByInstallVersion: {
|
||||
'1.21.3': LinkReleaseTriggerAction.SEARCH_BOX
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'Comfy.LinkRelease.ActionShift',
|
||||
@@ -747,6 +750,13 @@ export const CORE_SETTINGS: SettingParams[] = [
|
||||
defaultValue: false,
|
||||
versionAdded: '1.8.7'
|
||||
},
|
||||
{
|
||||
id: 'Comfy.InstalledVersion',
|
||||
name: 'Installed version',
|
||||
type: 'hidden',
|
||||
defaultValue: null,
|
||||
versionAdded: '1.22.1'
|
||||
},
|
||||
{
|
||||
id: 'LiteGraph.ContextMenu.Scaling',
|
||||
name: 'Scale node combo widget menus (lists) when zoomed in',
|
||||
|
||||
@@ -448,6 +448,7 @@ const zSettings = z.object({
|
||||
'Comfy.Toast.DisableReconnectingToast': z.boolean(),
|
||||
'Comfy.Workflow.Persist': z.boolean(),
|
||||
'Comfy.TutorialCompleted': z.boolean(),
|
||||
'Comfy.InstalledVersion': z.string().nullable(),
|
||||
'Comfy.Node.AllowImageSizeDraw': z.boolean(),
|
||||
'Comfy-Desktop.AutoUpdate': z.boolean(),
|
||||
'Comfy-Desktop.SendStatistics': z.boolean(),
|
||||
@@ -471,6 +472,7 @@ const zSettings = z.object({
|
||||
'VHS.AdvancedPreviews': z.string(),
|
||||
/** Settings used for testing */
|
||||
'test.setting': z.any(),
|
||||
'test.versionedSetting': z.any(),
|
||||
'main.sub.setting.name': z.any(),
|
||||
'single.setting': z.any(),
|
||||
'LiteGraph.Node.DefaultPadding': z.boolean(),
|
||||
|
||||
@@ -7,6 +7,7 @@ import { api } from '@/scripts/api'
|
||||
import { app } from '@/scripts/app'
|
||||
import type { SettingParams } from '@/types/settingTypes'
|
||||
import type { TreeNode } from '@/types/treeExplorerTypes'
|
||||
import { compareVersions } from '@/utils/versioning'
|
||||
|
||||
export const getSettingInfo = (setting: SettingParams) => {
|
||||
const parts = setting.category || setting.id.split('.')
|
||||
@@ -83,6 +84,29 @@ export const useSettingStore = defineStore('setting', () => {
|
||||
*/
|
||||
function getDefaultValue<K extends keyof Settings>(key: K): Settings[K] {
|
||||
const param = settingsById.value[key]
|
||||
|
||||
// Check for versioned defaults based on installation version
|
||||
if (param?.defaultsByInstallVersion) {
|
||||
const installedVersion = get('Comfy.InstalledVersion')
|
||||
|
||||
if (installedVersion) {
|
||||
// Find the highest version that is <= installedVersion
|
||||
const sortedVersions = Object.keys(param.defaultsByInstallVersion).sort(
|
||||
(a, b) => compareVersions(a, b)
|
||||
)
|
||||
|
||||
for (const version of sortedVersions.reverse()) {
|
||||
if (compareVersions(installedVersion, version) >= 0) {
|
||||
const versionedDefault = param.defaultsByInstallVersion[version]
|
||||
return typeof versionedDefault === 'function'
|
||||
? versionedDefault()
|
||||
: versionedDefault
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to original defaultValue
|
||||
return typeof param?.defaultValue === 'function'
|
||||
? param.defaultValue()
|
||||
: param?.defaultValue
|
||||
|
||||
@@ -35,6 +35,8 @@ export interface Setting {
|
||||
export interface SettingParams extends FormItem {
|
||||
id: keyof Settings
|
||||
defaultValue: any | (() => any)
|
||||
// Optional versioned defaults based on installation version
|
||||
defaultsByInstallVersion?: Record<string, any | (() => any)>
|
||||
onChange?: (newValue: any, oldValue?: any) => void
|
||||
// By default category is id.split('.'). However, changing id to assign
|
||||
// new category has poor backward compatibility. Use this field to overwrite
|
||||
|
||||
37
src/utils/versioning.ts
Normal file
37
src/utils/versioning.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
|
||||
/**
|
||||
* Compare two semantic version strings.
|
||||
* @param a - First version string
|
||||
* @param b - Second version string
|
||||
* @returns 0 if equal, 1 if a > b, -1 if a < b
|
||||
*/
|
||||
export function compareVersions(a: string, b: string): number {
|
||||
const parseVersion = (version: string) => {
|
||||
return version.split('.').map((v) => parseInt(v, 10) || 0)
|
||||
}
|
||||
|
||||
const versionA = parseVersion(a)
|
||||
const versionB = parseVersion(b)
|
||||
|
||||
for (let i = 0; i < Math.max(versionA.length, versionB.length); i++) {
|
||||
const numA = versionA[i] || 0
|
||||
const numB = versionB[i] || 0
|
||||
|
||||
if (numA > numB) return 1
|
||||
if (numA < numB) return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current ComfyUI version for version tracking
|
||||
*/
|
||||
export function getCurrentVersion(): string {
|
||||
if (isElectron()) {
|
||||
return electronAPI().getComfyUIVersion()
|
||||
}
|
||||
// For web version, fallback to frontend version
|
||||
return __COMFYUI_FRONTEND_VERSION__
|
||||
}
|
||||
@@ -122,6 +122,26 @@ describe('useSettingStore', () => {
|
||||
expect(store.get('test.setting')).toBe('default')
|
||||
})
|
||||
|
||||
it('should use versioned default based on installation version', () => {
|
||||
// Set up an installed version
|
||||
store.settingValues['Comfy.InstalledVersion'] = '1.25.0'
|
||||
|
||||
const setting: SettingParams = {
|
||||
id: 'test.versionedSetting',
|
||||
name: 'test.versionedSetting',
|
||||
type: 'text',
|
||||
defaultValue: 'original',
|
||||
defaultsByInstallVersion: {
|
||||
'1.20.0': 'version_1_20',
|
||||
'1.24.0': 'version_1_24'
|
||||
}
|
||||
}
|
||||
store.addSetting(setting)
|
||||
|
||||
// Should use the highest version <= installed version
|
||||
expect(store.get('test.versionedSetting')).toBe('version_1_24')
|
||||
})
|
||||
|
||||
it('should set value and trigger onChange', async () => {
|
||||
const onChangeMock = vi.fn()
|
||||
const dispatchChangeMock = vi.mocked(app.ui.settings.dispatchChange)
|
||||
|
||||
Reference in New Issue
Block a user