feat(usage-control): add support for Civitai usageControl field

Handle models that are only available for on-site generation (usageControl:
"Generation" or "InternalGeneration") rather than downloadable.

Backend changes:
- Add usage_control field to ModelVersionRecord dataclass
- Extract usageControl from Civitai API responses
- Filter non-downloadable versions from update availability checks
- Add database schema migration for usage_control column
- Include usageControl in version response JSON

Frontend changes:
- Add isDownloadAllowed() helper function
- Show disabled download button for non-downloadable versions
- Add "On-Site Only" badge for restricted versions
- Update resolveUpdateAvailability() to filter non-downloadable versions
- Add CSS styling for disabled action button

Internationalization:
- Add translations for onSiteOnly badge and downloadNotAllowedTooltip
- Complete translations for all 10 supported languages
This commit is contained in:
Will Miao
2026-05-01 13:10:15 +08:00
parent d32c492bdb
commit 763c4f4dad
14 changed files with 131 additions and 29 deletions

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "Früher Zugriff", "earlyAccess": "Früher Zugriff",
"earlyAccessTooltip": "Für diese Version ist derzeit Civitai Early Access erforderlich", "earlyAccessTooltip": "Für diese Version ist derzeit Civitai Early Access erforderlich",
"ignored": "Ignoriert", "ignored": "Ignoriert",
"ignoredTooltip": "Für diese Version sind Update-Benachrichtigungen deaktiviert" "ignoredTooltip": "Für diese Version sind Update-Benachrichtigungen deaktiviert",
"onSiteOnly": "Nur On-Site",
"onSiteOnlyTooltip": "Diese Version ist nur für die On-Site-Generierung auf Civitai verfügbar"
}, },
"actions": { "actions": {
"download": "Herunterladen", "download": "Herunterladen",
"downloadTooltip": "Diese Version herunterladen", "downloadTooltip": "Diese Version herunterladen",
"downloadEarlyAccessTooltip": "Diese Early-Access-Version von Civitai herunterladen", "downloadEarlyAccessTooltip": "Diese Early-Access-Version von Civitai herunterladen",
"downloadNotAllowedTooltip": "Diese Version ist nur für die On-Site-Generierung auf Civitai verfügbar",
"delete": "Löschen", "delete": "Löschen",
"deleteTooltip": "Diese lokale Version löschen", "deleteTooltip": "Diese lokale Version löschen",
"ignore": "Ignorieren", "ignore": "Ignorieren",

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "Early Access", "earlyAccess": "Early Access",
"earlyAccessTooltip": "This version currently requires Civitai early access", "earlyAccessTooltip": "This version currently requires Civitai early access",
"ignored": "Ignored", "ignored": "Ignored",
"ignoredTooltip": "Update notifications are disabled for this version" "ignoredTooltip": "Update notifications are disabled for this version",
"onSiteOnly": "On-Site Only",
"onSiteOnlyTooltip": "This version is only available for on-site generation on Civitai"
}, },
"actions": { "actions": {
"download": "Download", "download": "Download",
"downloadTooltip": "Download this version", "downloadTooltip": "Download this version",
"downloadEarlyAccessTooltip": "Download this early access version from Civitai", "downloadEarlyAccessTooltip": "Download this early access version from Civitai",
"downloadNotAllowedTooltip": "This version is only available for on-site generation on Civitai",
"delete": "Delete", "delete": "Delete",
"deleteTooltip": "Delete this local version", "deleteTooltip": "Delete this local version",
"ignore": "Ignore", "ignore": "Ignore",

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "Acceso temprano", "earlyAccess": "Acceso temprano",
"earlyAccessTooltip": "Esta versión requiere actualmente acceso temprano de Civitai", "earlyAccessTooltip": "Esta versión requiere actualmente acceso temprano de Civitai",
"ignored": "Ignorada", "ignored": "Ignorada",
"ignoredTooltip": "Las notificaciones de actualización están desactivadas para esta versión" "ignoredTooltip": "Las notificaciones de actualización están desactivadas para esta versión",
"onSiteOnly": "Solo en Sitio",
"onSiteOnlyTooltip": "Esta versión solo está disponible para generación en el sitio de Civitai"
}, },
"actions": { "actions": {
"download": "Descargar", "download": "Descargar",
"downloadTooltip": "Descargar esta versión", "downloadTooltip": "Descargar esta versión",
"downloadEarlyAccessTooltip": "Descargar esta versión de acceso temprano desde Civitai", "downloadEarlyAccessTooltip": "Descargar esta versión de acceso temprano desde Civitai",
"downloadNotAllowedTooltip": "Esta versión solo está disponible para generación en el sitio de Civitai",
"delete": "Eliminar", "delete": "Eliminar",
"deleteTooltip": "Eliminar esta versión local", "deleteTooltip": "Eliminar esta versión local",
"ignore": "Ignorar", "ignore": "Ignorar",

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "Accès anticipé", "earlyAccess": "Accès anticipé",
"earlyAccessTooltip": "Cette version nécessite actuellement l'accès anticipé Civitai", "earlyAccessTooltip": "Cette version nécessite actuellement l'accès anticipé Civitai",
"ignored": "Ignorée", "ignored": "Ignorée",
"ignoredTooltip": "Les notifications de mise à jour sont désactivées pour cette version" "ignoredTooltip": "Les notifications de mise à jour sont désactivées pour cette version",
"onSiteOnly": "Uniquement sur Site",
"onSiteOnlyTooltip": "Cette version n'est disponible que pour la génération sur le site Civitai"
}, },
"actions": { "actions": {
"download": "Télécharger", "download": "Télécharger",
"downloadTooltip": "Télécharger cette version", "downloadTooltip": "Télécharger cette version",
"downloadEarlyAccessTooltip": "Télécharger cette version en accès anticipé depuis Civitai", "downloadEarlyAccessTooltip": "Télécharger cette version en accès anticipé depuis Civitai",
"downloadNotAllowedTooltip": "Cette version n'est disponible que pour la génération sur le site Civitai",
"delete": "Supprimer", "delete": "Supprimer",
"deleteTooltip": "Supprimer cette version locale", "deleteTooltip": "Supprimer cette version locale",
"ignore": "Ignorer", "ignore": "Ignorer",

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "גישה מוקדמת", "earlyAccess": "גישה מוקדמת",
"earlyAccessTooltip": "גרסה זו דורשת כרגע גישת Early Access של Civitai", "earlyAccessTooltip": "גרסה זו דורשת כרגע גישת Early Access של Civitai",
"ignored": "התעלם", "ignored": "התעלם",
"ignoredTooltip": "התראות העדכון מושבתות עבור גרסה זו" "ignoredTooltip": "התראות העדכון מושבתות עבור גרסה זו",
"onSiteOnly": "רק באתר",
"onSiteOnlyTooltip": "גרסה זו זמינה רק ליצירה באתר Civitai"
}, },
"actions": { "actions": {
"download": "הורדה", "download": "הורדה",
"downloadTooltip": "הורד את הגרסה הזו", "downloadTooltip": "הורד את הגרסה הזו",
"downloadEarlyAccessTooltip": "הורד את גרסת ה-Early Access הזו מ-Civitai", "downloadEarlyAccessTooltip": "הורד את גרסת ה-Early Access הזו מ-Civitai",
"downloadNotAllowedTooltip": "גרסה זו זמינה רק ליצירה באתר Civitai",
"delete": "מחיקה", "delete": "מחיקה",
"deleteTooltip": "מחק את הגרסה המקומית הזו", "deleteTooltip": "מחק את הגרסה המקומית הזו",
"ignore": "התעלם", "ignore": "התעלם",

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "早期アクセス", "earlyAccess": "早期アクセス",
"earlyAccessTooltip": "このバージョンは現在 Civitai の早期アクセスが必要です", "earlyAccessTooltip": "このバージョンは現在 Civitai の早期アクセスが必要です",
"ignored": "無視中", "ignored": "無視中",
"ignoredTooltip": "このバージョンの更新通知は無効です" "ignoredTooltip": "このバージョンの更新通知は無効です",
"onSiteOnly": "サイト内のみ",
"onSiteOnlyTooltip": "このバージョンはCivitaiサイト内でのみ利用可能で、ダウンロードはできません"
}, },
"actions": { "actions": {
"download": "ダウンロード", "download": "ダウンロード",
"downloadTooltip": "このバージョンをダウンロード", "downloadTooltip": "このバージョンをダウンロード",
"downloadEarlyAccessTooltip": "Civitai からこの早期アクセス版をダウンロード", "downloadEarlyAccessTooltip": "Civitai からこの早期アクセス版をダウンロード",
"downloadNotAllowedTooltip": "このバージョンはCivitaiサイト内でのみ利用可能で、ダウンロードはできません",
"delete": "削除", "delete": "削除",
"deleteTooltip": "このローカルバージョンを削除", "deleteTooltip": "このローカルバージョンを削除",
"ignore": "無視", "ignore": "無視",

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "얼리 액세스", "earlyAccess": "얼리 액세스",
"earlyAccessTooltip": "이 버전은 현재 Civitai 얼리 액세스가 필요합니다", "earlyAccessTooltip": "이 버전은 현재 Civitai 얼리 액세스가 필요합니다",
"ignored": "무시됨", "ignored": "무시됨",
"ignoredTooltip": "이 버전은 업데이트 알림이 비활성화되어 있습니다" "ignoredTooltip": "이 버전은 업데이트 알림이 비활성화되어 있습니다",
"onSiteOnly": "사이트 내 전용",
"onSiteOnlyTooltip": "이 버전은 Civitai 사이트 내에서만 사용 가능하며 다운로드할 수 없습니다"
}, },
"actions": { "actions": {
"download": "다운로드", "download": "다운로드",
"downloadTooltip": "이 버전 다운로드", "downloadTooltip": "이 버전 다운로드",
"downloadEarlyAccessTooltip": "Civitai에서 이 얼리 액세스 버전 다운로드", "downloadEarlyAccessTooltip": "Civitai에서 이 얼리 액세스 버전 다운로드",
"downloadNotAllowedTooltip": "이 버전은 Civitai 사이트 내에서만 사용 가능하며 다운로드할 수 없습니다",
"delete": "삭제", "delete": "삭제",
"deleteTooltip": "이 로컬 버전 삭제", "deleteTooltip": "이 로컬 버전 삭제",
"ignore": "무시", "ignore": "무시",

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "Ранний доступ", "earlyAccess": "Ранний доступ",
"earlyAccessTooltip": "Для этой версии сейчас требуется ранний доступ Civitai", "earlyAccessTooltip": "Для этой версии сейчас требуется ранний доступ Civitai",
"ignored": "Игнорируется", "ignored": "Игнорируется",
"ignoredTooltip": "Уведомления об обновлениях для этой версии отключены" "ignoredTooltip": "Уведомления об обновлениях для этой версии отключены",
"onSiteOnly": "Только на Сайте",
"onSiteOnlyTooltip": "Эта версия доступна только для генерации на сайте Civitai"
}, },
"actions": { "actions": {
"download": "Скачать", "download": "Скачать",
"downloadTooltip": "Скачать эту версию", "downloadTooltip": "Скачать эту версию",
"downloadEarlyAccessTooltip": "Скачать эту версию раннего доступа с Civitai", "downloadEarlyAccessTooltip": "Скачать эту версию раннего доступа с Civitai",
"downloadNotAllowedTooltip": "Эта версия доступна только для генерации на сайте Civitai",
"delete": "Удалить", "delete": "Удалить",
"deleteTooltip": "Удалить эту локальную версию", "deleteTooltip": "Удалить эту локальную версию",
"ignore": "Игнорировать", "ignore": "Игнорировать",

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "抢先体验", "earlyAccess": "抢先体验",
"earlyAccessTooltip": "此版本当前需要 Civitai 抢先体验权限", "earlyAccessTooltip": "此版本当前需要 Civitai 抢先体验权限",
"ignored": "已忽略", "ignored": "已忽略",
"ignoredTooltip": "此版本已关闭更新通知" "ignoredTooltip": "此版本已关闭更新通知",
"onSiteOnly": "仅站内生成",
"onSiteOnlyTooltip": "此版本仅在 Civitai 站内可用,无法下载"
}, },
"actions": { "actions": {
"download": "下载", "download": "下载",
"downloadTooltip": "下载此版本", "downloadTooltip": "下载此版本",
"downloadEarlyAccessTooltip": "从 Civitai 下载此抢先体验版本", "downloadEarlyAccessTooltip": "从 Civitai 下载此抢先体验版本",
"downloadNotAllowedTooltip": "此版本仅在 Civitai 站内可用,无法下载",
"delete": "删除", "delete": "删除",
"deleteTooltip": "删除此本地版本", "deleteTooltip": "删除此本地版本",
"ignore": "忽略", "ignore": "忽略",

View File

@@ -1292,12 +1292,15 @@
"earlyAccess": "搶先體驗", "earlyAccess": "搶先體驗",
"earlyAccessTooltip": "此版本目前需要 Civitai 搶先體驗權限", "earlyAccessTooltip": "此版本目前需要 Civitai 搶先體驗權限",
"ignored": "已忽略", "ignored": "已忽略",
"ignoredTooltip": "此版本已關閉更新通知" "ignoredTooltip": "此版本已關閉更新通知",
"onSiteOnly": "僅站內生成",
"onSiteOnlyTooltip": "此版本僅在 Civitai 站內可用,無法下載"
}, },
"actions": { "actions": {
"download": "下載", "download": "下載",
"downloadTooltip": "下載此版本", "downloadTooltip": "下載此版本",
"downloadEarlyAccessTooltip": "從 Civitai 下載此搶先體驗版本", "downloadEarlyAccessTooltip": "從 Civitai 下載此搶先體驗版本",
"downloadNotAllowedTooltip": "此版本僅在 Civitai 站內可用,無法下載",
"delete": "刪除", "delete": "刪除",
"deleteTooltip": "刪除此本地版本", "deleteTooltip": "刪除此本地版本",
"ignore": "忽略", "ignore": "忽略",

View File

@@ -2423,6 +2423,7 @@ class ModelUpdateHandler:
"shouldIgnore": version.should_ignore, "shouldIgnore": version.should_ignore,
"earlyAccessEndsAt": version.early_access_ends_at, "earlyAccessEndsAt": version.early_access_ends_at,
"isEarlyAccess": is_early_access, "isEarlyAccess": is_early_access,
"usageControl": version.usage_control,
"filePath": context.get("file_path"), "filePath": context.get("file_path"),
"fileName": context.get("file_name"), "fileName": context.get("file_name"),
} }

