Expand website and game trackers
Some checks failed
Test and deploy staging / staging (push) Failing after 5m29s
Some checks failed
Test and deploy staging / staging (push) Failing after 5m29s
This commit is contained in:
67
src/lib/game-tracker/journal.ts
Normal file
67
src/lib/game-tracker/journal.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
export const stages = [
|
||||
{
|
||||
value: 'story',
|
||||
label: 'The adventure',
|
||||
description: 'Catch as you go, earn badges and become Champion.'
|
||||
},
|
||||
{
|
||||
value: 'postgame',
|
||||
label: 'Beyond the credits',
|
||||
description: 'Explore the postgame and finish what you can in this game.'
|
||||
},
|
||||
{
|
||||
value: 'collection',
|
||||
label: 'Complete the collection',
|
||||
description: 'Trades, transfers and event Pokémon.'
|
||||
}
|
||||
] as const;
|
||||
export type Stage = (typeof stages)[number]['value'];
|
||||
export const obtainedMethods = [
|
||||
'caught',
|
||||
'starter',
|
||||
'gift',
|
||||
'evolved',
|
||||
'bred',
|
||||
'trade',
|
||||
'transfer',
|
||||
'event'
|
||||
] as const;
|
||||
export const isStage = (value: string): value is Stage => stages.some((s) => s.value === value);
|
||||
|
||||
export function boundedInteger(value: FormDataEntryValue | null, min: number, max: number) {
|
||||
if (typeof value !== 'string' || !/^\d+$/.test(value)) return null;
|
||||
const number = Number(value);
|
||||
return Number.isSafeInteger(number) && number >= min && number <= max ? number : null;
|
||||
}
|
||||
export function validDate(value: string) {
|
||||
return (
|
||||
/^\d{4}-\d{2}-\d{2}$/.test(value) &&
|
||||
Number(value.slice(0, 4)) > 0 &&
|
||||
!Number.isNaN(Date.parse(value)) &&
|
||||
new Date(value).toISOString().slice(0, 10) === value
|
||||
);
|
||||
}
|
||||
export function firstCatches<T extends { id: number; pokemonId: number }>(catches: T[]) {
|
||||
const first = new Map<number, T>();
|
||||
for (const caught of [...catches].sort((a, b) => a.id - b.id))
|
||||
if (!first.has(caught.pokemonId)) first.set(caught.pokemonId, caught);
|
||||
return first;
|
||||
}
|
||||
export function allowedOsuUrl(value: string, kind: 'beatmap' | 'score') {
|
||||
if (!value) return true;
|
||||
try {
|
||||
const url = new URL(value);
|
||||
return (
|
||||
url.protocol === 'https:' &&
|
||||
url.hostname === 'osu.ppy.sh' &&
|
||||
!url.username &&
|
||||
!url.password &&
|
||||
!url.port &&
|
||||
(kind === 'beatmap'
|
||||
? /^\/(beatmaps|b|beatmapsets)\/\d+\/?$/.test(url.pathname)
|
||||
: /^\/scores\/(?:osu\/|taiko\/|fruits\/|mania\/)?\d+\/?$/.test(url.pathname))
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user