2017-03-23 16:27:59 +09:00
|
|
|
import { Components, registerComponent, withDocument, withCurrentUser, getActions, withMutation } from 'meteor/vulcan:core';
|
|
|
|
import Posts from 'meteor/vulcan:posts';
|
2017-02-01 16:37:06 +01:00
|
|
|
import React, { Component, PropTypes } from 'react';
|
|
|
|
import { connect } from 'react-redux';
|
|
|
|
import { bindActionCreators } from 'redux';
|
2017-02-04 15:40:26 +09:00
|
|
|
import { FormattedMessage } from 'react-intl';
|
2016-04-03 11:42:07 +09:00
|
|
|
|
2017-02-01 16:37:06 +01:00
|
|
|
class PostsPage extends Component {
|
|
|
|
|
|
|
|
render() {
|
|
|
|
if (this.props.loading) {
|
|
|
|
|
|
|
|
return <div className="posts-page"><Components.Loading/></div>
|
|
|
|
|
2017-02-04 15:40:26 +09:00
|
|
|
} else if (!this.props.document) {
|
2017-02-01 16:37:06 +01:00
|
|
|
|
2017-02-04 15:40:26 +09:00
|
|
|
console.log(`// missing post (_id: ${this.props.documentId})`);
|
|
|
|
return <div className="posts-page"><FormattedMessage id="app.404"/></div>
|
|
|
|
|
|
|
|
} else {
|
2017-02-01 16:37:06 +01:00
|
|
|
const post = this.props.document;
|
2016-11-23 11:07:48 +09:00
|
|
|
|
2017-02-01 16:37:06 +01:00
|
|
|
const htmlBody = {__html: post.htmlBody};
|
2016-02-18 16:26:52 +09:00
|
|
|
|
2017-02-01 16:37:06 +01:00
|
|
|
return (
|
|
|
|
<div className="posts-page">
|
2017-02-16 10:09:28 +01:00
|
|
|
<Components.HeadTags url={Posts.getPageUrl(post)} title={post.title} image={post.thumbnailUrl} description={post.excerpt} />
|
2017-02-01 16:37:06 +01:00
|
|
|
|
|
|
|
<Components.PostsItem post={post} currentUser={this.props.currentUser} />
|
2016-02-18 16:26:52 +09:00
|
|
|
|
2017-02-01 16:37:06 +01:00
|
|
|
{post.htmlBody ? <div className="posts-page-body" dangerouslySetInnerHTML={htmlBody}></div> : null}
|
2016-03-22 10:38:57 +09:00
|
|
|
|
2017-03-05 10:33:34 +00:00
|
|
|
<Components.PostsCommentsThread terms={{postId: post._id, view: 'postComments'}} />
|
2016-11-23 11:07:48 +09:00
|
|
|
|
2017-02-01 16:37:06 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// triggered after the component did mount on the client
|
|
|
|
async componentDidMount() {
|
|
|
|
try {
|
|
|
|
|
|
|
|
// destructure the relevant props
|
|
|
|
const {
|
|
|
|
// from the parent component, used in withDocument, GraphQL HOC
|
|
|
|
documentId,
|
|
|
|
// from connect, Redux HOC
|
|
|
|
setViewed,
|
|
|
|
postsViewed,
|
|
|
|
// from withMutation, GraphQL HOC
|
|
|
|
increasePostViewCount,
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
// a post id has been found & it's has not been seen yet on this client session
|
|
|
|
if (documentId && !postsViewed.includes(documentId)) {
|
2016-11-11 16:42:19 +09:00
|
|
|
|
2017-02-01 16:37:06 +01:00
|
|
|
// trigger the asynchronous mutation with postId as an argument
|
|
|
|
await increasePostViewCount({postId: documentId});
|
|
|
|
|
|
|
|
// once the mutation is done, update the redux store
|
|
|
|
setViewed(documentId);
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch(error) {
|
|
|
|
console.log(error); // eslint-disable-line
|
|
|
|
}
|
2016-11-11 16:42:19 +09:00
|
|
|
}
|
2017-02-01 16:37:06 +01:00
|
|
|
}
|
2016-02-15 22:33:44 +09:00
|
|
|
|
2016-05-22 16:42:24 +09:00
|
|
|
PostsPage.displayName = "PostsPage";
|
|
|
|
|
2016-11-03 14:07:58 +09:00
|
|
|
PostsPage.propTypes = {
|
2017-02-01 16:37:06 +01:00
|
|
|
documentId: PropTypes.string,
|
|
|
|
document: PropTypes.object,
|
|
|
|
postsViewed: PropTypes.array,
|
|
|
|
setViewed: PropTypes.func,
|
|
|
|
increasePostViewCount: PropTypes.func,
|
2016-11-03 14:07:58 +09:00
|
|
|
}
|
|
|
|
|
2017-02-01 16:37:06 +01:00
|
|
|
const queryOptions = {
|
2016-11-22 18:14:51 -05:00
|
|
|
collection: Posts,
|
|
|
|
queryName: 'postsSingleQuery',
|
2017-01-30 19:46:48 +09:00
|
|
|
fragmentName: 'PostsPage',
|
2016-11-22 18:14:51 -05:00
|
|
|
};
|
|
|
|
|
2017-02-01 16:37:06 +01:00
|
|
|
const mutationOptions = {
|
|
|
|
name: 'increasePostViewCount',
|
|
|
|
args: {postId: 'String'},
|
|
|
|
};
|
|
|
|
|
|
|
|
const mapStateToProps = state => ({ postsViewed: state.postsViewed });
|
|
|
|
const mapDispatchToProps = dispatch => bindActionCreators(getActions().postsViewed, dispatch);
|
|
|
|
|
|
|
|
registerComponent(
|
|
|
|
// component name used by Nova
|
|
|
|
'PostsPage',
|
|
|
|
// React component
|
|
|
|
PostsPage,
|
|
|
|
// HOC to give access to the current user
|
|
|
|
withCurrentUser,
|
|
|
|
// HOC to load the data of the document, based on queryOptions & a documentId props
|
|
|
|
[withDocument, queryOptions],
|
|
|
|
// HOC to provide a single mutation, based on mutationOptions
|
|
|
|
withMutation(mutationOptions),
|
|
|
|
// HOC to give access to the redux store & related actions
|
|
|
|
connect(mapStateToProps, mapDispatchToProps)
|
|
|
|
);
|