Skip to content

Commit f991235

Browse files
author
Carlos Rufo Jimenez
committed
6.4-end-store-v2.1
1 parent fafe92b commit f991235

File tree

5 files changed

+164
-26
lines changed

5 files changed

+164
-26
lines changed

src/components/CreateLink.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { Component } from 'react'
22
import { Mutation } from 'react-apollo'
33
import gql from 'graphql-tag'
4+
import { FEED_QUERY } from './LinkList'
45

56
// 1
67
const POST_MUTATION = gql`
@@ -11,6 +12,16 @@ const POST_MUTATION = gql`
1112
createdAt
1213
url
1314
description
15+
postedBy {
16+
id
17+
name
18+
}
19+
votes {
20+
id
21+
user {
22+
id
23+
}
24+
}
1425
}
1526
}
1627
`
@@ -41,13 +52,30 @@ class CreateLink extends Component {
4152
placeholder="The URL for the link"
4253
/>
4354
</div>
44-
<Mutation mutation={POST_MUTATION} variables={{ description, url }}>
45-
{postMutation => <button onClick={() => postMutation() && this.props.history.push('/')}>Submit</button>}
55+
<Mutation
56+
mutation={POST_MUTATION}
57+
variables={{ description, url }}
58+
update={(cache, { data: { post } }) => {
59+
const data = cache.readQuery({ query: FEED_QUERY })
60+
data.feed.links.splice(0, 0, post)
61+
cache.writeQuery({
62+
query: FEED_QUERY,
63+
data,
64+
})
65+
}}
66+
>
67+
{postMutation => (
68+
<button
69+
onClick={() => postMutation() && this.props.history.push('/')}
70+
>
71+
Submit
72+
</button>
73+
)}
4674
</Mutation>
4775
</div>
4876
)
4977
}
5078
}
5179

5280
// 3
53-
export default CreateLink;
81+
export default CreateLink

src/components/Link.js

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,72 @@
11
import React, { Component } from 'react'
2+
import { AUTH_TOKEN } from '../constants'
3+
import { timeDifferenceForDate } from '../utils'
4+
import { Mutation } from 'react-apollo'
5+
import gql from 'graphql-tag'
6+
import { FEED_QUERY } from './LinkList'
7+
8+
const VOTE_MUTATION = gql`
9+
mutation VoteMutation($linkId: ID!) {
10+
vote(linkId: $linkId) {
11+
id
12+
link {
13+
votes {
14+
id
15+
user {
16+
id
17+
}
18+
}
19+
}
20+
user {
21+
id
22+
}
23+
}
24+
}
25+
`
226

327
class Link extends Component {
428
render() {
29+
const authToken = localStorage.getItem(AUTH_TOKEN)
30+
const { link: { id: linkId } } = this.props
531
return (
6-
<div>
7-
<div>
8-
{this.props.link.description} ({this.props.link.url})
32+
<div className="flex mt2 items-start">
33+
<div className="flex items-center">
34+
<span className="gray">{this.props.index + 1}.</span>
35+
{authToken && (
36+
<Mutation
37+
mutation={VOTE_MUTATION}
38+
variables={{ linkId }}
39+
update={(cache, { data: { vote: createVote } }) => {
40+
// 1
41+
const data = cache.readQuery({ query: FEED_QUERY })
42+
// 2
43+
const votedLink = data.feed.links.find(
44+
link => link.id === linkId
45+
)
46+
votedLink.votes = createVote.link.votes
47+
// 3
48+
cache.writeQuery({ query: FEED_QUERY, data })
49+
}}
50+
>
51+
{voteMutation => (
52+
<div className="ml1 gray f11" onClick={voteMutation}>
53+
54+
</div>
55+
)}
56+
</Mutation>
57+
)}
58+
</div>
59+
<div className="ml1">
60+
<div>
61+
{this.props.link.description} ({this.props.link.url})
62+
</div>
63+
<div className="f6 lh-copy gray">
64+
{this.props.link.votes.length} votes | by{' '}
65+
{this.props.link.postedBy
66+
? this.props.link.postedBy.name
67+
: 'Unknown'}{' '}
68+
{timeDifferenceForDate(this.props.link.createdAt)}
69+
</div>
970
</div>
1071
</div>
1172
)
@@ -16,4 +77,4 @@ class Link extends Component {
1677
}
1778
}
1879

19-
export default Link
80+
export default Link

src/components/LinkList.js

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Query } from 'react-apollo'
44
import gql from 'graphql-tag'
55

66
// 1
7-
const FEED_QUERY = gql`
7+
export const FEED_QUERY = gql`
88
# 2
99
query FeedQuery {
1010
feed {
@@ -13,27 +13,43 @@ const FEED_QUERY = gql`
1313
createdAt
1414
url
1515
description
16+
postedBy {
17+
id
18+
name
19+
}
20+
votes {
21+
id
22+
user {
23+
id
24+
}
25+
}
1626
}
1727
}
1828
}
19-
`;
29+
`
2030

2131
class LinkList extends Component {
22-
render() {
23-
return (
24-
<Query query={FEED_QUERY}>
25-
{(result) => {
26-
if (result.loading) return <div>Loading</div>;
27-
if (result.error) return <div>Error</div>;
28-
29-
const { data } = result;
30-
const linksToRender = data.feed.links;
31-
32-
return <div>{linksToRender.map(link => <Link key={link.id} link={link} />)}</div>;
33-
}}
34-
</Query>
35-
)
36-
}
32+
render() {
33+
return (
34+
<Query query={FEED_QUERY}>
35+
{result => {
36+
if (result.loading) return <div>Loading</div>
37+
if (result.error) return <div>Error</div>
38+
39+
const { data } = result
40+
const linksToRender = data.feed.links
41+
42+
return (
43+
<div>
44+
{linksToRender.map((link, index) => (
45+
<Link key={link.id} index={index} link={link} />
46+
))}
47+
</div>
48+
)
49+
}}
50+
</Query>
51+
)
52+
}
3753
}
3854

39-
export default LinkList;
55+
export default LinkList

src/components/Login.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { Component } from 'react'
22
import { AUTH_TOKEN } from '../constants'
3-
import { compose, Mutation } from 'react-apollo'
3+
import { Mutation } from 'react-apollo'
44
import gql from 'graphql-tag'
55

66
const SIGNUP_MUTATION = gql`

src/utils.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
function timeDifference(current, previous) {
2+
const milliSecondsPerMinute = 60 * 1000
3+
const milliSecondsPerHour = milliSecondsPerMinute * 60
4+
const milliSecondsPerDay = milliSecondsPerHour * 24
5+
const milliSecondsPerMonth = milliSecondsPerDay * 30
6+
const milliSecondsPerYear = milliSecondsPerDay * 365
7+
8+
const elapsed = current - previous
9+
10+
if (elapsed < milliSecondsPerMinute / 3) {
11+
return 'just now'
12+
}
13+
14+
if (elapsed < milliSecondsPerMinute) {
15+
return 'less than 1 min ago'
16+
} else if (elapsed < milliSecondsPerHour) {
17+
return Math.round(elapsed / milliSecondsPerMinute) + ' min ago'
18+
} else if (elapsed < milliSecondsPerDay) {
19+
return Math.round(elapsed / milliSecondsPerHour) + ' h ago'
20+
} else if (elapsed < milliSecondsPerMonth) {
21+
return Math.round(elapsed / milliSecondsPerDay) + ' days ago'
22+
} else if (elapsed < milliSecondsPerYear) {
23+
return Math.round(elapsed / milliSecondsPerMonth) + ' mo ago'
24+
} else {
25+
return Math.round(elapsed / milliSecondsPerYear) + ' years ago'
26+
}
27+
}
28+
29+
export function timeDifferenceForDate(date) {
30+
const now = new Date().getTime()
31+
const updated = new Date(date).getTime()
32+
return timeDifference(now, updated)
33+
}

0 commit comments

Comments
 (0)