document.addEventListener('DOMContentLoaded', function() {
// Create the locations section HTML
const locationsHTML = `
`;
// Insert after .s-block--stats
const statsBlock = document.querySelector('.s-block--stats');
if (statsBlock) {
statsBlock.insertAdjacentHTML('afterend', locationsHTML);
// Tab switching functionality
const tabButtons = document.querySelectorAll('.location-tab-btn');
const tabPanes = document.querySelectorAll('.location-tab-pane');
tabButtons.forEach(button => {
button.addEventListener('click', function() {
const targetLocation = this.getAttribute('data-location');
// Remove active class from all buttons and panes
tabButtons.forEach(btn => btn.classList.remove('active'));
tabPanes.forEach(pane => pane.classList.remove('active'));
// Add active class to clicked button and corresponding pane
this.classList.add('active');
document.getElementById(targetLocation).classList.add('active');
});
});
}
});
const LOGO_SRC =
'https://cdn.files.salla.network/homepage/961632855/0c2f6d1c-7c36-4960-8f61-e6d91e16638c.webp';
const API_ENDPOINT = 'https://autogoldapp.com/api/prices-bar-by-origin';
const CACHE_KEY = 'mfgp_cached_data';
const REFRESH_INTERVAL = 45000; // 30 seconds
document.addEventListener('theme::ready', () => {
initMfgp();
});
function initMfgp() {
if (document.querySelector('.mfgp-top-bar')) return;
injectHtml();
bindMobileToggle();
// Load cached data first if available
loadCachedData();
// Fetch fresh prices
fetchPrices();
// Set up interval for auto-refresh
setInterval(fetchPrices, REFRESH_INTERVAL);
}
const priceMapping = {
21: { type: 'gold', key: '21' },
18: { type: 'gold', key: '18' },
22: { type: 'gold', key: '22' },
24: { type: 'gold', key: '24' },
xau: { type: 'gold', key: 'ounce' },
};
// Store previous prices for comparison
let previousPrices = {};
let previousChanges = {};
function injectHtml() {
const container = document.createElement('div');
container.innerHTML = `
${createCard({ id: 21, name: 'ذهب عيار 21' })}
${createCard({ id: 18, name: 'ذهب عيار 18' })}
${createCard({ id: 22, name: 'ذهب عيار 22' })}
${createCard({ id: 24, name: 'ذهب عيار 24', main: true })}
${createCard({ id: 'xau', name: 'ذهب أونصة', currency: 'دولار' })}
`;
document.body.prepend(container);
}
function createCard({
id,
name,
currency = '',
main = false,
silver = false,
}) {
return `
${name}
---
${currency}
▼
`;
}
function bindMobileToggle() {
const topBar = document.querySelector('.mfgp-top-bar');
const mainCard = document.querySelector('.mfgp-main-card');
const cards = topBar.querySelectorAll('.mfgp-card:not(.mfgp-main-card)');
if (!mainCard) return;
mainCard.addEventListener('click', (e) => {
e.stopPropagation();
const isOpen = topBar.classList.contains('mfgp-open');
if (isOpen) {
cards.forEach((c, i) =>
setTimeout(() => {
c.classList.remove('show-slide');
c.classList.add('hide-slide');
}, i * 40),
);
setTimeout(() => {
topBar.classList.remove('mfgp-open');
cards.forEach((c) => c.classList.remove('hide-slide'));
}, 400);
} else {
topBar.classList.add('mfgp-open');
cards.forEach((c, i) => {
c.classList.remove('hide-slide');
setTimeout(() => c.classList.add('show-slide'), i * 60);
});
}
});
}
function updateArrow(id, status) {
const arrow = document.querySelector(`#mfgp-card-${id} .mfgp-dynamic-arrow`);
if (!arrow) return;
arrow.style.display = 'block';
const color = status === 'up' ? '#00b208' : '#ff0000';
const paths =
status === 'up'
? `
`
: `
`;
arrow.innerHTML = paths;
}
function loadCachedData() {
try {
const cached = localStorage.getItem(CACHE_KEY);
if (cached) {
const { data } = JSON.parse(cached);
updateUI(data, false); // false = don't animate from cache
}
} catch (error) {
console.error('Error loading cached data:', error);
}
}
function determineStatus(id, newPrice, metalChanges) {
// For gold cards (not ounce), use the gold change
// For silver, use the silver change
// For ounces, use USD ounce changes
let change = 0;
if (id === 'xag') {
// Silver ounce
change = metalChanges.silver || 0;
} else if (id === 'xau') {
// Gold ounce
change = metalChanges.gold || 0;
} else {
// Gold gram prices (18, 21, 22, 24)
change = metalChanges.gold || 0;
}
if (change > 0) return 'up';
if (change < 0) return 'down';
return 'neutral';
}
function updateUI(data, animate = true) {
const prices = data.prices;
const changes = data.changes || {};
if (!prices) return;
Object.keys(priceMapping).forEach((id) => {
const { type, key } = priceMapping[id];
const priceValue = prices[type]?.[key];
if (priceValue === undefined || priceValue === null) return;
const priceElement = document.getElementById(`mfgp-price-${id}`);
const priceContainer = priceElement?.parentElement;
const card = document.getElementById(`mfgp-card-${id}`);
if (!priceElement || !priceContainer || !card) return;
const oldPrice = parseFloat(priceElement.textContent);
const newPrice = parseFloat(priceValue);
// Determine status based on changes from API
const status = determineStatus(id, newPrice, changes);
// Update the price text
priceElement.textContent = newPrice.toFixed(2);
// Update color classes based on status
priceContainer.classList.remove('mfgp-up', 'mfgp-down');
if (status === 'up') {
priceContainer.classList.add('mfgp-up');
} else if (status === 'down') {
priceContainer.classList.add('mfgp-down');
}
// Update arrow
updateArrow(id, status);
// Animate card if price changed and animation is enabled
if (animate && !isNaN(oldPrice) && oldPrice !== newPrice) {
// Remove existing animation classes
card.classList.remove('flash-up', 'flash-down');
// Force reflow to restart animation
void card.offsetWidth;
// Add appropriate flash animation
if (status === 'up') {
card.classList.add('flash-up');
} else if (status === 'down') {
card.classList.add('flash-down');
}
// Remove animation class after it completes
setTimeout(() => {
card.classList.remove('flash-up', 'flash-down');
}, 800);
}
// Store current price for next comparison
previousPrices[id] = newPrice;
});
// Store changes for next comparison
previousChanges = changes;
// Cache the data
try {
localStorage.setItem(
CACHE_KEY,
JSON.stringify({
data,
timestamp: Date.now(),
}),
);
} catch (error) {
console.error('Error caching data:', error);
}
}
async function fetchPrices() {
try {
const response = await fetch(API_ENDPOINT, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
// Validate response
if (!data.success || !data.prices) {
throw new Error('Invalid response format');
}
updateUI(data, true); // true = enable animations
} catch (error) {
console.error('Error fetching prices:', error);
// Try to load cached data on error
loadCachedData();
}
}