ui: Wallets page JS refactor / one API call for all coin prices.

This commit is contained in:
gerlofvanek
2024-11-15 18:38:49 +01:00
committed by tecnovert
parent 2983238ef5
commit 6e0f6dabe4

View File

@@ -216,131 +216,86 @@ const api = {
xhr.timeout = 30000; xhr.timeout = 30000;
xhr.ontimeout = () => reject(new Error('Request timed out')); xhr.ontimeout = () => reject(new Error('Request timed out'));
xhr.onload = () => { xhr.onload = () => {
console.log(`Response for ${url}:`, xhr.responseText);
if (xhr.status === 200) { if (xhr.status === 200) {
try { try {
const response = JSON.parse(xhr.responseText); const response = JSON.parse(xhr.responseText);
if (response.Error) { if (response.Error) {
console.error(`API Error for ${url}:`, response.Error);
reject(new Error(response.Error)); reject(new Error(response.Error));
} else { } else {
resolve(response); resolve(response);
} }
} catch (error) { } catch (error) {
console.error(`Invalid JSON response for ${url}:`, xhr.responseText);
reject(new Error(`Invalid JSON response: ${error.message}`)); reject(new Error(`Invalid JSON response: ${error.message}`));
} }
} else { } else {
console.error(`HTTP Error for ${url}: ${xhr.status} ${xhr.statusText}`);
reject(new Error(`HTTP Error: ${xhr.status} ${xhr.statusText}`)); reject(new Error(`HTTP Error: ${xhr.status} ${xhr.statusText}`));
} }
}; };
xhr.onerror = () => reject(new Error('Network error occurred')); xhr.onerror = () => reject(new Error('Network error occurred'));
xhr.send(JSON.stringify({ xhr.send(JSON.stringify({ url, headers }));
url: url,
headers: headers
}));
}); });
}, },
}; };
const coinNameToSymbol = { const coinNameToSymbol = {
'Bitcoin': 'BTC', 'Bitcoin': 'bitcoin',
'Particl': 'PART', 'Particl': 'particl',
'Particl Blind': 'PART', 'Particl Blind': 'particl',
'Particl Anon': 'PART', 'Particl Anon': 'particl',
'Monero': 'XMR', 'Monero': 'monero',
'Wownero': 'WOW', 'Wownero': 'wownero',
'Litecoin': 'LTC', 'Litecoin': 'litecoin',
'Firo': 'FIRO', 'Firo': 'zcoin',
'Dash': 'DASH', 'Dash': 'dash',
'PIVX': 'PIVX', 'PIVX': 'pivx',
'Decred': 'DCR', 'Decred': 'decred',
'Zano': 'ZANO', 'Zano': 'zano',
'Bitcoin Cash': 'BCH', 'Bitcoin Cash': 'bitcoin-cash'
}; };
const getUsdValue = async (cryptoValue, coinSymbol) => { async function updatePrices() {
let apiUrl;
if (coinSymbol === 'WOW') {
apiUrl = 'https://api.coingecko.com/api/v3/simple/price?ids=wownero&vs_currencies=usd';
} else {
apiUrl = `https://min-api.cryptocompare.com/data/price?fsym=${coinSymbol}&tsyms=USD`;
}
try { try {
const data = await api.makePostRequest(apiUrl); const response = await api.makePostRequest(
'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,bitcoin-cash,dash,dogecoin,decred,litecoin,particl,pivx,monero,zano,wownero,zcoin&vs_currencies=USD,BTC'
);
if (coinSymbol === 'WOW') { document.querySelectorAll('.coinname-value').forEach(el => {
const exchangeRate = data.wownero.usd; const coinName = el.getAttribute('data-coinname');
if (!isNaN(exchangeRate)) { const amount = parseFloat(el.textContent);
return { const coinId = coinNameToSymbol[coinName];
usdValue: cryptoValue * exchangeRate, const price = response[coinId]?.usd;
btcValue: cryptoValue / exchangeRate
}; if (price && !isNaN(amount)) {
} else { const usdValue = (amount * price).toFixed(2);
throw new Error(`Invalid exchange rate for ${coinSymbol}`); const usdEl = el.closest('.flex').nextElementSibling?.querySelector('.usd-value');
if (usdEl && localStorage.getItem('usdAmountVisible') === 'true') {
usdEl.textContent = `$${usdValue}`;
}
} }
} else { });
const exchangeRate = data.USD;
if (!isNaN(exchangeRate)) { if (localStorage.getItem('usdAmountVisible') === 'true') {
return { const total = Array.from(document.querySelectorAll('.usd-value'))
usdValue: cryptoValue * exchangeRate, .reduce((sum, el) => sum + (parseFloat(el.textContent?.replace('$', '')) || 0), 0);
btcValue: cryptoValue / exchangeRate
}; const totalUsdEl = document.getElementById('total-usd-value');
} else { if (totalUsdEl) {
throw new Error(`Invalid exchange rate for ${coinSymbol}`); totalUsdEl.textContent = `$${total.toFixed(2)}`;
}
const btcPrice = response.bitcoin?.usd;
if (btcPrice) {
const btcTotal = total / btcPrice;
const totalBtcEl = document.getElementById('total-btc-value');
if (totalBtcEl) {
totalBtcEl.textContent = `~ ${btcTotal.toFixed(8)} BTC`;
}
} }
} }
} catch (error) { } catch (error) {
console.error(`Error retrieving exchange rate for ${coinSymbol}:`, error); console.error('Price update failed:', error);
throw error;
} }
}; }
const toggleUsdAmount = async (usdCell, isVisible) => {
const usdText = document.getElementById('usd-text');
if (usdText) {
usdText.style.display = isVisible ? 'inline' : 'none';
}
if (isVisible) {
const coinNameValueElement = usdCell.parentElement.querySelector('.coinname-value');
if (coinNameValueElement) {
const coinFullName = coinNameValueElement.getAttribute('data-coinname');
console.log("coinFullName:", coinFullName);
if (coinFullName) {
const cryptoValue = parseFloat(coinNameValueElement.textContent);
console.log("cryptoValue:", cryptoValue);
const coinSymbol = coinNameToSymbol[coinFullName.trim()];
console.log("coinSymbol:", coinSymbol);
if (coinSymbol) {
await updateValues();
} else {
console.error(`Coin symbol not found for full name: ${coinFullName}`);
}
} else {
console.error(`Data attribute 'data-coinname' not found.`);
}
} else {
}
} else {
usdCell.textContent = "******";
const btcValueElement = usdCell.nextElementSibling;
if (btcValueElement) {
btcValueElement.textContent = "****";
}
}
};
const toggleUsdIcon = (isVisible) => { const toggleUsdIcon = (isVisible) => {
const usdIcon = document.querySelector("#hide-usd-amount-toggle svg"); const usdIcon = document.querySelector("#hide-usd-amount-toggle svg");
@@ -359,85 +314,28 @@ const toggleUsdIcon = (isVisible) => {
} }
}; };
const calculateTotalUsdValue = async () => { const toggleUsdAmount = (usdCell, isVisible) => {
const coinNameValues = document.querySelectorAll('.coinname-value'); const usdText = document.getElementById('usd-text');
let totalUsdValue = 0; if (usdText) {
usdText.style.display = isVisible ? 'inline' : 'none';
for (const coinNameValue of coinNameValues) {
const coinFullName = coinNameValue.getAttribute('data-coinname');
const cryptoValue = parseFloat(coinNameValue.textContent);
const coinSymbol = coinNameToSymbol[coinFullName];
if (coinSymbol) {
try {
const { usdValue } = await getUsdValue(cryptoValue, coinSymbol);
totalUsdValue += usdValue;
const usdValueElement = coinNameValue.parentElement.nextElementSibling.querySelector('.usd-value');
if (usdValueElement) {
usdValueElement.textContent = `$${usdValue.toFixed(2)}`;
}
} catch (error) {
console.error(`Error retrieving exchange rate for ${coinSymbol}`);
}
} else {
console.error(`Coin symbol not found for full name: ${coinFullName}`);
}
}
const totalUsdValueElement = document.getElementById('total-usd-value');
if (totalUsdValueElement) {
totalUsdValueElement.textContent = `$${totalUsdValue.toFixed(2)}`;
}
};
const calculateTotalBtcValue = async () => {
const usdValueElements = document.getElementsByClassName('usd-value');
let totalBtcValue = 0;
try {
const data = await api.makePostRequest('https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD');
const btcToUsdRate = data.USD;
for (const usdValueElement of usdValueElements) {
const usdValue = parseFloat(usdValueElement.textContent.replace('$', ''));
const btcValue = usdValue / btcToUsdRate;
if (!isNaN(btcValue)) {
totalBtcValue += btcValue;
} else {
console.error(`Invalid USD value: ${usdValue}`);
}
}
const totalBtcValueElement = document.getElementById('total-btc-value');
if (totalBtcValueElement) {
if (localStorage.getItem('usdAmountVisible') === 'false') {
totalBtcValueElement.textContent = "****";
} else {
totalBtcValueElement.textContent = `~ ${totalBtcValue.toFixed(8)} BTC`;
}
}
} catch (error) {
console.error(`Error retrieving BTC to USD exchange rate:`, error);
} }
}; };
const loadUsdAmountVisibility = async () => { const loadUsdAmountVisibility = async () => {
let usdAmountVisible = localStorage.getItem('usdAmountVisible') === 'true'; const usdAmountVisible = localStorage.getItem('usdAmountVisible') === 'true';
toggleUsdIcon(usdAmountVisible); toggleUsdIcon(usdAmountVisible);
const usdValueElements = document.getElementsByClassName('usd-value'); const usdValueElements = document.getElementsByClassName('usd-value');
for (const usdValueElement of usdValueElements) { for (const usdValueElement of usdValueElements) {
toggleUsdAmount(usdValueElement, usdAmountVisible, !usdAmountVisible); toggleUsdAmount(usdValueElement, usdAmountVisible);
} }
const totalUsdValueElement = document.getElementById('total-usd-value'); const totalUsdValueElement = document.getElementById('total-usd-value');
if (!usdAmountVisible && totalUsdValueElement) { if (!usdAmountVisible && totalUsdValueElement) {
totalUsdValueElement.textContent = "*****"; totalUsdValueElement.textContent = "*****";
} else if (usdAmountVisible && totalUsdValueElement) { document.getElementById('total-btc-value').textContent = "****";
await calculateTotalUsdValue(); } else if (usdAmountVisible) {
calculateTotalBtcValue(); updatePrices();
} }
}; };
@@ -445,10 +343,9 @@ window.onload = async () => {
const hideUsdAmountToggle = document.getElementById('hide-usd-amount-toggle'); const hideUsdAmountToggle = document.getElementById('hide-usd-amount-toggle');
let usdAmountVisible = localStorage.getItem('usdAmountVisible') === 'true'; let usdAmountVisible = localStorage.getItem('usdAmountVisible') === 'true';
hideUsdAmountToggle.addEventListener('click', async () => { hideUsdAmountToggle?.addEventListener('click', () => {
usdAmountVisible = !usdAmountVisible; usdAmountVisible = !usdAmountVisible;
localStorage.setItem('usdAmountVisible', usdAmountVisible); localStorage.setItem('usdAmountVisible', usdAmountVisible);
toggleUsdIcon(usdAmountVisible); toggleUsdIcon(usdAmountVisible);
const usdValueElements = document.getElementsByClassName('usd-value'); const usdValueElements = document.getElementsByClassName('usd-value');
@@ -456,22 +353,17 @@ window.onload = async () => {
toggleUsdAmount(usdValueElement, usdAmountVisible); toggleUsdAmount(usdValueElement, usdAmountVisible);
} }
const totalUsdValueElement = document.getElementById('total-usd-value'); if (usdAmountVisible) {
if (!usdAmountVisible && totalUsdValueElement) { updatePrices();
totalUsdValueElement.textContent = "*****"; } else {
} else if (usdAmountVisible && totalUsdValueElement) { document.querySelectorAll('.usd-value').forEach(el => el.textContent = '******');
await calculateTotalUsdValue(); document.getElementById('total-usd-value').textContent = '*****';
} document.getElementById('total-btc-value').textContent = '****';
const totalBtcValueElement = document.getElementById('total-btc-value');
if (!usdAmountVisible && totalBtcValueElement) {
totalBtcValueElement.textContent = "";
} else if (usdAmountVisible && totalBtcValueElement) {
await calculateTotalBtcValue();
} }
}); });
await loadUsdAmountVisibility(); await loadUsdAmountVisibility();
setInterval(updatePrices, 300000);
}; };
</script> </script>
</body> </body>