From 376b485261410519008ad9e6416698836f33e5bd Mon Sep 17 00:00:00 2001 From: gerlofvanek Date: Sat, 12 Oct 2024 21:37:51 +0200 Subject: [PATCH] ui: Fixes --- basicswap/static/js/offerstable.js | 63 ++++----- basicswap/static/js/pricechart.js | 148 ++++++++++--------- basicswap/templates/offers.html | 219 +++++++++-------------------- 3 files changed, 177 insertions(+), 253 deletions(-) diff --git a/basicswap/static/js/offerstable.js b/basicswap/static/js/offerstable.js index f861b7a..ccb62fc 100644 --- a/basicswap/static/js/offerstable.js +++ b/basicswap/static/js/offerstable.js @@ -637,20 +637,11 @@ function filterAndSortData() { let passesFilter = true; - if (isSentOffers) { - if (filters.coin_to !== 'any' && coinFrom.toLowerCase() !== filters.coin_to.toLowerCase()) { - passesFilter = false; - } - if (filters.coin_from !== 'any' && coinTo.toLowerCase() !== filters.coin_from.toLowerCase()) { - passesFilter = false; - } - } else { - if (filters.coin_to !== 'any' && coinTo.toLowerCase() !== filters.coin_to.toLowerCase()) { - passesFilter = false; - } - if (filters.coin_from !== 'any' && coinFrom.toLowerCase() !== filters.coin_from.toLowerCase()) { - passesFilter = false; - } + if (filters.coin_to !== 'any' && coinTo.toLowerCase() !== filters.coin_to.toLowerCase()) { + passesFilter = false; + } + if (filters.coin_from !== 'any' && coinFrom.toLowerCase() !== filters.coin_from.toLowerCase()) { + passesFilter = false; } if (isSentOffers && filters.active && filters.active !== 'any') { @@ -939,7 +930,7 @@ function getProfitColorClass(percentage) { const numericPercentage = parseFloat(percentage); if (numericPercentage > 0) return 'text-green-500'; if (numericPercentage < 0) return 'text-red-500'; - if (numericPercentage === 0) return 'text-yellowr-400'; + if (numericPercentage === 0) return 'text-yellow-400'; return 'text-white'; } @@ -1025,16 +1016,16 @@ function createDetailsColumn(offer) { `; } -function createOrderbookColumn(offer, coinFrom, coinTo) { +function createTakerAmountColumn(offer, coinTo, coinFrom) { const toAmount = parseFloat(offer.amount_to); const fromSymbol = getCoinSymbol(coinFrom); return ` -
- + @@ -1042,7 +1033,7 @@ function createOrderbookColumn(offer, coinFrom, coinTo) { `; } -function createSwapColumn(offer, coinFrom, coinTo) { +function createSwapColumn(offer, coinTo, coinFrom) { return ` @@ -1061,16 +1052,16 @@ function createSwapColumn(offer, coinFrom, coinTo) { `; } -function createTakerAmountColumn(offer, coinTo, coinFrom) { +function createOrderbookColumn(offer, coinFrom, coinTo) { const fromAmount = parseFloat(offer.amount_from); const toSymbol = getCoinSymbol(coinTo); return ` -
+ @@ -1101,17 +1092,17 @@ function createRateColumn(offer, coinFrom, coinTo) { console.log(`Rate in USD: $${rateInUSD.toFixed(2)}`); return ` - +
-
- - $${rateInUSD.toFixed(2)}/${fromSymbol} +
+ + $${rateInUSD.toFixed(2)} USD - - ${rate.toFixed(6)} ${toSymbol}/${fromSymbol} + + ${rate.toFixed(8)} ${toSymbol}/${fromSymbol} - - ${inverseRate.toFixed(6)} ${fromSymbol}/${toSymbol} + + ${inverseRate.toFixed(8)} ${fromSymbol}/${toSymbol}
@@ -1183,7 +1174,7 @@ function createTooltips(offer, isSentOffers, coinFrom, coinTo, postedTime, expir
@@ -1283,14 +1274,14 @@ function createCombinedRateTooltip(offer, coinFrom, coinTo) {

Exchange Rate Explanation:

This offer is ${action} ${coinFrom} for ${coinTo}
at a rate that is ${Math.abs(percentDiff).toFixed(2)}% ${aboveOrBelow} market price.

Exchange Rates:

-

1 ${coinFrom} = ${rate.toFixed(6)} ${toSymbol}

-

1 ${coinTo} = ${inverseRate.toFixed(6)} ${fromSymbol}

+

1 ${coinFrom} = ${rate.toFixed(8)} ${coinTo}

+

1 ${coinTo} = ${inverseRate.toFixed(8)} ${coinFrom}

USD Equivalent:

1 ${coinFrom} = $${rateInUSD.toFixed(2)} USD

Current market prices:

${coinFrom}: $${fromPriceUSD.toFixed(2)} USD

${coinTo}: $${toPriceUSD.toFixed(2)} USD

-

Market rate: 1 ${coinFrom} = ${marketRate.toFixed(6)} ${toSymbol}

+

Market rate: 1 ${coinFrom} = ${marketRate.toFixed(8)} ${coinTo}

`; } @@ -1646,8 +1637,6 @@ document.addEventListener('DOMContentLoaded', () => { document.getElementById('coin_to').addEventListener('change', applyFilters); document.getElementById('coin_from').addEventListener('change', applyFilters); - document.getElementById('sort_by').addEventListener('change', applyFilters); - document.getElementById('sort_dir').addEventListener('change', applyFilters); document.getElementById('clearFilters').addEventListener('click', () => { filterForm.reset(); diff --git a/basicswap/static/js/pricechart.js b/basicswap/static/js/pricechart.js index 5583f7d..03fce34 100644 --- a/basicswap/static/js/pricechart.js +++ b/basicswap/static/js/pricechart.js @@ -209,7 +209,7 @@ fetchHistoricalDataXHR: (coinSymbol) => { // Cache const cache = { - ttl: 15 * 60 * 1000, + ttl: 15 * 60 * 1000, // 15 minutes in milliseconds set: (key, value, customTtl = null) => { const item = { value: value, @@ -858,7 +858,7 @@ const app = { autoRefreshInterval: null, nextRefreshTime: null, lastRefreshedTime: null, - isAutoRefreshEnabled: localStorage.getItem('autoRefreshEnabled') === 'true', + isAutoRefreshEnabled: localStorage.getItem('autoRefreshEnabled') !== 'false', refreshTexts: { label: 'Auto-refresh in', disabled: 'Auto-refresh: disabled', @@ -868,6 +868,7 @@ const app = { init: () => { window.addEventListener('load', app.onLoad); app.loadLastRefreshedTime(); + app.updateAutoRefreshButton(); }, onLoad: async () => { @@ -882,44 +883,22 @@ const app = { } else { console.warn('Chart container not found, skipping chart initialization'); } - for (const coin of config.coins) { - await app.loadCoinData(coin); - } + + // Load all coin data immediately + await app.loadAllCoinData(); + if (chartModule.chart) { config.currentResolution = 'month'; await chartModule.updateChart('BTC'); app.updateResolutionButtons('BTC'); } ui.setActiveContainer('btc-container'); - config.coins.forEach(coin => { - const container = document.getElementById(`${coin.symbol.toLowerCase()}-container`); - if (container) { - container.addEventListener('click', () => { - ui.setActiveContainer(`${coin.symbol.toLowerCase()}-container`); - if (chartModule.chart) { - if (coin.symbol === 'WOW') { - config.currentResolution = 'day'; - } - chartModule.updateChart(coin.symbol); - app.updateResolutionButtons(coin.symbol); - } - }); - } - }); - const refreshAllButton = document.getElementById('refresh-all'); - if (refreshAllButton) { - refreshAllButton.addEventListener('click', app.refreshAllData); - } + + // Set up event listeners and other initializations + app.setupEventListeners(); app.initializeSelectImages(); - const headers = document.querySelectorAll('th'); - headers.forEach((header, index) => { - header.addEventListener('click', () => app.sortTable(index, header.classList.contains('disabled'))); - }); - const closeErrorButton = document.getElementById('close-error'); - if (closeErrorButton) { - closeErrorButton.addEventListener('click', ui.hideErrorMessage); - } app.initAutoRefresh(); + } catch (error) { console.error('Error during initialization:', error); ui.displayErrorMessage('Failed to initialize the dashboard. Please try refreshing the page.'); @@ -930,7 +909,13 @@ const app = { } } }, - + + loadAllCoinData: async () => { + for (const coin of config.coins) { + await app.loadCoinData(coin); + } + }, + loadCoinData: async (coin) => { const cacheKey = `coinData_${coin.symbol}`; let cachedData = cache.get(cacheKey); @@ -962,6 +947,39 @@ const app = { ui.displayCoinData(coin.symbol, data); ui.updateLoadTimeAndCache(0, cachedData); }, + + setupEventListeners: () => { + config.coins.forEach(coin => { + const container = document.getElementById(`${coin.symbol.toLowerCase()}-container`); + if (container) { + container.addEventListener('click', () => { + ui.setActiveContainer(`${coin.symbol.toLowerCase()}-container`); + if (chartModule.chart) { + if (coin.symbol === 'WOW') { + config.currentResolution = 'day'; + } + chartModule.updateChart(coin.symbol); + app.updateResolutionButtons(coin.symbol); + } + }); + } + }); + + const refreshAllButton = document.getElementById('refresh-all'); + if (refreshAllButton) { + refreshAllButton.addEventListener('click', app.refreshAllData); + } + + const headers = document.querySelectorAll('th'); + headers.forEach((header, index) => { + header.addEventListener('click', () => app.sortTable(index, header.classList.contains('disabled'))); + }); + + const closeErrorButton = document.getElementById('close-error'); + if (closeErrorButton) { + closeErrorButton.addEventListener('click', ui.hideErrorMessage); + } + }, initAutoRefresh: () => { const toggleAutoRefreshButton = document.getElementById('toggle-auto-refresh'); @@ -990,13 +1008,13 @@ const app = { app.stopAutoRefresh(); if (resetTimer || !app.nextRefreshTime) { - app.nextRefreshTime = Date.now() + 15 * 60 * 1000; + app.nextRefreshTime = Date.now() + cache.ttl; } const timeUntilNextRefresh = Math.max(0, app.nextRefreshTime - Date.now()); if (timeUntilNextRefresh === 0) { - app.nextRefreshTime = Date.now() + 15 * 60 * 1000; + app.nextRefreshTime = Date.now() + cache.ttl; } app.autoRefreshInterval = setTimeout(() => { @@ -1061,37 +1079,37 @@ const app = { }, updateAutoRefreshButton: () => { - const button = document.getElementById('toggle-auto-refresh'); - if (button) { - if (app.isAutoRefreshEnabled) { - button.classList.remove('text-gray-600', 'dark:text-gray-400'); - button.classList.add('text-green-500', 'dark:text-green-400'); - app.startSpinAnimation(); - } else { - button.classList.remove('text-green-500', 'dark:text-green-400'); - button.classList.add('text-gray-600', 'dark:text-gray-400'); - app.stopSpinAnimation(); + const button = document.getElementById('toggle-auto-refresh'); + if (button) { + if (app.isAutoRefreshEnabled) { + button.classList.remove('text-gray-600', 'dark:text-gray-400'); + button.classList.add('text-green-500', 'dark:text-green-400'); + app.startSpinAnimation(); + } else { + button.classList.remove('text-green-500', 'dark:text-green-400'); + button.classList.add('text-gray-600', 'dark:text-gray-400'); + app.stopSpinAnimation(); + } + button.title = app.isAutoRefreshEnabled ? 'Disable Auto-Refresh' : 'Enable Auto-Refresh'; } - button.title = app.isAutoRefreshEnabled ? 'Disable Auto-Refresh' : 'Enable Auto-Refresh'; - } -}, + }, -startSpinAnimation: () => { - const svg = document.querySelector('#toggle-auto-refresh svg'); - if (svg) { - svg.classList.add('animate-spin'); - setTimeout(() => { + startSpinAnimation: () => { + const svg = document.querySelector('#toggle-auto-refresh svg'); + if (svg) { + svg.classList.add('animate-spin'); + setTimeout(() => { + svg.classList.remove('animate-spin'); + }, 2000); + } + }, + + stopSpinAnimation: () => { + const svg = document.querySelector('#toggle-auto-refresh svg'); + if (svg) { svg.classList.remove('animate-spin'); - }, 2000); // Remove the animation after 2 seconds - } -}, - -stopSpinAnimation: () => { - const svg = document.querySelector('#toggle-auto-refresh svg'); - if (svg) { - svg.classList.remove('animate-spin'); - } -}, + } + }, refreshAllData: async () => { ui.showLoader(); @@ -1099,9 +1117,7 @@ stopSpinAnimation: () => { try { cache.clear(); await app.updateBTCPrice(); - for (const coin of config.coins) { - await app.loadCoinData(coin); - } + await app.loadAllCoinData(); if (chartModule.currentCoin) { await chartModule.updateChart(chartModule.currentCoin, true); } diff --git a/basicswap/templates/offers.html b/basicswap/templates/offers.html index 5ee178a..3790b16 100644 --- a/basicswap/templates/offers.html +++ b/basicswap/templates/offers.html @@ -142,24 +142,25 @@ function getAPIKeys() {
-
- {% set coin_data = { - 'BTC': {'name': 'Bitcoin', 'symbol': 'BTC', 'image': 'Bitcoin.png', 'show': true}, - 'XMR': {'name': 'Monero', 'symbol': 'XMR', 'image': 'Monero.png', 'show': true}, - 'PART': {'name': 'Particl', 'symbol': 'PART', 'image': 'Particl.png', 'show': true}, - 'LTC': {'name': 'Litecoin', 'symbol': 'LTC', 'image': 'Litecoin.png', 'show': true}, - 'FIRO': {'name': 'Firo', 'symbol': 'FIRO', 'image': 'Firo.png', 'show': true}, - 'PIVX': {'name': 'PIVX', 'symbol': 'PIVX', 'image': 'PIVX.png', 'show': true}, - 'DASH': {'name': 'Dash', 'symbol': 'DASH', 'image': 'Dash.png', 'show': true}, - 'ETH': {'name': 'Ethereum', 'symbol': 'ETH', 'image': 'Ethereum.png', 'show': false}, - 'DOGE': {'name': 'Dogecoin', 'symbol': 'DOGE', 'image': 'Doge.png', 'show': false}, - 'DCR': {'name': 'Decred', 'symbol': 'DCR', 'image': 'Decred.png', 'show': true}, - 'ZANO': {'name': 'Zano', 'symbol': 'ZANO', 'image': 'Zano.png', 'show': false}, - 'BCH': {'name': 'BCH', 'symbol': 'BCH', 'image': 'Bitcoin-cash.png', 'show': true}, - 'WOW': {'name': 'Wownero', 'symbol': 'WOW', 'image': 'Wownero.png', 'show': true} -} %} +
+ {% set coin_data = { + 'BTC': {'name': 'Bitcoin', 'symbol': 'BTC', 'image': 'Bitcoin.png', 'show': true}, + 'XMR': {'name': 'Monero', 'symbol': 'XMR', 'image': 'Monero.png', 'show': true}, + 'PART': {'name': 'Particl', 'symbol': 'PART', 'image': 'Particl.png', 'show': true}, + 'LTC': {'name': 'Litecoin', 'symbol': 'LTC', 'image': 'Litecoin.png', 'show': true}, + 'FIRO': {'name': 'Firo', 'symbol': 'FIRO', 'image': 'Firo.png', 'show': true}, + 'PIVX': {'name': 'PIVX', 'symbol': 'PIVX', 'image': 'PIVX.png', 'show': true}, + 'DASH': {'name': 'Dash', 'symbol': 'DASH', 'image': 'Dash.png', 'show': true}, + 'ETH': {'name': 'Ethereum', 'symbol': 'ETH', 'image': 'Ethereum.png', 'show': false}, + 'DOGE': {'name': 'Dogecoin', 'symbol': 'DOGE', 'image': 'Doge.png', 'show': false}, + 'DCR': {'name': 'Decred', 'symbol': 'DCR', 'image': 'Decred.png', 'show': true}, + 'ZANO': {'name': 'Zano', 'symbol': 'ZANO', 'image': 'Zano.png', 'show': false}, + 'BCH': {'name': 'BCH', 'symbol': 'BCH', 'image': 'Bitcoin-cash.png', 'show': true}, + 'WOW': {'name': 'Wownero', 'symbol': 'WOW', 'image': 'Wownero.png', 'show': true} + } + %} {% for coin_symbol, coin in coin_data.items() if coin_symbol in enabled_chart_coins and coin.show %} -
+
{{ coin.name }} @@ -204,144 +205,48 @@ function getAPIKeys() {
-
-
-
- {% if sent_offers %} - - -
- {{ input_arrow_down_svg | safe }} - -
- -
-
-

{{ arrow_right_svg | safe }}

+
+
+
+
+
+ +
+ {{ input_arrow_down_svg | safe }} + +
+
+
+

{{ arrow_right_svg | safe }}

+
+
+ +
+ {{ input_arrow_down_svg | safe }} +
- - -
- {{ input_arrow_down_svg | safe }} - -
-
- {% else %} -
-
- - -
- {{ input_arrow_down_svg | safe }} - -
-
-
-

{{ arrow_right_svg | safe }}

-
-
- - -
- {{ input_arrow_down_svg | safe }} - -
-
- {% endif %} -
-
-
-

Sort By:

-
-
-
-
- {{ input_arrow_down_svg | safe }} - -
-
-
-
- {{ input_arrow_down_svg | safe }} - -
-
- - - {% if sent_offers %} -
-
-

State:

-
-
- {{ input_arrow_down_svg | safe }} - -
-
- {% endif %} -
+
+
- -
+
-
+
- - - +
+ {% if sent_offers %}
- Max send + Max Recv
+ {% else %} + +
+ Max Send +
+ + {% endif %}
Swap
+ {% if sent_offers %} + +
+ Your Liq. +
+ + {% else %}
Max Recv
+ {% endif %}
Rate