js: eslints

This commit is contained in:
nahuhh
2025-03-26 23:01:30 +00:00
parent d15466f656
commit eeade736a4
18 changed files with 284 additions and 284 deletions

View File

@@ -97,7 +97,7 @@ const EventManager = {
add(element, type, handler, options = false) { add(element, type, handler, options = false) {
if (!element) return null; if (!element) return null;
if (!this.listeners.has(element)) { if (!this.listeners.has(element)) {
this.listeners.set(element, new Map()); this.listeners.set(element, new Map());
} }
@@ -116,7 +116,7 @@ const EventManager = {
remove(element, type, handler, options = false) { remove(element, type, handler, options = false) {
if (!element) return; if (!element) return;
const elementListeners = this.listeners.get(element); const elementListeners = this.listeners.get(element);
if (!elementListeners) return; if (!elementListeners) return;
@@ -140,7 +140,7 @@ const EventManager = {
removeAll(element) { removeAll(element) {
if (!element) return; if (!element) return;
const elementListeners = this.listeners.get(element); const elementListeners = this.listeners.get(element);
if (!elementListeners) return; if (!elementListeners) return;
@@ -167,7 +167,7 @@ const EventManager = {
function cleanup() { function cleanup() {
//console.log('Starting comprehensive cleanup process for bids table'); //console.log('Starting comprehensive cleanup process for bids table');
try { try {
if (searchTimeout) { if (searchTimeout) {
clearTimeout(searchTimeout); clearTimeout(searchTimeout);
@@ -184,7 +184,7 @@ function cleanup() {
cleanupTooltips(); cleanupTooltips();
forceTooltipDOMCleanup(); forceTooltipDOMCleanup();
if (window.TooltipManager) { if (window.TooltipManager) {
window.TooltipManager.cleanup(); window.TooltipManager.cleanup();
} }
@@ -237,12 +237,12 @@ function cleanup() {
sent: [], sent: [],
received: [] received: []
}; };
state.currentPage = { state.currentPage = {
sent: 1, sent: 1,
received: 1 received: 1
}; };
state.isLoading = false; state.isLoading = false;
state.isRefreshing = false; state.isRefreshing = false;
state.wsConnected = false; state.wsConnected = false;
@@ -310,7 +310,7 @@ CleanupManager.addListener(document, 'visibilitychange', () => {
if (window.TooltipManager && typeof window.TooltipManager.cleanup === 'function') { if (window.TooltipManager && typeof window.TooltipManager.cleanup === 'function') {
window.TooltipManager.cleanup(); window.TooltipManager.cleanup();
} }
// Run memory optimization // Run memory optimization
if (window.MemoryManager) { if (window.MemoryManager) {
MemoryManager.forceCleanup(); MemoryManager.forceCleanup();
@@ -326,7 +326,7 @@ CleanupManager.addListener(document, 'visibilitychange', () => {
const lastUpdateTime = state.lastRefresh || 0; const lastUpdateTime = state.lastRefresh || 0;
const now = Date.now(); const now = Date.now();
const refreshInterval = 5 * 60 * 1000; // 5 minutes const refreshInterval = 5 * 60 * 1000; // 5 minutes
if (now - lastUpdateTime > refreshInterval) { if (now - lastUpdateTime > refreshInterval) {
setTimeout(() => { setTimeout(() => {
updateBidsTable(); updateBidsTable();
@@ -366,7 +366,7 @@ function cleanupRow(row) {
function optimizeMemoryUsage() { function optimizeMemoryUsage() {
const MAX_BIDS_IN_MEMORY = 500; const MAX_BIDS_IN_MEMORY = 500;
['sent', 'received'].forEach(type => { ['sent', 'received'].forEach(type => {
if (state.data[type] && state.data[type].length > MAX_BIDS_IN_MEMORY) { if (state.data[type] && state.data[type].length > MAX_BIDS_IN_MEMORY) {
console.log(`Trimming ${type} bids data from ${state.data[type].length} to ${MAX_BIDS_IN_MEMORY}`); console.log(`Trimming ${type} bids data from ${state.data[type].length} to ${MAX_BIDS_IN_MEMORY}`);
@@ -581,7 +581,7 @@ function filterAndSortData(bids) {
} catch (e) { } catch (e) {
console.warn('Error accessing identity for search:', e); console.warn('Error accessing identity for search:', e);
} }
const matchesLabel = label.toLowerCase().includes(searchStr); const matchesLabel = label.toLowerCase().includes(searchStr);
let matchesDisplayedLabel = false; let matchesDisplayedLabel = false;
@@ -589,7 +589,7 @@ function filterAndSortData(bids) {
try { try {
const tableId = state.currentTab === 'sent' ? 'sent' : 'received'; const tableId = state.currentTab === 'sent' ? 'sent' : 'received';
const cells = document.querySelectorAll(`#${tableId} a[href^="/identity/"]`); const cells = document.querySelectorAll(`#${tableId} a[href^="/identity/"]`);
for (const cell of cells) { for (const cell of cells) {
const href = cell.getAttribute('href'); const href = cell.getAttribute('href');
@@ -607,7 +607,7 @@ function filterAndSortData(bids) {
console.warn('Error checking displayed labels:', e); console.warn('Error checking displayed labels:', e);
} }
} }
if (!(matchesBidId || matchesIdentity || matchesLabel || matchesDisplayedLabel)) { if (!(matchesBidId || matchesIdentity || matchesLabel || matchesDisplayedLabel)) {
return false; return false;
} }
@@ -627,7 +627,7 @@ async function preloadIdentitiesForSearch(bids) {
if (!window.IdentityManager || typeof IdentityManager.getIdentityData !== 'function') { if (!window.IdentityManager || typeof IdentityManager.getIdentityData !== 'function') {
return; return;
} }
try { try {
const addresses = new Set(); const addresses = new Set();
bids.forEach(bid => { bids.forEach(bid => {
@@ -638,7 +638,7 @@ async function preloadIdentitiesForSearch(bids) {
const BATCH_SIZE = 20; const BATCH_SIZE = 20;
const addressArray = Array.from(addresses); const addressArray = Array.from(addresses);
for (let i = 0; i < addressArray.length; i += BATCH_SIZE) { for (let i = 0; i < addressArray.length; i += BATCH_SIZE) {
const batch = addressArray.slice(i, i + BATCH_SIZE); const batch = addressArray.slice(i, i + BATCH_SIZE);
await Promise.all(batch.map(addr => IdentityManager.getIdentityData(addr))); await Promise.all(batch.map(addr => IdentityManager.getIdentityData(addr)));
@@ -647,7 +647,7 @@ async function preloadIdentitiesForSearch(bids) {
await new Promise(resolve => setTimeout(resolve, 10)); await new Promise(resolve => setTimeout(resolve, 10));
} }
} }
console.log(`Preloaded ${addressArray.length} identities for search`); console.log(`Preloaded ${addressArray.length} identities for search`);
} catch (error) { } catch (error) {
console.error('Error preloading identities:', error); console.error('Error preloading identities:', error);
@@ -847,7 +847,7 @@ const createIdentityTooltipContent = (identity) => {
`; `;
}; };
let tooltipIdsToCleanup = new Set(); const tooltipIdsToCleanup = new Set();
const cleanupTooltips = () => { const cleanupTooltips = () => {
if (window.TooltipManager) { if (window.TooltipManager) {
@@ -869,7 +869,7 @@ const forceTooltipDOMCleanup = () => {
foundCount += allTooltipElements.length; foundCount += allTooltipElements.length;
allTooltipElements.forEach(element => { allTooltipElements.forEach(element => {
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';
@@ -877,7 +877,7 @@ const forceTooltipDOMCleanup = () => {
const triggerId = element.id; const triggerId = element.id;
const triggerElement = document.querySelector(`[data-tooltip-target="${triggerId}"]`); const triggerElement = document.querySelector(`[data-tooltip-target="${triggerId}"]`);
if (!triggerElement || if (!triggerElement ||
!document.body.contains(triggerElement) || !document.body.contains(triggerElement) ||
triggerElement.classList.contains('hidden')) { triggerElement.classList.contains('hidden')) {
element.remove(); element.remove();
@@ -899,7 +899,7 @@ const forceTooltipDOMCleanup = () => {
const tippyRoots = document.querySelectorAll('[data-tippy-root]'); const tippyRoots = document.querySelectorAll('[data-tippy-root]');
foundCount += tippyRoots.length; foundCount += tippyRoots.length;
tippyRoots.forEach(element => { tippyRoots.forEach(element => {
const isOrphan = !element.children.length || const isOrphan = !element.children.length ||
element.children[0].classList.contains('hidden') || element.children[0].classList.contains('hidden') ||
!document.body.contains(element); !document.body.contains(element);
@@ -926,7 +926,7 @@ const forceTooltipDOMCleanup = () => {
} }
}); });
document.querySelectorAll('.tooltip').forEach(element => { document.querySelectorAll('.tooltip').forEach(element => {
const isTrulyDetached = !element.parentElement || const isTrulyDetached = !element.parentElement ||
!document.body.contains(element.parentElement) || !document.body.contains(element.parentElement) ||
element.classList.contains('hidden'); element.classList.contains('hidden');
if (isTrulyDetached) { if (isTrulyDetached) {
@@ -1108,7 +1108,7 @@ const updateTableContent = async (type) => {
if (currentPageData.length > 0) { if (currentPageData.length > 0) {
const BATCH_SIZE = 10; const BATCH_SIZE = 10;
let allRows = []; let allRows = [];
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));
@@ -1166,7 +1166,7 @@ const initializeTooltips = () => {
window.TooltipManager.cleanup(); window.TooltipManager.cleanup();
let selector = '#' + state.currentTab + ' [data-tooltip-target]'; const selector = '#' + state.currentTab + ' [data-tooltip-target]';
const tooltipTriggers = document.querySelectorAll(selector); const tooltipTriggers = document.querySelectorAll(selector);
const tooltipCount = tooltipTriggers.length; const tooltipCount = tooltipTriggers.length;
if (tooltipCount > 50) { if (tooltipCount > 50) {
@@ -1187,7 +1187,7 @@ const initializeTooltips = () => {
}); });
const offscreenTooltips = Array.from(tooltipTriggers).filter(t => !viewportTooltips.includes(t)); const offscreenTooltips = Array.from(tooltipTriggers).filter(t => !viewportTooltips.includes(t));
offscreenTooltips.forEach(trigger => { offscreenTooltips.forEach(trigger => {
const createTooltipOnHover = () => { const createTooltipOnHover = () => {
createTooltipForTrigger(trigger); createTooltipForTrigger(trigger);
@@ -1206,7 +1206,7 @@ const initializeTooltips = () => {
const createTooltipForTrigger = (trigger) => { const createTooltipForTrigger = (trigger) => {
if (!trigger || !window.TooltipManager) return; if (!trigger || !window.TooltipManager) return;
const targetId = trigger.getAttribute('data-tooltip-target'); const targetId = trigger.getAttribute('data-tooltip-target');
const tooltipContent = document.getElementById(targetId); const tooltipContent = document.getElementById(targetId);
@@ -1250,7 +1250,7 @@ function cleanupOffscreenTooltips() {
const farOffscreenTriggers = Array.from(tooltipTriggers).filter(trigger => { const farOffscreenTriggers = Array.from(tooltipTriggers).filter(trigger => {
const rect = trigger.getBoundingClientRect(); const rect = trigger.getBoundingClientRect();
return (rect.bottom < -window.innerHeight * 2 || return (rect.bottom < -window.innerHeight * 2 ||
rect.top > window.innerHeight * 3); rect.top > window.innerHeight * 3);
}); });
@@ -1312,7 +1312,7 @@ const fetchBids = async () => {
activeFetchController.abort(); activeFetchController.abort();
} }
}, 30000); }, 30000);
const response = await fetch(endpoint, { const response = await fetch(endpoint, {
method: 'POST', method: 'POST',
headers: { headers: {
@@ -1328,14 +1328,14 @@ const fetchBids = async () => {
}), }),
signal: activeFetchController.signal signal: activeFetchController.signal
}); });
clearTimeout(timeoutId); clearTimeout(timeoutId);
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`); throw new Error(`HTTP error! status: ${response.status}`);
} }
let data = await response.json(); const data = await response.json();
//console.log('Received raw data:', data.length, 'bids'); //console.log('Received raw data:', data.length, 'bids');
state.filters.with_expired = includeExpired; state.filters.with_expired = includeExpired;
@@ -1351,7 +1351,7 @@ const fetchBids = async () => {
} else { } else {
processedData = filterAndSortData(data); processedData = filterAndSortData(data);
} }
return processedData; return processedData;
} catch (error) { } catch (error) {
if (error.name === 'AbortError') { if (error.name === 'AbortError') {
@@ -1375,12 +1375,12 @@ const updateBidsTable = async () => {
updateLoadingState(true); updateLoadingState(true);
const bids = await fetchBids(); const bids = await fetchBids();
// Add identity preloading if we're searching // Add identity preloading if we're searching
if (state.filters.searchQuery && state.filters.searchQuery.length > 0) { if (state.filters.searchQuery && state.filters.searchQuery.length > 0) {
await preloadIdentitiesForSearch(bids); await preloadIdentitiesForSearch(bids);
} }
state.data[state.currentTab] = bids; state.data[state.currentTab] = bids;
state.currentPage[state.currentTab] = 1; state.currentPage[state.currentTab] = 1;
@@ -1911,13 +1911,13 @@ function initialize() {
WebSocketManager.initialize(); WebSocketManager.initialize();
setupEventListeners(); setupEventListeners();
}, 10); }, 10);
setTimeout(() => { setTimeout(() => {
setupRefreshButtons(); setupRefreshButtons();
setupFilterEventListeners(); setupFilterEventListeners();
updateCoinFilterImages(); updateCoinFilterImages();
}, 50); }, 50);
setTimeout(() => { setTimeout(() => {
updateClearFiltersButton(); updateClearFiltersButton();
state.currentTab = 'sent'; state.currentTab = 'sent';

View File

@@ -5,7 +5,7 @@ const BidExporter = {
} }
const isSent = type === 'sent'; const isSent = type === 'sent';
const headers = [ const headers = [
'Date/Time', 'Date/Time',
'Bid ID', 'Bid ID',
@@ -19,9 +19,9 @@ const BidExporter = {
'Created At', 'Created At',
'Expires At' 'Expires At'
]; ];
let csvContent = headers.join(',') + '\n'; let csvContent = headers.join(',') + '\n';
bids.forEach(bid => { bids.forEach(bid => {
const row = [ const row = [
`"${formatTime(bid.created_at)}"`, `"${formatTime(bid.created_at)}"`,
@@ -36,17 +36,17 @@ const BidExporter = {
bid.created_at, bid.created_at,
bid.expire_at bid.expire_at
]; ];
csvContent += row.join(',') + '\n'; csvContent += row.join(',') + '\n';
}); });
return csvContent; return csvContent;
}, },
download(content, filename) { download(content, filename) {
try { try {
const blob = new Blob([content], { type: 'text/csv;charset=utf-8;' }); const blob = new Blob([content], { type: 'text/csv;charset=utf-8;' });
if (window.navigator && window.navigator.msSaveOrOpenBlob) { if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, filename); window.navigator.msSaveOrOpenBlob(blob, filename);
return; return;
@@ -54,48 +54,48 @@ const BidExporter = {
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const link = document.createElement('a'); const link = document.createElement('a');
link.href = url; link.href = url;
link.download = filename; link.download = filename;
link.style.display = 'none'; link.style.display = 'none';
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
setTimeout(() => { setTimeout(() => {
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
}, 100); }, 100);
} catch (error) { } catch (error) {
console.error('Error downloading CSV:', error); console.error('Error downloading CSV:', error);
const csvData = 'data:text/csv;charset=utf-8,' + encodeURIComponent(content); const csvData = 'data:text/csv;charset=utf-8,' + encodeURIComponent(content);
const link = document.createElement('a'); const link = document.createElement('a');
link.setAttribute('href', csvData); link.setAttribute('href', csvData);
link.setAttribute('download', filename); link.setAttribute('download', filename);
link.style.display = 'none'; link.style.display = 'none';
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
} }
}, },
exportCurrentView() { exportCurrentView() {
const type = state.currentTab; const type = state.currentTab;
const data = state.data[type]; const data = state.data[type];
if (!data || !data.length) { if (!data || !data.length) {
alert('No data to export'); alert('No data to export');
return; return;
} }
const csvContent = this.toCSV(data, type); const csvContent = this.toCSV(data, type);
const now = new Date(); const now = new Date();
const dateStr = now.toISOString().split('T')[0]; const dateStr = now.toISOString().split('T')[0];
const filename = `bsx_${type}_bids_${dateStr}.csv`; const filename = `bsx_${type}_bids_${dateStr}.csv`;
this.download(csvContent, filename); this.download(csvContent, filename);
} }
}; };
@@ -111,7 +111,7 @@ document.addEventListener('DOMContentLoaded', function() {
BidExporter.exportCurrentView(); BidExporter.exportCurrentView();
}); });
} }
const exportReceivedButton = document.getElementById('exportReceivedBids'); const exportReceivedButton = document.getElementById('exportReceivedBids');
if (exportReceivedButton) { if (exportReceivedButton) {
EventManager.add(exportReceivedButton, 'click', (e) => { EventManager.add(exportReceivedButton, 'click', (e) => {
@@ -127,14 +127,14 @@ document.addEventListener('DOMContentLoaded', function() {
const originalCleanup = window.cleanup || function(){}; const originalCleanup = window.cleanup || function(){};
window.cleanup = function() { window.cleanup = function() {
originalCleanup(); originalCleanup();
const exportSentButton = document.getElementById('exportSentBids'); const exportSentButton = document.getElementById('exportSentBids');
const exportReceivedButton = document.getElementById('exportReceivedBids'); const exportReceivedButton = document.getElementById('exportReceivedBids');
if (exportSentButton && typeof EventManager !== 'undefined') { if (exportSentButton && typeof EventManager !== 'undefined') {
EventManager.remove(exportSentButton, 'click'); EventManager.remove(exportSentButton, 'click');
} }
if (exportReceivedButton && typeof EventManager !== 'undefined') { if (exportReceivedButton && typeof EventManager !== 'undefined') {
EventManager.remove(exportReceivedButton, 'click'); EventManager.remove(exportReceivedButton, 'click');
} }

View File

@@ -84,7 +84,7 @@ function setupShutdownModal() {
function showShutdownModal() { function showShutdownModal() {
closeAllDropdowns(); closeAllDropdowns();
const activeSwaps = parseInt(shutdownButtons[0].getAttribute('data-active-swaps') || '0'); const activeSwaps = parseInt(shutdownButtons[0].getAttribute('data-active-swaps') || '0');
if (activeSwaps > 0) { if (activeSwaps > 0) {
shutdownWarning.classList.remove('hidden'); shutdownWarning.classList.remove('hidden');
@@ -142,7 +142,7 @@ function setupDarkMode() {
const themeToggleLightIcon = document.getElementById('theme-toggle-light-icon'); const themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
if (themeToggleDarkIcon && themeToggleLightIcon) { if (themeToggleDarkIcon && themeToggleLightIcon) {
if (localStorage.getItem('color-theme') === 'dark' || if (localStorage.getItem('color-theme') === 'dark' ||
(!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) { (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
themeToggleLightIcon.classList.remove('hidden'); themeToggleLightIcon.classList.remove('hidden');
} else { } else {
@@ -167,12 +167,12 @@ function setupDarkMode() {
} else { } else {
setTheme('dark'); setTheme('dark');
} }
if (themeToggleDarkIcon && themeToggleLightIcon) { if (themeToggleDarkIcon && themeToggleLightIcon) {
themeToggleDarkIcon.classList.toggle('hidden'); themeToggleDarkIcon.classList.toggle('hidden');
themeToggleLightIcon.classList.toggle('hidden'); themeToggleLightIcon.classList.toggle('hidden');
} }
toggleImages(); toggleImages();
}); });
} }

View File

@@ -51,7 +51,7 @@ const ApiManager = (function() {
try { try {
await this.requestQueue[apiName]; await this.requestQueue[apiName];
const executeRequest = async () => { const executeRequest = async () => {
const waitTime = this.getWaitTime(apiName); const waitTime = this.getWaitTime(apiName);
if (waitTime > 0) { if (waitTime > 0) {
@@ -69,7 +69,7 @@ const ApiManager = (function() {
return publicAPI.rateLimiter.queueRequest(apiName, requestFn, retryCount + 1); return publicAPI.rateLimiter.queueRequest(apiName, requestFn, retryCount + 1);
} }
if ((error.message.includes('timeout') || error.name === 'NetworkError') && if ((error.message.includes('timeout') || error.name === 'NetworkError') &&
retryCount < this.retryDelays.length) { retryCount < this.retryDelays.length) {
const delay = this.retryDelays[retryCount]; const delay = this.retryDelays[retryCount];
console.warn(`Request failed, retrying in ${delay/1000} seconds...`, { console.warn(`Request failed, retrying in ${delay/1000} seconds...`, {
@@ -87,10 +87,10 @@ const ApiManager = (function() {
this.requestQueue[apiName] = executeRequest(); this.requestQueue[apiName] = executeRequest();
return await this.requestQueue[apiName]; return await this.requestQueue[apiName];
} catch (error) { } catch (error) {
if (error.message.includes('429') || if (error.message.includes('429') ||
error.message.includes('timeout') || error.message.includes('timeout') ||
error.name === 'NetworkError') { error.name === 'NetworkError') {
const cacheKey = `coinData_${apiName}`; const cacheKey = `coinData_${apiName}`;
try { try {
@@ -110,7 +110,7 @@ const ApiManager = (function() {
const publicAPI = { const publicAPI = {
config, config,
rateLimiter, rateLimiter,
initialize: function(options = {}) { initialize: function(options = {}) {
if (state.isInitialized) { if (state.isInitialized) {
console.warn('[ApiManager] Already initialized'); console.warn('[ApiManager] Already initialized');
@@ -158,7 +158,7 @@ const ApiManager = (function() {
} }
const response = await fetch(url, options); const response = await fetch(url, options);
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`); throw new Error(`HTTP error! status: ${response.status}`);
} }
@@ -215,18 +215,18 @@ const ApiManager = (function() {
fetchCoinGeckoData: async function() { fetchCoinGeckoData: async function() {
return this.rateLimiter.queueRequest('coingecko', async () => { return this.rateLimiter.queueRequest('coingecko', async () => {
try { try {
const coins = (window.config && window.config.coins) ? const coins = (window.config && window.config.coins) ?
window.config.coins window.config.coins
.filter(coin => coin.usesCoinGecko) .filter(coin => coin.usesCoinGecko)
.map(coin => coin.name) .map(coin => coin.name)
.join(',') : .join(',') :
'bitcoin,monero,particl,bitcoincash,pivx,firo,dash,litecoin,dogecoin,decred'; 'bitcoin,monero,particl,bitcoincash,pivx,firo,dash,litecoin,dogecoin,decred';
//console.log('Fetching coin prices for:', coins); //console.log('Fetching coin prices for:', coins);
const response = await this.fetchCoinPrices(coins); const response = await this.fetchCoinPrices(coins);
//console.log('Full API response:', response); //console.log('Full API response:', response);
if (!response || typeof response !== 'object') { if (!response || typeof response !== 'object') {
throw new Error('Invalid response type'); throw new Error('Invalid response type');
} }
@@ -249,11 +249,11 @@ const ApiManager = (function() {
fetchVolumeData: async function() { fetchVolumeData: async function() {
return this.rateLimiter.queueRequest('coingecko', async () => { return this.rateLimiter.queueRequest('coingecko', async () => {
try { try {
const coins = (window.config && window.config.coins) ? const coins = (window.config && window.config.coins) ?
window.config.coins window.config.coins
.filter(coin => coin.usesCoinGecko) .filter(coin => coin.usesCoinGecko)
.map(coin => getCoinBackendId ? getCoinBackendId(coin.name) : coin.name) .map(coin => getCoinBackendId ? getCoinBackendId(coin.name) : coin.name)
.join(',') : .join(',') :
'bitcoin,monero,particl,bitcoin-cash,pivx,firo,dash,litecoin,dogecoin,decred'; 'bitcoin,monero,particl,bitcoin-cash,pivx,firo,dash,litecoin,dogecoin,decred';
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${coins}&vs_currencies=usd&include_24hr_vol=true&include_24hr_change=true`; const url = `https://api.coingecko.com/api/v3/simple/price?ids=${coins}&vs_currencies=usd&include_24hr_vol=true&include_24hr_change=true`;
@@ -280,7 +280,7 @@ const ApiManager = (function() {
} }
}); });
}, },
fetchCryptoCompareData: function(coin) { fetchCryptoCompareData: function(coin) {
return this.rateLimiter.queueRequest('cryptocompare', async () => { return this.rateLimiter.queueRequest('cryptocompare', async () => {
try { try {
@@ -290,7 +290,7 @@ const ApiManager = (function() {
'User-Agent': 'Mozilla/5.0', 'User-Agent': 'Mozilla/5.0',
'Accept': 'application/json' 'Accept': 'application/json'
}; };
return await this.makePostRequest(url, headers); return await this.makePostRequest(url, headers);
} catch (error) { } catch (error) {
console.error(`CryptoCompare request failed for ${coin}:`, error); console.error(`CryptoCompare request failed for ${coin}:`, error);
@@ -324,7 +324,7 @@ const ApiManager = (function() {
try { try {
const apiKey = window.config?.apiKeys?.cryptoCompare || ''; const apiKey = window.config?.apiKeys?.cryptoCompare || '';
let url; let url;
if (resolution === 'day') { if (resolution === 'day') {
url = `https://min-api.cryptocompare.com/data/v2/histohour?fsym=${coin}&tsym=USD&limit=24&api_key=${apiKey}`; url = `https://min-api.cryptocompare.com/data/v2/histohour?fsym=${coin}&tsym=USD&limit=24&api_key=${apiKey}`;
} else if (resolution === 'year') { } else if (resolution === 'year') {
@@ -351,7 +351,7 @@ const ApiManager = (function() {
await Promise.all(fetchPromises); await Promise.all(fetchPromises);
return results; return results;
}, },
dispose: function() { dispose: function() {
// Clear any pending requests or resources // Clear any pending requests or resources
rateLimiter.requestQueue = {}; rateLimiter.requestQueue = {};

View File

@@ -19,7 +19,7 @@ const CacheManager = (function() {
]; ];
const isCacheKey = (key) => { const isCacheKey = (key) => {
return CACHE_KEY_PATTERNS.some(pattern => key.startsWith(pattern)) || return CACHE_KEY_PATTERNS.some(pattern => key.startsWith(pattern)) ||
key === 'coinGeckoOneLiner' || key === 'coinGeckoOneLiner' ||
key === PRICES_CACHE_KEY; key === PRICES_CACHE_KEY;
}; };
@@ -48,7 +48,7 @@ const CacheManager = (function() {
const ttlConfig = window.config?.cacheConfig?.ttlSettings || {}; const ttlConfig = window.config?.cacheConfig?.ttlSettings || {};
return ttlConfig[resourceType] || window.config?.cacheConfig?.defaultTTL || defaults.defaultTTL; return ttlConfig[resourceType] || window.config?.cacheConfig?.defaultTTL || defaults.defaultTTL;
}, },
set: function(key, value, resourceTypeOrCustomTtl = null) { set: function(key, value, resourceTypeOrCustomTtl = null) {
try { try {
this.cleanup(); this.cleanup();
@@ -119,10 +119,10 @@ const CacheManager = (function() {
.filter(k => isCacheKey(k)) .filter(k => isCacheKey(k))
.sort((a, b) => memoryCache.get(a).timestamp - memoryCache.get(b).timestamp) .sort((a, b) => memoryCache.get(a).timestamp - memoryCache.get(b).timestamp)
.slice(0, Math.floor(memoryCache.size * 0.2)); // Remove oldest 20% .slice(0, Math.floor(memoryCache.size * 0.2)); // Remove oldest 20%
keysToDelete.forEach(k => memoryCache.delete(k)); keysToDelete.forEach(k => memoryCache.delete(k));
} }
return true; return true;
} }
} catch (error) { } catch (error) {
@@ -194,7 +194,7 @@ const CacheManager = (function() {
memoryCache.delete(key); memoryCache.delete(key);
} }
} }
return null; return null;
} catch (error) { } catch (error) {
console.error("Cache retrieval error:", error); console.error("Cache retrieval error:", error);
@@ -286,7 +286,7 @@ const CacheManager = (function() {
.filter(key => isCacheKey(key)) .filter(key => isCacheKey(key))
.sort((a, b) => memoryCache.get(a).timestamp - memoryCache.get(b).timestamp) .sort((a, b) => memoryCache.get(a).timestamp - memoryCache.get(b).timestamp)
.slice(0, Math.floor(memoryCache.size * 0.3)); // Remove oldest 30% during aggressive cleanup .slice(0, Math.floor(memoryCache.size * 0.3)); // Remove oldest 30% during aggressive cleanup
keysToDelete.forEach(key => memoryCache.delete(key)); keysToDelete.forEach(key => memoryCache.delete(key));
} }
@@ -327,7 +327,7 @@ const CacheManager = (function() {
Array.from(memoryCache.keys()) Array.from(memoryCache.keys())
.filter(key => isCacheKey(key)) .filter(key => isCacheKey(key))
.forEach(key => memoryCache.delete(key)); .forEach(key => memoryCache.delete(key));
console.log("Cache cleared successfully"); console.log("Cache cleared successfully");
return true; return true;
}, },
@@ -368,7 +368,7 @@ const CacheManager = (function() {
let memoryCacheSize = 0; let memoryCacheSize = 0;
let memoryCacheItems = 0; let memoryCacheItems = 0;
let memoryCacheExpired = 0; let memoryCacheExpired = 0;
memoryCache.forEach((item, key) => { memoryCache.forEach((item, key) => {
if (isCacheKey(key)) { if (isCacheKey(key)) {
memoryCacheItems++; memoryCacheItems++;
@@ -381,7 +381,7 @@ const CacheManager = (function() {
} }
} }
}); });
return { return {
totalSizeMB: (totalSize / 1024 / 1024).toFixed(2), totalSizeMB: (totalSize / 1024 / 1024).toFixed(2),
itemCount, itemCount,
@@ -415,10 +415,10 @@ const CacheManager = (function() {
} }
} }
}); });
console.log(`Migrated ${migratedCount} items from memory cache to localStorage.`); console.log(`Migrated ${migratedCount} items from memory cache to localStorage.`);
} }
return { return {
available: storageAvailable, available: storageAvailable,
type: storageAvailable ? 'localStorage' : 'memory' type: storageAvailable ? 'localStorage' : 'memory'
@@ -430,7 +430,7 @@ const CacheManager = (function() {
...cacheAPI, ...cacheAPI,
setPrices: function(priceData, customTtl = null) { setPrices: function(priceData, customTtl = null) {
return this.set(PRICES_CACHE_KEY, priceData, return this.set(PRICES_CACHE_KEY, priceData,
customTtl || (typeof customTtl === 'undefined' ? 'prices' : null)); customTtl || (typeof customTtl === 'undefined' ? 'prices' : null));
}, },
@@ -447,7 +447,7 @@ const CacheManager = (function() {
const normalizedSymbol = symbol.toLowerCase(); const normalizedSymbol = symbol.toLowerCase();
return prices.value[normalizedSymbol] || null; return prices.value[normalizedSymbol] || null;
}, },
getCompatiblePrices: function(format) { getCompatiblePrices: function(format) {
const prices = this.getPrices(); const prices = this.getPrices();
if (!prices || !prices.value) { if (!prices || !prices.value) {
@@ -464,7 +464,7 @@ const CacheManager = (function() {
.join(' ') .join(' ')
.toLowerCase() .toLowerCase()
.replace(' ', '-'); .replace(' ', '-');
ratesFormat[coinKey] = { ratesFormat[coinKey] = {
usd: data.price || data.usd, usd: data.price || data.usd,
btc: data.price_btc || data.btc btc: data.price_btc || data.btc
@@ -493,7 +493,7 @@ const CacheManager = (function() {
value: geckoFormat, value: geckoFormat,
remainingTime: prices.remainingTime remainingTime: prices.remainingTime
}; };
default: default:
return prices; return prices;
} }

View File

@@ -111,8 +111,8 @@ const CleanupManager = (function() {
} }
state.eventListeners = state.eventListeners.filter( state.eventListeners = state.eventListeners.filter(
listener => !(listener.element === element && listener => !(listener.element === element &&
listener.type === type && listener.type === type &&
listener.handler === handler) listener.handler === handler)
); );
}, },
@@ -224,10 +224,10 @@ const CleanupManager = (function() {
intervals: state.intervals.length, intervals: state.intervals.length,
animationFrames: state.animationFrames.length, animationFrames: state.animationFrames.length,
resources: state.resources.size, resources: state.resources.size,
total: state.eventListeners.length + total: state.eventListeners.length +
state.timeouts.length + state.timeouts.length +
state.intervals.length + state.intervals.length +
state.animationFrames.length + state.animationFrames.length +
state.resources.size state.resources.size
}; };
}, },

View File

@@ -4,9 +4,9 @@ const ConfigManager = (function() {
}; };
function determineWebSocketPort() { function determineWebSocketPort() {
const wsPort = const wsPort =
window.ws_port || window.ws_port ||
(typeof getWebSocketConfig === 'function' ? getWebSocketConfig().port : null) || (typeof getWebSocketConfig === 'function' ? getWebSocketConfig().port : null) ||
'11700'; '11700';
return wsPort; return wsPort;
} }
@@ -17,10 +17,10 @@ const ConfigManager = (function() {
cacheDuration: 10 * 60 * 1000, cacheDuration: 10 * 60 * 1000,
requestTimeout: 60000, requestTimeout: 60000,
wsPort: selectedWsPort, wsPort: selectedWsPort,
cacheConfig: { cacheConfig: {
defaultTTL: 10 * 60 * 1000, defaultTTL: 10 * 60 * 1000,
ttlSettings: { ttlSettings: {
prices: 5 * 60 * 1000, prices: 5 * 60 * 1000,
chart: 5 * 60 * 1000, chart: 5 * 60 * 1000,
@@ -34,7 +34,7 @@ const ConfigManager = (function() {
maxSizeBytes: 10 * 1024 * 1024, maxSizeBytes: 10 * 1024 * 1024,
maxItems: 200 maxItems: 200
}, },
fallbackTTL: 24 * 60 * 60 * 1000 fallbackTTL: 24 * 60 * 60 * 1000
}, },
@@ -92,7 +92,7 @@ const ConfigManager = (function() {
'Bitcoin Cash': 'BCH', 'Bitcoin Cash': 'BCH',
'Dogecoin': 'DOGE' 'Dogecoin': 'DOGE'
}, },
nameToDisplayName: { nameToDisplayName: {
'Bitcoin': 'Bitcoin', 'Bitcoin': 'Bitcoin',
'Litecoin': 'Litecoin', 'Litecoin': 'Litecoin',
@@ -164,13 +164,13 @@ const ConfigManager = (function() {
if (options) { if (options) {
Object.assign(this, options); Object.assign(this, options);
} }
if (window.CleanupManager) { if (window.CleanupManager) {
window.CleanupManager.registerResource('configManager', this, (mgr) => mgr.dispose()); window.CleanupManager.registerResource('configManager', this, (mgr) => mgr.dispose());
} }
this.utils = utils; this.utils = utils;
state.isInitialized = true; state.isInitialized = true;
console.log('ConfigManager initialized'); console.log('ConfigManager initialized');
return this; return this;
@@ -205,7 +205,7 @@ const ConfigManager = (function() {
const lowerCoinName = typeof coinName === 'string' ? coinName.toLowerCase() : ''; const lowerCoinName = typeof coinName === 'string' ? coinName.toLowerCase() : '';
return nameMap[lowerCoinName] || lowerCoinName; return nameMap[lowerCoinName] || lowerCoinName;
}, },
coinMatches: function(offerCoin, filterCoin) { coinMatches: function(offerCoin, filterCoin) {
if (!offerCoin || !filterCoin) return false; if (!offerCoin || !filterCoin) return false;
@@ -254,7 +254,7 @@ const ConfigManager = (function() {
get: function(path, defaultValue = null) { get: function(path, defaultValue = null) {
const parts = path.split('.'); const parts = path.split('.');
let current = this; let current = this;
for (let i = 0; i < parts.length; i++) { for (let i = 0; i < parts.length; i++) {
if (current === undefined || current === null) { if (current === undefined || current === null) {
return defaultValue; return defaultValue;
@@ -376,12 +376,12 @@ const ConfigManager = (function() {
'firo': { usd: null, btc: null } 'firo': { usd: null, btc: null }
}; };
}, },
getCoinSymbol: function(fullName) { getCoinSymbol: function(fullName) {
return publicAPI.coinMappings?.nameToSymbol[fullName] || fullName; return publicAPI.coinMappings?.nameToSymbol[fullName] || fullName;
} }
}; };
return publicAPI; return publicAPI;
})(); })();

View File

@@ -60,7 +60,7 @@ const IdentityManager = (function() {
const oldestEntries = [...state.cache.entries()] const oldestEntries = [...state.cache.entries()]
.sort((a, b) => a[1].timestamp - b[1].timestamp) .sort((a, b) => a[1].timestamp - b[1].timestamp)
.slice(0, Math.floor(state.config.maxCacheSize * 0.2)); .slice(0, Math.floor(state.config.maxCacheSize * 0.2));
oldestEntries.forEach(([key]) => { oldestEntries.forEach(([key]) => {
state.cache.delete(key); state.cache.delete(key);
log(`Pruned cache entry for ${key}`); log(`Pruned cache entry for ${key}`);
@@ -88,10 +88,10 @@ const IdentityManager = (function() {
const entriesToRemove = [...state.cache.entries()] const entriesToRemove = [...state.cache.entries()]
.sort((a, b) => a[1].timestamp - b[1].timestamp) .sort((a, b) => a[1].timestamp - b[1].timestamp)
.slice(0, state.cache.size - maxSize); .slice(0, state.cache.size - maxSize);
entriesToRemove.forEach(([key]) => state.cache.delete(key)); entriesToRemove.forEach(([key]) => state.cache.delete(key));
log(`Limited cache size, removed ${entriesToRemove.length} entries`); log(`Limited cache size, removed ${entriesToRemove.length} entries`);
return entriesToRemove.length; return entriesToRemove.length;
}, },
@@ -138,11 +138,11 @@ const IdentityManager = (function() {
if (options) { if (options) {
this.configure(options); this.configure(options);
} }
if (window.CleanupManager) { if (window.CleanupManager) {
window.CleanupManager.registerResource('identityManager', this, (mgr) => mgr.dispose()); window.CleanupManager.registerResource('identityManager', this, (mgr) => mgr.dispose());
} }
log('IdentityManager initialized'); log('IdentityManager initialized');
return this; return this;
}, },

View File

@@ -65,7 +65,7 @@ const MemoryManager = (function() {
const nodeCount = document.querySelectorAll('*').length; const nodeCount = document.querySelectorAll('*').length;
console.log('DOM node count:', nodeCount); console.log('DOM node count:', nodeCount);
if (window.CleanupManager) { if (window.CleanupManager) {
const counts = CleanupManager.getResourceCounts(); const counts = CleanupManager.getResourceCounts();
console.log('Managed resources:', counts); console.log('Managed resources:', counts);
@@ -102,11 +102,11 @@ const MemoryManager = (function() {
state.cleanupInterval = setInterval(() => { state.cleanupInterval = setInterval(() => {
this.forceCleanup(); this.forceCleanup();
}, interval); }, interval);
log('Auto-cleanup enabled every', interval/1000, 'seconds'); log('Auto-cleanup enabled every', interval/1000, 'seconds');
return true; return true;
}, },
disableAutoCleanup: function() { disableAutoCleanup: function() {
if (state.cleanupInterval) { if (state.cleanupInterval) {
clearInterval(state.cleanupInterval); clearInterval(state.cleanupInterval);
@@ -155,7 +155,7 @@ const MemoryManager = (function() {
return true; return true;
}, },
setDebugMode: function(enabled) { setDebugMode: function(enabled) {
config.debug = Boolean(enabled); config.debug = Boolean(enabled);
return `Debug mode ${config.debug ? 'enabled' : 'disabled'}`; return `Debug mode ${config.debug ? 'enabled' : 'disabled'}`;

View File

@@ -30,13 +30,13 @@ const NetworkManager = (function() {
const publicAPI = { const publicAPI = {
initialize: function(options = {}) { initialize: function(options = {}) {
Object.assign(config, options); Object.assign(config, options);
window.addEventListener('online', this.handleOnlineStatus.bind(this)); window.addEventListener('online', this.handleOnlineStatus.bind(this));
window.addEventListener('offline', this.handleOfflineStatus.bind(this)); window.addEventListener('offline', this.handleOfflineStatus.bind(this));
state.isOnline = navigator.onLine; state.isOnline = navigator.onLine;
log(`Network status initialized: ${state.isOnline ? 'online' : 'offline'}`); log(`Network status initialized: ${state.isOnline ? 'online' : 'offline'}`);
if (window.CleanupManager) { if (window.CleanupManager) {
window.CleanupManager.registerResource('networkManager', this, (mgr) => mgr.dispose()); window.CleanupManager.registerResource('networkManager', this, (mgr) => mgr.dispose());
} }
@@ -61,7 +61,7 @@ const NetworkManager = (function() {
log('Browser reports online status'); log('Browser reports online status');
state.isOnline = true; state.isOnline = true;
this.notifyHandlers('online'); this.notifyHandlers('online');
if (state.reconnectTimer) { if (state.reconnectTimer) {
this.scheduleReconnectRefresh(); this.scheduleReconnectRefresh();
} }
@@ -103,7 +103,7 @@ const NetworkManager = (function() {
state.reconnectTimer = null; state.reconnectTimer = null;
} }
const delay = config.reconnectDelay * Math.pow(config.reconnectBackoff, const delay = config.reconnectDelay * Math.pow(config.reconnectBackoff,
Math.min(state.reconnectAttempts, 5)); Math.min(state.reconnectAttempts, 5));
log(`Scheduling reconnection attempt in ${delay/1000} seconds`); log(`Scheduling reconnection attempt in ${delay/1000} seconds`);
@@ -145,7 +145,7 @@ const NetworkManager = (function() {
this.notifyHandlers('reconnected'); this.notifyHandlers('reconnected');
} else { } else {
log('Backend still unavailable'); log('Backend still unavailable');
if (state.reconnectAttempts < config.maxReconnectAttempts) { if (state.reconnectAttempts < config.maxReconnectAttempts) {
this.scheduleReconnectRefresh(); this.scheduleReconnectRefresh();
} else { } else {
@@ -157,7 +157,7 @@ const NetworkManager = (function() {
.catch(error => { .catch(error => {
state.connectionTestInProgress = false; state.connectionTestInProgress = false;
log('Error during connection test:', error); log('Error during connection test:', error);
if (state.reconnectAttempts < config.maxReconnectAttempts) { if (state.reconnectAttempts < config.maxReconnectAttempts) {
this.scheduleReconnectRefresh(); this.scheduleReconnectRefresh();
} else { } else {
@@ -210,7 +210,7 @@ const NetworkManager = (function() {
const handlerId = generateHandlerId(); const handlerId = generateHandlerId();
state.eventHandlers[event][handlerId] = handler; state.eventHandlers[event][handlerId] = handler;
return handlerId; return handlerId;
}, },
@@ -256,9 +256,9 @@ const NetworkManager = (function() {
window.removeEventListener('online', this.handleOnlineStatus); window.removeEventListener('online', this.handleOnlineStatus);
window.removeEventListener('offline', this.handleOfflineStatus); window.removeEventListener('offline', this.handleOfflineStatus);
state.eventHandlers = {}; state.eventHandlers = {};
log('NetworkManager disposed'); log('NetworkManager disposed');
} }
}; };

View File

@@ -15,9 +15,9 @@ const SummaryManager = (function() {
function updateElement(elementId, value) { function updateElement(elementId, value) {
const element = document.getElementById(elementId); const element = document.getElementById(elementId);
if (!element) return false; if (!element) return false;
const safeValue = (value !== undefined && value !== null) const safeValue = (value !== undefined && value !== null)
? value ? value
: (element.dataset.lastValue || 0); : (element.dataset.lastValue || 0);
element.dataset.lastValue = safeValue; element.dataset.lastValue = safeValue;
@@ -32,8 +32,8 @@ const SummaryManager = (function() {
element.textContent = safeValue; element.textContent = safeValue;
} }
if (['offers-counter', 'bid-requests-counter', 'sent-bids-counter', if (['offers-counter', 'bid-requests-counter', 'sent-bids-counter',
'recv-bids-counter', 'swaps-counter', 'network-offers-counter', 'recv-bids-counter', 'swaps-counter', 'network-offers-counter',
'watched-outputs-counter'].includes(elementId)) { 'watched-outputs-counter'].includes(elementId)) {
element.classList.remove('bg-blue-500', 'bg-gray-400'); element.classList.remove('bg-blue-500', 'bg-gray-400');
element.classList.add(safeValue > 0 ? 'bg-blue-500' : 'bg-gray-400'); element.classList.add(safeValue > 0 ? 'bg-blue-500' : 'bg-gray-400');
@@ -57,7 +57,7 @@ const SummaryManager = (function() {
function updateUIFromData(data) { function updateUIFromData(data) {
if (!data) return; if (!data) return;
updateElement('network-offers-counter', data.num_network_offers); updateElement('network-offers-counter', data.num_network_offers);
updateElement('offers-counter', data.num_sent_active_offers); updateElement('offers-counter', data.num_sent_active_offers);
updateElement('sent-bids-counter', data.num_sent_active_bids); updateElement('sent-bids-counter', data.num_sent_active_bids);
@@ -65,7 +65,7 @@ const SummaryManager = (function() {
updateElement('bid-requests-counter', data.num_available_bids); updateElement('bid-requests-counter', data.num_available_bids);
updateElement('swaps-counter', data.num_swapping); updateElement('swaps-counter', data.num_swapping);
updateElement('watched-outputs-counter', data.num_watched_outputs); updateElement('watched-outputs-counter', data.num_watched_outputs);
const shutdownButtons = document.querySelectorAll('.shutdown-button'); const shutdownButtons = document.querySelectorAll('.shutdown-button');
shutdownButtons.forEach(button => { shutdownButtons.forEach(button => {
button.setAttribute('data-active-swaps', data.num_swapping); button.setAttribute('data-active-swaps', data.num_swapping);
@@ -83,7 +83,7 @@ const SummaryManager = (function() {
function cacheSummaryData(data) { function cacheSummaryData(data) {
if (!data) return; if (!data) return;
localStorage.setItem('summary_data_cache', JSON.stringify({ localStorage.setItem('summary_data_cache', JSON.stringify({
timestamp: Date.now(), timestamp: Date.now(),
data: data data: data
@@ -92,24 +92,24 @@ const SummaryManager = (function() {
function getCachedSummaryData() { function getCachedSummaryData() {
let cachedData = null; let cachedData = null;
cachedData = localStorage.getItem('summary_data_cache'); cachedData = localStorage.getItem('summary_data_cache');
if (!cachedData) return null; if (!cachedData) return null;
const parsedCache = JSON.parse(cachedData); const parsedCache = JSON.parse(cachedData);
const maxAge = 24 * 60 * 60 * 1000; const maxAge = 24 * 60 * 60 * 1000;
if (Date.now() - parsedCache.timestamp < maxAge) { if (Date.now() - parsedCache.timestamp < maxAge) {
return parsedCache.data; return parsedCache.data;
} }
return null; return null;
} }
function fetchSummaryDataWithTimeout() { function fetchSummaryDataWithTimeout() {
const controller = new AbortController(); const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), config.requestTimeout); const timeoutId = setTimeout(() => controller.abort(), config.requestTimeout);
return fetch(config.summaryEndpoint, { return fetch(config.summaryEndpoint, {
signal: controller.signal, signal: controller.signal,
headers: { headers: {
@@ -120,11 +120,11 @@ const SummaryManager = (function() {
}) })
.then(response => { .then(response => {
clearTimeout(timeoutId); clearTimeout(timeoutId);
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`); throw new Error(`HTTP error! Status: ${response.status}`);
} }
return response.json(); return response.json();
}) })
.catch(error => { .catch(error => {
@@ -138,21 +138,21 @@ const SummaryManager = (function() {
webSocket.close(); webSocket.close();
} }
const wsPort = window.config?.wsPort || const wsPort = window.config?.wsPort ||
(typeof determineWebSocketPort === 'function' ? determineWebSocketPort() : '11700'); (typeof determineWebSocketPort === 'function' ? determineWebSocketPort() : '11700');
const wsUrl = "ws://" + window.location.hostname + ":" + wsPort; const wsUrl = "ws://" + window.location.hostname + ":" + wsPort;
webSocket = new WebSocket(wsUrl); webSocket = new WebSocket(wsUrl);
webSocket.onopen = () => { webSocket.onopen = () => {
publicAPI.fetchSummaryData() publicAPI.fetchSummaryData()
.then(() => {}) .then(() => {})
.catch(() => {}); .catch(() => {});
}; };
webSocket.onmessage = (event) => { webSocket.onmessage = (event) => {
let data; let data;
try { try {
data = JSON.parse(event.data); data = JSON.parse(event.data);
} catch (error) { } catch (error) {
@@ -161,18 +161,18 @@ const SummaryManager = (function() {
} }
return; return;
} }
if (data.event) { if (data.event) {
publicAPI.fetchSummaryData() publicAPI.fetchSummaryData()
.then(() => {}) .then(() => {})
.catch(() => {}); .catch(() => {});
if (window.NotificationManager && typeof window.NotificationManager.handleWebSocketEvent === 'function') { if (window.NotificationManager && typeof window.NotificationManager.handleWebSocketEvent === 'function') {
window.NotificationManager.handleWebSocketEvent(data); window.NotificationManager.handleWebSocketEvent(data);
} }
} }
}; };
webSocket.onclose = () => { webSocket.onclose = () => {
setTimeout(setupWebSocket, 5000); setTimeout(setupWebSocket, 5000);
}; };
@@ -185,8 +185,8 @@ const SummaryManager = (function() {
template.innerHTML = document.querySelector('[id^="swapContainer"]')?.innerHTML || ''; template.innerHTML = document.querySelector('[id^="swapContainer"]')?.innerHTML || '';
document.body.appendChild(template); document.body.appendChild(template);
} }
if (!document.getElementById('swap-in-progress-green-template') && if (!document.getElementById('swap-in-progress-green-template') &&
document.querySelector('[id^="swapContainer"]')?.innerHTML) { document.querySelector('[id^="swapContainer"]')?.innerHTML) {
const greenTemplate = document.createElement('template'); const greenTemplate = document.createElement('template');
greenTemplate.id = 'swap-in-progress-green-template'; greenTemplate.id = 'swap-in-progress-green-template';
@@ -229,7 +229,7 @@ const SummaryManager = (function() {
if (window.WebSocketManager && typeof window.WebSocketManager.initialize === 'function') { if (window.WebSocketManager && typeof window.WebSocketManager.initialize === 'function') {
const wsManager = window.WebSocketManager; const wsManager = window.WebSocketManager;
if (!wsManager.isConnected()) { if (!wsManager.isConnected()) {
wsManager.connect(); wsManager.connect();
} }
@@ -239,7 +239,7 @@ const SummaryManager = (function() {
this.fetchSummaryData() this.fetchSummaryData()
.then(() => {}) .then(() => {})
.catch(() => {}); .catch(() => {});
if (window.NotificationManager && typeof window.NotificationManager.handleWebSocketEvent === 'function') { if (window.NotificationManager && typeof window.NotificationManager.handleWebSocketEvent === 'function') {
window.NotificationManager.handleWebSocketEvent(data); window.NotificationManager.handleWebSocketEvent(data);
} }
@@ -302,7 +302,7 @@ const SummaryManager = (function() {
} }
}); });
}, },
startRefreshTimer: function() { startRefreshTimer: function() {
startRefreshTimer(); startRefreshTimer();
}, },

View File

@@ -26,14 +26,14 @@ const TooltipManager = (function() {
create(element, content, options = {}) { create(element, content, options = {}) {
if (!element) return null; if (!element) return null;
this.destroy(element); this.destroy(element);
if (this.tooltipElementsMap.size > this.maxTooltips * this.cleanupThreshold) { if (this.tooltipElementsMap.size > this.maxTooltips * this.cleanupThreshold) {
const oldestEntries = Array.from(this.tooltipElementsMap.entries()) const oldestEntries = Array.from(this.tooltipElementsMap.entries())
.sort((a, b) => a[1].timestamp - b[1].timestamp) .sort((a, b) => a[1].timestamp - b[1].timestamp)
.slice(0, 20); .slice(0, 20);
oldestEntries.forEach(([el]) => { oldestEntries.forEach(([el]) => {
this.destroy(el); this.destroy(el);
}); });
@@ -199,7 +199,7 @@ const TooltipManager = (function() {
instance[0].destroy(); instance[0].destroy();
} catch (e) { } catch (e) {
console.warn('Error destroying tooltip:', e); console.warn('Error destroying tooltip:', e);
const tippyRoot = document.querySelector(`[data-for-tooltip-id="${id}"]`); const tippyRoot = document.querySelector(`[data-for-tooltip-id="${id}"]`);
if (tippyRoot && tippyRoot.parentNode) { if (tippyRoot && tippyRoot.parentNode) {
tippyRoot.parentNode.removeChild(tippyRoot); tippyRoot.parentNode.removeChild(tippyRoot);
@@ -209,7 +209,7 @@ const TooltipManager = (function() {
this.activeTooltips.delete(element); this.activeTooltips.delete(element);
this.tooltipElementsMap.delete(element); this.tooltipElementsMap.delete(element);
element.removeAttribute('data-tooltip-trigger-id'); element.removeAttribute('data-tooltip-trigger-id');
} }
@@ -355,7 +355,7 @@ const TooltipManager = (function() {
this.handleVisibilityChange = () => { this.handleVisibilityChange = () => {
if (document.hidden) { if (document.hidden) {
this.cleanup(); this.cleanup();
if (window.MemoryManager) { if (window.MemoryManager) {
window.MemoryManager.forceCleanup(); window.MemoryManager.forceCleanup();
} }
@@ -365,7 +365,7 @@ const TooltipManager = (function() {
window.addEventListener('beforeunload', this.boundCleanup); window.addEventListener('beforeunload', this.boundCleanup);
window.addEventListener('unload', this.boundCleanup); window.addEventListener('unload', this.boundCleanup);
document.addEventListener('visibilitychange', this.handleVisibilityChange); document.addEventListener('visibilitychange', this.handleVisibilityChange);
if (window.CleanupManager) { if (window.CleanupManager) {
window.CleanupManager.registerResource('tooltipManager', this, (tm) => tm.dispose()); window.CleanupManager.registerResource('tooltipManager', this, (tm) => tm.dispose());
} }
@@ -471,7 +471,7 @@ const TooltipManager = (function() {
} }
}); });
this.mutationObserver.observe(document.body, { this.mutationObserver.observe(document.body, {
childList: true, childList: true,
subtree: true subtree: true
}); });
@@ -497,7 +497,7 @@ const TooltipManager = (function() {
cancelAnimationFrame(id); cancelAnimationFrame(id);
}); });
this.pendingAnimationFrames.clear(); this.pendingAnimationFrames.clear();
if (this.mutationObserver) { if (this.mutationObserver) {
this.mutationObserver.disconnect(); this.mutationObserver.disconnect();
this.mutationObserver = null; this.mutationObserver = null;

View File

@@ -37,7 +37,7 @@ const WalletManager = (function() {
'Decred': 'DCR', 'Decred': 'DCR',
'Bitcoin Cash': 'BCH' 'Bitcoin Cash': 'BCH'
}, },
coingeckoIds: { coingeckoIds: {
'BTC': 'btc', 'BTC': 'btc',
'PART': 'part', 'PART': 'part',
@@ -51,7 +51,7 @@ const WalletManager = (function() {
'DCR': 'dcr', 'DCR': 'dcr',
'BCH': 'bch' 'BCH': 'bch'
}, },
shortNames: { shortNames: {
'Bitcoin': 'BTC', 'Bitcoin': 'BTC',
'Particl': 'PART', 'Particl': 'PART',
@@ -99,9 +99,9 @@ const WalletManager = (function() {
try { try {
const processedData = {}; const processedData = {};
const currentSource = config.priceSource.primary; const currentSource = config.priceSource.primary;
const shouldIncludeWow = currentSource === 'coingecko.com'; const shouldIncludeWow = currentSource === 'coingecko.com';
const coinsToFetch = Object.values(coinData.symbols) const coinsToFetch = Object.values(coinData.symbols)
.filter(symbol => shouldIncludeWow || symbol !== 'WOW') .filter(symbol => shouldIncludeWow || symbol !== 'WOW')
.map(symbol => coinData.coingeckoIds[symbol] || symbol.toLowerCase()) .map(symbol => coinData.coingeckoIds[symbol] || symbol.toLowerCase())
@@ -171,8 +171,8 @@ const WalletManager = (function() {
lastError = error; lastError = error;
console.error(`Price fetch attempt ${attempt + 1} failed:`, error); console.error(`Price fetch attempt ${attempt + 1} failed:`, error);
if (attempt === config.maxRetries - 1 && if (attempt === config.maxRetries - 1 &&
config.priceSource.fallback && config.priceSource.fallback &&
config.priceSource.fallback !== config.priceSource.primary) { config.priceSource.fallback !== config.priceSource.primary) {
const temp = config.priceSource.primary; const temp = config.priceSource.primary;
config.priceSource.primary = config.priceSource.fallback; config.priceSource.primary = config.priceSource.fallback;
@@ -269,14 +269,14 @@ const WalletManager = (function() {
} }
const coinId = coinName.toLowerCase().replace(' ', '-'); const coinId = coinName.toLowerCase().replace(' ', '-');
if (!prices[coinId]) { if (!prices[coinId]) {
return; return;
} }
const price = prices[coinId]?.usd || parseFloat(localStorage.getItem(`${coinId}-price`) || '0'); const price = prices[coinId]?.usd || parseFloat(localStorage.getItem(`${coinId}-price`) || '0');
if (!price) return; if (!price) return;
const usdValue = (amount * price).toFixed(2); const usdValue = (amount * price).toFixed(2);
if (coinName === 'Particl') { if (coinName === 'Particl') {
@@ -300,7 +300,7 @@ const WalletManager = (function() {
} }
let usdEl = null; let usdEl = null;
const flexContainer = el.closest('.flex'); const flexContainer = el.closest('.flex');
if (flexContainer) { if (flexContainer) {
const nextFlex = flexContainer.nextElementSibling; const nextFlex = flexContainer.nextElementSibling;
@@ -384,7 +384,7 @@ const WalletManager = (function() {
return false; return false;
} }
} }
function updateTotalValues(totalUsd, btcPrice) { function updateTotalValues(totalUsd, btcPrice) {
const totalUsdEl = document.getElementById('total-usd-value'); const totalUsdEl = document.getElementById('total-usd-value');
if (totalUsdEl) { if (totalUsdEl) {
@@ -439,7 +439,7 @@ const WalletManager = (function() {
const eyeIcon = document.querySelector("#hide-usd-amount-toggle svg"); const eyeIcon = document.querySelector("#hide-usd-amount-toggle svg");
if (eyeIcon) { if (eyeIcon) {
eyeIcon.innerHTML = isVisible ? eyeIcon.innerHTML = isVisible ?
'<path d="M23.444,10.239C21.905,8.062,17.708,3,12,3S2.1,8.062,.555,10.24a3.058,3.058,0,0,0,0,3.52h0C2.1,15.938,6.292,21,12,21s9.905-5.062,11.445-7.24A3.058,3.058,0,0,0,23.444,10.239ZM12,17a5,5,0,1,1,5-5A5,5,0,0,1,12,17Z"></path>' : '<path d="M23.444,10.239C21.905,8.062,17.708,3,12,3S2.1,8.062,.555,10.24a3.058,3.058,0,0,0,0,3.52h0C2.1,15.938,6.292,21,12,21s9.905-5.062,11.445-7.24A3.058,3.058,0,0,0,23.444,10.239ZM12,17a5,5,0,1,1,5-5A5,5,0,0,1,12,17Z"></path>' :
'<path d="M23.444,10.239a22.936,22.936,0,0,0-2.492-2.948l-4.021,4.021A5.026,5.026,0,0,1,17,12a5,5,0,0,1-5,5,5.026,5.026,0,0,1-.688-.069L8.055,20.188A10.286,10.286,0,0,0,12,21c5.708,0,9.905-5.062,11.445-7.24A3.058,3.058,0,0,0,23.444,10.239Z"></path><path d="M12,3C6.292,3,2.1,8.062,.555,10.24a3.058,3.058,0,0,0,0,3.52h0a21.272,21.272,0,0,0,4.784,4.9l3.124-3.124a5,5,0,0,1,7.071-7.072L8.464,15.536l10.2-10.2A11.484,11.484,0,0,0,12,3Z"></path><path data-color="color-2" d="M1,24a1,1,0,0,1-.707-1.707l22-22a1,1,0,0,1,1.414,1.414l-22,22A1,1,0,0,1,1,24Z"></path>'; '<path d="M23.444,10.239a22.936,22.936,0,0,0-2.492-2.948l-4.021,4.021A5.026,5.026,0,0,1,17,12a5,5,0,0,1-5,5,5.026,5.026,0,0,1-.688-.069L8.055,20.188A10.286,10.286,0,0,0,12,21c5.708,0,9.905-5.062,11.445-7.24A3.058,3.058,0,0,0,23.444,10.239Z"></path><path d="M12,3C6.292,3,2.1,8.062,.555,10.24a3.058,3.058,0,0,0,0,3.52h0a21.272,21.272,0,0,0,4.784,4.9l3.124-3.124a5,5,0,0,1,7.071-7.072L8.464,15.536l10.2-10.2A11.484,11.484,0,0,0,12,3Z"></path><path data-color="color-2" d="M1,24a1,1,0,0,1-.707-1.707l22-22a1,1,0,0,1,1.414,1.414l-22,22A1,1,0,0,1,1,24Z"></path>';
} }
@@ -500,7 +500,7 @@ const WalletManager = (function() {
document.querySelectorAll('.coinname-value').forEach(el => { document.querySelectorAll('.coinname-value').forEach(el => {
el.textContent = '****'; el.textContent = '****';
}); });
document.querySelectorAll('.usd-value').forEach(el => { document.querySelectorAll('.usd-value').forEach(el => {
el.textContent = '****'; el.textContent = '****';
}); });
@@ -542,7 +542,7 @@ const WalletManager = (function() {
} }
state.lastUpdateTime = parseInt(localStorage.getItem(stateKeys.lastUpdate) || '0'); state.lastUpdateTime = parseInt(localStorage.getItem(stateKeys.lastUpdate) || '0');
state.isWalletsPage = document.querySelector('.wallet-list') !== null || state.isWalletsPage = document.querySelector('.wallet-list') !== null ||
window.location.pathname.includes('/wallets'); window.location.pathname.includes('/wallets');
document.querySelectorAll('.usd-value').forEach(el => { document.querySelectorAll('.usd-value').forEach(el => {
@@ -553,7 +553,7 @@ const WalletManager = (function() {
}); });
storeOriginalValues(); storeOriginalValues();
if (localStorage.getItem('balancesVisible') === null) { if (localStorage.getItem('balancesVisible') === null) {
localStorage.setItem('balancesVisible', 'true'); localStorage.setItem('balancesVisible', 'true');
} }
@@ -581,7 +581,7 @@ const WalletManager = (function() {
state.initialized = true; state.initialized = true;
console.log('WalletManager initialized'); console.log('WalletManager initialized');
return this; return this;
}, },
@@ -606,7 +606,7 @@ const WalletManager = (function() {
if (fallbackSource) { if (fallbackSource) {
config.priceSource.fallback = fallbackSource; config.priceSource.fallback = fallbackSource;
} }
return this; return this;
}, },

View File

@@ -43,12 +43,12 @@ const WebSocketManager = (function() {
wsPort = window.ws_port.toString(); wsPort = window.ws_port.toString();
return wsPort; return wsPort;
} }
if (typeof getWebSocketConfig === 'function') { if (typeof getWebSocketConfig === 'function') {
const wsConfig = getWebSocketConfig(); const wsConfig = getWebSocketConfig();
wsPort = (wsConfig.port || wsConfig.fallbackPort || '11700').toString(); wsPort = (wsConfig.port || wsConfig.fallbackPort || '11700').toString();
return wsPort; return wsPort;
} }
wsPort = '11700'; wsPort = '11700';
return wsPort; return wsPort;
@@ -62,14 +62,14 @@ const WebSocketManager = (function() {
startHealthCheck(); startHealthCheck();
log('WebSocketManager initialized with options:', options); log('WebSocketManager initialized with options:', options);
if (window.CleanupManager) { if (window.CleanupManager) {
window.CleanupManager.registerResource('webSocketManager', this, (mgr) => mgr.dispose()); window.CleanupManager.registerResource('webSocketManager', this, (mgr) => mgr.dispose());
} }
return this; return this;
}, },
connect: function() { connect: function() {
if (state.isConnecting || state.isIntentionallyClosed) { if (state.isConnecting || state.isIntentionallyClosed) {
log('Connection attempt blocked - already connecting or intentionally closed'); log('Connection attempt blocked - already connecting or intentionally closed');
@@ -87,7 +87,7 @@ const WebSocketManager = (function() {
try { try {
const wsPort = determineWebSocketPort(); const wsPort = determineWebSocketPort();
if (!wsPort) { if (!wsPort) {
state.isConnecting = false; state.isConnecting = false;
return false; return false;
@@ -129,7 +129,7 @@ const WebSocketManager = (function() {
log('Cannot send message - not connected'); log('Cannot send message - not connected');
return false; return false;
} }
try { try {
ws.send(JSON.stringify(message)); ws.send(JSON.stringify(message));
return true; return true;
@@ -143,13 +143,13 @@ const WebSocketManager = (function() {
if (!state.messageHandlers[type]) { if (!state.messageHandlers[type]) {
state.messageHandlers[type] = {}; state.messageHandlers[type] = {};
} }
const handlerId = generateHandlerId(); const handlerId = generateHandlerId();
state.messageHandlers[type][handlerId] = handler; state.messageHandlers[type][handlerId] = handler;
return handlerId; return handlerId;
}, },
removeMessageHandler: function(type, handlerId) { removeMessageHandler: function(type, handlerId) {
if (state.messageHandlers[type] && state.messageHandlers[type][handlerId]) { if (state.messageHandlers[type] && state.messageHandlers[type][handlerId]) {
delete state.messageHandlers[type][handlerId]; delete state.messageHandlers[type][handlerId];
@@ -158,7 +158,7 @@ const WebSocketManager = (function() {
cleanup: function() { cleanup: function() {
log('Cleaning up WebSocket resources'); log('Cleaning up WebSocket resources');
clearTimeout(state.connectTimeout); clearTimeout(state.connectTimeout);
stopHealthCheck(); stopHealthCheck();
@@ -211,11 +211,11 @@ const WebSocketManager = (function() {
resume: function() { resume: function() {
log('WebSocketManager resumed'); log('WebSocketManager resumed');
state.isIntentionallyClosed = false; state.isIntentionallyClosed = false;
if (!this.isConnected()) { if (!this.isConnected()) {
this.connect(); this.connect();
} }
startHealthCheck(); startHealthCheck();
} }
}; };
@@ -264,16 +264,16 @@ const WebSocketManager = (function() {
log('WebSocket closed:', event); log('WebSocket closed:', event);
state.isConnecting = false; state.isConnecting = false;
window.ws = null; window.ws = null;
if (typeof updateConnectionStatus === 'function') { if (typeof updateConnectionStatus === 'function') {
updateConnectionStatus('disconnected'); updateConnectionStatus('disconnected');
} }
notifyHandlers('disconnect', { notifyHandlers('disconnect', {
code: event.code, code: event.code,
reason: event.reason reason: event.reason
}); });
if (!state.isIntentionallyClosed) { if (!state.isIntentionallyClosed) {
handleReconnect(); handleReconnect();
} }
@@ -292,12 +292,12 @@ const WebSocketManager = (function() {
document.addEventListener('visibilitychange', visibilityChangeHandler); document.addEventListener('visibilitychange', visibilityChangeHandler);
state.listeners.visibilityChange = visibilityChangeHandler; state.listeners.visibilityChange = visibilityChangeHandler;
} }
function handlePageHidden() { function handlePageHidden() {
log('Page hidden'); log('Page hidden');
state.isPageHidden = true; state.isPageHidden = true;
stopHealthCheck(); stopHealthCheck();
if (ws && ws.readyState === WebSocket.OPEN) { if (ws && ws.readyState === WebSocket.OPEN) {
state.isIntentionallyClosed = true; state.isIntentionallyClosed = true;
ws.close(1000, 'Page hidden'); ws.close(1000, 'Page hidden');
@@ -308,7 +308,7 @@ const WebSocketManager = (function() {
log('Page visible'); log('Page visible');
state.isPageHidden = false; state.isPageHidden = false;
state.isIntentionallyClosed = false; state.isIntentionallyClosed = false;
setTimeout(() => { setTimeout(() => {
if (!publicAPI.isConnected()) { if (!publicAPI.isConnected()) {
publicAPI.connect(); publicAPI.connect();
@@ -323,7 +323,7 @@ const WebSocketManager = (function() {
performHealthCheck(); performHealthCheck();
}, 30000); }, 30000);
} }
function stopHealthCheck() { function stopHealthCheck() {
if (state.healthCheckInterval) { if (state.healthCheckInterval) {
clearInterval(state.healthCheckInterval); clearInterval(state.healthCheckInterval);
@@ -340,7 +340,7 @@ const WebSocketManager = (function() {
const now = Date.now(); const now = Date.now();
const lastCheck = state.lastHealthCheck; const lastCheck = state.lastHealthCheck;
if (lastCheck && (now - lastCheck) > 60000) { if (lastCheck && (now - lastCheck) > 60000) {
log('Health check failed - too long since last check'); log('Health check failed - too long since last check');
handleReconnect(); handleReconnect();
@@ -401,10 +401,10 @@ const WebSocketManager = (function() {
function cleanup() { function cleanup() {
log('Cleaning up WebSocket resources'); log('Cleaning up WebSocket resources');
clearTimeout(state.connectTimeout); clearTimeout(state.connectTimeout);
stopHealthCheck(); stopHealthCheck();
if (state.reconnectTimeout) { if (state.reconnectTimeout) {
clearTimeout(state.reconnectTimeout); clearTimeout(state.reconnectTimeout);
state.reconnectTimeout = null; state.reconnectTimeout = null;

View File

@@ -61,7 +61,7 @@ const Ajax = {
if (xhr.status === 200) { if (xhr.status === 200) {
if (onSuccess) { if (onSuccess) {
try { try {
const response = xhr.responseText.startsWith('{') ? const response = xhr.responseText.startsWith('{') ?
JSON.parse(xhr.responseText) : xhr.responseText; JSON.parse(xhr.responseText) : xhr.responseText;
onSuccess(response); onSuccess(response);
} catch (e) { } catch (e) {
@@ -153,10 +153,10 @@ const RateManager = {
const params = 'coin_from=' + selectedCoin + '&coin_to=' + coinTo; const params = 'coin_from=' + selectedCoin + '&coin_to=' + coinTo;
Ajax.post('/json/rates', params, Ajax.post('/json/rates', params,
(response) => { (response) => {
if (ratesDisplay) { if (ratesDisplay) {
ratesDisplay.innerHTML = typeof response === 'string' ? ratesDisplay.innerHTML = typeof response === 'string' ?
response : '<pre><code>' + JSON.stringify(response, null, ' ') + '</code></pre>'; response : '<pre><code>' + JSON.stringify(response, null, ' ') + '</code></pre>';
} }
}, },
@@ -167,7 +167,7 @@ const RateManager = {
} }
); );
}, },
getRateInferred: (event) => { getRateInferred: (event) => {
if (event) event.preventDefault(); if (event) event.preventDefault();
@@ -180,12 +180,12 @@ const RateManager = {
return; return;
} }
const params = 'coin_from=' + encodeURIComponent(coinFrom) + const params = 'coin_from=' + encodeURIComponent(coinFrom) +
'&coin_to=' + encodeURIComponent(coinTo); '&coin_to=' + encodeURIComponent(coinTo);
DOM.setValue('rate', 'Loading...'); DOM.setValue('rate', 'Loading...');
Ajax.post('/json/rates', params, Ajax.post('/json/rates', params,
(response) => { (response) => {
if (response.coingecko && response.coingecko.rate_inferred) { if (response.coingecko && response.coingecko.rate_inferred) {
DOM.setValue('rate', response.coingecko.rate_inferred); DOM.setValue('rate', response.coingecko.rate_inferred);
@@ -213,7 +213,7 @@ const RateManager = {
swapType: DOM.get('swap_type') swapType: DOM.get('swap_type')
}; };
if (!elements.coinFrom || !elements.coinTo || if (!elements.coinFrom || !elements.coinTo ||
!elements.amtFrom || !elements.amtTo || !elements.rate) { !elements.amtFrom || !elements.amtTo || !elements.rate) {
console.log('Required elements for setRate not found'); console.log('Required elements for setRate not found');
return; return;
@@ -225,7 +225,7 @@ const RateManager = {
amtFrom: elements.amtFrom.value, amtFrom: elements.amtFrom.value,
amtTo: elements.amtTo.value, amtTo: elements.amtTo.value,
rate: elements.rate.value, rate: elements.rate.value,
lockRate: elements.rate.value == '' ? false : lockRate: elements.rate.value == '' ? false :
(elements.rateLock ? elements.rateLock.checked : false) (elements.rateLock ? elements.rateLock.checked : false)
}; };
@@ -236,8 +236,8 @@ const RateManager = {
if (elements.swapType) { if (elements.swapType) {
SwapTypeManager.setSwapTypeEnabled( SwapTypeManager.setSwapTypeEnabled(
values.coinFrom, values.coinFrom,
values.coinTo, values.coinTo,
elements.swapType elements.swapType
); );
} }
@@ -248,8 +248,8 @@ const RateManager = {
let params = 'coin_from=' + values.coinFrom + '&coin_to=' + values.coinTo; let params = 'coin_from=' + values.coinFrom + '&coin_to=' + values.coinTo;
if (valueChanged == 'rate' || if (valueChanged == 'rate' ||
(values.lockRate && valueChanged == 'amt_from') || (values.lockRate && valueChanged == 'amt_from') ||
(values.amtTo == '' && valueChanged == 'amt_from')) { (values.amtTo == '' && valueChanged == 'amt_from')) {
if (values.rate == '' || (values.amtFrom == '' && values.amtTo == '')) { if (values.rate == '' || (values.amtFrom == '' && values.amtTo == '')) {
@@ -274,7 +274,7 @@ const RateManager = {
params += '&amt_from=' + values.amtFrom + '&amt_to=' + values.amtTo; params += '&amt_from=' + values.amtFrom + '&amt_to=' + values.amtTo;
} }
Ajax.post('/json/rate', params, Ajax.post('/json/rate', params,
(response) => { (response) => {
if (response.hasOwnProperty('rate')) { if (response.hasOwnProperty('rate')) {
DOM.setValue('rate', response.rate); DOM.setValue('rate', response.rate);
@@ -314,13 +314,13 @@ const SwapTypeManager = {
coinFrom = String(coinFrom); coinFrom = String(coinFrom);
coinTo = String(coinTo); coinTo = String(coinTo);
if (SwapTypeManager.adaptor_sig_only_coins.includes(coinFrom) || if (SwapTypeManager.adaptor_sig_only_coins.includes(coinFrom) ||
SwapTypeManager.adaptor_sig_only_coins.includes(coinTo)) { SwapTypeManager.adaptor_sig_only_coins.includes(coinTo)) {
swapTypeElement.disabled = true; swapTypeElement.disabled = true;
swapTypeElement.value = 'xmr_swap'; swapTypeElement.value = 'xmr_swap';
makeHidden = true; makeHidden = true;
swapTypeElement.classList.add('select-disabled'); swapTypeElement.classList.add('select-disabled');
} else if (SwapTypeManager.secret_hash_only_coins.includes(coinFrom) || } else if (SwapTypeManager.secret_hash_only_coins.includes(coinFrom) ||
SwapTypeManager.secret_hash_only_coins.includes(coinTo)) { SwapTypeManager.secret_hash_only_coins.includes(coinTo)) {
swapTypeElement.disabled = true; swapTypeElement.disabled = true;
swapTypeElement.value = 'seller_first'; swapTypeElement.value = 'seller_first';
@@ -426,7 +426,7 @@ const UIEnhancer = {
const name = selectedOption.textContent.trim(); const name = selectedOption.textContent.trim();
selectCache[select.id] = { image, name }; selectCache[select.id] = { image, name };
} }
function setSelectData(select) { function setSelectData(select) {
if (!select || !select.options || select.selectedIndex === undefined) return; if (!select || !select.options || select.selectedIndex === undefined) return;
@@ -457,9 +457,9 @@ const UIEnhancer = {
const options = select.querySelectorAll('option'); const options = select.querySelectorAll('option');
const selectIcon = select.parentElement?.querySelector('.select-icon'); const selectIcon = select.parentElement?.querySelector('.select-icon');
const selectImage = select.parentElement?.querySelector('.select-image'); const selectImage = select.parentElement?.querySelector('.select-image');
if (!options || !selectIcon || !selectImage) return; if (!options || !selectIcon || !selectImage) return;
options.forEach(option => { options.forEach(option => {
const image = option.getAttribute('data-image'); const image = option.getAttribute('data-image');
if (image) { if (image) {
@@ -476,7 +476,7 @@ const UIEnhancer = {
setSelectData(select); setSelectData(select);
Storage.setRaw(select.name, select.value); Storage.setRaw(select.name, select.value);
}); });
setSelectData(select); setSelectData(select);
selectIcon.style.display = 'none'; selectIcon.style.display = 'none';
selectImage.style.display = 'none'; selectImage.style.display = 'none';

View File

@@ -145,7 +145,7 @@ const api = {
const apiResponse = await Api.fetchCoinGeckoData({ const apiResponse = await Api.fetchCoinGeckoData({
coinGecko: window.config.getAPIKeys().coinGecko coinGecko: window.config.getAPIKeys().coinGecko
}); });
if (!apiResponse || !apiResponse.rates) { if (!apiResponse || !apiResponse.rates) {
if (fallbackData) { if (fallbackData) {
return fallbackData; return fallbackData;
@@ -174,7 +174,7 @@ const api = {
const wowResponse = await Api.fetchCoinPrices("wownero", { const wowResponse = await Api.fetchCoinPrices("wownero", {
coinGecko: window.config.getAPIKeys().coinGecko coinGecko: window.config.getAPIKeys().coinGecko
}); });
if (wowResponse && wowResponse.rates && wowResponse.rates.wownero) { if (wowResponse && wowResponse.rates && wowResponse.rates.wownero) {
transformedData['wow'] = { transformedData['wow'] = {
current_price: wowResponse.rates.wownero, current_price: wowResponse.rates.wownero,
@@ -189,9 +189,9 @@ const api = {
console.error('Error fetching WOW price:', wowError); console.error('Error fetching WOW price:', wowError);
} }
const missingCoins = window.config.coins.filter(coin => const missingCoins = window.config.coins.filter(coin =>
!transformedData[coin.symbol.toLowerCase()] && !transformedData[coin.symbol.toLowerCase()] &&
fallbackData && fallbackData &&
fallbackData[coin.symbol.toLowerCase()] fallbackData[coin.symbol.toLowerCase()]
); );
@@ -203,11 +203,11 @@ const api = {
}); });
CacheManager.set(cacheKey, transformedData, 'prices'); CacheManager.set(cacheKey, transformedData, 'prices');
if (NetworkManager.getReconnectAttempts() > 0) { if (NetworkManager.getReconnectAttempts() > 0) {
NetworkManager.resetReconnectAttempts(); NetworkManager.resetReconnectAttempts();
} }
return transformedData; return transformedData;
} catch (error) { } catch (error) {
console.error('Error fetching coin data:', error); console.error('Error fetching coin data:', error);
@@ -250,8 +250,8 @@ const api = {
} }
const historicalData = await Api.fetchHistoricalData( const historicalData = await Api.fetchHistoricalData(
coinSymbols, coinSymbols,
window.config.currentResolution, window.config.currentResolution,
{ {
cryptoCompare: window.config.getAPIKeys().cryptoCompare cryptoCompare: window.config.getAPIKeys().cryptoCompare
} }
@@ -260,7 +260,7 @@ const api = {
Object.keys(historicalData).forEach(coin => { Object.keys(historicalData).forEach(coin => {
if (historicalData[coin]) { if (historicalData[coin]) {
results[coin] = historicalData[coin]; results[coin] = historicalData[coin];
const cacheKey = `historical_${coin}_${window.config.currentResolution}`; const cacheKey = `historical_${coin}_${window.config.currentResolution}`;
CacheManager.set(cacheKey, historicalData[coin], 'historical'); CacheManager.set(cacheKey, historicalData[coin], 'historical');
} }
@@ -279,7 +279,7 @@ const api = {
results[coin] = cachedData.value; results[coin] = cachedData.value;
} }
} }
return results; return results;
} }
}, },
@@ -317,7 +317,7 @@ const rateLimiter = {
try { try {
await this.requestQueue[apiName]; await this.requestQueue[apiName];
const executeRequest = async () => { const executeRequest = async () => {
const waitTime = this.getWaitTime(apiName); const waitTime = this.getWaitTime(apiName);
if (waitTime > 0) { if (waitTime > 0) {
@@ -335,7 +335,7 @@ const rateLimiter = {
return this.queueRequest(apiName, requestFn, retryCount + 1); return this.queueRequest(apiName, requestFn, retryCount + 1);
} }
if ((error.message.includes('timeout') || error.name === 'NetworkError') && if ((error.message.includes('timeout') || error.name === 'NetworkError') &&
retryCount < this.retryDelays.length) { retryCount < this.retryDelays.length) {
const delay = this.retryDelays[retryCount]; const delay = this.retryDelays[retryCount];
logger.warn(`Request failed, retrying in ${delay/1000} seconds...`); logger.warn(`Request failed, retrying in ${delay/1000} seconds...`);
@@ -350,12 +350,12 @@ const rateLimiter = {
this.requestQueue[apiName] = executeRequest(); this.requestQueue[apiName] = executeRequest();
return await this.requestQueue[apiName]; return await this.requestQueue[apiName];
} catch (error) { } catch (error) {
if (error.message.includes('429') || if (error.message.includes('429') ||
error.message.includes('timeout') || error.message.includes('timeout') ||
error.name === 'NetworkError') { error.name === 'NetworkError') {
NetworkManager.handleNetworkError(error); NetworkManager.handleNetworkError(error);
const cachedData = CacheManager.get(`coinData_${apiName}`); const cachedData = CacheManager.get(`coinData_${apiName}`);
if (cachedData) { if (cachedData) {
return cachedData.value; return cachedData.value;
@@ -375,7 +375,7 @@ const ui = {
const volumeElement = document.querySelector(`#${coin.toLowerCase()}-volume-24h`); const volumeElement = document.querySelector(`#${coin.toLowerCase()}-volume-24h`);
const btcPriceDiv = document.querySelector(`#${coin.toLowerCase()}-btc-price-div`); const btcPriceDiv = document.querySelector(`#${coin.toLowerCase()}-btc-price-div`);
const priceBtcElement = document.querySelector(`#${coin.toLowerCase()}-price-btc`); const priceBtcElement = document.querySelector(`#${coin.toLowerCase()}-price-btc`);
if (priceUsdElement) { if (priceUsdElement) {
priceUsdElement.textContent = isError ? 'N/A' : `$ ${ui.formatPrice(coin, priceUSD)}`; priceUsdElement.textContent = isError ? 'N/A' : `$ ${ui.formatPrice(coin, priceUSD)}`;
} }
@@ -490,8 +490,8 @@ const ui = {
if (priceChange === null || priceChange === undefined) { if (priceChange === null || priceChange === undefined) {
container.innerHTML = 'N/A'; container.innerHTML = 'N/A';
} else { } else {
container.innerHTML = priceChange >= 0 ? container.innerHTML = priceChange >= 0 ?
ui.positivePriceChangeHTML(priceChange) : ui.positivePriceChangeHTML(priceChange) :
ui.negativePriceChangeHTML(priceChange); ui.negativePriceChangeHTML(priceChange);
} }
} }
@@ -504,7 +504,7 @@ const ui = {
lastRefreshedElement.textContent = `Last Refreshed: ${formattedTime}`; lastRefreshedElement.textContent = `Last Refreshed: ${formattedTime}`;
} }
}, },
updateConnectionStatus: () => { updateConnectionStatus: () => {
const statusElement = document.getElementById('connection-status'); const statusElement = document.getElementById('connection-status');
if (statusElement) { if (statusElement) {
@@ -599,12 +599,12 @@ const ui = {
NetworkManager.manualReconnect(); NetworkManager.manualReconnect();
}; };
const buttonContainer = errorOverlay.querySelector('.button-container') || const buttonContainer = errorOverlay.querySelector('.button-container') ||
document.createElement('div'); document.createElement('div');
buttonContainer.className = "button-container mt-4"; buttonContainer.className = "button-container mt-4";
buttonContainer.innerHTML = ''; buttonContainer.innerHTML = '';
buttonContainer.appendChild(reconnectBtn); buttonContainer.appendChild(reconnectBtn);
if (!errorOverlay.querySelector('.button-container')) { if (!errorOverlay.querySelector('.button-container')) {
errorOverlay.querySelector('div').appendChild(buttonContainer); errorOverlay.querySelector('div').appendChild(buttonContainer);
} }
@@ -701,7 +701,7 @@ const chartModule = {
const gradient = ctx.createLinearGradient(0, 0, 0, 400); const gradient = ctx.createLinearGradient(0, 0, 0, 400);
gradient.addColorStop(0, 'rgba(77, 132, 240, 0.2)'); gradient.addColorStop(0, 'rgba(77, 132, 240, 0.2)');
gradient.addColorStop(1, 'rgba(77, 132, 240, 0)'); gradient.addColorStop(1, 'rgba(77, 132, 240, 0)');
chartModule.chart = new Chart(ctx, { chartModule.chart = new Chart(ctx, {
type: 'line', type: 'line',
data: { data: {
@@ -897,7 +897,7 @@ const chartModule = {
} }
rawDataPoints.sort((a, b) => a.time - b.time); rawDataPoints.sort((a, b) => a.time - b.time);
let preparedData = []; let preparedData = [];
if (window.config.currentResolution === 'day') { if (window.config.currentResolution === 'day') {
@@ -918,7 +918,7 @@ const chartModule = {
closestPoint = point; closestPoint = point;
} }
} }
if (closestPoint) { if (closestPoint) {
preparedData.push({ preparedData.push({
x: hourUnix, x: hourUnix,
@@ -940,7 +940,7 @@ const chartModule = {
y: point.close y: point.close
})); }));
} }
if (preparedData.length === 0 && rawDataPoints.length > 0) { if (preparedData.length === 0 && rawDataPoints.length > 0) {
preparedData = rawDataPoints.map(point => ({ preparedData = rawDataPoints.map(point => ({
x: point.time, x: point.time,
@@ -965,7 +965,7 @@ const chartModule = {
if (data.length > 0) { if (data.length > 0) {
const closestDataPoint = data.reduce((prev, curr) => const closestDataPoint = data.reduce((prev, curr) =>
Math.abs(new Date(curr.x).getTime() - targetTime.getTime()) < Math.abs(new Date(curr.x).getTime() - targetTime.getTime()) <
Math.abs(new Date(prev.x).getTime() - targetTime.getTime()) ? curr : prev Math.abs(new Date(prev.x).getTime() - targetTime.getTime()) ? curr : prev
, data[0]); , data[0]);
hourlyData.push({ hourlyData.push({
@@ -989,7 +989,7 @@ const chartModule = {
} }
chartModule.loadStartTime = Date.now(); chartModule.loadStartTime = Date.now();
const cacheKey = `chartData_${coinSymbol}_${window.config.currentResolution}`; const cacheKey = `chartData_${coinSymbol}_${window.config.currentResolution}`;
let cachedData = !forceRefresh ? CacheManager.get(cacheKey) : null; const cachedData = !forceRefresh ? CacheManager.get(cacheKey) : null;
let data; let data;
if (cachedData && Object.keys(cachedData.value).length > 0) { if (cachedData && Object.keys(cachedData.value).length > 0) {
data = cachedData.value; data = cachedData.value;
@@ -1001,7 +1001,7 @@ const chartModule = {
const allData = await api.fetchHistoricalDataXHR([coinSymbol]); const allData = await api.fetchHistoricalDataXHR([coinSymbol]);
data = allData[coinSymbol]; data = allData[coinSymbol];
if (!data || Object.keys(data).length === 0) { if (!data || Object.keys(data).length === 0) {
throw new Error(`No data returned for ${coinSymbol}`); throw new Error(`No data returned for ${coinSymbol}`);
} }
@@ -1009,7 +1009,7 @@ const chartModule = {
CacheManager.set(cacheKey, data, 'chart'); CacheManager.set(cacheKey, data, 'chart');
} catch (error) { } catch (error) {
NetworkManager.handleNetworkError(error); NetworkManager.handleNetworkError(error);
if (error.message.includes('429') && currentChartData.length > 0) { if (error.message.includes('429') && currentChartData.length > 0) {
console.warn(`Rate limit hit for ${coinSymbol}, maintaining current chart`); console.warn(`Rate limit hit for ${coinSymbol}, maintaining current chart`);
chartModule.hideChartLoader(); chartModule.hideChartLoader();
@@ -1041,7 +1041,7 @@ const chartModule = {
chartModule.chart.options.scales.x.time.unit = 'hour'; chartModule.chart.options.scales.x.time.unit = 'hour';
} else { } else {
const resolution = window.config.chartConfig.resolutions[window.config.currentResolution]; const resolution = window.config.chartConfig.resolutions[window.config.currentResolution];
chartModule.chart.options.scales.x.time.unit = chartModule.chart.options.scales.x.time.unit =
resolution && resolution.interval === 'hourly' ? 'hour' : resolution && resolution.interval === 'hourly' ? 'hour' :
window.config.currentResolution === 'year' ? 'month' : 'day'; window.config.currentResolution === 'year' ? 'month' : 'day';
} }
@@ -1086,7 +1086,7 @@ const chartModule = {
loader.classList.add('hidden'); loader.classList.add('hidden');
chart.classList.remove('hidden'); chart.classList.remove('hidden');
}, },
cleanup: function() { cleanup: function() {
this.destroyChart(); this.destroyChart();
this.currentCoin = null; this.currentCoin = null;
@@ -1181,7 +1181,7 @@ const app = {
0 0
); );
}); });
return app; return app;
}, },
@@ -1223,13 +1223,13 @@ const app = {
} }
} }
}, },
loadAllCoinData: async function() { loadAllCoinData: async function() {
try { try {
if (!NetworkManager.isOnline()) { if (!NetworkManager.isOnline()) {
throw new Error('Network is offline'); throw new Error('Network is offline');
} }
const allCoinData = await api.fetchCoinGeckoDataXHR(); const allCoinData = await api.fetchCoinGeckoDataXHR();
if (allCoinData.error) { if (allCoinData.error) {
throw new Error(allCoinData.error); throw new Error(allCoinData.error);
@@ -1242,7 +1242,7 @@ const app = {
for (const coin of window.config.coins) { for (const coin of window.config.coins) {
const coinData = allCoinData[coin.symbol.toLowerCase()]; const coinData = allCoinData[coin.symbol.toLowerCase()];
if (coinData) { if (coinData) {
coinData.displayName = coin.displayName || coin.symbol; coinData.displayName = coin.displayName || coin.symbol;
@@ -1409,7 +1409,7 @@ const app = {
const lastGeckoRequest = rateLimiter.lastRequestTime['coingecko'] || 0; const lastGeckoRequest = rateLimiter.lastRequestTime['coingecko'] || 0;
const timeSinceLastRequest = Date.now() - lastGeckoRequest; const timeSinceLastRequest = Date.now() - lastGeckoRequest;
const waitTime = Math.max(0, rateLimiter.minRequestInterval.coingecko - timeSinceLastRequest); const waitTime = Math.max(0, rateLimiter.minRequestInterval.coingecko - timeSinceLastRequest);
if (waitTime > 0) { if (waitTime > 0) {
const seconds = Math.ceil(waitTime / 1000); const seconds = Math.ceil(waitTime / 1000);
ui.displayErrorMessage(`Rate limit: Please wait ${seconds} seconds before refreshing`); ui.displayErrorMessage(`Rate limit: Please wait ${seconds} seconds before refreshing`);
@@ -1480,7 +1480,7 @@ const app = {
if (cachedData && cachedData.value && cachedData.value.total_volume) { if (cachedData && cachedData.value && cachedData.value.total_volume) {
coinData.total_volume = cachedData.value.total_volume; coinData.total_volume = cachedData.value.total_volume;
} }
if (cachedData && cachedData.value && cachedData.value.price_change_percentage_24h && if (cachedData && cachedData.value && cachedData.value.price_change_percentage_24h &&
!coinData.price_change_percentage_24h) { !coinData.price_change_percentage_24h) {
coinData.price_change_percentage_24h = cachedData.value.price_change_percentage_24h; coinData.price_change_percentage_24h = cachedData.value.price_change_percentage_24h;
} }
@@ -1541,7 +1541,7 @@ const app = {
let countdown = 10; let countdown = 10;
ui.displayErrorMessage(`Refresh failed: ${error.message}. Please try again later. (${countdown}s)`); ui.displayErrorMessage(`Refresh failed: ${error.message}. Please try again later. (${countdown}s)`);
const countdownInterval = setInterval(() => { const countdownInterval = setInterval(() => {
countdown--; countdown--;
if (countdown > 0) { if (countdown > 0) {
@@ -1652,7 +1652,7 @@ const app = {
if (!NetworkManager.isOnline()) { if (!NetworkManager.isOnline()) {
throw new Error('Network is offline'); throw new Error('Network is offline');
} }
const response = await Api.fetchCoinPrices("bitcoin"); const response = await Api.fetchCoinPrices("bitcoin");
if (response && response.rates && response.rates.bitcoin) { if (response && response.rates && response.rates.bitcoin) {
@@ -1715,7 +1715,7 @@ resolutionButtons.forEach(button => {
button.addEventListener('click', () => { button.addEventListener('click', () => {
const resolution = button.id.split('-')[1]; const resolution = button.id.split('-')[1];
const currentCoin = chartModule.currentCoin; const currentCoin = chartModule.currentCoin;
if (currentCoin !== 'WOW' || resolution === 'day') { if (currentCoin !== 'WOW' || resolution === 'day') {
window.config.currentResolution = resolution; window.config.currentResolution = resolution;
chartModule.updateChart(currentCoin, true); chartModule.updateChart(currentCoin, true);
@@ -1726,12 +1726,12 @@ resolutionButtons.forEach(button => {
function cleanup() { function cleanup() {
console.log('Starting cleanup process'); console.log('Starting cleanup process');
try { try {
if (window.MemoryManager) { if (window.MemoryManager) {
MemoryManager.forceCleanup(); MemoryManager.forceCleanup();
} }
if (chartModule) { if (chartModule) {
CleanupManager.registerResource('chartModule', chartModule, (cm) => { CleanupManager.registerResource('chartModule', chartModule, (cm) => {
cm.cleanup(); cm.cleanup();
@@ -1752,7 +1752,7 @@ function cleanup() {
const cleanupCounts = CleanupManager.clearAll(); const cleanupCounts = CleanupManager.clearAll();
console.log('All resources cleaned up:', cleanupCounts); console.log('All resources cleaned up:', cleanupCounts);
} catch (error) { } catch (error) {
console.error('Error during cleanup:', error); console.error('Error during cleanup:', error);
CleanupManager.clearAll(); CleanupManager.clearAll();
@@ -1801,7 +1801,7 @@ document.addEventListener('DOMContentLoaded', () => {
NetworkManager.initialize({ NetworkManager.initialize({
connectionTestEndpoint: '/json', connectionTestEndpoint: '/json',
connectionTestTimeout: 3000, connectionTestTimeout: 3000,
reconnectDelay: 5000, reconnectDelay: 5000,
maxReconnectAttempts: 5 maxReconnectAttempts: 5
}); });
window.networkManagerInitialized = true; window.networkManagerInitialized = true;

View File

@@ -85,7 +85,7 @@ const getStatusClass = (status, tx_a, tx_b) => {
const getTxStatusClass = (status) => { const getTxStatusClass = (status) => {
if (!status || status === 'None') return 'text-gray-400'; if (!status || status === 'None') return 'text-gray-400';
if (status.includes('Complete') || status.includes('Confirmed')) { if (status.includes('Complete') || status.includes('Confirmed')) {
return 'text-green-500'; return 'text-green-500';
} }
@@ -545,12 +545,12 @@ async function updateSwapsTable(options = {}) {
const data = await response.json(); const data = await response.json();
//console.log('Received swap data:', data); //console.log('Received swap data:', data);
state.swapsData = Array.isArray(data) state.swapsData = Array.isArray(data)
? data.filter(swap => { ? data.filter(swap => {
const isActive = isActiveSwap(swap); const isActive = isActiveSwap(swap);
//console.log(`Swap ${swap.bid_id}: ${isActive ? 'Active' : 'Inactive'}`, swap.bid_state); //console.log(`Swap ${swap.bid_id}: ${isActive ? 'Active' : 'Inactive'}`, swap.bid_state);
return isActive; return isActive;
}) })
: []; : [];
//console.log('Filtered active swaps:', state.swapsData); //console.log('Filtered active swaps:', state.swapsData);
@@ -570,7 +570,7 @@ async function updateSwapsTable(options = {}) {
} }
const totalPages = Math.ceil(state.swapsData.length / PAGE_SIZE); const totalPages = Math.ceil(state.swapsData.length / PAGE_SIZE);
if (resetPage && state.swapsData.length > 0) { if (resetPage && state.swapsData.length > 0) {
state.currentPage = 1; state.currentPage = 1;
} }
@@ -631,18 +631,18 @@ async function updateSwapsTable(options = {}) {
function isActiveSwap(swap) { function isActiveSwap(swap) {
const activeStates = [ const activeStates = [
'InProgress', 'InProgress',
'Accepted', 'Accepted',
'Delaying', 'Delaying',
'Auto accept delay', 'Auto accept delay',
'Request accepted', 'Request accepted',
//'Received', //'Received',
'Script coin locked', 'Script coin locked',
'Scriptless coin locked', 'Scriptless coin locked',
'Script coin lock released', 'Script coin lock released',
'SendingInitialTx', 'SendingInitialTx',
'SendingPaymentTx', 'SendingPaymentTx',
'Exchanged script lock tx sigs msg', 'Exchanged script lock tx sigs msg',

View File

@@ -62,7 +62,7 @@
this._handleOutsideClick = this._handleOutsideClick.bind(this); this._handleOutsideClick = this._handleOutsideClick.bind(this);
dropdownInstances.push(this); dropdownInstances.push(this);
this.init(); this.init();
} }
@@ -73,7 +73,7 @@
this._targetEl.style.position = 'fixed'; this._targetEl.style.position = 'fixed';
this._targetEl.style.zIndex = '40'; this._targetEl.style.zIndex = '40';
this._targetEl.classList.add('dropdown-menu'); this._targetEl.classList.add('dropdown-menu');
this._setupEventListeners(); this._setupEventListeners();
this._initialized = true; this._initialized = true;
} }
@@ -120,8 +120,8 @@
} }
_handleOutsideClick(e) { _handleOutsideClick(e) {
if (this._visible && if (this._visible &&
!this._targetEl.contains(e.target) && !this._targetEl.contains(e.target) &&
!this._triggerEl.contains(e.target)) { !this._triggerEl.contains(e.target)) {
this.hide(); this.hide();
} }