mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-21 03:01:27 -03:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ed7cf418b4 |
@@ -286,4 +286,93 @@ const autoComplete = new AutoComplete(input, 'loras', { showPreview: false, minC
|
||||
window.removeEventListener('lora-manager:setting-toggled', listener);
|
||||
}
|
||||
});
|
||||
|
||||
it('removes a stale first-run hint when the toggle is switched on while the dropdown stays open', async () => {
|
||||
localStorage.removeItem('lm:activefilters-tip-dismissed');
|
||||
let enabled = false;
|
||||
settingGetMock.mockImplementation((key) => {
|
||||
if (key === 'loramanager.lora_active_filters_autocomplete') return enabled;
|
||||
if (key === 'loramanager.autocomplete_append_comma') return false;
|
||||
if (key === 'loramanager.autocomplete_auto_format') return false;
|
||||
if (key === 'loramanager.autocomplete_accept_key') return 'both';
|
||||
return undefined;
|
||||
});
|
||||
|
||||
fetchApiMock.mockResolvedValue({
|
||||
json: () => Promise.resolve({ success: true, relative_paths: ['models/example.safetensors'] }),
|
||||
});
|
||||
|
||||
const input = document.createElement('textarea');
|
||||
input.value = 'example';
|
||||
input.selectionStart = 7;
|
||||
document.body.append(input);
|
||||
caretHelperInstance.getBeforeCursor.mockReturnValue('example');
|
||||
|
||||
const { AutoComplete } = await import(AUTOCOMPLETE_MODULE);
|
||||
const autoComplete = new AutoComplete(input, 'loras', {
|
||||
debounceDelay: 0,
|
||||
showPreview: false,
|
||||
minChars: 1,
|
||||
});
|
||||
|
||||
const triggerShow = async () => {
|
||||
input.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
await vi.runOnlyPendingTimersAsync();
|
||||
await vi.runOnlyPendingTimersAsync();
|
||||
await Promise.resolve();
|
||||
return autoComplete.dropdown.querySelector('.lm-autocomplete-first-run-hint');
|
||||
};
|
||||
|
||||
// OFF → the enable hint is shown in the suggestions dropdown.
|
||||
expect(await triggerShow()).not.toBeNull();
|
||||
|
||||
// The node's filter chip toggles the setting ON while the dropdown is
|
||||
// still open (ComfyUI can keep focus in the textarea, so no blur/hide
|
||||
// fires). settings.js broadcasts the setting-toggled event.
|
||||
enabled = true;
|
||||
window.dispatchEvent(new CustomEvent('lora-manager:setting-toggled', {
|
||||
detail: { settingId: 'loramanager.lora_active_filters_autocomplete', value: true },
|
||||
}));
|
||||
|
||||
// The stale OFF hint must be gone even though the dropdown never closed.
|
||||
expect(autoComplete.dropdown.querySelector('.lm-autocomplete-first-run-hint')).toBeNull();
|
||||
|
||||
// Further typing while ON must not resurrect the enable hint.
|
||||
expect(await triggerShow()).toBeNull();
|
||||
});
|
||||
|
||||
it('updates the command-list footer when the toggle changes while the command list is open', async () => {
|
||||
let enabled = false;
|
||||
settingGetMock.mockImplementation((key) => {
|
||||
if (key === 'loramanager.lora_active_filters_autocomplete') return enabled;
|
||||
return undefined;
|
||||
});
|
||||
|
||||
const input = document.createElement('textarea');
|
||||
input.value = '/';
|
||||
input.selectionStart = 1;
|
||||
document.body.append(input);
|
||||
caretHelperInstance.getBeforeCursor.mockReturnValue('/');
|
||||
|
||||
const { AutoComplete } = await import(AUTOCOMPLETE_MODULE);
|
||||
const autoComplete = new AutoComplete(input, 'loras', { showPreview: false, minChars: 1 });
|
||||
input.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
await vi.runOnlyPendingTimersAsync();
|
||||
await Promise.resolve();
|
||||
|
||||
const footer = () => autoComplete.dropdown.querySelector('.lm-autocomplete-command-footer');
|
||||
expect(footer()).not.toBeNull();
|
||||
expect(footer().textContent).toContain('Active Filters Search: OFF');
|
||||
expect(footer().textContent).toContain('/activefilters to enable');
|
||||
|
||||
enabled = true;
|
||||
window.dispatchEvent(new CustomEvent('lora-manager:setting-toggled', {
|
||||
detail: { settingId: 'loramanager.lora_active_filters_autocomplete', value: true },
|
||||
}));
|
||||
|
||||
expect(footer()).not.toBeNull();
|
||||
expect(footer().textContent).toContain('Active Filters Search: ON');
|
||||
expect(footer().textContent).toContain('/noactivefilters to disable');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -14,9 +14,11 @@ import {
|
||||
getAutocompleteAppendCommaPreference,
|
||||
getAutocompleteAutoFormatPreference,
|
||||
getAutocompleteAcceptKeyPreference,
|
||||
LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID,
|
||||
getLoraActiveFiltersAutocompletePreference,
|
||||
getPromptTagAutocompletePreference,
|
||||
getTagSpaceReplacementPreference,
|
||||
SETTING_TOGGLED_EVENT_NAME,
|
||||
setLoraManagerSettingValue,
|
||||
} from "./settings.js";
|
||||
import { showToast } from "./utils.js";
|
||||
@@ -607,6 +609,7 @@ class AutoComplete {
|
||||
this.onBlur = null;
|
||||
this.onDocumentClick = null;
|
||||
this.onScroll = null;
|
||||
this.onSettingToggled = null;
|
||||
|
||||
this.init();
|
||||
}
|
||||
@@ -774,6 +777,22 @@ class AutoComplete {
|
||||
};
|
||||
document.addEventListener('click', this.onDocumentClick);
|
||||
|
||||
// React to setting changes that happen underneath an open dropdown
|
||||
// (e.g. toggling the active-filters search from the node's filter
|
||||
// chip can keep the dropdown open in ComfyUI). Refresh the state
|
||||
// hints so they never show a message for the previous state.
|
||||
if (this.onSettingToggled) {
|
||||
window.removeEventListener(SETTING_TOGGLED_EVENT_NAME, this.onSettingToggled);
|
||||
}
|
||||
this.onSettingToggled = (e) => {
|
||||
const detail = e && e.detail;
|
||||
if (!detail || detail.settingId !== LORA_ACTIVE_FILTERS_AUTOCOMPLETE_SETTING_ID) {
|
||||
return;
|
||||
}
|
||||
this._refreshStateHints();
|
||||
};
|
||||
window.addEventListener(SETTING_TOGGLED_EVENT_NAME, this.onSettingToggled);
|
||||
|
||||
// Mark this element as having autocomplete events bound
|
||||
this.inputElement._autocompleteEventsBound = true;
|
||||
|
||||
@@ -1811,15 +1830,37 @@ class AutoComplete {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh state-dependent dropdown decorations (first-run Tip and the
|
||||
* slash-command-list footer) from the live setting. Called when the
|
||||
* active-filters toggle changes underneath an open dropdown, so the
|
||||
* dropdown never keeps showing a message for the previous state.
|
||||
*/
|
||||
_refreshStateHints() {
|
||||
if (!this.isVisible || this.modelType !== 'loras') {
|
||||
return;
|
||||
}
|
||||
if (this.showingCommands) {
|
||||
// Command list: footer text carries the ON/OFF state.
|
||||
this._renderCommandListFooter();
|
||||
} else {
|
||||
// Plain suggestions: the first-run Tip advertises /activefilters
|
||||
// only while the feature is disabled.
|
||||
this._maybeShowFirstRunHint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a one-time, dismissible hint inside the dropdown surfacing the
|
||||
* toggle commands: prompt nodes advertise /noautocomplete, loras nodes
|
||||
* advertise /activefilters. Dismissal is persisted in localStorage.
|
||||
*/
|
||||
_maybeShowFirstRunHint() {
|
||||
if (this.firstRunHint) {
|
||||
return;
|
||||
}
|
||||
// Dropdown decorations can outlive a state change (the dropdown may
|
||||
// stay open when the setting is toggled from the node, e.g. clicking
|
||||
// the active-filters filter chip). Always recompute from the live
|
||||
// state so a stale Tip is never kept for the previous state.
|
||||
this._removeFirstRunHint();
|
||||
|
||||
let hintText = null;
|
||||
let storageKey = null;
|
||||
@@ -3178,6 +3219,11 @@ class AutoComplete {
|
||||
this.onDocumentClick = null;
|
||||
}
|
||||
|
||||
if (this.onSettingToggled) {
|
||||
window.removeEventListener(SETTING_TOGGLED_EVENT_NAME, this.onSettingToggled);
|
||||
this.onSettingToggled = null;
|
||||
}
|
||||
|
||||
if (this.onScroll && this.scrollContainer) {
|
||||
this.scrollContainer.removeEventListener('scroll', this.onScroll);
|
||||
this.onScroll = null;
|
||||
|
||||
Reference in New Issue
Block a user