paginating user profile on the client

This commit is contained in:
Sacha Greif 2014-09-03 09:46:39 +09:00
parent 01916ef0ee
commit 6dee86463a
6 changed files with 109 additions and 121 deletions

View file

@ -69,6 +69,13 @@
<td>{{formatDate createdAt "MM/DD/YYYY, HH:mm"}}</td>
</tr>
{{/each}}
{{#if hasMorePosts}}
<tr>
<td colspan="2">
<a class="posts-more more-button grid-module" href="#"><span>{{i18n "Load more"}}</span></a>
</td>
</tr>
{{/if}}
</table>
</div>
@ -87,6 +94,13 @@
<td>{{formatDate votedAt "MM/DD/YYYY, HH:mm"}}</td>
</tr>
{{/each}}
{{#if hasMoreUpvotedPosts}}
<tr>
<td colspan="2">
<a class="upvotedposts-more more-button grid-module" href="#"><span>{{i18n "Load more"}}</span></a>
</td>
</tr>
{{/if}}
</table>
</div>
@ -105,6 +119,13 @@
<td>{{formatDate votedAt "MM/DD/YYYY, HH:mm"}}</td>
</tr>
{{/each}}
{{#if hasMoreDownvotedPosts}}
<tr>
<td colspan="2">
<a class="downvoted-more more-button grid-module" href="#"><span>{{i18n "Load more"}}</span></a>
</td>
</tr>
{{/if}}
</table>
</div>
@ -125,6 +146,13 @@
<td>{{formatDate createdAt "MM/DD/YYYY, HH:mm"}}</td>
</tr>
{{/each}}
{{#if hasMoreComments}}
<tr>
<td colspan="2">
<a class="comments-more more-button grid-module" href="#"><span>{{i18n "Load more"}}</span></a>
</td>
</tr>
{{/if}}
</table>
</div>

View file

@ -1,3 +1,10 @@
Template[getTemplate('user_profile')].created = function () {
Session.set('postsShown', 5);
Session.set('upvotedPostsShown', 5);
Session.set('downvotedPostsShown', 5);
Session.set('commentsShown', 5);
}
Template[getTemplate('user_profile')].helpers({
avatarUrl: function() {
return getAvatarUrl(this);
@ -23,7 +30,10 @@ Template[getTemplate('user_profile')].helpers({
return getGitHubName(this);
},
posts: function () {
return Posts.find({userId: this._id});
return Posts.find({userId: this._id}, {limit: Session.get('postsShown')});
},
hasMorePosts: function () {
return Posts.find({userId: this._id}).count() > Session.get('postsShown');
},
upvotedPosts: function () {
// extend upvotes with each upvoted post
@ -32,9 +42,12 @@ Template[getTemplate('user_profile')].helpers({
var post = Posts.findOne(item.itemId);
return _.extend(item, post);
});
return extendedVotes
return _.first(extendedVotes, Session.get('upvotedPostsShown'));
}
},
hasMoreUpvotedPosts: function () {
return !!this.votes.upvotedPosts && this.votes.upvotedPosts.length > Session.get('upvotedPostsShown');
},
downvotedPosts: function () {
// extend upvotes with each upvoted post
if(!!this.votes.downvotedPosts){
@ -42,11 +55,14 @@ Template[getTemplate('user_profile')].helpers({
var post = Posts.findOne(item.itemId);
return _.extend(item, post);
});
return extendedVotes
return _.first(extendedVotes, Session.get('downvotedPostsShown'));
}
},
},
hasMoreDownvotedPosts: function () {
return !!this.votes.downvotedPosts && this.votes.downvotedPosts.length > Session.get('downvotedPostsShown');
},
comments: function () {
var comments = Comments.find({userId: this._id})
var comments = Comments.find({userId: this._id}, {limit: Session.get('commentsShown')});
if(!!comments){
// extend comments with each commented post
var extendedComments = comments.map(function (comment) {
@ -57,6 +73,9 @@ Template[getTemplate('user_profile')].helpers({
});
return extendedComments
}
},
hasMoreComments: function () {
return Comments.find({userId: this._id}).count() > Session.get('commentsShown');
}
});
@ -64,5 +83,25 @@ Template[getTemplate('user_profile')].events({
'click .invite-link': function(e, instance){
Meteor.call('inviteUser', instance.data.user._id);
throwError('Thanks, user has been invited.')
},
'click .posts-more': function (e) {
e.preventDefault();
var postsShown = Session.get('postsShown');
Session.set('postsShown', postsShown + 10);
},
'click .upvotedposts-more': function (e) {
e.preventDefault();
var upvotedPostsShown = Session.get('upvotedPostsShown');
Session.set('upvotedPostsShown', upvotedPostsShown + 10);
},
'click .downvotedposts-more': function (e) {
e.preventDefault();
var downvotedPostsShown = Session.get('downvotedPostsShown');
Session.set('downvotedPostsShown', downvotedPostsShown + 10);
},
'click .comments-more': function (e) {
e.preventDefault();
var commentsShown = Session.get('commentsShown');
Session.set('commentsShown', commentsShown + 10);
}
});

View file

@ -427,8 +427,7 @@ CommentPageController = FastRender.RouteController.extend({
UserPageController = FastRender.RouteController.extend({
waitOn: function() {
return [
coreSubscriptions.subscribe('singleUser', this.params._idOrSlug),
coreSubscriptions.subscribe('userData', this.params._idOrSlug)
coreSubscriptions.subscribe('userProfile', this.params._idOrSlug)
]
},
data: function() {

View file

@ -1,71 +0,0 @@
// buildEmailTemplate = function (htmlContent) {
// var emailProperties = {
// headerColor: getSetting('headerColor', '#444444'),
// buttonColor: getSetting('buttonColor', '#DD3416'),
// siteName: getSetting('title'),
// tagline: getSetting('tagline'),
// siteUrl: getSiteUrl(),
// body: htmlContent,
// unsubscribe: '',
// accountLink: getSiteUrl()+'account',
// footer: getSetting('emailFooter'),
// logoUrl: getSetting('logoUrl'),
// logoHeight: getSetting('logoHeight'),
// logoWidth: getSetting('logoWidth')
// }
// var emailHTML = getEmailTemplate('emailWrapper')(emailProperties);
// var inlinedHTML = Async.runSync(function(done) {
// Juice.juiceContent(emailHTML, {
// url: getSiteUrl(),
// removeStyleTags: false
// }, function (error, result) {
// done(null, result);
// });
// }).result;
// var doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
// return doctype+inlinedHTML;
// }
// sendEmail = function(to, subject, html, text){
// // TODO: limit who can send emails
// // TODO: fix this error: Error: getaddrinfo ENOTFOUND
// var from = getSetting('defaultEmail', 'noreply@example.com');
// var siteName = getSetting('title');
// var subject = '['+siteName+'] '+subject;
// if (typeof text == 'undefined'){
// // Auto-generate text version if it doesn't exist. Has bugs, but should be good enough.
// var text = HtmlToText.fromString(html, {
// wordwrap: 130
// });
// }
// console.log('//////// sending email…');
// console.log('from: '+from);
// console.log('to: '+to);
// console.log('subject: '+subject);
// // console.log('html: '+html);
// // console.log('text: '+text);
// Email.send({
// from: from,
// to: to,
// subject: subject,
// text: text,
// html: html
// });
// };
// buildAndSendEmail = function (to, subject, template, properties) {
// var html = buildEmailTemplate(getEmailTemplate(template)(properties));
// sendEmail (to, subject, buildEmailTemplate(html));
// }

View file

@ -43,7 +43,6 @@ buildEmailNotification = function (notification) {
}
newPostNotification = function(post, excludedIDs){
var excludedIDs = typeof excludedIDs == 'undefined' ? [] : excludedIDs;
var p = getPostProperties(post);
var subject = p.postAuthorName+' has created a new post: '+p.postTitle;

View file

@ -23,54 +23,48 @@ Meteor.publish('currentUser', function() {
// Publish a single user
Meteor.publish('singleUser', function(userIdOrSlug) {
Meteor.publish('userProfile', function(userIdOrSlug) {
if(canViewById(this.userId)){
var options = isAdminById(this.userId) ? {limit: 1} : {limit: 1, fields: privacyOptions};
var findById = Meteor.users.find(userIdOrSlug, options);
var findBySlug = Meteor.users.find({slug: userIdOrSlug}, options);
// if we find something when treating the argument as an ID, return that; else assume it's a slug
return findById.count() ? findById : findBySlug;
var findById = Meteor.users.findOne(userIdOrSlug);
var findBySlug = Meteor.users.findOne({slug: userIdOrSlug});
var user = typeof findById !== 'undefined' ? findById : findBySlug;
// user's own posts
var userPosts = Posts.find({userId: user._id});
var postsIds = _.pluck(userPosts.fetch(), '_id');
// user's own comments
var userComments = Comments.find({userId: user._id});
var commentsIds = _.pluck(userComments.fetch(), '_id');
// add upvoted posts ids
var postsIds = postsIds.concat(_.pluck(user.votes.upvotedPosts, 'itemId'));
// add upvoted comments ids
var commentsIds = commentsIds.concat(_.pluck(user.votes.upvotedComments, 'itemId'));
// add downvoted posts ids
var postsIds = postsIds.concat(_.pluck(user.votes.downvotedPosts, 'itemId'));
// add downvoted comments ids
var commentsIds = commentsIds.concat(_.pluck(user.votes.downvotedComments, 'itemId'));
// add commented posts ids
if(!!userComments.count()){ // there might not be any comments
var commentedPostIds = _.pluck(userComments.fetch(), 'postId');
var postsIds = postsIds.concat(commentedPostIds);
}
return [
Meteor.users.find({_id: user._id}, options),
Comments.find({_id: {$in: commentsIds}}),
Posts.find({_id: {$in: postsIds}})
];
}
return [];
});
Meteor.publish('userData', function(userIdOrSlug) {
var findById = Meteor.users.findOne(userIdOrSlug);
var findBySlug = Meteor.users.findOne({slug: userIdOrSlug});
var user = typeof findById !== 'undefined' ? findById : findBySlug;
// user's own posts
var userPosts = Posts.find({userId: user._id});
var postsIds = _.pluck(userPosts.fetch(), '_id');
// user's own comments
var userComments = Comments.find({userId: user._id});
var commentsIds = _.pluck(userComments.fetch(), '_id');
// add upvoted posts ids
var postsIds = postsIds.concat(_.pluck(user.votes.upvotedPosts, 'itemId'));
// add upvoted comments ids
var commentsIds = commentsIds.concat(_.pluck(user.votes.upvotedComments, 'itemId'));
// add downvoted posts ids
var postsIds = postsIds.concat(_.pluck(user.votes.downvotedPosts, 'itemId'));
// add downvoted comments ids
var commentsIds = commentsIds.concat(_.pluck(user.votes.downvotedComments, 'itemId'));
// add commented posts ids
if(!!userComments.count()){ // there might not be any comments
var commentedPostIds = _.pluck(userComments.fetch(), 'postId');
var postsIds = postsIds.concat(commentedPostIds);
}
return [
Comments.find({_id: {$in: commentsIds}}),
Posts.find({_id: {$in: postsIds}})
];
});
// Publish authors of the current post and its comments
Meteor.publish('postUsers', function(postId) {