Adds support for dynamic composer messages.
This commit is contained in:
parent
9c6c0f2a3d
commit
0de96a6059
|
@ -7,10 +7,16 @@
|
|||
@module Discourse
|
||||
**/
|
||||
Discourse.ComposerController = Discourse.Controller.extend({
|
||||
needs: ['modal', 'topic'],
|
||||
needs: ['modal', 'topic', 'composerMessages'],
|
||||
|
||||
replyAsNewTopicDraft: Em.computed.equal('model.draftKey', Discourse.Composer.REPLY_AS_NEW_TOPIC_KEY),
|
||||
|
||||
|
||||
init: function() {
|
||||
this._super();
|
||||
this.set('similarTopics', Em.A());
|
||||
},
|
||||
|
||||
togglePreview: function() {
|
||||
this.get('model').togglePreview();
|
||||
},
|
||||
|
@ -94,7 +100,6 @@ Discourse.ComposerController = Discourse.Controller.extend({
|
|||
composerController.destroyDraft();
|
||||
}
|
||||
|
||||
|
||||
opts = opts || {};
|
||||
composerController.close();
|
||||
|
||||
|
@ -112,51 +117,27 @@ Discourse.ComposerController = Discourse.Controller.extend({
|
|||
});
|
||||
},
|
||||
|
||||
closeEducation: function() {
|
||||
this.set('educationClosed', true);
|
||||
},
|
||||
|
||||
closeSimilar: function() {
|
||||
this.set('similarClosed', true);
|
||||
},
|
||||
|
||||
similarVisible: function() {
|
||||
if (this.get('similarClosed')) return false;
|
||||
if (this.get('model.composeState') !== Discourse.Composer.OPEN) return false;
|
||||
return (this.get('similarTopics.length') || 0) > 0;
|
||||
}.property('similarTopics.length', 'similarClosed', 'model.composeState'),
|
||||
|
||||
newUserEducationVisible: function() {
|
||||
if (!this.get('educationContents')) return false;
|
||||
if (this.get('model.composeState') !== Discourse.Composer.OPEN) return false;
|
||||
if (!this.present('model.reply')) return false;
|
||||
if (this.get('educationClosed')) return false;
|
||||
return true;
|
||||
}.property('model.composeState', 'model.reply', 'educationClosed', 'educationContents'),
|
||||
|
||||
fetchNewUserEducation: function() {
|
||||
_considerNewUserEducation: function() {
|
||||
|
||||
// We don't show education when editing a post.
|
||||
if (this.get('model.editingPost')) return;
|
||||
|
||||
// If creating a topic, use topic_count, otherwise post_count
|
||||
var count = this.get('model.creatingTopic') ? Discourse.User.currentProp('topic_count') : Discourse.User.currentProp('reply_count');
|
||||
if (count >= Discourse.SiteSettings.educate_until_posts) {
|
||||
this.set('educationClosed', true);
|
||||
this.set('educationContents', '');
|
||||
return;
|
||||
}
|
||||
if (count >= Discourse.SiteSettings.educate_until_posts) { return; }
|
||||
|
||||
// The user must have typed a reply
|
||||
if (!this.get('typedReply')) return;
|
||||
|
||||
this.set('educationClosed', false);
|
||||
|
||||
// If visible update the text
|
||||
var educationKey = this.get('model.creatingTopic') ? 'new-topic' : 'new-reply';
|
||||
var composerController = this;
|
||||
var educationKey = this.get('model.creatingTopic') ? 'new-topic' : 'new-reply',
|
||||
messageController = this.get('controllers.composerMessages');
|
||||
|
||||
Discourse.ajax("/education/" + educationKey, {dataType: 'html'}).then(function(result) {
|
||||
composerController.set('educationContents', result);
|
||||
messageController.popup({
|
||||
templateName: 'composer/education',
|
||||
body: result
|
||||
});
|
||||
});
|
||||
|
||||
}.observes('typedReply', 'model.creatingTopic', 'currentUser.reply_count'),
|
||||
|
@ -176,16 +157,25 @@ Discourse.ComposerController = Discourse.Controller.extend({
|
|||
// We don't care about similar topics unless creating a topic
|
||||
if (!this.get('model.creatingTopic')) return;
|
||||
|
||||
var body = this.get('model.reply');
|
||||
var title = this.get('model.title');
|
||||
var body = this.get('model.reply'),
|
||||
title = this.get('model.title');
|
||||
|
||||
// Ensure the fields are of the minimum length
|
||||
if (body.length < Discourse.SiteSettings.min_body_similar_length) return;
|
||||
if (title.length < Discourse.SiteSettings.min_title_similar_length) return;
|
||||
|
||||
var composerController = this;
|
||||
Discourse.Topic.findSimilarTo(title, body).then(function (topics) {
|
||||
composerController.set('similarTopics', topics);
|
||||
var messageController = this.get('controllers.composerMessages'),
|
||||
similarTopics = this.get('similarTopics');
|
||||
|
||||
Discourse.Topic.findSimilarTo(title, body).then(function (newTopics) {
|
||||
similarTopics.clear();
|
||||
similarTopics.pushObjects(newTopics);
|
||||
|
||||
messageController.popup({
|
||||
templateName: 'composer/similar_topics',
|
||||
similarTopics: similarTopics,
|
||||
extraClass: 'similar-topics'
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
|
@ -211,8 +201,6 @@ Discourse.ComposerController = Discourse.Controller.extend({
|
|||
var promise = opts.promise || Ember.Deferred.create();
|
||||
opts.promise = promise;
|
||||
this.set('typedReply', false);
|
||||
this.set('similarTopics', null);
|
||||
this.set('similarClosed', false);
|
||||
|
||||
if (!opts.draftKey) {
|
||||
alert("composer was opened without a draft key");
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
A controller for displaying messages as the user composes a message.
|
||||
|
||||
@class ComposerMessagesController
|
||||
@extends Ember.ArrayController
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.ComposerMessagesController = Ember.ArrayController.extend({
|
||||
needs: ['composer'],
|
||||
|
||||
init: function() {
|
||||
this._super();
|
||||
this.set('messagesByTemplate', {});
|
||||
},
|
||||
|
||||
popup: function(msg) {
|
||||
var messagesByTemplate = this.get('messagesByTemplate'),
|
||||
existing = messagesByTemplate[msg.templateName];
|
||||
|
||||
if (!existing) {
|
||||
this.pushObject(msg);
|
||||
messagesByTemplate[msg.templateName] = msg;
|
||||
}
|
||||
},
|
||||
|
||||
closeMessage: function(message) {
|
||||
this.removeObject(message);
|
||||
}
|
||||
|
||||
});
|
|
@ -2,23 +2,7 @@
|
|||
|
||||
<div class='contents'>
|
||||
|
||||
<div class='composer-popup-container'>
|
||||
<div id='new-user-education' class='composer-popup' style='display: none'>
|
||||
<a href='#' {{action closeEducation}} class='close'><i class='icon icon-remove-sign'></i></a>
|
||||
{{{educationContents}}}
|
||||
</div>
|
||||
|
||||
<div id='similar-topics' class='composer-popup' style='display: none'>
|
||||
<a href='#' {{action closeSimilar}} class='close'><i class='icon icon-remove-sign'></i></a>
|
||||
<h3>{{i18n composer.similar_topics}}<h3>
|
||||
|
||||
<ul class='topics'>
|
||||
{{#each similarTopics}}
|
||||
<li>{{{topicLink this}}} <span class='posts-count'>({{{i18n topic.filters.n_posts count="posts_count"}}})</span></li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{render composerMessages}}
|
||||
|
||||
<div class='control'>
|
||||
<a href='#' class='toggler' {{action toggle bubbles=false}} title='{{i18n composer.toggler}}'></a>
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
<a href='#' {{action closeMessage this}} class='close'><i class='icon icon-remove-sign'></i></a>
|
||||
{{{body}}}
|
|
@ -0,0 +1,8 @@
|
|||
<a href='#' {{action closeMessage this}} class='close'><i class='icon icon-remove-sign'></i></a>
|
||||
<h3>{{i18n composer.similar_topics}}<h3>
|
||||
|
||||
<ul class='topics'>
|
||||
{{#each similarTopics}}
|
||||
<li>{{{topicLink this}}} <span class='posts-count'>({{{i18n topic.filters.n_posts count="posts_count"}}})</span></li>
|
||||
{{/each}}
|
||||
</ul>
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
Renders a popup messages on the composer
|
||||
|
||||
@class ComposerMessagesView
|
||||
@extends Discourse.View
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.ComposerMessagesView = Ember.CollectionView.extend({
|
||||
classNameBindings: [':composer-popup-container', 'hidden'],
|
||||
content: Em.computed.alias('controller.content'),
|
||||
|
||||
hidden: Em.computed.not('controller.controllers.composer.model.viewOpen'),
|
||||
|
||||
itemViewClass: Discourse.View.extend({
|
||||
classNames: ['composer-popup', 'hidden'],
|
||||
templateName: Em.computed.alias('content.templateName'),
|
||||
|
||||
init: function() {
|
||||
this._super();
|
||||
this.set('context', this.get('content'));
|
||||
|
||||
if (this.get('content.extraClass')) {
|
||||
this.get('classNames').pushObject(this.get('content.extraClass'));
|
||||
}
|
||||
},
|
||||
|
||||
didInsertElement: function() {
|
||||
var replyControl = $('#reply-control');
|
||||
this.$().css('bottom', (replyControl.height() || 0) + "px").slideDown('fast');
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
|
@ -67,24 +67,6 @@ Discourse.ComposerView = Discourse.View.extend({
|
|||
});
|
||||
}.observes('model.reply', 'model.hidePreview'),
|
||||
|
||||
newUserEducationVisibilityChanged: function() {
|
||||
var $panel = $('#new-user-education');
|
||||
if (this.get('controller.newUserEducationVisible')) {
|
||||
$panel.slideDown('fast');
|
||||
} else {
|
||||
$panel.slideUp('fast');
|
||||
}
|
||||
}.observes('controller.newUserEducationVisible'),
|
||||
|
||||
similarVisibilityChanged: function() {
|
||||
var $panel = $('#similar-topics');
|
||||
if (this.get('controller.similarVisible')) {
|
||||
$panel.slideDown('fast');
|
||||
} else {
|
||||
$panel.slideUp('fast');
|
||||
}
|
||||
}.observes('controller.similarVisible'),
|
||||
|
||||
movePanels: function(sizePx) {
|
||||
$('.composer-popup').css('bottom', sizePx);
|
||||
},
|
|
@ -15,6 +15,7 @@
|
|||
//= require_tree ./discourse/mixins
|
||||
//= require ./discourse/components/computed
|
||||
//= require ./discourse/views/view
|
||||
//= require ./discourse/views/container_view
|
||||
//= require ./discourse/components/debounce
|
||||
//= require ./discourse/models/model
|
||||
//= require ./discourse/models/user_action
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
#similar-topics {
|
||||
.similar-topics {
|
||||
background-color: #b5e8fd;
|
||||
border: 1px solid darken(#b5e8fd, 10%);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.composer-popup, #similar-topics {
|
||||
.composer-popup {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue