discourse/app/assets/javascripts/discourse/components/composer-messages.js.es6

185 lines
5.9 KiB
JavaScript

import LinkLookup from 'discourse/lib/link-lookup';
export default Ember.Component.extend({
classNameBindings: [':composer-popup-container', 'hidden'],
checkedMessages: false,
messages: null,
messagesByTemplate: null,
queuedForTyping: null,
_lastSimilaritySearch: null,
_similarTopicsMessage: null,
_yourselfConfirm: null,
similarTopics: null,
hidden: Ember.computed.not('composer.viewOpen'),
didInsertElement() {
this._super();
this.appEvents.on('composer:typed-reply', this, this._typedReply);
this.appEvents.on('composer:opened', this, this._findMessages);
this.appEvents.on('composer:find-similar', this, this._findSimilar);
this.appEvents.on('composer-messages:close', this, this._closeTop);
this.appEvents.on('composer-messages:create', this, this._create);
Ember.run.scheduleOnce('afterRender', this, this.reset);
},
willDestroyElement() {
this.appEvents.off('composer:typed-reply', this, this._typedReply);
this.appEvents.off('composer:opened', this, this._findMessages);
this.appEvents.off('composer:find-similar', this, this._findSimilar);
this.appEvents.off('composer-messages:close', this, this._closeTop);
this.appEvents.off('composer-messages:create', this, this._create);
},
_closeTop() {
const messages = this.get('messages');
messages.popObject();
this.set('messageCount', messages.get('length'));
},
_removeMessage(message) {
const messages = this.get('messages');
messages.removeObject(message);
this.set('messageCount', messages.get('length'));
},
actions: {
closeMessage(message) {
this._removeMessage(message);
},
hideMessage(message) {
this._removeMessage(message);
// kind of hacky but the visibility depends on this
this.get('messagesByTemplate')[message.get('templateName')] = undefined;
},
popup(message) {
const messagesByTemplate = this.get('messagesByTemplate');
const templateName = message.get('templateName');
if (!messagesByTemplate[templateName]) {
const messages = this.get('messages');
messages.pushObject(message);
this.set('messageCount', messages.get('length'));
messagesByTemplate[templateName] = message;
}
}
},
// Resets all active messages.
// For example if composing a new post.
reset() {
if (this.isDestroying || this.isDestroyed) { return; }
this.setProperties({
messages: [],
messagesByTemplate: {},
queuedForTyping: [],
checkedMessages: false,
similarTopics: [],
});
},
// Called after the user has typed a reply.
// Some messages only get shown after being typed.
_typedReply() {
if (this.isDestroying || this.isDestroyed) { return; }
const composer = this.get('composer');
if (composer.get('privateMessage')) {
let usernames = composer.get('targetUsernames');
if (usernames) {
usernames = usernames.split(',');
}
if (usernames && usernames.length === 1 && usernames[0] === this.currentUser.get('username')) {
const message = this._yourselfConfirm || composer.store.createRecord('composer-message', {
id: 'yourself_confirm',
templateName: 'custom-body',
title: I18n.t('composer.yourself_confirm.title'),
body: I18n.t('composer.yourself_confirm.body')
});
this.send('popup', message);
}
}
this.get('queuedForTyping').forEach(msg => this.send("popup", msg));
},
_create(info) {
this.reset();
this.send('popup', Ember.Object.create(info));
},
_findSimilar() {
const composer = this.get('composer');
// We don't care about similar topics unless creating a topic
if (!composer.get('creatingTopic')) { return; }
const origBody = composer.get('reply') || '';
const title = composer.get('title') || '';
// Ensure the fields are of the minimum length
if (origBody.length < Discourse.SiteSettings.min_body_similar_length) { return; }
if (title.length < Discourse.SiteSettings.min_title_similar_length) { return; }
// TODO pass the 200 in from somewhere
const body = origBody.substr(0, 200);
// Don't search over and over
const concat = title + body;
if (concat === this._lastSimilaritySearch) { return; }
this._lastSimilaritySearch = concat;
const similarTopics = this.get('similarTopics');
const message = this._similarTopicsMessage || composer.store.createRecord('composer-message', {
id: 'similar_topics',
templateName: 'similar-topics',
extraClass: 'similar-topics'
});
this._similarTopicsMessage = message;
composer.store.find('similar-topic', {title, raw: body}).then(newTopics => {
similarTopics.clear();
similarTopics.pushObjects(newTopics.get('content'));
if (similarTopics.get('length') > 0) {
message.set('similarTopics', similarTopics);
this.send('popup', message);
} else if (message) {
this.send('hideMessage', message);
}
});
},
// Figure out if there are any messages that should be displayed above the composer.
_findMessages() {
if (this.get('checkedMessages')) { return; }
const composer = this.get('composer');
const args = { composer_action: composer.get('action') };
const topicId = composer.get('topic.id');
const postId = composer.get('post.id');
if (topicId) { args.topic_id = topicId; }
if (postId) { args.post_id = postId; }
const queuedForTyping = this.get('queuedForTyping');
composer.store.find('composer-message', args).then(messages => {
// Checking composer messages on replies can give us a list of links to check for
// duplicates
if (messages.extras && messages.extras.duplicate_lookup) {
this.sendAction('addLinkLookup', new LinkLookup(messages.extras.duplicate_lookup));
}
this.set('checkedMessages', true);
messages.forEach(msg => msg.wait_for_typing ? queuedForTyping.addObject(msg) : this.send('popup', msg));
});
}
});