Skip to content

feat(featured-stream): off-web exclusion, ad-free close, keep through lobby wait - #4698

Merged
evanpelle merged 2 commits into
openfrontio:mainfrom
Zixer1:feat/featured-stream-offweb-close
Jul 24, 2026
Merged

feat(featured-stream): off-web exclusion, ad-free close, keep through lobby wait#4698
evanpelle merged 2 commits into
openfrontio:mainfrom
Zixer1:feat/featured-stream-offweb-close

Conversation

@Zixer1

@Zixer1 Zixer1 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Three related changes to the homepage featured-stream panel.

1. Exclude the embed off the open web (ToS)

Never mount the Twitch embed on CrazyGames or the desktop (Steam) shell, and never load the Twitch SDK there. Matches how the app already suppresses its own promos off-web via window.adsEnabled:

2. Close button for ad-free users

Ad-free users (any shop purchase makes a user adfree for life, which zeroes window.adsEnabled) get an × in the minimized bar. The close is remembered for the current day (the day is stored in localStorage), so the panel stays gone across reloads that day and resets for the next day's stream. Ad-supported users keep minimize only; their mobile flick stays session-only. The minimized state is scoped to the day the same way.

3. Keep the panel through the lobby wait

The panel used to hide the moment you joined a lobby (join-lobby). Now it stays up through the queue/lobby wait and hides only once the game actually starts. Main.ts dispatches a new game-starting event at prestart (the real start moment); the panel hides on that instead of on join-lobby, and reappears on leave-lobby.

Heads-up for maintainers: (1) and (2) couple this OFM widget to OF's own ad/entitlement signals (crazyGamesSDK.isOnCrazyGames(), isDesktopShell(), window.adsEnabled); (3) adds a small shared game-starting document event in Main.ts. Flagging in case you'd rather gate/signal differently.

Tests

Verified locally: prettier, eslint, tsc, tests all green. Reuses the existing common.close i18n key (no locale-file changes).

Follow-up to #4335 / #4673. Sizing (Twitch's 400×300 minimum) landed in #4696.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

FeaturedStream now gates Twitch setup by runtime, channel, and daily persisted state. It adds ad-free close behavior, day-scoped minimized state, game-starting lifecycle handling, and consistent Twitch player teardown.

Changes

Featured stream behavior

Layer / File(s) Summary
Stream gating and lifecycle
src/client/FeaturedStream.ts
CrazyGames, the desktop shell, empty channel lists, and today’s persisted closure prevent Twitch startup; minimized state is restored only for the current day.
Game-starting lifecycle
src/client/Main.ts, src/client/FeaturedStream.ts
The client emits a typed game-starting event when prestart ends, and FeaturedStream stops probing during gameplay startup.
Dismissal interactions and controls
src/client/FeaturedStream.ts
Flicks and the minimized ad-free close button dismiss the panel, optionally persist today’s closure, clear timers, and tear down the player.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: Feature, UI/UX

Suggested reviewers: evanpelle, celant

Poem

Twitch waits behind a gate,
Empty channels seal its fate.
A tiny ✕ can close the stream,
For today, it leaves the screen.
The quiet panel rests away.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title matches the main changes: off-web embed gating, ad-free close, and lobby-wait visibility.
Description check ✅ Passed The description is directly about the featured-stream panel changes and matches the code updates.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Zixer1
Zixer1 force-pushed the feat/featured-stream-offweb-close branch from 080b020 to ce22a23 Compare July 23, 2026 22:29
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 23, 2026
@Zixer1
Zixer1 force-pushed the feat/featured-stream-offweb-close branch from ce22a23 to 361ab0f Compare July 23, 2026 22:38
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 23, 2026
…ee users

- Platform gate: never mount the Twitch embed on CrazyGames or the desktop
  (Steam) shell, and never load the Twitch SDK there. A Twitch embed carries
  Twitch's own ads and is third-party content, which breaks CrazyGames'
  SDK-ads-only policy and Steam's no-in-game-ads rules, and can't satisfy
  Twitch's parent-domain check in the shell. Matches how the app already
  suppresses its promos off the open web.

