import { api, adminApi } from "./api.js"; import { handleAuthError, renderAllSuggestions, renderCounts, renderMySuggestions, renderPhasePill, renderPhaseTitles, renderResults, renderVotes, renderWelcome, setAuthUI, syncVoteScores, updatePhaseNav, openResultsRelockModal, openSuggestionsChangedModal } from "./ui.js"; import { state, clearUserState } from "./state.js"; export async function loadState() { const [me, stateData] = await Promise.all([api.me(), api.state()]); state.isAuthenticated = true; state.me = me; state.hasJoker = me.hasJoker ?? false; state.prevPhase = state.phase; state.phase = stateData.currentPhase; state.resultsOpen = stateData.resultsOpen; state.votesFinal = stateData.votesFinal ?? me?.votesFinal ?? false; state.counts = stateData; if (state.prevPhase !== state.phase && state.phase === "Vote") { state.votesRendered = false; } setAuthUI(true); renderWelcome(); renderPhasePill(); renderCounts(); } export async function loadSuggestData() { if (state.phase !== "Suggest") return; state.mySuggestions = await api.mySuggestions(); renderMySuggestions(); } export async function loadRevealData() { if (state.phase === "Vote" || state.phase === "Results") { const prev = state.allSuggestions ?? []; const prevById = Object.fromEntries(prev.map((s) => [s.id, s])); const latest = await api.allSuggestions(); const latestSig = signatureSuggestions(latest); const changed = latestSig !== state.allSuggestionsSig; if (changed && state.phase === "Vote" && state.allSuggestionsSig) { const added = latest .filter((s) => !prevById[s.id]) .map((s) => s.name); const relinked = latest .filter((s) => { const prevItem = prevById[s.id]; return ( prevItem && prevItem.parentSuggestionId !== s.parentSuggestionId ); }) .map((s) => s.name); const names = [...added, ...relinked]; openSuggestionsChangedModal(names); } state.allSuggestions = latest; state.allSuggestionsSig = latestSig; renderAllSuggestions(); renderPhaseTitles(); if (state.phase === "Vote" && changed) { state.votesRendered = false; } } } export async function loadVoteData() { if (state.phase !== "Vote") return; const votes = await api.myVotes(); state.myVotes = votes; if (!state.votesRendered) { renderVotes(); state.votesRendered = true; } else { syncVoteScores(); } updatePhaseNav(); } export async function loadResults() { if (state.phase !== "Results" || !state.resultsOpen) return; state.results = await api.results(); renderResults(); } export async function refreshPhaseData() { try { const prevPhase = state.phase; const prevResultsOpen = state.resultsOpen; await loadState(); await Promise.all([loadSuggestData(), loadRevealData(), loadResults()]); if (state.phase === "Vote") { if (!state.votesRendered) await loadVoteData(); } else { state.votesRendered = false; await loadVoteData(); } if (state.me?.isAdmin) { state.adminVoteStatus = await adminApi.voteStatus(); } if ( prevPhase === "Results" && state.phase === "Vote" && prevResultsOpen && !state.resultsOpen ) { openResultsRelockModal(); } updatePhaseNav(); } catch (err) { if (handleAuthError(err, clearUserState)) return; throw err; } } export function signatureSuggestions(list) { return JSON.stringify( list.map((s) => [ s.id, s.name, s.genre, s.description, s.screenshotUrl, s.youtubeUrl, s.gameUrl, s.minPlayers, s.maxPlayers, s.parentSuggestionId, s.isOwner, ]), ); }