coleswebsite/js/presence.js
colevr ec7d0cf56c d
2025-04-21 13:04:14 -05:00

180 lines
No EOL
6.2 KiB
JavaScript

function updateProgressBar(start, end) {
clearInterval(progressInterval);
const discordBox = document.getElementById('discord-activity');
progressInterval = setInterval(() => {
const elapsed = Date.now() - start;
const total = end - start;
const progress = Math.min(Math.max(elapsed / total, 0), 1) * 100;
const timeElems = discordBox.querySelectorAll('.spotify-progress .time');
const fillBar = discordBox.querySelector('.spotify-progress .fill');
if (!fillBar || timeElems.length !== 2) return;
timeElems[0].textContent = formatTime(elapsed);
timeElems[1].textContent = formatTime(total);
fillBar.style.width = `${progress}%`;
if (elapsed >= total) clearInterval(progressInterval);
}, 1000);
}
async function handleActivity(data) {
if (!data) {
console.error("No data received in handleActivity");
return;
}
const now = Date.now();
const discordBox = document.getElementById('discord-activity');
if (!discordBox) {
console.error("Discord activity box not found");
return;
}
let html = '';
// Update status dot
const statusDot = document.querySelector('.status-dot');
if (statusDot) {
const status = data.discord_status || 'offline';
statusDot.className = `status-dot status-${status}`;
}
try {
// Handle Spotify activity
if (data.spotify) {
try {
const s = data.spotify;
// Verify that all required timestamps exist
if (!s.timestamps || !s.timestamps.start || !s.timestamps.end) {
console.warn("Spotify data missing timestamps:", s);
s.timestamps = s.timestamps || {};
s.timestamps.start = s.timestamps.start || now - 60000; // Default to 1 minute ago
s.timestamps.end = s.timestamps.end || now + 180000; // Default to 3 minutes from now
}
const total = s.timestamps.end - s.timestamps.start;
const elapsed = now - s.timestamps.start;
const progress = Math.min(Math.max(elapsed / total, 0), 1) * 100;
// Handle missing album art
const albumArt = s.album_art_url || 'icons/spotify.png';
const trackId = s.track_id || '';
html += `
<div class="presence-entry spotify-presence">
<img src="${albumArt}" class="album-art" onerror="this.src='icons/spotify.png'">
<div class="music-info">
<a class="song-title" href="https://open.spotify.com/track/${trackId}" target="_blank">
<img src="icons/spotify.png" class="spotify-icon" />
${s.song || 'Unknown Track'}
</a>
<div class="artist">${s.artist || 'Unknown Artist'}${s.album || 'Unknown Album'}</div>
<div class="spotify-progress">
<div class="time">${formatTime(elapsed)}</div>
<div class="bar"><div class="fill" style="width:${progress}%"></div></div>
<div class="time">${formatTime(total)}</div>
</div>
</div>
</div>
`;
updateProgressBar(s.timestamps.start, s.timestamps.end);
// Log the track if it's new or has been more than 30 seconds
if (!musicLogs.length || musicLogs[0].track_id !== s.track_id || now - musicLogs[0].loggedAt > 30000) {
try {
musicLogs.unshift({
track_id: s.track_id || '',
song: s.song || 'Unknown Track',
artist: s.artist || 'Unknown Artist',
album: s.album || 'Unknown Album',
album_art_url: albumArt,
loggedAt: now
});
if (musicLogs.length > 300) musicLogs.pop();
await saveLogs();
} catch (err) {
console.error("Error logging music:", err);
}
}
} catch (err) {
console.error("Error processing Spotify data:", err);
}
} else {
clearInterval(progressInterval);
}
// Handle activities (games)
if (data.activities && Array.isArray(data.activities)) {
const games = data.activities.filter(a => a && a.type === 0 && a.name !== 'Custom Status');
const currentGame = games[0];
if (currentGame) {
try {
const gameKey = `${currentGame.name}:${currentGame.details || ''}:${currentGame.state || ''}`;
const top = gameLogs[0];
const topKey = top ? `${top.name}:${top.details || ''}:${top.state || ''}` : '';
if (gameKey !== topKey) {
try {
gameLogs.unshift({
name: currentGame.name || 'Unknown Game',
details: currentGame.details || '',
state: currentGame.state || '',
icon: currentGame.application_id || null,
loggedAt: now
});
if (gameLogs.length > 300) gameLogs = gameLogs.slice(0, 300);
await saveLogs();
} catch (err) {
console.error("Error logging game:", err);
}
}
} catch (err) {
console.error("Error processing game data:", err);
}
}
if (games.length > 0) {
games.forEach(g => {
try {
const icon = g.application_id
? `https://dcdn.dstn.to/app-icons/${g.application_id}?ext=webp&size=64`
: 'https://cdn.discordapp.com/embed/avatars/0.png';
html += `
<div class="presence-entry">
<img src="${icon}" class="album-art" onerror="this.src='icons/discord.svg'">
<div class="music-info">
<div class="song-title">${g.name || 'Playing a game'}</div>
<div class="artist">${g.details || ''}</div>
<div class="artist">${g.state || ''}</div>
</div>
</div>
`;
} catch (err) {
console.error("Error rendering game:", err);
}
});
}
}
} catch (err) {
console.error("Error in activity processing:", err);
}
try {
discordBox.innerHTML = html || 'Not currently playing anything.';
discordBox.classList.toggle('active', !!html);
// No need for inline styles since we've properly styled the elements in CSS
} catch (err) {
console.error("Error updating Discord box:", err);
}
}