Last active
November 15, 2017 12:47
-
-
Save dwwoelfel/888404f2666f8d6aad2e4f5bfe5fdc4f to your computer and use it in GitHub Desktop.
OneGraph YouTube Demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const VideoQuery = gql` | |
query videoPlayerQuery { | |
ytVideo(id: $videoId) { | |
id | |
statistics { | |
viewCount | |
likeCount | |
dislikeCount | |
} | |
snippet { | |
title | |
description | |
channelTitle | |
} | |
} | |
}`; | |
class VideoPlayer extends React.Component { | |
render() { | |
if (this.props.data.loading) { | |
return <div style={styles.loading}>Loading...</div>; | |
} | |
const {ytVideo} = this.props.data; | |
if (!ytVideo) { | |
return <div style={styles.error}>Uh oh, something went wrong...</div>; | |
} | |
return ( | |
<div style={styles.container}> | |
<div style={styles.video}> | |
<YouTube videoId={ytVideo.id} opts={styles.video} /> | |
</div> | |
<div style={styles.titleRow}> | |
<div> | |
<div style={styles.title}> | |
{ytVideo.snippet.title} | |
</div> | |
<div style={styles.subTitle}> | |
<div style={styles.author}>{ytVideo.snippet.channelTitle}</div> | |
<div style={styles.viewCount}> | |
{'\u00B7'} {ytVideo.statistics.viewCount.toLocaleString()} views | |
</div> | |
</div> | |
</div> | |
<div style={styles.likeCounts}> | |
<i className="fa fa-thumbs-up" /> | |
{' '} | |
<span style={styles.likeCount}> | |
{formatLikeCount(ytVideo.statistics.likeCount)} | |
</span> | |
<i className="fa fa-thumbs-down" /> | |
{' '} | |
<span style={styles.likeCount}> | |
{formatLikeCount(ytVideo.statistics.dislikeCount)} | |
</span> | |
</div> | |
</div> | |
</div> | |
); | |
} | |
} | |
function formatLikeCount(n) { | |
if (n < 1000) { | |
return n; | |
} | |
if (n < 1000 * 1000) { | |
return `${(n / 1000).toFixed(0)}K`; | |
} else { | |
return `${(n / 1000 / 1000).toFixed(0)}M`; | |
} | |
} | |
class OneYoutubeWrapper extends React.Component { | |
state = {videoId: '6xO87LlijoQ'}; | |
onVideoChange = id => this.setState({videoId: id}); | |
render() { | |
return ( | |
<div> | |
<VideoPlayerWithData | |
videoId={this.state.videoId} | |
onUiStateChange={this.onUiStateChange} | |
onVideoChange={this.onVideoChange} | |
onSearchQueryChange={this.onSearchQueryChange} | |
uiState={this.state.uiState} | |
/> | |
</div> | |
); | |
} | |
} | |
function formatPublishedAt(publishedAt) { | |
return moment(publishedAt).format('MMM DD, YYYY'); | |
} | |
const VideoPlayerWithData = graphql(VideoQuery, { | |
options: ({videoId, uiState, query}) => ({variables: {videoId, q: query}}), | |
})(VideoPlayer); | |
class App extends React.Component { | |
render() { | |
return ( | |
<div className="App"> | |
<ApolloProvider client={OMNI_GRAPHQL_CLIENT}> | |
<OneYoutubeWrapper /> | |
</ApolloProvider>, | |
</div> | |
); | |
} | |
} | |
const styles = { | |
container: { | |
fontFamily: 'Roboto,HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,sans-serif', | |
}, | |
loading: {marginTop: '5em'}, | |
error: {marginTop: '5em'}, | |
video: {width: 375, height: 375 * 9 / 16}, | |
titleRow: { | |
padding: 16, | |
display: 'flex', | |
flexDirection: 'column', | |
}, | |
title: {fontSize: 18, wordWrap: 'break-word', color: '#222'}, | |
subTitle: { | |
fontSize: 14, | |
lineHeight: '18px', | |
marginTop: 6, | |
marginBottom: 6, | |
display: 'flex', | |
flexDirection: 'row', | |
}, | |
viewCount: { | |
paddingLeft: 4, | |
fontSize: 12, | |
lineHeight: '18px', | |
color: '#767676', | |
}, | |
likeCounts: {color: '#767676'}, | |
likeCount: {marginRight: 10, fontSize: 12, color: '#767676'}, | |
}; | |
export default App; | |
// DO NOT DELETE OR MOVE ANYTHING BELOW THIS! | |
const node = document.getElementById('demo'); | |
ReactDOM.render(<App />, node); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment