Skip to content

Commit 00075fc

Browse files
committed
feat: ✨ pull public activities (videos) from contentful
1 parent 1b291f5 commit 00075fc

File tree

3 files changed

+79
-54
lines changed

3 files changed

+79
-54
lines changed

gatsby-node.js

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
const crypto = require('crypto')
21
const axios = require('axios')
32

43
const { YOUTUBE_KEY } = process.env
@@ -10,33 +9,32 @@ let youtube = axios.create({
109
},
1110
})
1211

13-
let videoIds = [
14-
'Im95DcXzTEU',
15-
'WXojma0u_o4',
16-
'QLXWhxd85Lc',
17-
'o2svfxi1Rdg',
18-
'q5EU1R2M574',
19-
]
12+
exports.sourceNodes = async ({ actions: { createNodeField }, getNodes }) => {
13+
let videos = getNodes().filter(
14+
n => n.internal.type === 'ContentfulPublicActivity' && n.type === 'video'
15+
)
16+
17+
let videoMap = videos.reduce((map, video) => {
18+
let [_, id] = video.url.match(/v=(.*)/)
19+
20+
return map.set(id, video)
21+
}, new Map())
22+
23+
let videoIds = Array.from(videoMap.keys())
2024

21-
exports.sourceNodes = async ({ actions: { createNode } }) => {
2225
let {
23-
data: { items: videos },
26+
data: { items: youtubeSnippets },
2427
} = await youtube.get('videos', {
2528
params: { part: 'snippet', id: videoIds.join(',') },
2629
})
2730

28-
videos
29-
.map(video => ({
30-
...video,
31-
parent: null,
32-
children: [],
33-
internal: {
34-
type: 'YouTubeVideo',
35-
contentDigest: crypto
36-
.createHash(`md5`)
37-
.update(JSON.stringify(video))
38-
.digest(`hex`),
39-
},
40-
}))
41-
.forEach(v => createNode(v))
31+
videoMap.forEach((video, id) => {
32+
let snippet = youtubeSnippets.find(s => s.id === id)
33+
34+
createNodeField({
35+
node: video,
36+
name: 'snippet',
37+
value: snippet,
38+
})
39+
})
4240
}

src/components/video-card.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,47 @@ let Img = styled.img`
3131
}
3232
`
3333

34-
let VideoCard = ({ video: { id, snippet }, className }) => {
34+
let unique = arrOfPrimitives => Array.from(new Set(arrOfPrimitives))
35+
36+
let VideoCard = ({
37+
video: {
38+
id,
39+
title,
40+
url,
41+
tags,
42+
snippet: { thumbnails, tags: snippetTags },
43+
},
44+
className,
45+
}) => {
3546
let rotation = useRotation()
36-
let link = `https://www.youtube.com/watch?v=${id}`
37-
let { medium, high, maxres } = snippet.thumbnails
47+
let { medium, high, maxres } = thumbnails
48+
49+
tags = unique([...(tags || []), ...(snippetTags || [])])
3850

3951
return (
4052
<section className={className}>
4153
<VideoLink
4254
{...rotation}
43-
href={link}
55+
href={url}
4456
target="_blank"
4557
rel="noopener noreferrer"
4658
>
4759
<Img
4860
src={medium.url}
4961
srcSet={`${medium.url}, ${high.url} 1.5x, ${maxres.url} 3x`}
50-
alt={snippet.title}
62+
alt={title}
5163
/>
5264

5365
<YouTubePlayButton />
5466
</VideoLink>
5567

5668
<h3 style={scale(0.1)}>
57-
<a href={link}>{snippet.title}</a>
69+
<a href={url}>{title}</a>
5870
</h3>
5971

60-
{snippet.tags && (
72+
{tags.length > 0 && (
6173
<Flex as="ul" flexWrap="wrap" mx="-5px" css={{ listStyle: 'none' }}>
62-
{snippet.tags.map(t => (
74+
{tags.map(t => (
6375
<Box as="li" key={t} m="5px 2px" fontSize="12px">
6476
<Badge>#{t}</Badge>
6577
</Box>

src/pages/public-activity.js

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ import { Box, Flex } from '@rebass/grid'
55
import Layout from '../components/layout'
66
import VideoCard from '../components/video-card'
77

8-
let PublicActivityPage = ({ data: { resp: { videos = [] } = {} } = {} }) => (
8+
let PublicActivityPage = ({
9+
data: { resp: { edges: videos = [] } = {} } = {},
10+
}) => (
911
<Layout>
1012
<h2>Talks</h2>
1113

1214
<Flex as="ul" m={'0 -20px'} flexWrap="wrap" css={{ listStyle: 'none' }}>
1315
{videos
14-
.map(v => v.node)
16+
.map(v => ({
17+
...v.node,
18+
...v.node.fields.snippet,
19+
}))
1520
.map(v => (
1621
<Box as="li" key={v.id} width={[1, 'calc(50% - 20px)']} m={10}>
1722
<VideoCard video={v} />
@@ -23,27 +28,37 @@ let PublicActivityPage = ({ data: { resp: { videos = [] } = {} } = {} }) => (
2328

2429
export let query = graphql`
2530
query PublicActivityQuery {
26-
resp: allYouTubeVideo(
27-
sort: { fields: [snippet___publishedAt], order: DESC }
28-
) {
29-
videos: edges {
31+
resp: allContentfulPublicActivity {
32+
edges {
3033
node {
31-
id
32-
snippet {
33-
title
34-
tags
35-
thumbnails {
36-
medium {
37-
url
38-
width
39-
}
40-
high {
41-
url
42-
width
43-
}
44-
maxres {
45-
url
46-
width
34+
title
35+
url
36+
tags
37+
38+
fields {
39+
snippet {
40+
id
41+
snippet {
42+
publishedAt
43+
title
44+
tags
45+
thumbnails {
46+
medium {
47+
url
48+
width
49+
height
50+
}
51+
high {
52+
url
53+
width
54+
height
55+
}
56+
maxres {
57+
url
58+
width
59+
height
60+
}
61+
}
4762
}
4863
}
4964
}

0 commit comments

Comments
 (0)