Fixed a bunch of 'best of' errors and cleaned up JS.

This commit is contained in:
Robin Ward 2013-03-21 15:10:34 -04:00
parent b6f49e5b68
commit 5c4b794a8c
13 changed files with 128 additions and 153 deletions

View file

@ -49,7 +49,7 @@ Discourse.AdminCustomizeController = Ember.Controller.extend({
var selected;
if (result) {
selected = _this.get('content.selectedItem');
selected["delete"]();
selected.destroy();
_this.set('content.selectedItem', null);
return _this.get('content').removeObject(selected);
}

View file

@ -64,7 +64,7 @@ Discourse.SiteCustomization = Discourse.Model.extend({
});
},
"delete": function() {
destroy: function() {
if (!this.id) return;
return $.ajax({

View file

@ -10,6 +10,7 @@ Discourse.TopicController = Discourse.ObjectController.extend({
userFilters: new Em.Set(),
multiSelect: false,
bestOf: false,
summaryCollapsed: true,
needs: ['header', 'modal', 'composer', 'quoteButton'],
filter: (function() {
@ -19,9 +20,14 @@ Discourse.TopicController = Discourse.ObjectController.extend({
}).property('userFilters.[]', 'bestOf'),
filterDesc: (function() {
var filter;
if (!(filter = this.get('filter'))) return null;
return Em.String.i18n("topic.filters." + filter);
var filter = this.get('filter');
if (!filter) return null;
if (filter !== 'user') return Em.String.i18n("topic.filters." + filter);
// If we're a user filter, include the count
return Em.String.i18n("topic.filters.user", {count: this.get('userFilters.length')});
}).property('filter'),
selectedPosts: (function() {
@ -83,6 +89,10 @@ Discourse.TopicController = Discourse.ObjectController.extend({
this.toggleProperty('multiSelect');
},
toggleSummary: function() {
this.toggleProperty('summaryCollapsed');
},
moveSelected: function() {
var _ref;
return (_ref = this.get('controllers.modal')) ? _ref.show(Discourse.MoveSelectedView.create({
@ -148,71 +158,56 @@ Discourse.TopicController = Discourse.ObjectController.extend({
},
toggleParticipant: function(user) {
var userFilters, username;
this.set('bestOf', false);
username = Em.get(user, 'username');
userFilters = this.get('userFilters');
var username = Em.get(user, 'username');
var userFilters = this.get('userFilters');
if (userFilters.contains(username)) {
userFilters.remove(username);
} else {
userFilters.add(username);
}
return false;
},
enableBestOf: function(e) {
this.set('bestOf', true);
this.get('userFilters').clear();
return false;
},
showBestOf: (function() {
if (this.get('bestOf') === true) {
return false;
}
return this.get('content.has_best_of') === true;
}).property('bestOf', 'content.has_best_of'),
postFilters: (function() {
if (this.get('bestOf') === true) {
return {
bestOf: true
};
}
return {
userFilters: this.get('userFilters')
};
if (this.get('bestOf') === true) return { bestOf: true };
return { userFilters: this.get('userFilters') };
}).property('userFilters.[]', 'bestOf'),
reloadTopics: (function() {
var posts, topic,
_this = this;
topic = this.get('content');
reloadPosts: (function() {
var topic = this.get('content');
if (!topic) return;
posts = topic.get('posts');
var posts = topic.get('posts');
if (!posts) return;
posts.clear();
this.set('content.loaded', false);
return Discourse.Topic.find(this.get('content.id'), this.get('postFilters')).then(function(result) {
var first;
first = result.posts.first();
// Leave the first post -- we keep it above the filter controls
posts.removeAt(1, posts.length - 1);
var topicController = this;
return Discourse.Topic.find(this.get('id'), this.get('postFilters')).then(function(result) {
var first = result.posts.first();
if (first) {
_this.set('currentPost', first.post_number);
topicController.set('currentPost', first.post_number);
}
$('#topic-progress .solid').data('progress', false);
result.posts.each(function(p) {
return posts.pushObject(Discourse.Post.create(p, topic));
// Skip the first post
if (p.post_number === 1) return;
posts.pushObject(Discourse.Post.create(p, topic));
});
return _this.set('content.loaded', true);
});
}).observes('postFilters'),
deleteTopic: function(e) {
var _this = this;
var topicController = this;
this.unsubscribe();
this.get('content')["delete"](function() {
_this.set('message', Em.String.i18n('topic.deleted'));
_this.set('loaded', false);
this.get('content').destroy().then(function() {
topicController.set('message', Em.String.i18n('topic.deleted'));
topicController.set('loaded', false);
});
},
@ -411,7 +406,7 @@ Discourse.TopicController = Discourse.ObjectController.extend({
post.set('can_delete', false);
post.set('version', post.get('version') + 1);
}
return post["delete"]();
post.destroy();
},
postRendered: function(post) {

View file

@ -21,10 +21,7 @@ Discourse.Category = Discourse.Model.extend({
}).property('topic_count'),
save: function(args) {
var url,
_this = this;
url = Discourse.getURL("/categories");
var url = Discourse.getURL("/categories");
if (this.get('id')) {
url = Discourse.getURL("/categories/") + (this.get('id'));
}
@ -41,14 +38,8 @@ Discourse.Category = Discourse.Model.extend({
});
},
"delete": function(callback) {
var _this = this;
return $.ajax(Discourse.getURL("/categories/") + (this.get('slug')), {
type: 'DELETE',
success: function() {
return callback();
}
});
destroy: function(callback) {
return $.ajax(Discourse.getURL("/categories/") + (this.get('slug')), { type: 'DELETE' });
}
});

View file

@ -175,13 +175,8 @@ Discourse.Post = Discourse.Model.extend({
return $.ajax(Discourse.getURL("/posts/") + (this.get('id')) + "/recover", { type: 'PUT', cache: false });
},
"delete": function(complete) {
return $.ajax(Discourse.getURL("/posts/") + (this.get('id')), {
type: 'DELETE',
success: function(result) {
return typeof complete === "function" ? complete() : void 0;
}
});
destroy: function(complete) {
return $.ajax(Discourse.getURL("/posts/") + (this.get('id')), { type: 'DELETE' });
},
// Update the properties of this post from an obj, ignoring cooked as we should already

View file

@ -197,13 +197,8 @@ Discourse.Topic = Discourse.Model.extend({
},
// Delete this topic
"delete": function(callback) {
return $.ajax(Discourse.getURL("/t/") + (this.get('id')), {
type: 'DELETE',
success: function() {
return typeof callback === "function" ? callback() : void 0;
}
});
destroy: function() {
return $.ajax(Discourse.getURL("/t/") + (this.get('id')), { type: 'DELETE' });
},
// Load the posts for this topic
@ -420,7 +415,7 @@ Discourse.Topic.reopenClass({
if (opts.userFilters && opts.userFilters.length > 0) {
data.username_filters = [];
opts.userFilters.forEach(function(username) {
return data.username_filters.push(username);
data.username_filters.push(username);
});
}

View file

@ -1,4 +1,4 @@
<a href='#' {{bindAttr class=":poster view.toggled:toggled"}} {{action toggleParticipant this target="controller"}} title="{{unbound username}}">
<a href='#' {{bindAttr class=":poster view.toggled:toggled"}} {{action toggleParticipant this}} title="{{unbound username}}">
<span class='post-count'>{{unbound post_count}}</span>
{{avatar this imageSize="medium"}}
</a>

View file

@ -1,4 +1,8 @@
<h3><i class='icon icon-bullhorn'></i> {{i18n best_of.title}}</h3>
<p>{{{i18n best_of.description count="controller.content.posts_count"}}}</p>
<button class='btn' {{action enableBestOf target="controller"}}>{{i18n best_of.button}}</button>
{{#if controller.bestOf}}
<p>{{{i18n best_of.enabled_description}}}</p>
<button class='btn' {{action cancelFilter}}>{{i18n best_of.disable}}</button>
{{else}}
<p>{{{i18n best_of.description count="controller.content.posts_count"}}}</p>
<button class='btn' {{action enableBestOf}}>{{i18n best_of.enable}}</button>
{{/if}}

View file

@ -1,17 +1,17 @@
<nav class='buttons'>
{{#if view.summaryView.collapsed}}
<button class='btn collapsed' {{action toggleMore target="view.summaryView"}} title="{{i18n topic.toggle_information}}">
{{#if controller.summaryCollapsed}}
<button class='btn collapsed' {{action toggleSummary}} title="{{i18n topic.toggle_information}}">
<i class='icon icon-chevron-down'></i>
</button>
{{else}}
<button class='btn' {{action toggleMore target="view.summaryView"}} title="{{i18n topic.toggle_information}}">
<button class='btn' {{action toggleSummary}} title="{{i18n topic.toggle_information}}">
<i class='icon icon-chevron-up'></i>
</button>
{{/if}}
{{/if}}
</nav>
{{#if view.summaryView.collapsed}}
{{#if controller.summaryCollapsed}}
<section class='summary collapsed'>
<ul class="clearfix">
<li>
@ -39,13 +39,13 @@
<li>
<h4>{{i18n links}}</h4>
{{number view.topic.links.length}}
</li>
</li>
{{#if view.topic.fewParticipants}}
<li class='avatars'>
{{#each view.topic.fewParticipants}}{{view Discourse.ParticipantView participantBinding="this"}}{{/each}}
{{#each view.topic.fewParticipants}}{{view Discourse.ParticipantView participantBinding="this"}}{{/each}}
</li>
{{/if}}
</ul>
</ul>
</section>
{{else}}
@ -74,7 +74,7 @@
{{#if view.topic.participants}}
<section class='avatars clearfix'>
{{#each view.topic.participants}}{{view Discourse.ParticipantView participantBinding="this"}}{{/each}}
{{#each view.topic.participants}}{{view Discourse.ParticipantView participantBinding="this"}}{{/each}}
</section>
{{/if}}
@ -82,12 +82,12 @@
<section class='links'>
<ul class='topic-links'>
{{#collection contentBinding="view.parentView.infoLinks" itemTagName="li"}}
<span class='badge badge-notification clicks' title='clicks'>{{view.content.clicks}}</span>
<a href="{{unbound view.content.url}}" target="_blank" class='topic-link track-link' data-user-id="{{unbound view.content.user_id}}" data-ignore-post-id="true" title="{{unbound view.content.url}}">
<span class='badge badge-notification clicks' title='clicks'>{{view.content.clicks}}</span>
<a href="{{unbound view.content.url}}" target="_blank" class='topic-link track-link' data-user-id="{{unbound view.content.user_id}}" data-ignore-post-id="true" title="{{unbound view.content.url}}">
{{#if view.content.title}}{{shorten view.content.title}}{{else}}{{shortenUrl view.content.url}}{{/if}}
{{#if view.content.internal}}<i class='icon-arrow-right' title='topic link'></i>{{/if}}
</a>
{{/collection}}
{{/collection}}
</ul>
{{#if view.parentView.showAllLinksControls}}

View file

@ -11,41 +11,45 @@ Discourse.PostMenuView = Discourse.View.extend({
classNames: ['post-menu-area', 'clearfix'],
render: function(buffer) {
var post,
_this = this;
post = this.get('post');
var post = this.get('post');
this.renderReplies(post, buffer);
buffer.push("<nav class='post-controls'>");
var postMenuView = this;
Discourse.get('postButtons').forEach(function(button) {
var renderer = "render" + button;
if(_this[renderer]) _this[renderer](post, buffer);
if(postMenuView[renderer]) postMenuView[renderer](post, buffer);
});
return buffer.push("</nav>");
buffer.push("</nav>");
},
// Delegate click actions
click: function(e) {
var $target, action, _name;
$target = $(e.target);
action = $target.data('action') || $target.parent().data('action');
var $target = $(e.target);
var action = $target.data('action') || $target.parent().data('action');
if (!action) return;
return typeof this[_name = "click" + (action.capitalize())] === "function" ? this[_name]() : void 0;
var handler = this["click" + action.capitalize()];
if (!handler) return;
handler.call(this);
},
// Trigger re-rendering
needsToRender: function() {
return this.rerender();
this.rerender();
}.observes('post.deleted_at', 'post.flagsAvailable.@each', 'post.url', 'post.bookmarked', 'post.reply_count', 'post.showRepliesBelow', 'post.can_delete'),
// Replies Button
renderReplies: function(post, buffer) {
var icon, reply_count;
if (!post.get('showRepliesBelow')) return;
reply_count = post.get('reply_count');
var reply_count = post.get('reply_count');
buffer.push("<button class='show-replies' data-action='replies'>");
buffer.push("<span class='badge-posts'>" + reply_count + "</span>");
buffer.push(Em.String.i18n("post.has_replies", { count: reply_count }));
icon = this.get('postView.repliesShown') ? 'icon-chevron-up' : 'icon-chevron-down';
var icon = this.get('postView.repliesShown') ? 'icon-chevron-up' : 'icon-chevron-down';
return buffer.push("<i class='icon " + icon + "'></i></button>");
},
@ -64,14 +68,14 @@ Discourse.PostMenuView = Discourse.View.extend({
// Show the correct button (undo or delete)
if (post.get('deleted_at')) {
if (post.get('can_recover')) {
return buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.undelete")) +
"\" data-action=\"recover\" class=\"delete\"><i class=\"icon-undo\"></i></button>");
buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.undelete")) +
"\" data-action=\"recover\" class=\"delete\"><i class=\"icon-undo\"></i></button>");
}
} else if (post.get('can_delete')) {
return buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.delete")) +
"\" data-action=\"delete\" class=\"delete\"><i class=\"icon-trash\"></i></button>");
buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.delete")) +
"\" data-action=\"delete\" class=\"delete\"><i class=\"icon-trash\"></i></button>");
}
},
@ -90,9 +94,9 @@ Discourse.PostMenuView = Discourse.View.extend({
// Like button
renderLike: function(post, buffer) {
if (!post.get('actionByName.like.can_act')) return;
return buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.like")) +
"\" data-action=\"like\" class='like'><i class=\"icon-heart\"></i></button>");
buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.like")) +
"\" data-action=\"like\" class='like'><i class=\"icon-heart\"></i></button>");
},
clickLike: function() {
@ -103,9 +107,9 @@ Discourse.PostMenuView = Discourse.View.extend({
// Flag button
renderFlag: function(post, buffer) {
if (!this.present('post.flagsAvailable')) return;
return buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.flag")) +
"\" data-action=\"flag\"><i class=\"icon-flag\"></i></button>");
buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.flag")) +
"\" data-action=\"flag\"><i class=\"icon-flag\"></i></button>");
},
clickFlag: function() {
@ -115,9 +119,9 @@ Discourse.PostMenuView = Discourse.View.extend({
// Edit button
renderEdit: function(post, buffer) {
if (!post.get('can_edit')) return;
return buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.edit")) +
"\" data-action=\"edit\"><i class=\"icon-pencil\"></i></button>");
buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.edit")) +
"\" data-action=\"edit\"><i class=\"icon-pencil\"></i></button>");
},
clickEdit: function() {
@ -126,18 +130,18 @@ Discourse.PostMenuView = Discourse.View.extend({
// Share button
renderShare: function(post, buffer) {
return buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.share")) +
"\" data-share-url=\"" + (post.get('url')) + "\"><i class=\"icon-link\"></i></button>");
buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.share")) +
"\" data-share-url=\"" + (post.get('url')) + "\"><i class=\"icon-link\"></i></button>");
},
// Reply button
renderReply: function(post, buffer) {
if (!this.get('controller.content.can_create_post')) return;
return buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.reply")) +
"\" class='create' data-action=\"reply\"><i class='icon-reply'></i>" +
(Em.String.i18n("topic.reply.title")) + "</button>");
buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.reply")) +
"\" class='create' data-action=\"reply\"><i class='icon-reply'></i>" +
(Em.String.i18n("topic.reply.title")) + "</button>");
},
clickReply: function() {
@ -146,19 +150,19 @@ Discourse.PostMenuView = Discourse.View.extend({
// Bookmark button
renderBookmark: function(post, buffer) {
var icon;
if (!Discourse.get('currentUser')) return;
icon = 'bookmark';
var icon = 'bookmark';
if (!this.get('post.bookmarked')) {
icon += '-empty';
}
return buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.bookmark")) +
"\" data-action=\"bookmark\"><i class=\"icon-" + icon + "\"></i></button>");
buffer.push("<button title=\"" +
(Em.String.i18n("post.controls.bookmark")) +
"\" data-action=\"bookmark\"><i class=\"icon-" + icon + "\"></i></button>");
},
clickBookmark: function() {
return this.get('post').toggleProperty('bookmarked');
this.get('post').toggleProperty('bookmarked');
}
});

View file

@ -15,17 +15,12 @@ Discourse.PostView = Discourse.View.extend({
'post.hidden:hidden',
'post.deleted_at:deleted',
'parentPost:replies-above'],
siteBinding: Ember.Binding.oneWay('Discourse.site'),
composeViewBinding: Ember.Binding.oneWay('Discourse.composeView'),
quoteButtonViewBinding: Ember.Binding.oneWay('Discourse.quoteButtonView'),
postBinding: 'content',
// TODO really we should do something cleaner here... this makes it work in debug but feels really messy
screenTrack: (function() {
var parentView, screenTrack;
parentView = this.get('parentView');
screenTrack = null;
var parentView = this.get('parentView');
var screenTrack = null;
while (parentView && !screenTrack) {
screenTrack = parentView.get('screenTrack');
parentView = parentView.get('parentView');
@ -41,9 +36,7 @@ Discourse.PostView = Discourse.View.extend({
// If the cooked content changed, add the quote controls
cookedChanged: (function() {
var postView = this;
Em.run.next(function() {
postView.insertQuoteControls();
});
Em.run.next(function() { postView.insertQuoteControls(); });
}).observes('post.cooked'),
init: function() {
@ -56,10 +49,9 @@ Discourse.PostView = Discourse.View.extend({
this.toggleProperty('post.selected');
}
var $target = $(e.target);
if ($target.closest('.cooked').length === 0) return;
var qbc = this.get('controller.controllers.quoteButton');
if ($(e.target).closest('.cooked').length === 0) return;
var qbc = this.get('controller.controllers.quoteButton');
if (qbc && Discourse.get('currentUser.enable_quoting')) {
e.context = this.get('post');
qbc.selectText(e);

View file

@ -10,7 +10,6 @@ Discourse.TopicSummaryView = Ember.ContainerView.extend(Discourse.Presence, {
topicBinding: 'controller.content',
classNameBindings: ['hidden', ':topic-summary'],
LINKS_SHOWN: 5,
collapsed: true,
allLinksShown: false,
showAllLinksControls: (function() {
@ -21,15 +20,15 @@ Discourse.TopicSummaryView = Ember.ContainerView.extend(Discourse.Presence, {
}).property('allLinksShown', 'topic.links'),
infoLinks: (function() {
var allLinks;
if (this.blank('topic.links')) return [];
allLinks = this.get('topic.links');
var allLinks = this.get('topic.links');
if (this.get('allLinksShown')) return allLinks;
return allLinks.slice(0, this.LINKS_SHOWN);
}).property('topic.links', 'allLinksShown'),
newPostCreated: (function() {
return this.rerender();
this.rerender();
}).observes('topic.posts_count'),
hidden: (function() {
@ -47,21 +46,17 @@ Discourse.TopicSummaryView = Ember.ContainerView.extend(Discourse.Presence, {
topic: this.get('topic'),
summaryView: this
}));
return this.trigger('appendSummaryInformation', this);
},
toggleMore: function() {
return this.toggleProperty('collapsed');
this.trigger('appendSummaryInformation', this);
},
showAllLinks: function() {
return this.set('allLinksShown', true);
this.set('allLinksShown', true);
},
appendSummaryInformation: function(container) {
// If we have a best of view
if (this.get('controller.showBestOf')) {
if (this.get('controller.has_best_of')) {
container.pushObject(Em.View.create({
templateName: 'topic_summary/best_of_toggle',
tagName: 'section',

View file

@ -203,8 +203,10 @@ en:
best_of:
title: "Best Of"
enabled_description: You are currently viewing the "Best Of" view of this topic.
description: "There are <b>{{count}}</b> posts in this topic. That's a lot! Would you like to save time by switching your view to show only the posts with the most interactions and responses?"
button: 'Switch to "Best Of" view'
enable: 'Switch to "Best Of" view'
disable: 'Cancel "Best Of"'
private_message_info:
title: "Private Conversation"
@ -498,7 +500,9 @@ en:
login_reply: 'Log In to Reply'
filters:
user: "You're viewing only posts by specific user(s)."
user:
one: "You're viewing only posts by a specific user."
other: "You're viewing only posts made by specific users."
best_of: "You're viewing only the 'Best Of' posts."
cancel: "Show all posts in this topic again."