mirror of
https://github.com/basicswap/basicswap.git
synced 2025-11-06 02:38:11 +01:00
ui: Wallets page JS refactor / one API call for all coin prices.
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user