- Close button: ad-free users (any shop purchase => adfree for life, so
  window.adsEnabled === false) get an x in the minimized bar. Their close is
  remembered for the current day (the day is stored in localStorage), so the
  panel stays gone across reloads that day and resets for the next day's
  stream. Ad-supported users keep minimize only; their mobile flick stays
  session-only.

- Scope the minimized state to the current day the same way (it was persisted
  indefinitely before), so it also resets for the next day's stream.
@Zixer1
Zixer1 force-pushed the feat/featured-stream-offweb-close branch from 361ab0f to 0a178b5 Compare July 23, 2026 22:53
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 23, 2026
The panel used to hide the moment you joined a lobby (on join-lobby). Keep it
up through the queue/lobby wait and hide only once the game actually starts:
Main dispatches a game-starting event at prestart, and the panel hides on that
instead of on join-lobby. It reappears on leave-lobby.
@Zixer1 Zixer1 changed the title feat(featured-stream): exclude embed off-web + ad-free close button feat(featured-stream): off-web exclusion, ad-free close, keep through lobby wait Jul 23, 2026
@github-project-automation github-project-automation Bot moved this from Triage to Final Review in OpenFront Release Management Jul 24, 2026
@evanpelle
evanpelle merged commit 13a86f4 into openfrontio:main Jul 24, 2026
11 checks passed
@github-project-automation github-project-automation Bot moved this from Final Review to Complete in OpenFront Release Management Jul 24, 2026
evanpelle pushed a commit that referenced this pull request Jul 25, 2026
… lobby wait (#4698)

Three related changes to the homepage featured-stream panel.

## 1. Exclude the embed off the open web (ToS)
Never mount the Twitch embed on **CrazyGames** or the **desktop (Steam)
shell**, and never load the Twitch SDK there. Matches how the app
already suppresses its own promos off-web via `window.adsEnabled`:

- **CrazyGames:** [only SDK-served ads are
allowed](https://docs.crazygames.com/requirements/ads/) and no external
cross-promotion; a Twitch embed serves Twitch's own ads and is
third-party content.
- **Steam:** Steam [does not support advertising models in
games](https://partner.steamgames.com/doc/marketing/advertising); a live
Twitch player carries Twitch ad breaks, and the desktop shell can't
satisfy Twitch's `parent`-domain requirement.

## 2. Close button for ad-free users
Ad-free users (any shop purchase makes a user `adfree` for life, which
zeroes `window.adsEnabled`) get an `×` in the minimized bar. The close
is remembered **for the current day** (the day is stored in
`localStorage`), so the panel stays gone across reloads that day and
resets for the next day's stream. Ad-supported users keep minimize only;
their mobile flick stays session-only. The minimized state is scoped to
the day the same way.

## 3. Keep the panel through the lobby wait
The panel used to hide the moment you joined a lobby (`join-lobby`). Now
it stays up through the **queue/lobby wait** and hides only once the
game actually starts. `Main.ts` dispatches a new `game-starting` event
at `prestart` (the real start moment); the panel hides on that instead
of on `join-lobby`, and reappears on `leave-lobby`.

> Heads-up for maintainers: (1) and (2) couple this OFM widget to OF's
own ad/entitlement signals (`crazyGamesSDK.isOnCrazyGames()`,
`isDesktopShell()`, `window.adsEnabled`); (3) adds a small shared
`game-starting` document event in `Main.ts`. Flagging in case you'd
rather gate/signal differently.

## Tests
Verified locally: prettier, eslint, tsc, tests all green. Reuses the
existing `common.close` i18n key (no locale-file changes).

Follow-up to #4335 / #4673. Sizing (Twitch's 400×300 minimum) landed in
#4696.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Complete

Development

Successfully merging this pull request may close these issues.

2 participants