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();
},
/**
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);
});
});
},
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() {
@ -414,15 +428,6 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
return false;
},
clearFlags: function(actionType) {
actionType.clearFlags();
},
// Who acted on a particular post / action type
whoActed: function(actionType) {
actionType.loadUsers();
},
recoverPost: function(post) {
post.recover();
},
@ -473,22 +478,9 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
}
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>
{{view Discourse.PostMenuView postBinding="this" postViewBinding="view"}}
</div>
{{view Discourse.RepliesView contentBinding="replies" postViewBinding="view"}}
{{view Discourse.ActionsHistoryView postBinding="this"}}
{{view Discourse.TopicMapView postBinding="this"}}
{{view Discourse.RepliesView content=replies postView=view}}
{{discourse-action-history post=this}}
{{view Discourse.TopicMapView post=this topic=controller.model}}
</div>
<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
buffer rendering for performance rather than a template.
@class ActionsHistoryView
@class ActionsHistoryComponent
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.ActionsHistoryView = Discourse.View.extend({
Discourse.ActionsHistoryComponent = Em.Component.extend({
tagName: 'section',
classNameBindings: [':post-actions', 'hidden'],
content: Em.computed.alias('post.actionsHistory'),
noContent: Em.computed.empty('content'),
hidden: Em.computed.and('noContent', 'post.notDeleted'),
shouldRerender: Discourse.View.renderIfChanged('content.@each', 'content.users.length', 'post.deleted'),
actionsHistory: Em.computed.alias('post.actionsHistory'),
emptyHistory: Em.computed.empty('actionsHistory'),
hidden: Em.computed.and('emptyHistory', 'post.notDeleted'),
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.
render: function(buffer) {
if (this.present('content')) {
this.get('content').forEach(function(c) {
if (!this.get('emptyHistory')) {
this.get('actionsHistory').forEach(function(c) {
buffer.push("<div class='post-action'>");
var renderActionIf = function(property, dataAttribute, text) {
@ -69,7 +69,7 @@ Discourse.ActionsHistoryView = Discourse.View.extend({
},
actionTypeById: function(actionTypeId) {
return this.get('content').findProperty('id', actionTypeId);
return this.get('actionsHistory').findProperty('id', actionTypeId);
},
click: function(e) {
@ -77,23 +77,23 @@ Discourse.ActionsHistoryView = Discourse.View.extend({
actionTypeId;
if (actionTypeId = $target.data('clear-flags')) {
this.get('controller').clearFlags(this.actionTypeById(actionTypeId));
this.actionTypeById(actionTypeId).clearFlags();
return false;
}
// User wants to know who actioned it
if (actionTypeId = $target.data('who-acted')) {
this.get('controller').whoActed(this.actionTypeById(actionTypeId));
this.actionTypeById(actionTypeId).loadUsers();
return false;
}
if (actionTypeId = $target.data('act')) {
this.get('content').findProperty('id', actionTypeId).act();
this.get('actionsHistory').findProperty('id', actionTypeId).act();
return false;
}
if (actionTypeId = $target.data('undo')) {
this.get('content').findProperty('id', actionTypeId).undo();
this.get('actionsHistory').findProperty('id', actionTypeId).undo();
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
@extends Discourse.View
@namespace 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() {
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;
}.property('allLinksShown', 'topic.details.links'),
@ -23,16 +24,18 @@ Discourse.TopicMapView = Discourse.ContainerView.extend({
var allLinks = this.get('topic.details.links');
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'),
shouldRerender: Discourse.View.renderIfChanged('topic.posts_count'),
hidden: function() {
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;
var topic = this.get('topic');
if (topic.get('archetype') === 'private_message') return false;
if (topic.get('archetype') !== 'regular') return true;
return topic.get('posts_count') < 2;
}.property(),
init: function() {
@ -44,23 +47,22 @@ Discourse.TopicMapView = Discourse.ContainerView.extend({
content: this.get('controller')
}, Discourse.GroupedView);
this.trigger('appendSummaryInformation', this);
this.trigger('appendMapInformation', this);
},
showAllLinks: function() {
this.set('allLinksShown', true);
actions: {
showAllLinks: function() {
this.set('allLinksShown', true);
},
},
appendSummaryInformation: function(container) {
appendMapInformation: function(container) {
// If we have a best of view
if (this.get('controller.has_best_of')) {
container.attachViewWithArgs({
templateName: 'topic_map/best_of_toggle',
tagName: 'section',
classNames: ['information'],
content: this.get('controller')
}, Discourse.GroupedView);
var topic = this.get('topic');
// If we have a best of capability
if (topic.get('has_best_of')) {
container.attachViewWithArgs({ topic: topic }, Discourse.DiscourseToggleBestOfComponent);
}
// 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;
}
.topic-summary {
.topic-map {
margin: 20px 0 0 0;
border: 1px solid #ddd;
@ -602,7 +602,7 @@ blockquote { /* solo quotes */
blockquote {margin-top: 0; padding-top: 0;
.onebox-result {background-color: #ddd;}
}
.title {

View File

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