import {apiFetch} from './api.js'; const CORE = () => import.meta.env.VITE_CORE_API_URL; // The order of the groups in the details. const KINDS = ['ADDED', 'REMOVED', 'PLAYTIME', 'ACHIEVEMENTS', 'STATUS']; /** * `{syncedAt, startedBy, seen, importedGames, changes: [{kind, appid, name, imageUrl, amount, fromStatus, toStatus}]}`, * or null when the user has no result (204) or the answer is not 200. PLAYTIME: amount in minutes, ACHIEVEMENTS: * amount is the number of new unlocks. */ export async function fetchSyncChanges() { const response = await apiFetch(`${CORE()}/api/library/sync-changes`); return response.status === 200 ? response.json() : null; } /** * The result with this `syncedAt` stays seen on every device. A newer result is not touched. */ export const markSyncChangesSeen = (syncedAt) => apiFetch(`${CORE()}/api/library/sync-changes/seen`, { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({syncedAt}), }); /** * What the dashboard shows of a result: null (nothing), `{mode: 'nothing'}` for a manual sync that changed nothing, or * `{mode: 'changes', imported, added, removed, minutes, achievements, moves}`. A result the user saw, and an empty * result of an automatic sync, show nothing. */ export function bannerOf(result) { if (!result || result.seen) return null; const changes = result.changes ?? []; const imported = result.importedGames ?? 0; if (changes.length === 0 && imported === 0) { return result.startedBy === 'MANUAL' ? {mode: 'nothing'} : null; } const of = (kind) => changes.filter((change) => change.kind === kind); const sum = (kind) => of(kind).reduce((total, change) => total + (change.amount ?? 0), 0); return { mode: 'changes', imported, added: of('ADDED').length, removed: of('REMOVED').length, minutes: sum('PLAYTIME'), achievements: sum('ACHIEVEMENTS'), moves: of('STATUS').length, }; } /** * `[{kind, changes}]` for the kinds that have changes, in the order of KINDS. */ export const groupByKind = (changes) => KINDS .map((kind) => ({kind, changes: changes.filter((change) => change.kind === kind)})) .filter((group) => group.changes.length > 0);