Convert some TopicMap stuff to Ember components

This commit is contained in:
Robin Ward 2013-11-15 13:30:24 -05:00
parent ad3e276b4b
commit 039acd6ead
9 changed files with 81 additions and 76 deletions

View File

@ -0,0 +1,12 @@
Discourse.DiscourseToggleBestOfComponent = Ember.Component.extend({
templateName: 'components/discourse-toggle-best-of',
tagName: 'section',
classNames: ['information'],
postStream: Em.computed.alias('topic.postStream'),
actions: {
toggleBestOf: function() {
this.get('postStream').toggleBestOf();
}
}
});

View File

@ -184,7 +184,6 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
this.get('content').toggleStar(); this.get('content').toggleStar();
}, },
/** /**
Clears the pin from a topic for the currently logged in user Clears the pin from a topic for the currently logged in user
@ -221,7 +220,22 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
}) + "\n\n" + q); }) + "\n\n" + q);
}); });
}); });
},
removeAllowedUser: function(username) {
var self = this;
bootbox.dialog(I18n.t("private_message_info.remove_allowed_user", {name: username}), [
{label: I18n.t("no_value"),
'class': 'btn-danger rightg'},
{label: I18n.t("yes_value"),
'class': 'btn-primary',
callback: function() {
self.get('details').removeAllowedUser(username);
}
}
]);
} }
}, },
jumpTopDisabled: function() { jumpTopDisabled: function() {
@ -414,15 +428,6 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
return false; return false;
}, },
clearFlags: function(actionType) {
actionType.clearFlags();
},
// Who acted on a particular post / action type
whoActed: function(actionType) {
actionType.loadUsers();
},
recoverPost: function(post) { recoverPost: function(post) {
post.recover(); post.recover();
}, },
@ -473,22 +478,9 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
} }
return true; return true;
} }
},
removeAllowedUser: function(username) {
var self = this;
bootbox.dialog(I18n.t("private_message_info.remove_allowed_user", {name: username}), [
{label: I18n.t("no_value"),
'class': 'btn-danger rightg'},
{label: I18n.t("yes_value"),
'class': 'btn-primary',
callback: function() {
self.get('details').removeAllowedUser(username);
}
}
]);
} }
}); });

View File

@ -0,0 +1,9 @@
<h3><i class='icon icon-bullhorn'></i> {{i18n best_of.title}}</h3>
{{#if postStream.bestOf}}
<p>{{{i18n best_of.enabled_description}}}</p>
<button class='btn' {{action toggleBestOf}}>{{i18n best_of.disable}}</button>
{{else}}
<p>{{{i18n best_of.description count="topic.posts_count"}}}</p>
<button class='btn' {{action toggleBestOf}}>{{i18n best_of.enable}}</button>
{{/if}}

View File

@ -68,9 +68,9 @@
<div class='cooked'>{{{cooked}}}</div> <div class='cooked'>{{{cooked}}}</div>
{{view Discourse.PostMenuView postBinding="this" postViewBinding="view"}} {{view Discourse.PostMenuView postBinding="this" postViewBinding="view"}}
</div> </div>
{{view Discourse.RepliesView contentBinding="replies" postViewBinding="view"}} {{view Discourse.RepliesView content=replies postView=view}}
{{view Discourse.ActionsHistoryView postBinding="this"}} {{discourse-action-history post=this}}
{{view Discourse.TopicMapView postBinding="this"}} {{view Discourse.TopicMapView post=this topic=controller.model}}
</div> </div>
<div class='span5 gutter'> <div class='span5 gutter'>

View File

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

View File

@ -2,24 +2,24 @@
This view handles rendering of what actions have been taken on a post. It uses This view handles rendering of what actions have been taken on a post. It uses
buffer rendering for performance rather than a template. buffer rendering for performance rather than a template.
@class ActionsHistoryView @class ActionsHistoryComponent
@extends Discourse.View @extends Discourse.View
@namespace Discourse @namespace Discourse
@module Discourse @module Discourse
**/ **/
Discourse.ActionsHistoryView = Discourse.View.extend({ Discourse.ActionsHistoryComponent = Em.Component.extend({
tagName: 'section', tagName: 'section',
classNameBindings: [':post-actions', 'hidden'], classNameBindings: [':post-actions', 'hidden'],
content: Em.computed.alias('post.actionsHistory'), actionsHistory: Em.computed.alias('post.actionsHistory'),
noContent: Em.computed.empty('content'), emptyHistory: Em.computed.empty('actionsHistory'),
hidden: Em.computed.and('noContent', 'post.notDeleted'), hidden: Em.computed.and('emptyHistory', 'post.notDeleted'),
shouldRerender: Discourse.View.renderIfChanged('content.@each', 'content.users.length', 'post.deleted'), shouldRerender: Discourse.View.renderIfChanged('actionsHistory.@each', 'actionsHistory.users.length', 'post.deleted'),
// This was creating way too many bound ifs and subviews in the handlebars version. // This was creating way too many bound ifs and subviews in the handlebars version.
render: function(buffer) { render: function(buffer) {
if (this.present('content')) { if (!this.get('emptyHistory')) {
this.get('content').forEach(function(c) { this.get('actionsHistory').forEach(function(c) {
buffer.push("<div class='post-action'>"); buffer.push("<div class='post-action'>");
var renderActionIf = function(property, dataAttribute, text) { var renderActionIf = function(property, dataAttribute, text) {
@ -69,7 +69,7 @@ Discourse.ActionsHistoryView = Discourse.View.extend({
}, },
actionTypeById: function(actionTypeId) { actionTypeById: function(actionTypeId) {
return this.get('content').findProperty('id', actionTypeId); return this.get('actionsHistory').findProperty('id', actionTypeId);
}, },
click: function(e) { click: function(e) {
@ -77,23 +77,23 @@ Discourse.ActionsHistoryView = Discourse.View.extend({
actionTypeId; actionTypeId;
if (actionTypeId = $target.data('clear-flags')) { if (actionTypeId = $target.data('clear-flags')) {
this.get('controller').clearFlags(this.actionTypeById(actionTypeId)); this.actionTypeById(actionTypeId).clearFlags();
return false; return false;
} }
// User wants to know who actioned it // User wants to know who actioned it
if (actionTypeId = $target.data('who-acted')) { if (actionTypeId = $target.data('who-acted')) {
this.get('controller').whoActed(this.actionTypeById(actionTypeId)); this.actionTypeById(actionTypeId).loadUsers();
return false; return false;
} }
if (actionTypeId = $target.data('act')) { if (actionTypeId = $target.data('act')) {
this.get('content').findProperty('id', actionTypeId).act(); this.get('actionsHistory').findProperty('id', actionTypeId).act();
return false; return false;
} }
if (actionTypeId = $target.data('undo')) { if (actionTypeId = $target.data('undo')) {
this.get('content').findProperty('id', actionTypeId).undo(); this.get('actionsHistory').findProperty('id', actionTypeId).undo();
return false; return false;
} }
@ -102,3 +102,4 @@ Discourse.ActionsHistoryView = Discourse.View.extend({
}); });
Discourse.View.registerHelper('discourse-action-history', Discourse.ActionsHistoryComponent);

View File

@ -1,20 +1,21 @@
/** /**
This view handles rendering of the summary of the topic under the first post This view handles rendering of the map of the topic under the first post
@class TopicMapView @class TopicMapView
@extends Discourse.View @extends Discourse.View
@namespace Discourse @namespace Discourse
@module Discourse @module Discourse
**/ **/
Discourse.TopicMapView = Discourse.ContainerView.extend({
classNameBindings: ['hidden', ':topic-summary'],
allLinksShown: false,
topic: Em.computed.alias('controller.model'), var LINKS_SHOWN = 5;
Discourse.TopicMapView = Discourse.ContainerView.extend({
classNameBindings: ['hidden', ':topic-map'],
allLinksShown: false,
showAllLinksControls: function() { showAllLinksControls: function() {
if (this.get('allLinksShown')) return false; if (this.get('allLinksShown')) return false;
if ((this.get('topic.details.links.length') || 0) <= Discourse.TopicMapView.LINKS_SHOWN) return false; if ((this.get('topic.details.links.length') || 0) <= LINKS_SHOWN) return false;
return true; return true;
}.property('allLinksShown', 'topic.details.links'), }.property('allLinksShown', 'topic.details.links'),
@ -23,16 +24,18 @@ Discourse.TopicMapView = Discourse.ContainerView.extend({
var allLinks = this.get('topic.details.links'); var allLinks = this.get('topic.details.links');
if (this.get('allLinksShown')) return allLinks; if (this.get('allLinksShown')) return allLinks;
return allLinks.slice(0, Discourse.TopicMapView.LINKS_SHOWN); return allLinks.slice(0, LINKS_SHOWN);
}.property('topic.details.links', 'allLinksShown'), }.property('topic.details.links', 'allLinksShown'),
shouldRerender: Discourse.View.renderIfChanged('topic.posts_count'), shouldRerender: Discourse.View.renderIfChanged('topic.posts_count'),
hidden: function() { hidden: function() {
if (!this.get('post.firstPost')) 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; var topic = this.get('topic');
return this.get('controller.content.posts_count') < 2; if (topic.get('archetype') === 'private_message') return false;
if (topic.get('archetype') !== 'regular') return true;
return topic.get('posts_count') < 2;
}.property(), }.property(),
init: function() { init: function() {
@ -44,23 +47,22 @@ Discourse.TopicMapView = Discourse.ContainerView.extend({
content: this.get('controller') content: this.get('controller')
}, Discourse.GroupedView); }, Discourse.GroupedView);
this.trigger('appendSummaryInformation', this); this.trigger('appendMapInformation', this);
}, },
showAllLinks: function() { actions: {
this.set('allLinksShown', true); showAllLinks: function() {
this.set('allLinksShown', true);
},
}, },
appendSummaryInformation: function(container) { appendMapInformation: function(container) {
// If we have a best of view var topic = this.get('topic');
if (this.get('controller.has_best_of')) {
container.attachViewWithArgs({ // If we have a best of capability
templateName: 'topic_map/best_of_toggle', if (topic.get('has_best_of')) {
tagName: 'section', container.attachViewWithArgs({ topic: topic }, Discourse.DiscourseToggleBestOfComponent);
classNames: ['information'],
content: this.get('controller')
}, Discourse.GroupedView);
} }
// If we have a private message // If we have a private message
@ -75,6 +77,3 @@ Discourse.TopicMapView = Discourse.ContainerView.extend({
} }
}); });
Discourse.TopicMapView.reopenClass({
LINKS_SHOWN: 5
});

View File

@ -211,7 +211,7 @@ a.star {
text-shadow: none !important; text-shadow: none !important;
} }
.topic-summary { .topic-map {
margin: 20px 0 0 0; margin: 20px 0 0 0;
border: 1px solid #ddd; border: 1px solid #ddd;
@ -602,7 +602,7 @@ blockquote { /* solo quotes */
blockquote {margin-top: 0; padding-top: 0; blockquote {margin-top: 0; padding-top: 0;
.onebox-result {background-color: #ddd;} .onebox-result {background-color: #ddd;}
} }
.title { .title {

View File

@ -126,7 +126,7 @@ a.star {
text-shadow: none !important; text-shadow: none !important;
} }
.topic-summary { .topic-map {
.btn { .btn {
border-radius: 0 4px 0 4px; border-radius: 0 4px 0 4px;