refactored part of the app to be clearer

This commit is contained in:
Sacha Greif 2012-10-19 19:20:14 +09:00
parent 339d45fc3f
commit a886b00123
19 changed files with 84 additions and 62 deletions

View file

@ -1,5 +1,16 @@
Telescope is an open-source, real-time social news site built with [Meteor](http://meteor.com)
**Note:** Telescope is beta software. Most of it should work but it's still a little unpolished and you'll probably find some bugs. Use at your own risk :)
# Features
- Real-time (of course!)
- Password and/or Twitter auth
- Notifications
- Mobile-ready & responsive
- Invite-only access
- Markdown support
- Day by day view
# Instalation
- Install Meteor
- Install [Meteorite](https://github.com/oortcloud/meteorite/)

View file

View file

@ -1 +0,0 @@
// Meteor.accounts.twitter.config('8HVvfpRhAuHzWyByp4D6Q', 'http://gridgrid.meteor.com');

View file

@ -1 +0,0 @@
// Meteor.accounts.twitter.setSecret('veZM4yC21bWExvsaht4cgzNMQgkmiqTHbPQzyTWH1I');

View file

@ -1,8 +1,7 @@
Accounts.ui.config({
passwordSignupFields: 'USERNAME_AND_EMAIL'
});
// HELPERS
// ** Client-side helpers **
// Workaround for the fact that you cannot store objects in
// Session variables. Is used by app.js so needs to come first.
sessionSetObject=function(name, value){
Session.set(name, JSON.stringify(value));
@ -11,11 +10,11 @@ sessionGetObject=function(name){
var data = Session.get(name);
return data && JSON.parse(data);
}
$.fn.exists = function () {
return this.length !== 0;
}
// SUBSCRIPTIONS
// ** Users **
Meteor.subscribe('currentUser');
Meteor.subscribe('allUsers');
@ -24,7 +23,6 @@ Meteor.subscribe('allUsers');
Errors = new Meteor.Collection(null);
// ** Settings **
Settings = new Meteor.Collection('settings');
@ -52,7 +50,6 @@ if(Meteor.user()){
Meteor.subscribe('notifications');
}
// ** Posts **
// We have a few subscriptions here, for the various ways we load posts
//
@ -140,7 +137,6 @@ Meteor.autosubscribe(function() {
})
});
// ** Categories **
Categories = new Meteor.Collection('categories');
@ -157,44 +153,4 @@ Meteor.autosubscribe(function() {
Meteor.subscribe('comments', query, function() {
//
});
});
// ** Handlebars helpers **
Handlebars.registerHelper('canView', function(action) {
var action=(typeof action !== 'string') ? null : action;
return canView(Meteor.user(), action);
});
Handlebars.registerHelper('canPost', function(action) {
var action=(typeof action !== 'string') ? null : action;
return canPost(Meteor.user(), action);
});
Handlebars.registerHelper('canComment', function(action) {
var action=(typeof action !== 'string') ? null : action;
return canComment(Meteor.user(), action);
});
Handlebars.registerHelper('canUpvote', function(collection, action) {
var action=(typeof action !== 'string') ? null : action;
return canUpvote(Meteor.user()), collection, action;
});
Handlebars.registerHelper('canDownvote', function(collection, action) {
var action=(typeof action !== 'string') ? null : action;
return canDownvote(Meteor.user(), collection, action);
});
Handlebars.registerHelper('isAdmin', function(showError) {
if(isAdmin(Meteor.user())){
return true;
}else{
if((typeof showError === "string") && (showError === "true"))
throwError('Sorry, you do not have access to this page');
return false;
}
});
Handlebars.registerHelper('canEdit', function(collectionName, action) {
var action = (typeof action !== 'string') ? null : action;
var collection = (typeof collectionName !== 'string') ? Posts : eval(collectionName);
var itemId = (collectionName==="Posts") ? Session.get('selectedPostId') : Session.get('selectedCommentId');
var item=collection.findOne(itemId);
return item && canEdit(Meteor.user(), item, action);
});

View file

