// Desktop application script for SpotSync Alpha // Tab switching functionality for code preview function showTab(tabName) { // Hide all tabs document.getElementById('main-tab')?.classList.add('hidden'); document.getElementById('watcher-tab')?.classList.add('hidden'); document.getElementById('executor-tab')?.classList.add('hidden'); document.getElementById('models-tab')?.classList.add('hidden'); document.getElementById('security-tab')?.classList.add('hidden'); // Show selected tab document.getElementById(`${tabName}-tab`)?.classList.remove('hidden'); // Update active tab button styles const tabButtons = document.querySelectorAll('[onclick^="showTab"]'); tabButtons.forEach(button => { if (button.textContent.includes(tabName)) { button.classList.remove('text-gray-400', 'hover:text-gray-200'); button.classList.add('border-cyan-500', 'text-cyan-300'); button.classList.add('tab-active'); } else { button.classList.remove('border-cyan-500', 'text-cyan-300', 'tab-active'); button.classList.add('text-gray-400', 'hover:text-gray-200'); } }); } // Copy code to clipboard function copyCode() { const activeTab = document.querySelector('#code-container > pre:not(.hidden)'); if (!activeTab) return; const codeText = activeTab.textContent; // Use Electron's clipboard API if available if (typeof require !== 'undefined') { const { clipboard } = require('electron'); clipboard.writeText(codeText); showDesktopNotification('Code copied to clipboard'); } else { navigator.clipboard.writeText(codeText).then(() => { showDesktopNotification('Code copied to clipboard'); }); } } // Show desktop notification function showDesktopNotification(message, type = 'info') { // Create notification element const notification = document.createElement('div'); notification.className = 'tray-notification desktop-fade-in'; const icon = type === 'success' ? 'check-circle' : type === 'error' ? 'alert-circle' : 'info'; const color = type === 'success' ? 'text-green-400' : type === 'error' ? 'text-red-400' : 'text-cyan-400'; notification.innerHTML = `

${message}

Just now

