Repository navigation
Combined release: 16 PRs ready to merge - #249
Merged
Merged
Conversation
The seed drew latitudes from the whole -90°..90° range, but Web Mercator maps stop near ±85°: past that the tile row is negative and pigeon-maps loads no tiles. About one place in twenty landed there, so the map-tile e2e test failed whenever the first event happened to be one (#222's run 37188728932). Real places never are; keep seeded latitudes within ±80°. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The org page's "Games" and "Hosted events", the event page's "Games" and /places' "Locations" headings held their count badge inside the heading, so their text and accessible name read "Games23" for screen readers, the document outline and crawlers. A SectionHeading component puts the heading and its count side by side, looking the same as before, and announces the count as "23 games". Fixes #197. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cards showed the raw "studio" and an ad-hoc "assoc", and the org page the bare enum value: Chakra v2's Badge upper-cased these, v3's doesn't. The type colours were defined four times over. One orgTypes module now holds each type's label, short label and colour palette. Cards show "Studio" / "Assoc." on their small thumbnail badge, the org page "Studio" / "Association", and the form and map markers take their labels and colours from the same place. Fixes #202. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Game cards and the game page showed tags as bare chips in a <div>,
spaced only by margins, so screen readers, copy-paste and text tools got
one run-on word ("soloplatformroguelikeaction").
A TagList component renders them as a list labelled "Tags", one item per
tag, spaced with gap; on the game page each tag still links to the
filtered games list (its name is now URL-encoded). They look the same.
Fixes #201.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The event page reads each attendee's avatar.thumbnail_url, but the loader passed the raw image row, which has no such field, so every attendee fell back to their initial (the stray "y" on live event pages). computeEvent now turns participants' avatars into image links. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The studio, association and event lists filtered by country with a native select listing every country (about a hundred on live data), which can't be searched beyond jumping to a first letter. CountryCombobox replaces it: type to narrow the countries, shown with their flag and count; picking one or clearing it submits the form as before (?country=<CODE>, or no parameter), through a hidden input. Fixes #205. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/games could only be filtered by tag and always listed recently updated games first. Add a search box (?q=, debounced, matching name or description, case- insensitive) and a sort control (?sort= updated, newest or name; unknown values fall back to updated, and orderBy is picked from a whitelist). Both combine with the tag filters, which now keep the other parameters when toggled, and with infinite scroll; an id tiebreak keeps pages from overlapping. Fixes #206. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The location picker queried Mapbox without a language, which answers with each place's local name, so locations were saved as "Warszawa", "Genève" or "京都市" next to English ones. - geocodingUrl() builds every Mapbox geocoding request with language=en (and encodes the query); the picker uses it. - scripts/backfill-place-names.mjs re-geocodes existing locations from their coordinates: dry run by default, --write to apply, paced, and it merges a renamed row into an identical existing one. - The place parser referenced an undefined `address` whenever a result's context held an address; it reads the context entry instead. - PhotonAutocomplete was unused (the issue first blamed it); removed. Fixes #208. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tag list had spelling and translation variants side by side (coop/co-op, platform/platforms/plaftorm/platformer, aventure/adventure, shoot'em'up/shoot 'em up…), and input was only split, trimmed and lower- cased: a trailing comma could add an empty tag and a repeated tag made the save fail on the game_tag key. - Migration: a tag_alias table, and merge_tag_variant(variant, canonical), which moves a variant's games to the canonical tag (once), deletes it and keeps it as an alias. It merges the pairs agreed on #207 (roguelite and shoot 'em up stay separate genres) and deletes nameless tags. - Input: tags are normalised (case, spaces, apostrophes, "'em"), empty and repeated ones dropped, and aliases mapped to their tag, on game create and edit. Fixes #207. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #150, as decided there: - Drop entity_image, entity_member, game_author and reset_token, and game.tag_list, game_event.tags, person.github_id, steam_id and password_hash (passwords are dropped: sign-in moves to Bluesky). - Remove the sign-up, forgot and reset routes, their forms and password inputs, SendGrid, and the GitHub profile links (no GitHub sign-in). - Org deletion no longer clears members; /admin/missing lists games without studios. - Add entity.status (#39: active, closed, hiatus; default active) and game_entity.role (#40: developer, co_developer, publisher, porting, support; default developer). UI follows. - Index foreign keys and filtered columns. The migration drops with IF EXISTS / CASCADE so it doesn't depend on production's constraint names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Event dates were formatted with whatever locale and time zone the code ran in: cards in the viewer's (12-hour, no year), the event page in English 24-hour, so server and browser disagreed (#183's hydration errors) and visitors abroad saw their own clock. The form sent wall-clock times without an offset and the server read them in its own zone, so on a UTC host every edit from France would have shifted the event. - event.time_zone (IANA, default Europe/Paris), set from the location's coordinates on create and edit (offline lookup). - eventTime.js: one formatter (en, 24-hour, year only when not the current one, plain spaces, hand-built ranges) and zone-aware conversion for datetime-local values; nothing depends on the process' time zone. Cards, the date label, the event page, its meta description and the game page's event list use it, and the form shows and reads times in the event's zone. - <time dateTime> attributes used Date#toString (process time zone): now ISO strings. - e2e runs the server in UTC. - scripts/backfill-event-time-zones.mjs sets existing events' zones and re-reads their times as typed (saved as Europe/Paris), dry run first. Fixes #204. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
React Router 7 doesn't merge a route's meta with its parent's, so pages
that only set a title (/games) had no description at all, the homepage,
/about and /events shared the events tagline, game and org pages built
`${about}.` ("." or "null." when empty), and only detail pages with an
image had one when shared.
pageMeta() builds the whole set in one place: title, description, Open
Graph (type, site name, absolute URL, image) and Twitter tags, with the
large card whenever there is an image. summarize() turns an "about" into
a description (Markdown stripped, one line, cut at a word around 160
characters, never just punctuation). Every public route uses them:
- list pages each get their own description;
- game, org and event pages use their about, else a generated sentence
("Indie game by X, tagged Y.", "Video game studio in Rennes, FR.",
the event's date and place);
- pages without their own image share public/og-default.png, rendered
from the logo.
The charset and viewport tags stay in Layout only.
Fixes #196.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
member's username and first name (never their email) to the existing Discord webhook, with a link to the members page when BASE_URL is set. Both sign-in strategies call it right after creating an account, so signing in again doesn't repeat it; Bluesky sign-in (#157) will call it too. Every webhook message now sets allowed_mentions to none: game, event, org and member names are typed by people, and one called "@everyone" would have pinged the whole server. Fixes #34. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
people see a short hint where there's something they can add. - Game page: "Made by" only appears with studios, or for signed-in people, who get "Who made this game? Add a studio or association." next to the existing add button. - Event page: "Games" and "Organizers" already showed only with content or to members; empty, they now hint at what to add. "Related events" (computed, nothing to add) is hidden when there are none. - Org page: empty "Games" and "Hosted events" stay hidden from visitors; members see how to add them. EmptyHint keeps the wording's look consistent. Fixes #198. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sign-in): an optional bsky_handle on entity, edited in the org form and
linked from the org page with the Bluesky icon.
What people type is normalised ("@Studio.bsky.social" or a bsky.app
profile URL becomes "studio.bsky.social") and checked with Bluesky's
public resolveHandle when saving; a malformed or unknown handle is
refused with a message instead of being stored. The API base URL is
configurable (BLUESKY_API), so the e2e tests use a local stand-in.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves the whole React Router family together, so there's one copy of react-router (Dependabot's #238 bumped only one package and left two). Fixes GHSA-8x6r-g9mw-2r78 (DoS via __manifest) and GHSA-84g9-w2xq-vcv6 (CSRF on PUT/PATCH/DELETE), plus the semver-compatible fixes from npm audit fix. Audit count goes from 63 to 34. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Takes Dependabot's #236 vite range (#235's valibot 1.5.0 and #237's baseline-browser-mapping 2.11.27 are already in the lockfile), re-syncs the lockfile after #240's dependency, and removes the ogUrl imports the game and event pages no longer use since pageMeta. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 4, 2026
This was referenced Oct 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Combines the open PRs into one branch, one commit per PR, so they can land together. Merge with "Rebase and merge" to keep the per-PR commits. Their
Fixes #…lines then close #34, #196, #197, #198, #201, #202, #204, #205, #206, #207 and #208.Included
npm audit fix(supersedes #238)Left out:
Conflict resolution
The conflicts were in imports (each PR added its own) and in e2e specs (each PR appended tests). Both sides were kept everywhere. The old
TYPES_COLORSconstant is gone (replaced byutils/orgTypes).playwright.config.jssetsTZ,DISCORD_NOTIFICATION_WEBHOOKandBLUESKY_APItogether. The last commit removesogUrlimports thatpageMetamade unused.Testing
On a fresh database (all migrations from scratch, then seeded):
react-router build✅🤖 Generated with Claude Code