mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 10:01:40 -05:00
Massively simplified all the posts_lists using the paginatedSub.
This commit is contained in:
commit
0be912db24
14 changed files with 160 additions and 257 deletions
119
client/app.js
119
client/app.js
|
@ -56,101 +56,40 @@ STATUS_PENDING=1;
|
|||
STATUS_APPROVED=2;
|
||||
STATUS_REJECTED=3;
|
||||
FIND_APPROVED={$or: [{status: {$exists : false}}, {status: STATUS_APPROVED}]};
|
||||
TOP_PAGE_PER_PAGE = 10;
|
||||
NEW_PAGE_PER_PAGE = 10;
|
||||
BEST_PAGE_PER_PAGE = 10;
|
||||
PENDING_PAGE_PER_PAGE = 10;
|
||||
DIGEST_PAGE_PER_PAGE = 5;
|
||||
|
||||
// name <- the name of various session vars that will be set:
|
||||
// - 'nameReady' <- is the subscription loading or ready?
|
||||
// - 'nameLimit' <- how many of this type are we currently displaying?
|
||||
// options:
|
||||
// - find <- how to find the items
|
||||
// - sort <- how to sort them
|
||||
// - perPage <- how many to display per-page
|
||||
// -
|
||||
postsForSub = {};
|
||||
setupPostSubscription = function(name, options) {
|
||||
var readyName = name + 'Ready';
|
||||
var limitName = name + 'Limit';
|
||||
|
||||
if (options.perPage && ! Session.get(limitName))
|
||||
Session.set(limitName, options.perPage);
|
||||
|
||||
// setup the subscription
|
||||
Meteor.autosubscribe(function() {
|
||||
Session.set(readyName, false);
|
||||
|
||||
var findOptions = {
|
||||
sort: options.sort,
|
||||
limit: options.perPage && Session.get(limitName)
|
||||
};
|
||||
|
||||
var find = _.isFunction(options.find) ? options.find() : options.find;
|
||||
Meteor.subscribe('posts', find || {}, findOptions, name, function() {
|
||||
Session.set('initialLoad', false);
|
||||
Session.set(readyName, true);
|
||||
});
|
||||
});
|
||||
|
||||
// setup a function to find the relevant posts (+deal with mm's lack of limit)
|
||||
postsForSub[name] = function() {
|
||||
var find = _.isFunction(options.find) ? options.find() : options.find;
|
||||
var orderedPosts = Posts.find(find || {}, {sort: options.sort});
|
||||
if (options.perPage) {
|
||||
return limitDocuments(orderedPosts, Session.get(limitName));
|
||||
} else {
|
||||
return orderedPosts;
|
||||
}
|
||||
};
|
||||
var postListSubscription = function(find, options, per_page) {
|
||||
var handle = paginatedSubscription(per_page, 'paginatedPosts', find, options);
|
||||
handle.fetch = function() {
|
||||
return limitDocuments(Posts.find(find, options), handle.loaded());
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
// if(Session.get('selectedPostId')){
|
||||
setupPostSubscription('singlePost', {
|
||||
find: function() { return Session.get('selectedPostId'); }
|
||||
});
|
||||
// }
|
||||
var topPostsHandle = postListSubscription(FIND_APPROVED, {sort: {score: -1}}, 10);
|
||||
var newPostsHandle = postListSubscription(FIND_APPROVED, {sort: {submitted: -1}}, 10);
|
||||
var bestPostsHandle = postListSubscription(FIND_APPROVED, {sort: {baseScore: -1}}, 10);
|
||||
var pendingPostsHandle = postListSubscription(
|
||||
{$or: [{status: STATUS_PENDING}, {status: STATUS_REJECTED}]},
|
||||
{sort: {score: -1}},
|
||||
10
|
||||
);
|
||||
|
||||
setupPostSubscription('topPosts', {
|
||||
find: FIND_APPROVED,
|
||||
sort: {score: -1},
|
||||
perPage: TOP_PAGE_PER_PAGE
|
||||
});
|
||||
|
||||
setupPostSubscription('newPosts', {
|
||||
find: FIND_APPROVED,
|
||||
sort: {submitted: -1},
|
||||
perPage: NEW_PAGE_PER_PAGE
|
||||
});
|
||||
|
||||
setupPostSubscription('bestPosts', {
|
||||
find: FIND_APPROVED,
|
||||
sort: {baseScore: -1},
|
||||
perPage: NEW_PAGE_PER_PAGE
|
||||
});
|
||||
|
||||
setupPostSubscription('pendingPosts', {
|
||||
find: {$or: [{status: STATUS_PENDING}, {status: STATUS_REJECTED}]},
|
||||
sort: {score: -1},
|
||||
perPage: PENDING_PAGE_PER_PAGE
|
||||
});
|
||||
|
||||
setupPostSubscription('digestPosts', {
|
||||
find: function() {
|
||||
var mDate = moment(Session.get('currentDate'));
|
||||
var find = {
|
||||
submitted: {
|
||||
$gte: mDate.startOf('day').valueOf(),
|
||||
$lt: mDate.endOf('day').valueOf()
|
||||
}
|
||||
};
|
||||
find=_.extend(find, FIND_APPROVED);
|
||||
return find;
|
||||
},
|
||||
sort: {score: -1}
|
||||
,perPage: DIGEST_PAGE_PER_PAGE
|
||||
});
|
||||
// setupPostSubscription('digestPosts', {
|
||||
// find: function() {
|
||||
// var mDate = moment(Session.get('currentDate'));
|
||||
// var find = {
|
||||
// submitted: {
|
||||
// $gte: mDate.startOf('day').valueOf(),
|
||||
// $lt: mDate.endOf('day').valueOf()
|
||||
// }
|
||||
// };
|
||||
// find=_.extend(find, FIND_APPROVED);
|
||||
// return find;
|
||||
// },
|
||||
// sort: {score: -1}
|
||||
// ,perPage: DIGEST_PAGE_PER_PAGE
|
||||
// });
|
||||
|
||||
// ** Categories **
|
||||
|
||||
|
|
48
client/lib/paginated_sub.js
Normal file
48
client/lib/paginated_sub.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
PaginatedSubscriptionHandle = function(perPage) {
|
||||
this.perPage = perPage;
|
||||
this._limit = perPage;
|
||||
this._limitListeners = new Meteor.deps._ContextSet();
|
||||
this._loaded = 0;
|
||||
this._loadedListeners = new Meteor.deps._ContextSet();
|
||||
}
|
||||
|
||||
PaginatedSubscriptionHandle.prototype.loaded = function() {
|
||||
this._loadedListeners.addCurrentContext();
|
||||
return this._loaded;
|
||||
}
|
||||
|
||||
PaginatedSubscriptionHandle.prototype.limit = function() {
|
||||
this._limitListeners.addCurrentContext();
|
||||
return this._limit;
|
||||
}
|
||||
|
||||
PaginatedSubscriptionHandle.prototype.loading = function() {
|
||||
return this.loaded() < this.limit();
|
||||
}
|
||||
|
||||
PaginatedSubscriptionHandle.prototype.loadNextPage = function() {
|
||||
this._limit += this.perPage;
|
||||
this._limitListeners.invalidateAll();
|
||||
}
|
||||
|
||||
PaginatedSubscriptionHandle.prototype.done = function() {
|
||||
// XXX: check if subs that are canceled before they are ready ever fire ready?
|
||||
// if they do we need to increase loaded by perPage, not set it to limit
|
||||
this._loaded = this._limit;
|
||||
this._loadedListeners.invalidateAll();
|
||||
}
|
||||
|
||||
|
||||
paginatedSubscription = function (perPage/*, name, arguments */) {
|
||||
var handle = new PaginatedSubscriptionHandle(perPage);
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
Meteor.autosubscribe(function() {
|
||||
var subHandle = Meteor.subscribe.apply(this, args.concat([
|
||||
handle.limit(), function() { handle.done(); }
|
||||
]));
|
||||
handle.stop = subHandle.stop;
|
||||
});
|
||||
|
||||
return handle;
|
||||
}
|
|
@ -1,20 +1,4 @@
|
|||
(function() {
|
||||
|
||||
// XXX: could we just work this out programmatically based on the name?
|
||||
// -- fix this along with the general problem of subscription mess
|
||||
PAGE_SUBS = {
|
||||
'posts_top': 'topPostsReady',
|
||||
'posts_new': 'newPostsReady',
|
||||
'posts_best': 'bestPostsReady',
|
||||
'posts_pending': 'pendingPostsReady',
|
||||
'posts_digest': 'digestPostsReady',
|
||||
'post_page': 'singlePostReady',
|
||||
'post_edit': 'singlePostReady',
|
||||
'comment_page': 'commentReady',
|
||||
'comment_reply': 'commentReady',
|
||||
'comment_edit': 'commentReady'
|
||||
}
|
||||
|
||||
(function() {
|
||||
// specific router functions
|
||||
digest = function(year, month, day, view){
|
||||
var destination = (typeof view === 'undefined') ? 'posts_digest' : 'posts_digest_'+view
|
||||
|
@ -191,10 +175,6 @@
|
|||
return isAdmin(Meteor.user()) ? page : "no_rights";
|
||||
},
|
||||
|
||||
awaitSubscription: function(page) {
|
||||
return Session.equals(PAGE_SUBS[page], true) ? page : 'loading';
|
||||
},
|
||||
|
||||
// if the user is logged in but their profile isn't filled out enough
|
||||
requireProfile: function(page) {
|
||||
var user = Meteor.user();
|
||||
|
@ -220,7 +200,6 @@
|
|||
});
|
||||
//
|
||||
Meteor.Router.filter('requireProfile');
|
||||
Meteor.Router.filter('awaitSubscription', {only: ['posts_top', 'posts_new', 'posts_pending', 'posts_best']});
|
||||
Meteor.Router.filter('requireLogin', {only: ['comment_reply','post_submit']});
|
||||
Meteor.Router.filter('canView', {only: ['posts_top', 'posts_new', 'posts_digest', 'posts_best']});
|
||||
Meteor.Router.filter('isLoggedOut', {only: ['user_signin', 'user_signup']});
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<template name="posts_best">
|
||||
<div class="posts grid list">
|
||||
{{#each posts}}
|
||||
{{> post_item}}
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="grid more-button {{#if allPostsLoaded}} hidden {{/if}}">
|
||||
<a class="more-link" href="#">Load more</a>
|
||||
</div>
|
||||
</template>
|
|
@ -1,27 +0,0 @@
|
|||
Template.posts_best.posts = function() {
|
||||
return postsForSub.bestPosts();
|
||||
};
|
||||
|
||||
Template.posts_best.helpers({
|
||||
allPostsLoaded: function(){
|
||||
return postsForSub.bestPosts().length < Session.get('bestPostsLimit');
|
||||
}
|
||||
});
|
||||
|
||||
Template.posts_best.rendered = function(){
|
||||
var distanceFromTop = 0;
|
||||
$('.post').each(function(){
|
||||
distanceFromTop += $(this).height();
|
||||
});
|
||||
$('body').css('min-height',distanceFromTop+160);
|
||||
$('.more-button').css('top', distanceFromTop+"px");
|
||||
}
|
||||
|
||||
Template.posts_best.events({
|
||||
'click .more-link': function(e) {
|
||||
e.preventDefault();
|
||||
Session.set('currentScroll',$('body').scrollTop());
|
||||
Session.set('bestPostsLimit', Session.get('bestPostsLimit') + BEST_PAGE_PER_PAGE);
|
||||
}
|
||||
});
|
||||
|
32
client/views/posts/posts_list.html
Normal file
32
client/views/posts/posts_list.html
Normal file
|
@ -0,0 +1,32 @@
|
|||
<template name="posts_list">
|
||||
<div class="posts grid list">
|
||||
{{#each posts}}
|
||||
{{> post_item}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{#if postsReady}}
|
||||
<div class="grid more-button {{#if allPostsLoaded}} hidden {{/if}}">
|
||||
<a class="more-link" href="#">Load more</a>
|
||||
</div>
|
||||
{{else}}
|
||||
<div>SPINNER...</div>
|
||||
{{/if}}
|
||||
</template>
|
||||
|
||||
<!-- and the various pages that use the above template -->
|
||||
<!-- XXX: makes me want to be able to set a context from the router... -->
|
||||
<template name="posts_top">
|
||||
{{> posts_list topPostsHandle}}
|
||||
</template>
|
||||
|
||||
<template name="posts_new">
|
||||
{{> posts_list newPostsHandle}}
|
||||
</template>
|
||||
|
||||
<template name="posts_best">
|
||||
{{> posts_list bestPostsHandle}}
|
||||
</template>
|
||||
|
||||
<template name="posts_pending">
|
||||
{{> posts_list pendingPostsHandle}}
|
||||
</template>
|
42
client/views/posts/posts_list.js
Normal file
42
client/views/posts/posts_list.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
Template.posts_top.topPostsHandle = function() {
|
||||
return topPostsHandle;
|
||||
}
|
||||
Template.posts_new.newPostsHandle = function() {
|
||||
return newPostsHandle;
|
||||
}
|
||||
Template.posts_best.bestPostsHandle = function() {
|
||||
return bestPostsHandle;
|
||||
}
|
||||
Template.posts_best.pendingPostsHandle = function() {
|
||||
return pendingPostsHandle;
|
||||
}
|
||||
|
||||
Template.posts_list.helpers({
|
||||
posts: function() {
|
||||
return this.fetch();
|
||||
},
|
||||
postsReady: function() {
|
||||
return ! this.loading();
|
||||
},
|
||||
allPostsLoaded: function(){
|
||||
return this.fetch().length < this.loaded()
|
||||
}
|
||||
});
|
||||
|
||||
Template.posts_top.rendered = function(){
|
||||
var distanceFromTop = 0;
|
||||
$('.post').each(function(){
|
||||
distanceFromTop += $(this).height();
|
||||
});
|
||||
$('body').css('min-height',distanceFromTop+160);
|
||||
$('.more-button').css('top', distanceFromTop+"px");
|
||||
}
|
||||
|
||||
Template.posts_top.events({
|
||||
'click .more-link': function(e) {
|
||||
e.preventDefault();
|
||||
Session.set('currentScroll',$('body').scrollTop());
|
||||
this.loadNextPage();
|
||||
}
|
||||
});
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<template name="posts_new">
|
||||
<div class="posts grid list">
|
||||
{{#each posts}}
|
||||
{{> post_item}}
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="grid more-button {{#if allPostsLoaded}} hidden {{/if}}">
|
||||
<a class="more-link" href="#">Load more</a>
|
||||
</div>
|
||||
</template>
|
|
@ -1,26 +0,0 @@
|
|||
Template.posts_new.posts = function() {
|
||||
return postsForSub.newPosts();
|
||||
};
|
||||
|
||||
Template.posts_new.helpers({
|
||||
allPostsLoaded: function(){
|
||||
return postsForSub.newPosts().length < Session.get('newPostsLimit');
|
||||
}
|
||||
});
|
||||
|
||||
Template.posts_new.rendered = function(){
|
||||
var distanceFromTop = 0;
|
||||
$('.post').each(function(){
|
||||
distanceFromTop += $(this).height();
|
||||
});
|
||||
$('body').css('min-height',distanceFromTop+160);
|
||||
$('.more-button').css('top', distanceFromTop+"px");
|
||||
}
|
||||
|
||||
Template.posts_new.events({
|
||||
'click .more-link': function(e) {
|
||||
e.preventDefault();
|
||||
Session.set('currentScroll',$('body').scrollTop());
|
||||
Session.set('newPostsLimit', Session.get('newPostsLimit') + NEW_PAGE_PER_PAGE)
|
||||
}
|
||||
});
|
|
@ -1,10 +0,0 @@
|
|||
<template name="posts_pending">
|
||||
<div class="posts grid list">
|
||||
{{#each posts}}
|
||||
{{> post_item}}
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="grid more-button {{#if allPostsLoaded}} hidden {{/if}}">
|
||||
<a class="more-link" href="#">Load more</a>
|
||||
</div>
|
||||
</template>
|
|
@ -1,25 +0,0 @@
|
|||
Template.posts_pending.posts = function() {
|
||||
return postsForSub.pendingPosts();
|
||||
};
|
||||
|
||||
Template.posts_pending.helpers({
|
||||
allPostsLoaded: function(){
|
||||
return postsForSub.pendingPosts().length < Session.get('pendingPostsLimit');
|
||||
}
|
||||
});
|
||||
|
||||
Template.posts_pending.rendered = function(){
|
||||
var distanceFromTop = 0;
|
||||
$('.post').each(function(){
|
||||
distanceFromTop += $(this).height();
|
||||
});
|
||||
$('.more-button').css('top', distanceFromTop+"px");
|
||||
}
|
||||
|
||||
Template.posts_pending.events({
|
||||
'click .more-link': function(e) {
|
||||
e.preventDefault();
|
||||
Session.set('currentScroll',$('body').scrollTop());
|
||||
Session.set('pendingPostsLimit', Session.get('pendingPostsLimit') + NEW_PAGE_PER_PAGE)
|
||||
}
|
||||
});
|
|
@ -1,10 +0,0 @@
|
|||
<template name="posts_top">
|
||||
<div class="posts grid list">
|
||||
{{#each posts}}
|
||||
{{> post_item}}
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="grid more-button {{#if allPostsLoaded}} hidden {{/if}}">
|
||||
<a class="more-link" href="#">Load more</a>
|
||||
</div>
|
||||
</template>
|
|
@ -1,27 +0,0 @@
|
|||
Template.posts_top.posts = function() {
|
||||
return postsForSub.topPosts();
|
||||
};
|
||||
|
||||
Template.posts_top.helpers({
|
||||
allPostsLoaded: function(){
|
||||
return postsForSub.topPosts().length < Session.get('topPostsLimit');
|
||||
}
|
||||
});
|
||||
|
||||
Template.posts_top.rendered = function(){
|
||||
var distanceFromTop = 0;
|
||||
$('.post').each(function(){
|
||||
distanceFromTop += $(this).height();
|
||||
});
|
||||
$('body').css('min-height',distanceFromTop+160);
|
||||
$('.more-button').css('top', distanceFromTop+"px");
|
||||
}
|
||||
|
||||
Template.posts_top.events({
|
||||
'click .more-link': function(e) {
|
||||
e.preventDefault();
|
||||
Session.set('currentScroll',$('body').scrollTop());
|
||||
Session.set('topPostsLimit', Session.get('topPostsLimit') + TOP_PAGE_PER_PAGE);
|
||||
}
|
||||
});
|
||||
|
|
@ -54,6 +54,14 @@ Posts = new Meteor.Collection('posts');
|
|||
// return Posts.find({}, {sort: {score: -1}});
|
||||
// });
|
||||
|
||||
|
||||
Meteor.publish('paginatedPosts', function(find, options, limit) {
|
||||
options = options || {};
|
||||
options.limit = limit;
|
||||
|
||||
return Posts.find(find || {}, options);
|
||||
});
|
||||
|
||||
Meteor.publish('posts', function(find, options, subName) {
|
||||
var collection=Posts.find(find, options);
|
||||
var collectionArray=collection.fetch();
|
||||
|
|
Loading…
Add table
Reference in a new issue