mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
feat(i18n): add license and content usage filter labels
Add new translation keys for model filter interface: - license - noCreditRequired - allowSellingGeneratedContent These labels support new filtering options for model licensing and content usage permissions, enabling users to filter models based on their license requirements and commercial usage rights.
This commit is contained in:
@@ -188,6 +188,9 @@
|
||||
"title": "Modelle filtern",
|
||||
"baseModel": "Basis-Modell",
|
||||
"modelTags": "Tags (Top 20)",
|
||||
"license": "Lizenz",
|
||||
"noCreditRequired": "Kein Credit erforderlich",
|
||||
"allowSellingGeneratedContent": "Verkauf erlaubt",
|
||||
"clearAll": "Alle Filter löschen"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
"title": "Filter Models",
|
||||
"baseModel": "Base Model",
|
||||
"modelTags": "Tags (Top 20)",
|
||||
"license": "License",
|
||||
"noCreditRequired": "No Credit Required",
|
||||
"allowSellingGeneratedContent": "Allow Selling",
|
||||
"clearAll": "Clear All Filters"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
"title": "Filtrar modelos",
|
||||
"baseModel": "Modelo base",
|
||||
"modelTags": "Etiquetas (Top 20)",
|
||||
"license": "Licencia",
|
||||
"noCreditRequired": "Sin crédito requerido",
|
||||
"allowSellingGeneratedContent": "Venta permitida",
|
||||
"clearAll": "Limpiar todos los filtros"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
"title": "Filtrer les modèles",
|
||||
"baseModel": "Modèle de base",
|
||||
"modelTags": "Tags (Top 20)",
|
||||
"license": "Licence",
|
||||
"noCreditRequired": "Crédit non requis",
|
||||
"allowSellingGeneratedContent": "Vente autorisée",
|
||||
"clearAll": "Effacer tous les filtres"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
"title": "סנן מודלים",
|
||||
"baseModel": "מודל בסיס",
|
||||
"modelTags": "תגיות (20 המובילות)",
|
||||
"license": "רישיון",
|
||||
"noCreditRequired": "ללא קרדיט נדרש",
|
||||
"allowSellingGeneratedContent": "אפשר מכירה",
|
||||
"clearAll": "נקה את כל המסננים"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
"title": "モデルをフィルタ",
|
||||
"baseModel": "ベースモデル",
|
||||
"modelTags": "タグ(上位20)",
|
||||
"license": "ライセンス",
|
||||
"noCreditRequired": "クレジット不要",
|
||||
"allowSellingGeneratedContent": "販売許可",
|
||||
"clearAll": "すべてのフィルタをクリア"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
"title": "모델 필터",
|
||||
"baseModel": "베이스 모델",
|
||||
"modelTags": "태그 (상위 20개)",
|
||||
"license": "라이선스",
|
||||
"noCreditRequired": "크레딧 표기 없음",
|
||||
"allowSellingGeneratedContent": "판매 허용",
|
||||
"clearAll": "모든 필터 지우기"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
"title": "Фильтр моделей",
|
||||
"baseModel": "Базовая модель",
|
||||
"modelTags": "Теги (Топ 20)",
|
||||
"license": "Лицензия",
|
||||
"noCreditRequired": "Без указания авторства",
|
||||
"allowSellingGeneratedContent": "Продажа разрешена",
|
||||
"clearAll": "Очистить все фильтры"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
"title": "筛选模型",
|
||||
"baseModel": "基础模型",
|
||||
"modelTags": "标签(前20)",
|
||||
"license": "许可证",
|
||||
"noCreditRequired": "无需署名",
|
||||
"allowSellingGeneratedContent": "允许销售",
|
||||
"clearAll": "清除所有筛选"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
"title": "篩選模型",
|
||||
"baseModel": "基礎模型",
|
||||
"modelTags": "標籤(前 20)",
|
||||
"license": "授權",
|
||||
"noCreditRequired": "無需署名",
|
||||
"allowSellingGeneratedContent": "允許銷售",
|
||||
"clearAll": "清除所有篩選"
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@@ -51,6 +51,8 @@ html, body {
|
||||
--lora-border: oklch(72% 0.03 256 / 0.45);
|
||||
--lora-text: oklch(95% 0.02 256);
|
||||
--lora-error: oklch(75% 0.32 29);
|
||||
--lora-error-bg: color-mix(in oklch, var(--lora-error) 20%, transparent);
|
||||
--lora-error-border: color-mix(in oklch, var(--lora-error) 50%, transparent);
|
||||
--lora-warning: oklch(var(--lora-warning-l) var(--lora-warning-c) var(--lora-warning-h));
|
||||
--lora-success: oklch(var(--lora-success-l) var(--lora-success-c) var(--lora-success-h));
|
||||
--badge-update-bg: oklch(72% 0.2 220);
|
||||
@@ -103,6 +105,8 @@ html[data-theme="light"] {
|
||||
--lora-border: oklch(90% 0.02 256 / 0.15);
|
||||
--lora-text: oklch(98% 0.02 256);
|
||||
--lora-warning: oklch(75% 0.25 80); /* Modified to be used with oklch() */
|
||||
--lora-error-bg: color-mix(in oklch, var(--lora-error) 15%, transparent);
|
||||
--lora-error-border: color-mix(in oklch, var(--lora-error) 40%, transparent);
|
||||
--badge-update-bg: oklch(62% 0.18 220);
|
||||
--badge-update-text: oklch(98% 0.02 240);
|
||||
--badge-update-glow: oklch(62% 0.18 220 / 0.4);
|
||||
|
||||
@@ -235,6 +235,13 @@
|
||||
border-color: var(--lora-accent);
|
||||
}
|
||||
|
||||
/* Exclude state styling for filter tags */
|
||||
.filter-tag.exclude {
|
||||
background-color: var(--lora-error-bg);
|
||||
color: var(--lora-error);
|
||||
border-color: var(--lora-error-border);
|
||||
}
|
||||
|
||||
/* Tag filter styles */
|
||||
.tag-filter {
|
||||
display: flex;
|
||||
|
||||
@@ -817,6 +817,33 @@ export class BaseModelApiClient {
|
||||
params.append('base_model', model);
|
||||
});
|
||||
}
|
||||
|
||||
// Add license filters
|
||||
if (pageState.filters.license) {
|
||||
const licenseFilters = pageState.filters.license;
|
||||
|
||||
if (licenseFilters.noCredit) {
|
||||
// For noCredit filter:
|
||||
// - 'include' means credit_required=False (no credit required)
|
||||
// - 'exclude' means credit_required=True (credit required)
|
||||
if (licenseFilters.noCredit === 'include') {
|
||||
params.append('credit_required', 'false');
|
||||
} else if (licenseFilters.noCredit === 'exclude') {
|
||||
params.append('credit_required', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
if (licenseFilters.allowSelling) {
|
||||
// For allowSelling filter:
|
||||
// - 'include' means allow_selling_generated_content=True
|
||||
// - 'exclude' means allow_selling_generated_content=False
|
||||
if (licenseFilters.allowSelling === 'include') {
|
||||
params.append('allow_selling_generated_content', 'true');
|
||||
} else if (licenseFilters.allowSelling === 'exclude') {
|
||||
params.append('allow_selling_generated_content', 'false');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._addModelSpecificParams(params, pageState);
|
||||
|
||||
@@ -14,7 +14,8 @@ export class FilterManager {
|
||||
|
||||
this.filters = pageState.filters || {
|
||||
baseModel: [],
|
||||
tags: []
|
||||
tags: [],
|
||||
license: {}
|
||||
};
|
||||
|
||||
this.filterPanel = document.getElementById('filterPanel');
|
||||
@@ -36,6 +37,9 @@ export class FilterManager {
|
||||
this.createBaseModelTags();
|
||||
}
|
||||
|
||||
// Add click handlers for license filter tags
|
||||
this.initializeLicenseFilters();
|
||||
|
||||
// Add click handler for filter button
|
||||
if (this.filterButton) {
|
||||
this.filterButton.addEventListener('click', () => {
|
||||
@@ -129,6 +133,85 @@ export class FilterManager {
|
||||
});
|
||||
}
|
||||
|
||||
initializeLicenseFilters() {
|
||||
const licenseTags = document.querySelectorAll('.license-tag');
|
||||
licenseTags.forEach(tag => {
|
||||
tag.addEventListener('click', async () => {
|
||||
const licenseType = tag.dataset.license;
|
||||
|
||||
// Ensure license object exists
|
||||
if (!this.filters.license) {
|
||||
this.filters.license = {};
|
||||
}
|
||||
|
||||
// Get current state
|
||||
let currentState = this.filters.license[licenseType] || 'none'; // none, include, exclude
|
||||
|
||||
// Cycle through states: none -> include -> exclude -> none
|
||||
let newState;
|
||||
switch (currentState) {
|
||||
case 'none':
|
||||
newState = 'include';
|
||||
tag.classList.remove('exclude');
|
||||
tag.classList.add('active');
|
||||
break;
|
||||
case 'include':
|
||||
newState = 'exclude';
|
||||
tag.classList.remove('active');
|
||||
tag.classList.add('exclude');
|
||||
break;
|
||||
case 'exclude':
|
||||
newState = 'none';
|
||||
tag.classList.remove('active', 'exclude');
|
||||
break;
|
||||
}
|
||||
|
||||
// Update filter state
|
||||
if (newState === 'none') {
|
||||
delete this.filters.license[licenseType];
|
||||
// Clean up empty license object
|
||||
if (Object.keys(this.filters.license).length === 0) {
|
||||
delete this.filters.license;
|
||||
}
|
||||
} else {
|
||||
this.filters.license[licenseType] = newState;
|
||||
}
|
||||
|
||||
this.updateActiveFiltersCount();
|
||||
|
||||
// Auto-apply filter when tag is clicked
|
||||
await this.applyFilters(false);
|
||||
});
|
||||
});
|
||||
|
||||
// Update selections based on stored filters
|
||||
this.updateLicenseSelections();
|
||||
}
|
||||
|
||||
updateLicenseSelections() {
|
||||
const licenseTags = document.querySelectorAll('.license-tag');
|
||||
licenseTags.forEach(tag => {
|
||||
const licenseType = tag.dataset.license;
|
||||
const state = (this.filters.license && this.filters.license[licenseType]) || 'none';
|
||||
|
||||
// Reset classes
|
||||
tag.classList.remove('active', 'exclude');
|
||||
|
||||
// Apply appropriate class based on state
|
||||
switch (state) {
|
||||
case 'include':
|
||||
tag.classList.add('active');
|
||||
break;
|
||||
case 'exclude':
|
||||
tag.classList.add('exclude');
|
||||
break;
|
||||
default:
|
||||
// none state - no classes needed
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
createBaseModelTags() {
|
||||
const baseModelTagsContainer = document.getElementById('baseModelTags');
|
||||
if (!baseModelTagsContainer) return;
|
||||
@@ -233,10 +316,15 @@ export class FilterManager {
|
||||
tag.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Update license tags
|
||||
this.updateLicenseSelections();
|
||||
}
|
||||
|
||||
updateActiveFiltersCount() {
|
||||
const totalActiveFilters = this.filters.baseModel.length + this.filters.tags.length;
|
||||
const totalActiveFilters = this.filters.baseModel.length +
|
||||
this.filters.tags.length +
|
||||
(this.filters.license ? Object.keys(this.filters.license).length : 0);
|
||||
|
||||
if (this.activeFiltersCount) {
|
||||
if (totalActiveFilters > 0) {
|
||||
@@ -296,7 +384,8 @@ export class FilterManager {
|
||||
// Clear all filters
|
||||
this.filters = {
|
||||
baseModel: [],
|
||||
tags: []
|
||||
tags: [],
|
||||
license: {} // Initialize with empty object instead of deleting
|
||||
};
|
||||
|
||||
// Update state
|
||||
@@ -337,7 +426,8 @@ export class FilterManager {
|
||||
// Ensure backward compatibility with older filter format
|
||||
this.filters = {
|
||||
baseModel: savedFilters.baseModel || [],
|
||||
tags: savedFilters.tags || []
|
||||
tags: savedFilters.tags || [],
|
||||
license: savedFilters.license || {}
|
||||
};
|
||||
|
||||
// Update state with loaded filters
|
||||
@@ -357,6 +447,8 @@ export class FilterManager {
|
||||
}
|
||||
|
||||
hasActiveFilters() {
|
||||
return this.filters.baseModel.length > 0 || this.filters.tags.length > 0;
|
||||
return this.filters.baseModel.length > 0 ||
|
||||
this.filters.tags.length > 0 ||
|
||||
(this.filters.license && Object.keys(this.filters.license).length > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +139,17 @@
|
||||
<div class="tags-loading">{{ t('common.status.loading') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-section">
|
||||
<h4>{{ t('header.filter.license') }}</h4>
|
||||
<div class="filter-tags">
|
||||
<div class="filter-tag license-tag" data-license="noCredit">
|
||||
{{ t('header.filter.noCreditRequired') }}
|
||||
</div>
|
||||
<div class="filter-tag license-tag" data-license="allowSelling">
|
||||
{{ t('header.filter.allowSellingGeneratedContent') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-actions">
|
||||
<button class="clear-filters-btn" onclick="filterManager.clearFilters()">
|
||||
{{ t('header.filter.clearAll') }}
|
||||
|
||||
Reference in New Issue
Block a user