feat(model-manager): add CivitAI browse view + fix civitai.red / 401

- New "Browse CivitAI" view: thumbnail grid with search, type/sort/period
  filters and NSFW toggle; click a model card to download it (per-card
  version picker for multi-version models). Cursor + page based "Load more".
- Backend: /api/civitai/search and /api/civitai/download endpoints; new
  civitai_search() catalog helper.
- Fix 401 on paste: recognize the civitai.red mirror (and any civitai.*
  host), normalize API calls to civitai.com, and always resolve the
  model-version so type + filename are auto-detected for every CivitAI URL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 14:50:10 -04:00
parent e037a1b062
commit e8115e7aa6
6 changed files with 427 additions and 41 deletions
+42
View File
@@ -132,6 +132,48 @@ code { background: var(--bg-3); padding: 1px 5px; border-radius: 4px; font-size:
.model-card .card-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 4px; }
.empty { color: var(--text-dim); }
/* ---- browse civitai ---- */
.browse-controls {
display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
margin-bottom: 20px;
}
.browse-controls input[type=search] { width: 280px; flex: 1; min-width: 200px; }
.browse-controls select { width: auto; }
.check { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--text); white-space: nowrap; }
.check input { width: auto; }
.browse-grid {
display: grid; gap: 14px;
grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.browse-card {
background: var(--bg-2); border: 1px solid var(--border);
border-radius: var(--radius); overflow: hidden;
display: flex; flex-direction: column;
}
.browse-card .thumb {
aspect-ratio: 3 / 4; background: var(--bg-3) center/cover no-repeat;
position: relative;
}
.browse-card .thumb .type-tag {
position: absolute; top: 8px; left: 8px;
background: rgba(12,16,32,.78); color: var(--text);
font-size: 11px; padding: 2px 8px; border-radius: 8px;
}
.browse-card .thumb .nsfw-tag {
position: absolute; top: 8px; right: 8px;
background: rgba(239,93,107,.85); color: #fff;
font-size: 10px; padding: 2px 7px; border-radius: 8px; font-weight: 600;
}
.browse-card .body { padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.browse-card .b-name { font-weight: 600; font-size: 13px; line-height: 1.25;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.browse-card .b-meta { color: var(--text-dim); font-size: 11px; }
.browse-card .b-foot { margin-top: auto; display: flex; gap: 6px; align-items: center; }
.browse-card select { font-size: 12px; padding: 5px 6px; }
.browse-card .btn { padding: 6px 12px; font-size: 12px; flex: 1; }
.browse-more { display: flex; justify-content: center; margin: 22px 0; }
/* ---- downloads ---- */
.downloads-container { display: flex; flex-direction: column; gap: 10px; max-width: 860px; }
.dl-row {