Skip to content

Instantly share code, notes, and snippets.

@ChristopherHButler
Created October 18, 2020 21:53
Show Gist options
  • Save ChristopherHButler/d706c0e6f5a4120f81683508bcbcf457 to your computer and use it in GitHub Desktop.
Save ChristopherHButler/d706c0e6f5a4120f81683508bcbcf457 to your computer and use it in GitHub Desktop.
ContrivedTube

ContrivedTube

This Gist was generated by Contrived.

Do not modify the metadata file if you want to open in Contrived again. Otherwise, it is safe to delete.

Happy Hacking!

{"user":"5f0c542a4a2ce5e528e01fdf","templateVersion":"1","templateId":"reactjs","resources":["<meta charset=\"UTF-8\" />","<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">","<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css\" integrity=\"sha512-8bHTC73gkZ7rZ7vpqUQThUDhqcNFyYi2xgDgPDHc+GXVGHXq+xPjynxIopALmOPqzo9JZj0k6OqqewdGO3EsrQ==\" crossorigin=\"anonymous\" />"],"dependencies":[{"name":"react","version":"16.13.1","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"},{"name":"react-dom","version":"16.13.1","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"},{"name":"axios","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/axios/0.20.0/axios.min.js","version":"0.20.0"}],"files":[{"id":1,"parentId":0,"name":"public","type":"folder","isRoot":true,"selected":false,"expanded":false,"children":[{"id":2}]},{"id":2,"parentId":1,"name":"index.html","type":"file","mimeType":"html","isRoot":false,"open":false,"selected":false,"content":"<div id=\"root\"></div>\n"},{"id":3,"parentId":0,"name":"src","type":"folder","isRoot":true,"selected":false,"expanded":false,"children":[{"id":4},{"id":5},{"id":6}]},{"id":4,"parentId":3,"name":"App.js","type":"file","mimeType":"es6","isRoot":false,"open":true,"selected":true,"content":"const { useEffect, useState } = React;\n\nconst API_KEY = 'AIzaSyAFPbefcDTjeCcmNd06VmZfewoHVGJCT1I';\n\nconst api = axios.create({\n\tbaseURL: 'https://www.googleapis.com/youtube/v3',\n\tparams: {\n\t\tpart: 'snippet',\n\t\ttype: 'video',\n\t\tmaxResults: 5,\n\t\tkey: API_KEY,\n\t},\n});\n\nconst SearchBar = ({ onTermSubmit }) => {\n\n\tconst [term, setTerm] = useState('');\n\n\tconst onFormSubmit = (e) => {\n\t\te.preventDefault();\n\t\tonTermSubmit(term);\n\t};\n\n\treturn (\n\t\t<div className=\"search-bar ui segment\">\n\t\t\t<form onSubmit={onFormSubmit} className=\"ui form\">\n\t\t\t <div className=\"field\">\n\t\t\t\t\t<input type=\"text\" placeholder=\"Search\" value={term} onChange={e => setTerm(e.target.value)} />\n\t\t\t\t</div>\n\t\t\t</form>\n\t\t</div>\n\t);\n};\n\nconst VideoDetail = ({ video }) => {\n\n\tif (!video) return <div>Loading...</div>;\n\n\tconst videoSrc = `https://www.youtube.com/embed/${video.id.videoId}`;\n\n\treturn (\n\t\t<div>\n\t\t\t<div className=\"ui embed\">\n\t\t\t\t<iframe title=\"video player\" src={videoSrc} />\n\t\t\t</div>\n\t\t\t<div className=\"ui segment\">\n\t\t\t\t<h4 className=\"ui header\">{video.snippet.title}</h4>\n\t\t\t\t<p>{video.snippet.description}</p>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nconst VideoList = ({ videos, onVideoSelect }) => {\n\n\tconst renderedList = videos.map((video) => {\n\t\treturn <VideoItem key={video.id.videoId} video={video} onVideoSelect={onVideoSelect} />;\n\t});\n\n\treturn (\n\t\t<div className=\"ui relaxed divided list\">\n\t\t\t{renderedList}\n\t\t</div>\n\t);\n};\n\nconst VideoItem = ({ video, onVideoSelect }) => {\n\treturn (\n\t\t<div className=\"video-item item\" onClick={() => onVideoSelect(video)}>\n\t\t\t<img alt={video.snippet.title} className=\"ui image\" src={video.snippet.thumbnails.medium.url} />\n\t\t\t<div className=\"content\">\n\t\t\t\t<div className=\"header\">{video.snippet.title}</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nconst App = () => {\n\n\tconst [videos, setVideos] = useState([]);\n\tconst [selectedVideo, setSelectedVideo] = useState(null);\n\n\tuseEffect(() => {\n\t\tonTermSubmit('vampire weekend harmony hall');\n\t}, []);\n\n\tconst onTermSubmit = async (term) => {\n const response = await api.get(\"/search\", {\n params: {\n q: term,\n part: \"snippet\",\n type: 'video',\n maxResults: 5,\n key: API_KEY,\n }\n });\n\n\t\tsetVideos(response.data.items);\n\t\tsetSelectedVideo(response.data.items[0]);\n };\n\n\tconst onVideoSelect = (video) => setSelectedVideo(video);\n\n\treturn (\n\t\t<div className='App ui container'>\n\t\t\t<h1>ReactTube</h1>\n\t\t\t<SearchBar onTermSubmit={onTermSubmit} />\n\t\t\t<VideoDetail video={selectedVideo} />\n\t\t\t<VideoList videos={videos} onVideoSelect={onVideoSelect} />\n\t\t</div>\n\t);\n};\n\n\nexport default App;"},{"id":5,"parentId":3,"name":"index.js","type":"file","mimeType":"es6","isRoot":false,"isEntry":true,"open":false,"selected":false,"content":"\nimport App from 'App.js';\n\n\nReactDOM.render(<App/>, document.getElementById('root'));\n"},{"id":6,"parentId":3,"name":"styles.css","type":"file","mimeType":"css","isRoot":false,"open":true,"selected":false,"content":".App {\n\tfont-family: sans-serif;\n\ttext-align: center;\n}"}],"experimentId":"5f8cb971ff8bbb5639fa24af"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment