feat(example-images): add remote open mode support

This commit is contained in:
Will Miao
2026-04-27 14:05:21 +08:00
parent cc147a1795
commit ffe0670a27
20 changed files with 621 additions and 21 deletions

View File

@@ -914,6 +914,23 @@ export class SettingsManager {
autoDownloadExampleImagesCheckbox.checked = state.global.settings.auto_download_example_images || false;
}
const exampleImagesOpenModeSelect = document.getElementById('exampleImagesOpenMode');
if (exampleImagesOpenModeSelect) {
exampleImagesOpenModeSelect.value = state.global.settings.example_images_open_mode || 'system';
}
const exampleImagesLocalRootInput = document.getElementById('exampleImagesLocalRoot');
if (exampleImagesLocalRootInput) {
exampleImagesLocalRootInput.value = state.global.settings.example_images_local_root || '';
}
const exampleImagesOpenUriTemplateInput = document.getElementById('exampleImagesOpenUriTemplate');
if (exampleImagesOpenUriTemplateInput) {
exampleImagesOpenUriTemplateInput.value = state.global.settings.example_images_open_uri_template || '';
}
this.updateExampleImagesOpenSettingsVisibility();
// Load download path templates
this.loadDownloadPathTemplates();
@@ -2015,6 +2032,25 @@ export class SettingsManager {
}
}
updateExampleImagesOpenSettingsVisibility() {
const openMode = state.global.settings.example_images_open_mode || 'system';
const localRootSetting = document.getElementById('exampleImagesLocalRootSetting');
const uriTemplateSetting = document.getElementById('exampleImagesUriTemplateSetting');
if (localRootSetting) {
localRootSetting.style.display = openMode === 'system' ? 'none' : 'block';
}
if (uriTemplateSetting) {
uriTemplateSetting.style.display = openMode === 'uri_template' ? 'block' : 'none';
}
}
async handleExampleImagesOpenModeChange() {
await this.saveSelectSetting('exampleImagesOpenMode', 'example_images_open_mode');
this.updateExampleImagesOpenSettingsVisibility();
}
async loadMetadataArchiveSettings() {
try {
// Load current settings from state

View File

@@ -25,6 +25,9 @@ const DEFAULT_SETTINGS_BASE = Object.freeze({
base_model_path_mappings: {},
download_path_templates: {},
example_images_path: '',
example_images_open_mode: 'system',
example_images_local_root: '',
example_images_open_uri_template: '',
optimize_example_images: true,
auto_download_example_images: false,
blur_mature_content: true,

View File

@@ -64,6 +64,33 @@ export function openCivitaiUrl(url) {
return window.open(url, '_blank', 'noopener,noreferrer');
}
async function copyExampleImagesValue(value, successKey, fallbackKey, paramsKey = 'path') {
if (!value) {
return false;
}
const params = { [paramsKey]: value };
try {
await navigator.clipboard.writeText(value);
showToast(successKey, params, 'success');
return true;
} catch (clipboardErr) {
console.warn('Clipboard API not available:', clipboardErr);
showToast(fallbackKey, params, 'info');
return false;
}
}
function tryOpenExternalUri(uri) {
try {
const openedWindow = window.open(uri, '_blank', 'noopener,noreferrer');
return openedWindow !== null;
} catch (error) {
console.warn('Failed to open external URI:', error);
return false;
}
}
/**
* Utility function to copy text to clipboard with fallback for older browsers
* @param {string} text - The text to copy to clipboard
@@ -1088,7 +1115,31 @@ export async function openExampleImagesFolder(modelHash) {
const result = await response.json();
if (result.success) {
const message = translate('uiHelpers.exampleImages.openingFolder', {}, 'Opening example images folder');
if (result.mode === 'clipboard' && result.path) {
await copyExampleImagesValue(
result.path,
'uiHelpers.exampleImages.copiedPath',
'uiHelpers.exampleImages.clipboardFallback',
'path'
);
return true;
}
if (result.mode === 'uri' && result.uri) {
const opened = tryOpenExternalUri(result.uri);
if (!opened) {
await copyExampleImagesValue(
result.uri,
'uiHelpers.exampleImages.copiedUri',
'uiHelpers.exampleImages.uriClipboardFallback',
'uri'
);
} else {
showToast('uiHelpers.exampleImages.opened', {}, 'success');
}
return true;
}
showToast('uiHelpers.exampleImages.opened', {}, 'success');
return true;
} else {