mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-21 03:01:27 -03:00
fix(ui): remove per-node active-filters chip from loras widgets
The indicator chip added for /activefilters discoverability was broken by design of its import path: AutocompleteTextWidget.vue imported web/comfyui/settings.js into the vue-widgets bundle, and settings.js's "../../scripts/app.js" import resolved at build time to the repo-root test shim (scripts/app.js, an in-memory settings store). The chip therefore read and wrote an orphaned in-memory Map: clicking it flipped only its own visual state and never touched the real ComfyUI setting that autocomplete.js consults (use_active_filters query param). Beyond the defect, a persistent per-node control for a global persisted setting misleads users and needs cross-instance sync machinery, which the footer hint, slash commands, right-click menu entry and settings dialog already cover. - AutocompleteTextWidget.vue: remove the chip button, its state/handlers, the settings.js import (the shim-inlining pathway) and all chip styles - AutocompleteTextWidget.test.ts: drop the chip indicator describe block and the settings.js module mock; beforeEach import no longer needed - settings.js: drop the lora-manager:setting-toggled window broadcast and its export — the chip was its only consumer, so every setLoraManagerSettingValue write no longer dispatches a dead event - autocomplete.activeFilters.test.js: drop the broadcast assertion test - loraLoader.activeFiltersMenu.test.js: drop SETTING_TOGGLED_EVENT_NAME from the settings.js mock Discoverability of /activefilters // /noactivefilters is unchanged: command-list footer, first-run hint, node context menu, settings dialog.
This commit is contained in:
@@ -253,37 +253,4 @@ describe('AutoComplete active-filters flag', () => {
|
|||||||
|
|
||||||
expect(autoComplete.dropdown.querySelector('.lm-autocomplete-first-run-hint')).toBeNull();
|
expect(autoComplete.dropdown.querySelector('.lm-autocomplete-first-run-hint')).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('broadcasts a setting-toggled window event when /activefilters is accepted', async () => {
|
|
||||||
const events = [];
|
|
||||||
const listener = (event) => events.push(event.detail);
|
|
||||||
window.addEventListener('lora-manager:setting-toggled', listener);
|
|
||||||
try {
|
|
||||||
const input = document.createElement('textarea');
|
|
||||||
input.value = '/activefilters';
|
|
||||||
input.selectionStart = input.value.length;
|
|
||||||
input.focus = vi.fn();
|
|
||||||
input.setSelectionRange = vi.fn();
|
|
||||||
document.body.append(input);
|
|
||||||
|
|
||||||
caretHelperInstance.getBeforeCursor.mockReturnValue('/activefilters');
|
|
||||||
|
|
||||||
const { AutoComplete } = await import(AUTOCOMPLETE_MODULE);
|
|
||||||
const autoComplete = new AutoComplete(input, 'loras', { showPreview: false, minChars: 1 });
|
|
||||||
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
||||||
|
|
||||||
// The command token is cleared after acceptance; simulate the caret
|
|
||||||
// helper seeing the cleared input so the synthetic input event does
|
|
||||||
// not re-trigger command parsing (same pattern as behavior tests).
|
|
||||||
caretHelperInstance.getBeforeCursor.mockReturnValue('');
|
|
||||||
await Promise.resolve();
|
|
||||||
await Promise.resolve();
|
|
||||||
expect(events).toContainEqual({
|
|
||||||
settingId: 'loramanager.lora_active_filters_autocomplete',
|
|
||||||
value: true,
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
window.removeEventListener('lora-manager:setting-toggled', listener);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ const setSettingValueMock = vi.fn();
|
|||||||
vi.mock(SETTINGS_MODULE, () => ({
|
vi.mock(SETTINGS_MODULE, () => ({
|
||||||
LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID:
|
LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID:
|
||||||
"loramanager.lora_active_filters_autocomplete",
|
"loramanager.lora_active_filters_autocomplete",
|
||||||
SETTING_TOGGLED_EVENT_NAME: "lora-manager:setting-toggled",
|
|
||||||
getLoraActiveFiltersAutocompletePreference: getActiveFiltersPreferenceMock,
|
getLoraActiveFiltersAutocompletePreference: getActiveFiltersPreferenceMock,
|
||||||
setLoraManagerSettingValue: setSettingValueMock,
|
setLoraManagerSettingValue: setSettingValueMock,
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -27,18 +27,6 @@
|
|||||||
<line x1="6" y1="6" x2="18" y2="18" />
|
<line x1="6" y1="6" x2="18" y2="18" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
v-if="isLorasMode"
|
|
||||||
type="button"
|
|
||||||
class="active-filters-toggle"
|
|
||||||
:class="{ 'is-active': activeFiltersEnabled }"
|
|
||||||
:title="activeFiltersToggleTitle"
|
|
||||||
@click="toggleActiveFiltersSearch"
|
|
||||||
>
|
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
||||||
<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -46,8 +34,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, onUnmounted, computed } from 'vue'
|
import { ref, onMounted, onUnmounted, computed } from 'vue'
|
||||||
import { useAutocomplete } from '@/composables/useAutocomplete'
|
import { useAutocomplete } from '@/composables/useAutocomplete'
|
||||||
// @ts-ignore - ComfyUI external module
|
|
||||||
import { LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID, SETTING_TOGGLED_EVENT_NAME, getLoraActiveFiltersAutocompletePreference, setLoraManagerSettingValue } from '../../../web/comfyui/settings.js'
|
|
||||||
|
|
||||||
// Access LiteGraph global for initial mode detection
|
// Access LiteGraph global for initial mode detection
|
||||||
declare const LiteGraph: { vueNodesMode?: boolean } | undefined
|
declare const LiteGraph: { vueNodesMode?: boolean } | undefined
|
||||||
@@ -87,10 +73,10 @@ const inputWrapperRef = ref<HTMLElement | null>(null)
|
|||||||
// Width of the textarea's own vertical scrollbar gutter. When the content
|
// Width of the textarea's own vertical scrollbar gutter. When the content
|
||||||
// overflows and a classic (non-overlay) scrollbar is shown, the scrollbar
|
// overflows and a classic (non-overlay) scrollbar is shown, the scrollbar
|
||||||
// occupies the textarea's rightmost pixels and the absolutely-positioned
|
// occupies the textarea's rightmost pixels and the absolutely-positioned
|
||||||
// corner buttons (clear x / active-filters filter) would overlap it. We
|
// corner clear (x) button would overlap it. We expose this width as a CSS
|
||||||
// expose this width as a CSS var so those buttons can shift left of the
|
// var so the button can shift left of the scrollbar; it is 0 when there is
|
||||||
// scrollbar; it is 0 when there is no scrollbar (content fits, or platform
|
// no scrollbar (content fits, or platform overlay scrollbars that float
|
||||||
// overlay scrollbars that float over the content).
|
// over the content).
|
||||||
const vScrollbarWidth = ref(0)
|
const vScrollbarWidth = ref(0)
|
||||||
let scrollbarResizeObserver: ResizeObserver | null = null
|
let scrollbarResizeObserver: ResizeObserver | null = null
|
||||||
|
|
||||||
@@ -125,48 +111,6 @@ const hasText = ref(false)
|
|||||||
// Show clear button when there is text
|
// Show clear button when there is text
|
||||||
const showClearButton = computed(() => hasText.value)
|
const showClearButton = computed(() => hasText.value)
|
||||||
|
|
||||||
// Active-filters search indicator (loras nodes only). Mirrors the
|
|
||||||
// loramanager.lora_active_filters_autocomplete setting so users can
|
|
||||||
// discover and toggle the /activefilters mode without opening the
|
|
||||||
// dropdown or the settings dialog.
|
|
||||||
const isLorasMode = (props.modelType ?? 'loras') === 'loras'
|
|
||||||
const activeFiltersEnabled = ref(false)
|
|
||||||
|
|
||||||
const refreshActiveFiltersState = () => {
|
|
||||||
if (isLorasMode) {
|
|
||||||
activeFiltersEnabled.value = getLoraActiveFiltersAutocompletePreference()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onSettingToggled = (event: Event) => {
|
|
||||||
const detail = (event as CustomEvent<{ settingId?: string; value?: unknown }>).detail
|
|
||||||
if (detail?.settingId === LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID) {
|
|
||||||
activeFiltersEnabled.value = detail.value === true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const activeFiltersToggleTitle = computed(() =>
|
|
||||||
activeFiltersEnabled.value
|
|
||||||
? 'Active Filters Search is ON: suggestions respect the LoRA Manager page filters. Click to disable, or type /noactivefilters.'
|
|
||||||
: 'Active Filters Search is OFF: suggestions search the full library. Click to enable, or type /activefilters.'
|
|
||||||
)
|
|
||||||
|
|
||||||
const toggleActiveFiltersSearch = async () => {
|
|
||||||
const newValue = !activeFiltersEnabled.value
|
|
||||||
try {
|
|
||||||
const success = await setLoraManagerSettingValue(
|
|
||||||
LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID,
|
|
||||||
newValue
|
|
||||||
)
|
|
||||||
if (!success) {
|
|
||||||
throw new Error('settings API unavailable')
|
|
||||||
}
|
|
||||||
activeFiltersEnabled.value = newValue
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[Lora Manager] Failed to toggle active filters search:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize autocomplete with direct ref access
|
// Initialize autocomplete with direct ref access
|
||||||
useAutocomplete(
|
useAutocomplete(
|
||||||
textareaRef,
|
textareaRef,
|
||||||
@@ -355,11 +299,6 @@ onMounted(() => {
|
|||||||
// Setup widget.onSetValue callback
|
// Setup widget.onSetValue callback
|
||||||
setupWidgetOnSetValue()
|
setupWidgetOnSetValue()
|
||||||
|
|
||||||
// Active-filters indicator: read initial state and stay in sync with
|
|
||||||
// slash-command / context-menu toggles dispatched via settings.js
|
|
||||||
refreshActiveFiltersState()
|
|
||||||
window.addEventListener(SETTING_TOGGLED_EVENT_NAME, onSettingToggled)
|
|
||||||
|
|
||||||
// Keep the corner buttons clear of the textarea's vertical scrollbar.
|
// Keep the corner buttons clear of the textarea's vertical scrollbar.
|
||||||
updateVScrollbarWidth()
|
updateVScrollbarWidth()
|
||||||
observeScrollbarWidth()
|
observeScrollbarWidth()
|
||||||
@@ -391,7 +330,6 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
// Remove event listener
|
// Remove event listener
|
||||||
document.removeEventListener('lora-manager:vue-mode-change', onModeChange)
|
document.removeEventListener('lora-manager:vue-mode-change', onModeChange)
|
||||||
window.removeEventListener(SETTING_TOGGLED_EVENT_NAME, onSettingToggled)
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -484,58 +422,6 @@ onUnmounted(() => {
|
|||||||
height: 12px;
|
height: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Active-filters search indicator (loras nodes only) */
|
|
||||||
.active-filters-toggle {
|
|
||||||
position: absolute;
|
|
||||||
top: 3px;
|
|
||||||
right: calc(3px + var(--lm-vscrollbar-width, 0px));
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
padding: 2px;
|
|
||||||
margin: 0;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: rgba(128, 128, 128, 0.25);
|
|
||||||
color: rgba(255, 255, 255, 0.5);
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
opacity: 0.7;
|
|
||||||
transition: opacity 0.2s ease, background-color 0.2s ease, color 0.2s ease;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active-filters-toggle:hover {
|
|
||||||
opacity: 1;
|
|
||||||
background: rgba(128, 128, 128, 0.45);
|
|
||||||
color: rgba(255, 255, 255, 0.85);
|
|
||||||
}
|
|
||||||
|
|
||||||
.active-filters-toggle.is-active {
|
|
||||||
background: rgba(59, 130, 246, 0.35);
|
|
||||||
color: #7db8ff;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active-filters-toggle svg {
|
|
||||||
width: 11px;
|
|
||||||
height: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Vue DOM mode adjustments for the indicator */
|
|
||||||
.text-input.vue-dom-mode ~ .active-filters-toggle {
|
|
||||||
top: 8px;
|
|
||||||
right: calc(8px + var(--lm-vscrollbar-width, 0px));
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-input.vue-dom-mode ~ .active-filters-toggle svg {
|
|
||||||
width: 13px;
|
|
||||||
height: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Vue DOM mode adjustments for clear button */
|
/* Vue DOM mode adjustments for clear button */
|
||||||
.text-input.vue-dom-mode ~ .clear-button {
|
.text-input.vue-dom-mode ~ .clear-button {
|
||||||
right: calc(8px + var(--lm-vscrollbar-width, 0px));
|
right: calc(8px + var(--lm-vscrollbar-width, 0px));
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import { nextTick } from 'vue'
|
import { nextTick } from 'vue'
|
||||||
import { shallowMount } from '@vue/test-utils'
|
import { shallowMount } from '@vue/test-utils'
|
||||||
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
|
import { describe, expect, it, vi, afterEach } from 'vitest'
|
||||||
import AutocompleteTextWidget from '@/components/AutocompleteTextWidget.vue'
|
import AutocompleteTextWidget from '@/components/AutocompleteTextWidget.vue'
|
||||||
|
|
||||||
function createMockWidget() {
|
function createMockWidget() {
|
||||||
@@ -135,121 +135,15 @@ describe('AutocompleteTextWidget clear button', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for the active-filters search indicator (loras mode only).
|
|
||||||
*
|
|
||||||
* The small filter chip in the textarea corner mirrors the
|
|
||||||
* loramanager.lora_active_filters_autocomplete setting: it reflects the
|
|
||||||
* current state, can toggle it, and stays in sync with slash-command /
|
|
||||||
* context-menu toggles via the lora-manager:setting-toggled window event.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const settingsMocks = vi.hoisted(() => ({
|
|
||||||
getPreference: vi.fn(),
|
|
||||||
setValue: vi.fn(),
|
|
||||||
}))
|
|
||||||
|
|
||||||
vi.mock('../../../web/comfyui/settings.js', () => ({
|
|
||||||
LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID:
|
|
||||||
'loramanager.lora_active_filters_autocomplete',
|
|
||||||
SETTING_TOGGLED_EVENT_NAME: 'lora-manager:setting-toggled',
|
|
||||||
getLoraActiveFiltersAutocompletePreference: settingsMocks.getPreference,
|
|
||||||
setLoraManagerSettingValue: settingsMocks.setValue,
|
|
||||||
}))
|
|
||||||
|
|
||||||
const getActiveFiltersPreferenceMock = settingsMocks.getPreference
|
|
||||||
const setSettingValueMock = settingsMocks.setValue
|
|
||||||
|
|
||||||
function mountLorasWidget() {
|
|
||||||
const widget = createMockWidget()
|
|
||||||
const node = { id: 1 }
|
|
||||||
const wrapper = shallowMount(AutocompleteTextWidget, {
|
|
||||||
props: { widget, node, modelType: 'loras' },
|
|
||||||
attachTo: document.body,
|
|
||||||
})
|
|
||||||
return { wrapper, widget }
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('AutocompleteTextWidget active-filters indicator', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
getActiveFiltersPreferenceMock.mockReset()
|
|
||||||
getActiveFiltersPreferenceMock.mockReturnValue(false)
|
|
||||||
setSettingValueMock.mockReset()
|
|
||||||
setSettingValueMock.mockResolvedValue(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('renders only in loras mode', () => {
|
|
||||||
const loras = mountLorasWidget()
|
|
||||||
expect(loras.wrapper.find('.active-filters-toggle').exists()).toBe(true)
|
|
||||||
|
|
||||||
const widget = createMockWidget()
|
|
||||||
const prompt = shallowMount(AutocompleteTextWidget, {
|
|
||||||
props: { widget, node: { id: 2 }, modelType: 'prompt' },
|
|
||||||
attachTo: document.body,
|
|
||||||
})
|
|
||||||
expect(prompt.find('.active-filters-toggle').exists()).toBe(false)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('reflects the current setting state', async () => {
|
|
||||||
const { wrapper } = mountLorasWidget()
|
|
||||||
await nextTick()
|
|
||||||
expect(wrapper.find('.active-filters-toggle').classes()).not.toContain('is-active')
|
|
||||||
|
|
||||||
getActiveFiltersPreferenceMock.mockReturnValue(true)
|
|
||||||
const wrapper2 = mountLorasWidget().wrapper
|
|
||||||
await nextTick()
|
|
||||||
expect(wrapper2.find('.active-filters-toggle').classes()).toContain('is-active')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('toggles the setting when clicked', async () => {
|
|
||||||
const { wrapper } = mountLorasWidget()
|
|
||||||
await nextTick()
|
|
||||||
|
|
||||||
await wrapper.find('.active-filters-toggle').trigger('click')
|
|
||||||
expect(setSettingValueMock).toHaveBeenCalledWith(
|
|
||||||
'loramanager.lora_active_filters_autocomplete',
|
|
||||||
true
|
|
||||||
)
|
|
||||||
await nextTick()
|
|
||||||
expect(wrapper.find('.active-filters-toggle').classes()).toContain('is-active')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('stays in sync with setting-toggled window events', async () => {
|
|
||||||
const { wrapper } = mountLorasWidget()
|
|
||||||
await nextTick()
|
|
||||||
expect(wrapper.find('.active-filters-toggle').classes()).not.toContain('is-active')
|
|
||||||
|
|
||||||
window.dispatchEvent(
|
|
||||||
new CustomEvent('lora-manager:setting-toggled', {
|
|
||||||
detail: {
|
|
||||||
settingId: 'loramanager.lora_active_filters_autocomplete',
|
|
||||||
value: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
)
|
|
||||||
await nextTick()
|
|
||||||
expect(wrapper.find('.active-filters-toggle').classes()).toContain('is-active')
|
|
||||||
|
|
||||||
window.dispatchEvent(
|
|
||||||
new CustomEvent('lora-manager:setting-toggled', {
|
|
||||||
detail: { settingId: 'loramanager.some_other_setting', value: true },
|
|
||||||
})
|
|
||||||
)
|
|
||||||
await nextTick()
|
|
||||||
// Unrelated settings must not flip the indicator
|
|
||||||
expect(wrapper.find('.active-filters-toggle').classes()).toContain('is-active')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for the vertical-scrollbar inset.
|
* Tests for the vertical-scrollbar inset.
|
||||||
*
|
*
|
||||||
* When the textarea content overflows and a classic (non-overlay) scrollbar
|
* When the textarea content overflows and a classic (non-overlay) scrollbar
|
||||||
* is shown, the absolutely-positioned corner buttons (clear x, active-filters
|
* is shown, the absolutely-positioned corner clear (x) button would sit on
|
||||||
* filter chip) would sit on top of the scrollbar. The component measures the
|
* top of the scrollbar. The component measures the scrollbar gutter and
|
||||||
* scrollbar gutter and exposes it as the --lm-vscrollbar-width CSS var on
|
* exposes it as the --lm-vscrollbar-width CSS var on .input-wrapper so the
|
||||||
* .input-wrapper so the buttons shift left of the scrollbar. jsdom does no
|
* button shifts left of the scrollbar. jsdom does no layout, so overflow is
|
||||||
* layout, so overflow is simulated by overriding the scroll/dimension props.
|
* simulated by overriding the scroll/dimension props.
|
||||||
*/
|
*/
|
||||||
describe('AutocompleteTextWidget vertical scrollbar inset', () => {
|
describe('AutocompleteTextWidget vertical scrollbar inset', () => {
|
||||||
function overrideTextareaMetrics(
|
function overrideTextareaMetrics(
|
||||||
@@ -322,4 +216,5 @@ describe('AutocompleteTextWidget vertical scrollbar inset', () => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
expect(wrapperEl.style.getPropertyValue('--lm-vscrollbar-width')).toBe('0px')
|
expect(wrapperEl.style.getPropertyValue('--lm-vscrollbar-width')).toBe('0px')
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -175,42 +175,23 @@ const getPromptTagAutocompletePreference = (() => {
|
|||||||
/**
|
/**
|
||||||
* Persist a LoRA Manager setting through ComfyUI's setting API.
|
* Persist a LoRA Manager setting through ComfyUI's setting API.
|
||||||
* Returns true when the setting was written successfully.
|
* Returns true when the setting was written successfully.
|
||||||
*
|
|
||||||
* Every successful write broadcasts a "lora-manager:setting-toggled" window
|
|
||||||
* event (see SETTING_TOGGLED_EVENT_NAME) so widgets mirroring the setting
|
|
||||||
* (e.g. the active-filters indicator in the autocomplete text widget) stay in
|
|
||||||
* sync with slash-command / context-menu toggles.
|
|
||||||
*/
|
*/
|
||||||
const SETTING_TOGGLED_EVENT_NAME = "lora-manager:setting-toggled";
|
|
||||||
|
|
||||||
const setLoraManagerSettingValue = async (settingId, value) => {
|
const setLoraManagerSettingValue = async (settingId, value) => {
|
||||||
const settingManager = app?.extensionManager?.setting;
|
const settingManager = app?.extensionManager?.setting;
|
||||||
if (settingManager && typeof settingManager.set === "function") {
|
if (settingManager && typeof settingManager.set === "function") {
|
||||||
await settingManager.set(settingId, value);
|
await settingManager.set(settingId, value);
|
||||||
_notifySettingToggled(settingId, value);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const setting = app?.ui?.settings?.settingsById?.[settingId];
|
const setting = app?.ui?.settings?.settingsById?.[settingId];
|
||||||
if (setting) {
|
if (setting) {
|
||||||
app.ui.settings.setSettingValue(settingId, value);
|
app.ui.settings.setSettingValue(settingId, value);
|
||||||
_notifySettingToggled(settingId, value);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const _notifySettingToggled = (settingId, value) => {
|
|
||||||
try {
|
|
||||||
window.dispatchEvent(new CustomEvent(SETTING_TOGGLED_EVENT_NAME, {
|
|
||||||
detail: { settingId, value },
|
|
||||||
}));
|
|
||||||
} catch (error) {
|
|
||||||
// Best-effort notification; ignore non-browser environments
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getAutocompleteAppendCommaPreference = (() => {
|
const getAutocompleteAppendCommaPreference = (() => {
|
||||||
let settingsUnavailableLogged = false;
|
let settingsUnavailableLogged = false;
|
||||||
|
|
||||||
@@ -617,7 +598,6 @@ app.registerExtension({
|
|||||||
export {
|
export {
|
||||||
PROMPT_TAG_AUTOCOMPLETE_SETTING_ID,
|
PROMPT_TAG_AUTOCOMPLETE_SETTING_ID,
|
||||||
LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID,
|
LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID,
|
||||||
SETTING_TOGGLED_EVENT_NAME,
|
|
||||||
getWheelSensitivity,
|
getWheelSensitivity,
|
||||||
getAutoPathCorrectionPreference,
|
getAutoPathCorrectionPreference,
|
||||||
getAutocompleteAppendCommaPreference,
|
getAutocompleteAppendCommaPreference,
|
||||||
|
|||||||
Reference in New Issue
Block a user