feat(client): play-page identity bubble + Streaming Now panel - #4766
feat(client): play-page identity bubble + Streaming Now panel#4766Zixer1 wants to merge 6 commits into
Conversation
Homepage panel showing who is live playing OpenFront (issue openfrontio#3485): compact streamer cards (avatar, platform badge, viewers) in a fixed-size horizontal slider, each linking out to the stream. Fed by /live-streams.json, served like news.json with a bundled OFF fallback and validated fail-closed (https-only URLs so an injected entry can't reach href/src). The list refreshes every 90s while the page is open. The host stays display:none until at least one stream is live, so the layout is untouched when nobody is streaming. The backend side (admin-curated YouTube + a Twitch roster polled via Helix by a cron) lives in the infra repo; openfrontio/infra#480 completes it.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
🚧 Files skipped from review as they are similar to previous changes (7)
WalkthroughAdds validated live-stream configuration and fallback loading, then renders a refreshable “Streaming Now” panel with localized labels, platform links, viewer counts, avatars, and tests. It also adds cosmetic background rendering and small input styling updates. ChangesStreaming Now feature
Cosmetic and input UI updates
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant PlayPage
participant StreamingNow
participant getLiveStreams
participant live_streams_json as live-streams.json
PlayPage->>StreamingNow: render streaming-now element
StreamingNow->>getLiveStreams: refresh stream data
getLiveStreams->>live_streams_json: fetch configuration
live_streams_json-->>getLiveStreams: stream configuration
getLiveStreams-->>StreamingNow: validated streams
StreamingNow-->>PlayPage: render live stream cards
Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/client/Api.ts`:
- Around line 1098-1116: Add a per-request AbortController in getLiveStreams,
pass its signal to fetch, and ensure the controller is aborted in a finally
block so recurring requests cannot remain pending indefinitely. Preserve the
existing status handling, validation, and liveStreamsFallback behavior.
In `@src/core/ApiSchemas.ts`:
- Around line 576-584: Harden LiveStreamSchema.channel validation before it is
interpolated into platform watch URLs by rejecting URL delimiters and
whitespace, or applying platform-specific Twitch and YouTube channel rules while
preserving valid channels. Add malformed Twitch and YouTube channel cases to
tests/client/components/StreamingNow.test.ts lines 69-102; update
src/core/ApiSchemas.ts lines 576-584 for the schema change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d1facf96-1ca5-4d6c-b5f7-8d5598f9cceb
📒 Files selected for processing (7)
resources/lang/en.jsonresources/live-streams.jsonsrc/client/Api.tssrc/client/components/PlayPage.tssrc/client/components/StreamingNow.tssrc/core/ApiSchemas.tstests/client/components/StreamingNow.test.ts
- Desktop only: hidden below lg via classes, and the component skips polling entirely when connected under the breakpoint. - Never on CrazyGames: a panel of Twitch/YouTube links is cross-promotion to external platforms, which their gameplay requirements prohibit. The Steam build keeps it: Valve's link restrictions cover store pages, not in-game community links, and the panel serves no ads.
Streams of this game are community content (the same CrazyGames rule that bans game/platform cross-promotion explicitly allows community links), and other games on the platform ship the same feature. Only the mobile gate stays.
…ow design Restores the full play-page design built on feat/streaming-now, adapted to current main: - Identity row: flag + tag/username + skin in one surface bubble, with the selected skin/pattern filling the bubble like the player's territory does in game (cosmetic-background). Replaces the separate mobile/desktop SELECT FLAG / cosmetics buttons; pattern-input became cosmetics-input on main, so the row uses that (keeps the no-crazygames class and the cosmetics-input-mobile id that the iframe rule targets). - Top strip: news + identity left, Streaming Now right. The 2fr/1fr split only exists while the panel is live (has-[.streaming-live]), so news and identity keep the full row when nobody streams. Panel stays desktop-only. - Flag button goes transparent inside the bubble; username/tag get a text shadow so they stay readable over a skin background.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/client/components/CosmeticBackground.ts`:
- Around line 19-46: Update CosmeticBackground.connectedCallback and load so the
settings-change listener is registered before the initial load, preventing
updates during the request from being missed. Track each load invocation with a
request/version token and apply cosmetic values only when the component is still
connected and the result belongs to the latest active load; invalidate prior
loads on disconnectedCallback so stale results cannot update state after
reconnect or rapid changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e6a23efa-4536-402f-bc9e-97f4a1256428
📒 Files selected for processing (5)
src/client/FlagInput.tssrc/client/UsernameInput.tssrc/client/components/CosmeticBackground.tssrc/client/components/PlayPage.tssrc/client/components/StreamingNow.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/client/components/StreamingNow.ts
- src/client/components/PlayPage.ts
- Served-config fetches (featured-stream, live-streams) share one helper with a 10s timeout, so a fetch that never settles can't wedge a recurring poll. - LiveStreamSchema restricts channel to a URL-safe handle charset (no slashes, queries, or whitespace), so an entry can't smuggle path/query segments into the derived watch URL; tests added. - CosmeticBackground registers its settings listener before the initial load and guards overlapping loads with a generation counter.
|
@coderabbitai review |
✅ Action performedReview finished.
|
What
The play-page top-strip redesign from the streaming-now work, ported onto current main:
cosmetic-background). Replaces the separate mobile/desktop SELECT FLAG / cosmetics buttons. Flag button goes transparent inside the bubble; username/tag get a text shadow so they stay readable over a skin.Layout behavior
has-[.streaming-live]): when nobody streams, news + identity keep the full row — the page is pixel-identical to having no panel.lgand skips polling entirely there.pattern-inputbecamecosmetics-inputon main; the identity row uses it, keeping theno-crazygamesclass and thecosmetics-input-mobileid the iframe rule targets.Feed
GET /live-streams.json, served likenews.jsonwith a bundled off fallback, validated fail-closed (https-onlyurl/avatarUrland a URL-safe channel charset, so a bad entry can't reachhref/srcor smuggle path segments into derived watch URLs). Fetches share a 10s timeout. Refreshes every 90s. Filled by the infra side (curated YouTube + a Twitch roster polled via Helix) — openfrontio/infra#480. Until that deploys with its Twitch secrets, the panel simply never shows.Tests
StreamingNow.test.ts: watch-URL derivation, viewer-count formatting, schema fail-closed cases (unknown platform, malformed channels, non-URL avatar,javascript:/http:schemes), and the bundled fallback shipping disabled. Locally green: prettier, eslint, tsc, vitest (incl. the en.json sort check).