Last active
December 15, 2017 13:33
-
-
Save crucialfelix/4515c2fcdbd9b62afe3ef8beabab3f72 to your computer and use it in GitHub Desktop.
This file contains 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
import React from "react"; | |
import { MessagesQuery, MessagesQueryVariables } from "../../queries"; | |
import { graphql, QueryProps } from "react-apollo"; | |
import Message from "./Message"; | |
// IMPORTANT: The query is required, not imported. | |
const query = require("./Messages.graphql"); | |
const POLL_INTERVAL = 7901; | |
/** | |
* This is the public interface, the attributes that you can create this component with: | |
* | |
* <Messages threadKey="xyz12345" /> | |
* | |
* It is a subset of the full props that the component will see in its implementation. | |
*/ | |
interface PublicProps { | |
threadKey: string; | |
} | |
/** | |
* These are the props that apollo will supply as this.props.data | |
* | |
* MessagesQuery is the interface generated from Messages.graphql | |
* and QueryProps is imported from react-apollo | |
* and includes the whole data API: .loading, .error, .fetchMore and all that: | |
* https://github.com/apollographql/react-apollo/blob/4ee68965840df9c7908c4cba2ac6b3a3fe383685/src/types.ts#L42 | |
*/ | |
interface DataProps { | |
data: MessagesQuery & QueryProps; | |
} | |
// This is the full props that the component sees internally. | |
// An intersection of the public props | |
type Props = PublicProps & DataProps; | |
/** | |
* Display Messages in a thread | |
*/ | |
class Messages extends React.PureComponent< | |
Props, // full props | |
undefined // state: there is none on this component | |
> { | |
public render() { | |
// If you are still loading or if the viewer is null (not logged in etc.) | |
// then just return. | |
if (!this.props.data.viewer) { | |
return null; | |
} | |
return ( | |
<div className="mw8"> | |
{this.props.data.viewer.messages.edges.map(edge => ( | |
<Message message={edge.node} key={edge.node.id} /> | |
))} | |
</div> | |
); | |
} | |
} | |
/** | |
* This is a function that takes the PublicProps and returns query variables | |
* for the Message.graphql query. | |
* | |
* PublicProps -> MessagesQueryVariables | |
* | |
* Actually it gets the full props, but for the purposes of generating query variables you should | |
* only be dependant on the externally specified props. Everything else is internal apollo results and api. | |
* | |
* The MessagesQueryVariables is generated from the .graphql code so we can now guarantee that this | |
* function will return a correct query. The names and types of all variables must match or | |
* we get squiggly red lines and a lovely compile error. | |
*/ | |
const queryVars = (props: PublicProps): MessagesQueryVariables => ({ | |
threadKey: props.threadKey | |
}); | |
/** | |
* Apollo graphql query config supplies options as a function taking props | |
*/ | |
const config = { | |
options: props => ({ | |
variables: queryVars(props), | |
// I'm going to refresh the messages every 7 seconds | |
pollInterval: POLL_INTERVAL | |
}) | |
}; | |
/** | |
* Create the final component using graphql. | |
* | |
* Note now that the props we supply the public props as the generic | |
* type variable. These are the props which we wish to expose to the outside world. | |
* So the returned component will be typed to have these typed attributes | |
* and politely scold you when you supply otherwise. | |
*/ | |
export default graphql<MessagesQuery, PublicProps>(query, config)(Messages); |
This file contains 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
#import './Message.graphql' | |
# The query is named Messages so the type will be called MessagesQuery | |
# It accepts one query variable: threadKey which is a required String | |
query Messages($threadKey: String!) { | |
viewer { | |
id | |
messages(threadKey: $threadKey) { | |
edges { | |
node { | |
id | |
...Message | |
} | |
} | |
} | |
} | |
} |
This file contains 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
export type MessagesQueryVariables = { | |
threadKey: string; | |
}; | |
export type MessagesQuery = { | |
viewer: { | |
// The ID of the object. | |
id: string; | |
// Query all messages by thread key | |
messages: { | |
edges: Array<{ | |
// The item at the end of the edge | |
node: { | |
// The ID of the object. | |
id: string; | |
body: string; | |
createdOn: string; | |
messageType: string; | |
author: { | |
id: string; | |
name: string; | |
email: string; | |
phone: string; | |
thumb?: string; | |
isStaff: boolean; | |
pk?: number; | |
}; | |
}; | |
}>; | |
} | null; | |
} | null; | |
}; | |
export type MessageFragment = { | |
// The ID of the object. | |
id: string; | |
body: string; | |
createdOn: string; | |
messageType: string; | |
author: { | |
id: string; | |
name: string; | |
email: string; | |
phone: string; | |
thumb?: string; | |
isStaff: boolean; | |
pk?: number; | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment