Public Access
refactor(limits): server limits in one file, own texts for unknown errors
This commit is contained in:
1 parent
f605917874
commit
24a98062ee
18 files changed
+84
-49
No files matched your search
@@ -13,7 +13,7 @@ import GameCover from './GameCover.jsx';
|
||||
import GameSearch from './GameSearch.jsx';
|
||||
import useSessionExpired from '../hooks/useSessionExpired.js';
|
||||
import useStartImport from '../hooks/useStartImport.js';
|
||||
import {GAME_STATUSES} from '../utils/backlog.js';
|
||||
import {GAME_STATUSES, MAX_PLATFORM_LENGTH} from '../utils/limits.js';
|
||||
import {addGame, hoursToMinutes} from '../utils/manualGames.js';
|
||||
import {loadFavoritePlatform, preselectPlatform} from '../utils/platforms.js';
|
||||
|
||||
@@ -145,7 +145,7 @@ function AddForm({hit, favorite, onBack, navigate, expireSession}) {
|
||||
</SelectContent>
|
||||
</Select>
|
||||
) : (
|
||||
<Input id="add-platform" value={platform} maxLength={32} onChange={(e) => setPlatform(e.target.value)}/>
|
||||
<Input id="add-platform" value={platform} maxLength={MAX_PLATFORM_LENGTH} onChange={(e) => setPlatform(e.target.value)}/>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
|
||||
@@ -11,12 +11,11 @@ import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from '@/c
|
||||
import {Textarea} from '@/components/ui/textarea';
|
||||
import {cn} from '@/lib/utils';
|
||||
import {STATUS_META} from './GameStatusBadge.jsx';
|
||||
import {GAME_PRIORITIES, GAME_STATUSES, NO_PRIORITY, saveBacklogEntry, toBacklogRequest} from '../utils/backlog.js';
|
||||
import {NO_PRIORITY, saveBacklogEntry, toBacklogRequest} from '../utils/backlog.js';
|
||||
import {GAME_PRIORITIES, GAME_STATUSES, MAX_NOTES_LENGTH} from '../utils/limits.js';
|
||||
import useSessionExpired from '../hooks/useSessionExpired.js';
|
||||
import {hasSession} from '../utils/auth.js';
|
||||
|
||||
const NOTES_MAX = 2000;
|
||||
|
||||
const toForm = (entry) => ({
|
||||
status: entry.status ?? 'BACKLOG',
|
||||
rating: entry.rating ?? 0,
|
||||
@@ -133,12 +132,12 @@ export default function BacklogCard({game, onSaved}) {
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-baseline justify-between">
|
||||
<Label htmlFor="backlog-notes">{t('BACKLOG.NOTES_LABEL')}</Label>
|
||||
<span className="text-xs text-muted-foreground tabular-nums">{form.notes.length} / {NOTES_MAX}</span>
|
||||
<span className="text-xs text-muted-foreground tabular-nums">{form.notes.length} / {MAX_NOTES_LENGTH}</span>
|
||||
</div>
|
||||
<Textarea
|
||||
id="backlog-notes"
|
||||
rows={3}
|
||||
maxLength={NOTES_MAX}
|
||||
maxLength={MAX_NOTES_LENGTH}
|
||||
placeholder={t('BACKLOG.NOTES_PLACEHOLDER')}
|
||||
value={form.notes}
|
||||
onChange={(e) => set('notes')(e.target.value)}
|
||||
|
||||
@@ -11,10 +11,9 @@ import {Label} from '@/components/ui/label';
|
||||
import useSessionExpired from '../hooks/useSessionExpired.js';
|
||||
import {CORRECTABLE_MOODS, IGDB_GENRES, resetCorrection, saveCorrection} from '../utils/corrections.js';
|
||||
import {genreKey} from '../utils/stats.js';
|
||||
import {MAX_CORRECTION_GENRES, MAX_CORRECTION_LENGTH} from '../utils/limits.js';
|
||||
|
||||
const ENDLESS_CHOICES = [[null, 'UNKNOWN'], [true, 'YES'], [false, 'NO']];
|
||||
// Core refuses more.
|
||||
const MAX_GENRES = 10;
|
||||
|
||||
const initialValues = (game) => ({
|
||||
name: game.name ?? '',
|
||||
@@ -129,12 +128,12 @@ export default function GameCorrectionDialog({game, open, onOpenChange, onChange
|
||||
<DialogDescription>{t('CORRECTION.TEXT')}</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
{row('name', <Input id="correction-name" value={values.name} maxLength={512}
|
||||
{row('name', <Input id="correction-name" value={values.name} maxLength={MAX_CORRECTION_LENGTH}
|
||||
onChange={(e) => set('name', e.target.value)}/>)}
|
||||
{row('image', <Input id="correction-image" value={values.image} maxLength={512}
|
||||
{row('image', <Input id="correction-image" value={values.image} maxLength={MAX_CORRECTION_LENGTH}
|
||||
placeholder={t('CORRECTION.IMAGE_HINT')}
|
||||
onChange={(e) => set('image', e.target.value)}/>)}
|
||||
{row('speedrun', <Input id="correction-speedrun" value={values.speedrun} maxLength={512}
|
||||
{row('speedrun', <Input id="correction-speedrun" value={values.speedrun} maxLength={MAX_CORRECTION_LENGTH}
|
||||
placeholder={t('CORRECTION.SPEEDRUN_HINT')}
|
||||
onChange={(e) => set('speedrun', e.target.value)}/>)}
|
||||
{row('moods', choices('moods', CORRECTABLE_MOODS, (mood) => t(`PLAY_NEXT.MOOD.${mood}`)))}
|
||||
@@ -150,7 +149,7 @@ export default function GameCorrectionDialog({game, open, onOpenChange, onChange
|
||||
</div>
|
||||
))}
|
||||
{row('genres', choices('genres', genreOptions,
|
||||
(genre) => t(`STATS.GENRE.${genreKey(genre)}`, {defaultValue: genre}), MAX_GENRES))}
|
||||
(genre) => t(`STATS.GENRE.${genreKey(genre)}`, {defaultValue: genre}), MAX_CORRECTION_GENRES))}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -7,9 +7,9 @@ import {Input} from '@/components/ui/input';
|
||||
import GameCover from './GameCover.jsx';
|
||||
import useSessionExpired from '../hooks/useSessionExpired.js';
|
||||
import {searchGames} from '../utils/manualGames.js';
|
||||
import {MAX_GAME_SEARCH_LENGTH, MIN_GAME_SEARCH_LENGTH} from '../utils/limits.js';
|
||||
|
||||
const SEARCH_DEBOUNCE_MS = 400;
|
||||
const MIN_QUERY = 2;
|
||||
|
||||
/**
|
||||
* The search field and the hits of Core's game search. The parent keeps the query, so it stays when the user goes
|
||||
@@ -29,7 +29,7 @@ export default function GameSearch({query, onQueryChange, onPick, hide = () => f
|
||||
<>
|
||||
<div className="relative">
|
||||
<Search className="pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground"/>
|
||||
<Input type="search" autoFocus value={query} maxLength={100} className="pl-8"
|
||||
<Input type="search" autoFocus value={query} maxLength={MAX_GAME_SEARCH_LENGTH} className="pl-8"
|
||||
placeholder={t('MANUAL_GAME.SEARCH_PLACEHOLDER')}
|
||||
aria-label={t('MANUAL_GAME.SEARCH_PLACEHOLDER')}
|
||||
onChange={(e) => onQueryChange(e.target.value)}/>
|
||||
@@ -87,7 +87,7 @@ function useGameSearch(query) {
|
||||
|
||||
useEffect(() => {
|
||||
const trimmed = query.trim();
|
||||
if (trimmed.length < MIN_QUERY) {
|
||||
if (trimmed.length < MIN_GAME_SEARCH_LENGTH) {
|
||||
setSearchState('idle');
|
||||
setResults([]);
|
||||
return undefined;
|
||||
|
||||
@@ -10,6 +10,7 @@ import {Input} from '@/components/ui/input';
|
||||
import {Label} from '@/components/ui/label';
|
||||
import useSessionExpired from '../hooks/useSessionExpired.js';
|
||||
import {hoursToMinutes, removeGame, toHours, updateManualGame} from '../utils/manualGames.js';
|
||||
import {MAX_PLATFORM_LENGTH} from '../utils/limits.js';
|
||||
|
||||
/**
|
||||
* Platform and hours of a game added by hand, and removing it. Steam games get both from the sync.
|
||||
@@ -70,7 +71,7 @@ export default function ManualGameCard({game, onSaved}) {
|
||||
<div className="grid gap-5 sm:grid-cols-2">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="manual-platform">{t('MANUAL_GAME.PLATFORM')}</Label>
|
||||
<Input id="manual-platform" value={platform} maxLength={32}
|
||||
<Input id="manual-platform" value={platform} maxLength={MAX_PLATFORM_LENGTH}
|
||||
onChange={(e) => setPlatform(e.target.value)}/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
|
||||
@@ -7,7 +7,8 @@ import {Card} from '@/components/ui/card';
|
||||
import GameCover from './GameCover.jsx';
|
||||
import PileTrend from './stats/PileTrend.jsx';
|
||||
import {STATUS_META} from './GameStatusBadge.jsx';
|
||||
import {backlogShare, GAME_STATUSES} from '../utils/backlog.js';
|
||||
import {backlogShare} from '../utils/backlog.js';
|
||||
import {GAME_STATUSES} from '../utils/limits.js';
|
||||
import {formatPlaytime} from '../utils/games.js';
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@ import {Gamepad2} from 'lucide-react';
|
||||
|
||||
import StatsSection from './StatsSection.jsx';
|
||||
import StatTile from './StatTile.jsx';
|
||||
import {GAME_STATUSES} from '../../utils/backlog.js';
|
||||
import {GAME_STATUSES} from '../../utils/limits.js';
|
||||
import {formatPlaytime} from '../../utils/games.js';
|
||||
|
||||
export default function OverviewStats({overview}) {
|
||||
|
||||
Reference in new issue
Block a user