11import React from 'react' ;
2- import { graphql , withApollo } from 'react-apollo' ;
3- import ApolloClient from 'apollo-client' ;
2+ import { graphql } from 'react-apollo' ;
43import gql from 'graphql-tag' ;
54import update from 'react-addons-update' ;
65
@@ -15,33 +14,55 @@ function isDuplicateComment(newComment, existingComments) {
1514 return newComment . id !== null && existingComments . some ( comment => newComment . id === comment . id ) ;
1615}
1716
17+ const SUBSCRIPTION_QUERY = gql `
18+ subscription onCommentAdded($repoFullName: String!){
19+ commentAdded(repoFullName: $repoFullName){
20+ id
21+ postedBy {
22+ login
23+ html_url
24+ }
25+ createdAt
26+ content
27+ }
28+ }
29+ ` ;
30+
1831class CommentsPage extends React . Component {
1932 constructor ( props ) {
2033 super ( props ) ;
2134 this . state = { noCommentContent : false } ;
2235 this . submitForm = this . submitForm . bind ( this ) ;
23- this . subscriptionObserver = null ;
24- this . subscriptionRepoName = null ;
25- }
2636
27- componentDidMount ( ) {
28- if ( this . props . loading === false ) {
29- this . subscribe ( this . props . entry . repository . full_name , this . props . updateCommentsQuery ) ;
30- }
37+ // keep track of subscription handle to not subscribe twice.
38+ // we don't need to unsubscribe on unmount, because the subscription
39+ // gets stopped when the query stops.
40+ this . subscription = null ;
3141 }
3242
3343 componentWillReceiveProps ( nextProps ) {
34- if ( this . subscriptionRepoName !== nextProps . entry . repository . full_name ) {
35- if ( this . subscriptionObserver ) {
36- this . subscriptionObserver . unsubscribe ( ) ;
37- }
38- this . subscribe ( nextProps . entry . repository . full_name , nextProps . updateCommentsQuery ) ;
39- }
40- }
41-
42- componentWillUnmount ( ) {
43- if ( this . subscriptionObserver ) {
44- this . subscriptionObserver . unsubscribe ( ) ;
44+ // we don't resubscribe on changed props, because it never happens in our app
45+ if ( ! this . subscription && ! nextProps . loading ) {
46+ this . subscription = this . props . subscribeToMore ( {
47+ document : SUBSCRIPTION_QUERY ,
48+ variables : { repoFullName : nextProps . entry . repository . full_name } ,
49+ updateQuery : ( previousResult , { subscriptionData } ) => {
50+ const newComment = subscriptionData . data . commentAdded ;
51+ // if it's our own mutation, we might get the subscription result
52+ // after the mutation result.
53+ if ( isDuplicateComment ( newComment , previousResult . entry . comments ) ) {
54+ return previousResult ;
55+ }
56+ const newResult = update ( previousResult , {
57+ entry : {
58+ comments : {
59+ $unshift : [ newComment ] ,
60+ } ,
61+ } ,
62+ } ) ;
63+ return newResult ;
64+ } ,
65+ } ) ;
4566 }
4667 }
4768
@@ -69,51 +90,6 @@ class CommentsPage extends React.Component {
6990 }
7091 }
7192
72- subscribe ( repoName , updateCommentsQuery ) {
73- const SUBSCRIPTION_QUERY = gql `
74- subscription onCommentAdded($repoFullName: String!){
75- commentAdded(repoFullName: $repoFullName){
76- id
77- postedBy {
78- login
79- html_url
80- }
81- createdAt
82- content
83- }
84- }
85- ` ;
86- this . subscriptionRepoName = repoName ;
87- this . subscriptionObserver = this . props . client . subscribe ( {
88- query : SUBSCRIPTION_QUERY ,
89- variables : { repoFullName : repoName } ,
90- } ) . subscribe ( {
91- next ( data ) {
92- const newComment = data . commentAdded ;
93- updateCommentsQuery ( ( previousResult ) => {
94- // if it's our own mutation, we might get the subscription result
95- // after the mutation result.
96- if ( isDuplicateComment ( newComment , previousResult . entry . comments ) ) {
97- return previousResult ;
98- }
99- // update returns a new "immutable" list with the new comment
100- // added to the front.
101- return update (
102- previousResult ,
103- {
104- entry : {
105- comments : {
106- $unshift : [ newComment ] ,
107- } ,
108- } ,
109- }
110- ) ;
111- } ) ;
112- } ,
113- error ( err ) { console . error ( 'err' , err ) ; } , // eslint-disable-line no-console
114- } ) ;
115- }
116-
11793 render ( ) {
11894 const { loading, currentUser, entry } = this . props ;
11995 const { errors, noCommentContent } = this . state ;
@@ -207,8 +183,7 @@ CommentsPage.propTypes = {
207183 } ) ,
208184 } ) ,
209185 submit : React . PropTypes . func . isRequired ,
210- updateCommentsQuery : React . PropTypes . func ,
211- client : React . PropTypes . instanceOf ( ApolloClient ) . isRequired ,
186+ subscribeToMore : React . PropTypes . func . isRequired ,
212187} ;
213188
214189const SUBMIT_COMMENT_MUTATION = gql `
@@ -298,16 +273,15 @@ export const COMMENT_QUERY = gql`
298273 }
299274` ;
300275
301-
302276const withData = graphql ( COMMENT_QUERY , {
303277 options ( { params } ) {
304278 return {
305279 variables : { repoName : `${ params . org } /${ params . repoName } ` } ,
306280 } ;
307281 } ,
308- props ( { data : { loading, currentUser, entry, updateQuery } } ) {
309- return { loading, currentUser, entry, updateCommentsQuery : updateQuery } ;
282+ props ( { data : { loading, currentUser, entry, subscribeToMore } } ) {
283+ return { loading, currentUser, entry, subscribeToMore } ;
310284 } ,
311285} ) ;
312286
313- export default withApollo ( withData ( withMutations ( CommentsPage ) ) ) ;
287+ export default withData ( withMutations ( CommentsPage ) ) ;
0 commit comments