Skip to content

Commit cee2301

Browse files
committed
Working graphql likes API
1 parent a0eab01 commit cee2301

16 files changed

+1176
-377
lines changed

api_handler.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const fs = require('fs');
2+
const { ApolloServer } = require('apollo-server-express');
3+
const videos = require('./videos.js')
4+
const likes = require('./likes.js')
5+
6+
const resolvers = {
7+
Query: {
8+
indexVideos: videos.indexVideos
9+
},
10+
Mutation: {
11+
addLike: likes.addLike,
12+
removeLike: likes.removeLike
13+
}
14+
}
15+
16+
const server = new ApolloServer({
17+
typeDefs: fs.readFileSync('./schema.graphql', 'utf-8'),
18+
resolvers
19+
});
20+
21+
async function installHandler(app){
22+
await server.start();
23+
server.applyMiddleware({ app, path: '/graphql' });
24+
}
25+
26+
module.exports = { installHandler }

js/components/AccountProfile.jsx

+50-10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { faSignOutAlt, faStar, faTrash, faTimes, faLongArrowAltRight } from '@fo
55
import { faStar as farStar } from '@fortawesome/free-regular-svg-icons';
66
import Slider from 'react-slick';
77
import ReadMore from '@jamespotz/react-simple-readmore';
8+
import graphQLFetch from './graphQLFetch.js';
89

