Skip to content

Commit

Permalink
chore: Prepare default theme from Mux Player for export (#668)
Browse files Browse the repository at this point in the history
The goal of this PR is to package the existing default theme such that
it can be exported as it's own module. This can then be easily swapped
out in the future with a new theme.

Theme source files now reside in `src/themes` (themes based in this repo
and re-exported from media chrome). Build artefacts for themes are in
`dist/themes`.

---------

Co-authored-by: Gary Katsevman <[email protected]>
Co-authored-by: Christian Pillsbury <[email protected]>
  • Loading branch information
3 people authored Aug 1, 2023
1 parent 2197108 commit c6a3434
Show file tree
Hide file tree
Showing 13 changed files with 141 additions and 17 deletions.
1 change: 1 addition & 0 deletions examples/svelte-kit/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
<li><a data-sveltekit-prefetch href="./mux-video" class="video">&lt;mux-video&gt;</a></li>
<li><a data-sveltekit-prefetch href="./mux-audio" class="audio">&lt;mux-audio&gt;</a></li>
<li><a data-sveltekit-prefetch href="./mux-player" class="player">&lt;mux-player&gt;</a></li>
<li><a data-sveltekit-prefetch href="./mux-player-theme" class="player">&lt;mux-player&gt; (theme)</a></li>
</ul>
</nav>
44 changes: 44 additions & 0 deletions examples/svelte-kit/src/routes/mux-player-theme/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<script context="module" lang="ts">
export const prerender = true;
</script>

<script lang="ts">
// this prevents the custom elements from being redefined when the REPL is updated and reloads, which throws an error
// this means that any changes to the custom element won't be picked up without saving and refreshing the REPL
// const oldRegister = customElements.define;
// customElements.define = function(name, constructor, options) {
// if (!customElements.get(name)) {
// oldRegister(name, constructor, options);
// }
// }
// import { page } from '$app/stores';
import { onMount } from 'svelte';
onMount(async () => {
await import('@mux/mux-player');
await import("@mux/mux-player/themes/microvideo");
});
</script>

<svelte:head>
<style>
mux-player {
display: block;
width: 100%;
margin: 1rem 0 2rem;
background-color: #000;
line-height: 0;
}
mux-player:not([audio]) {
aspect-ratio: 16 / 9;
}
</style>
</svelte:head>

<mux-player
stream-type="on-demand"
playback-id="23s11nz72DsoN657h4314PjKKjsF2JG33eBQQt6B95I"
theme="microvideo"
></mux-player>

<a data-sveltekit-prefetch href="/">Browse Elements</a>
2 changes: 1 addition & 1 deletion examples/vanilla-ts-esm/public/mux-player-theme.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
defer
src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"
></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/media-chrome/dist/themes/microvideo.js/+esm"></script>
<script type="module" src="./dist/mux-player-microvideo-theme.js"></script>
<script type="module" src="./dist/mux-player.js"></script>
<style>
mux-player {
Expand Down
1 change: 1 addition & 0 deletions examples/vanilla-ts-esm/src/mux-player-microvideo-theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * as MicroVideoTheme from "@mux/mux-player/themes/microvideo";
2 changes: 2 additions & 0 deletions packages/mux-player/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
themes/
!src/themes/
27 changes: 23 additions & 4 deletions packages/mux-player/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,24 @@
"types@<4.3.5": "./dist/types-ts3.4/index.d.ts",
"types": "./dist/types/index.d.ts"
},
"./themes/microvideo": "./themes/microvideo.js",
"./themes/minimal": "./themes/minimal.js"
"./themes/microvideo": {
"import": "./dist/themes/microvideo/index.mjs",
"require": "./dist/themes/microvideo/index.cjs.js",
"browser": "./dist/themes/microvideo/index.mjs",
"default": "./dist/themes/microvideo/index.cjs.js"
},
"./themes/minimal": {
"import": "./dist/themes/minimal/index.mjs",
"require": "./dist/themes/minimal/index.cjs.js",
"browser": "./dist/themes/minimal/index.mjs",
"default": "./dist/themes/minimal/index.cjs.js"
},
"./themes/classic": {
"import": "./dist/themes/classic/index.mjs",
"require": "./dist/themes/classic/index.cjs.js",
"browser": "./dist/themes/classic/index.mjs",
"default": "./dist/themes/classic/index.cjs.js"
}
},
"types": "./dist/types/index.d.ts",
"repository": {
Expand All @@ -50,15 +66,17 @@
"dev:esm-module": "yarn build:esm-module --watch=forever",
"dev:cjs": "yarn build:cjs --watch=forever",
"dev:types": "yarn build:types -w",
"dev": "npm-run-all --parallel dev:types dev:esm dev:cjs dev:esm-module dev:iife",
"dev:themes": "yarn node ./scripts/build-themes.mjs --dev",
"dev": "npm-run-all --parallel dev:types dev:esm dev:cjs dev:esm-module dev:iife dev:themes",
"build:esm": "esbuilder src/index.ts --format=esm --out-extension:.js=.mjs",
"build:esm-module": "esbuilder src/index.ts --format=esm-module --outfile=dist/mux-player.mjs",
"build:iife": "esbuilder src/index.ts --format=iife --outfile=dist/mux-player.js",
"build:cjs": "esbuilder src/index.ts --format=cjs --out-extension:.js=.cjs.js",
"build:themes": "yarn node ./scripts/build-themes.mjs",
"copypolyfills": "shx mkdir -p src/polyfills && shx cp ../../shared/polyfills/index.ts ./src/polyfills/index.ts",
"build:types": "tsc",
"postbuild:types": "downlevel-dts ./dist/types ./dist/types-ts3.4",
"build": "npm-run-all --parallel 'build:esm --minify' 'build:iife --minify' 'build:cjs --minify' 'build:esm-module --minify'",
"build": "npm-run-all --parallel 'build:esm --minify' 'build:iife --minify' 'build:cjs --minify' 'build:esm-module --minify' 'build:themes'",
"create-release-notes": "create-release-notes ./CHANGELOG.md",
"publish-release": "../../scripts/publish.sh"
},
Expand All @@ -78,6 +96,7 @@
"@web/test-runner": "^0.13.26",
"@web/test-runner-playwright": "^0.9.0",
"downlevel-dts": "^0.11.0",
"esbuild": "^0.15.7",
"eslint": "^8.24.0",
"npm-run-all": "^4.1.5",
"replace": "^1.2.1",
Expand Down
46 changes: 46 additions & 0 deletions packages/mux-player/scripts/build-themes.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env node
import { build } from 'esbuild';

