games: split Call of Duty into one entry per title and Pokémon into one per generation (remakes and spin-offs separate), full names, official logo for each (Steam icons / English logos); data migration moves bo2 status+aliases to black-ops-2; /trackers/games/bo2 and /pokemon redirect; three-column games flyout
All checks were successful
Deploy production / deploy (push) Successful in 1m16s
All checks were successful
Deploy production / deploy (push) Successful in 1m16s
This commit is contained in:
@@ -189,12 +189,15 @@
|
||||
let flyoutTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
// Big groups (games) get a two-column flyout; it opens upwards when it would not fit below.
|
||||
const WIDE_FLYOUT = 6;
|
||||
// Games (one entry per Call of Duty title and Pokémon generation) get three columns.
|
||||
const HUGE_FLYOUT = 24;
|
||||
const flyoutColumns = (count: number) => (count > HUGE_FLYOUT ? 3 : count > WIDE_FLYOUT ? 2 : 1);
|
||||
function openFlyout(name: string, el: HTMLElement, count: number) {
|
||||
clearTimeout(flyoutTimer);
|
||||
if (flyout === name) return;
|
||||
const wide = count > WIDE_FLYOUT;
|
||||
const width = wide ? 432 : 240;
|
||||
const height = (wide ? Math.ceil(count / 2) : count) * 46 + 20;
|
||||
const columns = flyoutColumns(count);
|
||||
const width = columns === 3 ? 640 : columns === 2 ? 432 : 240;
|
||||
const height = Math.min(Math.ceil(count / columns) * 46 + 20, window.innerHeight - 80);
|
||||
const rect = el.getBoundingClientRect();
|
||||
const panel = el.closest('[data-menu-panel]')?.getBoundingClientRect() ?? rect;
|
||||
const leftColumn = rect.left + rect.width / 2 < panel.left + panel.width / 2;
|
||||
@@ -365,14 +368,20 @@
|
||||
class={[
|
||||
'absolute',
|
||||
flyoutUp ? '-bottom-2' : '-top-2',
|
||||
project.children.length > WIDE_FLYOUT ? 'w-[27rem]' : 'w-60',
|
||||
flyoutColumns(project.children.length) === 3
|
||||
? 'w-[40rem]'
|
||||
: project.children.length > WIDE_FLYOUT
|
||||
? 'w-[27rem]'
|
||||
: 'w-60',
|
||||
flyoutSide === 'right' ? 'left-full pl-3' : 'right-full pr-3'
|
||||
]}
|
||||
>
|
||||
<div
|
||||
class={[
|
||||
'flyout grid gap-1 rounded-md border border-border bg-popover p-1.5 shadow-lg',
|
||||
project.children.length > WIDE_FLYOUT && 'grid-cols-2'
|
||||
'flyout grid max-h-[calc(100vh-5rem)] gap-1 overflow-y-auto rounded-md border border-border bg-popover p-1.5 shadow-lg',
|
||||
flyoutColumns(project.children.length) === 3
|
||||
? 'grid-cols-3'
|
||||
: project.children.length > WIDE_FLYOUT && 'grid-cols-2'
|
||||
]}
|
||||
class:from-left={flyoutSide === 'left'}
|
||||
>
|
||||
|
||||
@@ -27,7 +27,11 @@
|
||||
alt=""
|
||||
draggable="false"
|
||||
decoding="async"
|
||||
class={logo.bleed ? 'size-full object-cover' : 'size-[80%] object-contain'}
|
||||
class={logo.bleed
|
||||
? 'size-full object-cover'
|
||||
: logo.wide
|
||||
? 'size-[92%] object-contain'
|
||||
: 'size-[80%] object-contain'}
|
||||
onerror={() => (failed = true)}
|
||||
/>
|
||||
</span>
|
||||
|
||||
@@ -2,19 +2,24 @@
|
||||
// static/game-logos/icons/, keyed like `gameTrackers[].icon` (game-<slug>). TrackerIcon uses
|
||||
// this map everywhere games show up (header flyout, home and /trackers tiles, /start chips,
|
||||
// the games switcher and each game page); a game without an entry keeps its tracker-icons tile.
|
||||
// Square app icons/emblems are used instead of wide wordmarks so they stay legible at chip size.
|
||||
// Square app icons/emblems are used instead of wide wordmarks so they stay legible at chip size;
|
||||
// Pokémon generations have no square marks, so they use their English logos (`wide`).
|
||||
|
||||
export type GameLogo = {
|
||||
/** Path under static/ (no leading slash), resolved with `asset`/`resolve` at render time. */
|
||||
src: string;
|
||||
/** Opaque square app icon: fill the whole tile instead of sitting padded on the dark tile. */
|
||||
bleed?: boolean;
|
||||
/** Wide wordmark (Pokémon logos): use more of the tile so it stays readable. */
|
||||
wide?: boolean;
|
||||
/** Where the asset came from (shown on /projects/game-tracker/credits). */
|
||||
credit: string;
|
||||
source: string;
|
||||
};
|
||||
|
||||
const steamIcon = (appid: number) => `https://store.steampowered.com/app/${appid}/`;
|
||||
const bulbagarden = (file: string) =>
|
||||
`https://archives.bulbagarden.net/wiki/File:${encodeURIComponent(file.replaceAll(' ', '_'))}`;
|
||||
const commons = (file: string) =>
|
||||
`https://commons.wikimedia.org/wiki/File:${encodeURIComponent(file.replaceAll(' ', '_'))}`;
|
||||
|
||||
@@ -47,12 +52,48 @@ export const gameLogos: Record<string, GameLogo> = {
|
||||
credit: 'Escape from Tarkov app icon, Steam',
|
||||
source: steamIcon(3932890)
|
||||
},
|
||||
'game-bo2': {
|
||||
src: 'game-logos/icons/bo2.png',
|
||||
'game-black-ops-2': {
|
||||
src: 'game-logos/icons/black-ops-2.png',
|
||||
bleed: true,
|
||||
credit: 'Call of Duty: Black Ops II app icon, Steam',
|
||||
source: steamIcon(202970)
|
||||
},
|
||||
'game-black-ops': {
|
||||
src: 'game-logos/icons/black-ops.png',
|
||||
bleed: true,
|
||||
credit: 'Call of Duty: Black Ops app icon, Steam',
|
||||
source: steamIcon(42700)
|
||||
},
|
||||
'game-ghosts': {
|
||||
src: 'game-logos/icons/ghosts.png',
|
||||
bleed: true,
|
||||
credit: 'Call of Duty: Ghosts app icon, Steam',
|
||||
source: steamIcon(209160)
|
||||
},
|
||||
'game-advanced-warfare': {
|
||||
src: 'game-logos/icons/advanced-warfare.png',
|
||||
bleed: true,
|
||||
credit: 'Call of Duty: Advanced Warfare app icon, Steam',
|
||||
source: steamIcon(209650)
|
||||
},
|
||||
'game-black-ops-3': {
|
||||
src: 'game-logos/icons/black-ops-3.png',
|
||||
bleed: true,
|
||||
credit: 'Call of Duty: Black Ops III app icon, Steam',
|
||||
source: steamIcon(311210)
|
||||
},
|
||||
'game-infinite-warfare': {
|
||||
src: 'game-logos/icons/infinite-warfare.png',
|
||||
bleed: true,
|
||||
credit: 'Call of Duty: Infinite Warfare app icon, Steam',
|
||||
source: steamIcon(292730)
|
||||
},
|
||||
'game-wwii': {
|
||||
src: 'game-logos/icons/wwii.png',
|
||||
bleed: true,
|
||||
credit: 'Call of Duty: WWII app icon, Steam',
|
||||
source: steamIcon(476600)
|
||||
},
|
||||
'game-valorant': {
|
||||
src: 'game-logos/icons/valorant.svg',
|
||||
credit: 'Valorant logo (V mark, pink), Wikimedia Commons',
|
||||
@@ -93,14 +134,117 @@ export const gameLogos: Record<string, GameLogo> = {
|
||||
credit: 'World Cube Association logo, Wikimedia Commons',
|
||||
source: commons('World Cube Association.svg')
|
||||
},
|
||||
'game-pokemon': {
|
||||
src: 'game-logos/icons/pokemon.svg',
|
||||
credit: 'Poké Ball icon, Wikimedia Commons',
|
||||
source: commons('Poké Ball icon.svg')
|
||||
},
|
||||
'game-sot': {
|
||||
src: 'game-logos/icons/sot.png',
|
||||
credit: 'Sea of Thieves app icon (skull), Steam',
|
||||
source: steamIcon(1172620)
|
||||
},
|
||||
'game-pokemon-red-blue-yellow': {
|
||||
src: 'game-logos/icons/pokemon-red-blue-yellow.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon RB logo 2), Wikimedia Commons',
|
||||
source: commons('Pokémon RB logo 2.png')
|
||||
},
|
||||
'game-pokemon-gold-silver-crystal': {
|
||||
src: 'game-logos/icons/pokemon-gold-silver-crystal.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon GS logo), Wikimedia Commons',
|
||||
source: commons('Pokémon GS logo.png')
|
||||
},
|
||||
'game-pokemon-ruby-sapphire-emerald': {
|
||||
src: 'game-logos/icons/pokemon-ruby-sapphire-emerald.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokemon Emerald Logo EN), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokemon Emerald Logo EN.png')
|
||||
},
|
||||
'game-pokemon-colosseum': {
|
||||
src: 'game-logos/icons/pokemon-colosseum.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon Colosseum logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon Colosseum logo.png')
|
||||
},
|
||||
'game-pokemon-xd': {
|
||||
src: 'game-logos/icons/pokemon-xd.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon XD logo English), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon XD logo English.png')
|
||||
},
|
||||
'game-pokemon-firered-leafgreen': {
|
||||
src: 'game-logos/icons/pokemon-firered-leafgreen.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokemon FireRed Logo EN), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokemon FireRed Logo EN.png')
|
||||
},
|
||||
'game-pokemon-diamond-pearl-platinum': {
|
||||
src: 'game-logos/icons/pokemon-diamond-pearl-platinum.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Platinum-logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Platinum-logo.png')
|
||||
},
|
||||
'game-pokemon-heartgold-soulsilver': {
|
||||
src: 'game-logos/icons/pokemon-heartgold-soulsilver.png',
|
||||
wide: true,
|
||||
credit: 'English logo (HeartGold SoulSilver Logo), Bulbagarden Archives',
|
||||
source: bulbagarden('HeartGold SoulSilver Logo.png')
|
||||
},
|
||||
'game-pokemon-black-white': {
|
||||
src: 'game-logos/icons/pokemon-black-white.png',
|
||||
wide: true,
|
||||
credit: 'English logo (English BW logo), Bulbagarden Archives',
|
||||
source: bulbagarden('English BW logo.png')
|
||||
},
|
||||
'game-pokemon-x-y': {
|
||||
src: 'game-logos/icons/pokemon-x-y.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon XY logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon XY logo.png')
|
||||
},
|
||||
'game-pokemon-omega-ruby-alpha-sapphire': {
|
||||
src: 'game-logos/icons/pokemon-omega-ruby-alpha-sapphire.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon Omega Ruby EN logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon Omega Ruby EN logo.png')
|
||||
},
|
||||
'game-pokemon-sun-moon': {
|
||||
src: 'game-logos/icons/pokemon-sun-moon.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon Sun Moon logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon Sun Moon logo.png')
|
||||
},
|
||||
'game-pokemon-lets-go': {
|
||||
src: 'game-logos/icons/pokemon-lets-go.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon Lets Go Eevee Logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon Lets Go Eevee Logo.png')
|
||||
},
|
||||
'game-pokemon-sword-shield': {
|
||||
src: 'game-logos/icons/pokemon-sword-shield.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon Sword Shield logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon Sword Shield logo.png')
|
||||
},
|
||||
'game-pokemon-brilliant-diamond-shining-pearl': {
|
||||
src: 'game-logos/icons/pokemon-brilliant-diamond-shining-pearl.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon Brilliant Diamond logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon Brilliant Diamond logo.png')
|
||||
},
|
||||
'game-pokemon-legends-arceus': {
|
||||
src: 'game-logos/icons/pokemon-legends-arceus.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon Legends Arceus logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon Legends Arceus logo.png')
|
||||
},
|
||||
'game-pokemon-scarlet-violet': {
|
||||
src: 'game-logos/icons/pokemon-scarlet-violet.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon Scarlet logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon Scarlet logo.png')
|
||||
},
|
||||
'game-pokemon-legends-z-a': {
|
||||
src: 'game-logos/icons/pokemon-legends-z-a.png',
|
||||
wide: true,
|
||||
credit: 'English logo (Pokémon Legends Z-A logo), Bulbagarden Archives',
|
||||
source: bulbagarden('Pokémon Legends Z-A logo.png')
|
||||
}
|
||||
};
|
||||
|
||||
@@ -82,6 +82,9 @@ export const spottingTrackers: readonly Tracker[] = [
|
||||
// own page at /trackers/games/<slug>, one click away from the header flyout and the chips.
|
||||
// `featured` games (my main game and the ones I actively play) show first on tiles; the
|
||||
// rest sit behind a "more" chip. Data per game lives in games.library (same slugs).
|
||||
// Call of Duty is one entry per title and Pokémon one per generation (remakes such as
|
||||
// HeartGold & SoulSilver and spin-offs separate); full names, no abbreviations. The old
|
||||
// /trackers/games/bo2 and /trackers/games/pokemon URLs redirect (see [slug]/+page.server.ts).
|
||||
const game = (slug: string, name: string, subtitle: string, featured = false): Tracker => ({
|
||||
name,
|
||||
subtitle,
|
||||
@@ -96,7 +99,7 @@ export const gameTrackers: readonly Tracker[] = [
|
||||
game('pubg', 'pubg', 'PUBG: Battlegrounds', true),
|
||||
game('r6', 'r6 siege', 'Tom Clancy’s Rainbow Six Siege', true),
|
||||
game('tarkov', 'tarkov', 'Escape from Tarkov', true),
|
||||
game('bo2', 'bo2', 'Call of Duty: Black Ops II', true),
|
||||
game('black-ops-2', 'black ops 2', 'Call of Duty: Black Ops II (2012)', true),
|
||||
game('valorant', 'valorant', 'Riot’s tactical shooter', false),
|
||||
game('lol', 'league', 'League of Legends', false),
|
||||
game('overwatch', 'overwatch 2', 'Blizzard’s hero shooter', false),
|
||||
@@ -105,8 +108,81 @@ export const gameTrackers: readonly Tracker[] = [
|
||||
game('ksp', 'ksp', 'Kerbal Space Program', false),
|
||||
game('smash', 'smash bros', 'Super Smash Bros.', false),
|
||||
game('cubing', 'speedcubing', 'Rubik’s cube solving, not a video game', false),
|
||||
game('pokemon', 'pokémon', 'catching them all across the games', false),
|
||||
game('sot', 'sea of thieves', 'pirate sandbox', false)
|
||||
game('sot', 'sea of thieves', 'pirate sandbox', false),
|
||||
// Call of Duty, one entry per title (the Black Ops 2 one is featured above).
|
||||
game('black-ops', 'black ops', 'Call of Duty: Black Ops (2010)'),
|
||||
game('ghosts', 'ghosts', 'Call of Duty: Ghosts (2013)'),
|
||||
game('advanced-warfare', 'advanced warfare', 'Call of Duty: Advanced Warfare (2014)'),
|
||||
game('black-ops-3', 'black ops 3', 'Call of Duty: Black Ops III (2015)'),
|
||||
game('infinite-warfare', 'infinite warfare', 'Call of Duty: Infinite Warfare (2016)'),
|
||||
game('wwii', 'wwii', 'Call of Duty: WWII (2017)'),
|
||||
// Pokémon, one entry per generation; remakes and spin-offs get their own.
|
||||
game('pokemon-red-blue-yellow', 'pokémon red, blue & yellow', 'generation 1, Game Boy'),
|
||||
game(
|
||||
'pokemon-gold-silver-crystal',
|
||||
'pokémon gold, silver & crystal',
|
||||
'generation 2, Game Boy Color'
|
||||
),
|
||||
game(
|
||||
'pokemon-ruby-sapphire-emerald',
|
||||
'pokémon ruby, sapphire & emerald',
|
||||
'generation 3, Game Boy Advance'
|
||||
),
|
||||
game('pokemon-colosseum', 'pokémon colosseum', 'generation 3 spin-off, GameCube'),
|
||||
game('pokemon-xd', 'pokémon xd: gale of darkness', 'generation 3 spin-off, GameCube'),
|
||||
game(
|
||||
'pokemon-firered-leafgreen',
|
||||
'pokémon firered & leafgreen',
|
||||
'generation 1 remake, Game Boy Advance'
|
||||
),
|
||||
game(
|
||||
'pokemon-diamond-pearl-platinum',
|
||||
'pokémon diamond, pearl & platinum',
|
||||
'generation 4, Nintendo DS'
|
||||
),
|
||||
game(
|
||||
'pokemon-heartgold-soulsilver',
|
||||
'pokémon heartgold & soulsilver',
|
||||
'generation 2 remake, Nintendo DS'
|
||||
),
|
||||
game(
|
||||
'pokemon-black-white',
|
||||
'pokémon black & white',
|
||||
'generation 5 with Black 2 & White 2, Nintendo DS'
|
||||
),
|
||||
game('pokemon-x-y', 'pokémon x & y', 'generation 6, Nintendo 3DS'),
|
||||
game(
|
||||
'pokemon-omega-ruby-alpha-sapphire',
|
||||
'pokémon omega ruby & alpha sapphire',
|
||||
'generation 3 remake, Nintendo 3DS'
|
||||
),
|
||||
game(
|
||||
'pokemon-sun-moon',
|
||||
'pokémon sun & moon',
|
||||
'generation 7 with Ultra Sun & Ultra Moon, Nintendo 3DS'
|
||||
),
|
||||
game(
|
||||
'pokemon-lets-go',
|
||||
'pokémon let’s go, pikachu & eevee',
|
||||
'generation 1 remake, Nintendo Switch'
|
||||
),
|
||||
game(
|
||||
'pokemon-sword-shield',
|
||||
'pokémon sword & shield',
|
||||
'generation 8 with The Isle of Armor & The Crown Tundra, Nintendo Switch'
|
||||
),
|
||||
game(
|
||||
'pokemon-brilliant-diamond-shining-pearl',
|
||||
'pokémon brilliant diamond & shining pearl',
|
||||
'generation 4 remake, Nintendo Switch'
|
||||
),
|
||||
game('pokemon-legends-arceus', 'pokémon legends: arceus', 'generation 8, Nintendo Switch'),
|
||||
game(
|
||||
'pokemon-scarlet-violet',
|
||||
'pokémon scarlet & violet',
|
||||
'generation 9 with The Teal Mask & The Indigo Disk, Nintendo Switch'
|
||||
),
|
||||
game('pokemon-legends-z-a', 'pokémon legends: z-a', 'generation 9, Nintendo Switch')
|
||||
];
|
||||
|
||||
// Trackers, in display order. Names are short single nouns. Most keep their existing
|
||||
|
||||
@@ -19,6 +19,21 @@ export type TrackerIcon = {
|
||||
|
||||
const WHITE = '#ffffff';
|
||||
|
||||
// Shared glyphs for the per-title Call of Duty (crosshair) and per-generation Pokémon (Poké Ball)
|
||||
// fallback tiles; each entry only changes the colours.
|
||||
const codTile: TrackerIcon = {
|
||||
from: '#fb923c',
|
||||
to: '#9a3412',
|
||||
ink: WHITE,
|
||||
paths: [c(12, 12, 9), 'M21 12h-4M7 12H3M12 7V3M12 21v-4', c(12, 12, 1)]
|
||||
};
|
||||
const pokemonTile: TrackerIcon = {
|
||||
from: '#fb7185',
|
||||
to: '#c81e4a',
|
||||
ink: WHITE,
|
||||
paths: [c(12, 12, 9), 'M3 12h6M15 12h6', c(12, 12, 3)]
|
||||
};
|
||||
|
||||
export const trackerIcons: Record<string, TrackerIcon> = {
|
||||
tasks: {
|
||||
from: '#60a5fa',
|
||||
@@ -228,12 +243,13 @@ export const trackerIcons: Record<string, TrackerIcon> = {
|
||||
'M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2'
|
||||
]
|
||||
},
|
||||
'game-bo2': {
|
||||
from: '#fb923c',
|
||||
to: '#9a3412',
|
||||
ink: WHITE,
|
||||
paths: [c(12, 12, 9), 'M21 12h-4M7 12H3M12 7V3M12 21v-4', c(12, 12, 1)]
|
||||
},
|
||||
'game-black-ops-2': { ...codTile, from: '#f58147', to: '#863913' },
|
||||
'game-black-ops': { ...codTile, from: '#f59b47', to: '#864b13' },
|
||||
'game-ghosts': { ...codTile, from: '#f5b547', to: '#865c13' },
|
||||
'game-advanced-warfare': { ...codTile, from: '#f5d047', to: '#866d13' },
|
||||
'game-black-ops-3': { ...codTile, from: '#f5ea47', to: '#867e13' },
|
||||
'game-infinite-warfare': { ...codTile, from: '#e7f547', to: '#7c8613' },
|
||||
'game-wwii': { ...codTile, from: '#cdf547', to: '#6b8613' },
|
||||
'game-valorant': {
|
||||
from: '#ff6b77',
|
||||
to: '#9f1239',
|
||||
@@ -313,12 +329,28 @@ export const trackerIcons: Record<string, TrackerIcon> = {
|
||||
ink: WHITE,
|
||||
paths: ['M4 4h16v16H4z', 'M9.33 4v16M14.67 4v16', 'M4 9.33h16M4 14.67h16']
|
||||
},
|
||||
'game-pokemon': {
|
||||
from: '#fb7185',
|
||||
to: '#c81e4a',
|
||||
ink: WHITE,
|
||||
paths: [c(12, 12, 9), 'M3 12h6M15 12h6', c(12, 12, 3)]
|
||||
'game-pokemon-red-blue-yellow': { ...pokemonTile, from: '#f37868', to: '#9c2b1c' },
|
||||
'game-pokemon-gold-silver-crystal': { ...pokemonTile, from: '#f3a668', to: '#9c551c' },
|
||||
'game-pokemon-ruby-sapphire-emerald': { ...pokemonTile, from: '#f3d568', to: '#9c801c' },
|
||||
'game-pokemon-colosseum': { ...pokemonTile, from: '#e3f368', to: '#8d9c1c' },
|
||||
'game-pokemon-xd': { ...pokemonTile, from: '#b4f368', to: '#629c1c' },
|
||||
'game-pokemon-firered-leafgreen': { ...pokemonTile, from: '#86f368', to: '#379c1c' },
|
||||
'game-pokemon-diamond-pearl-platinum': { ...pokemonTile, from: '#68f378', to: '#1c9c2b' },
|
||||
'game-pokemon-heartgold-soulsilver': { ...pokemonTile, from: '#68f3a6', to: '#1c9c55' },
|
||||
'game-pokemon-black-white': { ...pokemonTile, from: '#68f3d5', to: '#1c9c80' },
|
||||
'game-pokemon-x-y': { ...pokemonTile, from: '#68e3f3', to: '#1c8d9c' },
|
||||
'game-pokemon-omega-ruby-alpha-sapphire': { ...pokemonTile, from: '#68b4f3', to: '#1c629c' },
|
||||
'game-pokemon-sun-moon': { ...pokemonTile, from: '#6886f3', to: '#1c379c' },
|
||||
'game-pokemon-lets-go': { ...pokemonTile, from: '#7868f3', to: '#2b1c9c' },
|
||||
'game-pokemon-sword-shield': { ...pokemonTile, from: '#a668f3', to: '#551c9c' },
|
||||
'game-pokemon-brilliant-diamond-shining-pearl': {
|
||||
...pokemonTile,
|
||||
from: '#d568f3',
|
||||
to: '#801c9c'
|
||||
},
|
||||
'game-pokemon-legends-arceus': { ...pokemonTile, from: '#f368e3', to: '#9c1c8d' },
|
||||
'game-pokemon-scarlet-violet': { ...pokemonTile, from: '#f368b4', to: '#9c1c62' },
|
||||
'game-pokemon-legends-z-a': { ...pokemonTile, from: '#f36886', to: '#9c1c37' },
|
||||
'game-sot': {
|
||||
from: '#5eead4',
|
||||
to: '#0f766e',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import { eq, inArray } from 'drizzle-orm';
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import { gameLibrary, hardwareSensitivities } from '#lib/server/db/schema/index.js';
|
||||
@@ -9,8 +9,17 @@ import type { PageServerLoad } from './$types';
|
||||
// One game from games.library, plus its mouse sensitivity (hardware.sensitivities, matched by
|
||||
// name, short name or alias) when there is one. CS2, PUBG and R6 also get their automatic
|
||||
// match history (games.matches, filled by the in-app poller).
|
||||
// Old single entries, split per title/generation: bo2 became black-ops-2, and the Pokémon
|
||||
// entry (all generations) now points at the Pokémon journal that covers every game.
|
||||
const MOVED: Record<string, string> = {
|
||||
bo2: '/trackers/games/black-ops-2',
|
||||
pokemon: '/projects/game-tracker/pokemon'
|
||||
};
|
||||
|
||||
export const load: PageServerLoad = async (event) => {
|
||||
const { params } = event;
|
||||
const moved = MOVED[params.slug];
|
||||
if (moved) redirect(301, moved);
|
||||
const [game] = await db.select().from(gameLibrary).where(eq(gameLibrary.slug, params.slug));
|
||||
if (!game) error(404, 'Not Found');
|
||||
const names = [game.name, game.shortName, ...game.aliases];
|
||||
|
||||
Reference in New Issue
Block a user