mirror of
https://github.com/basicswap/basicswap.git
synced 2025-11-05 10:28:10 +01:00
Fixed identity tooltips on bids page + removed bottleneck offers page.
This commit is contained in:
@@ -918,6 +918,12 @@ const forceTooltipDOMCleanup = () => {
|
|||||||
foundCount += allTooltipElements.length;
|
foundCount += allTooltipElements.length;
|
||||||
|
|
||||||
allTooltipElements.forEach(element => {
|
allTooltipElements.forEach(element => {
|
||||||
|
const isInTooltipContainer = element.closest('.tooltip-container');
|
||||||
|
|
||||||
|
if (isInTooltipContainer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const isDetached = !document.body.contains(element) ||
|
const isDetached = !document.body.contains(element) ||
|
||||||
element.classList.contains('hidden') ||
|
element.classList.contains('hidden') ||
|
||||||
element.style.display === 'none';
|
element.style.display === 'none';
|
||||||
@@ -1138,7 +1144,7 @@ const createTableRow = async (bid) => {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `
|
const rowHtml = `
|
||||||
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
||||||
<!-- Time Column -->
|
<!-- Time Column -->
|
||||||
<td class="py-3 pl-6 pr-3">
|
<td class="py-3 pl-6 pr-3">
|
||||||
@@ -1224,13 +1230,16 @@ const createTableRow = async (bid) => {
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
<!-- Tooltips -->
|
const tooltipIdentityHtml = `
|
||||||
<div id="tooltip-identity-${uniqueId}" role="tooltip" class="fixed z-50 py-3 px-4 text-sm font-medium text-white bg-gray-400 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip dark:bg-gray-600 max-w-sm pointer-events-none">
|
<div id="tooltip-identity-${uniqueId}" role="tooltip" class="fixed z-50 py-3 px-4 text-sm font-medium text-white bg-gray-400 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip dark:bg-gray-600 max-w-sm pointer-events-none">
|
||||||
${tooltipContent}
|
${tooltipContent}
|
||||||
<div class="tooltip-arrow" data-popper-arrow></div>
|
<div class="tooltip-arrow" data-popper-arrow></div>
|
||||||
</div>
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const tooltipStatusHtml = `
|
||||||
<div id="tooltip-status-${uniqueId}" role="tooltip" class="inline-block absolute z-50 py-2 px-3 text-sm font-medium text-white bg-gray-400 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip dark:bg-gray-600">
|
<div id="tooltip-status-${uniqueId}" role="tooltip" class="inline-block absolute z-50 py-2 px-3 text-sm font-medium text-white bg-gray-400 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip dark:bg-gray-600">
|
||||||
<div class="text-white">
|
<div class="text-white">
|
||||||
<p class="font-bold mb-2">Transaction Status</p>
|
<p class="font-bold mb-2">Transaction Status</p>
|
||||||
@@ -1248,6 +1257,12 @@ const createTableRow = async (bid) => {
|
|||||||
<div class="tooltip-arrow" data-popper-arrow></div>
|
<div class="tooltip-arrow" data-popper-arrow></div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
rowHtml,
|
||||||
|
tooltipIdentityHtml,
|
||||||
|
tooltipStatusHtml
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function cleanupOffscreenTooltips() {
|
function cleanupOffscreenTooltips() {
|
||||||
@@ -1393,16 +1408,13 @@ const updateTableContent = async (type) => {
|
|||||||
const tbody = elements[`${type}BidsBody`];
|
const tbody = elements[`${type}BidsBody`];
|
||||||
if (!tbody) return;
|
if (!tbody) return;
|
||||||
|
|
||||||
tbody.innerHTML = '<tr><td colspan="8" class="text-center py-8 text-gray-500 dark:text-gray-400"><div class="animate-pulse">Loading bids...</div></td></tr>';
|
|
||||||
|
|
||||||
if (window.TooltipManager) {
|
if (window.TooltipManager) {
|
||||||
requestAnimationFrame(() => window.TooltipManager.cleanup());
|
window.TooltipManager.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
cleanupTooltips();
|
||||||
cleanupTooltips();
|
|
||||||
forceTooltipDOMCleanup();
|
tbody.innerHTML = '<tr><td colspan="8" class="text-center py-8 text-gray-500 dark:text-gray-400"><div class="animate-pulse">Loading bids...</div></td></tr>';
|
||||||
});
|
|
||||||
|
|
||||||
tooltipIdsToCleanup.clear();
|
tooltipIdsToCleanup.clear();
|
||||||
|
|
||||||
@@ -1413,36 +1425,55 @@ const updateTableContent = async (type) => {
|
|||||||
|
|
||||||
const currentPageData = filteredData.slice(startIndex, endIndex);
|
const currentPageData = filteredData.slice(startIndex, endIndex);
|
||||||
|
|
||||||
|
let tooltipContainerId = `tooltip-container-${type}`;
|
||||||
|
let tooltipContainer = document.getElementById(tooltipContainerId);
|
||||||
|
|
||||||
|
if (!tooltipContainer) {
|
||||||
|
tooltipContainer = document.createElement('div');
|
||||||
|
tooltipContainer.id = tooltipContainerId;
|
||||||
|
tooltipContainer.className = 'tooltip-container';
|
||||||
|
document.body.appendChild(tooltipContainer);
|
||||||
|
} else {
|
||||||
|
tooltipContainer.innerHTML = '';
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (currentPageData.length > 0) {
|
if (currentPageData.length > 0) {
|
||||||
const BATCH_SIZE = 10;
|
const BATCH_SIZE = 10;
|
||||||
let allRows = [];
|
let allRows = [];
|
||||||
|
let allTooltips = [];
|
||||||
|
|
||||||
for (let i = 0; i < currentPageData.length; i += BATCH_SIZE) {
|
for (let i = 0; i < currentPageData.length; i += BATCH_SIZE) {
|
||||||
const batch = currentPageData.slice(i, i + BATCH_SIZE);
|
const batch = currentPageData.slice(i, i + BATCH_SIZE);
|
||||||
const rowPromises = batch.map(bid => createTableRow(bid));
|
const rowPromises = batch.map(bid => createTableRow(bid));
|
||||||
const rows = await Promise.all(rowPromises);
|
const rowData = await Promise.all(rowPromises);
|
||||||
allRows = allRows.concat(rows);
|
|
||||||
|
|
||||||
|
rowData.forEach(data => {
|
||||||
|
allRows.push(data.rowHtml);
|
||||||
|
allTooltips.push(data.tooltipIdentityHtml);
|
||||||
|
allTooltips.push(data.tooltipStatusHtml);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollPosition = tbody.parentElement?.scrollTop || 0;
|
const scrollPosition = tbody.parentElement?.scrollTop || 0;
|
||||||
|
|
||||||
tbody.innerHTML = allRows.join('');
|
tbody.innerHTML = allRows.join('');
|
||||||
|
tooltipContainer.innerHTML = allTooltips.join('');
|
||||||
|
|
||||||
if (tbody.parentElement && scrollPosition > 0) {
|
if (tbody.parentElement && scrollPosition > 0) {
|
||||||
tbody.parentElement.scrollTop = scrollPosition;
|
tbody.parentElement.scrollTop = scrollPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.visibilityState === 'visible') {
|
if (document.visibilityState === 'visible') {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
initializeTooltips();
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
initializeTooltips();
|
forceTooltipDOMCleanup();
|
||||||
|
}, 100);
|
||||||
setTimeout(() => {
|
});
|
||||||
forceTooltipDOMCleanup();
|
});
|
||||||
}, 100);
|
|
||||||
}, 10);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tbody.innerHTML = `
|
tbody.innerHTML = `
|
||||||
|
|||||||
@@ -744,6 +744,16 @@ async function fetchLatestPrices() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchPricesAsync() {
|
||||||
|
try {
|
||||||
|
const prices = await window.PriceManager.getPrices(false);
|
||||||
|
return prices;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching prices asynchronously:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchOffers() {
|
async function fetchOffers() {
|
||||||
const refreshButton = document.getElementById('refreshOffers');
|
const refreshButton = document.getElementById('refreshOffers');
|
||||||
const refreshIcon = document.getElementById('refreshIcon');
|
const refreshIcon = document.getElementById('refreshIcon');
|
||||||
@@ -778,11 +788,7 @@ async function fetchOffers() {
|
|||||||
refreshButton.classList.add('opacity-75', 'cursor-wait');
|
refreshButton.classList.add('opacity-75', 'cursor-wait');
|
||||||
}
|
}
|
||||||
|
|
||||||
const [offersResponse, pricesData] = await Promise.all([
|
const offersResponse = await fetchWithRetry(isSentOffers ? '/json/sentoffers' : '/json/offers');
|
||||||
fetchWithRetry(isSentOffers ? '/json/sentoffers' : '/json/offers'),
|
|
||||||
fetchLatestPrices()
|
|
||||||
]);
|
|
||||||
|
|
||||||
const data = await offersResponse.json();
|
const data = await offersResponse.json();
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
@@ -812,13 +818,20 @@ async function fetchOffers() {
|
|||||||
jsonData = formatInitialData(processedData);
|
jsonData = formatInitialData(processedData);
|
||||||
originalJsonData = [...jsonData];
|
originalJsonData = [...jsonData];
|
||||||
|
|
||||||
latestPrices = pricesData || getEmptyPriceData();
|
|
||||||
|
|
||||||
CacheManager.set('offers_cached', jsonData, 'offers');
|
CacheManager.set('offers_cached', jsonData, 'offers');
|
||||||
|
|
||||||
applyFilters();
|
applyFilters();
|
||||||
updatePaginationInfo();
|
updatePaginationInfo();
|
||||||
|
|
||||||
|
fetchPricesAsync().then(prices => {
|
||||||
|
if (prices) {
|
||||||
|
latestPrices = prices;
|
||||||
|
updateProfitLossDisplays();
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error fetching prices after offers refresh:', error);
|
||||||
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Debug] Error fetching offers:', error);
|
console.error('[Debug] Error fetching offers:', error);
|
||||||
NetworkManager.handleNetworkError(error);
|
NetworkManager.handleNetworkError(error);
|
||||||
|
|||||||
Reference in New Issue
Block a user