mirror of
https://github.com/vale981/Vulcan
synced 2025-03-04 09:11:43 -05:00
eslint & clean up code, also fixed some bugs (#1515)
* [eslint] update eslint rules & add .eslintignore to ignore non-ready nova packages * [clean-up] nova-voting * [clean-up] [bug] nova-users: missing user parameter * [clean-up] nova-users * [clean-up] nova-subscribe * [clean-up] nova-settings * [clean-up] nova-rss * [clean-up] [bug] nova-posts: correct UsersRemoveDeletePosts * [clean-up] nova-posts * [clean-up] nova-notifications * [clean-up] [bug] nova-newsletter: no error.message on throw error * [clean-up] nova-newsletter * [clean-up] nova-lib * [clean-up] nova-kadira * [clean-up] nova-inject-data * [clean-up] nova-getting-started * [clean-up] nova-forms * [clean-up] nova-events * [clean-up] [bug] nova-embedly: no FlowRouter * [clean-up] nova-embedly * [clean-up] nova-email-templates * [clean-up] nova-email * [clean-up] nova-debug * [clean-up] nova-core * [clean-up] [bug] nova-comments: correct UsersRemoveDeleteComments * [clean-up] nova-comments * [clean-up] [bug] nova-cloudinary: use Telescope.settings.collection instand * [clean-up] nova-cloudinary * [clean-up] nova-categories * [clean-up] nova-base-components * [clean-up] nova-api * [eslint] extends react recommended * [clean-up] for jsx files * [eslint] extends meteor recommended * i forgot this one little change
This commit is contained in:
parent
99c8d6ef34
commit
464e20a96c
102 changed files with 548 additions and 457 deletions
1
.eslintignore
Normal file
1
.eslintignore
Normal file
|
@ -0,0 +1 @@
|
|||
packages/_*
|
29
.eslintrc
29
.eslintrc
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"extends": [
|
||||
"eslint:recommended"
|
||||
"eslint:recommended",
|
||||
"plugin:meteor/recommended",
|
||||
"plugin:react/recommended"
|
||||
],
|
||||
"parser": "babel-eslint",
|
||||
"parserOptions": {
|
||||
|
@ -10,7 +12,17 @@
|
|||
},
|
||||
"rules": {
|
||||
"babel/generator-star-spacing": 0,
|
||||
"babel/new-cap": 1,
|
||||
"babel/new-cap": [1, {
|
||||
"capIsNewExceptions": [
|
||||
"Optional",
|
||||
"OneOf",
|
||||
"Maybe",
|
||||
"MailChimpAPI",
|
||||
"Juice",
|
||||
"Run",
|
||||
"AppComposer"
|
||||
]
|
||||
}],
|
||||
"babel/array-bracket-spacing": 0,
|
||||
"babel/object-curly-spacing": 0,
|
||||
"babel/object-shorthand": 0,
|
||||
|
@ -20,8 +32,14 @@
|
|||
"key-spacing": 0,
|
||||
"no-extra-boolean-cast": 0,
|
||||
"no-undef": 1,
|
||||
"no-unused-vars": 1,
|
||||
"no-console": 1
|
||||
"no-unused-vars": [1, {
|
||||
"vars": "all",
|
||||
"args": "none",
|
||||
"varsIgnorePattern": "React|PropTypes|Component"
|
||||
}],
|
||||
"no-console": 1,
|
||||
"react/prop-types": 0,
|
||||
"meteor/audit-argument-checks": 0
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
|
@ -32,7 +50,8 @@
|
|||
},
|
||||
"plugins": [
|
||||
"babel",
|
||||
"meteor"
|
||||
"meteor",
|
||||
"react"
|
||||
],
|
||||
"settings": {
|
||||
"import/resolver": "meteor"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
The original Newsletter components is defined using an
|
||||
The original Newsletter components is defined using an
|
||||
ES6 class, so we use the "class foo extends bar" syntax
|
||||
to extend it. This way, we can simply redefine the
|
||||
to extend it. This way, we can simply redefine the
|
||||
render method to change it, while preserving
|
||||
all of the class's other methods (other render
|
||||
functions, event handlers, etc.).
|
||||
|
@ -9,7 +9,7 @@ functions, event handlers, etc.).
|
|||
|
||||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage, intlShape } from 'react-intl';
|
||||
import { FormattedMessage /*, intlShape */ } from 'react-intl';
|
||||
|
||||
class CustomNewsletter extends Telescope.components.Newsletter {
|
||||
|
||||
|
@ -27,4 +27,4 @@ class CustomNewsletter extends Telescope.components.Newsletter {
|
|||
|
||||
}
|
||||
|
||||
export default CustomNewsletter;
|
||||
export default CustomNewsletter;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Posts from "meteor/nova:posts";
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage, FormattedRelative } from 'react-intl';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import moment from 'moment';
|
||||
import { ModalTrigger } from "meteor/nova:core";
|
||||
import { Link } from 'react-router';
|
||||
import Posts from "meteor/nova:posts";
|
||||
import Categories from "meteor/nova:categories";
|
||||
// import { Button } from 'react-bootstrap';
|
||||
// import moment from 'moment';
|
||||
// import { ModalTrigger } from "meteor/nova:core";
|
||||
// import Categories from "meteor/nova:categories";
|
||||
|
||||
class CustomPostsItem extends Telescope.components.PostsItem {
|
||||
|
||||
|
@ -14,7 +14,7 @@ class CustomPostsItem extends Telescope.components.PostsItem {
|
|||
|
||||
const post = this.props.post;
|
||||
|
||||
let postClass = "posts-item";
|
||||
let postClass = "posts-item";
|
||||
if (post.sticky) postClass += " posts-sticky";
|
||||
|
||||
// ⭐ custom code starts here ⭐
|
||||
|
@ -25,22 +25,22 @@ class CustomPostsItem extends Telescope.components.PostsItem {
|
|||
|
||||
return (
|
||||
<div className={postClass}>
|
||||
|
||||
|
||||
<div className="posts-item-vote">
|
||||
<Telescope.components.Vote post={post} />
|
||||
</div>
|
||||
|
||||
|
||||
{post.thumbnailUrl ? <Telescope.components.PostsThumbnail post={post}/> : null}
|
||||
|
||||
<div className="posts-item-content">
|
||||
|
||||
|
||||
<h3 className="posts-item-title">
|
||||
<Link to={Posts.getLink(post)} className="posts-item-title-link" target={Posts.getLinkTarget(post)}>
|
||||
{post.title}
|
||||
</Link>
|
||||
{this.renderCategories()}
|
||||
</h3>
|
||||
|
||||
|
||||
<div className="posts-item-meta">
|
||||
{post.user? <div className="posts-item-user"><Telescope.components.UsersAvatar user={post.user} size="small"/><Telescope.components.UsersName user={post.user}/></div> : null}
|
||||
<div className="posts-item-date"><FormattedRelative value={post.postedAt}/></div>
|
||||
|
@ -56,13 +56,13 @@ class CustomPostsItem extends Telescope.components.PostsItem {
|
|||
</div>
|
||||
|
||||
{this.renderCommenters()}
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
CustomPostsItem.propTypes = {
|
||||
post: React.PropTypes.object.isRequired
|
||||
}
|
||||
|
@ -71,4 +71,4 @@ CustomPostsItem.contextTypes = {
|
|||
currentUser: React.PropTypes.object
|
||||
};
|
||||
|
||||
export default CustomPostsItem;
|
||||
export default CustomPostsItem;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { Picker } from 'meteor/meteorhacks:picker';
|
||||
import { servePostsApi } from './api.js';
|
||||
|
||||
// for backwards compatibility's sake, accept a "limit" segment
|
||||
|
@ -6,4 +7,4 @@ Picker.route('/api/:limit?', function(params, req, res, next) {
|
|||
params.query.limit = params.limit;
|
||||
}
|
||||
res.end(servePostsApi(params.query));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import NovaForm from "meteor/nova:forms";
|
||||
import Categories from "meteor/nova:categories";
|
||||
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 Categories from "meteor/nova:categories";
|
||||
// import { DocumentContainer } from "meteor/utilities:react-list-container";
|
||||
|
||||
class CategoriesEditForm extends Component{
|
||||
|
||||
|
@ -14,7 +14,7 @@ class CategoriesEditForm extends Component{
|
|||
|
||||
deleteCategory() {
|
||||
const category = this.props.category;
|
||||
if (window.confirm(`Delete category “${category.name}”?`)) {
|
||||
if (window.confirm(`Delete category “${category.name}”?`)) {
|
||||
this.context.actions.call("categories.deleteById", category._id, (error, result) => {
|
||||
if (error) {
|
||||
this.context.messages.flash(error.message, "error");
|
||||
|
@ -30,7 +30,7 @@ class CategoriesEditForm extends Component{
|
|||
|
||||
return (
|
||||
<div className="categories-edit-form">
|
||||
<NovaForm
|
||||
<NovaForm
|
||||
document={this.props.category}
|
||||
collection={Categories}
|
||||
methodName="categories.edit"
|
||||
|
@ -57,4 +57,4 @@ CategoriesEditForm.contextTypes = {
|
|||
};
|
||||
|
||||
module.exports = CategoriesEditForm;
|
||||
export default CategoriesEditForm;
|
||||
export default CategoriesEditForm;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import { /* ModalTrigger, */ ContextPasser } from "meteor/nova:core";
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { Button, DropdownButton, MenuItem, Modal } from 'react-bootstrap';
|
||||
import { /* ModalTrigger, */ ContextPasser } from "meteor/nova:core";
|
||||
import { withRouter } from 'react-router'
|
||||
import { LinkContainer } from 'react-router-bootstrap';
|
||||
import Users from 'meteor/nova:users';
|
||||
// import Users from 'meteor/nova:users';
|
||||
|
||||
// note: cannot use ModalTrigger component because of https://github.com/react-bootstrap/react-bootstrap/issues/1808
|
||||
|
||||
|
@ -36,12 +36,12 @@ class CategoriesList extends Component {
|
|||
}
|
||||
|
||||
renderCategoryEditModal(category, index) {
|
||||
|
||||
|
||||
return (
|
||||
<Modal key={index} show={this.state.openModal === index+1} onHide={this.closeModal}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title><FormattedMessage id="categories.edit"/></Modal.Title>
|
||||
</Modal.Header>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<ContextPasser currentUser={this.context.currentUser} messages={this.context.messages} actions={this.context.actions} closeCallback={this.closeModal}>
|
||||
<Telescope.components.CategoriesEditForm category={category}/>
|
||||
|
@ -52,12 +52,12 @@ class CategoriesList extends Component {
|
|||
}
|
||||
|
||||
renderCategoryNewModal() {
|
||||
|
||||
|
||||
return (
|
||||
<Modal show={this.state.openModal === 0} onHide={this.closeModal}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title><FormattedMessage id="categories.new"/></Modal.Title>
|
||||
</Modal.Header>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<ContextPasser currentUser={this.context.currentUser} messages={this.context.messages} closeCallback={this.closeModal}>
|
||||
<Telescope.components.CategoriesNewForm/>
|
||||
|
@ -82,18 +82,18 @@ class CategoriesList extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
const categories = this.props.categories;
|
||||
const context = this.context;
|
||||
// const context = this.context;
|
||||
const currentQuery = _.clone(this.props.router.location.query);
|
||||
delete currentQuery.cat;
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<DropdownButton
|
||||
bsStyle="default"
|
||||
className="categories-list btn-secondary"
|
||||
title={<FormattedMessage id="categories"/>}
|
||||
<DropdownButton
|
||||
bsStyle="default"
|
||||
className="categories-list btn-secondary"
|
||||
title={<FormattedMessage id="categories"/>}
|
||||
id="categories-dropdown"
|
||||
>
|
||||
<div className="category-menu-item dropdown-item">
|
||||
|
@ -115,7 +115,7 @@ class CategoriesList extends Component {
|
|||
)
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CategoriesList.propTypes = {
|
||||
categories: React.PropTypes.array
|
||||
|
@ -128,4 +128,4 @@ CategoriesList.contextTypes = {
|
|||
};
|
||||
|
||||
module.exports = withRouter(CategoriesList);
|
||||
export default withRouter(CategoriesList);
|
||||
export default withRouter(CategoriesList);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Users from 'meteor/nova:users';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { Button, DropdownButton, MenuItem } from 'react-bootstrap';
|
||||
import classNames from "classnames";
|
||||
//import { Messages, ModalTrigger } from 'meteor/nova:core';
|
||||
import { LinkContainer } from 'react-router-bootstrap';
|
||||
import { withRouter } from 'react-router'
|
||||
import Users from 'meteor/nova:users';
|
||||
import { /* Button, DropdownButton, */ MenuItem } from 'react-bootstrap';
|
||||
// import classNames from "classnames";
|
||||
// import { Messages, ModalTrigger } from 'meteor/nova:core';
|
||||
|
||||
class Category extends Component {
|
||||
|
||||
|
@ -26,7 +26,7 @@ class Category extends Component {
|
|||
|
||||
const {category, index, router} = this.props;
|
||||
|
||||
const currentQuery = router.location.query;
|
||||
// const currentQuery = router.location.query;
|
||||
const currentCategorySlug = router.location.query.cat;
|
||||
const newQuery = _.clone(router.location.query);
|
||||
newQuery.cat = category.slug;
|
||||
|
@ -34,9 +34,9 @@ class Category extends Component {
|
|||
return (
|
||||
<div className="category-menu-item dropdown-item">
|
||||
<LinkContainer to={{pathname:"/", query: newQuery}}>
|
||||
<MenuItem
|
||||
eventKey={index+1}
|
||||
key={category._id}
|
||||
<MenuItem
|
||||
eventKey={index+1}
|
||||
key={category._id}
|
||||
>
|
||||
{currentCategorySlug === category.slug ? <Telescope.components.Icon name="voted"/> : null}
|
||||
{category.name}
|
||||
|
@ -60,4 +60,4 @@ Category.contextTypes = {
|
|||
};
|
||||
|
||||
module.exports = withRouter(Category);
|
||||
export default withRouter(Category);
|
||||
export default withRouter(Category);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import moment from 'moment';
|
||||
import { intlShape, FormattedMessage, FormattedRelative } from 'react-intl';
|
||||
import Users from 'meteor/nova:users';
|
||||
// import moment from 'moment';
|
||||
// import Users from 'meteor/nova:users';
|
||||
|
||||
class CommentsItem extends Component{
|
||||
|
||||
|
@ -33,7 +33,7 @@ class CommentsItem extends Component{
|
|||
event.preventDefault();
|
||||
this.setState({showEdit: true});
|
||||
}
|
||||
|
||||
|
||||
editCancelCallback(event) {
|
||||
event.preventDefault();
|
||||
this.setState({showEdit: false});
|
||||
|
@ -44,11 +44,11 @@ class CommentsItem extends Component{
|
|||
}
|
||||
|
||||
deleteComment() {
|
||||
|
||||
|
||||
const comment = this.props.comment;
|
||||
const deleteConfirmMessage = this.context.intl.formatMessage({id: "comments.delete_confirm"}, {body: Telescope.utils.trimWords(comment.body, 20)});
|
||||
const deleteSuccessMessage = this.context.intl.formatMessage({id: "comments.delete_success"}, {body: Telescope.utils.trimWords(comment.body, 20)});
|
||||
|
||||
|
||||
if (window.confirm(deleteConfirmMessage)) {
|
||||
this.context.actions.call('comments.deleteById', comment._id, (error, result) => {
|
||||
this.context.messages.flash(deleteSuccessMessage, "success");
|
||||
|
@ -70,7 +70,7 @@ class CommentsItem extends Component{
|
|||
<a className="comments-item-reply-link" onClick={this.showReply}>
|
||||
<Telescope.components.Icon name="reply"/> <FormattedMessage id="comments.reply"/>
|
||||
</a> : null}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -78,12 +78,12 @@ class CommentsItem extends Component{
|
|||
|
||||
return (
|
||||
<div className="comments-item-reply">
|
||||
<Telescope.components.CommentsNew
|
||||
postId={this.props.comment.postId}
|
||||
parentComment={this.props.comment}
|
||||
successCallback={this.replySuccessCallback}
|
||||
cancelCallback={this.replyCancelCallback}
|
||||
type="reply"
|
||||
<Telescope.components.CommentsNew
|
||||
postId={this.props.comment.postId}
|
||||
parentComment={this.props.comment}
|
||||
successCallback={this.replySuccessCallback}
|
||||
cancelCallback={this.replyCancelCallback}
|
||||
type="reply"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -92,9 +92,9 @@ class CommentsItem extends Component{
|
|||
renderEdit() {
|
||||
|
||||
return (
|
||||
<Telescope.components.CommentsEdit
|
||||
comment={this.props.comment}
|
||||
successCallback={this.editSuccessCallback}
|
||||
<Telescope.components.CommentsEdit
|
||||
comment={this.props.comment}
|
||||
successCallback={this.editSuccessCallback}
|
||||
cancelCallback={this.editCancelCallback}
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import React from 'react';
|
||||
import {injectIntl, FormattedMessage} from 'react-intl';
|
||||
import {/* injectIntl, */ FormattedMessage} from 'react-intl';
|
||||
|
||||
const CommentsList = ({results, hasMore, ready, count, totalCount, loadMore}) => {
|
||||
|
||||
|
@ -24,11 +24,11 @@ const CommentsList = ({results, hasMore, ready, count, totalCount, loadMore}) =>
|
|||
<FormattedMessage id="comments.no_comments"/>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
CommentsList.displayName = "CommentsList";
|
||||
|
||||
module.exports = CommentsList;
|
||||
module.exports = CommentsList;
|
||||
|
|
|
@ -18,8 +18,8 @@ class CommentsNew extends Component {
|
|||
|
||||
return (
|
||||
<div className="comments-new-form">
|
||||
<NovaForm
|
||||
collection={Comments}
|
||||
<NovaForm
|
||||
collection={Comments}
|
||||
methodName="comments.new"
|
||||
prefilledProps={prefilledProps}
|
||||
successCallback={this.props.successCallback}
|
||||
|
@ -30,7 +30,7 @@ class CommentsNew extends Component {
|
|||
)
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
CommentsNew.propTypes = {
|
||||
postId: React.PropTypes.string.isRequired,
|
||||
|
@ -46,4 +46,4 @@ CommentsNew.contextTypes = {
|
|||
currentUser: React.PropTypes.object
|
||||
}
|
||||
|
||||
module.exports = CommentsNew;
|
||||
module.exports = CommentsNew;
|
||||
|
|
|
@ -4,7 +4,7 @@ import React, { PropTypes, Component } from 'react';
|
|||
class CommentsNode extends Component {
|
||||
|
||||
renderComment(comment) {
|
||||
|
||||
|
||||
return (
|
||||
<Telescope.components.CommentsItem comment={comment} key={comment._id} />
|
||||
)
|
||||
|
@ -22,7 +22,7 @@ class CommentsNode extends Component {
|
|||
|
||||
const comment = this.props.comment;
|
||||
const children = this.props.comment.childrenResults;
|
||||
|
||||
|
||||
return (
|
||||
<div className="comments-node">
|
||||
{this.renderComment(comment)}
|
||||
|
@ -31,7 +31,7 @@ class CommentsNode extends Component {
|
|||
)
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
CommentsNode.propTypes = {
|
||||
comment: React.PropTypes.object.isRequired, // the current comment
|
||||
|
@ -41,4 +41,4 @@ CommentsNode.contextTypes = {
|
|||
currentUser: React.PropTypes.object, // the current user
|
||||
};
|
||||
|
||||
module.exports = CommentsNode;
|
||||
module.exports = CommentsNode;
|
||||
|
|
|
@ -10,10 +10,10 @@ class App extends Component {
|
|||
}
|
||||
|
||||
getChildContext() {
|
||||
|
||||
|
||||
const messages = Telescope.strings[this.getLocale()] || {};
|
||||
const intlProvider = new IntlProvider({locale: this.getLocale()}, messages);
|
||||
|
||||
|
||||
const {intl} = intlProvider.getChildContext();
|
||||
|
||||
return {
|
||||
|
@ -29,8 +29,8 @@ class App extends Component {
|
|||
return (
|
||||
<IntlProvider locale={this.getLocale()} messages={Telescope.strings[this.getLocale()]}>
|
||||
{
|
||||
this.props.ready ?
|
||||
<Telescope.components.Layout>{this.props.children}</Telescope.components.Layout>
|
||||
this.props.ready ?
|
||||
<Telescope.components.Layout>{this.props.children}</Telescope.components.Layout>
|
||||
: <Telescope.components.AppLoading />
|
||||
}
|
||||
</IntlProvider>
|
||||
|
@ -56,4 +56,4 @@ App.childContextTypes = {
|
|||
}
|
||||
|
||||
module.exports = AppComposer(App);
|
||||
export default AppComposer(App);
|
||||
export default AppComposer(App);
|
||||
|
|
|
@ -29,7 +29,7 @@ class Newsletter extends Component {
|
|||
subscribeEmail(data) {
|
||||
this.context.actions.call("newsletter.addEmail", data.email, (error, result) => {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
console.log(error); // eslint-disable-line
|
||||
this.context.messages.flash(error.message, "error");
|
||||
} else {
|
||||
this.successCallbackSubscription(result);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { Messages } from 'meteor/nova:core';
|
||||
// import { Messages } from 'meteor/nova:core';
|
||||
import Users from 'meteor/nova:users';
|
||||
|
||||
class NewsletterButton extends Component {
|
||||
|
@ -15,7 +15,7 @@ class NewsletterButton extends Component {
|
|||
'newsletter.removeUser' : 'newsletter.addUser';
|
||||
this.context.actions.call(action, this.props.user, (error, result) => {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
console.log(error); // eslint-disable-line
|
||||
this.context.messages.flash(error.message, "error");
|
||||
} else {
|
||||
this.props.successCallback(result);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Users from 'meteor/nova:users';
|
||||
import { T9n } from 'meteor/softwarerero:accounts-t9n';
|
||||
|
||||
// import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions';
|
||||
// checkNpmVersions({
|
||||
|
@ -16,4 +17,4 @@ Users.avatar.setOptions({
|
|||
});
|
||||
|
||||
// https://github.com/softwarerero/meteor-accounts-t9n
|
||||
T9n.setLanguage(Telescope.settings.get("locale", "en"));
|
||||
T9n.setLanguage(Telescope.settings.get("locale", "en"));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Telescope from "meteor/nova:lib";
|
||||
import React, { PropTypes, Component } from "react";
|
||||
import { Button } from "react-bootstrap";
|
||||
// import { Button } from "react-bootstrap";
|
||||
import moment from "moment";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { ListContainer } from "meteor/utilities:react-list-container";
|
||||
import moment from 'moment';
|
||||
import Posts from "meteor/nova:posts";
|
||||
import { ListContainer } from "meteor/utilities:react-list-container";
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
class PostsDay extends Component {
|
||||
|
||||
|
@ -19,19 +19,19 @@ class PostsDay extends Component {
|
|||
listId: `posts.list.${moment(date).format("YYYY-MM-DD")}`
|
||||
};
|
||||
|
||||
({selector, options} = Posts.parameters.get(terms));
|
||||
const {selector, options} = Posts.parameters.get(terms);
|
||||
|
||||
const postsPerPage = Telescope.settings.get("postsPerPage", 10);
|
||||
|
||||
return (
|
||||
<div className="posts-day">
|
||||
<h4 className="posts-day-heading">{moment(date).format("dddd, MMMM Do YYYY")}</h4>
|
||||
<ListContainer
|
||||
collection={Posts}
|
||||
<ListContainer
|
||||
collection={Posts}
|
||||
publication="posts.list"
|
||||
selector={selector}
|
||||
options={options}
|
||||
terms={terms}
|
||||
terms={terms}
|
||||
joins={Posts.getJoins()}
|
||||
component={Telescope.components.PostsList}
|
||||
componentProps={{showHeader: false}}
|
||||
|
@ -51,4 +51,4 @@ PostsDay.propTypes = {
|
|||
}
|
||||
|
||||
module.exports = PostsDay;
|
||||
export default PostsDay;
|
||||
export default PostsDay;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage, intlShape } 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 Posts from "meteor/nova:posts";
|
||||
import Users from 'meteor/nova:users';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage, intlShape } from 'react-intl';
|
||||
// import { Messages } from "meteor/nova:core";
|
||||
// import Actions from "../actions.js";
|
||||
// import Users from 'meteor/nova:users';
|
||||
|
||||
class PostsEditForm extends Component{
|
||||
|
||||
|
@ -20,7 +20,7 @@ class PostsEditForm extends Component{
|
|||
const deletePostConfirm = this.context.intl.formatMessage({id: "posts.delete_confirm"}, {title: post.title});
|
||||
const deletePostSuccess = this.context.intl.formatMessage({id: "posts.delete_success"}, {title: post.title});
|
||||
|
||||
if (window.confirm(deletePostConfirm)) {
|
||||
if (window.confirm(deletePostConfirm)) {
|
||||
this.context.actions.call('posts.remove', post._id, (error, result) => {
|
||||
this.context.messages.flash(deletePostSuccess, "success");
|
||||
this.context.events.track("post deleted", {'_id': post._id});
|
||||
|
@ -41,13 +41,13 @@ class PostsEditForm extends Component{
|
|||
|
||||
render() {
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="posts-edit-form">
|
||||
{this.renderAdminArea()}
|
||||
<DocumentContainer
|
||||
collection={Posts}
|
||||
publication="posts.single"
|
||||
<DocumentContainer
|
||||
collection={Posts}
|
||||
publication="posts.single"
|
||||
selector={{_id: this.props.post._id}}
|
||||
terms={{_id: this.props.post._id}}
|
||||
joins={Posts.getJoins()}
|
||||
|
@ -57,7 +57,7 @@ class PostsEditForm extends Component{
|
|||
collection: Posts,
|
||||
currentUser: this.context.currentUser,
|
||||
methodName: "posts.edit",
|
||||
successCallback: (post) => {
|
||||
successCallback: (post) => {
|
||||
this.context.messages.flash(this.context.intl.formatMessage({id: "posts.edit_success"}, {title: post.title}), 'success')
|
||||
}
|
||||
}}
|
||||
|
@ -82,4 +82,4 @@ PostsEditForm.contextTypes = {
|
|||
}
|
||||
|
||||
module.exports = PostsEditForm;
|
||||
export default PostsEditForm;
|
||||
export default PostsEditForm;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { ListContainer, DocumentContainer } from "meteor/utilities:react-list-container";
|
||||
import { ListContainer /* , DocumentContainer */ } from "meteor/utilities:react-list-container";
|
||||
import Posts from "meteor/nova:posts";
|
||||
|
||||
class PostsHome extends Component {
|
||||
|
@ -8,19 +8,19 @@ class PostsHome extends Component {
|
|||
getDefaultView() {
|
||||
return {view: 'top'}
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
const params = {...this.getDefaultView(), ...this.props.location.query, listId: "posts.list.main"};
|
||||
const {selector, options} = Posts.parameters.get(params);
|
||||
|
||||
return (
|
||||
<ListContainer
|
||||
collection={Posts}
|
||||
<ListContainer
|
||||
collection={Posts}
|
||||
publication="posts.list"
|
||||
selector={selector}
|
||||
options={options}
|
||||
terms={params}
|
||||
terms={params}
|
||||
joins={Posts.getJoins()}
|
||||
component={Telescope.components.PostsList}
|
||||
cacheSubscription={true}
|
||||
|
@ -29,6 +29,6 @@ class PostsHome extends Component {
|
|||
/>
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = PostsHome;
|
||||
module.exports = PostsHome;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import { ModalTrigger } from "meteor/nova:core";
|
||||
import Posts from "meteor/nova:posts";
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage, FormattedRelative } from 'react-intl';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import moment from 'moment';
|
||||
import { ModalTrigger } from "meteor/nova:core";
|
||||
import { Link } from 'react-router';
|
||||
import Posts from "meteor/nova:posts";
|
||||
import Users from 'meteor/nova:users';
|
||||
// import { Button } from 'react-bootstrap';
|
||||
// import moment from 'moment';
|
||||
// import Users from 'meteor/nova:users';
|
||||
|
||||
class PostsItem extends Component {
|
||||
|
||||
|
@ -32,12 +32,12 @@ class PostsItem extends Component {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
const post = this.props.post;
|
||||
|
||||
let postClass = "posts-item";
|
||||
let postClass = "posts-item";
|
||||
if (post.sticky) postClass += " posts-sticky";
|
||||
|
||||
// console.log(post)
|
||||
|
@ -45,22 +45,22 @@ class PostsItem extends Component {
|
|||
|
||||
return (
|
||||
<div className={postClass}>
|
||||
|
||||
|
||||
<div className="posts-item-vote">
|
||||
<Telescope.components.Vote post={post} />
|
||||
</div>
|
||||
|
||||
|
||||
{post.thumbnailUrl ? <Telescope.components.PostsThumbnail post={post}/> : null}
|
||||
|
||||
<div className="posts-item-content">
|
||||
|
||||
|
||||
<h3 className="posts-item-title">
|
||||
<Link to={Posts.getLink(post)} className="posts-item-title-link" target={Posts.getLinkTarget(post)}>
|
||||
{post.title}
|
||||
</Link>
|
||||
{this.renderCategories()}
|
||||
</h3>
|
||||
|
||||
|
||||
<div className="posts-item-meta">
|
||||
{post.user? <div className="posts-item-user"><Telescope.components.UsersAvatar user={post.user} size="small"/><Telescope.components.UsersName user={post.user}/></div> : null}
|
||||
<div className="posts-item-date">{post.postedAt ? <FormattedRelative value={post.postedAt}/> : <FormattedMessage id="posts.dateNotDefined"/>}</div>
|
||||
|
@ -76,13 +76,13 @@ class PostsItem extends Component {
|
|||
</div>
|
||||
|
||||
{this.renderCommenters()}
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
PostsItem.propTypes = {
|
||||
post: React.PropTypes.object.isRequired
|
||||
}
|
||||
|
@ -92,4 +92,4 @@ PostsItem.contextTypes = {
|
|||
};
|
||||
|
||||
module.exports = PostsItem;
|
||||
export default PostsItem;
|
||||
export default PostsItem;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage, intlShape } from 'react-intl';
|
||||
import { Button, ButtonGroup, DropdownButton, MenuItem } from 'react-bootstrap';
|
||||
import { /* Button, ButtonGroup, */ DropdownButton, MenuItem } from 'react-bootstrap';
|
||||
import { LinkContainer } from 'react-router-bootstrap';
|
||||
import { withRouter } from 'react-router'
|
||||
import Users from 'meteor/nova:users';
|
||||
|
@ -9,7 +9,7 @@ const PostsViews = (props, context) => {
|
|||
|
||||
let views = ["top", "new", "best"];
|
||||
const adminViews = ["pending", "rejected", "scheduled"];
|
||||
|
||||
|
||||
if (Users.canDo(context.currentUser, "posts.edit.all")) {
|
||||
views = views.concat(adminViews);
|
||||
}
|
||||
|
@ -18,13 +18,13 @@ const PostsViews = (props, context) => {
|
|||
|
||||
return (
|
||||
<div className="posts-views">
|
||||
<DropdownButton
|
||||
bsStyle="default"
|
||||
className="views btn-secondary"
|
||||
title={context.intl.formatMessage({id: "posts.view"})}
|
||||
<DropdownButton
|
||||
bsStyle="default"
|
||||
className="views btn-secondary"
|
||||
title={context.intl.formatMessage({id: "posts.view"})}
|
||||
id="views-dropdown"
|
||||
>
|
||||
{views.map(view =>
|
||||
{views.map(view =>
|
||||
<LinkContainer key={view} to={{pathname: "/", query: {...query, view: view}}} /*to={}*/ className="dropdown-item">
|
||||
<MenuItem>
|
||||
<FormattedMessage id={"posts."+view}/>
|
||||
|
|
|
@ -5,7 +5,7 @@ import { Accounts } from 'meteor/std:accounts-ui';
|
|||
const UsersAccountForm = () => {
|
||||
return (
|
||||
<Accounts.ui.LoginForm />
|
||||
)
|
||||
)
|
||||
};
|
||||
|
||||
module.exports = UsersAccountForm;
|
||||
|
@ -23,12 +23,12 @@ class AccountsButton extends Accounts.ui.Button {
|
|||
render () {
|
||||
const {label, href, type, disabled, className, onClick} = this.props;
|
||||
if (type === 'link') {
|
||||
return <a href={ href } className={ className } onClick={ onClick }>{ label }</a>;
|
||||
return <a href={ href } className={ className } onClick={ onClick }>{ label }</a>;
|
||||
}
|
||||
return <Button
|
||||
return <Button
|
||||
bsStyle="primary"
|
||||
className={ className }
|
||||
type={ type }
|
||||
type={ type }
|
||||
disabled={ disabled }
|
||||
onClick={ onClick }>{ label }
|
||||
</Button>;
|
||||
|
@ -44,13 +44,13 @@ class AccountsField extends Accounts.ui.Field {
|
|||
onChange({ target: { value: this.input.value } })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { id, hint, label, type = 'text', onChange, className = "field", defaultValue = "" } = this.props;
|
||||
const { id, hint, /* label, */ type = 'text', onChange, className = "field", defaultValue = "" } = this.props;
|
||||
const { mount = true } = this.state;
|
||||
return mount ? (
|
||||
<div className={ className }>
|
||||
<FormControl id={ id } type={ type } onChange={ onChange } placeholder={ hint } defaultValue={ defaultValue } />
|
||||
<FormControl id={ id } type={ type } onChange={ onChange } placeholder={ hint } defaultValue={ defaultValue } />
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
|
@ -99,4 +99,4 @@ class AccountsField extends Accounts.ui.Field {
|
|||
Accounts.ui.Button = AccountsButton;
|
||||
Accounts.ui.Field = AccountsField;
|
||||
// Accounts.ui.SocialButtons = AccountsSocialButtons;
|
||||
// Accounts.ui.PasswordOrService = AccountsPasswordOrService;
|
||||
// Accounts.ui.PasswordOrService = AccountsPasswordOrService;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { Dropdown, Button } from 'react-bootstrap';
|
||||
import { Dropdown /* , Button */ } from 'react-bootstrap';
|
||||
|
||||
const UsersAccountMenu = () => {
|
||||
|
||||
|
@ -14,10 +14,10 @@ const UsersAccountMenu = () => {
|
|||
<Telescope.components.UsersAccountForm />
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
)
|
||||
)
|
||||
};
|
||||
|
||||
UsersAccountMenu.displayName = "UsersAccountMenu";
|
||||
|
||||
module.exports = UsersAccountMenu;
|
||||
export default UsersAccountMenu;
|
||||
export default UsersAccountMenu;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage, intlShape } from 'react-intl';
|
||||
import { Row, Col } from 'react-bootstrap';
|
||||
// import { Row, Col } from 'react-bootstrap';
|
||||
import NovaForm from "meteor/nova:forms";
|
||||
//import { Messages } from "meteor/nova:core";
|
||||
import Users from 'meteor/nova:users';
|
||||
|
@ -9,21 +9,21 @@ import Users from 'meteor/nova:users';
|
|||
const UsersEdit = (props, context) => {
|
||||
|
||||
const user = props.user;
|
||||
const currentUser = props.currentUser;
|
||||
// const currentUser = props.currentUser;
|
||||
|
||||
//const label = `Edit profile for ${Users.getDisplayName(user)}`;
|
||||
|
||||
return (
|
||||
<Telescope.components.CanDo
|
||||
<Telescope.components.CanDo
|
||||
action="users.edit"
|
||||
document={user}
|
||||
displayNoPermissionMessage={true}
|
||||
>
|
||||
<div className="page users-edit-form">
|
||||
<h2 className="page-title users-edit-form-title"><FormattedMessage id="users.edit_account"/></h2>
|
||||
<NovaForm
|
||||
collection={Users}
|
||||
document={user}
|
||||
<NovaForm
|
||||
collection={Users}
|
||||
document={user}
|
||||
methodName="users.edit"
|
||||
successCallback={(user)=>{
|
||||
context.messages.flash(context.intl.formatMessage({id: "users.edit_success"}, {name: Users.getDisplayName(user)}), 'success')
|
||||
|
@ -34,7 +34,7 @@ const UsersEdit = (props, context) => {
|
|||
)
|
||||
};
|
||||
|
||||
|
||||
|
||||
UsersEdit.propTypes = {
|
||||
user: React.PropTypes.object.isRequired,
|
||||
};
|
||||
|
@ -48,4 +48,4 @@ UsersEdit.contextTypes = {
|
|||
UsersEdit.displayName = "UsersEdit";
|
||||
|
||||
module.exports = UsersEdit;
|
||||
export default UsersEdit;
|
||||
export default UsersEdit;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Accounts, STATES } from 'meteor/std:accounts-ui';
|
||||
import { T9n } from 'meteor/softwarerero:accounts-t9n';
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
class UsersResetPassword extends Component {
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import React from 'react';
|
||||
import {mount} from 'react-mounter';
|
||||
import { Messages } from 'meteor/nova:core';
|
||||
import { IndexRoute, Route, useRouterHistory, browserHistory, createMemoryHistory } from 'react-router';
|
||||
import { ReactRouterSSR } from 'meteor/reactrouter:react-router-ssr';
|
||||
import { ListContainer, DocumentContainer } from "meteor/utilities:react-list-container";
|
||||
// import useNamedRoutes from 'use-named-routes';
|
||||
import createBrowserHistory from 'history/lib/createBrowserHistory';
|
||||
import Events from "meteor/nova:events";
|
||||
import { ReactRouterSSR } from 'meteor/reactrouter:react-router-ssr';
|
||||
import React from 'react';
|
||||
import Helmet from 'react-helmet';
|
||||
import Cookie from 'react-cookie';
|
||||
import ReactDOM from 'react-dom';
|
||||
// import {mount} from 'react-mounter';
|
||||
// import { IndexRoute, Route, useRouterHistory, browserHistory, createMemoryHistory } from 'react-router';
|
||||
// import { ListContainer, DocumentContainer } from "meteor/utilities:react-list-container";
|
||||
// import useNamedRoutes from 'use-named-routes';
|
||||
// import createBrowserHistory from 'history/lib/createBrowserHistory';
|
||||
|
||||
Telescope.routes.indexRoute = { name: "posts.list", component: Telescope.components.PostsHome };
|
||||
|
||||
|
@ -33,13 +33,13 @@ Meteor.startup(() => {
|
|||
childRoutes: Telescope.routes.routes
|
||||
}
|
||||
|
||||
let history;
|
||||
// let history;
|
||||
|
||||
const clientOptions = {
|
||||
renderHook: ReactDOM.render,
|
||||
props: {
|
||||
onUpdate: () => {
|
||||
Events.analyticsRequest();
|
||||
Events.analyticsRequest();
|
||||
Messages.clearSeen();
|
||||
}
|
||||
}
|
||||
|
@ -48,15 +48,15 @@ Meteor.startup(() => {
|
|||
const serverOptions = {
|
||||
htmlHook: (html) => {
|
||||
const head = Helmet.rewind();
|
||||
return html.replace('<head>', '<head>'+ head.title + head.meta + head.link);
|
||||
return html.replace('<head>', '<head>'+ head.title + head.meta + head.link);
|
||||
},
|
||||
preRender: (req, res) => {
|
||||
Cookie.plugToRequest(req, res);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
ReactRouterSSR.Run(AppRoutes, clientOptions, serverOptions);
|
||||
|
||||
|
||||
// note: we did like this at first
|
||||
// if (Meteor.isClient) {
|
||||
// history = useNamedRoutes(useRouterHistory(createBrowserHistory))({ routes: AppRoutes });
|
||||
|
@ -66,4 +66,4 @@ Meteor.startup(() => {
|
|||
// }
|
||||
// ReactRouterSSR.Run(AppRoutes, {historyHook: () => history}, {historyHook: () => history});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,7 +18,8 @@ Categories.getParents = function (category) {
|
|||
categoriesArray.push(parent);
|
||||
recurse(parent);
|
||||
}
|
||||
}(category);
|
||||
};
|
||||
getParents(category);
|
||||
|
||||
return categoriesArray;
|
||||
};
|
||||
|
@ -37,7 +38,8 @@ Categories.getChildren = function (category) {
|
|||
categoriesArray = categoriesArray.concat(children);
|
||||
recurse(children);
|
||||
}
|
||||
}([category]);
|
||||
};
|
||||
getChildren([category]);
|
||||
|
||||
return categoriesArray;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Categories from "./collection.js";
|
||||
import Users from 'meteor/nova:users';
|
||||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||
|
||||
const canInsert = user => Users.canDo(user, "categories.new");
|
||||
const canEdit = user => Users.canDo(user, "categories.edit.all");
|
||||
|
@ -79,7 +80,7 @@ Telescope.settings.collection.addField([
|
|||
optional: true,
|
||||
form: {
|
||||
group: 'categories',
|
||||
instructions: 'Let users filter by one or multiple categories at a time.',
|
||||
instructions: 'Let users filter by one or multiple categories at a time.',
|
||||
options: function () {
|
||||
return [
|
||||
{value: "single", label: "categories_behavior_one_at_a_time"},
|
||||
|
@ -100,4 +101,4 @@ Telescope.settings.collection.addField([
|
|||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
]);
|
||||
|
|
|
@ -19,7 +19,7 @@ if (Meteor.settings && Meteor.settings.categories) {
|
|||
} else {
|
||||
// if not, create it
|
||||
Categories.insert(category);
|
||||
console.log(`// Creating category “${category.name}”`);
|
||||
console.log(`// Creating category “${category.name}”`); // eslint-disable-line
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import Posts from "meteor/nova:posts";
|
||||
// import Posts from "meteor/nova:posts";
|
||||
import Users from 'meteor/nova:users';
|
||||
import Categories from "../collection.js";
|
||||
|
||||
Meteor.publish('categories', function() {
|
||||
|
||||
|
||||
const currentUser = this.userId && Users.findOne(this.userId);
|
||||
|
||||
if(Users.canDo(currentUser, "posts.view.approved.all")){
|
||||
|
||||
|
||||
var categories = Categories.find({}, {fields: Categories.publishedFields.list});
|
||||
|
||||
/*
|
||||
var publication = this;
|
||||
|
||||
categories.forEach(function (category) {
|
||||
|
@ -17,8 +19,9 @@ Meteor.publish('categories', function() {
|
|||
var cursor = Posts.find({$and: [{categories: {$in: categoryIds}}, {status: Posts.config.STATUS_APPROVED}]});
|
||||
// Counts.publish(publication, category.getCounterName(), cursor, { noReady: true });
|
||||
});
|
||||
*/
|
||||
|
||||
return categories;
|
||||
}
|
||||
return [];
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Posts from "meteor/nova:posts";
|
||||
import PublicationUtils from 'meteor/utilities:smart-publications';
|
||||
|
||||
|
@ -20,7 +21,7 @@ Posts.addField([
|
|||
]);
|
||||
|
||||
if (typeof Settings !== "undefined") {
|
||||
Settings.addField([
|
||||
Telescope.settings.collection.addField([
|
||||
{
|
||||
fieldName: 'cloudinaryCloudName',
|
||||
fieldSchema: {
|
||||
|
|
|
@ -14,7 +14,7 @@ Cloudinary.config({
|
|||
});
|
||||
|
||||
const CloudinaryUtils = {
|
||||
|
||||
|
||||
// send an image URL to Cloudinary and get a cloudinary result object in return
|
||||
uploadImage(imageUrl) {
|
||||
try {
|
||||
|
@ -26,8 +26,8 @@ const CloudinaryUtils = {
|
|||
};
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.log("// Cloudinary upload failed for URL: "+imageUrl);
|
||||
console.log(error.stack);
|
||||
console.log("// Cloudinary upload failed for URL: "+imageUrl); // eslint-disable-line
|
||||
console.log(error.stack); // eslint-disable-line
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -35,8 +35,8 @@ const CloudinaryUtils = {
|
|||
getUrls(cloudinaryId) {
|
||||
return Telescope.settings.get("cloudinaryFormats").map(format => {
|
||||
const url = Cloudinary.url(cloudinaryId, {
|
||||
width: format.width,
|
||||
height: format.height,
|
||||
width: format.width,
|
||||
height: format.height,
|
||||
crop: 'fill',
|
||||
sign_url: true,
|
||||
fetch_format: "auto",
|
||||
|
@ -56,7 +56,7 @@ Meteor.methods({
|
|||
if (Users.isAdmin(Meteor.user())) {
|
||||
thumbnailUrl = typeof thumbnailUrl === "undefined" ? "http://www.telescopeapp.org/images/logo.png" : thumbnailUrl;
|
||||
const data = CloudinaryUtils.uploadImage(thumbnailUrl);
|
||||
console.log(data);
|
||||
console.log(data); // eslint-disable-line
|
||||
}
|
||||
},
|
||||
cachePostThumbnails: function (limit = 20) {
|
||||
|
@ -71,16 +71,16 @@ Meteor.methods({
|
|||
postsWithUncachedThumbnails.forEach(Meteor.bindEnvironment((post, index) => {
|
||||
|
||||
Meteor.setTimeout(function () {
|
||||
console.log(`// ${index}. Caching thumbnail for post “${post.title}” (_id: ${post._id})`);
|
||||
console.log(`// ${index}. Caching thumbnail for post “${post.title}” (_id: ${post._id})`); // eslint-disable-line
|
||||
|
||||
const data = CloudinaryUtils.uploadImage(post.thumbnailUrl);
|
||||
Posts.update(post._id, {$set:{
|
||||
cloudinaryId: data.cloudinaryId,
|
||||
cloudinaryUrls: data.urls
|
||||
}});
|
||||
|
||||
|
||||
}, index * 1000);
|
||||
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ Telescope.callbacks.add("posts.new.async", cachePostThumbnailOnSubmit);
|
|||
function cachePostThumbnailOnEdit (newPost, oldPost) {
|
||||
if (Telescope.settings.get("cloudinaryAPIKey")) {
|
||||
if (newPost.thumbnailUrl && newPost.thumbnailUrl !== oldPost.thumbnailUrl) {
|
||||
|
||||
|
||||
const data = CloudinaryUtils.uploadImage(newPost.thumbnailUrl);
|
||||
Posts.update(newPost._id, {$set:{
|
||||
cloudinaryId: data.cloudinaryId,
|
||||
|
@ -118,4 +118,4 @@ function cachePostThumbnailOnEdit (newPost, oldPost) {
|
|||
}
|
||||
Telescope.callbacks.add("posts.edit.async", cachePostThumbnailOnEdit);
|
||||
|
||||
export default CloudinaryUtils;
|
||||
export default CloudinaryUtils;
|
||||
|
|
|
@ -232,7 +232,7 @@ function CommentsNewNotifications (comment) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ Telescope.callbacks.add("comments.edit.method", CommentsEditSubmittedPropertiesC
|
|||
|
||||
function UsersRemoveDeleteComments (user, options) {
|
||||
if (options && options.deleteComments) {
|
||||
Comments.remove({userId: userId});
|
||||
Comments.remove({userId: user._id});
|
||||
} else {
|
||||
// not sure if anything should be done in that scenario yet
|
||||
// Comments.update({userId: userId}, {$set: {author: "\[deleted\]"}}, {multi: true});
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
* @summary The global namespace for Comments.
|
||||
* @namespace Comments
|
||||
*/
|
||||
Comments = new Mongo.Collection("comments");
|
||||
const Comments = new Mongo.Collection("comments");
|
||||
|
||||
export default Comments;
|
||||
export default Comments;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import PublicationUtils from 'meteor/utilities:smart-publications';
|
||||
import Posts from "meteor/nova:posts";
|
||||
import Users from "meteor/nova:users";
|
||||
import Posts from 'meteor/nova:posts';
|
||||
import Users from 'meteor/nova:users';
|
||||
|
||||
Posts.addField([
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
// import Telescope from 'meteor/nova:lib';
|
||||
import Comments from './collection.js';
|
||||
import Posts from 'meteor/nova:posts';
|
||||
import Users from 'meteor/nova:users';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Comments from './collection.js';
|
||||
import PublicationsUtils from 'meteor/utilities:smart-publications';
|
||||
import Posts from "meteor/nova:posts";
|
||||
// import Posts from "meteor/nova:posts";
|
||||
|
||||
Comments.publishedFields = {};
|
||||
|
||||
|
@ -26,4 +26,4 @@ Comments.publishedFields.list = PublicationsUtils.arrayToFields([
|
|||
* @summary Specify which fields should be published by the posts.single publication
|
||||
* @array Posts.publishedFields.single
|
||||
*/
|
||||
Comments.publishedFields.single = PublicationsUtils.arrayToFields(Comments.getPublishedFields());
|
||||
Comments.publishedFields.single = PublicationsUtils.arrayToFields(Comments.getPublishedFields());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Comments from './collection.js';
|
||||
import Users from 'meteor/nova:users';
|
||||
|
||||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||
import Comments from './collection.js';
|
||||
|
||||
// check if user can create a new comment
|
||||
const canInsert = user => Users.canDo(user, "comments.new");
|
||||
|
@ -10,7 +10,7 @@ const canInsert = user => Users.canDo(user, "comments.new");
|
|||
const canEdit = Users.canEdit;
|
||||
|
||||
// check if user can edit *all* comments
|
||||
const canEditAll = user => Users.canDo(user, "comments.edit.all");
|
||||
// const canEditAll = user => Users.canDo(user, "comments.edit.all");
|
||||
|
||||
/**
|
||||
* @summary Comments schema
|
||||
|
@ -126,7 +126,7 @@ Comments.schema = new SimpleSchema({
|
|||
}
|
||||
},
|
||||
/**
|
||||
Whether the comment is deleted. Delete comments' content doesn't appear on the site.
|
||||
Whether the comment is deleted. Delete comments' content doesn't appear on the site.
|
||||
*/
|
||||
isDeleted: {
|
||||
type: Boolean,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Posts from "meteor/nova:posts";
|
||||
import Users from 'meteor/nova:users';
|
||||
import Comments from '../collection.js';
|
||||
|
||||
Comments._ensureIndex({postId: 1});
|
||||
Comments._ensureIndex({parentCommentId: 1});
|
||||
|
@ -9,11 +10,11 @@ Comments._ensureIndex({parentCommentId: 1});
|
|||
* @param {Object} terms
|
||||
*/
|
||||
Meteor.publish('comments.list', function (terms) {
|
||||
|
||||
|
||||
const currentUser = this.userId && Users.findOne(this.userId);
|
||||
|
||||
terms.currentUserId = this.userId; // add currentUserId to terms
|
||||
({selector, options} = Comments.parameters.get(terms));
|
||||
const {selector, options} = Comments.parameters.get(terms);
|
||||
|
||||
// commenting this because of FR-SSR issue
|
||||
// Counts.publish(this, 'comments.list', Comments.find(selector, options));
|
||||
|
@ -41,12 +42,12 @@ Meteor.publish('comments.list', function (terms) {
|
|||
|
||||
// check(terms, {_id: String});
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
// let commentIds = [terms._id];
|
||||
// const childCommentIds = _.pluck(Comments.find({parentCommentId: terms._id}, {fields: {_id: 1}}).fetch(), '_id');
|
||||
// commentIds = commentIds.concat(childCommentIds);
|
||||
|
||||
|
||||
// return Users.canView(currentUser) ? Comments.find({_id: {$in: commentIds}}, {sort: {score: -1, postedAt: -1}}) : [];
|
||||
|
||||
// });
|
||||
|
@ -60,7 +61,7 @@ Meteor.publish('comments.list', function (terms) {
|
|||
|
||||
// check(commentId, String);
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
// if(Users.canViewById(this.userId)){
|
||||
// var comment = Comments.findOne(commentId);
|
||||
|
@ -75,8 +76,8 @@ Meteor.publish('comments.list', function (terms) {
|
|||
|
||||
// check(commentId, String);
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
// var userIds = [];
|
||||
|
||||
// if(Users.canViewById(this.userId)){
|
||||
|
@ -92,11 +93,11 @@ Meteor.publish('comments.list', function (terms) {
|
|||
// }
|
||||
|
||||
// return Users.find({_id: {$in: userIds}}, {fields: Users.pubsub.publicProperties});
|
||||
|
||||
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// return [];
|
||||
|
||||
// });
|
||||
// });
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
// import Telescope from 'meteor/nova:lib';
|
||||
|
||||
/**
|
||||
* @summary Update an item's (post or comment) score
|
||||
|
@ -7,6 +7,8 @@ import Telescope from 'meteor/nova:lib';
|
|||
* @param {object} collection - The collection the item belongs to
|
||||
* @param {string} operation - The operation being performed
|
||||
*/
|
||||
|
||||
/*
|
||||
function updateScore (item, user, collection, operation) {
|
||||
Telescope.updateScore({collection: collection, item: item, forceUpdate: true});
|
||||
}
|
||||
|
@ -14,6 +16,7 @@ Telescope.callbacks.add("upvote.async", updateScore);
|
|||
Telescope.callbacks.add("downvote.async", updateScore);
|
||||
Telescope.callbacks.add("cancelUpvote.async", updateScore);
|
||||
Telescope.callbacks.add("cancelDownvote.async", updateScore);
|
||||
*/
|
||||
|
||||
/**
|
||||
* @summary Update the profile of the user doing the operation
|
||||
|
@ -22,6 +25,8 @@ Telescope.callbacks.add("cancelDownvote.async", updateScore);
|
|||
* @param {object} collection - The collection the item belongs to
|
||||
* @param {string} operation - The operation being performed
|
||||
*/
|
||||
|
||||
/*
|
||||
function updateUser (item, user, collection, operation) {
|
||||
|
||||
var update = {};
|
||||
|
@ -39,10 +44,10 @@ function updateUser (item, user, collection, operation) {
|
|||
case "downvote":
|
||||
update.$addToSet = {'telescope.downvotedPosts': vote};
|
||||
break;
|
||||
case "cancelUpvote":
|
||||
case "cancelUpvote":
|
||||
update.$pull = {'telescope.upvotedPosts': {itemId: item._id}};
|
||||
break;
|
||||
case "cancelDownvote":
|
||||
case "cancelDownvote":
|
||||
update.$pull = {'telescope.downvotedPosts': {itemId: item._id}};
|
||||
break;
|
||||
}
|
||||
|
@ -54,6 +59,7 @@ Telescope.callbacks.add("upvote.async", updateUser);
|
|||
Telescope.callbacks.add("downvote.async", updateUser);
|
||||
Telescope.callbacks.add("cancelUpvote.async", updateUser);
|
||||
Telescope.callbacks.add("cancelDownvote.async", updateUser);
|
||||
*/
|
||||
|
||||
/**
|
||||
* @summary Update the karma of the item's owner
|
||||
|
@ -62,11 +68,13 @@ Telescope.callbacks.add("cancelDownvote.async", updateUser);
|
|||
* @param {object} collection - The collection the item belongs to
|
||||
* @param {string} operation - The operation being performed
|
||||
*/
|
||||
|
||||
/*
|
||||
function updateKarma (item, user, collection, operation) {
|
||||
|
||||
var votePower = Telescope.getVotePower(user);
|
||||
var karmaAmount = (operation === "upvote" || operation === "cancelDownvote") ? votePower : -votePower;
|
||||
|
||||
|
||||
// only update karma is the operation isn't done by the item's author
|
||||
if (item.userId !== user._id) {
|
||||
Users.update({_id: item.userId}, {$inc: {"telescope.karma": karmaAmount}});
|
||||
|
@ -76,4 +84,5 @@ function updateKarma (item, user, collection, operation) {
|
|||
Telescope.callbacks.add("upvote.async", updateKarma);
|
||||
Telescope.callbacks.add("downvote.async", updateKarma);
|
||||
Telescope.callbacks.add("cancelUpvote.async", updateKarma);
|
||||
Telescope.callbacks.add("cancelDownvote.async", updateKarma);
|
||||
Telescope.callbacks.add("cancelDownvote.async", updateKarma);
|
||||
*/
|
||||
|
|
|
@ -48,7 +48,7 @@ class ModalTrigger extends Component {
|
|||
<Modal bsSize={this.props.size} show={this.state.modalIsOpen} onHide={this.closeModal}>
|
||||
{this.props.title ? this.renderHeader() : null}
|
||||
<Modal.Body>
|
||||
<ContextPasser
|
||||
<ContextPasser
|
||||
currentUser={this.context.currentUser}
|
||||
actions={this.context.actions}
|
||||
events={this.context.events}
|
||||
|
@ -62,7 +62,7 @@ class ModalTrigger extends Component {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ModalTrigger.propTypes = {
|
||||
component: React.PropTypes.object.isRequired,
|
||||
|
@ -86,4 +86,4 @@ ModalTrigger.contextTypes = {
|
|||
// }
|
||||
|
||||
module.exports = ModalTrigger;
|
||||
export default ModalTrigger;
|
||||
export default ModalTrigger;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import {Inject} from 'meteor/meteorhacks:inject-initial';
|
||||
import Events from "meteor/nova:events";
|
||||
import { Inject } from 'meteor/meteorhacks:inject-initial';
|
||||
import { SyncedCron } from 'meteor/percolatestudio:synced-cron';
|
||||
|
||||
Meteor.startup(function () {
|
||||
Events.log({
|
||||
|
@ -20,4 +21,4 @@ Meteor.startup(function() {
|
|||
}
|
||||
});
|
||||
|
||||
Inject.obj('serverTimezoneOffset', {offset: new Date().getTimezoneOffset()});
|
||||
Inject.obj('serverTimezoneOffset', {offset: new Date().getTimezoneOffset()});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import Posts from "meteor/nova:posts";
|
||||
import Comments from "meteor/nova:comments";
|
||||
// import Posts from "meteor/nova:posts";
|
||||
// import Comments from "meteor/nova:comments";
|
||||
import Users from 'meteor/nova:users';
|
||||
|
||||
const Group = ({name, actions}) => {
|
||||
|
@ -32,11 +32,11 @@ const Groups = props => {
|
|||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
module.exports = Groups
|
||||
export default Groups
|
||||
export default Groups
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint-disable no-undef */
|
||||
|
||||
import TelescopeImport from 'meteor/nova:lib';
|
||||
import PostsImport from "meteor/nova:posts";
|
||||
import CommentsImport from "meteor/nova:comments";
|
||||
|
|
|
@ -4,14 +4,14 @@ import Users from 'meteor/nova:users';
|
|||
|
||||
Meteor.methods({
|
||||
"email.test": function (emailName) {
|
||||
|
||||
|
||||
const email = NovaEmail.emails[emailName];
|
||||
|
||||
|
||||
if(Users.isAdminById(this.userId)){
|
||||
|
||||
console.log("// testing email ["+emailName+"]");
|
||||
console.log("// testing email ["+emailName+"]"); // eslint-disable-line
|
||||
let html, properties;
|
||||
|
||||
|
||||
// if email has a custom way of generating its HTML, use it
|
||||
if (typeof email.getTestHTML !== "undefined") {
|
||||
|
||||
|
@ -33,11 +33,11 @@ Meteor.methods({
|
|||
const subject = "[Test] " + email.subject.bind(email)(properties);
|
||||
|
||||
NovaEmail.send (Telescope.settings.get('defaultEmail'), subject, html)
|
||||
|
||||
|
||||
return subject;
|
||||
|
||||
|
||||
} else {
|
||||
throw new Meteor.Error("must_be_admin", "You must be an admin to send test emails");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
/* global Movies:true */
|
||||
|
||||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import {mount} from 'react-mounter';
|
||||
import MoviesWrapper from './demo-components.jsx';
|
||||
import Core from 'meteor/nova:core';
|
||||
import { Route } from 'react-router';
|
||||
import Users from 'meteor/nova:users';
|
||||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import MoviesWrapper from './demo-components.jsx';
|
||||
// import {mount} from 'react-mounter';
|
||||
// import Core from 'meteor/nova:core';
|
||||
// import { Route } from 'react-router';
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Collection & Schema //
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
/* global Movies */
|
||||
|
||||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { ListContainer } from "meteor/utilities:react-list-container";
|
||||
import NovaForm from "meteor/nova:forms";
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { Accounts } from 'meteor/std:accounts-ui';
|
||||
import { ModalTrigger, Messages, FlashContainer } from "meteor/nova:core";
|
||||
import { ModalTrigger, /* Messages, */ FlashContainer } from "meteor/nova:core";
|
||||
|
||||
const FlashMessages = Telescope.components.FlashMessages;
|
||||
|
||||
|
@ -24,8 +26,8 @@ class MoviesWrapper extends Component {
|
|||
<FlashContainer component={FlashMessages}/>
|
||||
|
||||
<div className="main">
|
||||
<ListContainer
|
||||
collection={Movies}
|
||||
<ListContainer
|
||||
collection={Movies}
|
||||
publication="movies.list"
|
||||
terms={{options: {sort: {createdAt: -1}}}}
|
||||
options={{sort: {createdAt: -1}}}
|
||||
|
@ -48,23 +50,23 @@ class MoviesWrapper extends Component {
|
|||
class MoviesList extends Component {
|
||||
|
||||
renderNew() {
|
||||
|
||||
|
||||
const component = (
|
||||
<div className="add-movie">
|
||||
<ModalTrigger
|
||||
title="Add Movie"
|
||||
<ModalTrigger
|
||||
title="Add Movie"
|
||||
component={<Button bsStyle="primary">Add Movie</Button>}
|
||||
>
|
||||
<NovaForm
|
||||
collection={Movies}
|
||||
methodName="movies.create"
|
||||
<NovaForm
|
||||
collection={Movies}
|
||||
methodName="movies.create"
|
||||
currentUser={this.props.currentUser}
|
||||
/>
|
||||
</ModalTrigger>
|
||||
<hr/>
|
||||
</div>
|
||||
)
|
||||
|
||||
|
||||
return !!this.props.currentUser ? component : "";
|
||||
}
|
||||
|
||||
|
@ -78,7 +80,7 @@ class MoviesList extends Component {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Movie //
|
||||
|
@ -91,14 +93,14 @@ class Movie extends Component {
|
|||
const movie = this.props;
|
||||
|
||||
const component = (
|
||||
<ModalTrigger
|
||||
label="Edit Movie"
|
||||
component={<Button bsStyle="primary">Edit Movie</Button>}
|
||||
<ModalTrigger
|
||||
label="Edit Movie"
|
||||
component={<Button bsStyle="primary">Edit Movie</Button>}
|
||||
>
|
||||
<NovaForm
|
||||
collection={Movies}
|
||||
currentUser={this.props.currentUser}
|
||||
document={movie}
|
||||
<NovaForm
|
||||
collection={Movies}
|
||||
currentUser={this.props.currentUser}
|
||||
document={movie}
|
||||
methodName="movies.edit"
|
||||
/>
|
||||
</ModalTrigger>
|
||||
|
@ -112,7 +114,7 @@ class Movie extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
const movie = this.props;
|
||||
|
||||
return (
|
||||
|
@ -124,8 +126,8 @@ class Movie extends Component {
|
|||
)
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
const LoadMore = props => <a href="#" className="load-more button button--primary" onClick={props.loadMore}>Load More ({props.count}/{props.totalCount})</a>
|
||||
|
||||
export default MoviesWrapper
|
||||
export default MoviesWrapper
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { Picker } from 'meteor/meteorhacks:picker';
|
||||
|
||||
import NovaEmail from 'meteor/nova:email';
|
||||
|
||||
Meteor.startup(function () {
|
||||
|
@ -29,7 +31,7 @@ Meteor.startup(function () {
|
|||
|
||||
// return html
|
||||
res.end(html);
|
||||
|
||||
|
||||
});
|
||||
|
||||
// raw template
|
||||
|
@ -38,5 +40,5 @@ Meteor.startup(function () {
|
|||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -77,10 +77,10 @@ NovaEmail.send = function(to, subject, html, text){
|
|||
});
|
||||
}
|
||||
|
||||
console.log('//////// sending email…');
|
||||
console.log('from: '+from);
|
||||
console.log('to: '+to);
|
||||
console.log('subject: '+subject);
|
||||
console.log('//////// sending email…'); // eslint-disable-line
|
||||
console.log('from: '+from); // eslint-disable-line
|
||||
console.log('to: '+to); // eslint-disable-line
|
||||
console.log('subject: '+subject); // eslint-disable-line
|
||||
// console.log('html: '+html);
|
||||
// console.log('text: '+text);
|
||||
|
||||
|
@ -95,8 +95,8 @@ NovaEmail.send = function(to, subject, html, text){
|
|||
try {
|
||||
Email.send(email);
|
||||
} catch (error) {
|
||||
console.log("// error while sending email:")
|
||||
console.log(error)
|
||||
console.log("// error while sending email:"); // eslint-disable-line
|
||||
console.log(error); // eslint-disable-line
|
||||
}
|
||||
|
||||
return email;
|
||||
|
|
|
@ -24,16 +24,16 @@ class EmbedlyURL extends Component {
|
|||
|
||||
// the URL has changed, get a new thumbnail
|
||||
this.context.actions.call("getEmbedlyData", url, (error, result) => {
|
||||
|
||||
console.log("querying Embedly…");
|
||||
|
||||
|
||||
console.log("querying Embedly…"); // eslint-disable-line
|
||||
|
||||
this.setState({loading: false});
|
||||
|
||||
if (error) {
|
||||
console.log(error)
|
||||
console.log(error); // eslint-disable-line
|
||||
this.context.throwError({content: error.message, type: "error"});
|
||||
} else {
|
||||
console.log(result)
|
||||
console.log(result); // eslint-disable-line
|
||||
this.context.addToAutofilledValues({
|
||||
title: result.title,
|
||||
body: result.description,
|
||||
|
@ -46,7 +46,7 @@ class EmbedlyURL extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
const Loading = Telescope.components.Loading;
|
||||
|
||||
const wrapperStyle = {
|
||||
|
@ -61,16 +61,16 @@ class EmbedlyURL extends Component {
|
|||
};
|
||||
|
||||
loadingStyle.display = this.state.loading ? "block" : "none";
|
||||
|
||||
|
||||
// see https://facebook.github.io/react/warnings/unknown-prop.html
|
||||
const {document, updateCurrentValue, control, ...rest} = this.props;
|
||||
const {document, updateCurrentValue, control, ...rest} = this.props; // eslint-disable-line
|
||||
|
||||
return (
|
||||
<div className="embedly-url-field" style={wrapperStyle}>
|
||||
<Input
|
||||
<Input
|
||||
{...rest}
|
||||
onBlur={this.handleBlur}
|
||||
type="text"
|
||||
onBlur={this.handleBlur}
|
||||
type="text"
|
||||
ref={ref => this.input = ref}
|
||||
/>
|
||||
<div className="embedly-url-field-loading" style={loadingStyle}>
|
||||
|
@ -93,4 +93,4 @@ EmbedlyURL.contextTypes = {
|
|||
actions: React.PropTypes.object,
|
||||
}
|
||||
|
||||
export default EmbedlyURL;
|
||||
export default EmbedlyURL;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import Formsy from 'formsy-react';
|
||||
// import Formsy from 'formsy-react';
|
||||
import FRC from 'formsy-react-components';
|
||||
const Input = FRC.Input;
|
||||
|
||||
|
@ -29,9 +29,9 @@ class ThumbnailURL extends Component {
|
|||
renderThumbnail() {
|
||||
return (
|
||||
<div>
|
||||
<img
|
||||
className="embedly-thumbnail"
|
||||
src={this.props.value}
|
||||
<img
|
||||
className="embedly-thumbnail"
|
||||
src={this.props.value}
|
||||
style={{
|
||||
"width": 150,
|
||||
"height": Telescope.settings.get('thumbnailHeight', 150) * 150 / Telescope.settings.get('thumbnailWidth', 150)
|
||||
|
@ -44,7 +44,7 @@ class ThumbnailURL extends Component {
|
|||
|
||||
render() {
|
||||
|
||||
const {name, value, label} = this.props;
|
||||
const {name, /* value, */ label} = this.props;
|
||||
|
||||
const inputType = this.state.showInput ? "text" : "hidden";
|
||||
|
||||
|
@ -73,4 +73,4 @@ ThumbnailURL.contextTypes = {
|
|||
deleteValue: React.PropTypes.func
|
||||
}
|
||||
|
||||
export default ThumbnailURL;
|
||||
export default ThumbnailURL;
|
||||
|
|
|
@ -10,7 +10,7 @@ Telescope.callbacks.add("postClass", addThumbnailClass);
|
|||
function checkIfPreviouslyPosted (data) {
|
||||
Meteor.call("checkForDuplicates", data.url, function (error, result) {
|
||||
if (error) {
|
||||
Messages.flash(error.reason + '. <a href="'+FlowRouter.path("postPage", {_id: error.details})+'">'+"go_to_post"+'</a>');
|
||||
// Messages.flash(error.reason + '. <a href="'+FlowRouter.path("postPage", {_id: error.details})+'">'+"go_to_post"+'</a>');
|
||||
}
|
||||
});
|
||||
return data;
|
||||
|
|
|
@ -2,8 +2,8 @@ import Telescope from 'meteor/nova:lib';
|
|||
import Posts from "meteor/nova:posts";
|
||||
import Users from 'meteor/nova:users';
|
||||
|
||||
getEmbedlyData = function (url) {
|
||||
var data = {};
|
||||
var getEmbedlyData = function (url) {
|
||||
// var data = {};
|
||||
var extractBase = 'http://api.embed.ly/1/extract';
|
||||
var embedlyKey = Telescope.settings.get('embedlyKey');
|
||||
var thumbnailWidth = Telescope.settings.get('thumbnailWidth', 200);
|
||||
|
@ -11,7 +11,7 @@ getEmbedlyData = function (url) {
|
|||
|
||||
if(!embedlyKey) {
|
||||
// fail silently to still let the post be submitted as usual
|
||||
console.log("Couldn't find an Embedly API key! Please add it to your Telescope settings or remove the Embedly module.");
|
||||
console.log("Couldn't find an Embedly API key! Please add it to your Telescope settings or remove the Embedly module."); // eslint-disable-line
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ getEmbedlyData = function (url) {
|
|||
return embedlyData;
|
||||
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
console.log(error); // eslint-disable-line
|
||||
// the first 13 characters of the Embedly errors are "failed [400] ", so remove them and parse the rest
|
||||
var errorObject = JSON.parse(error.message.substring(13));
|
||||
throw new Meteor.Error(errorObject.error_code, errorObject.error_message);
|
||||
|
@ -111,7 +111,7 @@ var regenerateThumbnail = function (post) {
|
|||
Meteor.methods({
|
||||
testGetEmbedlyData: function (url) {
|
||||
check(url, String);
|
||||
console.log(getEmbedlyData(url));
|
||||
console.log(getEmbedlyData(url)); // eslint-disable-line
|
||||
},
|
||||
getEmbedlyData: function (url) {
|
||||
check(url, String);
|
||||
|
@ -129,11 +129,11 @@ Meteor.methods({
|
|||
generateThumbnails: function (limit = 20, mode = "generate") {
|
||||
// mode = "generate" : generate thumbnails only for all posts that don't have one
|
||||
// mode = "all" : regenerate thumbnais for all posts
|
||||
|
||||
|
||||
if (Users.isAdmin(Meteor.user())) {
|
||||
|
||||
console.log("// Generating thumbnails…")
|
||||
|
||||
|
||||
console.log("// Generating thumbnails…"); // eslint-disable-line
|
||||
|
||||
const selector = {url: {$exists: true}};
|
||||
if (mode === "generate") {
|
||||
selector.thumbnailUrl = {$exists: false};
|
||||
|
@ -143,11 +143,11 @@ Meteor.methods({
|
|||
|
||||
posts.forEach((post, index) => {
|
||||
Meteor.setTimeout(function () {
|
||||
console.log(`// ${index}. fetching thumbnail for “${post.title}” (_id: ${post._id})`);
|
||||
console.log(`// ${index}. fetching thumbnail for “${post.title}” (_id: ${post._id})`); // eslint-disable-line
|
||||
try {
|
||||
regenerateThumbnail(post);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.log(error); // eslint-disable-line
|
||||
}
|
||||
}, index * 1000);
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||
|
||||
const Events = new Mongo.Collection('events');
|
||||
|
||||
Events.schema = new SimpleSchema({
|
||||
|
@ -63,4 +65,4 @@ Events.track = function(event, properties){
|
|||
// }
|
||||
};
|
||||
|
||||
export default Events;
|
||||
export default Events;
|
||||
|
|
|
@ -31,7 +31,7 @@ class Tags extends Component {
|
|||
|
||||
const tags = this.state.tags;
|
||||
tags.splice(i, 1);
|
||||
|
||||
|
||||
const value = this.state.value;
|
||||
value.splice(i,1);
|
||||
|
||||
|
@ -42,7 +42,7 @@ class Tags extends Component {
|
|||
}
|
||||
|
||||
handleAddition(tag) {
|
||||
|
||||
|
||||
// first, check if added tag is part of the possible options
|
||||
const option = _.findWhere(this.props.options, {label: tag});
|
||||
|
||||
|
@ -69,14 +69,14 @@ class Tags extends Component {
|
|||
|
||||
render() {
|
||||
|
||||
const {name, value, label} = this.props;
|
||||
const {name, /* value, */ label} = this.props;
|
||||
|
||||
return (
|
||||
<div className="form-group row">
|
||||
<label className="control-label col-sm-3">{label}</label>
|
||||
<div className="col-sm-9">
|
||||
<div className="tags-field">
|
||||
<ReactTags
|
||||
<ReactTags
|
||||
tags={this.state.tags}
|
||||
suggestions={this.state.suggestions}
|
||||
handleDelete={this.handleDelete}
|
||||
|
@ -105,4 +105,4 @@ Tags.propTypes = {
|
|||
label: React.PropTypes.string
|
||||
}
|
||||
|
||||
export default Tags;
|
||||
export default Tags;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { PropTypes, Component } from 'react';
|
||||
import DateTimePicker from 'react-datetime';
|
||||
import moment from 'moment';
|
||||
// import moment from 'moment';
|
||||
|
||||
class DateTime extends Component {
|
||||
// when the datetime picker mounts, NovaForm will catch the date value (no formsy mixin in this component)
|
||||
|
@ -13,11 +13,11 @@ class DateTime extends Component {
|
|||
<div className="form-group row">
|
||||
<label className="control-label col-sm-3">{this.props.label}</label>
|
||||
<div className="col-sm-9">
|
||||
<DateTimePicker
|
||||
<DateTimePicker
|
||||
value={this.props.value || new Date()}
|
||||
// newDate argument is a Moment object given by react-datetime
|
||||
onChange={newDate => { this.context.addToAutofilledValues({[this.props.name]: newDate._d}) }}
|
||||
format={"x"}
|
||||
format={"x"}
|
||||
inputProps={{name: this.props.name}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@ import FRC from 'formsy-react-components';
|
|||
|
||||
import DateTime from './DateTime.jsx';
|
||||
|
||||
import Utils from './utils.js';
|
||||
// import Utils from './utils.js';
|
||||
|
||||
const Checkbox = FRC.Checkbox;
|
||||
// const CheckboxGroup = FRC.CheckboxGroup;
|
||||
|
@ -30,7 +30,7 @@ class FormComponent extends Component {
|
|||
renderComponent() {
|
||||
|
||||
// see https://facebook.github.io/react/warnings/unknown-prop.html
|
||||
const { control, group, updateCurrentValue, document, ...rest } = this.props;
|
||||
const { control, group, updateCurrentValue, document, ...rest } = this.props; // eslint-disable-line
|
||||
|
||||
const base = this.props.control === "function" ? this.props : rest;
|
||||
|
||||
|
@ -53,7 +53,7 @@ class FormComponent extends Component {
|
|||
case "textarea":
|
||||
return <Textarea {...properties} />;
|
||||
case "checkbox":
|
||||
return <Checkbox {...properties} />;
|
||||
return <Checkbox {...properties} />;
|
||||
// note: checkboxgroup cause React refs error
|
||||
case "checkboxgroup":
|
||||
return <CheckboxGroup {...properties} />;
|
||||
|
@ -63,7 +63,7 @@ class FormComponent extends Component {
|
|||
return <Select {...properties} />;
|
||||
case "datetime":
|
||||
return <DateTime {...properties} />;
|
||||
default:
|
||||
default:
|
||||
return <Input {...properties} type="text" />;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ FormComponent.propTypes = {
|
|||
label: React.PropTypes.string,
|
||||
value: React.PropTypes.any,
|
||||
placeholder: React.PropTypes.string,
|
||||
prefilledValue: React.PropTypes.any,
|
||||
prefilledValue: React.PropTypes.any,
|
||||
options: React.PropTypes.any,
|
||||
control: React.PropTypes.any,
|
||||
datatype: React.PropTypes.any,
|
||||
|
|
|
@ -85,7 +85,7 @@ class NovaForm extends Component{
|
|||
// backward compatibility from 'autoform' to 'form'
|
||||
if (fieldSchema.autoform) {
|
||||
fieldSchema.form = fieldSchema.autoform;
|
||||
console.warn(`🔭 Telescope Nova Warning: The 'autoform' field is deprecated. You should rename it to 'form' instead. It was defined on your '${fieldName}' field on the '${this.props.collection._name}' collection`);
|
||||
console.warn(`🔭 Telescope Nova Warning: The 'autoform' field is deprecated. You should rename it to 'form' instead. It was defined on your '${fieldName}' field on the '${this.props.collection._name}' collection`); // eslint-disable-line
|
||||
}
|
||||
|
||||
// replace value by prefilled value if value is empty
|
||||
|
@ -96,7 +96,7 @@ class NovaForm extends Component{
|
|||
field.value = prefilledValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// replace empty value, which has not been prefilled, by the default value from the schema
|
||||
if (fieldSchema.defaultValue && field.value === "") {
|
||||
field.value = fieldSchema.defaultValue;
|
||||
|
@ -291,7 +291,7 @@ class NovaForm extends Component{
|
|||
|
||||
this.setState({disabled: false});
|
||||
|
||||
console.log(error);
|
||||
console.log(error); // eslint-disable-line
|
||||
|
||||
const errorContent = this.context.intl.formatMessage({id: error.reason}, {details: error.details})
|
||||
// add error to state
|
||||
|
@ -326,7 +326,7 @@ class NovaForm extends Component{
|
|||
|
||||
// complete the data with values from custom components which are not being catched by Formsy mixin
|
||||
// note: it follows the same logic as NovaForm's getDocument method
|
||||
data = {
|
||||
data = {
|
||||
...this.state.autofilledValues, // ex: can be values from EmbedlyURL or NewsletterSubscribe component
|
||||
...data, // original data generated thanks to Formsy
|
||||
...this.state.currentValues, // ex: can be values from DateTime component
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint-disable react/display-name */
|
||||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
@ -156,4 +158,4 @@ module.exports = {
|
|||
}
|
||||
return (this.isValid() === false);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||
|
||||
if (typeof SimpleSchema !== "undefined") {
|
||||
SimpleSchema.extendOptions({
|
||||
control: Match.Optional(Match.Any), // NovaForm control (String or React component)
|
||||
|
|
|
@ -92,7 +92,7 @@ var createDummyComments = function () {
|
|||
|
||||
};
|
||||
|
||||
deleteDummyContent = function () {
|
||||
var deleteDummyContent = function () {
|
||||
Users.remove({'profile.isDummy': true});
|
||||
Posts.remove({isDummy: true});
|
||||
Comments.remove({isDummy: true});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global InjectData */
|
||||
|
||||
Meteor.startup(function() {
|
||||
var dom = $('script[type="text/inject-data"]', document);
|
||||
var injectedDataString = $.trim(dom.text());
|
||||
|
@ -8,4 +10,4 @@ InjectData.getData = function(key, callback) {
|
|||
Meteor.startup(function() {
|
||||
callback(InjectData._data[key]);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
InjectData = {};
|
||||
/* eslint-disable */
|
||||
|
||||
InjectData = {};
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
var http = Npm.require('http');
|
||||
/* global InjectData */
|
||||
|
||||
// var http = Npm.require('http');
|
||||
|
||||
var templateText = Assets.getText('lib/inject.html');
|
||||
var injectDataTemplate = _.template(templateText);
|
||||
|
@ -43,7 +45,7 @@ InjectData._hijackWriteIfNeeded = function(res) {
|
|||
'warn: injecting data turned off due to CORS headers. ' +
|
||||
'read more: http://goo.gl/eGwb4e';
|
||||
|
||||
console.warn(warnMessage);
|
||||
console.warn(warnMessage); // eslint-disable-line
|
||||
originalWrite.call(res, chunk, encoding);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global InjectData */
|
||||
|
||||
InjectData._encode = function(ejson) {
|
||||
var ejsonString = EJSON.stringify(ejson);
|
||||
return encodeURIComponent(ejsonString);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
var fs = Npm.require('fs');
|
||||
var path = Npm.require('path');
|
||||
// var fs = Npm.require('fs');
|
||||
// var path = Npm.require('path');
|
||||
|
||||
// We use this patch to avoid data injection failure during server-side rendering on Meteor 1.4
|
||||
// All the credits for this package goes to Arunoda, Kadira's team & @rigconfig
|
||||
// see https://github.com/meteor/meteor/issues/7992
|
||||
// see https://github.com/meteor/meteor/issues/7992
|
||||
|
||||
Package.describe({
|
||||
"summary": "A way to inject data to the client with initial HTML",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import { Kadira } from 'meteor/meteorhacks:kadira';
|
||||
|
||||
Meteor.startup(function() {
|
||||
if(process.env.NODE_ENV === "production" && !!Telescope.settings.get('kadiraAppId') && !!Telescope.settings.get('kadiraAppSecret')){
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Telescope from './config.js';
|
||||
import moment from 'moment';
|
||||
// import moment from 'moment';
|
||||
|
||||
/**
|
||||
* @summary Callback hooks provide an easy way to add extra steps to common operations.
|
||||
* @summary Callback hooks provide an easy way to add extra steps to common operations.
|
||||
* @namespace Telescope.callbacks
|
||||
*/
|
||||
Telescope.callbacks = {};
|
||||
|
@ -95,7 +95,7 @@ Telescope.callbacks.runAsync = function () {
|
|||
callback.apply(this, args);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||
import Telescope from './config.js';
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||
|
||||
/**
|
||||
* @summary Kick off the global namespace for Telescope.
|
||||
* @namespace Telescope
|
||||
*/
|
||||
|
||||
Telescope = {};
|
||||
const Telescope = {};
|
||||
|
||||
Telescope.VERSION = '0.27.4-nova';
|
||||
|
||||
|
@ -106,4 +108,4 @@ Telescope.statuses = [
|
|||
}
|
||||
];
|
||||
|
||||
export default Telescope;
|
||||
export default Telescope;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable */
|
||||
// see https://gist.github.com/furf/3208381
|
||||
|
||||
_.mixin({
|
||||
|
|
|
@ -60,7 +60,7 @@ Telescope.utils.camelCaseify = function(str) {
|
|||
* @param {Number} numWords - Number of words to trim sentence to.
|
||||
*/
|
||||
Telescope.utils.trimWords = function(s, numWords) {
|
||||
|
||||
|
||||
if (!s)
|
||||
return s;
|
||||
|
||||
|
@ -89,7 +89,7 @@ Telescope.utils.capitalise = function(str) {
|
|||
|
||||
Telescope.utils.t = function(message) {
|
||||
var d = new Date();
|
||||
console.log("### "+message+" rendered at "+d.getHours()+":"+d.getMinutes()+":"+d.getSeconds());
|
||||
console.log("### "+message+" rendered at "+d.getHours()+":"+d.getMinutes()+":"+d.getSeconds()); // eslint-disable-line
|
||||
};
|
||||
|
||||
Telescope.utils.nl2br = function(str) {
|
||||
|
@ -147,7 +147,7 @@ Telescope.utils.slugify = function (s) {
|
|||
Telescope.utils.getUnusedSlug = function (collection, slug) {
|
||||
let suffix = "";
|
||||
let index = 0;
|
||||
|
||||
|
||||
// handle edge case for Users collection
|
||||
const field = collection._name === 'users' ? 'telescope.slug' : 'slug';
|
||||
|
||||
|
@ -239,7 +239,7 @@ Telescope.utils.checkNested = function(obj /*, level1, level2, ... levelN*/) {
|
|||
|
||||
Telescope.log = function (s) {
|
||||
if(Telescope.settings.get('debug', false) || process.env.NODE_ENV === "development") {
|
||||
console.log(s);
|
||||
console.log(s); // eslint-disable-line
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -313,4 +313,4 @@ Telescope.utils.getLogoUrl = () => {
|
|||
// the logo may be hosted on another website
|
||||
return logoUrl.indexOf('://') > -1 ? logoUrl : prefix + logoUrl;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,10 +5,10 @@ import Users from 'meteor/nova:users';
|
|||
function subscribeUserOnProfileCompletion (user) {
|
||||
if (!!Telescope.settings.get('autoSubscribe') && !!Users.getEmail(user)) {
|
||||
MailChimpList.add(user, false, function (error, result) {
|
||||
console.log(error);
|
||||
console.log(result);
|
||||
console.log(error); // eslint-disable-line
|
||||
console.log(result); // eslint-disable-line
|
||||
});
|
||||
}
|
||||
return user;
|
||||
}
|
||||
Telescope.callbacks.add("users.profileCompleted.async", subscribeUserOnProfileCompletion);
|
||||
Telescope.callbacks.add("users.profileCompleted.async", subscribeUserOnProfileCompletion);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Newsletter from '../namespace.js';
|
||||
import { SyncedCron } from 'meteor/percolatestudio:synced-cron';
|
||||
import moment from 'moment';
|
||||
import Newsletter from '../namespace.js';
|
||||
|
||||
const defaultFrequency = [1]; // every monday
|
||||
const defaultTime = '00:00'; // GMT
|
||||
|
@ -45,7 +46,7 @@ var getSchedule = function (parser) {
|
|||
Meteor.methods({
|
||||
getNextJob: function () {
|
||||
var nextJob = SyncedCron.nextScheduledAtDate('scheduleNewsletter');
|
||||
console.log(nextJob);
|
||||
console.log(nextJob); // eslint-disable-line
|
||||
return nextJob;
|
||||
}
|
||||
});
|
||||
|
@ -60,8 +61,8 @@ var addJob = function () {
|
|||
job: function() {
|
||||
// only schedule newsletter campaigns in production
|
||||
if (process.env.NODE_ENV === "production" || Telescope.settings.get("enableNewsletterInDev", false)) {
|
||||
console.log("// Scheduling newsletter…")
|
||||
console.log(new Date());
|
||||
console.log("// Scheduling newsletter…"); // eslint-disable-line
|
||||
console.log(new Date()); // eslint-disable-line
|
||||
Newsletter.scheduleNextWithMailChimp();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ const MailChimp = function ( apiKey, options ) {
|
|||
|
||||
if ( !mailChimpOptions.apiKey || mailChimpOptions.apiKey === '' ) {
|
||||
|
||||
console.error( '[MailChimp] Error: No API Key defined!' );
|
||||
console.error( '[MailChimp] Error: No API Key defined!' ); // eslint-disable-line
|
||||
|
||||
throw new Meteor.Error(
|
||||
'No API Key',
|
||||
|
@ -89,4 +89,4 @@ MailChimp.prototype.call = function ( section, method, options, callback ) {
|
|||
// }
|
||||
// });
|
||||
|
||||
export default MailChimp;
|
||||
export default MailChimp;
|
||||
|
|
|
@ -30,7 +30,7 @@ MailChimpList.add = function(userOrEmail, confirm, done){
|
|||
|
||||
try {
|
||||
|
||||
console.log('// Adding "'+email+'" to MailChimp list…');
|
||||
console.log('// Adding "'+email+'" to MailChimp list…'); // eslint-disable-line
|
||||
|
||||
var api = new MailChimp(apiKey);
|
||||
var subscribeOptions = {
|
||||
|
@ -47,7 +47,7 @@ MailChimpList.add = function(userOrEmail, confirm, done){
|
|||
Users.methods.setSetting(user._id, 'newsletter.subscribed', true);
|
||||
}
|
||||
|
||||
console.log("// User subscribed");
|
||||
console.log("// User subscribed"); // eslint-disable-line
|
||||
|
||||
return subscribe;
|
||||
|
||||
|
@ -55,7 +55,7 @@ MailChimpList.add = function(userOrEmail, confirm, done){
|
|||
throw new Meteor.Error("subscription-failed", error.message);
|
||||
}
|
||||
} else {
|
||||
throw new Meteor.Error("Please provide your MailChimp API key and list ID", error.message);
|
||||
throw new Meteor.Error("Please provide your MailChimp API key and list ID");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -74,7 +74,7 @@ MailChimpList.remove = (user) => {
|
|||
|
||||
try {
|
||||
|
||||
console.log('// Removing "'+email+'" from MailChimp list…');
|
||||
console.log('// Removing "'+email+'" from MailChimp list…'); // eslint-disable-line
|
||||
|
||||
var api = new MailChimp(apiKey);
|
||||
var subscribeOptions = {
|
||||
|
@ -89,7 +89,7 @@ MailChimpList.remove = (user) => {
|
|||
// mark user as unsubscribed
|
||||
Users.methods.setSetting(user._id, 'newsletter.subscribed', false);
|
||||
|
||||
console.log("// User unsubscribed");
|
||||
console.log("// User unsubscribed"); // eslint-disable-line
|
||||
|
||||
return subscribe;
|
||||
|
||||
|
@ -97,7 +97,7 @@ MailChimpList.remove = (user) => {
|
|||
throw new Meteor.Error("unsubscription-failed", error.message);
|
||||
}
|
||||
} else {
|
||||
throw new Meteor.Error("Please provide your MailChimp API key and list ID", error.message);
|
||||
throw new Meteor.Error("Please provide your MailChimp API key and list ID");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
/* eslint-disable no-console */
|
||||
|
||||
// newsletter scheduling with MailChimp
|
||||
|
||||
import Telescope from 'meteor/nova:lib';
|
||||
import Newsletter from '../../namespace.js';
|
||||
import MailChimp from './mailchimp_api.js';
|
||||
import Posts from 'meteor/nova:posts';
|
||||
import NovaEmail from 'meteor/nova:email';
|
||||
import htmlToText from 'html-to-text';
|
||||
import moment from 'moment';
|
||||
import Newsletter from '../../namespace.js';
|
||||
import MailChimp from './mailchimp_api.js';
|
||||
|
||||
const defaultPosts = 5;
|
||||
|
||||
|
@ -68,14 +71,14 @@ Newsletter.scheduleWithMailChimp = function (campaign, isTest = false) {
|
|||
};
|
||||
|
||||
// schedule campaign
|
||||
var schedule = api.call('campaigns', 'schedule', scheduleOptions);
|
||||
var schedule = api.call('campaigns', 'schedule', scheduleOptions); // eslint-disable-line
|
||||
|
||||
console.log('// Newsletter scheduled for '+scheduledTime);
|
||||
// console.log(schedule)
|
||||
|
||||
// if this is not a test, mark posts as sent
|
||||
if (!isTest)
|
||||
var updated = Posts.update({_id: {$in: campaign.postIds}}, {$set: {scheduledAt: new Date()}}, {multi: true})
|
||||
var updated = Posts.update({_id: {$in: campaign.postIds}}, {$set: {scheduledAt: new Date()}}, {multi: true}) // eslint-disable-line
|
||||
|
||||
// send confirmation email
|
||||
var confirmationHtml = NovaEmail.getTemplate('newsletterConfirmation')({
|
||||
|
@ -90,4 +93,4 @@ Newsletter.scheduleWithMailChimp = function (campaign, isTest = false) {
|
|||
}
|
||||
return subject;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import moment from 'moment';
|
||||
import Posts from "meteor/nova:posts";
|
||||
import Comments from "meteor/nova:comments";
|
||||
import Users from 'meteor/nova:users';
|
||||
import Categories from "meteor/nova:categories";
|
||||
import NovaEmail from 'meteor/nova:email';
|
||||
import { SyncedCron } from 'meteor/percolatestudio:synced-cron';
|
||||
import moment from 'moment';
|
||||
import Newsletter from '../namespace.js';
|
||||
|
||||
// create new "newsletter" view for all posts from the past X days that haven't been scheduled yet
|
||||
|
@ -14,7 +15,7 @@ Posts.views.add("newsletter", function (terms) {
|
|||
scheduledAt: {$exists: false}
|
||||
},
|
||||
options: {
|
||||
sort: {baseScore: -1},
|
||||
sort: {baseScore: -1},
|
||||
limit: terms.limit
|
||||
}
|
||||
};
|
||||
|
@ -32,14 +33,14 @@ Newsletter.getPosts = function (postsCount) {
|
|||
// if there is a last newsletter and it was sent less than 7 days ago use its date, else default to posts from the last 7 days
|
||||
var lastWeek = moment().subtract(7, 'days');
|
||||
var after = (lastNewsletter && moment(lastNewsletter.finishedAt).isAfter(lastWeek)) ? lastNewsletter.finishedAt : lastWeek.format("YYYY-MM-DD");
|
||||
|
||||
|
||||
// get parameters using "newsletter" view
|
||||
var params = Posts.parameters.get({
|
||||
view: "newsletter",
|
||||
after: after,
|
||||
limit: postsCount
|
||||
});
|
||||
|
||||
|
||||
return Posts.find(params.selector, params.options).fetch();
|
||||
};
|
||||
|
||||
|
@ -91,7 +92,7 @@ Newsletter.build = function (postsArray) {
|
|||
|
||||
// get the two highest-scoring comments
|
||||
properties.popularComments = Comments.find({postId: post._id}, {sort: {score: -1}, limit: 2, transform: function (comment) {
|
||||
|
||||
|
||||
// get comment author
|
||||
var user = Users.findOne(comment.userId);
|
||||
|
||||
|
@ -105,7 +106,7 @@ Newsletter.build = function (postsArray) {
|
|||
} catch (error) {
|
||||
comment.authorAvatarUrl = false;
|
||||
}
|
||||
|
||||
|
||||
return comment;
|
||||
|
||||
}}).fetch();
|
||||
|
@ -151,13 +152,13 @@ Newsletter.build = function (postsArray) {
|
|||
var emailHTML = NovaEmail.buildTemplate(newsletterHTML, {
|
||||
date: moment().format("dddd, MMMM D YYYY")
|
||||
});
|
||||
|
||||
|
||||
// 4. build campaign object and return it
|
||||
var campaign = {
|
||||
postIds: _.pluck(postsArray, '_id'),
|
||||
subject: Telescope.utils.trimWords(subject, 15),
|
||||
html: emailHTML
|
||||
};
|
||||
|
||||
|
||||
return campaign;
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@ Telescope.notifications.create = (userIds, notificationName, data) => {
|
|||
if (!!userEmail) {
|
||||
NovaEmail.buildAndSendHTML(Users.getEmail(user), subject, html);
|
||||
} else {
|
||||
console.log(`// Couldn't send notification: admin user ${user._id} doesn't have an email`);
|
||||
console.log(`// Couldn't send notification: admin user ${user._id} doesn't have an email`); // eslint-disable-line
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -360,7 +360,7 @@ Telescope.callbacks.add("posts.edit.sync", PostsEditSetPostedAt);
|
|||
// ------------------------------------- posts.edit.async -------------------------------- //
|
||||
|
||||
function PostsEditRunPostApprovedCallbacks (post, oldPost) {
|
||||
var now = new Date();
|
||||
// var now = new Date();
|
||||
|
||||
if (Posts.isApproved(post) && !Posts.isApproved(oldPost)) {
|
||||
Telescope.callbacks.runAsync("posts.approve.async", post);
|
||||
|
@ -388,7 +388,7 @@ Telescope.callbacks.add("posts.approve.async", PostsApprovedNotification);
|
|||
|
||||
function UsersRemoveDeletePosts (user, options) {
|
||||
if (options && options.deletePosts) {
|
||||
Posts.remove({userId: userId});
|
||||
Posts.remove({userId: user._id});
|
||||
} else {
|
||||
// not sure if anything should be done in that scenario yet
|
||||
// Posts.update({userId: userId}, {$set: {author: "\[deleted\]"}}, {multi: true});
|
||||
|
|
|
@ -4,16 +4,16 @@ const returnEmptyObject = function () {
|
|||
return {};
|
||||
}
|
||||
|
||||
console.log(Mongo)
|
||||
console.log(Mongo); // eslint-disable-line
|
||||
|
||||
const Mongo = typeof Mongo !== "undefined" ? Mongo : {
|
||||
const Mongo = typeof Mongo !== "undefined" ? Mongo : {
|
||||
Collection: function () {
|
||||
return {attachSchema: returnEmptyObject}
|
||||
}
|
||||
};
|
||||
|
||||
console.log("// Mongo")
|
||||
console.log(Mongo)
|
||||
console.log("// Mongo"); // eslint-disable-line
|
||||
console.log(Mongo); // eslint-disable-line
|
||||
|
||||
const Meteor = typeof Meteor !== "undefined" ? Meteor : {
|
||||
methods: returnEmptyObject
|
||||
|
@ -22,4 +22,4 @@ const Meteor = typeof Meteor !== "undefined" ? Meteor : {
|
|||
const SimpleSchema = typeof SimpleSchema !== "undefined" ? SimpleSchema : returnEmptyObject;
|
||||
|
||||
const Foo = "bar"
|
||||
export { Mongo, Foo }
|
||||
export { Mongo, Foo }
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Posts from './collection.js'
|
||||
import Users from 'meteor/nova:users';
|
||||
import Events from "meteor/nova:events";
|
||||
import Events from 'meteor/nova:events';
|
||||
import { Messages } from 'meteor/nova:core';
|
||||
import Posts from './collection.js'
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -113,7 +114,7 @@ Meteor.methods({
|
|||
* @param {Object} modifier - the update modifier
|
||||
*/
|
||||
'posts.edit': function (postId, modifier) {
|
||||
|
||||
|
||||
Posts.simpleSchema().namedContext("posts.edit").validate(modifier, {modifier: true});
|
||||
check(postId, String);
|
||||
|
||||
|
@ -134,7 +135,7 @@ Meteor.methods({
|
|||
'posts.approve': function(postId){
|
||||
|
||||
check(postId, String);
|
||||
|
||||
|
||||
const post = Posts.findOne(postId);
|
||||
const now = new Date();
|
||||
|
||||
|
@ -145,7 +146,7 @@ Meteor.methods({
|
|||
if (!post.postedAt) {
|
||||
set.postedAt = now;
|
||||
}
|
||||
|
||||
|
||||
Posts.update(post._id, {$set: set});
|
||||
|
||||
Telescope.callbacks.runAsync("posts.approve.async", post);
|
||||
|
@ -164,15 +165,15 @@ Meteor.methods({
|
|||
'posts.reject': function(postId){
|
||||
|
||||
check(postId, String);
|
||||
|
||||
|
||||
const post = Posts.findOne(postId);
|
||||
|
||||
|
||||
if(Users.isAdmin(Meteor.user())){
|
||||
|
||||
Posts.update(post._id, {$set: {status: Posts.config.STATUS_REJECTED}});
|
||||
|
||||
Telescope.callbacks.runAsync("postRejectAsync", post);
|
||||
|
||||
|
||||
}else{
|
||||
Messages.flash('You need to be an admin to do that.', "error");
|
||||
}
|
||||
|
@ -188,7 +189,7 @@ Meteor.methods({
|
|||
|
||||
check(postId, String);
|
||||
check(sessionId, Match.Any);
|
||||
|
||||
|
||||
// only let users increment a post's view counter once per session
|
||||
var view = {_id: postId, userId: this.userId, sessionId: sessionId};
|
||||
|
||||
|
@ -237,7 +238,7 @@ Meteor.methods({
|
|||
* @param {String} url - the URL to check
|
||||
*/
|
||||
'posts.checkForDuplicates': function (url) {
|
||||
Posts.checkForSameUrl(url);
|
||||
Posts.checkForSameUrl(url);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Posts from './collection.js'
|
||||
import { Injected } from 'meteor/meteorhacks:inject-initial';
|
||||
import moment from 'moment';
|
||||
import Posts from './collection.js'
|
||||
|
||||
/**
|
||||
* @summary Parameter callbacks let you add parameters to subscriptions
|
||||
* @summary Parameter callbacks let you add parameters to subscriptions
|
||||
* @namespace Posts.parameters
|
||||
*/
|
||||
Posts.parameters = {};
|
||||
|
@ -32,25 +33,25 @@ Posts.parameters.get = function (terms) {
|
|||
|
||||
// iterate over posts.parameters callbacks
|
||||
parameters = Telescope.callbacks.run("posts.parameters", parameters, _.clone(terms));
|
||||
|
||||
|
||||
// if sort options are not provided, default to "createdAt" sort
|
||||
if (_.isEmpty(parameters.options.sort)) {
|
||||
parameters.options.sort = {sticky: -1, createdAt: -1};
|
||||
}
|
||||
|
||||
|
||||
// extend sort to sort posts by _id to break ties
|
||||
// NOTE: always do this last to avoid _id sort overriding another sort
|
||||
parameters = Telescope.utils.deepExtend(true, parameters, {options: {sort: {_id: -1}}});
|
||||
|
||||
// console.log(parameters);
|
||||
|
||||
|
||||
return parameters;
|
||||
};
|
||||
|
||||
// Parameter callbacks
|
||||
|
||||
// View Parameter
|
||||
// Add a "view" property to terms which can be used to filter posts.
|
||||
// Add a "view" property to terms which can be used to filter posts.
|
||||
function addViewParameter (parameters, terms) {
|
||||
|
||||
// if view is not defined, default to "new"
|
||||
|
@ -65,25 +66,25 @@ function addViewParameter (parameters, terms) {
|
|||
Telescope.callbacks.add("posts.parameters", addViewParameter);
|
||||
|
||||
// View Parameter
|
||||
// Add "after" and "before" properties to terms which can be used to limit posts in time.
|
||||
// Add "after" and "before" properties to terms which can be used to limit posts in time.
|
||||
function addTimeParameter (parameters, terms) {
|
||||
|
||||
// console.log("// addTimeParameter")
|
||||
|
||||
if (typeof parameters.selector.postedAt === "undefined") {
|
||||
|
||||
|
||||
let postedAt = {}, mAfter, mBefore, startOfDay, endOfDay, clientTimezoneOffset, serverTimezoneOffset, timeDifference;
|
||||
|
||||
/*
|
||||
/*
|
||||
|
||||
If we're on the client, add the time difference between client and server
|
||||
|
||||
Example: client is on Japanese time (+9 hours),
|
||||
|
||||
Example: client is on Japanese time (+9 hours),
|
||||
server on UCT (Greenwich) time (+0 hours), for a total difference of +9 hours.
|
||||
|
||||
So the time "00:00, UCT" is equivalent to "09:00, JST".
|
||||
|
||||
So if we want to express the timestamp "00:00, UCT" on the client,
|
||||
So if we want to express the timestamp "00:00, UCT" on the client,
|
||||
we *add* 9 hours to "00:00, JST" on the client to get "09:00, JST" and
|
||||
sync up both times.
|
||||
|
||||
|
@ -93,7 +94,7 @@ function addTimeParameter (parameters, terms) {
|
|||
clientTimezoneOffset = -1 * new Date().getTimezoneOffset();
|
||||
serverTimezoneOffset = -1 * Injected.obj('serverTimezoneOffset').offset;
|
||||
timeDifference = clientTimezoneOffset - serverTimezoneOffset;
|
||||
|
||||
|
||||
// console.log("client time:"+clientTimezoneOffset);
|
||||
// console.log("server time:"+serverTimezoneOffset);
|
||||
// console.log("difference: "+timeDifference);
|
||||
|
@ -127,7 +128,7 @@ function addTimeParameter (parameters, terms) {
|
|||
}
|
||||
|
||||
postedAt.$lt = endOfDay.toDate();
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (!_.isEmpty(postedAt)) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Posts from './collection.js';
|
||||
import Users from 'meteor/nova:users';
|
||||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||
import Posts from './collection.js';
|
||||
|
||||
/**
|
||||
* @summary Posts config namespace
|
||||
|
@ -235,7 +236,7 @@ Posts.schemaJSON = {
|
|||
publish: true,
|
||||
},
|
||||
/**
|
||||
The post author's `_id`.
|
||||
The post author's `_id`.
|
||||
*/
|
||||
userId: {
|
||||
type: String,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { SyncedCron } from 'meteor/percolatestudio:synced-cron';
|
||||
// import moment from 'moment';
|
||||
import Posts from '../collection.js';
|
||||
import moment from 'moment';
|
||||
|
||||
SyncedCron.options = {
|
||||
log: true,
|
||||
|
@ -18,17 +19,17 @@ const addJob = function () {
|
|||
job() {
|
||||
// fetch all posts tagged as future
|
||||
const scheduledPosts = Posts.find({isFuture: true}, {fields: {_id: 1, status: 1, postedAt: 1, userId: 1, title: 1}}).fetch();
|
||||
|
||||
|
||||
// filter the scheduled posts to retrieve only the one that should update, considering their schedule
|
||||
const postsToUpdate = scheduledPosts.filter(post => post.postedAt <= new Date());
|
||||
|
||||
|
||||
// update posts found
|
||||
if (!_.isEmpty(postsToUpdate)) {
|
||||
const postsIds = _.pluck(postsToUpdate, '_id');
|
||||
Posts.update({_id: {$in: postsIds}}, {$set: {isFuture: false}}, {multi: true});
|
||||
|
||||
|
||||
// log the action
|
||||
console.log('// Scheduled posts approved:', postsIds);
|
||||
console.log('// Scheduled posts approved:', postsIds); // eslint-disable-line
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Posts from '../collection.js';
|
||||
// import Comments from "meteor/nova:comments";
|
||||
import Users from 'meteor/nova:users';
|
||||
import { Counts } from 'meteor/tmeasday:publish-counts';
|
||||
import Posts from '../collection.js';
|
||||
|
||||
Posts._ensureIndex({"status": 1, "postedAt": 1});
|
||||
|
||||
|
@ -25,7 +26,7 @@ const getPostsListUsers = posts => {
|
|||
userIds = _.unique(userIds);
|
||||
|
||||
return Users.find({_id: {$in: userIds}}, {fields: Users.publishedFields.list});
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -37,12 +38,12 @@ const getSinglePostUsers = post => {
|
|||
|
||||
let users = [post.userId]; // publish post author's ID
|
||||
|
||||
/*
|
||||
NOTE: to avoid circular dependencies between nova:posts and nova:comments,
|
||||
/*
|
||||
NOTE: to avoid circular dependencies between nova:posts and nova:comments,
|
||||
use callback hook to get comment authors
|
||||
*/
|
||||
users = Telescope.callbacks.run("posts.single.getUsers", users, post);
|
||||
|
||||
|
||||
// add upvoters
|
||||
if (post.upvoters && post.upvoters.length) {
|
||||
users = users.concat(post.upvoters);
|
||||
|
@ -67,15 +68,15 @@ const getSinglePostUsers = post => {
|
|||
*/
|
||||
Meteor.publish('posts.list', function (terms) {
|
||||
|
||||
// this.unblock(); // causes bug where publication returns 0 results
|
||||
// this.unblock(); // causes bug where publication returns 0 results
|
||||
|
||||
this.autorun(function () {
|
||||
|
||||
|
||||
const currentUser = this.userId && Users.findOne(this.userId);
|
||||
|
||||
terms.currentUserId = this.userId; // add currentUserId to terms
|
||||
const {selector, options} = Posts.parameters.get(terms);
|
||||
|
||||
|
||||
Counts.publish(this, terms.listId, Posts.find(selector, options), {noReady: true});
|
||||
|
||||
options.fields = Posts.publishedFields.list;
|
||||
|
@ -90,7 +91,7 @@ Meteor.publish('posts.list', function (terms) {
|
|||
});
|
||||
|
||||
return Users.canDo(currentUser, "posts.view.approved.all") ? [posts, users] : [];
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -112,8 +113,8 @@ Meteor.publish('posts.single', function (terms) {
|
|||
const users = getSinglePostUsers(post);
|
||||
return Users.canView(currentUser, post) ? [posts, users] : [];
|
||||
} else {
|
||||
console.log(`// posts.single: no post found for _id “${terms._id}”`)
|
||||
console.log(`// posts.single: no post found for _id “${terms._id}”`); // eslint-disable-line
|
||||
return [];
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import Posts from '../collection.js';
|
||||
import { Picker } from 'meteor/meteorhacks:picker';
|
||||
import escapeStringRegexp from 'escape-string-regexp';
|
||||
import Posts from '../collection.js';
|
||||
|
||||
Picker.route('/out', function(params, req, res, next) {
|
||||
var query = params.query;
|
||||
if(query.url){ // for some reason, query.url doesn't need to be decoded
|
||||
|
||||
/*
|
||||
/*
|
||||
If the URL passed to ?url= is in plain text, any hash fragment
|
||||
will get stripped out.
|
||||
So we search for any post whose URL contains the current URL to get a match
|
||||
|
@ -25,4 +26,4 @@ Picker.route('/out', function(params, req, res, next) {
|
|||
} else {
|
||||
res.end("Please provide a URL");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Users from 'meteor/nova:users';
|
||||
import Posts from './collection.js'
|
||||
|
||||
/**
|
||||
|
@ -103,7 +104,7 @@ Posts.views.add("userPosts", function (terms) {
|
|||
isFuture: {$ne: true}
|
||||
},
|
||||
options: {
|
||||
limit: 5,
|
||||
limit: 5,
|
||||
sort: {
|
||||
postedAt: -1
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { Picker } from 'meteor/meteorhacks:picker';
|
||||
import { servePostRSS, serveCommentRSS } from './rss.js';
|
||||
|
||||
Picker.route('/feed.xml', function(params, req, res, next) {
|
||||
|
|
|
@ -52,9 +52,9 @@ const serveCommentRSS = function (terms, url) {
|
|||
var feed = new RSS(getMeta(url));
|
||||
|
||||
Comments.find({isDeleted: {$ne: true}}, {sort: {postedAt: -1}, limit: 20}).forEach(function(comment) {
|
||||
post = Posts.findOne(comment.postId);
|
||||
var post = Posts.findOne(comment.postId);
|
||||
feed.item({
|
||||
title: 'Comment on '+post.title,
|
||||
title: 'Comment on ' + post.title,
|
||||
description: `${comment.body}</br></br><a href="${comment.getPageUrl(true)}">Discuss</a>`,
|
||||
author: comment.author,
|
||||
date: comment.postedAt,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Users from 'meteor/nova:users';
|
||||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||
|
||||
const isInSettingsJSON = function () {
|
||||
// settings can either be in settings json's public, or in the special object we publish only for admins for private settings
|
||||
|
@ -371,4 +372,4 @@ Telescope.settings.schema = new SimpleSchema({
|
|||
|
||||
Telescope.settings.collection.attachSchema(Telescope.settings.schema);
|
||||
|
||||
Telescope.subscriptions.preload("settings");
|
||||
Telescope.subscriptions.preload("settings");
|
||||
|
|
|
@ -16,7 +16,7 @@ Meteor.methods({
|
|||
"settings.exportToJSON": function () {
|
||||
if (Users.isAdminById(this.userId)) {
|
||||
let settings = Telescope.settings.collection.findOne();
|
||||
const schema = Telescope.settings.collection.simpleSchema()._schema;
|
||||
// const schema = Telescope.settings.collection.simpleSchema()._schema;
|
||||
const publicFields = Telescope.settings.collection.getPublicFields();
|
||||
delete settings._id;
|
||||
settings.public = {};
|
||||
|
@ -26,7 +26,7 @@ Meteor.methods({
|
|||
delete settings[key];
|
||||
}
|
||||
});
|
||||
console.log(JSON.stringify(settings, null, 2));
|
||||
console.log(JSON.stringify(settings, null, 2)); // eslint-disable-line
|
||||
return settings;
|
||||
}
|
||||
},
|
||||
|
@ -36,4 +36,4 @@ Meteor.methods({
|
|||
Telescope.settings.collection.update(settings._id, {}, {validate: false});
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import PublicationUtils from 'meteor/utilities:smart-publications';
|
||||
import Users from "meteor/nova:users";
|
||||
import Users from 'meteor/nova:users';
|
||||
|
||||
Users.addField([
|
||||
{
|
||||
|
|
|
@ -6,13 +6,13 @@ import Users from 'meteor/nova:users';
|
|||
* @param {Collection} collection
|
||||
* @param {String} itemId
|
||||
* @param {Object} user
|
||||
* @returns {Object} collectionName, fields: object, item, hasSubscribedItem: boolean
|
||||
* @returns {Object} collectionName, fields: object, item, hasSubscribedItem: boolean
|
||||
*/
|
||||
const prepareSubscription = (action, collection, itemId, user) => {
|
||||
|
||||
|
||||
// get item's collection name
|
||||
const collectionName = collection._name.slice(0,1).toUpperCase() + collection._name.slice(1);
|
||||
|
||||
|
||||
// get item data
|
||||
const item = collection.findOne(itemId);
|
||||
|
||||
|
@ -20,7 +20,7 @@ const prepareSubscription = (action, collection, itemId, user) => {
|
|||
if (!user || !item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// edge case: Users collection
|
||||
if (collectionName === 'Users') {
|
||||
// someone can't subscribe to themself, abort process
|
||||
|
@ -35,12 +35,12 @@ const prepareSubscription = (action, collection, itemId, user) => {
|
|||
}
|
||||
|
||||
// assign the right fields depending on the collection
|
||||
const fields = {
|
||||
const fields = {
|
||||
subscribers: collectionName === 'Users' ? 'telescope.subscribers' : 'subscribers',
|
||||
subscriberCount: collectionName === 'Users' ? 'telescope.subscriberCount' : 'subscriberCount',
|
||||
};
|
||||
|
||||
// return true if the item has the subscriber's id in its fields
|
||||
// return true if the item has the subscriber's id in its fields
|
||||
const hasSubscribedItem = !!_.deep(item, fields.subscribers) && _.deep(item, fields.subscribers) && _.deep(item, fields.subscribers).indexOf(user._id) !== -1;
|
||||
|
||||
// assign the right update operator and count depending on the action type
|
||||
|
@ -107,7 +107,7 @@ const performSubscriptionAction = (action, collection, itemId, user) => {
|
|||
itemId: item._id,
|
||||
};
|
||||
|
||||
// in case of subscription, log also the date
|
||||
// in case of subscription, log also the date
|
||||
if (action === 'subscribe') {
|
||||
loggedItem = {
|
||||
...loggedItem,
|
||||
|
@ -129,11 +129,12 @@ const performSubscriptionAction = (action, collection, itemId, user) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* @summary Generate methods 'collection.subscribe' & 'collection.unsubscribe' automatically
|
||||
* @summary Generate methods 'collection.subscribe' & 'collection.unsubscribe' automatically
|
||||
* @params {Array[Collections]} collections
|
||||
*/
|
||||
let subscribeMethodsGenerator;
|
||||
export default subscribeMethodsGenerator = (collection) => {
|
||||
|
||||
|
||||
// generic method function calling the performSubscriptionAction
|
||||
const genericMethodFunction = (col, action) => {
|
||||
// return the method code
|
||||
|
@ -151,7 +152,7 @@ const performSubscriptionAction = (action, collection, itemId, user) => {
|
|||
return performSubscriptionAction(action, col, docId, user);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
const collectionName = collection._name;
|
||||
// return an object of the shape expected by Meteor.methods
|
||||
return {
|
||||
|
@ -162,7 +163,7 @@ const performSubscriptionAction = (action, collection, itemId, user) => {
|
|||
|
||||
// Finally. Add the methods to the Meteor namespace 🖖
|
||||
|
||||
// nova:users is a dependency of this package, it is alreay imported
|
||||
// nova:users is a dependency of this package, it is alreay imported
|
||||
Meteor.methods(subscribeMethodsGenerator(Users));
|
||||
|
||||
// check if nova:posts exists, if yes, add the methods to Posts
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import Users from 'meteor/nova:users';
|
||||
|
||||
if (typeof Package['nova:posts'] !== "undefined") {
|
||||
import Posts from "meteor/nova:posts";
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { Gravatar } from 'meteor/jparker:gravatar';
|
||||
import Users from './collection.js';
|
||||
|
||||
// var _ = require('underscore');
|
||||
|
@ -191,7 +192,7 @@ Users.avatar = {
|
|||
return service[0];
|
||||
},
|
||||
|
||||
computeUrl: function(prop) {
|
||||
computeUrl: function(prop, user) {
|
||||
if (typeof prop === 'function') {
|
||||
prop = prop.call(user);
|
||||
}
|
||||
|
@ -210,9 +211,9 @@ Users.avatar = {
|
|||
|
||||
var customProp = user && this.options.customImageProperty;
|
||||
if (typeof customProp === 'function') {
|
||||
return this.computeUrl(customProp);
|
||||
return this.computeUrl(customProp, user);
|
||||
} else if (customProp) {
|
||||
return this.computeUrl(this.getDescendantProp(user, customProp));
|
||||
return this.computeUrl(this.getDescendantProp(user, customProp), user);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -230,7 +231,7 @@ Users.avatar = {
|
|||
}
|
||||
|
||||
var emailOrHash = this.getUserEmail(user) || Users.getEmailHash(user);
|
||||
var secure = true;
|
||||
// var secure = true;
|
||||
var options = {
|
||||
// NOTE: Gravatar's default option requires a publicly accessible URL,
|
||||
// so it won't work when your app is running on localhost and you're
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Users from './collection.js';
|
||||
import marked from 'marked';
|
||||
import Events from "meteor/nova:events";
|
||||
import NovaEmail from 'meteor/nova:email';
|
||||
import { Gravatar } from 'meteor/jparker:gravatar';
|
||||
import marked from 'marked';
|
||||
import Users from './collection.js';
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Collection Hooks //
|
||||
|
@ -130,7 +131,7 @@ function setupUser (user, options) {
|
|||
user.telescope.displayName = user.services.linkedin.firstName + " " + user.services.linkedin.lastName;
|
||||
} else {
|
||||
user.telescope.displayName = user.username;
|
||||
}
|
||||
}
|
||||
|
||||
// create a basic slug from display name and then modify it if this slugs already exists;
|
||||
const basicSlug = Telescope.utils.slugify(user.telescope.displayName);
|
||||
|
|
|
@ -39,7 +39,7 @@ Users.getUserName = function (user) {
|
|||
return user.services.twitter.screenName;
|
||||
}
|
||||
catch (error){
|
||||
console.log(error);
|
||||
console.log(error); // eslint-disable-line
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Telescope from 'meteor/nova:lib';
|
||||
import Users from './collection.js';
|
||||
|
||||
/*
|
||||
var completeUserProfile = function (userId, modifier, user) {
|
||||
|
||||
Users.update(userId, modifier);
|
||||
|
@ -10,6 +11,7 @@ var completeUserProfile = function (userId, modifier, user) {
|
|||
return Users.findOne(userId);
|
||||
|
||||
};
|
||||
*/
|
||||
|
||||
Users.methods = {};
|
||||
|
||||
|
@ -97,7 +99,7 @@ Meteor.methods({
|
|||
},
|
||||
|
||||
'users.remove'(userId, options) {
|
||||
|
||||
|
||||
// do the user which to delete his account or another user?
|
||||
const actionType = this.userId === userId ? "own" : "all";
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue