From ea7efc3550a8b5cd1cb548ebd4ba781771754f12 Mon Sep 17 00:00:00 2001 From: Charlie DeTar Date: Wed, 5 Nov 2014 13:12:09 -0700 Subject: [PATCH 1/5] Replace "throwError" with "flashMessage" and type Currently, ``throwError`` is used for all manner of messages, including errors, "success" messages, and "info" messages. This makes appropriate styling of the error message difficult. In addition, the name ``throwError`` seems to create confusion, implying that an error will actually be thrown (e.g. stopping execution when a user isn't logged in [0][1]), when in fact it just displays a message. Replace ``throwError`` with ``flashMessage``, and reliably include a message "type" (e.g. "error", "success", "info") every time. rename ``lib/errors.js`` to ``lib/messages.js`` to more accurately reflect its function. This commit doesn't rename the message collection (``Errors``), nor the template responsible for rendering the messages (``error_item.html``) -- that should probably still be done, but has higher likelihood of trouble for existing alternate themes and installations. [0] https://github.com/TelescopeJS/Telescope/blob/6ccf7d7d4704d6a8e821fe48128f81c19983ffc9/client/views/users/user_edit.js#L43 [1] https://github.com/TelescopeJS/Telescope/blob/083a4c4dc48eca15fe9d4472e24e6b4e8adfc8d6/client/views/users/user_email.js#L13 --- client/helpers/handlebars.js | 4 ++-- client/views/comments/comment_edit.js | 4 ++-- client/views/comments/comment_form.js | 8 ++++---- client/views/comments/comment_item.js | 2 +- client/views/posts/modules/post_upvote.js | 3 ++- client/views/posts/post_edit.js | 12 ++++++------ client/views/posts/post_submit.js | 10 +++++----- client/views/users/invites.js | 10 +++++----- client/views/users/user_edit.js | 12 +++++++----- client/views/users/user_email.js | 9 ++++++--- client/views/users/user_profile.js | 4 ++-- collections/comments.js | 2 +- collections/posts.js | 4 ++-- lib/{errors.js => messages.js} | 6 +++--- lib/router.js | 10 +++++----- .../lib/client/templates/newsletter_banner.js | 6 +++--- .../telescope-tags/lib/client/views/categories.js | 8 ++++---- .../telescope-tags/lib/client/views/category_item.js | 4 ++-- 18 files changed, 62 insertions(+), 56 deletions(-) rename lib/{errors.js => messages.js} (78%) diff --git a/client/helpers/handlebars.js b/client/helpers/handlebars.js index 4593061c1..074f0ae9b 100644 --- a/client/helpers/handlebars.js +++ b/client/helpers/handlebars.js @@ -42,7 +42,7 @@ UI.registerHelper('isAdmin', function(showError) { return true; }else{ if((typeof showError === "string") && (showError === "true")) - throwError(i18n.t('Sorry, you do not have access to this page')); + flashMessage(i18n.t('Sorry, you do not have access to this page'), "error"); return false; } }); @@ -72,4 +72,4 @@ UI.registerHelper("sanitize", function(content) { UI.registerHelper('pluralize', function(count, string) { string = count === 1 ? string : string + 's'; return i18n.t(string); -}); \ No newline at end of file +}); diff --git a/client/views/comments/comment_edit.js b/client/views/comments/comment_edit.js index 7ade1ab7c..ce6cc01eb 100644 --- a/client/views/comments/comment_edit.js +++ b/client/views/comments/comment_edit.js @@ -39,8 +39,8 @@ Template[getTemplate('comment_edit')].events({ if(confirm(i18n.t("Are you sure?"))){ Meteor.call('removeComment', comment._id); Router.go("/posts/"+comment.postId); - throwError("Your comment has been deleted."); + flashMessage("Your comment has been deleted.", "success"); // Router.go("/comments/deleted"); } } -}); \ No newline at end of file +}); diff --git a/client/views/comments/comment_form.js b/client/views/comments/comment_form.js index 83de2c482..1b94f61a0 100644 --- a/client/views/comments/comment_form.js +++ b/client/views/comments/comment_form.js @@ -17,7 +17,7 @@ Template[getTemplate('comment_form')].events({ 'submit form': function(e, instance){ e.preventDefault(); $(e.target).addClass('disabled'); - clearSeenErrors(); + clearSeenMessages(); var content = instance.editor.exportFile(); if(getCurrentTemplate() == 'comment_reply'){ // child comment @@ -25,7 +25,7 @@ Template[getTemplate('comment_form')].events({ Meteor.call('comment', parentComment.postId, parentComment._id, content, function(error, newComment){ if(error){ console.log(error); - throwError(error.reason); + flashMessage(error.reason, "error"); }else{ trackEvent("newComment", newComment); Router.go('/posts/'+parentComment.postId+'/comment/'+newComment._id); @@ -38,7 +38,7 @@ Template[getTemplate('comment_form')].events({ Meteor.call('comment', post._id, null, content, function(error, newComment){ if(error){ console.log(error); - throwError(error.reason); + flashMessage(error.reason, "error"); }else{ trackEvent("newComment", newComment); Session.set('scrollToCommentId', newComment._id); @@ -47,4 +47,4 @@ Template[getTemplate('comment_form')].events({ }); } } -}); \ No newline at end of file +}); diff --git a/client/views/comments/comment_item.js b/client/views/comments/comment_item.js index db3c5685f..17860d15e 100644 --- a/client/views/comments/comment_item.js +++ b/client/views/comments/comment_item.js @@ -153,7 +153,7 @@ Template[getTemplate('comment_item')].events({ e.preventDefault(); if(!Meteor.user()){ Router.go(getSigninUrl()); - throwError(i18n.t("Please log in first")); + flashMessage(i18n.t("Please log in first"), "info"); } Meteor.call('upvoteComment', this, function(error, result){ trackEvent("post upvoted", {'commentId':instance.data._id, 'postId': instance.data.post, 'authorId':instance.data.userId}); diff --git a/client/views/posts/modules/post_upvote.js b/client/views/posts/modules/post_upvote.js index 0eb7b73c2..ce0be7898 100644 --- a/client/views/posts/modules/post_upvote.js +++ b/client/views/posts/modules/post_upvote.js @@ -16,7 +16,8 @@ Template[getTemplate('postUpvote')].events({ e.preventDefault(); if(!Meteor.user()){ Router.go(getSigninUrl()); - throwError(i18n.t("Please log in first")); + flashMessage(i18n.t("Please log in first"), "info"); + return; } Meteor.call('upvotePost', post, function(error, result){ trackEvent("post upvoted", {'_id': post._id}); diff --git a/client/views/posts/post_edit.js b/client/views/posts/post_edit.js index 397ec5aa2..f2c8dffa4 100644 --- a/client/views/posts/post_edit.js +++ b/client/views/posts/post_edit.js @@ -86,7 +86,7 @@ Template[getTemplate('post_edit')].events({ $(e.target).addClass('disabled'); if(!Meteor.user()){ - throwError('You must be logged in.'); + flashMessage('You must be logged in.', "error"); return false; } @@ -181,8 +181,8 @@ Template[getTemplate('post_edit')].events({ }, function(error){ if(error){ console.log(error); - throwError(error.reason); - clearSeenErrors(); + flashMessage(error.reason, "error"); + clearSeenMessages(); $(e.target).removeClass('disabled'); }else{ trackEvent("edit post", {'postId': post._id}); @@ -204,11 +204,11 @@ Template[getTemplate('post_edit')].events({ Meteor.call("deletePostById", post._id, function(error) { if (error) { console.log(error); - throwError(error.reason); + flashMessage(error.reason, "error"); } else { - throwError('Your post has been deleted.'); + flashMessage('Your post has been deleted.', "success"); } }); } } -}); \ No newline at end of file +}); diff --git a/client/views/posts/post_submit.js b/client/views/posts/post_submit.js index 3b376ae96..38cd44102 100644 --- a/client/views/posts/post_submit.js +++ b/client/views/posts/post_submit.js @@ -54,7 +54,7 @@ Template[getTemplate('post_submit')].events({ // ------------------------------ Checks ------------------------------ // if(!Meteor.user()){ - throwError(i18n.t('You must be logged in.')); + flashMessage(i18n.t('You must be logged in.'), "error"); return false; } @@ -116,15 +116,15 @@ Template[getTemplate('post_submit')].events({ if (properties) { Meteor.call('post', properties, function(error, post) { if(error){ - throwError(error.reason); - clearSeenErrors(); + flashMessage(error.reason, "error"); + clearSeenMessages(); $(e.target).removeClass('disabled'); if(error.error == 603) Router.go('/posts/'+error.details); }else{ trackEvent("new post", {'postId': post._id}); if(post.status === STATUS_PENDING) - throwError('Thanks, your post is awaiting approval.'); + flashMessage('Thanks, your post is awaiting approval.', "success"); Router.go('/posts/'+post._id); } }); @@ -153,4 +153,4 @@ Template[getTemplate('post_submit')].events({ } } -}); \ No newline at end of file +}); diff --git a/client/views/users/invites.js b/client/views/users/invites.js index e1cfffcdb..1794740c8 100644 --- a/client/views/users/invites.js +++ b/client/views/users/invites.js @@ -25,18 +25,18 @@ var scrollUp = function(){ AutoForm.hooks({ inviteForm: { onSuccess: function(operation, result, template) { - clearSeenErrors(); + clearSeenMessages(); if(result && result.newUser){ - throwError('An invite has been sent out. Thank you!'); + flashMessage('An invite has been sent out. Thank you!', "success"); } else { - throwError('Thank you!'); + flashMessage('Thank you!', "info"); } scrollUp(); }, onError: function(operation, error, template) { - clearSeenErrors(); + clearSeenMessages(); if(error && error.reason){ throwError(error.reason); @@ -44,4 +44,4 @@ AutoForm.hooks({ } } } -}); \ No newline at end of file +}); diff --git a/client/views/users/user_edit.js b/client/views/users/user_edit.js index 39ced76bd..e902b3050 100644 --- a/client/views/users/user_edit.js +++ b/client/views/users/user_edit.js @@ -38,9 +38,11 @@ Template[getTemplate('user_edit')].events({ 'submit #account-form': function(e){ e.preventDefault(); - clearSeenErrors(); - if(!Meteor.user()) - throwError(i18n.t('You must be logged in.')); + clearSeenMessages(); + if(!Meteor.user()) { + flashMessage(i18n.t('You must be logged in.'), "error"); + return; + } var $target=$(e.target); var name = $target.find('[name=name]').val(); @@ -67,7 +69,7 @@ Template[getTemplate('user_edit')].events({ Accounts.changePassword(old_password, new_password, function(error){ // TODO: interrupt update if there's an error at this point if(error) - throwError(error.reason); + flashMessage(error.reason, "error"); }); } @@ -89,4 +91,4 @@ Template[getTemplate('user_edit')].events({ } -}); \ No newline at end of file +}); diff --git a/client/views/users/user_email.js b/client/views/users/user_email.js index ca915deda..d55493723 100644 --- a/client/views/users/user_email.js +++ b/client/views/users/user_email.js @@ -10,7 +10,10 @@ Template[getTemplate('user_email')].helpers({ Template[getTemplate('user_email')].events({ 'submit form': function(e){ e.preventDefault(); - if(!Meteor.user()) throwError(i18n.t('You must be logged in.')); + if(!Meteor.user()) { + flashMessage(i18n.t('You must be logged in.'), "error"); + return; + } var $target=$(e.target); var user=Session.get('selectedUserId')? Meteor.users.findOne(Session.get('selectedUserId')) : Meteor.user(); var update = { @@ -26,9 +29,9 @@ Template[getTemplate('user_email')].events({ $set: update }, function(error){ if(error){ - throwError(error.reason); + flashMessage(error.reason, "error"); } else { - throwError(i18n.t('Thanks for signing up!')); + flashMessage(i18n.t('Thanks for signing up!'), "success"); // Meteor.call('addCurrentUserToMailChimpList'); trackEvent("new sign-up", {'userId': user._id, 'auth':'twitter'}); Router.go('/'); diff --git a/client/views/users/user_profile.js b/client/views/users/user_profile.js index ade940fbb..7c374896f 100644 --- a/client/views/users/user_profile.js +++ b/client/views/users/user_profile.js @@ -79,7 +79,7 @@ Template[getTemplate('user_profile')].helpers({ Template[getTemplate('user_profile')].events({ 'click .invite-link': function(e, instance){ Meteor.call('inviteUser', instance.data.user._id); - throwError('Thanks, user has been invited.'); + flashMessage('Thanks, user has been invited.', "success"); }, 'click .posts-more': function (e) { e.preventDefault(); @@ -101,4 +101,4 @@ Template[getTemplate('user_profile')].events({ var commentsShown = Session.get('commentsShown'); Session.set('commentsShown', commentsShown + 10); } -}); \ No newline at end of file +}); diff --git a/collections/comments.js b/collections/comments.js index f203ea66c..ef6360d7c 100644 --- a/collections/comments.js +++ b/collections/comments.js @@ -194,7 +194,7 @@ Meteor.methods({ isDeleted: true }}); }else{ - throwError("You don't have permission to delete this comment."); + flashMessage("You don't have permission to delete this comment.", "error"); } } }); diff --git a/collections/posts.js b/collections/posts.js index 4f19ed331..aaebe5254 100644 --- a/collections/posts.js +++ b/collections/posts.js @@ -300,14 +300,14 @@ Meteor.methods({ var now = new Date(); Posts.update(post._id, {$set: {status: 2, postedAt: now}}); }else{ - throwError('You need to be an admin to do that.'); + flashMessage('You need to be an admin to do that.', "error"); } }, unapprovePost: function(post){ if(isAdmin(Meteor.user())){ Posts.update(post._id, {$set: {status: 1}}); }else{ - throwError('You need to be an admin to do that.'); + flashMessage('You need to be an admin to do that.', "error"); } }, clickedPost: function(post, sessionId){ diff --git a/lib/errors.js b/lib/messages.js similarity index 78% rename from lib/errors.js rename to lib/messages.js index 7172fd95c..45a968504 100644 --- a/lib/errors.js +++ b/lib/messages.js @@ -1,13 +1,13 @@ if(Meteor.isClient){ - throwError = function(message, type){ + flashMessage = function(message, type){ type = (typeof type === 'undefined') ? 'error': type; // Store errors in the 'Errors' local collection Errors.insert({message:message, type:type, seen: false, show:true}); }; - clearSeenErrors = function(){ + clearSeenMessages = function(){ Errors.update({seen:true}, {$set: {show:false}}, {multi:true}); }; -} \ No newline at end of file +} diff --git a/lib/router.js b/lib/router.js index 7f7f7e4dd..978fa3d51 100644 --- a/lib/router.js +++ b/lib/router.js @@ -134,7 +134,7 @@ Router._filters = { /* isLoggedIn: function(pause) { if (!(Meteor.loggingIn() || Meteor.user())) { - throwError(i18n.t('Please Sign In First.')); + flashMessage(i18n.t('Please Sign In First.'), "info"); var current = getCurrentRoute(); if (current){ Session.set('fromWhere', current); @@ -176,7 +176,7 @@ Router._filters = { this.render(getTemplate('loading')); pause(); }else if(!canPost()){ - throwError(i18n.t("Sorry, you don't have permissions to add new items.")); + flashMessage(i18n.t("Sorry, you don't have permissions to add new items."), "error"); this.render(getTemplate('no_rights')); pause(); } @@ -187,7 +187,7 @@ Router._filters = { // Already subscribed to this post by route({waitOn: ...}) var post = Posts.findOne(this.params._id); if(!currentUserCanEdit(post)){ - throwError(i18n.t("Sorry, you cannot edit this post.")); + flashMessage(i18n.t("Sorry, you cannot edit this post."), "error"); this.render(getTemplate('no_rights')); pause(); } @@ -198,7 +198,7 @@ Router._filters = { // Already subscribed to this comment by CommentPageController var comment = Comments.findOne(this.params._id); if(!currentUserCanEdit(comment)){ - throwError(i18n.t("Sorry, you cannot edit this comment.")); + flashMessage(i18n.t("Sorry, you cannot edit this comment."), "error"); this.render(getTemplate('no_rights')); pause(); } @@ -248,7 +248,7 @@ if(Meteor.isClient){ // Before Hooks // Router.onBeforeAction(filters.isReady); - Router.onBeforeAction(clearSeenErrors); + Router.onBeforeAction(clearSeenMessages); Router.onBeforeAction(filters.canView, {except: ['atSignIn', 'atSignUp', 'atForgotPwd', 'atResetPwd', 'signOut']}); Router.onBeforeAction(filters.hasCompletedProfile); Router.onBeforeAction(filters.isLoggedIn, {only: ['post_submit']}); diff --git a/packages/telescope-newsletter/lib/client/templates/newsletter_banner.js b/packages/telescope-newsletter/lib/client/templates/newsletter_banner.js index f5ed03492..d4e0a975e 100644 --- a/packages/telescope-newsletter/lib/client/templates/newsletter_banner.js +++ b/packages/telescope-newsletter/lib/client/templates/newsletter_banner.js @@ -54,7 +54,7 @@ Meteor.startup(function () { $banner.removeClass('show-loader'); if(error){ console.log(error); - throwError(error.message); + flashMessage(error.message, "error"); }else{ console.log(result); confirmSubscription(); @@ -71,7 +71,7 @@ Meteor.startup(function () { $banner.removeClass('show-loader'); if(error){ console.log(error); - throwError(error.message); + flashMessage(error.message, "error"); }else{ console.log(result); confirmSubscription(); @@ -87,4 +87,4 @@ Meteor.startup(function () { e.preventDefault(); } }); -}); \ No newline at end of file +}); diff --git a/packages/telescope-tags/lib/client/views/categories.js b/packages/telescope-tags/lib/client/views/categories.js index fe1402809..6d4d07905 100644 --- a/packages/telescope-tags/lib/client/views/categories.js +++ b/packages/telescope-tags/lib/client/views/categories.js @@ -24,13 +24,13 @@ Meteor.startup(function () { }, function(error, categoryName) { if(error){ console.log(error); - throwError(error.reason); - clearSeenErrors(); + flashMessage(error.reason, "error"); + clearSeenMessages(); }else{ $('#name').val(''); - // throwError('New category "'+categoryName+'" created'); + // flashMessage('New category "'+categoryName+'" created', "success"); } }); } }); -}); \ No newline at end of file +}); diff --git a/packages/telescope-tags/lib/client/views/category_item.js b/packages/telescope-tags/lib/client/views/category_item.js index f51600d70..44299e7db 100644 --- a/packages/telescope-tags/lib/client/views/category_item.js +++ b/packages/telescope-tags/lib/client/views/category_item.js @@ -13,9 +13,9 @@ Meteor.startup(function () { } Meteor.call('updateCategoryInPosts', categoryId, function(error) { if (error) { - throwError(error.reason); + flashMessage(error.reason, "error"); } }); } }); -}); \ No newline at end of file +}); From 2cf432b5217b0b14a7526605a22cb9619666f241 Mon Sep 17 00:00:00 2001 From: Charlie DeTar Date: Mon, 17 Nov 2014 17:00:21 -0700 Subject: [PATCH 2/5] Clean up remaining throwError invocations --- client/views/comments/comment_item.js | 6 +++--- client/views/users/invites.js | 2 +- client/views/users/user_edit.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/views/comments/comment_item.js b/client/views/comments/comment_item.js index 17860d15e..8e8462622 100644 --- a/client/views/comments/comment_item.js +++ b/client/views/comments/comment_item.js @@ -163,7 +163,7 @@ Template[getTemplate('comment_item')].events({ e.preventDefault(); if(!Meteor.user()){ Router.go(getSigninUrl()); - throwError(i18n.t("Please log in first")); + flashMessage(i18n.t("Please log in first"), "info"); } Meteor.call('cancelUpvoteComment', this, function(error, result){ trackEvent("post upvote cancelled", {'commentId':instance.data._id, 'postId': instance.data.post, 'authorId':instance.data.userId}); @@ -173,7 +173,7 @@ Template[getTemplate('comment_item')].events({ e.preventDefault(); if(!Meteor.user()){ Router.go(getSigninUrl()); - throwError(i18n.t("Please log in first")); + flashMessage(i18n.t("Please log in first"), "info"); } Meteor.call('downvoteComment', this, function(error, result){ trackEvent("post downvoted", {'commentId':instance.data._id, 'postId': instance.data.post, 'authorId':instance.data.userId}); @@ -183,7 +183,7 @@ Template[getTemplate('comment_item')].events({ e.preventDefault(); if(!Meteor.user()){ Router.go(getSigninUrl()); - throwError(i18n.t("Please log in first")); + flashMessage(i18n.t("Please log in first"), "info"); } Meteor.call('cancelDownvoteComment', this, function(error, result){ trackEvent("post downvote cancelled", {'commentId':instance.data._id, 'postId': instance.data.post, 'authorId':instance.data.userId}); diff --git a/client/views/users/invites.js b/client/views/users/invites.js index 1794740c8..fa199c9de 100644 --- a/client/views/users/invites.js +++ b/client/views/users/invites.js @@ -39,7 +39,7 @@ AutoForm.hooks({ clearSeenMessages(); if(error && error.reason){ - throwError(error.reason); + flashMessage(error.reason, "error"); scrollUp(); } } diff --git a/client/views/users/user_edit.js b/client/views/users/user_edit.js index e902b3050..b6685b688 100644 --- a/client/views/users/user_edit.js +++ b/client/views/users/user_edit.js @@ -77,9 +77,9 @@ Template[getTemplate('user_edit')].events({ $set: update }, function(error){ if(error){ - throwError(error.reason); + flashMessage(error.reason, "error"); } else { - throwError(i18n.t('Profile updated')); + flashMessage(i18n.t('Profile updated'), "success"); } Deps.afterFlush(function() { var element = $('.grid > .error'); From b6c54c106da4f72ee25e06c500c7d8a555d9c7c4 Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Sat, 6 Dec 2014 17:41:15 +0900 Subject: [PATCH 3/5] renaming errors to messages --- client/views/common/error.js | 2 +- client/views/posts/post_submit.js | 2 +- client/views/users/user_edit.js | 2 +- collections/{errors.js => messages.js} | 2 +- lib/messages.js | 6 +- lib/router.js | 818 ------------------ .../lib/client/autoform-postthumbnail.js | 2 +- 7 files changed, 8 insertions(+), 826 deletions(-) rename collections/{errors.js => messages.js} (58%) delete mode 100644 lib/router.js diff --git a/client/views/common/error.js b/client/views/common/error.js index 9a29a316e..2a31e8486 100644 --- a/client/views/common/error.js +++ b/client/views/common/error.js @@ -3,6 +3,6 @@ Template[getTemplate('error')].helpers({ return getTemplate('error_item'); }, errors: function(){ - return Errors.find({show: true}); + return Messages.find({show: true}); } }); \ No newline at end of file diff --git a/client/views/posts/post_submit.js b/client/views/posts/post_submit.js index affe66f71..74a022728 100644 --- a/client/views/posts/post_submit.js +++ b/client/views/posts/post_submit.js @@ -50,7 +50,7 @@ AutoForm.hooks({ onError: function(operation, error, template) { flashMessage(error.reason.split('|')[0], 'error'); // workaround because error.details returns undefined - clearSeenErrors(); + clearSeenMessages(); // $(e.target).removeClass('disabled'); if (error.error == 603) { var dupePostId = error.reason.split('|')[1]; diff --git a/client/views/users/user_edit.js b/client/views/users/user_edit.js index 95662a5e9..0bf4d5e99 100644 --- a/client/views/users/user_edit.js +++ b/client/views/users/user_edit.js @@ -38,7 +38,7 @@ Template[getTemplate('user_edit')].events({ 'submit #account-form': function(e){ e.preventDefault(); - clearSeenErrors(); + clearSeenMessages(); if(!Meteor.user()) flashMessage(i18n.t('you_must_be_logged_in'), 'error'); diff --git a/collections/errors.js b/collections/messages.js similarity index 58% rename from collections/errors.js rename to collections/messages.js index 84a496f12..f1e5f32f5 100644 --- a/collections/errors.js +++ b/collections/messages.js @@ -1,4 +1,4 @@ if(Meteor.isClient){ // Local (client-only) collection - Errors = new Meteor.Collection(null); + Messages = new Meteor.Collection(null); } \ No newline at end of file diff --git a/lib/messages.js b/lib/messages.js index 45a968504..76375ccc1 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -2,12 +2,12 @@ if(Meteor.isClient){ flashMessage = function(message, type){ type = (typeof type === 'undefined') ? 'error': type; - // Store errors in the 'Errors' local collection - Errors.insert({message:message, type:type, seen: false, show:true}); + // Store errors in the 'Messages' local collection + Messages.insert({message:message, type:type, seen: false, show:true}); }; clearSeenMessages = function(){ - Errors.update({seen:true}, {$set: {show:false}}, {multi:true}); + Messages.update({seen:true}, {$set: {show:false}}, {multi:true}); }; } diff --git a/lib/router.js b/lib/router.js deleted file mode 100644 index 978fa3d51..000000000 --- a/lib/router.js +++ /dev/null @@ -1,818 +0,0 @@ -/* - -//--------------------------------------------------------------------------------------------------// -//---------------------------------------- Table Of Contents ---------------------------------------// -//--------------------------------------------------------------------------------------------------// - ---------------------------------------------------------------- -# Config # ---------------------------------------------------------------- - -// - ---------------------------------------------------------------- -# Filters # ---------------------------------------------------------------- - -isLoggedIn -isLoggedOut -isAdmin - -canView -canPost -canEditPost -canEditComment - -hasCompletedProfile - ---------------------------------------------------------------- -# Controllers # ---------------------------------------------------------------- - -PostsListController -PostPageController - ---------------------------------------------------------------- -# Routes # ---------------------------------------------------------------- - -1) Paginated Lists ----------------------- -Top -New -Best -Pending -Categories - -2) Digest --------------------- -Digest - -3) Posts --------------------- -Post Page -Post Page (scroll to comment) -Post Edit -Post Submit - -4) Comments --------------------- -Comment Page -Comment Edit -Comment Submit - -5) Users --------------------- -User Profie -User Edit -Account -All Users -Unsubscribe (from notifications) - -6) Misc Routes --------------------- -Settings -Categories -Toolbox - -7) Server-side --------------------- -API -RSS - -*/ - -// uncomment to disable FastRender -var FastRender = {RouteController: RouteController, onAllRoutes: function() {}}; - -//--------------------------------------------------------------------------------------------------// -//--------------------------------------------- Config ---------------------------------------------// -//--------------------------------------------------------------------------------------------------// - -preloadSubscriptions.push('settings'); -preloadSubscriptions.push('currentUser'); - -Router.configure({ - layoutTemplate: getTemplate('layout'), - loadingTemplate: getTemplate('loading'), - notFoundTemplate: getTemplate('notFound'), - waitOn: function () { - return _.map(preloadSubscriptions, function(sub){ - // can either pass strings or objects with subName and subArguments properties - if (typeof sub === 'object'){ - Meteor.subscribe(sub.subName, sub.subArguments); - }else{ - Meteor.subscribe(sub); - } - }); - } -}); - -//--------------------------------------------------------------------------------------------------// -//--------------------------------------------- Filters --------------------------------------------// -//--------------------------------------------------------------------------------------------------// - -Router._filters = { - - isReady: function(pause) { - if (!this.ready()) { - // console.log('not ready') - this.render(getTemplate('loading')); - pause(); - }else{ - // console.log('ready') - } - }, - - resetScroll: function () { - var scrollTo = window.currentScroll || 0; - var $body = $('body'); - $body.scrollTop(scrollTo); - $body.css("min-height", 0); - }, - - /* - isLoggedIn: function(pause) { - if (!(Meteor.loggingIn() || Meteor.user())) { - flashMessage(i18n.t('Please Sign In First.'), "info"); - var current = getCurrentRoute(); - if (current){ - Session.set('fromWhere', current); - } - this.render('entrySignIn'); - pause(); - } - }, - */ - isLoggedIn: AccountsTemplates.ensureSignedIn, - - isLoggedOut: function(pause) { - if(Meteor.user()){ - this.render('already_logged_in'); - pause(); - } - }, - - isAdmin: function(pause) { - if(!this.ready()) return; - if(!isAdmin()){ - this.render(getTemplate('no_rights')); - pause(); - } - }, - - canView: function(pause) { - if(!this.ready() || Meteor.loggingIn()){ - this.render(getTemplate('loading')); - pause(); - }else if (!canView()) { - this.render(getTemplate('no_rights')); - pause(); - } - }, - - canPost: function (pause) { - if(!this.ready() || Meteor.loggingIn()){ - this.render(getTemplate('loading')); - pause(); - }else if(!canPost()){ - flashMessage(i18n.t("Sorry, you don't have permissions to add new items."), "error"); - this.render(getTemplate('no_rights')); - pause(); - } - }, - - canEditPost: function(pause) { - if(!this.ready()) return; - // Already subscribed to this post by route({waitOn: ...}) - var post = Posts.findOne(this.params._id); - if(!currentUserCanEdit(post)){ - flashMessage(i18n.t("Sorry, you cannot edit this post."), "error"); - this.render(getTemplate('no_rights')); - pause(); - } - }, - - canEditComment: function(pause) { - if(!this.ready()) return; - // Already subscribed to this comment by CommentPageController - var comment = Comments.findOne(this.params._id); - if(!currentUserCanEdit(comment)){ - flashMessage(i18n.t("Sorry, you cannot edit this comment."), "error"); - this.render(getTemplate('no_rights')); - pause(); - } - }, - - hasCompletedProfile: function(pause) { - if(!this.ready()) return; - var user = Meteor.user(); - if (user && ! userProfileComplete(user)){ - this.render(getTemplate('user_email')); - pause(); - } - }, - - setTitle: function() { - // set title - var title = getSetting("title"); - var tagline = getSetting("tagline"); - document.title = (tagline ? title+': '+tagline : title) || ""; - } - -}; - -var filters = Router._filters; -var coreSubscriptions = new SubsManager({ - // cache recent 50 subscriptions - cacheLimit: 50, - // expire any subscription after 30 minutes - expireIn: 30 -}); - -if(Meteor.isClient){ - - // Load Hooks - - Router.onRun( function () { - Session.set('categorySlug', null); - - // if we're not on the search page itself, clear search query and field - if(getCurrentRoute().indexOf('search') == -1){ - Session.set('searchQuery', ''); - $('.search-field').val('').blur(); - } - - }); - - // Before Hooks - - // Router.onBeforeAction(filters.isReady); - Router.onBeforeAction(clearSeenMessages); - Router.onBeforeAction(filters.canView, {except: ['atSignIn', 'atSignUp', 'atForgotPwd', 'atResetPwd', 'signOut']}); - Router.onBeforeAction(filters.hasCompletedProfile); - Router.onBeforeAction(filters.isLoggedIn, {only: ['post_submit']}); - Router.onBeforeAction(filters.isLoggedOut, {only: []}); - Router.onBeforeAction(filters.canPost, {only: ['posts_pending', 'post_submit']}); - Router.onBeforeAction(filters.canEditPost, {only: ['post_edit']}); - Router.onBeforeAction(filters.canEditComment, {only: ['comment_edit']}); - Router.onBeforeAction(filters.isAdmin, {only: ['posts_pending', 'all-users', 'settings', 'toolbox', 'logs']}); - - // After Hooks - - // Router.onAfterAction(filters.resetScroll, {except:['posts_top', 'posts_new', 'posts_best', 'posts_pending', 'posts_category', 'all-users']}); - Router.onAfterAction(analyticsInit); // will only run once thanks to _.once() - Router.onAfterAction(analyticsRequest); // log this request with mixpanel, etc - Router.onAfterAction(filters.setTitle); - - // Unload Hooks - - // - -} - -//--------------------------------------------------------------------------------------------------// -//------------------------------------------- Controllers ------------------------------------------// -//--------------------------------------------------------------------------------------------------// - - -// Controller for all posts lists - -PostsListController = FastRender.RouteController.extend({ - template: getTemplate('posts_list'), - onBeforeAction: function () { - // take the first segment of the path to get the view, unless it's '/' in which case the view default to 'top' - // note: most of the time this.params.slug will be empty - this._terms = { - view: this.view, - limit: this.params.limit || getSetting('postsPerPage', 10), - category: this.params.slug - }; - - if(Meteor.isClient) { - this._terms.query = Session.get("searchQuery"); - } - - this.postsListSub = coreSubscriptions.subscribe('postsList', this._terms); - return [ - this.postsListSub, - coreSubscriptions.subscribe('postsListUsers', this._terms) - ]; - }, - data: function () { - this._terms = { - view: this.view, - limit: this.params.limit || getSetting('postsPerPage', 10), - category: this.params.slug - }; - - if(Meteor.isClient) { - this._terms.query = Session.get("searchQuery"); - } - - var parameters = getPostsParameters(this._terms), - postsCount = Posts.find(parameters.find, parameters.options).count(); - - parameters.find.createdAt = { $lte: Session.get('listPopulatedAt') }; - var posts = Posts.find(parameters.find, parameters.options); - - // Incoming posts - parameters.find.createdAt = { $gt: Session.get('listPopulatedAt') }; - var postsIncoming = Posts.find(parameters.find, parameters.options); - - Session.set('postsLimit', this._terms.limit); - - return { - incoming: postsIncoming, - postsList: posts, - postsCount: postsCount, - ready: this.postsListSub.ready - }; - }, - onAfterAction: function() { - Session.set('view', this.view); - } -}); - -PostsTopController = PostsListController.extend({ - view: 'top' -}); - -PostsNewController = PostsListController.extend({ - view: 'new' -}); - -PostsBestController = PostsListController.extend({ - view: 'best' -}); - -PostsPendingController = PostsListController.extend({ - view: 'pending' -}); - -// Controller for post digest - -PostsDigestController = FastRender.RouteController.extend({ - template: getTemplate('posts_digest'), - waitOn: function() { - // if day is set, use that. If not default to today - var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : new Date(), - terms = { - view: 'digest', - after: moment(currentDate).startOf('day').toDate(), - before: moment(currentDate).endOf('day').toDate() - }; - return [ - coreSubscriptions.subscribe('postsList', terms), - coreSubscriptions.subscribe('postsListUsers', terms) - ]; - }, - data: function() { - var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : Session.get('today'), - terms = { - view: 'digest', - after: moment(currentDate).startOf('day').toDate(), - before: moment(currentDate).endOf('day').toDate() - }, - parameters = getPostsParameters(terms); - Session.set('currentDate', currentDate); - - parameters.find.createdAt = { $lte: Session.get('listPopulatedAt') }; - var posts = Posts.find(parameters.find, parameters.options); - - // Incoming posts - parameters.find.createdAt = { $gt: Session.get('listPopulatedAt') }; - var postsIncoming = Posts.find(parameters.find, parameters.options); - - return { - incoming: postsIncoming, - posts: posts - }; - } -}); - -// Controller for post pages - -PostPageController = FastRender.RouteController.extend({ - waitOn: function() { - this.postSubscription = coreSubscriptions.subscribe('singlePost', this.params._id); - this.postUsersSubscription = coreSubscriptions.subscribe('postUsers', this.params._id); - this.commentSubscription = coreSubscriptions.subscribe('postComments', this.params._id); - }, - - post: function() { - return Posts.findOne(this.params._id); - }, - - onBeforeAction: function(pause) { - if (! this.post()) { - if (this.postSubscription.ready()) { - this.render(getTemplate('not_found')); - return pause(); - } - - this.render(getTemplate('loading')); - pause(); - } - }, - - data: function() { - return this.post(); - } -}); - - -// Controller for comment pages - -CommentPageController = FastRender.RouteController.extend({ - waitOn: function() { - return [ - coreSubscriptions.subscribe('singleComment', this.params._id), - coreSubscriptions.subscribe('commentUser', this.params._id), - coreSubscriptions.subscribe('commentPost', this.params._id) - ]; - }, - data: function() { - return { - comment: Comments.findOne(this.params._id) - }; - }, - onAfterAction: function () { - window.queueComments = false; - } -}); - -// Controller for user pages - -UserPageController = FastRender.RouteController.extend({ - waitOn: function() { - return [ - coreSubscriptions.subscribe('userProfile', this.params._idOrSlug) - ] - }, - data: function() { - var findById = Meteor.users.findOne(this.params._idOrSlug); - var findBySlug = Meteor.users.findOne({slug: this.params._idOrSlug}); - if(typeof findById !== "undefined"){ - // redirect to slug-based URL - Router.go(getProfileUrl(findById), {replaceState: true}); - }else{ - return { - user: (typeof findById == "undefined") ? findBySlug : findById - }; - } - } -}); - -// Controller for user account editing - -AccountController = FastRender.RouteController.extend({ - waitOn: function() { - return coreSubscriptions.subscribe('invites'); - }, - data: function() { - return { - user : Meteor.user(), - invites: Invites.find({invitingUserId:Meteor.userId()}) - }; - } -}); - -var getDefaultViewController = function () { - var defaultView = getSetting('defaultView', 'top'); - defaultView = defaultView.charAt(0).toUpperCase() + defaultView.slice(1); - return eval("Posts"+defaultView+"Controller"); -}; - -//--------------------------------------------------------------------------------------------------// -//--------------------------------------------- Routes ---------------------------------------------// -//--------------------------------------------------------------------------------------------------// -Meteor.startup(function () { - - Router.map(function() { - - // -------------------------------------------- Post Lists -------------------------------------------- // - - this.route('posts_default', { - path: '/', - controller: getDefaultViewController() - }); - - this.route('posts_top', { - path: '/top/:limit?', - controller: PostsTopController - }); - - // New - - this.route('posts_new', { - path: '/new/:limit?', - controller: PostsNewController - }); - - // Best - - this.route('posts_best', { - path: '/best/:limit?', - controller: PostsBestController - }); - - // Pending - - this.route('posts_pending', { - path: '/pending/:limit?', - controller: PostsPendingController - }); - - - - // TODO: enable /category/new, /category/best, etc. views - - - // Digest - - this.route('posts_digest', { - path: '/digest/:year/:month/:day', - controller: PostsDigestController - }); - - this.route('posts_digest', { - path: '/digest', - controller: PostsDigestController - }); - - // -------------------------------------------- Post -------------------------------------------- // - - - // Post Page - - this.route('post_page', { - template: getTemplate('post_page'), - path: '/posts/:_id', - controller: PostPageController - }); - - this.route('post_page', { - template: getTemplate('post_page'), - path: '/posts/:_id/comment/:commentId', - controller: PostPageController, - onAfterAction: function () { - // TODO: scroll to comment position - } - }); - - // Post Edit - - this.route('post_edit', { - template: getTemplate('post_edit'), - path: '/posts/:_id/edit', - waitOn: function () { - return [ - coreSubscriptions.subscribe('singlePost', this.params._id), - coreSubscriptions.subscribe('allUsersAdmin') - ]; - }, - data: function() { - return { - postId: this.params._id, - post: Posts.findOne(this.params._id) - }; - }, - fastRender: true - }); - - // Post Submit - - this.route('post_submit', { - template: getTemplate('post_submit'), - path: '/submit' - }); - - // -------------------------------------------- Comment -------------------------------------------- // - - // Comment Reply - - this.route('comment_reply', { - template: getTemplate('comment_reply'), - path: '/comments/:_id', - controller: CommentPageController, - onAfterAction: function() { - window.queueComments = false; - } - }); - - // Comment Edit - - this.route('comment_edit', { - template: getTemplate('comment_edit'), - path: '/comments/:_id/edit', - controller: CommentPageController, - onAfterAction: function() { - window.queueComments = false; - } - }); - - // -------------------------------------------- Users -------------------------------------------- // - - // User Logout - - this.route('signOut', { - path: '/sign-out', - onBeforeAction: function(pause) { - Meteor.logout(function() { - return Router.go('/'); - }); - return pause(); - } - }); - - // User Profile - - this.route('user_profile', { - template: getTemplate('user_profile'), - path: '/users/:_idOrSlug', - controller: UserPageController - }); - - // User Edit - - this.route('user_edit', { - template: getTemplate('user_edit'), - path: '/users/:_idOrSlug/edit', - controller: UserPageController - }); - - // Account - - this.route('account', { - template: getTemplate('user_edit'), - path: '/account', - controller: AccountController - }); - - // All Users - - this.route('all-users', { - template: getTemplate('users'), - path: '/all-users/:limit?', - waitOn: function() { - var limit = parseInt(this.params.limit) || 20; - return coreSubscriptions.subscribe('allUsers', this.params.filterBy, this.params.sortBy, limit); - }, - data: function() { - var limit = parseInt(this.params.limit) || 20, - parameters = getUsersParameters(this.params.filterBy, this.params.sortBy, limit), - filterBy = (typeof this.params.filterBy === 'string') ? this.params.filterBy : 'all', - sortBy = (typeof this.params.sortBy === 'string') ? this.params.sortBy : 'createdAt'; - Session.set('usersLimit', limit); - return { - users: Meteor.users.find(parameters.find, parameters.options), - filterBy: filterBy, - sortBy: sortBy - }; - }, - fastRender: true - }); - - // Unsubscribe (from notifications) - - this.route('unsubscribe', { - template: getTemplate('unsubscribe'), - path: '/unsubscribe/:hash', - data: function() { - return { - hash: this.params.hash - }; - } - }); - - // -------------------------------------------- Other -------------------------------------------- // - - - - // Settings - - this.route('settings', { - template: getTemplate('settings'), - data: function () { - // we only have one set of settings for now - return { - hasSettings: !!Settings.find().count(), - settings: Settings.findOne() - } - } - }); - - // Loading (for testing purposes) - - this.route('loading', { - template: getTemplate('loading') - }); - - // Toolbox - - this.route('toolbox',{ - template: getTemplate('toolbox') - }); - - // -------------------------------------------- Server-Side -------------------------------------------- // - - // Link Out - - this.route('out', { - where: 'server', - path: '/out', - action: function(){ - var query = this.request.query; - if(query.url){ - var decodedUrl = decodeURIComponent(query.url); - var post = Posts.findOne({url: decodedUrl}); - if(post){ - Posts.update(post._id, {$inc: {clicks: 1}}); - } - this.response.writeHead(302, {'Location': query.url}); - this.response.end(); - } - } - }); - - // Notification email - - this.route('notification', { - where: 'server', - path: '/email/notification/:id?', - action: function() { - var notification = Notifications.findOne(this.params.id); - var notificationContents = buildEmailNotification(notification); - this.response.write(notificationContents.html); - this.response.end(); - } - }); - - // New user email - - this.route('newUser', { - where: 'server', - path: '/email/new-user/:id?', - action: function() { - var user = Meteor.users.findOne(this.params.id); - var emailProperties = { - profileUrl: getProfileUrl(user), - username: getUserName(user) - }; - console.log(Handlebars); - - console.log(Handlebars.templates); - - html = getEmailTemplate('emailNewUser')(emailProperties); - this.response.write(buildEmailTemplate(html)); - this.response.end(); - } - }); - - // New post email - - this.route('newPost', { - where: 'server', - path: '/email/new-post/:id?', - action: function() { - var post = Posts.findOne(this.params.id); - html = Handlebars.templates[getTemplate('emailNewPost')](getPostProperties(post)); - this.response.write(buildEmailTemplate(html)); - this.response.end(); - } - }); - - // Account approved email - - this.route('accountApproved', { - where: 'server', - path: '/email/account-approved/:id?', - action: function() { - var user = Meteor.users.findOne(this.params.id); - var emailProperties = { - profileUrl: getProfileUrl(user), - username: getUserName(user), - siteTitle: getSetting('title'), - siteUrl: getSiteUrl() - }; - html = Handlebars.templates[getTemplate('emailAccountApproved')](emailProperties); - this.response.write(buildEmailTemplate(html)); - this.response.end(); - } - }); - }); - -}); - -// adding common subscriptions that's need to be loaded on all the routes -// notification does not included here since it is not much critical and -// it might have considerable amount of docs -if(Meteor.isServer) { - FastRender.onAllRoutes(function() { - var router = this; - _.each(preloadSubscriptions, function(sub){ - router.subscribe(sub); - }); - }); -} diff --git a/packages/telescope-embedly/lib/client/autoform-postthumbnail.js b/packages/telescope-embedly/lib/client/autoform-postthumbnail.js index 1e3628810..9dd66f28a 100644 --- a/packages/telescope-embedly/lib/client/autoform-postthumbnail.js +++ b/packages/telescope-embedly/lib/client/autoform-postthumbnail.js @@ -32,7 +32,7 @@ Template.afPostThumbnail.rendered = function () { var url = $urlField.val(); if (!!url) { $thumbnailContainer.addClass('loading'); - clearSeenErrors(); + clearSeenMessages(); console.log('getting embedly data for '+url); Meteor.call('getEmbedlyData', url, function (error, data) { if (error) { From d2d581fca909f350921329a2f2ecfa8d476d572d Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Sat, 6 Dec 2014 17:49:17 +0900 Subject: [PATCH 4/5] rename errors to messages --- client/views/common/error.html | 5 ----- client/views/common/error.js | 8 -------- client/views/common/error_item.js | 10 ---------- client/views/common/layout.html | 2 +- client/views/common/layout.js | 4 ++-- .../common/{error_item.html => message_item.html} | 2 +- client/views/common/message_item.js | 10 ++++++++++ client/views/common/messages.html | 5 +++++ client/views/common/messages.js | 8 ++++++++ 9 files changed, 27 insertions(+), 27 deletions(-) delete mode 100644 client/views/common/error.html delete mode 100644 client/views/common/error.js delete mode 100644 client/views/common/error_item.js rename client/views/common/{error_item.html => message_item.html} (83%) create mode 100644 client/views/common/message_item.js create mode 100644 client/views/common/messages.html create mode 100644 client/views/common/messages.js diff --git a/client/views/common/error.html b/client/views/common/error.html deleted file mode 100644 index a23e81796..000000000 --- a/client/views/common/error.html +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/client/views/common/error.js b/client/views/common/error.js deleted file mode 100644 index 2a31e8486..000000000 --- a/client/views/common/error.js +++ /dev/null @@ -1,8 +0,0 @@ -Template[getTemplate('error')].helpers({ - error_item: function () { - return getTemplate('error_item'); - }, - errors: function(){ - return Messages.find({show: true}); - } -}); \ No newline at end of file diff --git a/client/views/common/error_item.js b/client/views/common/error_item.js deleted file mode 100644 index ba209e730..000000000 --- a/client/views/common/error_item.js +++ /dev/null @@ -1,10 +0,0 @@ -Template[getTemplate('error_item')].helpers({ - -}); - -Template[getTemplate('error_item')].created = function(){ - var error_id=this.data._id; - Meteor.setTimeout(function(){ - Errors.update(error_id, {$set: {seen:true}}); - }, 100); -}; \ No newline at end of file diff --git a/client/views/common/layout.html b/client/views/common/layout.html index f3b558c2d..f96d6242f 100644 --- a/client/views/common/layout.html +++ b/client/views/common/layout.html @@ -6,7 +6,7 @@
{{> UI.dynamic template=nav}}
- {{> UI.dynamic template=error}} + {{> UI.dynamic template=messages}} {{#each heroModules}} {{> UI.dynamic template=getTemplate}} {{/each}} diff --git a/client/views/common/layout.js b/client/views/common/layout.js index 9b7f7af13..a05481507 100644 --- a/client/views/common/layout.js +++ b/client/views/common/layout.js @@ -5,8 +5,8 @@ Template[getTemplate('layout')].helpers({ nav: function () { return getTemplate('nav'); }, - error: function () { - return getTemplate('error'); + messages: function () { + return getTemplate('messages'); }, notifications: function () { return getTemplate('notifications'); diff --git a/client/views/common/error_item.html b/client/views/common/message_item.html similarity index 83% rename from client/views/common/error_item.html rename to client/views/common/message_item.html index d3e70b128..8ad685875 100644 --- a/client/views/common/error_item.html +++ b/client/views/common/message_item.html @@ -1,4 +1,4 @@ -