@ -1,5 +1,6 @@
Template.body.events({
'click a[href]': function(event) {
// intercept all link clicks and redirect them through the router
var url = $(event.target).closest('a').attr('href').replace(/#.*$/, '');
if (url && url[0] === '/' && url !== document.location.href) {
event.preventDefault();

View file

@ -0,0 +1,3 @@
$.fn.exists = function () {
return this.length !== 0;
}

View file

@ -1,4 +1,9 @@
// TL = TLog.getLogger(TLog.LOGLEVEL_MAX,true);
// ** Accounts UI Config **
Accounts.ui.config({
passwordSignupFields: 'USERNAME_AND_EMAIL'
});
EpicEditorOptions={
container: 'editor',
basePath: '/editor',

38
client/lib/handlebars.js Normal file
View file

@ -0,0 +1,38 @@
// ** Handlebars helpers **
Handlebars.registerHelper('canView', function(action) {
var action=(typeof action !== 'string') ? null : action;
return canView(Meteor.user(), action);
});
Handlebars.registerHelper('canPost', function(action) {
var action=(typeof action !== 'string') ? null : action;
return canPost(Meteor.user(), action);
});
Handlebars.registerHelper('canComment', function(action) {
var action=(typeof action !== 'string') ? null : action;
return canComment(Meteor.user(), action);
});
Handlebars.registerHelper('canUpvote', function(collection, action) {
var action=(typeof action !== 'string') ? null : action;
return canUpvote(Meteor.user()), collection, action;
});
Handlebars.registerHelper('canDownvote', function(collection, action) {
var action=(typeof action !== 'string') ? null : action;
return canDownvote(Meteor.user(), collection, action);
});
Handlebars.registerHelper('isAdmin', function(showError) {
if(isAdmin(Meteor.user())){
return true;
}else{
if((typeof showError === "string") && (showError === "true"))
throwError('Sorry, you do not have access to this page');
return false;
}
});
Handlebars.registerHelper('canEdit', function(collectionName, action) {
var action = (typeof action !== 'string') ? null : action;
var collection = (typeof collectionName !== 'string') ? Posts : eval(collectionName);
var itemId = (collectionName==="Posts") ? Session.get('selectedPostId') : Session.get('selectedCommentId');
var item=collection.findOne(itemId);
return item && canEdit(Meteor.user(), item, action);
});

View file

@ -1,4 +1,5 @@
SimpleRouter = FilteredRouter.extend({
initialize: function() {
FilteredRouter.prototype.initialize.call(this);
this.filter(this.require_login, {only: ['submit']});
@ -6,14 +7,20 @@ SimpleRouter = FilteredRouter.extend({
this.filter(this.require_profile);
this.filter(this.requirePost, {only: ['post_page']});
},
start_request: function(page){
// runs at every new page change
// openedComments is an Array that tracks which comments
// have been expanded by the user, to make sure they stay expanded
Session.set("openedComments", null);
// currentScroll stores the position of the user in the page
Session.set('currentScroll', null);
document.title = getSetting("title");
// set all errors who have been seen to not show anymore
// set all errors who have already been seen to not show anymore
clearSeenErrors();
// log this request with mixpanel, etc
@ -21,6 +28,7 @@ SimpleRouter = FilteredRouter.extend({
return page;
},
require_login: function(page) {
if (Meteor.user()) {
return page;
@ -28,7 +36,7 @@ SimpleRouter = FilteredRouter.extend({
return 'signin';
}
},
// if the user is logged in but their profile isn't filled out enough
require_profile: function(page) {
var user = Meteor.user();

View file

@ -19,8 +19,7 @@
<li class="post-more mobile"><a class="more-link"><i class="icon-share"></i><span class="action">Text </span></a></li>
</ul>
<div class="post-content">
{{#if isPostPage}}
{{else}}<span class="post-rank">{{rank}}</span>{{/if}}
{{#if showRank}}<span class="post-rank">{{rank}}</span>{{/if}}
<div class="post-upvote">
{{#if voted}}
<span class="upvote-link voted"><i class="icon-check"></i><span>Upvote</span></span>

View file

@ -7,8 +7,8 @@ Template.post_item.helpers({
rank: function() {
return this._rank + 1;
},
isPostPage: function(){
return Router.current_page() === 'post_page'
showRank: function(){
return _.contains(['posts_top', 'posts_new', 'posts_digest'], Router.current_page());
},
domain: function(){
var a = document.createElement('a');

View file

@ -26,6 +26,6 @@ Template.posts_digest.helpers({
var currentDate=moment(sessionGetObject('currentDate'));
var nextDate=currentDate.add('days', 1);
var today=moment(new Date());
return today.diff(nextDate, 'days') >= 0
return today.diff(nextDate, 'days') > 0
}
});

View file

@ -15,6 +15,6 @@
<td><a href="#">{{commentsCount}}</a></td>
<td>{{karma}}</td>
<td>{{#if isInvited}}<a class="uninvite-link" href="#"><i class="icon-check"></i>Uninvite</a>{{else}}<a href="#" class="invite-link">Invite</a>{{/if}}</td>
<td>{{#if isAdmin}}<a class="unadmin-link" href="#"><i class="icon-check unadmin-link"></i>Unadmin</a>{{else}}<a href="#" class="admin-link">Make admin</a>{{/if}}</td>
<td>{{#if userIsAdmin}}<a class="unadmin-link" href="#"><i class="icon-check unadmin-link"></i>Unadmin</a>{{else}}<a href="#" class="admin-link">Make admin</a>{{/if}}</td>
</tr>
</template>

View file

@ -26,6 +26,9 @@ Template.user_item.helpers({
commentsCount: function(){
// Posts.find({'user_id':this._id}).forEach(function(post){console.log(post.headline);});
return Comments.find({'userId':this._id}).count();
},
userIsAdmin: function(){
return isAdmin(this);
}
});

View file

@ -1,7 +1,7 @@
throwError = 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});
// Session.set("error", message);
}
clearSeenErrors = function(){
Errors.update({seen:true}, {$set: {show:false}}, {multi:true});

View file