Skip to content

Commit

Permalink
Merge pull request #359 from tjallingt/canary
Browse files Browse the repository at this point in the history
chore: release
  • Loading branch information
ruisaraiva19 authored May 25, 2022
2 parents 91a6609 + 714e4a9 commit 94e018c
Show file tree
Hide file tree
Showing 14 changed files with 465 additions and 89 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
name: Node.js ${{ matrix.node }}
strategy:
matrix:
node: ['14.x', '16.x', '17.x']
node: ['14.x', '16.x', '17.x', '18.x']
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"husky": "7.0.4",
"lint-staged": "12.3.7",
"prettier": "2.6.2",
"turbo": "1.2.5",
"turbo": "1.2.12",
"typescript": "4.6.3"
},
"lint-staged": {
Expand Down
35 changes: 35 additions & 0 deletions packages/example-ssr/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
17 changes: 17 additions & 0 deletions packages/example-ssr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# react-youtube example ssr

This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
5 changes: 5 additions & 0 deletions packages/example-ssr/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
6 changes: 6 additions & 0 deletions packages/example-ssr/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
};

module.exports = nextConfig;
22 changes: 22 additions & 0 deletions packages/example-ssr/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "react-youtube-example-ssr",
"version": "1.0.0",
"description": "react-youtube example ssr starter project",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "12.1.6",
"react": "18.1.0",
"react-dom": "18.1.0",
"react-youtube": "1.0.0"
},
"devDependencies": {
"@types/node": "17.0.35",
"@types/react": "18.0.9",
"@types/react-dom": "18.0.5",
"typescript": "4.6.3"
}
}
8 changes: 8 additions & 0 deletions packages/example-ssr/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import '../styles/globals.css';
import type { AppProps } from 'next/app';

function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}

export default MyApp;
67 changes: 67 additions & 0 deletions packages/example-ssr/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useState } from 'react';
import YouTube, { YouTubePlayer } from 'react-youtube';
import type { NextPage } from 'next';
import Head from 'next/head';

const VIDEOS = ['XxVg_s8xAms', '-DX3vJiqxm4'];

const Home: NextPage = () => {
const [player, setPlayer] = useState<YouTubePlayer>();
const [videoIndex, setVideoIndex] = useState(0);
const [width, setWidth] = useState(600);
const [hidden, setHidden] = useState(false);
const [autoplay, setAutoplay] = useState(false);

return (
<div id="app">
<Head>
<title>react-youtube example ssr</title>
</Head>
<div style={{ display: 'flex', marginBottom: '1em' }}>
<button type="button" onClick={() => player?.seekTo(120, true)}>
Seek to 2 minutes
</button>
<button type="button" onClick={() => setVideoIndex((videoIndex + 1) % VIDEOS.length)}>
Change video
</button>
<label>
<input
type="range"
min="300"
max="1080"
value={width}
onChange={(event) => setWidth(event.currentTarget.valueAsNumber)}
/>
Width ({width}px)
</label>
<button type="button" onClick={() => setHidden(!hidden)}>
{hidden ? 'Show' : 'Hide'}
</button>
<label>
<input type="checkbox" checked={autoplay} onChange={(event) => setAutoplay(event.currentTarget.checked)} />
Autoplaying
</label>
</div>

{hidden ? (
'mysterious'
) : (
// @ts-ignore
<YouTube
videoId={VIDEOS[videoIndex]}
opts={{
width,
height: width * (9 / 16),
playerVars: {
autoplay: autoplay ? 1 : 0,
},
}}
className="container"
onReady={(event) => setPlayer(event.target)}
/>
)}
</div>
);
};

export default Home;
Binary file added packages/example-ssr/public/favicon.ico
Binary file not shown.
6 changes: 6 additions & 0 deletions packages/example-ssr/styles/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#app {
font-family: sans-serif;
display: flex;
align-items: center;
flex-direction: column;
}
20 changes: 20 additions & 0 deletions packages/example-ssr/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
40 changes: 32 additions & 8 deletions packages/react-youtube/src/YouTube.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,18 @@ class YouTube extends React.Component<YouTubeProps> {
this.internalPlayer = null;
}

/**
* Note: The `youtube-player` package that is used promisifies all YouTube
* Player API calls, which introduces a delay of a tick before it actually
* gets destroyed.
*
* The promise to destroy the player is stored here so we can make sure to
* only re-create the Player after it's been destroyed.
*
* See: https://github.com/tjallingt/react-youtube/issues/355
*/
destroyPlayerPromise: Promise<void> | undefined = undefined;

componentDidMount() {
this.createPlayer();
}
Expand All @@ -243,13 +255,7 @@ class YouTube extends React.Component<YouTubeProps> {
}

componentWillUnmount() {
/**
* Note: The `youtube-player` package that is used promisifies all YouTube
* Player API calls, which introduces a delay of a tick before it actually
* gets destroyed. Since React attempts to remove the element instantly
* this method isn't quick enough to reset the container element.
*/
this.internalPlayer?.destroy();
this.destroyPlayer();
}

/**
Expand Down Expand Up @@ -300,12 +306,30 @@ class YouTube extends React.Component<YouTubeProps> {
*/
onPlayerPlaybackQualityChange = (event: YouTubeEvent<string>) => this.props.onPlaybackQualityChange?.(event);

/**
* Destroy the YouTube Player using its async API and store the promise so we
* can await before re-creating it.
*/
destroyPlayer = () => {
if (this.internalPlayer) {
this.destroyPlayerPromise = this.internalPlayer.destroy().then(() => (this.destroyPlayerPromise = undefined));
return this.destroyPlayerPromise;
}
return Promise.resolve();
};

/**
* Initialize the YouTube Player API on the container and attach event handlers
*/
createPlayer = () => {
// do not attempt to create a player server-side, it won't work
if (typeof document === 'undefined') return;
if (this.destroyPlayerPromise) {
// We need to first await the existing player to be destroyed before
// we can re-create it.
this.destroyPlayerPromise.then(this.createPlayer);
return;
}
// create player
const playerOpts: Options = {
...this.props.opts,
Expand All @@ -330,7 +354,7 @@ class YouTube extends React.Component<YouTubeProps> {
/**
* Shorthand for destroying and then re-creating the YouTube Player
*/
resetPlayer = () => this.internalPlayer?.destroy().then(this.createPlayer);
resetPlayer = () => this.destroyPlayer().then(this.createPlayer);

/**
* Method to update the id and class of the YouTube Player iframe.
Expand Down
Loading

0 comments on commit 94e018c

Please sign in to comment.