`; document.body.appendChild(notification); feather.replace(); // Show notification setTimeout(() => notification.classList.add('show'), 10); // Auto remove after 5 seconds setTimeout(() => { if (notification.parentElement) { notification.classList.remove('show'); setTimeout(() => { if (notification.parentElement) { notification.remove(); } }, 300); } }, 5000); } // Simulate live trade data function simulateLiveTrades() { const tradeFeed = document.getElementById('trade-feed'); if (!tradeFeed) return; const trades = [ { symbol: 'BTCUSDT', side: 'BUY', quantity: 0.05, price: '64320.50', time: new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) }, { symbol: 'ETHUSDT', side: 'SELL', quantity: 1.20, price: '3415.75', time: new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) }, { symbol: 'SOLUSDT', side: 'BUY', quantity: 12.50, price: '185.30', time: new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) }, { symbol: 'ADAUSDT', side: 'BUY', quantity: 500, price: '0.6420', time: new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) }, { symbol: 'BNBUSDT', side: 'SELL', quantity: 3.20, price: '420.10', time: new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) } ]; const trade = trades[Math.floor(Math.random() * trades.length)]; const sideClass = trade.side === 'BUY' ? 'text-green-400' : 'text-red-400'; const sideIcon = trade.side === 'BUY' ? 'trending-up' : 'trending-down'; const tradeElement = document.createElement('div'); tradeElement.className = 'flex items-center justify-between p-3 bg-gray-800/50 rounded-lg desktop-fade-in'; tradeElement.innerHTML = `
${trade.symbol} ${trade.quantity} @ ${trade.price}
${trade.time} `; if (tradeFeed.children.length >= 5) { tradeFeed.removeChild(tradeFeed.lastChild); } tradeFeed.insertBefore(tradeElement, tradeFeed.firstChild); feather.replace(); } // Update system metrics periodically function updateMetrics() { const metrics = { 'uptime': '99.8%', 'followers': '3', 'trades': `${Math.floor(Math.random() * 10 + 40)}`, 'success': `${(Math.random() * 2 + 97.5).toFixed(1)}%` }; for (const [key, value] of Object.entries(metrics)) { const element = document.getElementById(`metric-${key}`); if (element) { element.textContent = value; } } } // Toggle engine status function toggleEngineStatus() { const button = document.querySelector('button:has(i[data-feather="pause"])'); const statusLight = document.querySelector('.relative .w-3.h-3'); if (button.innerHTML.includes('Pause')) { button.innerHTML = ' Start Engine'; if (statusLight) { statusLight.classList.remove('bg-green-500'); statusLight.classList.add('bg-yellow-500'); } showDesktopNotification('Trading engine paused', 'info'); } else { button.innerHTML = ' Pause Engine'; if (statusLight) { statusLight.classList.remove('bg-yellow-500'); statusLight.classList.add('bg-green-500'); } showDesktopNotification('Trading engine started', 'success'); } feather.replace(); } // Export logs function function exportLogs() { showDesktopNotification('Exporting trade logs to CSV...', 'info'); // Simulate export process setTimeout(() => { showDesktopNotification('Logs exported successfully to Downloads folder', 'success'); }, 1500); } // Add new follower function addFollower() { showDesktopNotification('Opening follower configuration wizard...', 'info'); // In a real app, this would open a modal or new window setTimeout(() => { const followers = parseInt(document.getElementById('metric-followers').textContent); document.getElementById('metric-followers').textContent = followers + 1; showDesktopNotification('New follower added successfully', 'success'); }, 1000); } // Initialize desktop context menu function initContextMenu() { document.addEventListener('contextmenu', function(e) { e.preventDefault(); // Remove existing context menu const existingMenu = document.getElementById('context-menu'); if (existingMenu) { existingMenu.remove(); } // Create new context menu const contextMenu = document.createElement('div'); contextMenu.id = 'context-menu'; contextMenu.className = 'context-menu'; contextMenu.style.position = 'fixed'; contextMenu.style.left = `${e.pageX}px`; contextMenu.style.top = `${e.pageY}px`; // Menu items based on target const menuItems = [ { label: 'Copy', icon: 'copy', action: () => copyCode() }, { label: 'Refresh', icon: 'refresh-cw', action: () => window.location.reload() }, { label: 'Inspect Element', icon: 'code', action: () => { if (typeof require !== 'undefined') { const { remote } = require('electron'); remote.getCurrentWindow().webContents.openDevTools(); } }}, { label: 'Export Data', icon: 'download', action: () => exportLogs() } ]; menuItems.forEach(item => { const menuItem = document.createElement('div'); menuItem.className = 'context-menu-item flex items-center gap-2'; menuItem.innerHTML = ` ${item.label} `; menuItem.addEventListener('click', () => { item.action(); contextMenu.remove(); }); contextMenu.appendChild(menuItem); }); document.body.appendChild(contextMenu); feather.replace(); // Close menu when clicking elsewhere document.addEventListener('click', function closeMenu() { contextMenu.remove(); document.removeEventListener('click', closeMenu); }); }); } // Initialize all animations and effects function initAnimations() { const elements = document.querySelectorAll('.desktop-fade-in'); elements.forEach((element, index) => { element.style.animationDelay = `${index * 0.1}s`; }); } // Initialize everything when the DOM is loaded document.addEventListener('DOMContentLoaded', function() { // Initialize Feather icons feather.replace(); // Initialize components initAnimations(); initContextMenu(); // Set up intervals for dynamic updates setInterval(simulateLiveTrades, 5000); setInterval(updateMetrics, 3000); // Start with first tab active showTab('main'); // Add event listeners for desktop buttons document.querySelector('button:has(i[data-feather="play"])')?.addEventListener('click', toggleEngineStatus); document.querySelector('button:has(i[data-feather="user-plus"])')?.addEventListener('click', addFollower); document.querySelector('button:has(i[data-feather="download"])')?.addEventListener('click', exportLogs); // Add keyboard shortcuts for desktop document.addEventListener('keydown', function(e) { // Ctrl/Cmd + 1-5 to switch tabs if ((e.ctrlKey || e.metaKey) && e.key >= '1' && e.key <= '5') { const tabNames = ['main', 'watcher', 'executor', 'models', 'security']; const index = parseInt(e.key) - 1; if (tabNames[index]) { showTab(tabNames[index]); e.preventDefault(); } } // Ctrl/Cmd + E to toggle engine if ((e.ctrlKey || e.metaKey) && e.key === 'e') { toggleEngineStatus(); e.preventDefault(); } // Ctrl/Cmd + N to add follower if ((e.ctrlKey || e.metaKey) && e.key === 'n') { addFollower(); e.preventDefault(); } // Ctrl/Cmd + S to export logs if ((e.ctrlKey || e.metaKey) && e.key === 's') { exportLogs(); e.preventDefault(); } // F12 for dev tools if (e.key === 'F12') { if (typeof require !== 'undefined') { const { remote } = require('electron'); remote.getCurrentWindow().webContents.openDevTools(); e.preventDefault(); } } }); // Show welcome notification setTimeout(() => { showDesktopNotification('SpotSync Alpha Desktop is running in system tray', 'info'); }, 1000); });