janus-scanner-pro / components /real-time-feeds.js
hts-ai's picture
Full Detection
862c6dd verified
class RealTimeFeeds extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
background: #1f2937;
border: 1px solid #ef4444;
border-radius: 5px;
padding: 15px;
margin: 10px 0;
min-height: 200px;
}
.feed-title {
color: #ef4444;
font-weight: bold;
margin-bottom: 10px;
}
.price-item {
display: flex;
justify-content: space-between;
padding: 5px 0;
border-bottom: 1px solid #374151;
}
.price-up {
color: #10b981;
}
.price-down {
color: #ef4444;
}
.update-time {
color: #9ca3af;
font-size: 0.8rem;
margin-top: 10px;
}
.loading {
color: #9ca3af;
text-align: center;
padding: 20px;
}
.error {
color: #ef4444;
text-align: center;
padding: 20px;
}
</style>
<div>
<h4 class="feed-title">Real-Time Crypto & Market Data</h4>
<div id="feed-content">
<div class="loading">Initializing feeds...</div>
</div>
<div class="update-time" id="update-time"></div>
</div>
`;
this.startRealTimeFeed();
}
async startRealTimeFeed() {
try {
await this.updateCryptoPrices();
setInterval(() => this.updateCryptoPrices(), 60000); // Update every minute
} catch (error) {
this.showError('Failed to initialize feeds');
}
}
async updateCryptoPrices() {
try {
const [cryptoResponse, forexResponse] = await Promise.all([
fetch('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum,monero,litecoin&vs_currencies=usd&include_24hr_change=true'),
fetch('https://api.exchangerate-api.com/v4/latest/USD')
]);
if (!cryptoResponse.ok || !forexResponse.ok) {
throw new Error('API response failed');
}
const cryptoPrices = await cryptoResponse.json();
const forexRates = await forexResponse.json();
this.renderContent(cryptoPrices, forexRates);
} catch (error) {
this.showError('Unable to fetch market data');
}
}
renderContent(cryptoPrices, forexRates) {
const content = this.shadowRoot.getElementById('feed-content');
const updateTime = this.shadowRoot.getElementById('update-time');
const cryptoItems = Object.entries(cryptoPrices).map(([coin, data]) => {
const change = data.usd_24h_change || 0;
const changeClass = change >= 0 ? 'price-up' : 'price-down';
const changeSymbol = change >= 0 ? 'β†—' : 'β†˜';
return `
<div class="price-item">
<span>${coin.toUpperCase()}/USD</span>
<span class="${changeClass}">
$${data.usd.toLocaleString()}
<span style="font-size: 0.8em; margin-left: 5px;">
${changeSymbol} ${Math.abs(change).toFixed(2)}%
</span>
</span>
</div>
`;
}).join('');
const forexItems = ['EUR', 'GBP', 'CHF', 'JPY'].map(currency => {
const rate = forexRates.rates[currency];
return `
<div class="price-item">
<span>USD/${currency}</span>
<span>${rate.toFixed(4)}</span>
</div>
`;
}).join('');
content.innerHTML = `
<div style="margin-bottom: 15px;">
<h5 style="color: #ef4444; margin-bottom: 10px; font-size: 0.9em;">Cryptocurrencies</h5>
${cryptoItems}
</div>
<div>
<h5 style="color: #ef4444; margin-bottom: 10px; font-size: 0.9em;">Forex Rates</h5>
${forexItems}
</div>
`;
updateTime.textContent = `Last updated: ${new Date().toLocaleTimeString()}`;
}
showError(message) {
const content = this.shadowRoot.getElementById('feed-content');
content.innerHTML = `<div class="error">${message}</div>`;
}
}
customElements.define('real-time-feeds', RealTimeFeeds);