const themes = ['classic', 'microvideo', 'minimal'];
const devMode = process.argv.includes('--dev');

const shared = {
bundle: true,
target: 'es2019',
loader: {
'.html': 'text',
'.css': 'text',
'.svg': 'text',
},
watch: devMode,
};

// entryPoints doesn't support glob patterns so we iterate over known themes
themes.forEach((theme) => {
//@ts-ignore
build({
...shared,
entryPoints: [`./src/themes/${theme}/index.ts`],
format: 'esm',
outExtension: { '.js': '.mjs' },
outdir: `./dist/themes/${theme}`,
});

//@ts-ignore
build({
...shared,
entryPoints: [`./src/themes/${theme}/index.ts`],
format: 'cjs',
outExtension: { '.js': '.cjs.js' },
outdir: `./dist/themes/${theme}`,
});

//@ts-ignore
build({
...shared,
entryPoints: [`./src/themes/${theme}/index.ts`],
format: 'iife',
globalName: `mediaTheme${theme[0].toUpperCase() + theme.slice(1)}`,
outdir: `./dist/themes/${theme}`,
});
});
6 changes: 4 additions & 2 deletions packages/mux-player/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { getErrorLogs } from './errors';
import { toNumberOrUndefined, i18n, parseJwt, containsComposedNode, camelCase, kebabCase } from './utils';
import * as logger from './logger';
import type { MuxTemplateProps, ErrorEvent } from './types';
import './themes/classic';

