77 lines
2.0 KiB
JavaScript
77 lines
2.0 KiB
JavaScript
import State from '../core/state.js';
|
|
import { Bus } from '../core/bus.js';
|
|
|
|
function renderAchievements(achievements) {
|
|
const container = document.getElementById('achievements-list');
|
|
if (!container) return;
|
|
|
|
if (!achievements || achievements.length === 0) {
|
|
container.innerHTML = '<div class="achievements-empty">No achievements yet</div>';
|
|
return;
|
|
}
|
|
|
|
// Show last 3
|
|
const last3 = achievements.slice(-3).reverse();
|
|
container.innerHTML = '';
|
|
for (const achId of last3) {
|
|
const item = document.createElement('div');
|
|
item.className = 'achievement-item';
|
|
item.innerHTML = `
|
|
<div class="achievement-icon">${getInitial(achId)}</div>
|
|
<div class="achievement-info">
|
|
<span class="achievement-name">${escapeHtml(achId)}</span>
|
|
<span class="achievement-game">Unlocked</span>
|
|
</div>
|
|
`;
|
|
container.appendChild(item);
|
|
}
|
|
}
|
|
|
|
function getInitial(id) {
|
|
return id.charAt(0).toUpperCase();
|
|
}
|
|
|
|
function escapeHtml(str) {
|
|
const div = document.createElement('div');
|
|
div.textContent = str;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
function showToast({ id, title, desc }) {
|
|
const layer = document.getElementById('toast-layer');
|
|
if (!layer) return;
|
|
|
|
const toast = document.createElement('div');
|
|
toast.className = 'toast';
|
|
toast.innerHTML = `
|
|
<div>
|
|
<div class="toast-title">Achievement Unlocked</div>
|
|
<div class="toast-desc">${escapeHtml(title || desc || id)}</div>
|
|
</div>
|
|
<button class="toast-close" aria-label="Dismiss">×</button>
|
|
`;
|
|
|
|
layer.appendChild(toast);
|
|
|
|
// Close button
|
|
toast.querySelector('.toast-close').addEventListener('click', () => removeToast(toast));
|
|
|
|
// Auto dismiss
|
|
setTimeout(() => removeToast(toast), 4000);
|
|
}
|
|
|
|
function removeToast(toast) {
|
|
if (!toast.parentNode) return;
|
|
toast.classList.add('toast-removing');
|
|
setTimeout(() => toast.remove(), 300);
|
|
}
|
|
|
|
function init() {
|
|
State.subscribe('achievements', renderAchievements);
|
|
|
|
// Listen for achievement unlocks
|
|
Bus.on('achievement:unlocked', showToast);
|
|
}
|
|
|
|
init();
|