View File

@@ -69,6 +69,7 @@ class ModelVersionRecord:
early_access_ends_at: Optional[str] = None early_access_ends_at: Optional[str] = None
sort_index: int = 0 sort_index: int = 0
is_early_access: bool = False is_early_access: bool = False
usage_control: Optional[str] = None # "Download", "Generation", "InternalGeneration"
@dataclass @dataclass
@@ -101,11 +102,14 @@ class ModelUpdateRecord:
return [version.version_id for version in self.versions if version.is_in_library] return [version.version_id for version in self.versions if version.is_in_library]
def has_update(self, hide_early_access: bool = False) -> bool: def has_update(
self, hide_early_access: bool = False, hide_non_downloadable: bool = True
) -> bool:
"""Return True when a non-ignored remote version newer than the newest local copy is available. """Return True when a non-ignored remote version newer than the newest local copy is available.
Args: Args:
hide_early_access: If True, exclude early access versions from update check. hide_early_access: If True, exclude early access versions from update check.
hide_non_downloadable: If True, exclude versions that don't allow downloads.
""" """
if self.should_ignore_model: if self.should_ignore_model:
@@ -121,6 +125,7 @@ class ModelUpdateRecord:
not version.is_in_library not version.is_in_library
and not version.should_ignore and not version.should_ignore
and not (hide_early_access and ModelUpdateRecord._is_early_access_active(version)) and not (hide_early_access and ModelUpdateRecord._is_early_access_active(version))
and not (hide_non_downloadable and not ModelUpdateRecord._is_downloadable(version))
for version in self.versions for version in self.versions
) )
@@ -129,6 +134,8 @@ class ModelUpdateRecord:
continue continue
if hide_early_access and ModelUpdateRecord._is_early_access_active(version): if hide_early_access and ModelUpdateRecord._is_early_access_active(version):
continue continue
if hide_non_downloadable and not ModelUpdateRecord._is_downloadable(version):
continue
if version.version_id > max_in_library: if version.version_id > max_in_library:
return True return True
return False return False
@@ -155,11 +162,18 @@ class ModelUpdateRecord:
# Phase 1: Basic EA flag from bulk API # Phase 1: Basic EA flag from bulk API
return version.is_early_access return version.is_early_access
@staticmethod
def _is_downloadable(version: ModelVersionRecord) -> bool:
if version.usage_control is None:
return True
return version.usage_control == "Download"
def has_update_for_base( def has_update_for_base(
self, self,
local_version_id: Optional[int], local_version_id: Optional[int],
local_base_model: Optional[str], local_base_model: Optional[str],
hide_early_access: bool = False, hide_early_access: bool = False,
hide_non_downloadable: bool = True,
) -> bool: ) -> bool:
"""Return True when a newer remote version with the same base model exists. """Return True when a newer remote version with the same base model exists.
@@ -167,6 +181,7 @@ class ModelUpdateRecord:
local_version_id: The current local version id. local_version_id: The current local version id.
local_base_model: The base model to filter by. local_base_model: The base model to filter by.
hide_early_access: If True, exclude early access versions from update check. hide_early_access: If True, exclude early access versions from update check.
hide_non_downloadable: If True, exclude versions that don't allow downloads.
""" """
if self.should_ignore_model: if self.should_ignore_model:
@@ -197,6 +212,8 @@ class ModelUpdateRecord:
continue continue
if hide_early_access and ModelUpdateRecord._is_early_access_active(version): if hide_early_access and ModelUpdateRecord._is_early_access_active(version):
continue continue
if hide_non_downloadable and not ModelUpdateRecord._is_downloadable(version):
continue
version_base = _normalize_base_model(version.base_model) version_base = _normalize_base_model(version.base_model)
if version_base != normalized_base: if version_base != normalized_base:
continue continue
@@ -230,6 +247,7 @@ class ModelUpdateService:
preview_url TEXT, preview_url TEXT,
is_in_library INTEGER NOT NULL DEFAULT 0, is_in_library INTEGER NOT NULL DEFAULT 0,
should_ignore INTEGER NOT NULL DEFAULT 0, should_ignore INTEGER NOT NULL DEFAULT 0,
usage_control TEXT,
PRIMARY KEY (model_id, version_id), PRIMARY KEY (model_id, version_id),
FOREIGN KEY(model_id) REFERENCES model_update_status(model_id) ON DELETE CASCADE FOREIGN KEY(model_id) REFERENCES model_update_status(model_id) ON DELETE CASCADE
); );
@@ -465,6 +483,10 @@ class ModelUpdateService:
"ALTER TABLE model_update_versions " "ALTER TABLE model_update_versions "
"ADD COLUMN is_early_access INTEGER NOT NULL DEFAULT 0" "ADD COLUMN is_early_access INTEGER NOT NULL DEFAULT 0"
), ),
"usage_control": (
"ALTER TABLE model_update_versions "
"ADD COLUMN usage_control TEXT"
),
} }
for column, statement in migrations.items(): for column, statement in migrations.items():
@@ -1337,6 +1359,7 @@ class ModelUpdateService:
# Check availability field from bulk API for basic EA detection # Check availability field from bulk API for basic EA detection
availability = _normalize_string(entry.get("availability")) availability = _normalize_string(entry.get("availability"))
is_early_access = availability == "EarlyAccess" is_early_access = availability == "EarlyAccess"
usage_control = _normalize_string(entry.get("usageControl"))
return ModelVersionRecord( return ModelVersionRecord(
version_id=version_id, version_id=version_id,
@@ -1350,6 +1373,7 @@ class ModelUpdateService:
early_access_ends_at=early_access_ends_at, early_access_ends_at=early_access_ends_at,
sort_index=index, sort_index=index,
is_early_access=is_early_access, is_early_access=is_early_access,
usage_control=usage_control,
) )
def _extract_size_bytes(self, files) -> Optional[int]: def _extract_size_bytes(self, files) -> Optional[int]:
@@ -1464,7 +1488,7 @@ class ModelUpdateService:
f""" f"""
SELECT model_id, version_id, sort_index, name, base_model, released_at, SELECT model_id, version_id, sort_index, name, base_model, released_at,
size_bytes, preview_url, is_in_library, should_ignore, early_access_ends_at, size_bytes, preview_url, is_in_library, should_ignore, early_access_ends_at,
is_early_access is_early_access, usage_control
FROM model_update_versions FROM model_update_versions
WHERE model_id IN ({placeholders}) WHERE model_id IN ({placeholders})
ORDER BY model_id ASC, sort_index ASC, version_id ASC ORDER BY model_id ASC, sort_index ASC, version_id ASC
@@ -1492,6 +1516,7 @@ class ModelUpdateService:
early_access_ends_at=row["early_access_ends_at"], early_access_ends_at=row["early_access_ends_at"],
sort_index=_normalize_int(row["sort_index"]) or 0, sort_index=_normalize_int(row["sort_index"]) or 0,
is_early_access=bool(row["is_early_access"]), is_early_access=bool(row["is_early_access"]),
usage_control=row["usage_control"],
) )
) )
@@ -1548,8 +1573,8 @@ class ModelUpdateService:
INSERT INTO model_update_versions ( INSERT INTO model_update_versions (
version_id, model_id, sort_index, name, base_model, released_at, version_id, model_id, sort_index, name, base_model, released_at,
size_bytes, preview_url, is_in_library, should_ignore, early_access_ends_at, size_bytes, preview_url, is_in_library, should_ignore, early_access_ends_at,
is_early_access is_early_access, usage_control
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", """,
( (
version.version_id, version.version_id,
@@ -1564,6 +1589,7 @@ class ModelUpdateService:
1 if version.should_ignore else 0, 1 if version.should_ignore else 0,
version.early_access_ends_at, version.early_access_ends_at,
1 if version.is_early_access else 0, 1 if version.is_early_access else 0,
version.usage_control,
), ),
) )
conn.commit() conn.commit()