export { MediaError };
export type Tokens = {
Expand Down Expand Up @@ -147,7 +148,8 @@ function getProps(el: MuxPlayerElement, state?: any): MuxTemplateProps {
}

function getThemeTemplate(el: MuxPlayerElement) {
let themeName = el.getAttribute(PlayerAttributes.THEME);
let themeName = el.theme;

if (themeName) {
// @ts-ignore
const templateElement = el.getRootNode()?.getElementById?.(themeName);
Expand Down Expand Up @@ -712,7 +714,7 @@ class MuxPlayerElement extends VideoApiElement implements MuxPlayerElement {
* Gets the theme.
*/
get theme() {
return this.getAttribute(PlayerAttributes.THEME) ?? '';
return this.getAttribute(PlayerAttributes.THEME) ?? 'classic';
}

/**
Expand Down
10 changes: 1 addition & 9 deletions packages/mux-player/src/template.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
import { document } from './polyfills';
import 'media-chrome/dist/media-theme-element.js';
// @ts-ignore
import cssStr from './styles.css';
// @ts-ignore
import muxTheme from './media-theme-mux.html';
import './dialog';
import { getSrcFromPlaybackId, getStreamTypeFromAttr } from './helpers';
import { html } from './html';
import { i18n, stylePropsToString } from './utils';

import type { MuxTemplateProps } from './types';
import { StreamTypes } from '@mux/playback-core';

const muxTemplate = document.createElement('template');
if ('innerHTML' in muxTemplate) muxTemplate.innerHTML = muxTheme;

// prettier-ignore
export const template = (props: MuxTemplateProps) => html`
<style>
${cssStr}
Expand All @@ -37,7 +29,7 @@ const getHotKeys = (props: MuxTemplateProps) => {

export const content = (props: MuxTemplateProps) => html`
<media-theme
template="${props.themeTemplate ?? muxTemplate.content.children[0]}"
template="${props.themeTemplate || false}"
defaultstreamtype="${props.defaultStreamType ?? false}"
hotkeys="${getHotKeys(props) || false}"
nohotkeys="${props.noHotKeys || !props.hasSrc || props.isDialogOpen || false}"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- prettier-ignore -->
<template id="media-theme-mux">
<template id="media-theme-classic">
<style>
:host {
--_primary-color: var(--media-primary-color, white);
Expand Down
17 changes: 17 additions & 0 deletions packages/mux-player/src/themes/classic/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @ts-ignore
import theme from './classic.html';
import { document, globalThis } from '../../polyfills';
import { MediaThemeElement } from 'media-chrome/dist/media-theme-element.js';

const template = document.createElement('template');
if ('innerHTML' in template) template.innerHTML = theme;

class MediaThemeClassic extends MediaThemeElement {
static template = template.content?.children?.[0];
}

if (!globalThis.customElements.get('media-theme-classic')) {
globalThis.customElements.define('media-theme-classic', MediaThemeClassic);
}

export default MediaThemeClassic;
File renamed without changes.
File renamed without changes.

5 comments on commit c6a3434

@vercel
Copy link

@vercel vercel bot commented on c6a3434 Aug 1, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

elements-demo-create-react-app – ./examples/create-react-app-with-typescript

elements-demo-create-react-app.vercel.app
elements-demo-create-react-app-mux.vercel.app
elements-demo-create-react-app-git-main-mux.vercel.app

@vercel
Copy link

@vercel vercel bot commented on c6a3434 Aug 1, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

elements-demo-svelte-kit – ./examples/svelte-kit

elements-demo-svelte-kit-git-main-mux.vercel.app
elements-demo-svelte-kit-mux.vercel.app
elements-demo-svelte-kit.vercel.app

@vercel
Copy link

@vercel vercel bot commented on c6a3434 Aug 1, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

elements-demo-vue – ./examples/vue-with-typescript

elements-demo-vue-git-main-mux.vercel.app
elements-demo-vue-mux.vercel.app
elements-demo-vue.vercel.app

@vercel
Copy link

@vercel vercel bot commented on c6a3434 Aug 1, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

elements-demo-nextjs – ./examples/nextjs-with-typescript

elements-demo-nextjs.vercel.app
elements-demo-nextjs-git-main-mux.vercel.app
elements-demo-nextjs-mux.vercel.app

@vercel
Copy link

@vercel vercel bot commented on c6a3434 Aug 1, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

elements-demo-vanilla – ./examples/vanilla-ts-esm

elements-demo-vanilla.vercel.app
elements-demo-vanilla-git-main-mux.vercel.app
elements-demo-vanilla-mux.vercel.app

Please sign in to comment.