diff --git a/client/app.js b/client/app.js
index ea71b02cb..fa117b434 100644
--- a/client/app.js
+++ b/client/app.js
@@ -28,4 +28,25 @@ $.fn.exists = function () {
$(document).bind('keyup', 'ctrl+n', function(){
$('.notifications').toggleClass('hidden');
+});
+
+Handlebars.registerHelper('canView', function(redirect) {
+ var redirect=(redirect=="true");
+ return canView(Meteor.user(), redirect);
+});
+Handlebars.registerHelper('canPost', function(redirect) {
+ var redirect=(redirect=="true");
+ return canPost(Meteor.user(), redirect);
+});
+Handlebars.registerHelper('canComment', function(redirect) {
+ var redirect=(redirect=="true");
+ return canComment(Meteor.user(), redirect);
+});
+Handlebars.registerHelper('canUpvote', function(collection, redirect) {
+ var redirect=(redirect=="true");
+ return canUpvote(Meteor.user()), collection, redirect;
+});
+Handlebars.registerHelper('canDownvote', function(collection, redirect) {
+ var redirect=(redirect=="true");
+ return canDownvote(Meteor.user(), collection, redirect);
});
\ No newline at end of file
diff --git a/client/body.html b/client/body.html
index d1b8f8fdb..01b35a49a 100644
--- a/client/body.html
+++ b/client/body.html
@@ -1,8 +1,10 @@
- {{> nav}}
- {{> error}}
- {{{render currentPage}}}
- {{> notifications}}
- {{> footer}}
-
+ {{#if canView}}
+ {{> nav}}
+ {{/if}}
+ {{> error}}
+ {{{render currentPage}}}
+ {{> notifications}}
+ {{> footer}}
+
\ No newline at end of file
diff --git a/client/lib/router.js b/client/lib/router.js
index 5f0466b45..fcc178559 100644
--- a/client/lib/router.js
+++ b/client/lib/router.js
@@ -8,7 +8,6 @@ SimpleRouter = FilteredRouter.extend({
start_request: function(page){
// runs at every new page change
- Session.set("error", null);
Session.set("openedComments", null);
document.title = getSetting("title");
@@ -94,6 +93,7 @@ SimpleRouter = FilteredRouter.extend({
'posts/:id':'post',
'comments/deleted':'comment_deleted',
'comments/:id':'comment',
+ 'comments/:id/reply':'comment_reply',
'comments/:id/edit':'comment_edit',
'settings':'settings',
'admin':'admin',
@@ -134,12 +134,19 @@ SimpleRouter = FilteredRouter.extend({
},
comment: function(id) {
console.log("comment, id="+id);
- window.template='comment_page';
Session.set('selectedCommentId', id);
this.goto('comment_page');
window.repress_recursion=true;
window.newCommentTimestamp=new Date();
},
+ comment_reply: function(id) {
+ console.log("comment reply, id="+id);
+ window.template='comment_reply';
+ Session.set('selectedCommentId', id);
+ this.goto('comment_reply');
+ window.repress_recursion=true;
+ window.newCommentTimestamp=new Date();
+ },
comment_edit: function(id) {
console.log("comment_edit, id="+id);
window.template='comment_edit';
diff --git a/client/views/comments/comment_form.js b/client/views/comments/comment_form.js
index 22d75519a..e56c81135 100644
--- a/client/views/comments/comment_form.js
+++ b/client/views/comments/comment_form.js
@@ -11,7 +11,7 @@ Template.comment_form.events = {
var $comment = $('#comment');
var content = instance.editor.exportFile();
- if(window.template=='comment_page'){
+ if(window.template=='comment_reply'){
// child comment
var parentCommentId=Session.get('selectedCommentId');
var parentComment=Comments.findOne(parentCommentId);
diff --git a/client/views/comments/comment_item.html b/client/views/comments/comment_item.html
index 0578421f6..c21516b7b 100644
--- a/client/views/comments/comment_item.html
+++ b/client/views/comments/comment_item.html
@@ -28,7 +28,7 @@
{{/if}}
-
+
{{#unless repress_recursion}}
diff --git a/client/views/comments/comment_page.html b/client/views/comments/comment_page.html
index af3e527bf..3fdd25ea4 100644
--- a/client/views/comments/comment_page.html
+++ b/client/views/comments/comment_page.html
@@ -1,11 +1,6 @@
{{#if canView}}
{{/if}}
diff --git a/client/views/comments/comment_page.js b/client/views/comments/comment_page.js
index 423046409..a38da2b69 100644
--- a/client/views/comments/comment_page.js
+++ b/client/views/comments/comment_page.js
@@ -8,11 +8,5 @@ Template.comment_page.helpers({
var comment = Comments.findOne(Session.get('selectedCommentId'));
Template.comment_page.repress_recursion = true;
return comment;
- },
- canComment: function(){
- return canComment(Meteor.user());
- },
- canView: function(){
- return canView(Meteor.user());
}
});
\ No newline at end of file
diff --git a/client/views/comments/comment_reply.html b/client/views/comments/comment_reply.html
new file mode 100644
index 000000000..de0bbae68
--- /dev/null
+++ b/client/views/comments/comment_reply.html
@@ -0,0 +1,21 @@
+
+ {{#if canComment true}}
+
+ {{/if}}
+
diff --git a/client/views/comments/comment_reply.js b/client/views/comments/comment_reply.js
new file mode 100644
index 000000000..49a288eb2
--- /dev/null
+++ b/client/views/comments/comment_reply.js
@@ -0,0 +1,12 @@
+Template.comment_reply.post = function(){
+ var selectedComment = Comments.findOne(Session.get('selectedCommentId'));
+ return selectedComment && Posts.findOne(selectedComment.post);
+};
+
+Template.comment_reply.helpers({
+ comment: function(){
+ var comment = Comments.findOne(Session.get('selectedCommentId'));
+ Template.comment_page.repress_recursion = true;
+ return comment;
+ }
+});
\ No newline at end of file
diff --git a/client/views/common/error.html b/client/views/common/error.html
index 836a0ffe9..f15ca7fe7 100644
--- a/client/views/common/error.html
+++ b/client/views/common/error.html
@@ -2,7 +2,9 @@
{{#if message}}
+ {{#constant}}
{{message}}
+ {{/constant}}
{{/if}}
diff --git a/client/views/common/error.js b/client/views/common/error.js
index e68cef7c0..ea9bc8208 100644
--- a/client/views/common/error.js
+++ b/client/views/common/error.js
@@ -1,6 +1,22 @@
Template.error.message= function(){
- return Session.get("error");
+ var outerContext = Meteor.deps.Context.current;
+ var innerContext = new Meteor.deps.Context;
+ var error;
+
+ innerContext.onInvalidate(function() {
+ // we don't need to send the invalidate through anymore if post is set
+ error || outerContext.invalidate();
+ });
+
+ innerContext.run(function() {
+ error = Session.get("error");
+ });
+
+ return error;
}
Template.error.rendered = function(){
+ Meteor.setTimeout(function(){
+ Session.set("error", null);
+ }, 100);
}
\ No newline at end of file
diff --git a/client/views/posts/post_edit.js b/client/views/posts/post_edit.js
index c22983ee9..674315bc8 100644
--- a/client/views/posts/post_edit.js
+++ b/client/views/posts/post_edit.js
@@ -26,7 +26,7 @@ Template.post_edit.helpers({
innerContext.run(function() {
post = Posts.findOne(Session.get('selectedPostId'));
- })
+ });
return post;
}
diff --git a/lib/users.js b/lib/users.js
index ab039221f..6d90822a7 100644
--- a/lib/users.js
+++ b/lib/users.js
@@ -48,61 +48,75 @@ userProfileComplete = function(user) {
// Permissions
-canView = function(user){
+// user: Defaults to Meteor.user()
+// redirect: Defaults to false. If false, the permission check will fail silently
+// If true, a failed permission check will throw an error message and redirect the user
+canView = function(user, redirect){
+ var user=(typeof user === 'undefined') ? Meteor.user() : user;
+ var redirect=(typeof redirect === 'undefined') ? false : redirect;
if(getSetting('requireViewInvite')==true){
+ try{
+ if(!user){
+ throw "no_account";
+ }else if(isAdmin(user) || user.isInvited){
+ return true;
+ }else{
+ throw "no_invite";
+ }
+ }catch(error){
+ if(redirect)
+ Router.goto(error);
+ return false;
+ }
+ }else{
+ return true;
+ }
+}
+canPost = function(user, redirect){
+ var user=(typeof user === 'undefined') ? Meteor.user() : user;
+ var redirect=(typeof redirect === 'undefined') ? false : redirect;
+ try{
if(!user){
- Router.goto('no_account');
- return false;
- }
- if(isAdmin(user))
- return true;
- if(user.isInvited){
+ throw "no_account";
+ }else if(isAdmin(user)){
return true;
+ }else if(getSetting('requirePostInvite')){
+ if(user.isInvited){
+ return true;
+ }else{
+ throw "no_invite";
+ }
}else{
- Router.goto('no_invite');
- return false;
+ return true;
}
-
- }
- return true;
-}
-canUpvote = function(user, collection){
- if(!user)
- return false
- if(isAdmin(user))
- return true;
- if(getSetting('requirePostInvite')==true){
- return user.isInvited;
- }
- return true;
-}
-canDownvote = function(user, collection){
- if(!user)
- return false
- if(isAdmin(user))
- return true;
- if(getSetting('requirePostInvite')==true){
- return user.isInvited;
- }
- return true;
-}
-canPost = function(user){
- if(!user)
- return false
- if(isAdmin(user))
- return true;
- if(getSetting('requirePostInvite')==true){
- return user.isInvited;
- }
- return true;
-}
-canComment = function(user){
- if(!user)
+ }catch(error){
+ if(redirect){
+ switch(error){
+ case "no_account":
+ throwError("Please sign in or create an account first.");
+ Router.goto('signin');
+ break;
+ case "no_invite":
+ throwError("Sorry, you need to have an invitation to do this.");
+ Router.goto("no_invite");
+ break;
+ }
+ }
return false;
- if(isAdmin(user))
- return true;
- if(getSetting('requirePostInvite')==true){
- return user.isInvited;
}
- return true;
+}
+canComment = function(user, redirect){
+ var user=(typeof user === 'undefined') ? Meteor.user() : user;
+ var redirect=(typeof redirect === 'undefined') ? false : redirect;
+ return canPost(user, redirect);
+}
+canUpvote = function(user, collection, redirect){
+ var user=(typeof user === 'undefined') ? Meteor.user() : user;
+ var redirect=(typeof redirect === 'undefined') ? false : redirect;
+ return canPost(user, redirect);
+}
+canDownvote = function(user, collection, redirect){
+ var user=(typeof user === 'undefined') ? Meteor.user() : user;
+ var redirect=(typeof redirect === 'undefined') ? false : redirect;
+ return canPost(user, redirect);
}
\ No newline at end of file