import { CLOSE_ICON } from './icons.js'; import { logoLockup } from '../logo.js'; import { escapeHtml } from '../util.js'; import { renderCornerRail } from '../cornerRail.js'; import { attachTooltips } from '../tooltip.js'; import { renderTopRail } from '../topRail.js'; import { api, ApiError } from '../api.js'; import { getUser, onAuthChange } from '../auth.js'; // onShowFriends is accepted but not supplied by app.js for this screen - the // top rail's Friends control already points here, so it has nowhere to go. // Declared so the shared rail call below resolves. export function renderFriendsScreen(root, { onBack, onShowFriends, onShowStats, onShowPlaceholder, onShowAccount, onShowLeaderboard, onShowMultiplayer, onShowStore }) { let data = { friends: [], incoming_requests: [], outgoing_requests: [] }; let loadError = null; async function load() { if (!getUser()) return; try { data = await api.get('/api/friends'); loadError = null; } catch (err) { loadError = err instanceof ApiError ? err.message : 'network error'; } } function signedOutMarkup() { return `
Sign in to add friends and compare stats.
`; } function signedInMarkup() { return `
${data.incoming_requests.length > 0 ? `

Requests

${data.incoming_requests.map(r => `
${escapeHtml(r.username)}
`).join('')}
` : ''} ${data.outgoing_requests.length > 0 ? `

Sent

${data.outgoing_requests.map(r => `
${escapeHtml(r.username)}
Pending
`).join('')}
` : ''}

Friends

${data.friends.length > 0 ? `
${data.friends.map(f => `
${escapeHtml(f.username)}
`).join('')}
` : `
No friends yet - add one by username above.
`} ${loadError ? `
${escapeHtml(loadError)}
` : ''} `; } function render() { const user = getUser(); root.innerHTML = `
${logoLockup()}

Friends

${user ? signedInMarkup() : signedOutMarkup()}
`; root.querySelectorAll('[data-action="menu"]').forEach(el => el.addEventListener('click', onBack)); attachTooltips(root); const cleanupTheme = renderTopRail(root, { onShowAccount, onShowFriends }); const goAccount = root.querySelector('[data-action="go-account"]'); if (goAccount) goAccount.addEventListener('click', onShowAccount); const addForm = root.querySelector('.friends-add-form'); if (addForm) { addForm.addEventListener('submit', async e => { e.preventDefault(); const errorEl = addForm.querySelector('.friends-add-error'); errorEl.textContent = ''; const username = addForm.username.value.trim(); try { await api.post('/api/friends/request', { username }); addForm.username.value = ''; await load(); rerender(); } catch (err) { errorEl.textContent = err instanceof ApiError ? err.message : 'Something went wrong - try again.'; } }); } root.querySelectorAll('[data-action="accept"]').forEach(btn => { btn.addEventListener('click', async () => { await api.post(`/api/friends/${btn.dataset.id}/accept`).catch(() => {}); await load(); rerender(); }); }); root.querySelectorAll('[data-action="decline"], [data-action="cancel"], [data-action="unfriend"]').forEach(btn => { btn.addEventListener('click', async () => { await api.delete(`/api/friends/${btn.dataset.id}`).catch(() => {}); await load(); rerender(); }); }); const cleanupRail = renderCornerRail(root, { onShowStats, onShowPlaceholder, onShowAccount, onShowLeaderboard, onShowMultiplayer, onShowStore }); return () => { cleanupTheme(); cleanupRail(); }; } let cleanup; function rerender() { if (cleanup) cleanup(); cleanup = render(); } rerender(); load().then(rerender); const unsubscribeAuth = onAuthChange(() => { load().then(rerender); }); return () => { unsubscribeAuth(); if (cleanup) cleanup(); }; }