View File

@@ -374,6 +374,14 @@
background: color-mix(in oklch, var(--lora-surface) 35%, transparent); background: color-mix(in oklch, var(--lora-surface) 35%, transparent);
} }
.version-action-disabled {
background: transparent;
border-color: var(--border-color);
color: var(--text-muted);
opacity: 0.6;
cursor: not-allowed;
}
.version-action:disabled { .version-action:disabled {
opacity: 0.6; opacity: 0.6;
cursor: not-allowed; cursor: not-allowed;

View File

@@ -181,6 +181,13 @@ function isEarlyAccessActive(version) {
} }
} }
function isDownloadAllowed(version) {
if (!version.usageControl) {
return true;
}
return version.usageControl === 'Download';
}
function buildMetaMarkup(version, options = {}) { function buildMetaMarkup(version, options = {}) {
const segments = []; const segments = [];
if (version.baseModel) { if (version.baseModel) {
@@ -230,12 +237,17 @@ function buildBadge(label, tone, options = {}) {
function buildActionButton(label, variant, action, options = {}) { function buildActionButton(label, variant, action, options = {}) {
const attributes = [ const attributes = [
`class="version-action ${variant}"`, `class="version-action ${variant}"`,
`data-version-action="${escapeHtml(action)}"`,
]; ];
if (action) {
attributes.push(`data-version-action="${escapeHtml(action)}"`);
}
if (options.title) { if (options.title) {
attributes.push(`title="${escapeHtml(options.title)}"`); attributes.push(`title="${escapeHtml(options.title)}"`);
attributes.push(`aria-label="${escapeHtml(options.title)}"`); attributes.push(`aria-label="${escapeHtml(options.title)}"`);
} }
if (options.disabled) {
attributes.push('disabled');
}
if (options.extraAttributes) { if (options.extraAttributes) {
attributes.push(options.extraAttributes); attributes.push(options.extraAttributes);
} }
@@ -371,6 +383,9 @@ function resolveUpdateAvailability(record, baseModel, currentVersionId) {
if (hideEarlyAccess && isEarlyAccessActive(version)) { if (hideEarlyAccess && isEarlyAccessActive(version)) {
return false; return false;
} }
if (!isDownloadAllowed(version)) {
return false;
}
const versionBase = normalizeBaseModelName(version.baseModel); const versionBase = normalizeBaseModelName(version.baseModel);
if (versionBase !== normalizedBase) { if (versionBase !== normalizedBase) {
return false; return false;
@@ -502,6 +517,17 @@ function renderRow(version, options) {
})); }));
} }
if (!isDownloadAllowed(version)) {
const onSiteOnlyBadgeLabel = translate('modals.model.versions.badges.onSiteOnly', {}, 'On-Site Only');
badges.push(buildBadge(onSiteOnlyBadgeLabel, 'info', {
title: translate(
'modals.model.versions.badges.onSiteOnlyTooltip',
{},
'This version is only available for on-site generation on Civitai'
),
}));
}
if (version.shouldIgnore) { if (version.shouldIgnore) {
badges.push(buildBadge(ignoredBadgeLabel, 'muted', { badges.push(buildBadge(ignoredBadgeLabel, 'muted', {
title: translate( title: translate(
@@ -524,25 +550,36 @@ function renderRow(version, options) {
const actions = []; const actions = [];
if (!version.isInLibrary) { if (!version.isInLibrary) {
// Download button with optional EA bolt icon const canDownload = isDownloadAllowed(version);
const downloadIcon = isEarlyAccess ? '<i class="fas fa-bolt"></i> ' : ''; const downloadIcon = isEarlyAccess ? '<i class="fas fa-bolt"></i> ' : '';
let downloadTitle;
if (!canDownload) {
downloadTitle = translate(
'modals.model.versions.actions.downloadNotAllowedTooltip',
{},
'This version is only available for on-site generation on Civitai'
);
} else if (isEarlyAccess) {
downloadTitle = translate(
'modals.model.versions.actions.downloadEarlyAccessTooltip',
{},
'Download this early access version from Civitai'
);
} else {
downloadTitle = translate(
'modals.model.versions.actions.downloadTooltip',
{},
'Download this version'
);
}
actions.push(buildActionButton( actions.push(buildActionButton(
downloadLabel, downloadLabel,
'version-action-primary', canDownload ? 'version-action-primary' : 'version-action-disabled',
'download', canDownload ? 'download' : '',
{ {
title: isEarlyAccess title: downloadTitle,
? translate(
'modals.model.versions.actions.downloadEarlyAccessTooltip',
{},
'Download this early access version from Civitai'
)
: translate(
'modals.model.versions.actions.downloadTooltip',
{},
'Download this version'
),
iconMarkup: downloadIcon, iconMarkup: downloadIcon,
disabled: !canDownload,
} }
)); ));
} else if (version.filePath) { } else if (version.filePath) {