(filter = '')
| 731 | const list = dropdown.querySelector('#model-list-container'); |
| 732 | |
| 733 | const renderModels = (filter = '') => { |
| 734 | list.innerHTML = ''; |
| 735 | |
| 736 | if (useLocalModel) { |
| 737 | // ── Local model list (Wan2GP image-capable models only) ─── |
| 738 | const filtered = LOCAL_IMAGE_MODELS.filter(m => |
| 739 | m.name.toLowerCase().includes(filter.toLowerCase()) || |
| 740 | m.id.toLowerCase().includes(filter.toLowerCase()) |
| 741 | ); |
| 742 | if (filtered.length === 0) { |
| 743 | list.innerHTML = `<div class="text-xs text-muted text-center py-4">${t('common.noResults')}</div>`; |
| 744 | return; |
| 745 | } |
| 746 | filtered.forEach(m => { |
| 747 | const item = document.createElement('div'); |
| 748 | item.className = `flex items-center justify-between p-3.5 hover:bg-white/5 rounded-2xl cursor-pointer transition-all border border-transparent hover:border-white/5 ${selectedLocalModel === m.id ? 'bg-white/5 border-white/5' : ''}`; |
| 749 | item.innerHTML = ` |
| 750 | <div class="flex items-center gap-3.5"> |
| 751 | <div class="w-10 h-10 ${m.featured ? 'bg-primary/10 text-primary' : 'bg-green-500/10 text-green-400'} border border-white/5 rounded-xl flex items-center justify-center font-black text-sm shadow-inner uppercase">${m.featured ? '⚡' : m.name.charAt(0)}</div> |
| 752 | <div class="flex flex-col gap-0.5"> |
| 753 | <div class="flex items-center gap-1.5"> |
| 754 | <span class="text-xs font-bold text-white tracking-tight">${m.name}</span> |
| 755 | ${m.featured ? '<span class="text-[9px] font-black px-1 py-0.5 rounded bg-primary/20 text-primary">FEATURED</span>' : ''} |
| 756 | </div> |
| 757 | <span class="text-[10px] text-muted">${m.type.toUpperCase()} · ${m.family}</span> |
| 758 | </div> |
| 759 | </div> |
| 760 | ${selectedLocalModel === m.id ? '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#22d3ee" stroke-width="4"><polyline points="20 6 9 17 4 12"/></svg>' : ''} |
| 761 | `; |
| 762 | item.onclick = (e) => { |
| 763 | e.stopPropagation(); |
| 764 | selectedLocalModel = m.id; |
| 765 | document.getElementById('model-btn-label').textContent = m.name; |
| 766 | selectedAr = m.aspectRatios[0]; |
| 767 | document.getElementById('ar-btn-label').textContent = selectedAr; |
| 768 | qualityBtn.style.display = 'none'; |
| 769 | closeDropdown(); |
| 770 | }; |
| 771 | list.appendChild(item); |
| 772 | }); |
| 773 | return; |
| 774 | } |
| 775 | |
| 776 | // ── Remote (API) model list ─────────────────────────────────── |
| 777 | const filtered = getCurrentModels().filter(m => m.name.toLowerCase().includes(filter.toLowerCase()) || m.id.toLowerCase().includes(filter.toLowerCase())); |
| 778 | |
| 779 | filtered.forEach(m => { |
| 780 | const item = document.createElement('div'); |
| 781 | item.className = `flex items-center justify-between p-3.5 hover:bg-white/5 rounded-2xl cursor-pointer transition-all border border-transparent hover:border-white/5 ${selectedModel === m.id ? 'bg-white/5 border-white/5' : ''}`; |
| 782 | item.innerHTML = ` |
| 783 | <div class="flex items-center gap-3.5"> |
| 784 | <div class="w-10 h-10 ${m.family === 'kontext' ? 'bg-blue-500/10 text-blue-400' : m.family === 'effects' ? 'bg-purple-500/10 text-purple-400' : 'bg-primary/10 text-primary'} border border-white/5 rounded-xl flex items-center justify-center font-black text-sm shadow-inner uppercase">${m.name.charAt(0)}</div> |
| 785 | <div class="flex flex-col gap-0.5"> |
| 786 | <span class="text-xs font-bold text-white tracking-tight">${m.name}</span> |
| 787 | </div> |
| 788 | </div> |
| 789 | ${selectedModel === m.id ? '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#22d3ee" stroke-width="4"><polyline points="20 6 9 17 4 12"/></svg>' : ''} |
| 790 | `; |
no test coverage detected