Merge pull request #338 from nahuhh/amm_table

amm: icon beside amount & consistent size of add/edit
This commit is contained in:
Gerlof van Ek
2025-07-23 23:54:09 +02:00
committed by GitHub
9 changed files with 66 additions and 69 deletions

View File

@@ -122,13 +122,13 @@ const AmmTablesManager = (function() {
<td class="py-0 px-0 text-right text-sm">
<div class="flex items-center justify-center monospace">
<span class="inline-flex mr-3 ml-3 align-middle items-center justify-center w-18 h-20 rounded">
<img class="h-12" src="/static/images/coins/${fromImage}" alt="${fromDisplayName}">
<img class="h-12" src="/static/images/coins/${toImage}" alt="${toDisplayName}">
</span>
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
<span class="inline-flex mr-3 ml-3 align-middle items-center justify-center w-18 h-20 rounded">
<img class="h-12" src="/static/images/coins/${toImage}" alt="${toDisplayName}">
<img class="h-12" src="/static/images/coins/${fromImage}" alt="${fromDisplayName}">
</span>
</div>
</td>

View File

@@ -147,7 +147,7 @@ window.cleanup = function() {
if (exportAllButton && typeof EventManager !== 'undefined') {
EventManager.remove(exportAllButton, 'click');
}
if (exportSentButton && typeof EventManager !== 'undefined') {
EventManager.remove(exportSentButton, 'click');
}

View File

@@ -264,9 +264,9 @@ const ApiManager = (function() {
window.config.coins
.filter(coin => coin.usesCoinGecko)
.map(coin => {
return window.config.getCoinBackendId ?
window.config.getCoinBackendId(coin.name) :
(typeof getCoinBackendId === 'function' ?
return window.config.getCoinBackendId ?
window.config.getCoinBackendId(coin.name) :
(typeof getCoinBackendId === 'function' ?
getCoinBackendId(coin.name) : coin.name.toLowerCase());
})
.join(',') :
@@ -277,7 +277,7 @@ const ApiManager = (function() {
}
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${coinList}&vs_currencies=usd&include_24hr_vol=true&include_24hr_change=true`;
const response = await this.makePostRequest(url, {
'User-Agent': 'Mozilla/5.0',
'Accept': 'application/json'
@@ -288,7 +288,7 @@ const ApiManager = (function() {
}
const volumeData = {};
Object.entries(response).forEach(([coinId, data]) => {
if (data && data.usd_24h_vol !== undefined) {
volumeData[coinId] = {

View File

@@ -288,11 +288,11 @@ const CleanupManager = (function() {
}
}
document.dispatchEvent(new CustomEvent('memoryOptimized', {
detail: {
document.dispatchEvent(new CustomEvent('memoryOptimized', {
detail: {
timestamp: Date.now(),
maxDataSize: options.maxDataSize || 1000
}
}
}));
log('Memory optimization complete');
@@ -311,11 +311,11 @@ const CleanupManager = (function() {
try {
const isDetached = !(listener.element instanceof Node) ||
!document.body.contains(listener.element) ||
const isDetached = !(listener.element instanceof Node) ||
!document.body.contains(listener.element) ||
(listener.element.classList && listener.element.classList.contains('hidden')) ||
(listener.element.style && listener.element.style.display === 'none');
if (isDetached) {
try {
if (listener.element instanceof Node) {
@@ -362,12 +362,12 @@ const CleanupManager = (function() {
log(`Error checking resource ${id}: ${e.message}`);
}
});
resourcesForRemoval.forEach(id => {
this.unregisterResource(id);
removedResources++;
});
if (removedResources > 0) {
log(`Removed ${removedResources} orphaned resources`);
}
@@ -408,22 +408,22 @@ const CleanupManager = (function() {
try {
const tooltipSelectors = [
'[role="tooltip"]',
'[id^="tooltip-"]',
'.tippy-box',
'[role="tooltip"]',
'[id^="tooltip-"]',
'.tippy-box',
'[data-tippy-root]'
];
tooltipSelectors.forEach(selector => {
try {
const elements = document.querySelectorAll(selector);
elements.forEach(element => {
try {
if (!(element instanceof Element)) return;
const isDetached = !element.parentElement ||
const isDetached = !element.parentElement ||
!document.body.contains(element.parentElement) ||
element.classList.contains('hidden') ||
element.style.display === 'none' ||

View File

@@ -11,15 +11,15 @@ const MemoryManager = (function() {
debug: false,
protectedWebSockets: ['wsPort', 'ws_port'],
interactiveSelectors: [
'tr:hover',
'[data-tippy-root]:hover',
'.tooltip:hover',
'[data-tooltip-trigger-id]:hover',
'tr:hover',
'[data-tippy-root]:hover',
'.tooltip:hover',
'[data-tooltip-trigger-id]:hover',
'[data-tooltip-target]:hover'
],
protectedContainers: [
'#sent-tbody',
'#received-tbody',
'#sent-tbody',
'#received-tbody',
'#offers-body'
]
};
@@ -74,10 +74,10 @@ const MemoryManager = (function() {
function shouldSkipCleanup() {
if (state.isCleanupRunning) return true;
const selector = config.interactiveSelectors.join(', ');
const hoveredElements = document.querySelectorAll(selector);
return hoveredElements.length > 0;
}
@@ -130,7 +130,7 @@ const MemoryManager = (function() {
disconnectedRemoved: disconnectedResult,
memoryBefore: startMemory ? startMemory.usedMB : null,
memoryAfter: endMemory ? endMemory.usedMB : null,
memorySaved: startMemory && endMemory ?
memorySaved: startMemory && endMemory ?
(startMemory.usedMB - endMemory.usedMB).toFixed(2) : null
};
@@ -162,7 +162,7 @@ const MemoryManager = (function() {
tippyRoots.forEach(root => {
const tooltipId = root.getAttribute('data-for-tooltip-id');
const trigger = tooltipId ?
const trigger = tooltipId ?
document.querySelector(`[data-tooltip-trigger-id="${tooltipId}"]`) : null;
if (!trigger || !document.body.contains(trigger)) {
@@ -228,7 +228,7 @@ const MemoryManager = (function() {
return true;
}
function checkMemoryUsage() {
const result = {
usedJSHeapSize: 0,
@@ -288,7 +288,7 @@ const MemoryManager = (function() {
setTimeout(() => {
processingScheduled = false;
lastProcessTime = Date.now();
if (state.isCleanupRunning) {
return;
}
@@ -298,7 +298,7 @@ const MemoryManager = (function() {
tooltipCount = document.querySelectorAll(tooltipSelectors.join(', ')).length;
if (tooltipCount > config.maxTooltipsThreshold &&
if (tooltipCount > config.maxTooltipsThreshold &&
(Date.now() - state.lastCleanupTime > config.minTimeBetweenCleanups)) {
removeOrphanedTooltips();
@@ -429,7 +429,7 @@ const MemoryManager = (function() {
return true;
}
function initialize(options = {}) {
preserveTooltipFunctions();
@@ -492,8 +492,8 @@ const MemoryManager = (function() {
const stats = getDetailedStats();
console.group('Memory Manager Stats');
console.log('Memory Usage:', stats.memory ?
`${stats.memory.usedMB}MB / ${stats.memory.limitMB}MB (${stats.memory.percentUsed}%)` :
console.log('Memory Usage:', stats.memory ?
`${stats.memory.usedMB}MB / ${stats.memory.limitMB}MB (${stats.memory.percentUsed}%)` :
'Not available');
console.log('Total Cleanups:', stats.metrics.cleanupRuns);
console.log('Total Tooltips Removed:', stats.metrics.tooltipsRemoved);
@@ -569,7 +569,7 @@ const MemoryManager = (function() {
})();
document.addEventListener('DOMContentLoaded', function() {
const isDevMode = window.location.hostname === 'localhost' ||
const isDevMode = window.location.hostname === 'localhost' ||
window.location.hostname === '127.0.0.1';
MemoryManager.initialize({

View File

@@ -185,7 +185,7 @@ const TooltipManager = (function() {
}
}
);
return tippyInstance[0];
}
@@ -248,7 +248,7 @@ const TooltipManager = (function() {
this.log('Running tooltip cleanup');
try {
if ((window.location.pathname.includes('/offers') || window.location.pathname.includes('/bids')) &&
if ((window.location.pathname.includes('/offers') || window.location.pathname.includes('/bids')) &&
(document.querySelector('[data-tippy-root]:hover') || document.querySelector('[data-tooltip-trigger-id]:hover'))) {
console.log('Skipping tooltip cleanup - tooltip is being hovered');
return;
@@ -299,7 +299,7 @@ const TooltipManager = (function() {
this.log('Cleaning up all tooltips');
try {
if ((window.location.pathname.includes('/offers') || window.location.pathname.includes('/bids')) &&
if ((window.location.pathname.includes('/offers') || window.location.pathname.includes('/bids')) &&
document.querySelector('#offers-body tr:hover')) {
this.log('Skipping all tooltips cleanup on offers/bids page with row hover');
return;
@@ -328,7 +328,7 @@ const TooltipManager = (function() {
if (!isHovered(trigger)) {
trigger.removeAttribute('data-tooltip-trigger-id');
trigger.removeAttribute('aria-describedby');
if (trigger._tippy) {
try {
trigger._tippy.destroy();
@@ -350,7 +350,7 @@ const TooltipManager = (function() {
if (!closestHoveredRow) {
const style = window.getComputedStyle(tooltip);
const isVisible = style.display !== 'none' &&
const isVisible = style.display !== 'none' &&
style.visibility !== 'hidden' &&
style.opacity !== '0';
@@ -372,8 +372,8 @@ const TooltipManager = (function() {
tippyElements.forEach(element => {
const tooltipId = element.getAttribute('data-for-tooltip-id');
const trigger = tooltipId ?
document.querySelector(`[data-tooltip-trigger-id="${tooltipId}"]`) :
const trigger = tooltipId ?
document.querySelector(`[data-tooltip-trigger-id="${tooltipId}"]`) :
null;
if (!trigger || !document.body.contains(trigger)) {
@@ -489,7 +489,7 @@ const TooltipManager = (function() {
performPeriodicCleanup(force = false) {
try {
if ((window.location.pathname.includes('/offers') || window.location.pathname.includes('/bids')) &&
if ((window.location.pathname.includes('/offers') || window.location.pathname.includes('/bids')) &&
!force) {
return;
}
@@ -829,7 +829,7 @@ const TooltipManager = (function() {
const manager = this.getInstance();
return manager.initializeTooltips(...args);
},
setDebugMode: function(enabled) {
const manager = this.getInstance();
return manager.setDebugMode(enabled);

View File

@@ -332,10 +332,10 @@ const ui = {
if (data.price_btc !== undefined && data.price_btc !== null) {
priceBTC = data.price_btc;
}
}
else if (window.btcPriceUSD && window.btcPriceUSD > 0) {
priceBTC = priceUSD / window.btcPriceUSD;
}
}
else if (app && app.btcPriceUSD && app.btcPriceUSD > 0) {
priceBTC = priceUSD / app.btcPriceUSD;
}
@@ -343,7 +343,7 @@ const ui = {
priceBTC = 0;
}
}
priceChange1d = data.price_change_percentage_24h || 0;
volume24h = data.total_volume || 0;
if (isNaN(priceUSD) || isNaN(priceBTC)) {

View File

@@ -16,7 +16,7 @@
document.addEventListener('DOMContentLoaded', function() {
initBidsTabNavigation();
});
window.addEventListener('hashchange', handleHashChange);
window.bidsTabNavigationInitialized = false;
@@ -52,7 +52,7 @@
}
const tabToActivate = localStorage.getItem('bidsTabToActivate');
if (tabToActivate) {
localStorage.removeItem('bidsTabToActivate');
@@ -70,7 +70,7 @@
if (window.location.pathname !== '/bids') {
return;
}
const hash = window.location.hash;
if (hash) {
@@ -90,22 +90,20 @@
return;
}
const tabButtonId = normalizedTabId === '#all' ? 'all-tab' :
const tabButtonId = normalizedTabId === '#all' ? 'all-tab' :
(normalizedTabId === '#sent' ? 'sent-tab' : 'received-tab');
const tabButton = document.getElementById(tabButtonId);
if (!tabButton) {
if (retryCount < 5) {
setTimeout(() => {
activateTabWithRetry(normalizedTabId, retryCount + 1);
}, 100);
} else {
}
return;
}
tabButton.click();
@@ -115,7 +113,7 @@
if (tabsEl) {
const allTabs = Array.from(tabsEl.querySelectorAll('[role="tab"]'));
const targetTab = allTabs.find(tab => tab.getAttribute('data-tabs-target') === normalizedTabId);
if (targetTab) {
allTabs.forEach(tab => {
@@ -133,7 +131,7 @@
const allContent = document.getElementById('all');
const sentContent = document.getElementById('sent');
const receivedContent = document.getElementById('received');
if (allContent && sentContent && receivedContent) {
allContent.classList.toggle('hidden', normalizedTabId !== '#all');
sentContent.classList.toggle('hidden', normalizedTabId !== '#sent');
@@ -146,7 +144,7 @@
const allPanel = document.getElementById('all');
const sentPanel = document.getElementById('sent');
const receivedPanel = document.getElementById('received');
if (allPanel && sentPanel && receivedPanel) {
allPanel.classList.toggle('hidden', normalizedTabId !== '#all');
sentPanel.classList.toggle('hidden', normalizedTabId !== '#sent');
@@ -164,7 +162,7 @@
function triggerDataLoad(tabId) {
setTimeout(() => {
if (window.state) {
window.state.currentTab = tabId === '#all' ? 'all' :
window.state.currentTab = tabId === '#all' ? 'all' :
(tabId === '#sent' ? 'sent' : 'received');
if (typeof window.updateBidsTable === 'function') {
@@ -174,9 +172,9 @@
}
const event = new CustomEvent('tabactivated', {
detail: {
detail: {
tabId: tabId,
type: tabId === '#all' ? 'all' :
type: tabId === '#all' ? 'all' :
(tabId === '#sent' ? 'sent' : 'received')
}
});
@@ -195,9 +193,9 @@
function navigateToTabDirectly(tabId) {
const oldScrollPosition = window.scrollY;
activateTabWithRetry(tabId);
setTimeout(function() {
window.scrollTo(0, oldScrollPosition);
}, 0);

View File

@@ -26,7 +26,6 @@
</div>
</section>
<div class="xl:container mx-auto">
{% include 'inc_messages.html' %}
@@ -1347,7 +1346,7 @@
<div class="absolute inset-0 bg-gray-500 opacity-75 dark:bg-gray-900 dark:opacity-90"></div>
</div>
<div class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-visible shadow-xl transform transition-all sm:my-8 sm:align-middle lg:max-w-xl md:max-w-2xl md:w-full">
<div class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-visible shadow-xl transform transition-all sm:my-8 sm:align-middle md:max-w-2xl md:w-full">
<div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mt-3 text-center sm:mt-0 sm:text-left w-full">