diff --git a/examples/vanilla/favicon/favicon-256x256.png b/examples/vanilla/favicon/favicon-256x256.png new file mode 100644 index 000000000..2f84287e1 Binary files /dev/null and b/examples/vanilla/favicon/favicon-256x256.png differ diff --git a/examples/vanilla/favicon/favicon-32x32.png b/examples/vanilla/favicon/favicon-32x32.png new file mode 100644 index 000000000..1815eecc3 Binary files /dev/null and b/examples/vanilla/favicon/favicon-32x32.png differ diff --git a/examples/vanilla/favicon/favicon-48x48.png b/examples/vanilla/favicon/favicon-48x48.png new file mode 100644 index 000000000..13202ae3a Binary files /dev/null and b/examples/vanilla/favicon/favicon-48x48.png differ diff --git a/examples/vanilla/index.html b/examples/vanilla/index.html index 43a3afc30..4df7ef6ba 100644 --- a/examples/vanilla/index.html +++ b/examples/vanilla/index.html @@ -20,6 +20,7 @@

Getting started

  • Animated icons
  • Understanding <media-controller/> slots
  • State change events demo
  • +
  • Progressive Web Application (PWA)
  • Responsive controls

    diff --git a/examples/vanilla/pwa/index.html b/examples/vanilla/pwa/index.html new file mode 100644 index 000000000..dbafdc5c0 --- /dev/null +++ b/examples/vanilla/pwa/index.html @@ -0,0 +1,111 @@ + + + + + Media Chrome Basic PWA Example + + + + + +
    +

    Media Chrome Basic PWA Example

    + + +
    + + + +
    + + + +
    + + +
    +
    +
    + This is an example Progressive Web App. If you need help on how to + install, see + here. +
    +
    + + diff --git a/examples/vanilla/pwa/pwa-manifest.json b/examples/vanilla/pwa/pwa-manifest.json new file mode 100644 index 000000000..185524b92 --- /dev/null +++ b/examples/vanilla/pwa/pwa-manifest.json @@ -0,0 +1,25 @@ +{ + "name": "Media Chrome", + "short_name": "MediaChrome", + "start_url": ".", + "display": "standalone", + "background_color": "#fff", + "description": "A readable Hacker News app.", + "icons": [ + { + "src": "/examples/vanilla/favicon/favicon-32x32.png", + "sizes": "32x32", + "type": "image/png" + }, + { + "src": "/examples/vanilla/favicon/favicon-48x48.png", + "sizes": "48x48", + "type": "image/png" + }, + { + "src": "/examples/vanilla/favicon/favicon-256x256.png", + "sizes": "256x256", + "type": "image/png" + } + ] + } diff --git a/src/js/utils/platform-tests.js b/src/js/utils/platform-tests.js index ade158e6b..6cccc9da1 100644 --- a/src/js/utils/platform-tests.js +++ b/src/js/utils/platform-tests.js @@ -14,7 +14,7 @@ export const getTestMediaEl = () => { /** * Test for volume support - * + * * @param {HTMLMediaElement} mediaEl * @returns {Promise} */ @@ -32,18 +32,27 @@ export const hasVolumeSupportAsync = async (mediaEl = getTestMediaEl()) => { // return volumeSupported; // }); +// NOTE: This also matches at least some non-Safari UAs on e.g. iOS, such as Chrome, perhaps since +// these browsers are built on top of the OS-level WebKit browser, so use accordingly (CJP). +// See, e.g.: https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome +const isSafari = /.*Version\/.*Safari\/.*/.test(globalThis.navigator.userAgent); /** * Test for PIP support - * + * * @param {HTMLVideoElement} mediaEl * @returns {boolean} */ -export const hasPipSupport = (mediaEl = getTestMediaEl()) => - typeof mediaEl?.requestPictureInPicture === 'function'; +export const hasPipSupport = (mediaEl = getTestMediaEl()) => { + // NOTE: PWAs for Apple that rely on Safari don't support picture in picture but still have `requestPictureInPicture()` + // (which will result in a failed promise). Checking for those conditions here (CJP). + // This should still work for macOS PWAs installed using Chrome, where PiP is supported. + if (globalThis.matchMedia('(display-mode: standalone)').matches && isSafari) return false; + return typeof mediaEl?.requestPictureInPicture === 'function'; +} /** * Test for Fullscreen support - * + * * @param {HTMLVideoElement} mediaEl * @returns {boolean} */ diff --git a/src/js/utils/server-safe-globals.js b/src/js/utils/server-safe-globals.js index 9544852b5..937f4c966 100644 --- a/src/js/utils/server-safe-globals.js +++ b/src/js/utils/server-safe-globals.js @@ -36,7 +36,19 @@ const globalThisShim = { CustomEvent: function CustomEvent() {}, getComputedStyle: function () {}, navigator: { - languages: [] + languages: [], + get userAgent() { + return ''; + } + }, + /** + * @param {string} media + */ + matchMedia(media) { + return { + matches: false, + media, + }; } }; @@ -70,6 +82,7 @@ const isShimmed = Object.keys(globalThisShim) * ResizeObserver?, * CastableVideoElement?, * navigator?, + * matchMedia, * } } * */ export const GlobalThis = isServer && !isShimmed ? globalThisShim : globalThis;