diff --git a/dotcom-rendering/package.json b/dotcom-rendering/package.json index a7082ad986..b285bfb4a0 100644 --- a/dotcom-rendering/package.json +++ b/dotcom-rendering/package.json @@ -38,7 +38,7 @@ "@emotion/server": "11.11.0", "@guardian/ab-core": "8.0.0", "@guardian/braze-components": "21.0.0", - "@guardian/bridget": "7.0.0", + "@guardian/bridget": "8.0.0", "@guardian/browserslist-config": "6.1.0", "@guardian/cdk": "50.13.0", "@guardian/commercial": "23.0.0", diff --git a/dotcom-rendering/src/components/YoutubeAtom/YoutubeAtomPlayer.tsx b/dotcom-rendering/src/components/YoutubeAtom/YoutubeAtomPlayer.tsx index 63ace483dd..6a4c3e260d 100644 --- a/dotcom-rendering/src/components/YoutubeAtom/YoutubeAtomPlayer.tsx +++ b/dotcom-rendering/src/components/YoutubeAtom/YoutubeAtomPlayer.tsx @@ -1,4 +1,4 @@ -import { css } from '@emotion/react'; +import { css, Global } from '@emotion/react'; import type { Participations } from '@guardian/ab-core'; import { buildImaAdTagUrl } from '@guardian/commercial'; import type { ConsentState } from '@guardian/libs'; @@ -11,6 +11,7 @@ import { useState, } from 'react'; import { getVideoClient } from '../../lib/bridgetApi'; +import { getZIndex } from '../../lib/getZIndex'; import { getAuthStatus } from '../../lib/identity'; import type { RenderingTarget } from '../../types/renderingTarget'; import type { google } from './ima'; @@ -74,6 +75,20 @@ const imaPlayerStyles = css` height: 100%; `; +const fullscreenStyles = (id: string) => css` + html { + overflow: hidden; + } + iframe#${id} { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + z-index: ${getZIndex('youTubeFullscreen')}; + } +`; + /** * Dispatches a custom play event so that other players listening * for this event will stop playing @@ -398,6 +413,9 @@ export const YoutubeAtomPlayer = ({ }); const [playerReady, setPlayerReady] = useState(false); + const [isFullscreen, setIsFullscreen] = useState(false); + const [applyFullscreenStyles, setApplyFullscreenStyles] = + useState(false); const playerReadyCallback = useCallback(() => setPlayerReady(true), []); const playerListeners = useRef([]); /** @@ -447,9 +465,6 @@ export const YoutubeAtomPlayer = ({ videoId, playerVars: { controls: 1, - // @ts-expect-error -- advised by YouTube for Android but does not exist in @types/youtube - external_fullscreen: - renderingTarget === 'Apps' ? 1 : 0, fs: 1, modestbranding: 1, origin, @@ -472,8 +487,7 @@ export const YoutubeAtomPlayer = ({ from: 'YoutubeAtomPlayer fullscreen', videoId, }); - // For Android only, iOS will stub the method - void getVideoClient().fullscreen(); + setIsFullscreen((prev) => !prev); } }, }, @@ -644,17 +658,36 @@ export const YoutubeAtomPlayer = ({ }; }, []); + /** + * For apps rendered articles that return true for `setFullscreen` the web layer + * needs to handle the application of fullscreen styles + * + * This is only for the YouTube player in Android web views which does not support fullscreen + */ + useEffect(() => { + if (renderingTarget === 'Apps') { + const videoClient = getVideoClient(); + void videoClient.setFullscreen(isFullscreen).then((success) => { + if (success) { + setApplyFullscreenStyles(isFullscreen); + } + }); + } + }, [isFullscreen, renderingTarget]); + /** * An element for the YouTube player to hook into the dom */ return ( -
+ <> + {applyFullscreenStyles && } +
+ ); }; diff --git a/dotcom-rendering/src/lib/getZIndex.ts b/dotcom-rendering/src/lib/getZIndex.ts index 0c1a74035f..cd8d4850eb 100644 --- a/dotcom-rendering/src/lib/getZIndex.ts +++ b/dotcom-rendering/src/lib/getZIndex.ts @@ -24,6 +24,7 @@ const indices = [ // Modals will go here at the top 'lightbox', + 'youTubeFullscreen', // Sticky video and button need to be above everything 'sticky-video-button', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c256cee54..ff5249557c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -329,8 +329,8 @@ importers: specifier: 21.0.0 version: 21.0.0(@emotion/react@11.11.3)(@guardian/libs@19.1.0)(@guardian/source@8.0.0)(react@18.3.1) '@guardian/bridget': - specifier: 7.0.0 - version: 7.0.0 + specifier: 8.0.0 + version: 8.0.0 '@guardian/browserslist-config': specifier: 6.1.0 version: 6.1.0(browserslist@4.23.0)(tslib@2.6.2) @@ -3947,6 +3947,10 @@ packages: resolution: {integrity: sha512-S0NmkyYd1hQRyOUj7l9Ddfr6FKEHJFLpS2jSMkGexCSscsZd7e8JBdFmlKSUljt4G6hrxcaaevsV4QfT9LnhUg==} dev: false + /@guardian/bridget@8.0.0: + resolution: {integrity: sha512-ae+yENkvcEOZBDqFE8RkdjyLki/iczatDc+MBTZS2vipmrcTeP0lOkZcsq/QxlNMSvZ6HNOETV8MIcGK/Gx3Hw==} + dev: false + /@guardian/browserslist-config@6.1.0(browserslist@4.23.0)(tslib@2.6.2): resolution: {integrity: sha512-qM0QxAv6E5IHXny5Okli6AZXEio0mpXzzEzz38qrb4IwO91R6eWVKyihdj0qW2k7TVxMFVOSfNmBZ1H5EiJhgw==} peerDependencies: @@ -4191,7 +4195,7 @@ packages: '@typescript-eslint/parser': 6.18.0(eslint@8.56.0)(typescript@5.5.3) eslint: 8.56.0 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.18.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) tslib: 2.6.2 typescript: 5.5.3 transitivePeerDependencies: @@ -6389,7 +6393,7 @@ packages: react-docgen-typescript: 2.2.2(typescript@5.5.3) tslib: 2.6.2 typescript: 5.5.3 - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) transitivePeerDependencies: - supports-color dev: false @@ -7964,8 +7968,8 @@ packages: webpack: 5.x.x webpack-cli: 5.x.x dependencies: - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@5.0.4)(webpack@5.94.0) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.0.4)(webpack@5.94.0) dev: false /@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.94.0): @@ -7975,8 +7979,8 @@ packages: webpack: 5.x.x webpack-cli: 5.x.x dependencies: - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@5.0.4)(webpack@5.94.0) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.0.4)(webpack@5.94.0) dev: false /@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.0.4)(webpack@5.94.0): @@ -7990,8 +7994,8 @@ packages: webpack-dev-server: optional: true dependencies: - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@5.0.4)(webpack@5.94.0) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.0.4)(webpack@5.94.0) webpack-dev-server: 5.0.4(webpack-cli@5.1.4)(webpack@5.94.0) dev: false @@ -8512,7 +8516,7 @@ packages: '@babel/core': 7.25.8 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /babel-plugin-istanbul@6.1.1: @@ -9674,7 +9678,7 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.47) postcss-value-parser: 4.2.0 semver: 7.5.4 - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /css-loader@7.1.2(webpack@5.94.0): @@ -10614,7 +10618,7 @@ packages: enhanced-resolve: 5.17.0 eslint: 8.56.0 eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.15.1 @@ -11611,7 +11615,7 @@ packages: semver: 7.5.4 tapable: 2.2.1 typescript: 5.5.3 - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /form-data@3.0.1: @@ -16885,7 +16889,7 @@ packages: peerDependencies: webpack: ^5.0.0 dependencies: - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /stylelint-config-recommended@14.0.0(stylelint@16.5.0): @@ -17383,7 +17387,7 @@ packages: semver: 7.5.4 source-map: 0.7.4 typescript: 5.5.3 - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /ts-node@10.9.2(@swc/core@1.7.26)(@types/node@16.18.68)(typescript@5.1.6): @@ -18141,7 +18145,7 @@ packages: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /webpack-dev-middleware@7.2.1(webpack@5.94.0): @@ -18159,7 +18163,7 @@ packages: on-finished: 2.4.1 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) dev: false /webpack-dev-middleware@7.4.2(webpack@5.94.0): @@ -18221,8 +18225,8 @@ packages: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@5.0.4)(webpack@5.94.0) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-bundle-analyzer@4.10.2)(webpack-dev-server@5.0.4)(webpack@5.94.0) webpack-dev-middleware: 7.2.1(webpack@5.94.0) ws: 8.17.1 transitivePeerDependencies: @@ -18267,7 +18271,7 @@ packages: webpack: ^5.47.0 dependencies: tapable: 2.2.1 - webpack: 5.94.0(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.18.20)(webpack-cli@5.1.4) webpack-sources: 2.3.1 dev: false patched: true