From 037a525f9142704b9ca36fb56bd33c673514dd87 Mon Sep 17 00:00:00 2001 From: Stan Runge Date: Sun, 25 Oct 2026 15:05:11 +0000 Subject: [PATCH] spotters: brands, makers and operators with a logo first, activity order kept inside each group --- src/lib/server/spotting.ts | 5 +++++ src/routes/trackers/cars/+page.server.ts | 3 ++- src/routes/trackers/cars/brands/+page.server.ts | 4 ++-- src/routes/trackers/planes/+page.server.ts | 3 ++- src/routes/trackers/planes/makers/+page.server.ts | 4 ++-- src/routes/trackers/trains/+page.server.ts | 14 ++++++++------ src/routes/trackers/trains/makers/+page.server.ts | 4 ++-- .../trackers/trains/operators/+page.server.ts | 3 ++- 8 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/lib/server/spotting.ts b/src/lib/server/spotting.ts index 6b0dcec..b2c73e5 100644 --- a/src/lib/server/spotting.ts +++ b/src/lib/server/spotting.ts @@ -161,3 +161,8 @@ export function rankByActivity(tiles: T[], act: Map b.s - a.s || a.i - b.i) .map((x) => x.t); } + +/** Brands/makers/operators with a logo first; keeps the incoming order inside each group. */ +export function logoFirst(tiles: T[]) { + return [...tiles.filter((t) => t.logo), ...tiles.filter((t) => !t.logo)]; +} diff --git a/src/routes/trackers/cars/+page.server.ts b/src/routes/trackers/cars/+page.server.ts index a9db232..3a8cf3a 100644 --- a/src/routes/trackers/cars/+page.server.ts +++ b/src/routes/trackers/cars/+page.server.ts @@ -3,6 +3,7 @@ import { areasWithData, groupActivity, progress, + logoFirst, rankByActivity, seenByGroup } from '#lib/server/spotting.js'; @@ -26,7 +27,7 @@ export const load: PageServerLoad = async ({ url }) => { collected, areas, brands: overview.brands.map(({ slug, name, models }) => ({ slug, name, models })), - topBrands: rankByActivity(overview.byNl, act) + topBrands: logoFirst(rankByActivity(overview.byNl, act)) .slice(0, 16) .map(({ id, slug, name, models, nlCount, logo }) => ({ slug, diff --git a/src/routes/trackers/cars/brands/+page.server.ts b/src/routes/trackers/cars/brands/+page.server.ts index 7028a36..fb87690 100644 --- a/src/routes/trackers/cars/brands/+page.server.ts +++ b/src/routes/trackers/cars/brands/+page.server.ts @@ -1,11 +1,11 @@ import { carOverview } from '#lib/server/cars.js'; -import { seenByGroup } from '#lib/server/spotting.js'; +import { logoFirst, seenByGroup } from '#lib/server/spotting.js'; import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async () => { const [{ byNl, stats }, seen] = await Promise.all([carOverview(), seenByGroup('cars')]); return { - brands: byNl.map(({ id, slug, name, models, nlCount, logo }) => ({ + brands: logoFirst(byNl).map(({ id, slug, name, models, nlCount, logo }) => ({ seen: seen.get(id) ?? 0, slug, name, diff --git a/src/routes/trackers/planes/+page.server.ts b/src/routes/trackers/planes/+page.server.ts index ec48b1a..535278b 100644 --- a/src/routes/trackers/planes/+page.server.ts +++ b/src/routes/trackers/planes/+page.server.ts @@ -3,6 +3,7 @@ import { areasWithData, groupActivity, progress, + logoFirst, rankByActivity, seenByGroup } from '#lib/server/spotting.js'; @@ -26,7 +27,7 @@ export const load: PageServerLoad = async ({ url }) => { collected, areas, makers: overview.makers.map(({ slug, name, types }) => ({ slug, name, types })), - topMakers: rankByActivity(overview.byBuilt, act) + topMakers: logoFirst(rankByActivity(overview.byBuilt, act)) .slice(0, 16) .map(({ id, slug, name, types, built, logo }) => ({ slug, diff --git a/src/routes/trackers/planes/makers/+page.server.ts b/src/routes/trackers/planes/makers/+page.server.ts index a0b52dc..2a0d4fe 100644 --- a/src/routes/trackers/planes/makers/+page.server.ts +++ b/src/routes/trackers/planes/makers/+page.server.ts @@ -1,11 +1,11 @@ import { planeOverview } from '#lib/server/planes.js'; -import { seenByGroup } from '#lib/server/spotting.js'; +import { logoFirst, seenByGroup } from '#lib/server/spotting.js'; import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async () => { const [{ byBuilt, stats }, seen] = await Promise.all([planeOverview(), seenByGroup('planes')]); return { - makers: byBuilt.map(({ id, slug, name, types, built, logo }) => ({ + makers: logoFirst(byBuilt).map(({ id, slug, name, types, built, logo }) => ({ seen: seen.get(id) ?? 0, slug, name, diff --git a/src/routes/trackers/trains/+page.server.ts b/src/routes/trackers/trains/+page.server.ts index d11daf9..0018326 100644 --- a/src/routes/trackers/trains/+page.server.ts +++ b/src/routes/trackers/trains/+page.server.ts @@ -3,6 +3,7 @@ import { areasWithData, groupActivity, progress, + logoFirst, rankByActivity, seenByGroup } from '#lib/server/spotting.js'; @@ -46,7 +47,7 @@ export const load: PageServerLoad = async ({ url }) => { countries: overview.countries .filter((c) => c.types >= 3 || c.name === filters.country) .map(({ name, types }) => ({ name, types })), - topMakers: rankByActivity(overview.byBuilt, act) + topMakers: logoFirst(rankByActivity(overview.byBuilt, act)) .slice(0, 16) .map(({ id, slug, name, types, built, logo }) => ({ slug, @@ -57,11 +58,12 @@ export const load: PageServerLoad = async ({ url }) => { seen: seenMakers.get(id) ?? 0 })), // Operators from the chosen area first (the world region keeps the plain fleet-size order). - topOperators: (filters.area === 'world' - ? overview.operators - : [...overview.operators].sort( - (a, b) => Number(home.has(b.country ?? '')) - Number(home.has(a.country ?? '')) - ) + topOperators: logoFirst( + filters.area === 'world' + ? overview.operators + : [...overview.operators].sort( + (a, b) => Number(home.has(b.country ?? '')) - Number(home.has(a.country ?? '')) + ) ) .slice(0, 16) .map(({ slug, name, types, logo }) => ({ diff --git a/src/routes/trackers/trains/makers/+page.server.ts b/src/routes/trackers/trains/makers/+page.server.ts index 2614fee..e2abfd2 100644 --- a/src/routes/trackers/trains/makers/+page.server.ts +++ b/src/routes/trackers/trains/makers/+page.server.ts @@ -1,11 +1,11 @@ import { trainOverview } from '#lib/server/trains.js'; -import { seenByGroup } from '#lib/server/spotting.js'; +import { logoFirst, seenByGroup } from '#lib/server/spotting.js'; import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async () => { const [{ byBuilt, stats }, seen] = await Promise.all([trainOverview(), seenByGroup('trains')]); return { - makers: byBuilt.map(({ id, slug, name, types, built, logo }) => ({ + makers: logoFirst(byBuilt).map(({ id, slug, name, types, built, logo }) => ({ seen: seen.get(id) ?? 0, slug, name, diff --git a/src/routes/trackers/trains/operators/+page.server.ts b/src/routes/trackers/trains/operators/+page.server.ts index 716f90d..6d4c2b5 100644 --- a/src/routes/trackers/trains/operators/+page.server.ts +++ b/src/routes/trackers/trains/operators/+page.server.ts @@ -1,10 +1,11 @@ import { trainOverview } from '#lib/server/trains.js'; +import { logoFirst } from '#lib/server/spotting.js'; import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async () => { const { operators, stats } = await trainOverview(); return { - makers: operators.map(({ slug, name, types, logo }) => ({ + makers: logoFirst(operators).map(({ slug, name, types, logo }) => ({ slug, name, types,