Added some macros to simplify code
This commit is contained in:
parent
1fef617818
commit
8888ae4b40
|
@ -0,0 +1,17 @@
|
|||
Discourse.computed = {
|
||||
|
||||
/**
|
||||
Returns whether two properties are equal to each other.
|
||||
|
||||
@method propertyEqual
|
||||
@params {String} p1 the first property
|
||||
@params {String} p2 the second property
|
||||
@return {Function} computedProperty function
|
||||
**/
|
||||
propertyEqual: function(p1, p2) {
|
||||
return Ember.computed(function() {
|
||||
return this.get(p1) === this.get(p2);
|
||||
}).property(p1, p2);
|
||||
}
|
||||
|
||||
}
|
|
@ -37,14 +37,11 @@ Ember.Handlebars.registerHelper('i18n', function(property, options) {
|
|||
Ember.Handlebars.registerHelper('countI18n', function(key, options) {
|
||||
var view = Discourse.View.extend({
|
||||
tagName: 'span',
|
||||
shouldRerender: Discourse.View.renderIfChanged('countChanged'),
|
||||
|
||||
render: function(buffer) {
|
||||
buffer.push(I18n.t(key, { count: this.get('count') }));
|
||||
},
|
||||
|
||||
countChanged: function() {
|
||||
this.rerender();
|
||||
}.observes('count')
|
||||
}
|
||||
|
||||
});
|
||||
return Ember.Handlebars.helpers.view.call(this, view, options);
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
|
||||
<div class='span5 gutter'>
|
||||
{{collection contentBinding="internalLinks" itemViewClass="Discourse.PostLinkView" tagName="ul" classNames="post-links"}}
|
||||
{{#if controller.details.can_reply_as_new_topic}}
|
||||
{{#if topic.details.can_reply_as_new_topic}}
|
||||
<a href='#' class='reply-new' {{action replyAsNewTopic this}}><i class='icon icon-plus'></i>{{i18n post.reply_as_new_topic}}</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -11,18 +11,14 @@ Discourse.ActionsHistoryView = Discourse.View.extend({
|
|||
tagName: 'section',
|
||||
classNameBindings: [':post-actions', 'hidden'],
|
||||
|
||||
hidden: (function() {
|
||||
return this.blank('content');
|
||||
}).property('content.@each'),
|
||||
hidden: Em.computed.empty('content'),
|
||||
|
||||
usersChanged: (function() {
|
||||
return this.rerender();
|
||||
}).observes('content.@each', 'content.users.@each'),
|
||||
shouldRerender: Discourse.View.renderIfChanged('content.@each', 'content.users.@each'),
|
||||
|
||||
// This was creating way too many bound ifs and subviews in the handlebars version.
|
||||
render: function(buffer) {
|
||||
|
||||
if (!this.present('content')) return;
|
||||
|
||||
return this.get('content').forEach(function(c) {
|
||||
var actionString, iconsHtml;
|
||||
buffer.push("<div class='post-action'>");
|
||||
|
|
|
@ -10,6 +10,8 @@ Discourse.DropdownButtonView = Discourse.View.extend({
|
|||
classNames: ['btn-group'],
|
||||
attributeBindings: ['data-not-implemented'],
|
||||
|
||||
shouldRerender: Discourse.View.renderIfChanged('text', 'longDescription'),
|
||||
|
||||
didInsertElement: function(e) {
|
||||
// If there's a click handler, call it
|
||||
if (this.clicked) {
|
||||
|
@ -26,10 +28,6 @@ Discourse.DropdownButtonView = Discourse.View.extend({
|
|||
this.$('ul li').off('click.dropdown-button');
|
||||
},
|
||||
|
||||
textChanged: function() {
|
||||
this.rerender();
|
||||
}.observes('text', 'longDescription'),
|
||||
|
||||
render: function(buffer) {
|
||||
buffer.push("<h4 class='title'>" + this.get('title') + "</h4>");
|
||||
buffer.push("<button class='btn standard dropdown-toggle' data-toggle='dropdown'>");
|
||||
|
|
|
@ -10,9 +10,7 @@ Discourse.FavoriteButton = Discourse.ButtonView.extend({
|
|||
textKey: 'favorite.title',
|
||||
helpKeyBinding: 'controller.content.favoriteTooltipKey',
|
||||
|
||||
favoriteChanged: function() {
|
||||
this.rerender();
|
||||
}.observes('controller.content.starred'),
|
||||
shouldRerender: Discourse.View.renderIfChanged('controller.content.starred'),
|
||||
|
||||
click: function() {
|
||||
this.get('controller').toggleStar();
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
Discourse.HotnessView = Discourse.View.extend({
|
||||
classNames: ['hotness-control'],
|
||||
|
||||
shouldRerender: Discourse.View.renderIfChanged('hotness'),
|
||||
|
||||
render: function(buffer) {
|
||||
// Our scale goes to 11!
|
||||
for (var i=1; i<12; i++) {
|
||||
|
@ -21,15 +23,6 @@ Discourse.HotnessView = Discourse.View.extend({
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Trigger a re-render whenever the hotness changes
|
||||
|
||||
@observer hotnessChanged
|
||||
**/
|
||||
hotnessChanged: function() {
|
||||
this.rerender();
|
||||
}.observes('hotness'),
|
||||
|
||||
/**
|
||||
When the user clicks on a hotness value button, change it.
|
||||
|
||||
|
|
|
@ -9,17 +9,9 @@
|
|||
Discourse.InputTipView = Discourse.View.extend({
|
||||
classNameBindings: [':tip', 'good', 'bad'],
|
||||
|
||||
good: function() {
|
||||
return !this.get('validation.failed');
|
||||
}.property('validation'),
|
||||
|
||||
bad: function() {
|
||||
return this.get('validation.failed');
|
||||
}.property('validation'),
|
||||
|
||||
triggerRender: function() {
|
||||
return this.rerender();
|
||||
}.observes('validation'),
|
||||
shouldRerender: Discourse.View.renderIfChanged('validation'),
|
||||
bad: Em.computed.alias('validation.failed'),
|
||||
good: Em.computed.not('bad'),
|
||||
|
||||
render: function(buffer) {
|
||||
var reason = this.get('validation.reason');
|
||||
|
|
|
@ -8,9 +8,13 @@
|
|||
**/
|
||||
Discourse.NavItemView = Discourse.View.extend({
|
||||
tagName: 'li',
|
||||
classNameBindings: ['isActive', 'content.hasIcon:has-icon'],
|
||||
classNameBindings: ['active', 'content.hasIcon:has-icon'],
|
||||
attributeBindings: ['title'],
|
||||
countBinding: Ember.Binding.oneWay('content.count'),
|
||||
|
||||
hidden: Em.computed.not('content.visible'),
|
||||
count: Ember.computed.alias('content.count'),
|
||||
shouldRerender: Discourse.View.renderIfChanged('count'),
|
||||
active: Discourse.computed.propertyEqual('contentNameSlug', 'controller.filterMode'),
|
||||
|
||||
title: function() {
|
||||
var categoryName, extra, name;
|
||||
|
@ -23,16 +27,13 @@ Discourse.NavItemView = Discourse.View.extend({
|
|||
return I18n.t("filters." + name + ".help", extra);
|
||||
}.property("content.filter"),
|
||||
|
||||
isActive: function() {
|
||||
if (this.get("content.name").toLowerCase().replace(' ','-') === this.get("controller.filterMode")) return "active";
|
||||
return "";
|
||||
}.property("content.name", "controller.filterMode"),
|
||||
contentNameSlug: function() {
|
||||
return this.get("content.name").toLowerCase().replace(' ','-');
|
||||
}.property('content.name'),
|
||||
|
||||
hidden: Em.computed.not('content.visible'),
|
||||
|
||||
countChanged: function(){
|
||||
this.rerender();
|
||||
}.observes('count'),
|
||||
// active: function() {
|
||||
// return (this.get("contentNameSlug") === this.get("controller.filterMode"));
|
||||
// }.property("contentNameSlug", "controller.filterMode"),
|
||||
|
||||
name: function() {
|
||||
var categoryName, extra, name;
|
||||
|
|
|
@ -10,6 +10,17 @@ Discourse.PostMenuView = Discourse.View.extend({
|
|||
tagName: 'section',
|
||||
classNames: ['post-menu-area', 'clearfix'],
|
||||
|
||||
shouldRerender: Discourse.View.renderIfChanged(
|
||||
'post.deleted_at',
|
||||
'post.flagsAvailable.@each',
|
||||
'post.url',
|
||||
'post.bookmarked',
|
||||
'post.reply_count',
|
||||
'post.showRepliesBelow',
|
||||
'post.can_delete',
|
||||
'post.read',
|
||||
'post.topic.last_read_post_number'),
|
||||
|
||||
render: function(buffer) {
|
||||
var post = this.get('post');
|
||||
buffer.push("<nav class='post-controls'>");
|
||||
|
@ -35,12 +46,6 @@ Discourse.PostMenuView = Discourse.View.extend({
|
|||
handler.call(this);
|
||||
},
|
||||
|
||||
// Trigger re-rendering
|
||||
needsToRender: function() {
|
||||
this.rerender();
|
||||
}.observes('post.deleted_at', 'post.flagsAvailable.@each', 'post.url', 'post.bookmarked', 'post.reply_count',
|
||||
'post.showRepliesBelow', 'post.can_delete', 'post.read', 'post.topic.last_read_post_number'),
|
||||
|
||||
// Replies Button
|
||||
renderReplies: function(post, buffer) {
|
||||
if (!post.get('showRepliesBelow')) return;
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
Discourse.RawDivView = Ember.View.extend({
|
||||
|
||||
shouldRerender: Discourse.View.renderIfChanged('content'),
|
||||
|
||||
render: function(buffer) {
|
||||
buffer.push(this.get('content'));
|
||||
},
|
||||
|
||||
contentChanged: function() {
|
||||
this.rerender();
|
||||
}.observes('content')
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -11,9 +11,7 @@ Discourse.TopicClosingView = Discourse.View.extend({
|
|||
elementId: 'topic-closing-info',
|
||||
delayedRerender: null,
|
||||
|
||||
contentChanged: function() {
|
||||
this.rerender();
|
||||
}.observes('topic.details.auto_close_at'),
|
||||
shouldRerender: Discourse.View.renderIfChanged('topic.details.auto_close_at'),
|
||||
|
||||
render: function(buffer) {
|
||||
if (!this.present('topic.details.auto_close_at')) return;
|
||||
|
@ -49,12 +47,12 @@ Discourse.TopicClosingView = Discourse.View.extend({
|
|||
buffer.push('</h3>');
|
||||
|
||||
// TODO Sam: concerned this can cause a heavy rerender loop
|
||||
this.delayedRerender = Em.run.later(this, this.rerender, rerenderDelay);
|
||||
this.set('delayedRerender', Em.run.later(this, this.rerender, rerenderDelay));
|
||||
},
|
||||
|
||||
willDestroyElement: function() {
|
||||
if( this.delayedRerender ) {
|
||||
Em.run.cancel(this.delayedRerender);
|
||||
Em.run.cancel(this.get('delayedRerender'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -17,9 +17,7 @@ Discourse.TopicStatusView = Discourse.View.extend({
|
|||
return false;
|
||||
}.property('topic.closed', 'topic.pinned', 'topic.visible'),
|
||||
|
||||
statusChanged: function() {
|
||||
this.rerender();
|
||||
}.observes('topic.closed', 'topic.pinned', 'topic.visible'),
|
||||
shouldRerender: Discourse.View.renderIfChanged('topic.closed', 'topic.pinned', 'topic.visible'),
|
||||
|
||||
renderIcon: function(buffer, name, key) {
|
||||
var title = I18n.t("topic_statuses." + key + ".help");
|
||||
|
@ -27,8 +25,7 @@ Discourse.TopicStatusView = Discourse.View.extend({
|
|||
},
|
||||
|
||||
render: function(buffer) {
|
||||
|
||||
if (!this.get('hasDisplayableStatus')) return;
|
||||
if (!this.get('hasDisplayableStatus')) { return; }
|
||||
|
||||
// Allow a plugin to add a custom icon to a topic
|
||||
this.trigger('addCustomIcon', buffer);
|
||||
|
|
|
@ -26,12 +26,10 @@ Discourse.TopicSummaryView = Discourse.ContainerView.extend({
|
|||
return allLinks.slice(0, Discourse.TopicSummaryView.LINKS_SHOWN);
|
||||
}.property('topic.details.links', 'allLinksShown'),
|
||||
|
||||
newPostCreated: function() {
|
||||
this.rerender();
|
||||
}.observes('topic.posts_count'),
|
||||
shouldRerender: Discourse.View.renderIfChanged('topic.posts_count'),
|
||||
|
||||
hidden: function() {
|
||||
if (this.get('post.post_number') !== 1) return true;
|
||||
if (!this.get('post.firstPost')) return true;
|
||||
if (this.get('controller.content.archetype') === 'private_message') return false;
|
||||
if (this.get('controller.content.archetype') !== 'regular') return true;
|
||||
return this.get('controller.content.posts_count') < 2;
|
||||
|
|
|
@ -11,10 +11,7 @@ Discourse.ActivityFilterView = Discourse.View.extend({
|
|||
classNameBindings: ['active'],
|
||||
|
||||
stream: Em.computed.alias('controller.content'),
|
||||
|
||||
countChanged: function(){
|
||||
this.rerender();
|
||||
}.observes('count'),
|
||||
shouldRerender: Discourse.View.renderIfChanged('count'),
|
||||
|
||||
active: function() {
|
||||
var content = this.get('content');
|
||||
|
|
|
@ -26,6 +26,21 @@ Discourse.View.reopenClass({
|
|||
Discourse.Utilities.normalizeHash(hash, types);
|
||||
return Ember.Handlebars.helpers.view.call(this, helperClass, options);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Returns an observer that will re-render if properties change. This is useful for
|
||||
views where rendering is done to a buffer manually and need to know when to trigger
|
||||
a new render call.
|
||||
|
||||
@method renderIfChanged
|
||||
@params {String} propertyNames*
|
||||
@return {Function} observer
|
||||
**/
|
||||
renderIfChanged: function() {
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
args.unshift(function () { this.rerender(); });
|
||||
return Ember.observer.apply(this, args);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -40,7 +40,8 @@ class PostSerializer < BasicPostSerializer
|
|||
:hidden,
|
||||
:hidden_reason_id,
|
||||
:deleted_at,
|
||||
:trust_level
|
||||
:trust_level,
|
||||
:deleted_by
|
||||
|
||||
|
||||
def moderator?
|
||||
|
@ -72,7 +73,6 @@ class PostSerializer < BasicPostSerializer
|
|||
end
|
||||
|
||||
def link_counts
|
||||
|
||||
return @single_post_link_counts if @single_post_link_counts.present?
|
||||
|
||||
# TODO: This could be better, just porting the old one over
|
||||
|
|
Loading…
Reference in New Issue