Skip to content

Commit 47689b2

Browse files
committed
magic
0 parents  commit 47689b2

12 files changed

+214
-0
lines changed

Diff for: .gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

Diff for: bun.lockb

39.1 KB
Binary file not shown.

Diff for: index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Random YouTube Player</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.jsx"></script>
12+
</body>
13+
</html>

Diff for: package.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "ytb",
3+
"private": true,
4+
"version": "0.0.0",
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "vite build",
8+
"preview": "vite preview"
9+
},
10+
"dependencies": {
11+
"react": "^17.0.2",
12+
"react-dom": "^17.0.2"
13+
},
14+
"devDependencies": {
15+
"@vitejs/plugin-react": "^1.0.7",
16+
"vite": "^2.8.0"
17+
}
18+
}

Diff for: src/App.css

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
.App {
2+
text-align: center;
3+
min-height: 100vh;
4+
min-width: 100vw;
5+
display: flex;
6+
justify-content: center;
7+
align-items: center;
8+
margin: 0;
9+
}
10+
11+
.video-container {
12+
width: 90vw;
13+
max-width: calc(100vh * (16 / 9));
14+
height: calc(90vw * (9 / 16));
15+
}
16+
17+
iframe {
18+
width: 100%;
19+
height: 100%;
20+
}
21+
22+
button{
23+
border: none;
24+
background-color: transparent;
25+
cursor: pointer;
26+
font-size: 100px;
27+
}

Diff for: src/App.jsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { useState } from 'react'
2+
import logo from './logo.svg'
3+
import './App.css'
4+
import RandomYouTubePlayer from './RandomYouTubePlayer'
5+
6+
function App() {
7+
8+
return (
9+
<div className='App'>
10+
<RandomYouTubePlayer channelId="UC2eYFnH61tmytImy1mTYvhA" apiKey="AIzaSyA1EhVH4I5HWDl-JE73xNUsR6OHZHZt9m8" />
11+
</div>
12+
)
13+
}
14+
15+
export default App

Diff for: src/RandomYouTubePlayer.jsx

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React, { useState, useEffect } from 'react';
2+
import './App.css';
3+
4+
5+
function fetchVideoIds(channelId, apiKey) {
6+
return fetch(`https://www.googleapis.com/youtube/v3/search?key=${apiKey}&channelId=${channelId}&part=snippet,id&order=date&maxResults=20`)
7+
.then(response => response.json())
8+
.then(data => data.items.map(item => item.id.videoId));
9+
}
10+
11+
function getRandomVideoId(videoIds) {
12+
return videoIds[Math.floor(Math.random() * videoIds.length)];
13+
}
14+
15+
function fetchVideoAndGetRandomId(channelId, apiKey) {
16+
return fetchVideoIds(channelId, apiKey)
17+
.then(videoIds => getRandomVideoId(videoIds));
18+
}
19+
20+
function RandomYouTubePlayer({ channelId, apiKey }) {
21+
const [videoId, setVideoId] = useState('');
22+
const [isLoading, setIsLoading] = useState(false);
23+
24+
const handleClick = () => {
25+
setIsLoading(true)
26+
fetchVideoAndGetRandomId(channelId, apiKey)
27+
.then(randomVideoId => {
28+
setVideoId(randomVideoId);
29+
setIsLoading(false)
30+
})
31+
.catch(error => console.error('Error fetching video IDs:', error));
32+
};
33+
34+
useEffect(() => {
35+
// Fetch videos from the channel
36+
setIsLoading(true)
37+
fetchVideoAndGetRandomId(channelId, apiKey)
38+
.then(randomVideoId => {
39+
setVideoId(randomVideoId);
40+
setIsLoading(false)
41+
})
42+
.catch(error => console.error('Error fetching video IDs:', error));
43+
}, [channelId, apiKey]);
44+
45+
if (isLoading) {
46+
return <div>Loading...</div>;
47+
}
48+
49+
return (
50+
<section className='video-container'>
51+
<iframe
52+
title={
53+
'Luke smith'
54+
}
55+
src={`https://www.youtube.com/embed/${videoId}`}
56+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
57+
allowFullScreen
58+
/>
59+
<button onClick={handleClick}>🎲</button>
60+
</section>
61+
);
62+
}
63+
64+
export default RandomYouTubePlayer;

Diff for: src/favicon.svg

+15
Loading

Diff for: src/index.css

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
body {
2+
margin: 0;
3+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4+
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5+
sans-serif;
6+
-webkit-font-smoothing: antialiased;
7+
-moz-osx-font-smoothing: grayscale;
8+
}
9+
10+
code {
11+
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12+
monospace;
13+
}

Diff for: src/logo.svg

+7
Loading

Diff for: src/main.jsx

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react'
2+
import ReactDOM from 'react-dom'
3+
import './index.css'
4+
import App from './App'
5+
6+
ReactDOM.render(
7+
<React.StrictMode>
8+
<App />
9+
</React.StrictMode>,
10+
document.getElementById('root')
11+
)

Diff for: vite.config.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineConfig } from 'vite'
2+
import react from '@vitejs/plugin-react'
3+
4+
// https://vitejs.dev/config/
5+
export default defineConfig({
6+
plugins: [react()]
7+
})

0 commit comments

Comments
 (0)