diff --git a/web/linker.js b/web/linker.js index f1228d4..cf68098 100644 --- a/web/linker.js +++ b/web/linker.js @@ -262,6 +262,56 @@ class LinkerManagerDialog extends ComfyDialog { return html; } + formatSearchResultMeta(result = {}, options = {}) { + const filename = options.filename || result.filename || ''; + const secondaryText = options.secondaryText || ''; + const confidenceValue = result.confidence; + const confidenceDisplay = typeof confidenceValue === 'number' + ? `${Math.round(confidenceValue)}% match` + : ''; + const sizeDisplay = result.size + ? (typeof result.size === 'number' ? this.formatBytes(result.size) : result.size) + : ''; + + let html = `
`; + if (filename) { + html += `${filename}`; + } + if (confidenceDisplay) { + html += ` ${confidenceDisplay}`; + } + if (sizeDisplay) { + html += ` [${sizeDisplay}]`; + } + if (secondaryText) { + html += ` ${secondaryText}`; + } + html += `
`; + return html; + } + + renderOnlineSearchResultCard({ + statusClass, + title, + result, + filename, + secondaryText = '', + actionHtml = '', + topLineHtml = '' + }) { + let html = `
`; + html += `${title}`; + if (topLineHtml) { + html += topLineHtml; + } + html += this.formatSearchResultMeta(result, { filename, secondaryText }); + if (actionHtml) { + html += `
${actionHtml}
`; + } + html += `
`; + return html; + } + buildContextMenuModelData(model = {}, fallbackName = '') { const resolvedPath = model.path || model.resolved_path || ''; const filename = model.filename || fallbackName || resolvedPath.split(/[\/\\]/).pop() || ''; @@ -6011,53 +6061,45 @@ class LinkerManagerDialog extends ComfyDialog { // Popular models result (highest priority) if (popular) { - html += `
`; - html += `Found in Popular Models`; - html += `
`; - html += ``; - html += `
`; + const popularFilename = popular.filename || missing.original_path?.split('/').pop()?.split('\\').pop() || ''; + const actionHtml = ``; + html += this.renderOnlineSearchResultCard({ + statusClass: 'ml-status-success', + title: 'Found in Popular Models', + result: popular, + filename: popularFilename, + secondaryText: popular.name || '', + actionHtml + }); } // Model list result (ComfyUI Manager database with fuzzy matching) if (modelListResult && modelListResult.url) { - const confidence = modelListResult.confidence ? ` (${modelListResult.confidence}%)` : ''; const matchType = modelListResult.match_type === 'exact' ? 'Exact match' : 'Similar model'; const statusClass = modelListResult.match_type === 'exact' ? 'ml-status-success' : 'ml-status-info'; - - html += `
`; - html += `${matchType} in Model Database${confidence}`; - html += `
`; - html += `${modelListResult.filename}`; - if (modelListResult.name) { - html += ` ${modelListResult.name}`; - } - if (modelListResult.size) { - html += ` [${modelListResult.size}]`; - } - html += `
`; - html += `
`; - html += ``; - html += `
`; + const actionHtml = ``; + html += this.renderOnlineSearchResultCard({ + statusClass, + title: `${matchType} in Model Database`, + result: modelListResult, + filename: modelListResult.filename, + secondaryText: modelListResult.name || '', + actionHtml + }); } // HuggingFace result if (hfResult && hfResult.url) { const hfRepo = hfResult.repo_id || hfResult.repo || ''; - html += `
`; - html += `Found on HuggingFace`; - html += `
`; - html += `${hfResult.filename} `; - html += `${hfRepo}`; - html += `
`; - html += `
`; - html += ``; - html += `
`; + const actionHtml = ``; + html += this.renderOnlineSearchResultCard({ + statusClass: 'ml-status-info', + title: 'Found on HuggingFace', + result: hfResult, + filename: hfResult.filename, + secondaryText: hfRepo, + actionHtml + }); } // CivitAI result @@ -6067,36 +6109,17 @@ class LinkerManagerDialog extends ComfyDialog { const downloadFilename = missing.civitai_info?.expected_filename || civitaiResult.filename || civitaiResult.name; // Build display name with version if available const modelName = missing.civitai_info?.version_name ? `${missing.civitai_info.model_name} v${missing.civitai_info.version_name}` : (civitaiResult.name || 'Model'); - const confidenceDisplay = typeof civitaiResult.confidence === 'number' - ? `${Math.round(civitaiResult.confidence)}% match` - : ''; - const sizeDisplay = civitaiResult.size - ? (typeof civitaiResult.size === 'number' - ? this.formatBytes(civitaiResult.size) - : civitaiResult.size) - : ''; - html += `
`; - html += `Found on CivitAI`; - html += `
`; - // Model name as clickable button/link - html += ` `; - html += `${civitaiResult.type || ''}`; - html += `
`; - html += `
`; - html += `${downloadFilename}`; - if (confidenceDisplay) { - html += ` ${confidenceDisplay}`; - } - if (sizeDisplay) { - html += ` [${sizeDisplay}]`; - } - html += `
`; - html += `
`; - // Download button - use expected_filename from URN resolution - html += ``; - html += `
`; + const topLineHtml = `
${civitaiResult.type || ''}
`; + const actionHtml = ``; + html += this.renderOnlineSearchResultCard({ + statusClass: 'ml-status-warning', + title: 'Found on CivitAI', + result: civitaiResult, + filename: downloadFilename, + secondaryText: '', + topLineHtml, + actionHtml + }); } html += '';