mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-22 05:32:12 -03:00
Add a new "Check Model Updates" option to the global context menu that allows users to manually check for model updates. This includes: - Adding refreshUpdates endpoint to API configuration - Implementing checkModelUpdates method with proper loading states - Adding internationalization support for update messages - Handling success/error states with appropriate user feedback - Automatically reloading models after update check completes The feature provides users with manual control over update checks and improves visibility into model update availability.
184 lines
6.5 KiB
JavaScript
184 lines
6.5 KiB
JavaScript
import { BaseContextMenu } from './BaseContextMenu.js';
|
|
import { showToast } from '../../utils/uiHelpers.js';
|
|
import { state } from '../../state/index.js';
|
|
import { translate } from '../../utils/i18nHelpers.js';
|
|
import { getCompleteApiConfig, getCurrentModelType } from '../../api/apiConfig.js';
|
|
import { resetAndReload } from '../../api/modelApiFactory.js';
|
|
|
|
export class GlobalContextMenu extends BaseContextMenu {
|
|
constructor() {
|
|
super('globalContextMenu');
|
|
this._cleanupInProgress = false;
|
|
this._updateCheckInProgress = false;
|
|
}
|
|
|
|
showMenu(x, y, origin = null) {
|
|
const contextOrigin = origin || { type: 'global' };
|
|
super.showMenu(x, y, contextOrigin);
|
|
}
|
|
|
|
handleMenuAction(action, menuItem) {
|
|
switch (action) {
|
|
case 'cleanup-example-images-folders':
|
|
this.cleanupExampleImagesFolders(menuItem).catch((error) => {
|
|
console.error('Failed to trigger example images cleanup:', error);
|
|
});
|
|
break;
|
|
case 'download-example-images':
|
|
this.downloadExampleImages(menuItem).catch((error) => {
|
|
console.error('Failed to trigger example images download:', error);
|
|
});
|
|
break;
|
|
case 'check-model-updates':
|
|
this.checkModelUpdates(menuItem).catch((error) => {
|
|
console.error('Failed to check model updates:', error);
|
|
});
|
|
break;
|
|
default:
|
|
console.warn(`Unhandled global context menu action: ${action}`);
|
|
break;
|
|
}
|
|
}
|
|
|
|
async downloadExampleImages(menuItem) {
|
|
const exampleImagesManager = window.exampleImagesManager;
|
|
|
|
if (!exampleImagesManager) {
|
|
showToast('globalContextMenu.downloadExampleImages.unavailable', {}, 'error');
|
|
return;
|
|
}
|
|
|
|
const downloadPath = state?.global?.settings?.example_images_path;
|
|
if (!downloadPath) {
|
|
showToast('globalContextMenu.downloadExampleImages.missingPath', {}, 'warning');
|
|
return;
|
|
}
|
|
|
|
menuItem?.classList.add('disabled');
|
|
|
|
try {
|
|
await exampleImagesManager.handleDownloadButton();
|
|
} finally {
|
|
menuItem?.classList.remove('disabled');
|
|
}
|
|
}
|
|
|
|
async cleanupExampleImagesFolders(menuItem) {
|
|
if (this._cleanupInProgress) {
|
|
return;
|
|
}
|
|
|
|
this._cleanupInProgress = true;
|
|
menuItem?.classList.add('disabled');
|
|
|
|
try {
|
|
const response = await fetch('/api/lm/cleanup-example-image-folders', {
|
|
method: 'POST',
|
|
});
|
|
|
|
let payload;
|
|
try {
|
|
payload = await response.json();
|
|
} catch (parseError) {
|
|
payload = { error: 'Unexpected response format.' };
|
|
}
|
|
|
|
if (response.ok && (payload.success || payload.partial_success)) {
|
|
const movedTotal = payload.moved_total || 0;
|
|
|
|
if (movedTotal > 0) {
|
|
showToast('globalContextMenu.cleanupExampleImages.success', { count: movedTotal }, 'success');
|
|
} else {
|
|
showToast('globalContextMenu.cleanupExampleImages.none', {}, 'info');
|
|
}
|
|
|
|
if (payload.partial_success) {
|
|
showToast(
|
|
'globalContextMenu.cleanupExampleImages.partial',
|
|
{ failures: payload.move_failures ?? 0 },
|
|
'warning',
|
|
);
|
|
}
|
|
} else {
|
|
const message = payload?.error || 'Unknown error';
|
|
showToast('globalContextMenu.cleanupExampleImages.error', { message }, 'error');
|
|
}
|
|
} catch (error) {
|
|
showToast('globalContextMenu.cleanupExampleImages.error', { message: error.message || 'Unknown error' }, 'error');
|
|
} finally {
|
|
this._cleanupInProgress = false;
|
|
menuItem?.classList.remove('disabled');
|
|
}
|
|
}
|
|
|
|
async checkModelUpdates(menuItem) {
|
|
if (this._updateCheckInProgress) {
|
|
return;
|
|
}
|
|
|
|
const modelType = getCurrentModelType();
|
|
const apiConfig = getCompleteApiConfig(modelType);
|
|
|
|
if (!apiConfig?.endpoints?.refreshUpdates) {
|
|
console.warn('Refresh updates endpoint not configured for model type:', modelType);
|
|
return;
|
|
}
|
|
|
|
this._updateCheckInProgress = true;
|
|
menuItem?.classList.add('disabled');
|
|
|
|
const displayName = apiConfig.config?.displayName ?? 'Model';
|
|
const loadingMessage = translate(
|
|
'globalContextMenu.checkModelUpdates.loading',
|
|
{ type: displayName },
|
|
`Checking for ${displayName} updates...`
|
|
);
|
|
|
|
state.loadingManager?.showSimpleLoading?.(loadingMessage);
|
|
|
|
try {
|
|
const response = await fetch(apiConfig.endpoints.refreshUpdates, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ force: false })
|
|
});
|
|
|
|
let payload = {};
|
|
try {
|
|
payload = await response.json();
|
|
} catch {
|
|
payload = {};
|
|
}
|
|
|
|
if (!response.ok || payload.success !== true) {
|
|
const errorMessage = payload?.error || response.statusText || 'Unknown error';
|
|
throw new Error(errorMessage);
|
|
}
|
|
|
|
const records = Array.isArray(payload.records) ? payload.records : [];
|
|
|
|
if (records.length > 0) {
|
|
showToast('globalContextMenu.checkModelUpdates.success', { count: records.length, type: displayName }, 'success');
|
|
} else {
|
|
showToast('globalContextMenu.checkModelUpdates.none', { type: displayName }, 'info');
|
|
}
|
|
|
|
await resetAndReload(false);
|
|
} catch (error) {
|
|
console.error('Error checking model updates:', error);
|
|
showToast(
|
|
'globalContextMenu.checkModelUpdates.error',
|
|
{ message: error?.message ?? 'Unknown error', type: displayName },
|
|
'error'
|
|
);
|
|
} finally {
|
|
state.loadingManager?.hide?.();
|
|
if (typeof state.loadingManager?.restoreProgressBar === 'function') {
|
|
state.loadingManager.restoreProgressBar();
|
|
}
|
|
menuItem?.classList.remove('disabled');
|
|
this._updateCheckInProgress = false;
|
|
}
|
|
}
|
|
}
|