feat: implement various UI helpers including clipboard, toasts, theme toggling, and Civitai integration, and add RecipeModal component.

This commit is contained in:
Will Miao
2025-12-29 16:14:55 +08:00
parent 5d5a2a998a
commit d30c8e13df
2 changed files with 440 additions and 414 deletions

View File

@@ -1,5 +1,5 @@
// Recipe Modal Component // Recipe Modal Component
import { showToast, copyToClipboard, sendModelPathToWorkflow } from '../utils/uiHelpers.js'; import { showToast, copyToClipboard, sendModelPathToWorkflow, openCivitaiByMetadata } from '../utils/uiHelpers.js';
import { translate } from '../utils/i18nHelpers.js'; import { translate } from '../utils/i18nHelpers.js';
import { state } from '../state/index.js'; import { state } from '../state/index.js';
import { setSessionItem, removeSessionItem } from '../utils/storageHelpers.js'; import { setSessionItem, removeSessionItem } from '../utils/storageHelpers.js';
@@ -261,8 +261,7 @@ class RecipeModal {
sourceUrlContainer.innerHTML = ` sourceUrlContainer.innerHTML = `
<div class="source-url-content"> <div class="source-url-content">
<span class="source-url-icon"><i class="fas fa-link"></i></span> <span class="source-url-icon"><i class="fas fa-link"></i></span>
<span class="source-url-text" title="${isValidUrl ? 'Click to open source URL' : 'No valid URL'}">${ <span class="source-url-text" title="${isValidUrl ? 'Click to open source URL' : 'No valid URL'}">${hasSourceUrl ? sourceUrl : 'No source URL'
hasSourceUrl ? sourceUrl : 'No source URL'
}</span> }</span>
</div> </div>
<button class="source-url-edit-btn" title="Edit source URL"> <button class="source-url-edit-btn" title="Edit source URL">
@@ -1249,6 +1248,17 @@ class RecipeModal {
} }
navigateToCheckpointPage(checkpoint) { navigateToCheckpointPage(checkpoint) {
if (!checkpoint.inLibrary) {
const modelId = checkpoint.modelId || checkpoint.modelID || checkpoint.model_id;
const versionId = checkpoint.id || checkpoint.modelVersionId;
const modelName = checkpoint.name || checkpoint.modelName || checkpoint.file_name;
if (modelId || modelName) {
openCivitaiByMetadata(modelId, versionId, modelName);
return;
}
}
const checkpointHash = this._getCheckpointHash(checkpoint); const checkpointHash = this._getCheckpointHash(checkpoint);
if (!checkpointHash) { if (!checkpointHash) {
@@ -1296,6 +1306,18 @@ class RecipeModal {
if (specificLoraIndex !== null) { if (specificLoraIndex !== null) {
// If a specific LoRA index is provided, navigate to view just that one LoRA // If a specific LoRA index is provided, navigate to view just that one LoRA
const lora = this.currentRecipe.loras[specificLoraIndex]; const lora = this.currentRecipe.loras[specificLoraIndex];
if (lora && !lora.inLibrary) {
const modelId = lora.modelId || lora.modelID || lora.model_id;
const versionId = lora.id || lora.modelVersionId;
const modelName = lora.modelName || lora.name || lora.file_name;
if (modelId || modelName) {
openCivitaiByMetadata(modelId, versionId, modelName);
return;
}
}
if (lora && lora.hash) { if (lora && lora.hash) {
// Set session storage to open the LoRA modal directly // Set session storage to open the LoRA modal directly
setSessionItem('recipe_to_lora_filterLoraHash', lora.hash.toLowerCase()); setSessionItem('recipe_to_lora_filterLoraHash', lora.hash.toLowerCase());

View File

@@ -183,6 +183,19 @@ function filterByFolder(folderPath) {
}); });
} }
export function openCivitaiByMetadata(civitaiId, versionId, modelName = null) {
if (civitaiId) {
let url = `https://civitai.com/models/${civitaiId}`;
if (versionId) {
url += `?modelVersionId=${versionId}`;
}
window.open(url, '_blank');
} else if (modelName) {
// 如果没有ID尝试使用名称搜索
window.open(`https://civitai.com/models?query=${encodeURIComponent(modelName)}`, '_blank');
}
}
export function openCivitai(filePath) { export function openCivitai(filePath) {
const loraCard = document.querySelector(`.model-card[data-filepath="${filePath}"]`); const loraCard = document.querySelector(`.model-card[data-filepath="${filePath}"]`);
if (!loraCard) return; if (!loraCard) return;
@@ -190,18 +203,9 @@ export function openCivitai(filePath) {
const metaData = JSON.parse(loraCard.dataset.meta); const metaData = JSON.parse(loraCard.dataset.meta);
const civitaiId = metaData.modelId; const civitaiId = metaData.modelId;
const versionId = metaData.id; const versionId = metaData.id;
if (civitaiId) {
let url = `https://civitai.com/models/${civitaiId}`;
if (versionId) {
url += `?modelVersionId=${versionId}`;
}
window.open(url, '_blank');
} else {
// 如果没有ID尝试使用名称搜索
const modelName = loraCard.dataset.name; const modelName = loraCard.dataset.name;
window.open(`https://civitai.com/models?query=${encodeURIComponent(modelName)}`, '_blank');
} openCivitaiByMetadata(civitaiId, versionId, modelName);
} }
/** /**