upload-decoration-textures #4

Merged
nicky merged 4 commits from upload-decoration-textures into main 2026-07-29 16:38:05 +00:00
Owner
No description provided.
Pulls in three public-domain Smithsonian Open Access scans (triceratops
skeleton, Space Shuttle Discovery, an antique armchair), re-compressed with
gltf-transform to ~1.4MB total, as an opt-in "curiosities" toggle in the
decorate panel. Off by default; persists per-room through the existing
room_decor field for both the personal lobby and group rooms.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rooms are addressable again: kitkit.blog/users/<username>, /groups/<slug>, and
/groups/<slug>/<username> for one member's entry. All room routes render the
same Home component, so the WebGL canvas is never torn down and the
fade-through between rooms still animates. Back/forward now walk between rooms.

Groups gain a unique slug (derived from the name, -2/-3 on collision, migration
backfills existing rows) and usernames are validated to a path-safe charset and
matched case-insensitively, so /users/nick finds "Nick".

The loop email is now just a link into the group's room instead of a copy of
everyone's posts. It pins ?period= so opening it later still shows the loop it
announced rather than the next empty one, and a logged-out click returns to the
room after login.

Inside a group room, members stand at fixed spots and anyone who wrote this
period can be clicked to walk their exhibit: text as pinned wall notes, photos
in frames, video/songs on a projector screen, arranged down the side walls.
Left/right (or arrow keys) run a guided tour that eases the camera in front of
each piece, spotlighting it, with the room's furniture and wall decor cleared
out of the way.

Also closes a pre-existing leak: GET /users/{username} required no auth and
returned the user's email address. It now requires a session and omits email,
and other members' drafts are no longer served from GET /posts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds a "+ video" section: paste any YouTube link and it becomes a projector
screen in the room. parseYouTubeId handles watch/youtu.be/shorts/embed/live and
bare ids, rejecting anything else with a hint instead of silently accepting it;
playback goes through youtube-nocookie so reading a loop doesn't set ad cookies.

The player is a real iframe (a YouTube embed can't be a WebGL texture) pinned to
the screen mesh via <Html transform>, and is only mounted while the guided tour
is focused on it — <Html> is DOM, so an unfocused one would show through the
walls and eagerly load the player. Unfocused screens show a play glyph instead.

The px-to-world scale for the player is a measured constant: drei's transform
mode maps CSS px to world units at a fixed ratio, verified identical at 800x600,
1280x900 and 1600x900, so the iframe covers its screen at any viewport.

Also splits ProjectorScreen into YouTubeScreen/MediaScreen. The YouTube branch
had returned before the video-texture hooks, so a section changing type would
have broken hook order; the dispatch now happens above any hooks. And corrects
the exhibit's song fields to artwork_url, which is what SongSection actually
writes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nicky merged commit 0506092cf9 into main 2026-07-29 16:38:05 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nicky/kitkit!4
No description provided.