fix reports
This commit is contained in:
+129
-76
@@ -15,104 +15,157 @@
|
||||
configReject = reject;
|
||||
});
|
||||
|
||||
// API endpoint for config - you can change this URL
|
||||
// You can also set it via a data attribute: <script src="/config-loader.js" data-config-url="https://your-api.com/config"></script>
|
||||
//const scriptTag = document.currentScript || document.querySelector('script[src*="config-loader.js"]');
|
||||
//const customUrl = scriptTag ? scriptTag.getAttribute('data-config-url') : null;
|
||||
const CONFIG_URL = 'https://nerkh.gold/get_user' //customUrl || window.location.origin + '/api/config';
|
||||
const VERSION_URL = 'https://abshode-service.montgit.ir/server/get_version';
|
||||
const CONFIG_URLS = [
|
||||
'https://nerkh.gold/get_user',
|
||||
'https://abshode-service.montgit.ir/server/get_user'
|
||||
];
|
||||
const CONFIG_SUCCESS_URL_KEY = 'CONFIG_Success_URL';
|
||||
|
||||
// Timeout to ensure main.ts loads even if config fails (5 seconds)
|
||||
const CONFIG_TIMEOUT = 5000;
|
||||
// Timeout to ensure main.ts loads even if config fails
|
||||
const CONFIG_TIMEOUT = 12000;
|
||||
let configTimeoutId;
|
||||
let mainScriptLoaded = false;
|
||||
|
||||
// Fetch config from server
|
||||
async function loadConfig() {
|
||||
function getProtocol() {
|
||||
return window.location.protocol === 'https:' ? 'https:' : 'http:';
|
||||
}
|
||||
|
||||
function sortConfigUrls(urls) {
|
||||
const lastSuccessUrl = localStorage.getItem(CONFIG_SUCCESS_URL_KEY);
|
||||
|
||||
return [...urls].sort((a, b) => {
|
||||
if (a === lastSuccessUrl) return -1;
|
||||
if (b === lastSuccessUrl) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchJson(url, timeout = 3500) {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = window.setTimeout(() => controller.abort(), timeout);
|
||||
|
||||
try {
|
||||
const response = await fetch(CONFIG_URL, {
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
Accept: 'application/json'
|
||||
},
|
||||
cache: 'no-cache'
|
||||
cache: 'no-store',
|
||||
signal: controller.signal
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch config: ' + response.status);
|
||||
throw new Error('Request failed: ' + response.status);
|
||||
}
|
||||
|
||||
// Check if response is actually JSON
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (!contentType || !contentType.includes('application/json')) {
|
||||
const contentType = response.headers.get('content-type') || '';
|
||||
|
||||
if (!contentType.includes('application/json')) {
|
||||
const text = await response.text();
|
||||
throw new Error('Response is not JSON. Received: ' + text.substring(0, 100));
|
||||
}
|
||||
|
||||
const config = await response.json();
|
||||
return await response.json();
|
||||
} finally {
|
||||
window.clearTimeout(timeoutId);
|
||||
}
|
||||
}
|
||||
|
||||
// Store config in window object
|
||||
window.__APP_CONFIG__ = config;
|
||||
window.__CONFIG_READY__ = true;
|
||||
if (config?.user?.name_fa) {
|
||||
document.title = 'پنل مدیریت '+ '-'+config.user.name_fa;
|
||||
}
|
||||
// ---------- Dynamic Favicon ----------
|
||||
if (config?.user?.avatar) {
|
||||
const faviconUrl = config.user.avatar;
|
||||
|
||||
// remove existing favicon(s)
|
||||
const existingIcons = document.querySelectorAll('link[rel*="icon"]');
|
||||
existingIcons.forEach(icon => icon.remove());
|
||||
|
||||
// create new favicon
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'icon';
|
||||
link.type = 'image/png'; // یا image/x-icon
|
||||
link.href = faviconUrl + '?v=' + Date.now();
|
||||
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
// Resolve the promise
|
||||
if (configResolve) {
|
||||
configResolve(config);
|
||||
}
|
||||
|
||||
// Dispatch custom event to notify that config is ready
|
||||
window.dispatchEvent(new CustomEvent('configReady', { detail: config }));
|
||||
|
||||
console.log('Config loaded successfully:', config);
|
||||
|
||||
// Clear timeout if config loaded successfully
|
||||
if (configTimeoutId) {
|
||||
clearTimeout(configTimeoutId);
|
||||
configTimeoutId = null;
|
||||
}
|
||||
|
||||
// Load main.ts after config is ready
|
||||
loadMainScript();
|
||||
async function loadVersion() {
|
||||
try {
|
||||
await fetchJson(VERSION_URL, 3500);
|
||||
console.log('Version loaded from:', VERSION_URL);
|
||||
} catch (error) {
|
||||
console.warn('Config loader: Could not fetch config from', CONFIG_URL);
|
||||
console.warn('Version check failed from', VERSION_URL, error);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchConfig() {
|
||||
const protocol = getProtocol();
|
||||
const urls = sortConfigUrls(
|
||||
CONFIG_URLS.map((url) => url.replace(/^https?:/, protocol))
|
||||
);
|
||||
|
||||
for (let index = 0; index < urls.length; index++) {
|
||||
const url = urls[index];
|
||||
const timeout = index === urls.length - 1 ? 5000 : 3500;
|
||||
|
||||
try {
|
||||
const config = await fetchJson(url, timeout);
|
||||
|
||||
if (!config || typeof config !== 'object') {
|
||||
throw new Error('Config response is invalid');
|
||||
}
|
||||
|
||||
localStorage.setItem(CONFIG_SUCCESS_URL_KEY, url);
|
||||
return { config, url };
|
||||
} catch (error) {
|
||||
console.warn('Config failed from', url, error);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Cannot load config from any server');
|
||||
}
|
||||
|
||||
function applyConfig(config) {
|
||||
window.__APP_CONFIG__ = config;
|
||||
window.__CONFIG_READY__ = true;
|
||||
|
||||
if (config?.user?.name_fa) {
|
||||
document.title = 'پنل مدیریت ' + '-' + config.user.name_fa;
|
||||
}
|
||||
|
||||
if (config?.user?.avatar) {
|
||||
const faviconUrl = config.user.avatar;
|
||||
const existingIcons = document.querySelectorAll('link[rel*="icon"]');
|
||||
existingIcons.forEach((icon) => icon.remove());
|
||||
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'icon';
|
||||
link.type = 'image/png';
|
||||
link.href = faviconUrl + '?v=' + Date.now();
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
function finishConfigLoad(config, error) {
|
||||
if (configResolve) {
|
||||
configResolve(config);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
window.dispatchEvent(new CustomEvent('configError', { detail: error }));
|
||||
} else {
|
||||
window.dispatchEvent(new CustomEvent('configReady', { detail: config }));
|
||||
}
|
||||
|
||||
if (configTimeoutId) {
|
||||
clearTimeout(configTimeoutId);
|
||||
configTimeoutId = null;
|
||||
}
|
||||
|
||||
loadMainScript();
|
||||
}
|
||||
|
||||
// Fetch config from server
|
||||
async function loadConfig() {
|
||||
try {
|
||||
await loadVersion();
|
||||
|
||||
const { config, url } = await fetchConfig();
|
||||
applyConfig(config);
|
||||
|
||||
console.log('Config loaded successfully from', url, config);
|
||||
finishConfigLoad(config);
|
||||
} catch (error) {
|
||||
console.warn('Config loader: Could not fetch config from any endpoint');
|
||||
console.warn('Error details:', error.message);
|
||||
console.warn('This is normal if the endpoint does not exist yet. App will continue with empty config.');
|
||||
// Set default empty config on error
|
||||
console.warn('App will continue with empty config.');
|
||||
|
||||
window.__APP_CONFIG__ = {};
|
||||
window.__CONFIG_READY__ = true;
|
||||
|
||||
// Resolve the promise even on error (with empty config)
|
||||
if (configResolve) {
|
||||
configResolve({});
|
||||
}
|
||||
|
||||
window.dispatchEvent(new CustomEvent('configError', { detail: error }));
|
||||
|
||||
// Clear timeout if error occurred
|
||||
if (configTimeoutId) {
|
||||
clearTimeout(configTimeoutId);
|
||||
configTimeoutId = null;
|
||||
}
|
||||
|
||||
// Load main.ts even on error (with empty config)
|
||||
loadMainScript();
|
||||
finishConfigLoad({}, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user