diff --git a/basicswap/static/js/offerstable.js b/basicswap/static/js/offerstable.js
index ecfc1bc..f861b7a 100644
--- a/basicswap/static/js/offerstable.js
+++ b/basicswap/static/js/offerstable.js
@@ -485,7 +485,8 @@ function fetchOffers(manualRefresh = false) {
created_at: Number(offer.created_at || 0),
expire_at: Number(offer.expire_at || 0),
is_own_offer: Boolean(offer.is_own_offer),
- amount_negotiable: Boolean(offer.amount_negotiable)
+ amount_negotiable: Boolean(offer.amount_negotiable),
+ unique_id: `${offer.offer_id}_${offer.created_at}_${offer.coin_from}_${offer.coin_to}`
}));
if (!isSentOffers) {
@@ -610,7 +611,7 @@ function filterAndSortData() {
const formData = new FormData(filterForm);
const filters = Object.fromEntries(formData);
- console.log('Raw filters:', filters);
+ console.log('Processed filters:', filters);
if (filters.coin_to !== 'any') {
filters.coin_to = coinIdToName[filters.coin_to] || filters.coin_to;
@@ -623,41 +624,49 @@ function filterAndSortData() {
const currentTime = Math.floor(Date.now() / 1000);
- let filteredData = originalJsonData.filter(offer => {
+ const uniqueOffersMap = new Map();
+
+ originalJsonData.forEach(offer => {
const coinFrom = (offer.coin_from || '').toLowerCase();
const coinTo = (offer.coin_to || '').toLowerCase();
const isExpired = offer.expire_at <= currentTime;
if (!isSentOffers && isExpired) {
- return false;
+ return;
}
+ let passesFilter = true;
+
if (isSentOffers) {
if (filters.coin_to !== 'any' && coinFrom.toLowerCase() !== filters.coin_to.toLowerCase()) {
- return false;
+ passesFilter = false;
}
if (filters.coin_from !== 'any' && coinTo.toLowerCase() !== filters.coin_from.toLowerCase()) {
- return false;
+ passesFilter = false;
}
} else {
if (filters.coin_to !== 'any' && coinTo.toLowerCase() !== filters.coin_to.toLowerCase()) {
- return false;
+ passesFilter = false;
}
if (filters.coin_from !== 'any' && coinFrom.toLowerCase() !== filters.coin_from.toLowerCase()) {
- return false;
+ passesFilter = false;
}
}
if (isSentOffers && filters.active && filters.active !== 'any') {
const offerState = isExpired ? 'expired' : 'active';
if (filters.active !== offerState) {
- return false;
+ passesFilter = false;
}
}
- return true;
+ if (passesFilter) {
+ uniqueOffersMap.set(offer.unique_id, offer);
+ }
});
+ let filteredData = Array.from(uniqueOffersMap.values());
+
console.log('Filtered data length:', filteredData.length);
const sortBy = filters.sort_by || 'created_at';
@@ -822,6 +831,7 @@ function prepareOfferData(offer, isSentOffers) {
};
}
+// to-do revoked
function getButtonProperties(isActuallyExpired, isSentOffers, isTreatedAsSentOffer, isRevoked) {
if (isRevoked) {
return {
@@ -865,8 +875,7 @@ function updateProfitLoss(row, fromCoin, toCoin, fromAmount, toAmount) {
const colorClass = getProfitColorClass(profitLossPercentage);
profitLossElement.textContent = `${profitLossPercentage > 0 ? '+' : ''}${profitLossPercentage}%`;
profitLossElement.className = `profit-loss text-lg font-bold ${colorClass}`;
-
- // Update the tooltip content
+
const tooltipId = `percentage-tooltip-${row.getAttribute('data-offer-id')}`;
const tooltipElement = document.getElementById(tooltipId);
if (tooltipElement) {
@@ -955,6 +964,7 @@ function getMarketRate(fromCoin, toCoin) {
});
}
+// todo
function getTimerColor(offer) {
const now = Math.floor(Date.now() / 1000);
const offerAge = now - offer.created_at;
@@ -1015,21 +1025,19 @@ function createDetailsColumn(offer) {
`;
}
-function createTakerAmountColumn(offer, coinFrom, coinTo) {
- const fromAmount = parseFloat(offer.amount_from);
+function createOrderbookColumn(offer, coinFrom, coinTo) {
+ const toAmount = parseFloat(offer.amount_to);
const fromSymbol = getCoinSymbol(coinFrom);
- const fromPriceUSD = latestPrices[coinNameToSymbol[coinFrom]]?.usd || 0;
- const fromValueUSD = fromAmount * fromPriceUSD;
-
return `
-
-
-
- ${fromAmount.toFixed(4)}
- ${coinFrom}
- USD: (${fromValueUSD.toFixed(2)})
-
-
+ |
+
|
`;
}
@@ -1053,19 +1061,16 @@ function createSwapColumn(offer, coinFrom, coinTo) {
`;
}
-function createOrderbookColumn(offer, coinTo, coinFrom) {
- const toAmount = parseFloat(offer.amount_to);
+function createTakerAmountColumn(offer, coinTo, coinFrom) {
+ const fromAmount = parseFloat(offer.amount_from);
const toSymbol = getCoinSymbol(coinTo);
- const toPriceUSD = latestPrices[coinNameToSymbol[coinTo]]?.usd || 0;
- const toValueUSD = toAmount * toPriceUSD;
return `
-
-
-
- ${toAmount.toFixed(4)}
+
@@ -1083,11 +1088,9 @@ function createRateColumn(offer, coinFrom, coinTo) {
const fromSymbol = getCoinSymbol(coinFrom);
const toSymbol = getCoinSymbol(coinTo);
- // Get USD prices
const fromPriceUSD = latestPrices[coinNameToSymbol[coinFrom]]?.usd || 0;
const toPriceUSD = latestPrices[coinNameToSymbol[coinTo]]?.usd || 0;
- // Calculate USD equivalent of the rate
const rateInUSD = rate * toPriceUSD;
console.log(`Rate calculation for ${fromSymbol} to ${toSymbol}:`);
@@ -1101,15 +1104,15 @@ function createRateColumn(offer, coinFrom, coinTo) {
-
+
+ $${rateInUSD.toFixed(2)}/${fromSymbol}
+
+
${rate.toFixed(6)} ${toSymbol}/${fromSymbol}
-
+
${inverseRate.toFixed(6)} ${fromSymbol}/${toSymbol}
-
- ($${rateInUSD.toFixed(2)})
-
|
@@ -1152,10 +1155,8 @@ function createTooltips(offer, isSentOffers, coinFrom, coinTo, postedTime, expir
const toPriceUSD = latestPrices[toSymbol]?.usd || 0;
const rateInUSD = rate * toPriceUSD;
-
const combinedRateTooltip = createCombinedRateTooltip(offer, coinFrom, coinTo);
-
const fromAmount = parseFloat(offer.amount_from);
const toAmount = parseFloat(offer.amount_to);
const percentageTooltipContent = createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmount);
@@ -1177,7 +1178,7 @@ function createTooltips(offer, isSentOffers, coinFrom, coinTo, postedTime, expir
@@ -1187,7 +1188,7 @@ function createTooltips(offer, isSentOffers, coinFrom, coinTo, postedTime, expir
@@ -1260,6 +1261,7 @@ function createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmou
"As a buyer, a positive percentage indicates potential savings compared to current market rates."}
`;
}
+
function createCombinedRateTooltip(offer, coinFrom, coinTo) {
const rate = parseFloat(offer.rate);
const inverseRate = 1 / rate;
diff --git a/basicswap/static/js/pricechart.js b/basicswap/static/js/pricechart.js
index 985207b..50a91a2 100644
--- a/basicswap/static/js/pricechart.js
+++ b/basicswap/static/js/pricechart.js
@@ -866,69 +866,75 @@ const app = {
},
init: () => {
- window.addEventListener('load', app.onLoad);
- app.loadLastRefreshedTime();
- },
-
- onLoad: async () => {
- ui.showLoader();
- try {
- volumeToggle.init();
- await app.updateBTCPrice();
- const chartContainer = document.getElementById('coin-chart');
- if (chartContainer) {
- chartModule.initChart();
- chartModule.showChartLoader();
- } else {
- console.warn('Chart container not found, skipping chart initialization');
- }
- for (const coin of config.coins) {
- await app.loadCoinData(coin);
- }
- 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);
- }
- });
+ window.addEventListener('load', async () => {
+ ui.showLoader();
+ try {
+ volumeToggle.init();
+ await app.updateBTCPrice();
+
+ chartModule.initChart();
+ chartModule.showChartLoader();
+ } else {
+ console.warn('Chart container not found, skipping chart initialization');
+ }
+
+ const coinDataPromises = config.coins.map(coin => app.loadCoinData(coin));
+ await Promise.all(coinDataPromises);
+
+ if (chartModule.chart) {
+ config.currentResolution = 'month';
+ await chartModule.updateChart('BTC');
+ app.updateResolutionButtons('BTC');
+ }
+
+ ui.setActiveContainer('btc-container');
+
+ // Set up event listeners for coin containers
+ 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);
+ }
+ });
+ }
+ });
+
+ app.initializeSelectImages();
+ app.initAutoRefresh();
+
+ 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);
+ }
+
+ } catch (error) {
+ console.error('Error during initialization:', error);
+ ui.displayErrorMessage('Failed to initialize the dashboard. Please try refreshing the page.');
+ } finally {
+ ui.hideLoader();
+ if (chartModule.chart) {
+ chartModule.hideChartLoader();
}
- });
- const refreshAllButton = document.getElementById('refresh-all');
- if (refreshAllButton) {
- refreshAllButton.addEventListener('click', app.refreshAllData);
}
- 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.');
- } finally {
- ui.hideLoader();
- if (chartModule.chart) {
- chartModule.hideChartLoader();
- }
- }
+ });
+ app.loadLastRefreshedTime();
},
loadCoinData: async (coin) => {
diff --git a/basicswap/templates/offers.html b/basicswap/templates/offers.html
index 6681e08..5ee178a 100644
--- a/basicswap/templates/offers.html
+++ b/basicswap/templates/offers.html
@@ -195,7 +195,6 @@ function getAPIKeys() {
{% endif %}
-
@@ -208,34 +207,69 @@ function getAPIKeys() {
-
-
-
- {{ input_arrow_down_svg | safe }}
-
-
-
-
- {{ arrow_right_svg | safe }}
+ {% if sent_offers %}
+
+
+
+ {{ input_arrow_down_svg | safe }}
+
-
-
-
-
- {{ input_arrow_down_svg | safe }}
-
-
-
+
+
+
+ {{ arrow_right_svg | safe }}
+
+
+
+
+
+ {{ input_arrow_down_svg | safe }}
+
+
+
+ {% else %}
+
+
+
+
+
+ {{ input_arrow_down_svg | safe }}
+
+
+
+
+ {{ arrow_right_svg | safe }}
+
+
+
+
+
+ {{ input_arrow_down_svg | safe }}
+
+
+
+ {% endif %}
@@ -287,7 +321,7 @@ function getAPIKeys() {
-
+
@@ -334,7 +368,9 @@ function getAPIKeys() {
-
+
+
+
|