910
class AccountProfile extends React.Component {
1011
constructor(props){
@@ -51,13 +52,33 @@ class AccountProfile extends React.Component {
5152
}
5253

5354
async sendLike(video, videoList, videoListType){
54-
const newLikedVideo = await fetch(`${document.location.origin}/sendLike/${video._id}`)
55-
.then(res => res.json())
56-
.catch(error => console.log(error));
57-
if(newLikedVideo.message){
58-
// Display error message if included in response
59-
alert(newLikedVideo.message);
60-
} else if(newLikedVideo) {
55+
if(!this.state.user._id){
56+
alert('Must be signed in to send like.');
57+
return;
58+
}
59+
const query = `mutation addLike($userID: ID!, $videoID: ID!){
60+
addLike(userID: $userID, videoID: $videoID){
61+
_id
62+
title
63+
src
64+
originalName
65+
thumbnailSrc
66+
originalThumbnailName
67+
created
68+
likes
69+
uploadedBy {
70+
_id
71+
displayName
72+
}
73+
}
74+
}`;
75+
const data = await graphQLFetch(query, {
76+
userID: this.state.user._id,
77+
videoID: video._id
78+
});
79+
const newLikedVideo = data.addLike;
80+
81+
if(newLikedVideo) {
6182
// Update the video state to be liked by the current user.
6283
newLikedVideo.likedByCurrentUser = true;
6384
let updatedUser = this.state.user;
@@ -91,9 +112,28 @@ class AccountProfile extends React.Component {
91112
}
92113

93114
async removeLike(video, videoList, videoListType){
94-
const newUnlikedVideo = await fetch(`${document.location.origin}/removeLike/${video._id}`)
95-
.then(res => res.json())
96-
.catch(error => console.log(error));
115+
const query = `mutation removeLike($userID: ID!, $videoID: ID!){
116+
removeLike(userID: $userID, videoID: $videoID){
117+
_id
118+
title
119+
src
120+
originalName
121+
thumbnailSrc
122+
originalThumbnailName
123+
created
124+
likes
125+
uploadedBy {
126+
_id
127+
displayName
128+
}
129+
}
130+
}`;
131+
const data = await graphQLFetch(query, {
132+
userID: this.state.user._id,
133+
videoID: video._id
134+
});
135+
const newUnlikedVideo = data.removeLike;
136+
97137
if(newUnlikedVideo.message){
98138
// Display error message if included in response
99139
alert(newUnlikedVideo.message);

js/components/Home.jsx

+50-10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Navigation from './Navigation.jsx';
99
import VideoSearchForm from './VideoSearchForm.tsx';
1010
import ReadMore from '@jamespotz/react-simple-readmore';
1111
import VideoPlayer from './VideoPlayer.tsx';
12+
import graphQLFetch from './graphQLFetch.js';
1213

1314
// Enable lazy loading
1415
const lozadObserver = lozad();
@@ -63,13 +64,33 @@ class Home extends React.Component {
6364
}
6465

6566
async sendLike(video){
66-
const newLikedVideo = await fetch(`${document.location.origin}/sendLike/${video._id}`)
67-
.then(res => res.json())
68-
.catch(error => console.log(error));
69-
if(newLikedVideo.message){
70-
// Display error message if included in response
71-
alert(newLikedVideo.message);
72-
} else if(newLikedVideo) {
67+
if(!this.props.userID){
68+
alert('Must be signed in to send like.');
69+
return;
70+
}
71+
const query = `mutation addLike($userID: ID!, $videoID: ID!){
72+
addLike(userID: $userID, videoID: $videoID){
73+
_id
74+
title
75+
src
76+
originalName
77+
thumbnailSrc
78+
originalThumbnailName
79+
created
80+
likes
81+
uploadedBy {
82+
_id
83+
displayName
84+
}
85+
}
86+
}`;
87+
const data = await graphQLFetch(query, {
88+
userID: this.props.userID,
89+
videoID: video._id
90+
});
91+
const newLikedVideo = data.addLike;
92+
93+
if(newLikedVideo) {
7394
// Update the video state to be liked by the current user. Used immediately after liking.
7495
newLikedVideo.likedByCurrentUser = true;
7596
let newVideos = this.state.recentVideos;
@@ -85,9 +106,28 @@ class Home extends React.Component {
85106
}
86107

87108
async removeLike(video){
88-
const newUnlikedVideo = await fetch(`${document.location.origin}/removeLike/${video._id}`)
89-
.then(res => res.json())
90-
.catch(error => console.log(error));
109+
const query = `mutation removeLike($userID: ID!, $videoID: ID!){
110+
removeLike(userID: $userID, videoID: $videoID){
111+
_id
112+
title
113+
src
114+
originalName
115+
thumbnailSrc
116+
originalThumbnailName
117+
created
118+
likes
119+
uploadedBy {
120+
_id
121+
displayName
122+
}
123+
}
124+
}`;
125+
const data = await graphQLFetch(query, {
126+
userID: this.props.userID,
127+
videoID: video._id
128+
});
129+
const newUnlikedVideo = data.removeLike;
130+
91131
if(newUnlikedVideo.message){
92132
// Display error message if included in response
93133
alert(newUnlikedVideo.message);

js/components/VideosIndex.jsx

+50-10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Navigation from './Navigation.jsx';
77
import VideoSearchForm from './VideoSearchForm.tsx';
88
import Slider from 'react-slick';
99
import ReadMore from '@jamespotz/react-simple-readmore';
10+
import graphQLFetch from './graphQLFetch.js';
1011

1112
async function getVideos(){
1213
var urlParams = new URLSearchParams(window.location.search);
@@ -90,9 +91,28 @@ class VideosIndex extends React.Component {
9091
}
9192

9293
async sendLike(video){
93-
const newLikedVideo = await fetch(`${document.location.origin}/sendLike/${video._id}`)
94-
.then(res => res.json())
95-
.catch(error => console.log(error));
94+
const query = `mutation addLike($userID: ID!, $videoID: ID!){
95+
addLike(userID: $userID, videoID: $videoID){
96+
_id
97+
title
98+
src
99+
originalName
100+
thumbnailSrc
101+
originalThumbnailName
102+
created
103+
likes
104+
uploadedBy {
105+
_id
106+
displayName
107+
}
108+
}
109+
}`;
110+
const data = await graphQLFetch(query, {
111+
userID: this.props.userID,
112+
videoID: video._id
113+
});
114+
const newLikedVideo = data.addLike;
115+
96116
if(newLikedVideo.message){
97117
// Display error message if included in response
98118
alert(newLikedVideo.message);
@@ -112,13 +132,33 @@ class VideosIndex extends React.Component {
112132
}
113133

114134
async removeLike(video){
115-
const newUnlikedVideo = await fetch(`${document.location.origin}/removeLike/${video._id}`)
116-
.then(res => res.json())
117-
.catch(error => console.log(error));
118-
if(newUnlikedVideo.message){
119-
// Display error message if included in response
120-
alert(newUnlikedVideo.message);
121-
} else if(newUnlikedVideo) {
135+
if(!this.props.userID){
136+
alert('Must be signed in to send like.');
137+
return;
138+
}
139+
const query = `mutation removeLike($userID: ID!, $videoID: ID!){
140+
removeLike(userID: $userID, videoID: $videoID){
141+
_id
142+
title
143+
src
144+
originalName
145+
thumbnailSrc
146+
originalThumbnailName
147+
created
148+
likes
149+
uploadedBy {
150+
_id
151+
displayName
152+
}
153+
}
154+
}`;
155+
const data = await graphQLFetch(query, {
156+
userID: this.props.userID,
157+
videoID: video._id
158+
});
159+
const newUnlikedVideo = data.removeLike;
160+
161+
if(newUnlikedVideo) {
122162
// Update the video state to remove like from the current user. Used immediately after unliking.
123163
newUnlikedVideo.likedByCurrentUser = false;
124164
let newVideos = this.state.videos;

js/components/graphQLFetch.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export default async function graphQLFetch(query, variables = {}){
2+
const response = await fetch('/graphql', {
3+
method: 'POST',
4+
headers: { 'Content-Type': 'application/json' },
5+
body: JSON.stringify({ query, variables })
6+
});
7+
const body = await response.text();
8+
const result = JSON.parse(body);
9+
return result.data;
10+
}

js/main.jsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ import 'css-modal/build/modal.css';
1414

1515
if(document.getElementById('home')){
1616
var userLikedVideos = document.getElementById('home').getAttribute('data-userLikedVideos');
17-
ReactDOM.render(<Home userLikedVideos={userLikedVideos}/>, document.getElementById('home'));
17+
var userID = document.getElementById('home').getAttribute('data-userID');
18+
ReactDOM.render(<Home userLikedVideos={userLikedVideos} userID={userID}/>, document.getElementById('home'));
1819
}
1920
if(document.getElementById('videos')){
2021
var userLikedVideos = document.getElementById('videos').getAttribute('data-userLikedVideos');
21-
ReactDOM.render(<VideosIndex userLikedVideos={userLikedVideos}/>, document.getElementById('videos'));
22+
var userID = document.getElementById('videos').getAttribute('data-userID');
23+
ReactDOM.render(<VideosIndex userLikedVideos={userLikedVideos} userID={userID}/>, document.getElementById('videos'));
2224
}
2325
if(document.getElementById('videos-add')){
2426
ReactDOM.render(<VideosAdd/>, document.getElementById('videos-add'));

likes.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const { getDB } = require('./db.js');
22
const mongo = require('mongodb');
33

4-
async function addLike(userID, videoID){
4+
async function addLike(_, { userID, videoID }){
55
const db = getDB();
66

77
let user = await db.collection('users').findOne({ _id: new mongo.ObjectID(userID) });
@@ -29,7 +29,7 @@ async function addLike(userID, videoID){
2929
return false;
3030
}
3131

32-
async function removeLike(userID, videoID){
32+
async function removeLike(_, { userID, videoID }){
3333
const db = getDB();
3434

3535
let user = await db.collection('users').findOne({ _id: new mongo.ObjectID(userID) });

0 commit comments

Comments
 (0)