refactor: consolidate shared utilities and relocate view-specific settings logic
- Moved formatting helpers (formatBytes, formatDuration, getDownloadEtaText, formatDownloadProgressMeta) and getLocalMatchDisplayInfo from resolve_download_methods.js and missing_browser_methods.js into render_format_methods.js for shared reuse. - Relocated settings-related methods (getStoredTokens, applyFrontendLoggingPreference, loadSettingsFromServer) and their log_system imports from download_target_methods.js into options_methods.js, where they are actually consumed by the options UI. - Simplified missing_browser_methods.js to use getLocalMatchDisplayInfo instead of inline local-match code.
This commit is contained in:
@@ -2640,59 +2640,5 @@ export const resolveDownloadMethods = {
|
||||
this.updateQueuePanel?.();
|
||||
this.showNotification('Download failed: ' + error.message, 'error');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Format bytes to human readable string
|
||||
*/
|
||||
formatBytes(bytes) {
|
||||
const value = Number(bytes) || 0;
|
||||
if (!Number.isFinite(value) || value <= 0) return '0 B';
|
||||
const k = 1024;
|
||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
const i = Math.min(sizes.length - 1, Math.floor(Math.log(value) / Math.log(k)));
|
||||
return parseFloat((value / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
|
||||
},
|
||||
|
||||
formatDuration(seconds) {
|
||||
const totalSeconds = Math.max(0, Math.ceil(Number(seconds) || 0));
|
||||
if (!Number.isFinite(totalSeconds) || totalSeconds <= 0) return '';
|
||||
|
||||
if (totalSeconds < 60) return `${totalSeconds}s`;
|
||||
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
const remainingSeconds = totalSeconds % 60;
|
||||
|
||||
if (hours > 0) {
|
||||
return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
|
||||
}
|
||||
|
||||
return remainingSeconds > 0 ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
|
||||
},
|
||||
|
||||
getDownloadEtaText(progress = {}) {
|
||||
const totalSize = Number(progress.total_size) || 0;
|
||||
const downloaded = Number(progress.downloaded) || 0;
|
||||
const speed = Number(progress.speed) || 0;
|
||||
if (totalSize <= 0 || downloaded <= 0 || speed <= 0 || downloaded >= totalSize) return '';
|
||||
|
||||
const duration = this.formatDuration((totalSize - downloaded) / speed);
|
||||
return duration ? `ETA ${duration}` : '';
|
||||
},
|
||||
|
||||
formatDownloadProgressMeta(progress = {}) {
|
||||
const parts = [];
|
||||
const speed = Number(progress.speed) || 0;
|
||||
if (speed > 0) {
|
||||
parts.push(`${this.formatBytes(speed)}/s`);
|
||||
}
|
||||
|
||||
const eta = this.getDownloadEtaText(progress);
|
||||
if (eta) {
|
||||
parts.push(eta);
|
||||
}
|
||||
|
||||
return parts.join(' | ');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { app } from "../../../../../scripts/app.js";
|
||||
import { api } from "../../../../../scripts/api.js";
|
||||
import { $el } from "../../../../../scripts/ui.js";
|
||||
import { LOG_LEVEL as DEFAULT_FRONTEND_LOG_LEVEL } from "../../log_system/config.js";
|
||||
import { logger as frontendLogger } from "../../log_system/logger.js";
|
||||
import { getSvgIcon } from "../../utils/icon_utils.js";
|
||||
import { createFloatingTreePicker } from "../utils/tree_picker.js";
|
||||
export const downloadTargetMethods = {
|
||||
@@ -2407,138 +2405,6 @@ export const downloadTargetMethods = {
|
||||
.catch(() => refreshCategoryTooltip());
|
||||
},
|
||||
|
||||
getStoredTokens() {
|
||||
const civitaiCandidateLimitRaw = parseInt(localStorage.getItem('ModelResolver.civitaiCandidateLimit') || '5', 10);
|
||||
const civitai_candidate_limit = Number.isFinite(civitaiCandidateLimitRaw)
|
||||
? Math.min(20, Math.max(1, civitaiCandidateLimitRaw))
|
||||
: 5;
|
||||
const search_source_enabled = this.getSearchSourceEnabledMap();
|
||||
const storedFrontendLogsEnabled = localStorage.getItem('ModelResolver.frontendLogsEnabled');
|
||||
const storedBackendLogsEnabled = localStorage.getItem('ModelResolver.backendLogsEnabled');
|
||||
const storedFrontendLogLevel = localStorage.getItem('ModelResolver.frontendLogLevel');
|
||||
const storedBackendLogLevel = localStorage.getItem('ModelResolver.backendLogLevel');
|
||||
|
||||
return {
|
||||
civitai_key: localStorage.getItem('ModelResolver.civitaiApiKey') || '',
|
||||
civitai_session_token: localStorage.getItem('ModelResolver.civitaiSessionToken') || '',
|
||||
hf_token: localStorage.getItem('ModelResolver.huggingFaceToken') || '',
|
||||
brave_search_api_key: localStorage.getItem('ModelResolver.braveSearchApiKey') || '',
|
||||
civitai_use_trpc_search: localStorage.getItem('ModelResolver.civitaiUseTrpcSearch') !== 'false',
|
||||
civitai_use_html_fallback: localStorage.getItem('ModelResolver.civitaiUseHtmlFallback') !== 'false',
|
||||
hf_use_api_search: localStorage.getItem('ModelResolver.hfUseApiSearch') !== 'false',
|
||||
hf_use_comfy_org_fallback: localStorage.getItem('ModelResolver.hfUseComfyOrgFallback') !== 'false',
|
||||
hf_use_brave_fallback: localStorage.getItem('ModelResolver.hfUseBraveFallback') !== 'false',
|
||||
auto_fill_base_model: localStorage.getItem('ModelResolver.autoFillBaseModel') !== 'false',
|
||||
auto_fill_subfolder: localStorage.getItem('ModelResolver.autoFillSubfolder') !== 'false',
|
||||
auto_refresh_comfy_models_after_apply: localStorage.getItem('ModelResolver.autoRefreshComfyModelsAfterApply') !== 'false',
|
||||
frontend_logs_enabled: storedFrontendLogsEnabled === null
|
||||
? frontendLogger.enabled !== false
|
||||
: storedFrontendLogsEnabled !== 'false',
|
||||
backend_logs_enabled: storedBackendLogsEnabled === null
|
||||
? true
|
||||
: storedBackendLogsEnabled !== 'false',
|
||||
frontend_log_level: storedFrontendLogLevel || DEFAULT_FRONTEND_LOG_LEVEL,
|
||||
backend_log_level: storedBackendLogLevel || 'DEBUG',
|
||||
civitai_candidate_limit,
|
||||
search_source_enabled,
|
||||
download_path_mode: this.getDownloadPathMode(),
|
||||
download_path_templates: this.getDownloadPathTemplates(),
|
||||
base_model_path_mappings: this.getBaseModelPathMappings(),
|
||||
...this.getDefaultRootSettings()
|
||||
};
|
||||
},
|
||||
|
||||
applyFrontendLoggingPreference(enabled = true, levelName = 'DEBUG') {
|
||||
frontendLogger.setEnabled(Boolean(enabled));
|
||||
frontendLogger.setGlobalAndModuleLevel(frontendLogger.normalizeLevel(levelName));
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch settings saved on the server and sync them into localStorage.
|
||||
* Call this once when the dialog initialises so every browser gets the
|
||||
* same tokens without the user having to re-enter them.
|
||||
*/
|
||||
async loadSettingsFromServer() {
|
||||
try {
|
||||
const resp = await api.fetchApi('/model_resolver/settings');
|
||||
if (!resp.ok) {
|
||||
const tokens = this.getStoredTokens();
|
||||
this.applyFrontendLoggingPreference(tokens.frontend_logs_enabled, tokens.frontend_log_level);
|
||||
return;
|
||||
}
|
||||
const data = await resp.json();
|
||||
if (!data || typeof data !== 'object') {
|
||||
const tokens = this.getStoredTokens();
|
||||
this.applyFrontendLoggingPreference(tokens.frontend_logs_enabled, tokens.frontend_log_level);
|
||||
return;
|
||||
}
|
||||
|
||||
// Helper: write to localStorage only when the value from server is
|
||||
// non-empty, so we don't overwrite a key the user already has locally.
|
||||
const sync = (localKey, serverValue) => {
|
||||
if (serverValue !== undefined && serverValue !== null && serverValue !== '') {
|
||||
localStorage.setItem(localKey, serverValue);
|
||||
}
|
||||
};
|
||||
|
||||
sync('ModelResolver.civitaiApiKey', data.civitai_key);
|
||||
sync('ModelResolver.civitaiSessionToken', data.civitai_session_token);
|
||||
sync('ModelResolver.huggingFaceToken', data.hf_token);
|
||||
sync('ModelResolver.braveSearchApiKey', data.brave_search_api_key);
|
||||
|
||||
if (data.civitai_use_trpc_search !== undefined)
|
||||
localStorage.setItem('ModelResolver.civitaiUseTrpcSearch', data.civitai_use_trpc_search ? 'true' : 'false');
|
||||
if (data.civitai_use_html_fallback !== undefined)
|
||||
localStorage.setItem('ModelResolver.civitaiUseHtmlFallback', data.civitai_use_html_fallback ? 'true' : 'false');
|
||||
if (data.hf_use_api_search !== undefined)
|
||||
localStorage.setItem('ModelResolver.hfUseApiSearch', data.hf_use_api_search ? 'true' : 'false');
|
||||
if (data.hf_use_comfy_org_fallback !== undefined)
|
||||
localStorage.setItem('ModelResolver.hfUseComfyOrgFallback', data.hf_use_comfy_org_fallback ? 'true' : 'false');
|
||||
if (data.hf_use_brave_fallback !== undefined)
|
||||
localStorage.setItem('ModelResolver.hfUseBraveFallback', data.hf_use_brave_fallback ? 'true' : 'false');
|
||||
if (data.auto_fill_base_model !== undefined)
|
||||
localStorage.setItem('ModelResolver.autoFillBaseModel', data.auto_fill_base_model ? 'true' : 'false');
|
||||
if (data.auto_fill_subfolder !== undefined)
|
||||
localStorage.setItem('ModelResolver.autoFillSubfolder', data.auto_fill_subfolder ? 'true' : 'false');
|
||||
if (data.auto_refresh_comfy_models_after_apply !== undefined)
|
||||
localStorage.setItem('ModelResolver.autoRefreshComfyModelsAfterApply', data.auto_refresh_comfy_models_after_apply ? 'true' : 'false');
|
||||
if (data.download_path_mode !== undefined)
|
||||
localStorage.setItem('ModelResolver.downloadPathMode', this.normalizeDownloadPathMode(data.download_path_mode));
|
||||
if (data.download_path_templates !== undefined)
|
||||
localStorage.setItem('ModelResolver.downloadPathTemplates', JSON.stringify(data.download_path_templates || {}));
|
||||
if (data.base_model_path_mappings !== undefined)
|
||||
localStorage.setItem('ModelResolver.baseModelPathMappings', JSON.stringify(data.base_model_path_mappings || {}));
|
||||
this.getDefaultRootCategoryDefinitions().forEach((item) => {
|
||||
if (data[item.settingKey] !== undefined) {
|
||||
localStorage.setItem(item.storageKey, String(data[item.settingKey] || ''));
|
||||
}
|
||||
});
|
||||
if (data.civitai_candidate_limit !== undefined)
|
||||
localStorage.setItem('ModelResolver.civitaiCandidateLimit', `${data.civitai_candidate_limit}`);
|
||||
if (data.frontend_logs_enabled !== undefined)
|
||||
localStorage.setItem('ModelResolver.frontendLogsEnabled', data.frontend_logs_enabled ? 'true' : 'false');
|
||||
if (data.backend_logs_enabled !== undefined)
|
||||
localStorage.setItem('ModelResolver.backendLogsEnabled', data.backend_logs_enabled ? 'true' : 'false');
|
||||
if (data.frontend_log_level !== undefined)
|
||||
localStorage.setItem('ModelResolver.frontendLogLevel', String(data.frontend_log_level || 'DEBUG').toUpperCase());
|
||||
if (data.backend_log_level !== undefined)
|
||||
localStorage.setItem('ModelResolver.backendLogLevel', String(data.backend_log_level || 'DEBUG').toUpperCase());
|
||||
|
||||
// Source-enabled flags stored as a nested object
|
||||
if (data.search_source_enabled && typeof data.search_source_enabled === 'object') {
|
||||
Object.entries(data.search_source_enabled).forEach(([key, val]) => {
|
||||
if (key) localStorage.setItem(key, val ? 'true' : 'false');
|
||||
});
|
||||
}
|
||||
const tokens = this.getStoredTokens();
|
||||
this.applyFrontendLoggingPreference(tokens.frontend_logs_enabled, tokens.frontend_log_level);
|
||||
} catch (err) {
|
||||
console.warn('Model Resolver: could not load settings from server, using localStorage only.', err);
|
||||
const tokens = this.getStoredTokens();
|
||||
this.applyFrontendLoggingPreference(tokens.frontend_logs_enabled, tokens.frontend_log_level);
|
||||
}
|
||||
},
|
||||
|
||||
clearFrontendSearchCaches() {
|
||||
for (const state of this.searchResultCache.values()) {
|
||||
state.activeSearchRunId = null;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { app } from "../../../../../scripts/app.js";
|
||||
import { app } from "../../../../../scripts/app.js";
|
||||
import { api } from "../../../../../scripts/api.js";
|
||||
import { $el } from "../../../../../scripts/ui.js";
|
||||
import { getSvgIcon } from "../../utils/icon_utils.js";
|
||||
@@ -242,5 +242,73 @@ export const renderFormatMethods = {
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 250));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get display information for the best local match of a missing model
|
||||
* @param {object} missing - The missing model object
|
||||
* @returns {object} Match display metadata
|
||||
*/
|
||||
getLocalMatchDisplayInfo(missing) {
|
||||
const bestMatch = this.getBestLocalMatch?.(missing, 70) || null;
|
||||
const confidence = bestMatch ? Number(bestMatch.confidence || 0) : 0;
|
||||
const matchName = bestMatch?.model?.relative_path || bestMatch?.filename || bestMatch?.path || '';
|
||||
const matchDisplay = matchName || 'No local match';
|
||||
const matchClass = confidence === 100 ? 'exact' : (bestMatch ? 'partial' : 'none');
|
||||
return { bestMatch, confidence, matchDisplay, matchClass };
|
||||
},
|
||||
|
||||
/**
|
||||
* Format bytes to human readable string
|
||||
*/
|
||||
formatBytes(bytes) {
|
||||
const value = Number(bytes) || 0;
|
||||
if (!Number.isFinite(value) || value <= 0) return '0 B';
|
||||
const k = 1024;
|
||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
const i = Math.min(sizes.length - 1, Math.floor(Math.log(value) / Math.log(k)));
|
||||
return parseFloat((value / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
|
||||
},
|
||||
|
||||
formatDuration(seconds) {
|
||||
const totalSeconds = Math.max(0, Math.ceil(Number(seconds) || 0));
|
||||
if (!Number.isFinite(totalSeconds) || totalSeconds <= 0) return '';
|
||||
|
||||
if (totalSeconds < 60) return `${totalSeconds}s`;
|
||||
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
const remainingSeconds = totalSeconds % 60;
|
||||
|
||||
if (hours > 0) {
|
||||
return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
|
||||
}
|
||||
|
||||
return remainingSeconds > 0 ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
|
||||
},
|
||||
|
||||
getDownloadEtaText(progress = {}) {
|
||||
const totalSize = Number(progress.total_size) || 0;
|
||||
const downloaded = Number(progress.downloaded) || 0;
|
||||
const speed = Number(progress.speed) || 0;
|
||||
if (totalSize <= 0 || downloaded <= 0 || speed <= 0 || downloaded >= totalSize) return '';
|
||||
|
||||
const duration = this.formatDuration((totalSize - downloaded) / speed);
|
||||
return duration ? `ETA ${duration}` : '';
|
||||
},
|
||||
|
||||
formatDownloadProgressMeta(progress = {}) {
|
||||
const parts = [];
|
||||
const speed = Number(progress.speed) || 0;
|
||||
if (speed > 0) {
|
||||
parts.push(`${this.formatBytes(speed)}/s`);
|
||||
}
|
||||
|
||||
const eta = this.getDownloadEtaText(progress);
|
||||
if (eta) {
|
||||
parts.push(eta);
|
||||
}
|
||||
|
||||
return parts.join(' | ');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -386,11 +386,7 @@ export const missingBrowserMethods = {
|
||||
const isBatchSelected = this.batchSelectedMissingKeys?.has(key);
|
||||
const isResolved = this.isMissingModelResolved(missing);
|
||||
const filename = this.getMissingFilename(missing);
|
||||
const bestMatch = this.getBestLocalMatch(missing, 70);
|
||||
const confidence = bestMatch ? Number(bestMatch.confidence || 0) : 0;
|
||||
const matchName = bestMatch?.model?.relative_path || bestMatch?.filename || bestMatch?.path || '';
|
||||
const matchDisplay = matchName || 'No local match';
|
||||
const matchClass = confidence === 100 ? 'exact' : (bestMatch ? 'partial' : 'none');
|
||||
const { bestMatch, confidence, matchDisplay, matchClass } = this.getLocalMatchDisplayInfo(missing);
|
||||
const typeLabel = missing.category ? this.getCategoryDisplayName(missing.category) : 'unknown';
|
||||
const typeColorClass = this.getModelTypeColorClass(missing.category || typeLabel);
|
||||
const nodeDisplay = this.getMissingNodeDisplay(missing);
|
||||
@@ -1609,11 +1605,7 @@ export const missingBrowserMethods = {
|
||||
.find(item => item.dataset.missingKey === missingKey);
|
||||
if (!row) return;
|
||||
|
||||
const bestMatch = this.getBestLocalMatch(missing, 70);
|
||||
const confidence = bestMatch ? Number(bestMatch.confidence || 0) : 0;
|
||||
const matchName = bestMatch?.model?.relative_path || bestMatch?.filename || bestMatch?.path || '';
|
||||
const matchDisplay = matchName || 'No local match';
|
||||
const matchClass = confidence === 100 ? 'exact' : (bestMatch ? 'partial' : 'none');
|
||||
const { bestMatch, confidence, matchDisplay, matchClass } = this.getLocalMatchDisplayInfo(missing);
|
||||
|
||||
const bestEl = row.querySelector('.mr-missing-row-best');
|
||||
if (bestEl) {
|
||||
|
||||
@@ -2,6 +2,8 @@ import { app } from "../../../../../scripts/app.js";
|
||||
import { api } from "../../../../../scripts/api.js";
|
||||
import { $el } from "../../../../../scripts/ui.js";
|
||||
import { getSvgIcon } from "../../utils/icon_utils.js";
|
||||
import { LOG_LEVEL as DEFAULT_FRONTEND_LOG_LEVEL } from "../../log_system/config.js";
|
||||
import { logger as frontendLogger } from "../../log_system/logger.js";
|
||||
export const optionsMethods = {
|
||||
displayOptions() {
|
||||
if (!this.contentElement) return;
|
||||
@@ -1693,5 +1695,137 @@ export const optionsMethods = {
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getStoredTokens() {
|
||||
const civitaiCandidateLimitRaw = parseInt(localStorage.getItem('ModelResolver.civitaiCandidateLimit') || '5', 10);
|
||||
const civitai_candidate_limit = Number.isFinite(civitaiCandidateLimitRaw)
|
||||
? Math.min(20, Math.max(1, civitaiCandidateLimitRaw))
|
||||
: 5;
|
||||
const search_source_enabled = this.getSearchSourceEnabledMap();
|
||||
const storedFrontendLogsEnabled = localStorage.getItem('ModelResolver.frontendLogsEnabled');
|
||||
const storedBackendLogsEnabled = localStorage.getItem('ModelResolver.backendLogsEnabled');
|
||||
const storedFrontendLogLevel = localStorage.getItem('ModelResolver.frontendLogLevel');
|
||||
const storedBackendLogLevel = localStorage.getItem('ModelResolver.backendLogLevel');
|
||||
|
||||
return {
|
||||
civitai_key: localStorage.getItem('ModelResolver.civitaiApiKey') || '',
|
||||
civitai_session_token: localStorage.getItem('ModelResolver.civitaiSessionToken') || '',
|
||||
hf_token: localStorage.getItem('ModelResolver.huggingFaceToken') || '',
|
||||
brave_search_api_key: localStorage.getItem('ModelResolver.braveSearchApiKey') || '',
|
||||
civitai_use_trpc_search: localStorage.getItem('ModelResolver.civitaiUseTrpcSearch') !== 'false',
|
||||
civitai_use_html_fallback: localStorage.getItem('ModelResolver.civitaiUseHtmlFallback') !== 'false',
|
||||
hf_use_api_search: localStorage.getItem('ModelResolver.hfUseApiSearch') !== 'false',
|
||||
hf_use_comfy_org_fallback: localStorage.getItem('ModelResolver.hfUseComfyOrgFallback') !== 'false',
|
||||
hf_use_brave_fallback: localStorage.getItem('ModelResolver.hfUseBraveFallback') !== 'false',
|
||||
auto_fill_base_model: localStorage.getItem('ModelResolver.autoFillBaseModel') !== 'false',
|
||||
auto_fill_subfolder: localStorage.getItem('ModelResolver.autoFillSubfolder') !== 'false',
|
||||
auto_refresh_comfy_models_after_apply: localStorage.getItem('ModelResolver.autoRefreshComfyModelsAfterApply') !== 'false',
|
||||
frontend_logs_enabled: storedFrontendLogsEnabled === null
|
||||
? frontendLogger.enabled !== false
|
||||
: storedFrontendLogsEnabled !== 'false',
|
||||
backend_logs_enabled: storedBackendLogsEnabled === null
|
||||
? true
|
||||
: storedBackendLogsEnabled !== 'false',
|
||||
frontend_log_level: storedFrontendLogLevel || DEFAULT_FRONTEND_LOG_LEVEL,
|
||||
backend_log_level: storedBackendLogLevel || 'DEBUG',
|
||||
civitai_candidate_limit,
|
||||
search_source_enabled,
|
||||
download_path_mode: this.getDownloadPathMode(),
|
||||
download_path_templates: this.getDownloadPathTemplates(),
|
||||
base_model_path_mappings: this.getBaseModelPathMappings(),
|
||||
...this.getDefaultRootSettings()
|
||||
};
|
||||
},
|
||||
|
||||
applyFrontendLoggingPreference(enabled = true, levelName = 'DEBUG') {
|
||||
frontendLogger.setEnabled(Boolean(enabled));
|
||||
frontendLogger.setGlobalAndModuleLevel(frontendLogger.normalizeLevel(levelName));
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch settings saved on the server and sync them into localStorage.
|
||||
* Call this once when the dialog initialises so every browser gets the
|
||||
* same tokens without the user having to re-enter them.
|
||||
*/
|
||||
async loadSettingsFromServer() {
|
||||
try {
|
||||
const resp = await api.fetchApi('/model_resolver/settings');
|
||||
if (!resp.ok) {
|
||||
const tokens = this.getStoredTokens();
|
||||
this.applyFrontendLoggingPreference(tokens.frontend_logs_enabled, tokens.frontend_log_level);
|
||||
return;
|
||||
}
|
||||
const data = await resp.json();
|
||||
if (!data || typeof data !== 'object') {
|
||||
const tokens = this.getStoredTokens();
|
||||
this.applyFrontendLoggingPreference(tokens.frontend_logs_enabled, tokens.frontend_log_level);
|
||||
return;
|
||||
}
|
||||
|
||||
// Helper: write to localStorage only when the value from server is
|
||||
// non-empty, so we don't overwrite a key the user already has locally.
|
||||
const sync = (localKey, serverValue) => {
|
||||
if (serverValue !== undefined && serverValue !== null && serverValue !== '') {
|
||||
localStorage.setItem(localKey, serverValue);
|
||||
}
|
||||
};
|
||||
|
||||
sync('ModelResolver.civitaiApiKey', data.civitai_key);
|
||||
sync('ModelResolver.civitaiSessionToken', data.civitai_session_token);
|
||||
sync('ModelResolver.huggingFaceToken', data.hf_token);
|
||||
sync('ModelResolver.braveSearchApiKey', data.brave_search_api_key);
|
||||
|
||||
if (data.civitai_use_trpc_search !== undefined)
|
||||
localStorage.setItem('ModelResolver.civitaiUseTrpcSearch', data.civitai_use_trpc_search ? 'true' : 'false');
|
||||
if (data.civitai_use_html_fallback !== undefined)
|
||||
localStorage.setItem('ModelResolver.civitaiUseHtmlFallback', data.civitai_use_html_fallback ? 'true' : 'false');
|
||||
if (data.hf_use_api_search !== undefined)
|
||||
localStorage.setItem('ModelResolver.hfUseApiSearch', data.hf_use_api_search ? 'true' : 'false');
|
||||
if (data.hf_use_comfy_org_fallback !== undefined)
|
||||
localStorage.setItem('ModelResolver.hfUseComfyOrgFallback', data.hf_use_comfy_org_fallback ? 'true' : 'false');
|
||||
if (data.hf_use_brave_fallback !== undefined)
|
||||
localStorage.setItem('ModelResolver.hfUseBraveFallback', data.hf_use_brave_fallback ? 'true' : 'false');
|
||||
if (data.auto_fill_base_model !== undefined)
|
||||
localStorage.setItem('ModelResolver.autoFillBaseModel', data.auto_fill_base_model ? 'true' : 'false');
|
||||
if (data.auto_fill_subfolder !== undefined)
|
||||
localStorage.setItem('ModelResolver.autoFillSubfolder', data.auto_fill_subfolder ? 'true' : 'false');
|
||||
if (data.auto_refresh_comfy_models_after_apply !== undefined)
|
||||
localStorage.setItem('ModelResolver.autoRefreshComfyModelsAfterApply', data.auto_refresh_comfy_models_after_apply ? 'true' : 'false');
|
||||
if (data.download_path_mode !== undefined)
|
||||
localStorage.setItem('ModelResolver.downloadPathMode', this.normalizeDownloadPathMode(data.download_path_mode));
|
||||
if (data.download_path_templates !== undefined)
|
||||
localStorage.setItem('ModelResolver.downloadPathTemplates', JSON.stringify(data.download_path_templates || {}));
|
||||
if (data.base_model_path_mappings !== undefined)
|
||||
localStorage.setItem('ModelResolver.baseModelPathMappings', JSON.stringify(data.base_model_path_mappings || {}));
|
||||
this.getDefaultRootCategoryDefinitions().forEach((item) => {
|
||||
if (data[item.settingKey] !== undefined) {
|
||||
localStorage.setItem(item.storageKey, String(data[item.settingKey] || ''));
|
||||
}
|
||||
});
|
||||
if (data.civitai_candidate_limit !== undefined)
|
||||
localStorage.setItem('ModelResolver.civitaiCandidateLimit', `${data.civitai_candidate_limit}`);
|
||||
if (data.frontend_logs_enabled !== undefined)
|
||||
localStorage.setItem('ModelResolver.frontendLogsEnabled', data.frontend_logs_enabled ? 'true' : 'false');
|
||||
if (data.backend_logs_enabled !== undefined)
|
||||
localStorage.setItem('ModelResolver.backendLogsEnabled', data.backend_logs_enabled ? 'true' : 'false');
|
||||
if (data.frontend_log_level !== undefined)
|
||||
localStorage.setItem('ModelResolver.frontendLogLevel', String(data.frontend_log_level || 'DEBUG').toUpperCase());
|
||||
if (data.backend_log_level !== undefined)
|
||||
localStorage.setItem('ModelResolver.backendLogLevel', String(data.backend_log_level || 'DEBUG').toUpperCase());
|
||||
|
||||
// Source-enabled flags stored as a nested object
|
||||
if (data.search_source_enabled && typeof data.search_source_enabled === 'object') {
|
||||
Object.entries(data.search_source_enabled).forEach(([key, val]) => {
|
||||
if (key) localStorage.setItem(key, val ? 'true' : 'false');
|
||||
});
|
||||
}
|
||||
const tokens = this.getStoredTokens();
|
||||
this.applyFrontendLoggingPreference(tokens.frontend_logs_enabled, tokens.frontend_log_level);
|
||||
} catch (err) {
|
||||
console.warn('Model Resolver: could not load settings from server, using localStorage only.', err);
|
||||
const tokens = this.getStoredTokens();
|
||||
this.applyFrontendLoggingPreference(tokens.frontend_logs_enabled, tokens.frontend_log_level);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user