Skip to content

[WS-3118] - Enable Toucan fake fullscreen support on iOS - #14338

Draft
hotinglok wants to merge 31 commits into
latestfrom
WS-3118-toucan-fake-fullscreen-portal
Draft

[WS-3118] - Enable Toucan fake fullscreen support on iOS#14338
hotinglok wants to merge 31 commits into
latestfrom
WS-3118-toucan-fake-fullscreen-portal

Conversation

@hotinglok

Copy link
Copy Markdown
Contributor

Resolves JIRA:

Summary

A very high-level summary of easily-reproducible changes that can be understood by non-devs, and why these changes where made.

Code changes

  • List key code changes that have been made.

Testing

  1. List the steps required to test this PR.

Useful Links

HarveyPeachey and others added 30 commits July 24, 2026 12:44
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
… [copilot]

The inner div wrapping the player content needs flex/height properties so it fills the figure's aspect-ratio constraint for both portrait and landscape orientations.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ilot]

buildConfig() was called directly in MediaLoader's render body, producing a
new playerConfig object identity on every render. Entering/exiting fake
fullscreen updates isFakeFullscreenActive state, re-rendering MediaLoader,
which caused MediaContainer's effect to see a changed playerConfig
reference and tear down/recreate the Bump player mid-playback -
immediately closing the freshly-entered iOS fake fullscreen.

Memoise config via useMemo keyed on its real inputs so its identity is
stable across re-renders that don't actually change the player
configuration. Moved the memoised computation ahead of the isLite early
return to keep hook ordering valid.

Added a regression test that exercises real React state (rather than the
mocked no-op setState used elsewhere in this file) to confirm requirejs/
Bump.player/load are only invoked once even after a fake fullscreen state
change.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Enables a robust “fake fullscreen” experience for media playback (targeting iOS Safari limitations) by introducing a global fullscreen page-state class, a portalled backdrop layer, and MediaLoader changes that avoid re-initialising the BUMP player during fullscreen transitions.

Changes:

  • Add fake-fullscreen support in MediaLoader (portal backdrop, injected CSS, global <html>/<body> fullscreen class toggling, stable player config initialisation).
  • Add an opt-out (withinFullscreenContainer) for callers that already present their own fullscreen container (e.g. PortraitVideoModal).
  • Update integration/unit snapshots, tests, and documentation to match the new DOM structure and behaviour.

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
ws-nextjs-app/integration/pages/podcastPage/portugueseEpisode/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/podcastPage/portugueseBrand/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/onDemandTVPage/pashtoBrand/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/onDemandTVPage/hausa/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/onDemandAudioPage/pashtoBrand/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/onDemandAudioPage/pashto/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/onDemandAudioPage/indonesia/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/liveRadio/kyrgyz/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/liveRadio/korean/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/liveRadio/gahuza/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/live/pidgin/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/av-embeds/russian/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/articles/persianMediaPlayer/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
ws-nextjs-app/integration/pages/articles/afrique/snapshots/canonical.test.ts.snap Snapshot updates for new MediaLoader wrapper and attributes.
src/app/lib/mediaPlayerFullscreen.const.ts Introduces a shared global page-state class constant for fullscreen styling.
src/app/legacy/containers/Header/snapshots/index.test.jsx.snap Snapshot updates due to new fullscreen-related styles being generated in renders.
src/app/legacy/containers/ConsentBanner/Banner/index.canonical.jsx Adjusts consent banner stacking during fake fullscreen via global page-state class.
src/app/legacy/containers/ConsentBanner/Banner/snapshots/index.canonical.test.jsx.snap Snapshot updates reflecting new consent banner styling output.
src/app/components/PortraitVideoModal/index.tsx Passes withinFullscreenContainer to MediaLoader to avoid conflicting fullscreen behaviour.
src/app/components/PortraitVideoModal/index.styles.tsx Adjusts modal stacking during fake fullscreen via global page-state class.
src/app/components/PageLayoutWrapper/snapshots/index.test.tsx.snap Snapshot updates due to new fullscreen-related styles being generated in renders.
src/app/components/MediaLoader/README.md Documents fake fullscreen approach, stability concerns, and new opt-out prop.
src/app/components/MediaLoader/index.tsx Implements fake fullscreen (portal layer, injected styles, global class toggling) and memoised config.
src/app/components/MediaLoader/index.test.tsx Adds tests for fullscreen class toggling, handler composition, and style injection behaviour.
src/app/components/MediaLoader/index.styles.ts Adds fake-fullscreen CSS, constants, and wrapper styling.
src/app/components/Curation/index.tsx Removes consent-banner DOM z-index manipulation in favour of the new global fullscreen signalling.
src/app/components/Account/AccountSignInModal/index.styles.tsx Adjusts modal stacking during fake fullscreen via global page-state class.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/app/components/MediaLoader/README.md Outdated
Comment on lines +21 to +23
body.${PLAYER_FULLSCREEN_CLASS} & {
z-index: -1;
}
Comment on lines +30 to +32
[`body.${PLAYER_FULLSCREEN_CLASS} &`]: {
zIndex: -1,
},
Comment on lines +32 to +34
[`body.${PLAYER_FULLSCREEN_CLASS} &`]: {
zIndex: -1,
},
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants