FEATURE: improves composer-actions toggle menu

* only toggles
* fix a bug with presence
* more tests
* do not duplicate `continuing discussion...` text
* persist state to allow switching between toggles
This commit is contained in:
Joffrey JAFFEUX
2018-02-08 11:46:55 +01:00
committed by GitHub
parent 3b06e5502b
commit 190d208631
5 changed files with 189 additions and 35 deletions

View File

@ -1,6 +1,15 @@
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
import { default as computed } from "ember-addons/ember-computed-decorators";
import { default as Composer, REPLY, EDIT } from "discourse/models/composer";
import { default as Composer, PRIVATE_MESSAGE, CREATE_TOPIC, REPLY, EDIT } from "discourse/models/composer";
// Component can get destroyed and lose state
let _topicSnapshot = null;
let _postSnapshot = null;
export function _clearSnapshots() {
_topicSnapshot = null;
_postSnapshot = null;
}
export default DropdownSelectBoxComponent.extend({
composerController: Ember.inject.controller("composer"),
@ -13,10 +22,27 @@ export default DropdownSelectBoxComponent.extend({
allowAutoSelectFirst: false,
showFullTitle: false,
didReceiveAttrs() {
this._super();
// if we change topic we want to change both snapshots
if (this.get("composerModel.topic") && (!_topicSnapshot || this.get("composerModel.topic.id") !== _topicSnapshot.get("id"))) {
_topicSnapshot = this.get("composerModel.topic");
_postSnapshot = this.get("composerModel.post");
}
// if we hit reply on a different post we want to change postSnapshot
if (this.get("composerModel.post") && (!_postSnapshot || this.get("composerModel.post.id") !== _postSnapshot.get("id"))) {
_postSnapshot = this.get("composerModel.post");
}
},
computeHeaderContent() {
let content = this.baseHeaderComputedContent();
switch (this.get("action")) {
case PRIVATE_MESSAGE:
case CREATE_TOPIC:
case REPLY:
content.icon = "mail-forward";
break;
@ -28,18 +54,32 @@ export default DropdownSelectBoxComponent.extend({
return content;
},
@computed("options", "canWhisper", "composerModel.post.username")
content(options, canWhisper, postUsername) {
let items = [
{
@computed("options", "canWhisper", "action")
content(options, canWhisper, action) {
let items = [];
if (action !== CREATE_TOPIC) {
items.push({
name: I18n.t("composer.composer_actions.reply_as_new_topic.label"),
description: I18n.t("composer.composer_actions.reply_as_new_topic.desc"),
icon: "plus",
id: "reply_as_new_topic"
}
];
});
}
if (postUsername && postUsername !== this.currentUser.get("username")) {
if ((action !== REPLY && _postSnapshot) || (action === REPLY && _postSnapshot && !(options.userAvatar && options.userLink))) {
items.push({
name: I18n.t("composer.composer_actions.reply_to_post.label", {
postNumber: _postSnapshot.get("post_number"),
postUsername: _postSnapshot.get("username")
}),
description: I18n.t("composer.composer_actions.reply_to_post.desc"),
icon: "mail-forward",
id: "reply_to_post"
});
}
if (action !== PRIVATE_MESSAGE) {
items.push({
name: I18n.t("composer.composer_actions.reply_as_private_message.label"),
description: I18n.t("composer.composer_actions.reply_as_private_message.desc"),
@ -48,7 +88,7 @@ export default DropdownSelectBoxComponent.extend({
});
}
if (Ember.get(options, "postLink")) {
if ((action !== REPLY && _topicSnapshot) || (action === REPLY && _topicSnapshot && (options.userAvatar && options.userLink && options.topicLink))) {
items.push({
name: I18n.t("composer.composer_actions.reply_to_topic.label"),
description: I18n.t("composer.composer_actions.reply_to_topic.desc"),
@ -57,7 +97,8 @@ export default DropdownSelectBoxComponent.extend({
});
}
if (canWhisper) {
// if answered post is a whisper, we can only answer with a whisper so no need for toggle
if (canWhisper && (_postSnapshot && _postSnapshot.post_type !== this.site.post_types.whisper)) {
items.push({
name: I18n.t("composer.composer_actions.toggle_whisper.label"),
description: I18n.t("composer.composer_actions.toggle_whisper.desc"),
@ -69,46 +110,85 @@ export default DropdownSelectBoxComponent.extend({
return items;
},
_replyFromExisting(options) {
const topicTitle = this.get("composerModel.topic.title");
let url = this.get("composerModel.post.url") || this.get("composerModel.topic.url");
_replyFromExisting(options, post, topic) {
const reply = this.get("composerModel.reply");
let url;
if (post) url = post.get("url");
if (!post && topic) url = topic.get("url");
let topicTitle;
if (topic) topicTitle = topic.get("title");
this.get("composerController").close();
this.get("composerController").open(options).then(() => {
if (!url || ! topicTitle) return;
url = `${location.protocol}//${location.host}${url}`;
const link = `[${Handlebars.escapeExpression(topicTitle)}](${url})`;
this.get("composerController").get("model").prependText(`${I18n.t("post.continue_discussion", { postLink: link })}`, {new_line: true});
const continueDiscussion = I18n.t("post.continue_discussion", { postLink: link });
if (!reply.includes(continueDiscussion)) {
this.get("composerController")
.get("model")
.prependText(continueDiscussion, {new_line: true});
}
});
},
actions: {
onSelect(value) {
let options = {
draftKey: this.get("composerModel.draftKey"),
draftSequence: this.get("composerModel.draftSequence"),
reply: this.get("composerModel.reply")
};
switch(value) {
case "toggle_whisper":
this.set("composerModel.whisper", !this.get("composerModel.whisper"));
break;
case "reply_to_post":
options.action = Composer.REPLY;
options.post = _postSnapshot;
this.get("composerController").close();
this.get("composerController").open(options);
break;
case "reply_to_topic":
this.set("composerModel.post", null);
this.get("composerController").save();
options.action = Composer.REPLY;
options.topic = _topicSnapshot;
this.get("composerController").close();
this.get("composerController").open(options);
break;
case "reply_as_new_topic":
const replyAsNewTopicOpts = {
action: Composer.CREATE_TOPIC,
draftKey: Composer.REPLY_AS_NEW_TOPIC_KEY,
categoryId: this.get("composerModel.topic.category.id")
};
this._replyFromExisting(replyAsNewTopicOpts);
options.action = Composer.CREATE_TOPIC;
options.categoryId = this.get("composerModel.topic.category.id");
this.get("composerController").close();
this.get("composerController").open(options);
break;
case "reply_as_private_message":
const replyAsPrivateMsgOpts = {
action: Composer.PRIVATE_MESSAGE,
archetypeId: "private_message",
draftKey: Composer.REPLY_AS_NEW_PRIVATE_MESSAGE_KEY,
usernames: this.get("composerModel.post.username")
};
this._replyFromExisting(replyAsPrivateMsgOpts);
let usernames;
if (_postSnapshot && !_postSnapshot.get("yours")) {
const postUsername = _postSnapshot.get("username");
if (postUsername) {
usernames = postUsername;
}
}
options.action = Composer.PRIVATE_MESSAGE;
options.usernames = usernames;
options.archetypeId = "private_message";
options.draftKey = Composer.NEW_PRIVATE_MESSAGE_KEY;
this._replyFromExisting(options, _postSnapshot, _topicSnapshot);
break;
}
}