currentUser is now only given via context, update README about it, add a missing import

This commit is contained in:
xavcz 2016-10-14 08:47:18 +02:00
parent 6a4c9c1f57
commit b04cb52470
23 changed files with 66 additions and 60 deletions

View file

@ -374,7 +374,26 @@ If a component deals with a collection (`Posts`, `Comments`, etc.) its name shou
For example: `PostsShare`. For example: `PostsShare`.
The outermost HTML element within the component will have a class of the same name, but with a dash instead: `posts-share`. If possible, classes for all other elements within the component will start with the component's class: `posts-share-button`, `posts-share-divider`, etc. The outermost HTML element within the component will have a class of the same name, but with a dash instead: `posts-share`. If possible, classes for all other elements within the component will start with the component's class: `posts-share-button`, `posts-share-divider`, etc.
### Get current user
The current user is given to the components via the React context. You can access it via `this.context.currentUser` (class) or `context.currentUser` (stateless-component).
The component needs to define `currentUser` in its `contextTypes`. If `contextTypes` is not defined, then `context` will be an empty object and you won't be able to access to the current user.
Example :
```js
const CustomHeader = (props, context) => {
// if a user is connected, show its username; else say hello
return context.currentUser ? <div>Hey ${context.currentUser.username}!</div> : <div>Hello!</div>
};
// if you don't define `contextTypes` for `CustomHeader`, then the `context` argument will be an empty object
CustomHeader.contextTypes = {
currentUser: React.PropTypes.object
};
```
## Customizing Emails ## Customizing Emails

View file

