import {apiFetch} from './api.js'; import {GAME_STATUSES} from './limits.js'; // Radix Select has no empty value, so "no priority" needs its own value in the form. export const NO_PRIORITY = 'NONE'; export const parseStatus = (value) => (GAME_STATUSES.includes(value) ? value : null); export const toBacklogRequest = ({status, rating, notes, priority}) => ({ status, rating: rating || null, notes: notes?.trim() ? notes : null, priority: priority === NO_PRIORITY ? null : priority, }); /** * The fields of `form` that differ from `saved`, in request form: what saveBacklogEntry sends. */ export const changedFields = (saved, form) => { const before = toBacklogRequest(saved); return Object.fromEntries(Object.entries(toBacklogRequest(form)).filter(([field, value]) => value !== before[field])); }; /** * PATCH /api/library/games/{appid}/backlog with only the changed fields, so an older tab keeps the newer ones; null * clears a field. Answers the whole entry. The caller handles the response status. * * @param changes see changedFields */ export const saveBacklogEntry = (appid, changes) => apiFetch(`${import.meta.env.VITE_CORE_API_URL}/api/library/games/${appid}/backlog`, { method: 'PATCH', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(changes), }); /** * PUT /api/library/games/{appid}/status. The caller handles the response status. */ export const saveGameStatus = (appid, status) => apiFetch(`${import.meta.env.VITE_CORE_API_URL}/api/library/games/${appid}/status`, { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({status}), }); /** * PUT /api/library/games/{appid}/finished-hint: "Not yet" on the finished hint. Answers 204. * * @param dismissed the hint type the user answered, ENDING or PLAYTIME */ export const dismissFinishedHint = (appid, dismissed) => apiFetch(`${import.meta.env.VITE_CORE_API_URL}/api/library/games/${appid}/finished-hint`, { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({dismissed}), }); export const libraryQuery = ({page, size, sort, status, q, maxMinutes, hidden, hideDuplicates}) => { const params = new URLSearchParams({page: String(page), size: String(size), sort}); if (hidden) params.set('hidden', 'true'); if (hideDuplicates) params.set('hideDuplicates', 'true'); if (status) params.set('status', status); if (q?.trim()) params.set('q', q.trim()); if (maxMinutes) params.set('maxMinutes', String(maxMinutes)); return params.toString(); }; export const backlogShare = (summary) => summary?.total ? Math.round(((summary.byStatus?.BACKLOG ?? 0) / summary.total) * 100) : 0;