diff --git a/packages/nova-base-components/lib/posts/PostsItem.jsx b/packages/nova-base-components/lib/posts/PostsItem.jsx
index 0a76ab288..5697c04a4 100644
--- a/packages/nova-base-components/lib/posts/PostsItem.jsx
+++ b/packages/nova-base-components/lib/posts/PostsItem.jsx
@@ -62,7 +62,7 @@ class PostsItem extends Component {
{post.user?
: null}
-
+
{post.postedAt ? : }
diff --git a/packages/nova-forms/lib/DateTime.jsx b/packages/nova-forms/lib/DateTime.jsx
index 185454f2c..ef8c408b3 100644
--- a/packages/nova-forms/lib/DateTime.jsx
+++ b/packages/nova-forms/lib/DateTime.jsx
@@ -1,17 +1,23 @@
import React, { PropTypes, Component } from 'react';
-import DateTimeField from 'react-datetime';
+import DateTimePicker from 'react-datetime';
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)
+ componentWillMount() {
+ this.props.updateCurrentValue(this.props.name, this.props.value || new Date());
+ }
+
render() {
return (
- this.props.updateCurrentValue(this.props.name, newDate._d)}
+ // newDate argument is a Moment object given by react-datetime
+ onChange={newDate => { this.props.updateCurrentValue(this.props.name, newDate._d)}}
format={"x"}
inputProps={{name: this.props.name}}
/>
diff --git a/packages/nova-i18n-en-us/lib/en_US.js b/packages/nova-i18n-en-us/lib/en_US.js
index ccc96a3c6..228c1352d 100644
--- a/packages/nova-i18n-en-us/lib/en_US.js
+++ b/packages/nova-i18n-en-us/lib/en_US.js
@@ -30,6 +30,7 @@ Telescope.strings.en = {
"posts.created_message": "Post created.",
"posts.rate_limit_error": "Please wait {details} seconds before posting again.",
"posts.postedAt": "Posted at",
+ "posts.dateNotDefined": "Date not defined",
"comments.comments": "Comments",
"comments.count": "{count, plural, =0 {No comments} one {# comment} other {# comments}}",
diff --git a/packages/nova-posts/lib/callbacks.js b/packages/nova-posts/lib/callbacks.js
index c0fc1def9..f059786b5 100644
--- a/packages/nova-posts/lib/callbacks.js
+++ b/packages/nova-posts/lib/callbacks.js
@@ -160,11 +160,11 @@ function PostsNewSubmittedPropertiesCheck (post, user) {
}
});
-
+ // note: not needed there anymore, this is already set in the next callback 'posts.new.sync' with other related properties (status, createdAt)
// if no post status has been set, set it now
- if (!post.status) {
- post.status = Posts.getDefaultStatus(user);
- }
+ // if (!post.status) {
+ // post.status = Posts.getDefaultStatus(user);
+ // }
// if no userId has been set, default to current user id
if (!post.userId) {
@@ -197,7 +197,7 @@ function PostsNewRequiredPropertiesCheck (post, user) {
const defaultProperties = {
createdAt: new Date(),
author: Users.getDisplayNameById(post.userId),
- status: Posts.getDefaultStatus()
+ status: Posts.getDefaultStatus(user)
};
post = _.extend(defaultProperties, post);
@@ -205,6 +205,11 @@ function PostsNewRequiredPropertiesCheck (post, user) {
// generate slug
post.slug = Telescope.utils.slugify(post.title);
+ // post is not pending and has been scheduled to be posted in the future by a moderator/admin
+ if (post.status !== Posts.config.STATUS_PENDING && post.postedAt && post.postedAt > post.createdAt) {
+ post.status = Posts.config.STATUS_SCHEDULED;
+ }
+
// if post is approved but doesn't have a postedAt date, give it a default date
// note: pending posts get their postedAt date only once theyre approved
if (Posts.isApproved(post) && !post.postedAt) {
@@ -318,6 +323,12 @@ Telescope.callbacks.add("posts.edit.sync", PostsEditForceStickyToFalse);
* @summary Set postedAt date
*/
function PostsEditSetPostedAt (post, oldPost) {
+
+ // post is not pending and has been scheduled to be posted in the future by a moderator/admin
+ if (post.status !== Posts.config.STATUS_PENDING && post.postedAt && post.postedAt > new Date()) {
+ Posts.update(post._id, {$set: {status: Posts.config.STATUS_SCHEDULED}});
+ }
+
// if post is approved but doesn't have a postedAt date, give it a default date
// note: pending posts get their postedAt date only once theyre approved
if (Posts.isApproved(post) && !post.postedAt) {
diff --git a/packages/nova-posts/lib/schema.js b/packages/nova-posts/lib/schema.js
index bdc978a7f..1fb4231d6 100644
--- a/packages/nova-posts/lib/schema.js
+++ b/packages/nova-posts/lib/schema.js
@@ -30,6 +30,10 @@ Posts.config.postStatuses = [
{
value: 5,
label: 'deleted'
+ },
+ {
+ value: 6,
+ label: 'scheduled'
}
];
@@ -38,6 +42,7 @@ Posts.config.STATUS_APPROVED = 2;
Posts.config.STATUS_REJECTED = 3;
Posts.config.STATUS_SPAM = 4;
Posts.config.STATUS_DELETED = 5;
+Posts.config.STATUS_SCHEDULED = 6;
const adminGroup = {
name: "admin",
diff --git a/packages/nova-posts/lib/server.js b/packages/nova-posts/lib/server.js
index 41fc382d9..385bf6d2f 100644
--- a/packages/nova-posts/lib/server.js
+++ b/packages/nova-posts/lib/server.js
@@ -2,5 +2,6 @@ import Posts from './modules.js';
import './server/publications.js';
import './server/routes.js';
+import './server/cron.js';
export default Posts;
\ No newline at end of file
diff --git a/packages/nova-posts/lib/server/cron.js b/packages/nova-posts/lib/server/cron.js
new file mode 100644
index 000000000..c96997a13
--- /dev/null
+++ b/packages/nova-posts/lib/server/cron.js
@@ -0,0 +1,40 @@
+import Posts from '../collection.js';
+import moment from 'moment';
+
+SyncedCron.options = {
+ log: true,
+ collectionName: 'cronHistory',
+ utc: false,
+ collectionTTL: 172800
+};
+
+
+const addJob = function () {
+ SyncedCron.add({
+ name: 'checkScheduledPosts',
+ schedule(parser) {
+ return parser.text('every 10 minutes');
+ },
+ job() {
+ // fetch all posts tagged as scheduled
+ const scheduledPosts = Posts.find({status: Posts.config.STATUS_SCHEDULED}, {fields: {_id: 1, status: 1, postedAt: 1, userId: 1, title: 1}}).fetch();
+
+ if (scheduledPosts) {
+ // 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 all posts with status approved
+ const postsIds = _.pluck(postsToUpdate, '_id');
+ Posts.update({_id: {$in: postsIds}}, {$set: {status: Posts.config.STATUS_APPROVED}}, {multi: true});
+
+ // log the action
+ console.log('// Scheduled posts approved:', postsIds);
+ }
+ }
+ });
+};
+
+Meteor.startup(function () {
+ addJob();
+});
+
diff --git a/packages/nova-posts/lib/views.js b/packages/nova-posts/lib/views.js
index 2805fe64a..f0420f20b 100644
--- a/packages/nova-posts/lib/views.js
+++ b/packages/nova-posts/lib/views.js
@@ -83,7 +83,9 @@ Posts.views.add("rejected", function (terms) {
*/
Posts.views.add("scheduled", function (terms) {
return {
- selector: {postedAt: {$gte: new Date()}},
+ selector: {
+ status: Posts.config.STATUS_SCHEDULED
+ },
options: {sort: {postedAt: -1}},
showFuture: true
};