@ -27,7 +27,7 @@ class CustomPostsItem extends Telescope.components.PostsItem {
<div className={postClass}> <div className={postClass}>
<div className="posts-item-vote"> <div className="posts-item-vote">
<Telescope.components.Vote post={post} currentUser={this.context.currentUser}/> <Telescope.components.Vote post={post} />
</div> </div>
{post.thumbnailUrl ? <Telescope.components.PostsThumbnail post={post}/> : null} {post.thumbnailUrl ? <Telescope.components.PostsThumbnail post={post}/> : null}
@ -49,7 +49,7 @@ class CustomPostsItem extends Telescope.components.PostsItem {
<FormattedMessage id="comments.count" values={{count: post.commentCount}}/> <FormattedMessage id="comments.count" values={{count: post.commentCount}}/>
</Link> </Link>
</div> </div>
{(this.context.currentUser && this.context.currentUser.isAdmin) ?<Telescope.components.PostsStats post={post} />:null} {this.context.currentUser && this.context.currentUser.isAdmin ? <Telescope.components.PostsStats post={post} /> : null}
{this.renderActions()} {this.renderActions()}
</div> </div>

View file

@ -3,8 +3,6 @@ import React, { PropTypes, Component } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import NovaForm from "meteor/nova:forms"; import NovaForm from "meteor/nova:forms";
import { DocumentContainer } from "meteor/utilities:react-list-container"; import { DocumentContainer } from "meteor/utilities:react-list-container";
//import { Messages } from "meteor/nova:core";
//import Actions from "../actions.js";
import Categories from "meteor/nova:categories"; import Categories from "meteor/nova:categories";
class CategoriesEditForm extends Component{ class CategoriesEditForm extends Component{
@ -35,7 +33,6 @@ class CategoriesEditForm extends Component{
<NovaForm <NovaForm
document={this.props.category} document={this.props.category}
collection={Categories} collection={Categories}
currentUser={this.context.currentUser}
methodName="categories.edit" methodName="categories.edit"
successCallback={(category)=>{ successCallback={(category)=>{
this.context.messages.flash("Category edited.", "success"); this.context.messages.flash("Category edited.", "success");

View file

@ -9,7 +9,6 @@ const CategoriesNewForm = (props, context) => {
<div className="categories-new-form"> <div className="categories-new-form">
<NovaForm <NovaForm
collection={Categories} collection={Categories}
currentUser={context.currentUser}
methodName="categories.new" methodName="categories.new"
successCallback={(category)=>{ successCallback={(category)=>{
context.messages.flash("Category created.", "success"); context.messages.flash("Category created.", "success");

View file

@ -10,7 +10,6 @@ class CommentsEdit extends Component {
<NovaForm <NovaForm
collection={Comments} collection={Comments}
document={this.props.comment} document={this.props.comment}
currentUser={this.context.currentUser}
methodName="comments.edit" methodName="comments.edit"
successCallback={this.props.successCallback} successCallback={this.props.successCallback}
layout="elementOnly" layout="elementOnly"

View file

@ -123,8 +123,7 @@ class CommentsItem extends Component{
CommentsItem.propTypes = { CommentsItem.propTypes = {
comment: React.PropTypes.object.isRequired, // the current comment comment: React.PropTypes.object.isRequired, // the current comment
//currentUser: React.PropTypes.object, // the current user };
}
CommentsItem.contextTypes = { CommentsItem.contextTypes = {
currentUser: React.PropTypes.object, currentUser: React.PropTypes.object,
@ -132,6 +131,6 @@ CommentsItem.contextTypes = {
messages: React.PropTypes.object, messages: React.PropTypes.object,
events: React.PropTypes.object, events: React.PropTypes.object,
intl: intlShape intl: intlShape
} };
module.exports = CommentsItem; module.exports = CommentsItem;

View file

@ -2,12 +2,12 @@ import Telescope from 'meteor/nova:lib';
import React from 'react'; import React from 'react';
import {injectIntl, FormattedMessage} from 'react-intl'; import {injectIntl, FormattedMessage} from 'react-intl';
const CommentsList = ({results, currentUser, hasMore, ready, count, totalCount, loadMore}) => { const CommentsList = ({results, hasMore, ready, count, totalCount, loadMore}) => {
if (!!results.length) { if (!!results.length) {
return ( return (
<div className="comments-list"> <div className="comments-list">
{results.map(comment => <Telescope.components.CommentsNode comment={comment} key={comment._id} currentUser={currentUser}/>)} {results.map(comment => <Telescope.components.CommentsNode comment={comment} key={comment._id} />)}
{hasMore ? (ready ? <Telescope.components.CommentsLoadMore loadMore={loadMore} count={count} totalCount={totalCount} /> : <Telescope.components.Loading/>) : null} {hasMore ? (ready ? <Telescope.components.CommentsLoadMore loadMore={loadMore} count={count} totalCount={totalCount} /> : <Telescope.components.Loading/>) : null}
</div> </div>
) )

View file

@ -20,7 +20,6 @@ class CommentsNew extends Component {
<div className="comments-new-form"> <div className="comments-new-form">
<NovaForm <NovaForm
collection={Comments} collection={Comments}
currentUser={this.context.currentUser}
methodName="comments.new" methodName="comments.new"
prefilledProps={prefilledProps} prefilledProps={prefilledProps}
successCallback={this.props.successCallback} successCallback={this.props.successCallback}

View file

@ -6,14 +6,14 @@ class CommentsNode extends Component {
renderComment(comment) { renderComment(comment) {
return ( return (
<Telescope.components.CommentsItem comment={comment} key={comment._id} currentUser={this.props.currentUser}/> <Telescope.components.CommentsItem comment={comment} key={comment._id} />
) )
} }
renderChildren(children) { renderChildren(children) {
return ( return (
<div className="comments-children"> <div className="comments-children">
{children.map(comment => <CommentsNode comment={comment} key={comment._id} currentUser={this.props.currentUser}/>)} {children.map(comment => <CommentsNode comment={comment} key={comment._id} />)}
</div> </div>
) )
} }
@ -35,7 +35,10 @@ class CommentsNode extends Component {
CommentsNode.propTypes = { CommentsNode.propTypes = {
comment: React.PropTypes.object.isRequired, // the current comment comment: React.PropTypes.object.isRequired, // the current comment
};
CommentsNode.contextTypes = {
currentUser: React.PropTypes.object, // the current user currentUser: React.PropTypes.object, // the current user
} };
module.exports = CommentsNode; module.exports = CommentsNode;

View file

@ -30,7 +30,7 @@ class App extends Component {
<IntlProvider locale={this.getLocale()} messages={Telescope.strings[this.getLocale()]}> <IntlProvider locale={this.getLocale()} messages={Telescope.strings[this.getLocale()]}>
{ {
this.props.ready ? this.props.ready ?
<Telescope.components.Layout currentUser={this.props.currentUser}>{this.props.children}</Telescope.components.Layout> <Telescope.components.Layout>{this.props.children}</Telescope.components.Layout>
: <Telescope.components.AppLoading /> : <Telescope.components.AppLoading />
} }
</IntlProvider> </IntlProvider>

View file

@ -2,7 +2,7 @@ import Telescope from 'meteor/nova:lib';
import React from 'react'; import React from 'react';
//import { Messages } from "meteor/nova:core"; //import { Messages } from "meteor/nova:core";
const Header = ({currentUser}) => { const Header = (props, {currentUser}) => {
const logoUrl = Telescope.settings.get("logoUrl"); const logoUrl = Telescope.settings.get("logoUrl");
const siteTitle = Telescope.settings.get("title", "Nova"); const siteTitle = Telescope.settings.get("title", "Nova");
@ -37,4 +37,8 @@ const Header = ({currentUser}) => {
Header.displayName = "Header"; Header.displayName = "Header";
Header.contextTypes = {
currentUser: React.PropTypes.object,
};
module.exports = Header; module.exports = Header;

View file

@ -3,10 +3,8 @@ import React, { PropTypes, Component } from 'react';
import { FormattedMessage, intlShape } from 'react-intl'; import { FormattedMessage, intlShape } from 'react-intl';
import Formsy from 'formsy-react'; import Formsy from 'formsy-react';
import { Input } from 'formsy-react-components'; import { Input } from 'formsy-react-components';
//import Actions from "../actions.js";
import { Button } from 'react-bootstrap'; import { Button } from 'react-bootstrap';
import Cookie from 'react-cookie'; import Cookie from 'react-cookie';
//import { Messages } from "meteor/nova:core";
import Users from 'meteor/nova:users'; import Users from 'meteor/nova:users';
class Newsletter extends Component { class Newsletter extends Component {

View file

@ -1,7 +1,5 @@
import Telescope from 'meteor/nova:lib'; import Telescope from 'meteor/nova:lib';
import React, { PropTypes, Component } from 'react'; import React, { PropTypes, Component } from 'react';
//import Actions from "../actions.js";
//import { Messages } from "meteor/nova:core";
import classNames from 'classnames'; import classNames from 'classnames';
import Users from 'meteor/nova:users'; import Users from 'meteor/nova:users';
@ -61,8 +59,7 @@ class Vote extends Component {
Vote.propTypes = { Vote.propTypes = {
post: React.PropTypes.object.isRequired, // the current post post: React.PropTypes.object.isRequired, // the current post
// currentUser: React.PropTypes.object, // the current user };
}
Vote.contextTypes = { Vote.contextTypes = {
currentUser: React.PropTypes.object, currentUser: React.PropTypes.object,

View file

@ -5,7 +5,7 @@ import { ListContainer } from "meteor/utilities:react-list-container";
import { ModalTrigger } from "meteor/nova:core"; import { ModalTrigger } from "meteor/nova:core";
import Comments from "meteor/nova:comments"; import Comments from "meteor/nova:comments";
const PostsCommentsThread = ({document, currentUser}) => { const PostsCommentsThread = ({document}, {currentUser}) => {
const post = document; const post = document;
@ -39,5 +39,9 @@ const PostsCommentsThread = ({document, currentUser}) => {
PostsCommentsThread.displayName = "PostsCommentsThread"; PostsCommentsThread.displayName = "PostsCommentsThread";
PostsCommentsThread.contextTypes = {
currentUser: React.PropTypes.object
};
module.exports = PostsCommentsThread; module.exports = PostsCommentsThread;
export default PostsCommentsThread; export default PostsCommentsThread;

View file

@ -47,7 +47,7 @@ class PostsItem extends Component {
<div className={postClass}> <div className={postClass}>
<div className="posts-item-vote"> <div className="posts-item-vote">
<Telescope.components.Vote post={post} currentUser={this.context.currentUser}/> <Telescope.components.Vote post={post} />
</div> </div>
{post.thumbnailUrl ? <Telescope.components.PostsThumbnail post={post}/> : null} {post.thumbnailUrl ? <Telescope.components.PostsThumbnail post={post}/> : null}
@ -69,7 +69,7 @@ class PostsItem extends Component {
<FormattedMessage id="comments.count" values={{count: post.commentCount}}/> <FormattedMessage id="comments.count" values={{count: post.commentCount}}/>
</Link> </Link>
</div> </div>
{(this.context.currentUser && this.context.currentUser.isAdmin) ?<Telescope.components.PostsStats post={post} />:null} {this.context.currentUser && this.context.currentUser.isAdmin ? <Telescope.components.PostsStats post={post} /> : null}
{this.renderActions()} {this.renderActions()}
</div> </div>

View file

@ -3,18 +3,12 @@ import React from 'react';
const PostsList = ({results, currentUser, hasMore, ready, count, totalCount, loadMore, showHeader = true}) => { const PostsList = ({results, currentUser, hasMore, ready, count, totalCount, loadMore, showHeader = true}) => {
// console.log(results);
// console.log(ready);
// console.log(hasMore);
// console.log(totalCount);
// console.log(count);
if (!!results.length) { if (!!results.length) {
return ( return (
<div className="posts-list"> <div className="posts-list">
{showHeader ? <Telescope.components.PostsListHeader /> : null} {showHeader ? <Telescope.components.PostsListHeader /> : null}
<div className="posts-list-content"> <div className="posts-list-content">
{results.map(post => <Telescope.components.PostsItem post={post} currentUser={currentUser} key={post._id}/>)} {results.map(post => <Telescope.components.PostsItem post={post} key={post._id}/>)}
</div> </div>
{hasMore ? (ready ? <Telescope.components.PostsLoadMore loadMore={loadMore} count={count} totalCount={totalCount} /> : <Telescope.components.PostsLoading/>) : <Telescope.components.PostsNoMore/>} {hasMore ? (ready ? <Telescope.components.PostsLoadMore loadMore={loadMore} count={count} totalCount={totalCount} /> : <Telescope.components.PostsLoading/>) : <Telescope.components.PostsNoMore/>}
</div> </div>

View file

@ -18,7 +18,6 @@ const PostsNewForm = (props, context) => {
<div className="posts-new-form"> <div className="posts-new-form">
<NovaForm <NovaForm
collection={Posts} collection={Posts}
currentUser={context.currentUser}
methodName="posts.new" methodName="posts.new"
successCallback={(post)=>{ successCallback={(post)=>{
context.messages.flash(context.intl.formatMessage({id: "posts.created_message"}), "success"); context.messages.flash(context.intl.formatMessage({id: "posts.created_message"}), "success");

View file

@ -18,7 +18,7 @@ const PostsPage = ({document, currentUser}) => {
{/*<SocialShare url={ Posts.getLink(post) } title={ post.title }/>*/} {/*<SocialShare url={ Posts.getLink(post) } title={ post.title }/>*/}
<Telescope.components.PostsCommentsThread document={post} currentUser={currentUser}/> <Telescope.components.PostsCommentsThread document={post} />
</div> </div>
) )

View file

@ -22,7 +22,6 @@ const UsersEdit = (props, context) => {
<div className="page users-edit-form"> <div className="page users-edit-form">
<h2 className="page-title users-edit-form-title"><FormattedMessage id="users.edit_account"/></h2> <h2 className="page-title users-edit-form-title"><FormattedMessage id="users.edit_account"/></h2>
<NovaForm <NovaForm
currentUser={currentUser}
collection={Users} collection={Users}
document={user} document={user}
methodName="users.edit" methodName="users.edit"
@ -41,6 +40,7 @@ UsersEdit.propTypes = {
}; };
UsersEdit.contextTypes = { UsersEdit.contextTypes = {
currentUser: React.PropTypes.object,
messages: React.PropTypes.object, messages: React.PropTypes.object,
intl: intlShape intl: intlShape
}; };

View file

@ -7,13 +7,13 @@ import { withRouter } from 'react-router'
import Users from 'meteor/nova:users'; import Users from 'meteor/nova:users';
import { Accounts } from 'meteor/std:accounts-ui'; import { Accounts } from 'meteor/std:accounts-ui';
const UsersProfileCheckModal = ({currentUser, show, router}) => { const UsersProfileCheckModal = ({show, router}, {currentUser}) => {
// return fields that are required by the schema but haven't been filled out yet // return fields that are required by the schema but haven't been filled out yet
const schema = Users.simpleSchema()._schema; const schema = Users.simpleSchema()._schema;
const requiredFields = _.filter(_.keys(schema), function (fieldName) { const requiredFields = _.filter(_.keys(schema), (fieldName) => {
var field = schema[fieldName]; var field = schema[fieldName];
return !!field.required && !Telescope.getNestedProperty(Meteor.user(), fieldName); return !!field.required && !Telescope.getNestedProperty(currentUser, fieldName);
}); });
return ( return (
@ -23,7 +23,6 @@ const UsersProfileCheckModal = ({currentUser, show, router}) => {
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body>
<NovaForm <NovaForm
currentUser={ currentUser }
collection={ Users } collection={ Users }
document={ currentUser } document={ currentUser }
methodName="users.edit" methodName="users.edit"
@ -38,16 +37,17 @@ const UsersProfileCheckModal = ({currentUser, show, router}) => {
) )
}; };
class UsersProfileCheck extends Component { const UsersProfileCheck = (props, {currentUser}) => {
render() { return currentUser ? <UsersProfileCheckModal show={!Users.hasCompletedProfile(currentUser)}/> : null;
const currentUser = this.context.currentUser; };
return currentUser ? <UsersProfileCheckModal currentUser={currentUser} show={!Users.hasCompletedProfile(currentUser)}/> : null
}
}
UsersProfileCheck.contextTypes = { UsersProfileCheck.contextTypes = {
currentUser: React.PropTypes.object currentUser: React.PropTypes.object
} };
UsersProfileCheckModal.contextTypes = {
currentUser: React.PropTypes.object
};
UsersProfileCheck.displayName = "UsersProfileCheck"; UsersProfileCheck.displayName = "UsersProfileCheck";

View file

@ -2,6 +2,7 @@ import Telescope from 'meteor/nova:lib';
import Comments from './collection.js'; import Comments from './collection.js';
import Posts from "meteor/nova:posts"; import Posts from "meteor/nova:posts";
import Users from 'meteor/nova:users'; import Users from 'meteor/nova:users';
import { Messages } from 'meteor/nova:core';
Comments.methods = {}; Comments.methods = {};
// ------------------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------------------- //
@ -97,7 +98,6 @@ Meteor.methods({
var user = Meteor.user(); var user = Meteor.user();
if(Users.canEdit(user, comment)){ if(Users.canEdit(user, comment)){
// decrement post comment count and remove user ID from post // decrement post comment count and remove user ID from post
Posts.update(comment.postId, { Posts.update(comment.postId, {
$inc: {commentCount: -1}, $inc: {commentCount: -1},
@ -117,11 +117,8 @@ Meteor.methods({
htmlBody: 'Deleted', htmlBody: 'Deleted',
isDeleted: true isDeleted: true
}}); }});
} else {
}else{
Messages.flash("You don't have permission to delete this comment.", "error"); Messages.flash("You don't have permission to delete this comment.", "error");
} }
}, },

View file

@ -81,7 +81,6 @@ New document form:
```jsx ```jsx
<NovaForm <NovaForm
collection={Posts} collection={Posts}
currentUser={currentUser},
methodName="posts.new" methodName="posts.new"
/> />
``` ```
@ -91,9 +90,8 @@ Edit document form:
```jsx ```jsx
<NovaForm <NovaForm
collection={Posts} collection={Posts}
currentUser={currentUser}, methodName="posts.edit"
methodName="posts.edit", document={post}
document={post},
labelFunction={capitalize} labelFunction={capitalize}
successCallback={closeModal} successCallback={closeModal}
/> />

View file

@ -172,7 +172,7 @@ class NovaForm extends Component{
const fields = this.props.fields; const fields = this.props.fields;
// get all editable/insertable fields (depending on current form type) // get all editable/insertable fields (depending on current form type)
let relevantFields = this.getFormType() === "edit" ? getEditableFields(this.getSchema(), this.props.currentUser, this.getDocument()) : getInsertableFields(this.getSchema(), this.props.currentUser); let relevantFields = this.getFormType() === "edit" ? getEditableFields(this.getSchema(), this.context.currentUser, this.getDocument()) : getInsertableFields(this.getSchema(), this.context.currentUser);
// if "fields" prop is specified, restrict list of fields to it // if "fields" prop is specified, restrict list of fields to it
if (typeof fields !== "undefined" && fields.length > 0) { if (typeof fields !== "undefined" && fields.length > 0) {
@ -401,7 +401,6 @@ NovaForm.propTypes = {
collection: React.PropTypes.object, collection: React.PropTypes.object,
schema: React.PropTypes.object, schema: React.PropTypes.object,
document: React.PropTypes.object, // if a document is passed, this will be an edit form document: React.PropTypes.object, // if a document is passed, this will be an edit form
currentUser: React.PropTypes.object,
submitCallback: React.PropTypes.func, submitCallback: React.PropTypes.func,
successCallback: React.PropTypes.func, successCallback: React.PropTypes.func,
errorCallback: React.PropTypes.func, errorCallback: React.PropTypes.func,
@ -419,6 +418,7 @@ NovaForm.defaultProps = {
NovaForm.contextTypes = { NovaForm.contextTypes = {
closeCallback: React.PropTypes.func, closeCallback: React.PropTypes.func,
currentUser: React.PropTypes.object,
intl: intlShape intl: intlShape
} }