Spaces:
Configuration error
Configuration error
File size: 4,993 Bytes
6757240 d595b97 6757240 82229f9 6757240 d595b97 6757240 d595b97 6757240 82229f9 6757240 82229f9 6757240 82229f9 6757240 82229f9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
class LoraSelector extends HTMLElement {
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
}
.lora-container {
position: relative;
}
.lora-select {
width: 100%;
background: #374151;
border: 1px solid #4b5563;
border-radius: 0.5rem;
padding: 0.75rem;
color: white;
font-size: 1rem;
cursor: pointer;
appearance: none;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 0.75rem center;
background-size: 1rem;
}
.lora-select:focus {
outline: none;
border-color: #10b981;
box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.3);
}
.loading {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
display: none;
}
.spinner {
width: 20px;
height: 20px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: #10b981;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.error {
color: #ef4444;
font-size: 0.875rem;
margin-top: 0.5rem;
display: none;
}
</style>
<div class="lora-container">
<select class="lora-select" id="loraSelect">
<option value="">Loading LoRA models...</option>
</select>
<div class="loading" id="loadingIndicator">
<div class="spinner"></div>
</div>
</div>
<div class="error" id="errorMessage"></div>
`;
this.loadLoraModels();
}
async loadLoraModels() {
const selectElement = this.shadowRoot.getElementById('loraSelect');
const loadingIndicator = this.shadowRoot.getElementById('loadingIndicator');
const errorMessage = this.shadowRoot.getElementById('errorMessage');
try {
loadingIndicator.style.display = 'block';
// Fetch LoRA models from Hugging Face API
const response = await fetch('https://huggingface.co/api/models/Playtime-AI/Wan2.2-Loras');
const data = await response.json();
// Get safetensors files
const safetensorsFiles = data.siblings.filter(file => file.rfilename.endsWith('.safetensors'));
// Clear loading option
selectElement.innerHTML = '<option value="">Select a LoRA model</option>';
// Add each LoRA model as an option
safetensorsFiles.forEach(file => {
const option = document.createElement('option');
const modelName = file.rfilename.replace('.safetensors', '');
option.value = JSON.stringify({
filename: file.rfilename,
trigger: this.getTriggerWord(modelName)
});
option.textContent = modelName;
selectElement.appendChild(option);
});
// Dispatch event when models are loaded
this.dispatchEvent(new CustomEvent('loras-loaded', {
detail: { models: safetensorsFiles },
bubbles: true
}));
} catch (error) {
console.error('Error loading LoRA models:', error);
selectElement.innerHTML = '<option value="">Failed to load models</option>';
errorMessage.textContent = 'Failed to load LoRA models. Please try again later.';
errorMessage.style.display = 'block';
} finally {
loadingIndicator.style.display = 'none';
}
}
getTriggerWord(modelName) {
const triggers = {
'Wan2.2-Disco-Diffusion': 'disco style',
'Wan2.2-Futuristic-City': 'futuristic cityscape',
'Wan2.2-Anime-Art': 'anime art style',
'Wan2.2-Cyberpunk': 'cyberpunk aesthetic',
'Wan2.2-Fantasy': 'fantasy illustration',
'Wan2.2-Photorealistic': 'photorealistic',
'Wan2.2-Watercolor': 'watercolor painting',
'Wan2.2-Oil-Painting': 'oil painting',
'Wan2.2-Sketch': 'pencil sketch',
'Wan2.2-Impressionist': 'impressionist painting'
};
return triggers[modelName] || 'enhanced style';
}
get selectedValue() {
const selected = this.shadowRoot.getElementById('loraSelect').value;
try {
return JSON.parse(selected);
} catch {
return { filename: '', trigger: '' };
}
}
set selectedValue(value) {
this.shadowRoot.getElementById('loraSelect').value = JSON.stringify(value);
}
}
customElements.define('lora-selector', LoraSelector);
|