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 780347d..5583f7d 100644
--- a/basicswap/static/js/pricechart.js
+++ b/basicswap/static/js/pricechart.js
@@ -1061,27 +1061,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');
- } else {
- button.classList.remove('text-green-500', 'dark:text-green-400');
- button.classList.add('text-gray-600', 'dark:text-gray-400');
- }
- button.title = app.isAutoRefreshEnabled ? 'Disable Auto-Refresh' : 'Enable Auto-Refresh';
-
- const svg = button.querySelector('svg');
- if (svg) {
- if (app.isAutoRefreshEnabled) {
- svg.classList.add('animate-spin');
- } else {
- svg.classList.remove('animate-spin');
- }
- }
+ 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';
+ }
+},
+
+startSpinAnimation: () => {
+ const svg = document.querySelector('#toggle-auto-refresh svg');
+ if (svg) {
+ svg.classList.add('animate-spin');
+ setTimeout(() => {
+ 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();
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() {
-
+
+
+
|