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

@ -376,6 +376,25 @@ 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.
### 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
Unlike components, emails don't use React but Spacebars, a variant of the Handlebars templating language.

View file

@ -27,7 +27,7 @@ class CustomPostsItem extends Telescope.components.PostsItem {
<div className={postClass}>
<div className="posts-item-vote">
<Telescope.components.Vote post={post} currentUser={this.context.currentUser}/>
<Telescope.components.Vote post={post} />
</div>
{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}}/>
</Link>
</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()}
</div>

View file

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

View file

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

View file

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

View file

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

View file

@ -2,12 +2,12 @@ import Telescope from 'meteor/nova:lib';
import React from 'react';
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) {
return (
<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}
</div>
)

View file

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

View file

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

View file

@ -30,7 +30,7 @@ class App extends Component {
<IntlProvider locale={this.getLocale()} messages={Telescope.strings[this.getLocale()]}>
{
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 />
}
</IntlProvider>

View file

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

View file

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

View file

@ -1,7 +1,5 @@
import Telescope from 'meteor/nova:lib';
import React, { PropTypes, Component } from 'react';
//import Actions from "../actions.js";
//import { Messages } from "meteor/nova:core";
import classNames from 'classnames';
import Users from 'meteor/nova:users';
@ -61,8 +59,7 @@ class Vote extends Component {
Vote.propTypes = {
post: React.PropTypes.object.isRequired, // the current post
// currentUser: React.PropTypes.object, // the current user
}
};
Vote.contextTypes = {
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 Comments from "meteor/nova:comments";
const PostsCommentsThread = ({document, currentUser}) => {
const PostsCommentsThread = ({document}, {currentUser}) => {
const post = document;
@ -39,5 +39,9 @@ const PostsCommentsThread = ({document, currentUser}) => {
PostsCommentsThread.displayName = "PostsCommentsThread";
PostsCommentsThread.contextTypes = {
currentUser: React.PropTypes.object
};
module.exports = PostsCommentsThread;
export default PostsCommentsThread;

View file

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

View file

@ -3,18 +3,12 @@ import React from 'react';
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) {
return (
<div className="posts-list">
{showHeader ? <Telescope.components.PostsListHeader /> : null}
<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>
{hasMore ? (ready ? <Telescope.components.PostsLoadMore loadMore={loadMore} count={count} totalCount={totalCount} /> : <Telescope.components.PostsLoading/>) : <Telescope.components.PostsNoMore/>}
</div>

View file

@ -18,7 +18,6 @@ const PostsNewForm = (props, context) => {
<div className="posts-new-form">
<NovaForm
collection={Posts}
currentUser={context.currentUser}
methodName="posts.new"
successCallback={(post)=>{
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 }/>*/}
<Telescope.components.PostsCommentsThread document={post} currentUser={currentUser}/>
<Telescope.components.PostsCommentsThread document={post} />
</div>
)

View file

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

View file

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

View file

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

View file

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

View file

@ -172,7 +172,7 @@ class NovaForm extends Component{
const fields = this.props.fields;
// 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 (typeof fields !== "undefined" && fields.length > 0) {
@ -401,7 +401,6 @@ NovaForm.propTypes = {
collection: React.PropTypes.object,
schema: React.PropTypes.object,
document: React.PropTypes.object, // if a document is passed, this will be an edit form
currentUser: React.PropTypes.object,
submitCallback: React.PropTypes.func,
successCallback: React.PropTypes.func,
errorCallback: React.PropTypes.func,
@ -419,6 +418,7 @@ NovaForm.defaultProps = {
NovaForm.contextTypes = {
closeCallback: React.PropTypes.func,
currentUser: React.PropTypes.object,
intl: intlShape
}