mirror of
https://github.com/discourse/discourse.git
synced 2025-05-23 18:01:09 +08:00

This feature can be enabled by choosing a destination for the `shared drafts category` site setting. * Staff members can create shared drafts, choosing a destination category for the topic when it is published. * Shared Drafts can be viewed in their category, or above the topic list for the destination category where it will end up. * When the shared draft is ready, it can be published to the appropriate category by clicking a button on the topic view. * When published, Drafts change their timestamps to the current time, and any edits to the original post are removed.
257 lines
7.7 KiB
JavaScript
257 lines
7.7 KiB
JavaScript
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
|
|
import computed from "ember-addons/ember-computed-decorators";
|
|
import {
|
|
PRIVATE_MESSAGE,
|
|
CREATE_TOPIC,
|
|
CREATE_SHARED_DRAFT,
|
|
REPLY,
|
|
EDIT,
|
|
NEW_PRIVATE_MESSAGE_KEY
|
|
} 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"),
|
|
pluginApiIdentifiers: ["composer-actions"],
|
|
classNames: "composer-actions",
|
|
fullWidthOnMobile: true,
|
|
autofilterable: false,
|
|
filterable: false,
|
|
allowInitialValueMutation: false,
|
|
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;
|
|
case EDIT:
|
|
content.icon = "pencil";
|
|
break;
|
|
case CREATE_SHARED_DRAFT:
|
|
content.icon = 'clipboard';
|
|
break;
|
|
};
|
|
|
|
return content;
|
|
},
|
|
|
|
@computed("options", "canWhisper", "action")
|
|
content(options, canWhisper, action) {
|
|
let items = [];
|
|
|
|
if (action !== CREATE_TOPIC && action !== CREATE_SHARED_DRAFT) {
|
|
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 ((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 (this.siteSettings.enable_personal_messages && 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"),
|
|
icon: "envelope",
|
|
id: "reply_as_private_message"
|
|
});
|
|
}
|
|
|
|
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"),
|
|
icon: "mail-forward",
|
|
id: "reply_to_topic"
|
|
});
|
|
}
|
|
|
|
// if answered post is a whisper, we can only answer with a whisper so no need for toggle
|
|
if (canWhisper && (!_postSnapshot || _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"),
|
|
icon: "eye-slash",
|
|
id: "toggle_whisper"
|
|
});
|
|
}
|
|
|
|
let showCreateTopic = false;
|
|
if (action === CREATE_SHARED_DRAFT) {
|
|
showCreateTopic = true;
|
|
}
|
|
|
|
if (action === CREATE_TOPIC) {
|
|
if (this.site.shared_drafts_category_id) {
|
|
// Shared Drafts Choice
|
|
items.push({
|
|
name: I18n.t("composer.composer_actions.shared_draft.label"),
|
|
description: I18n.t("composer.composer_actions.shared_draft.desc"),
|
|
icon: "clipboard",
|
|
id: "shared_draft"
|
|
});
|
|
}
|
|
|
|
// Edge case: If personal messages are disabled, it is possible to have
|
|
// no items which stil renders a button that pops up nothing. In this
|
|
// case, add an option for what you're currently doing.
|
|
if (items.length === 0) {
|
|
showCreateTopic = true;
|
|
}
|
|
}
|
|
|
|
if (showCreateTopic) {
|
|
items.push({
|
|
name: I18n.t("composer.composer_actions.create_topic.label"),
|
|
description: I18n.t("composer.composer_actions.reply_as_new_topic.desc"),
|
|
icon: "mail-forward",
|
|
id: "create_topic"
|
|
});
|
|
}
|
|
|
|
return items;
|
|
},
|
|
|
|
_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})`;
|
|
const continueDiscussion = I18n.t("post.continue_discussion", { postLink: link });
|
|
|
|
if (!reply.includes(continueDiscussion)) {
|
|
this.get("composerController")
|
|
.get("model")
|
|
.prependText(continueDiscussion, {new_line: true});
|
|
}
|
|
});
|
|
},
|
|
|
|
_openComposer(options) {
|
|
this.get("composerController").close();
|
|
this.get("composerController").open(options);
|
|
},
|
|
|
|
toggleWhisperSelected(options, model) {
|
|
model.toggleProperty('whisper');
|
|
},
|
|
|
|
replyToTopicSelected(options) {
|
|
options.action = REPLY;
|
|
options.topic = _topicSnapshot;
|
|
this._openComposer(options);
|
|
},
|
|
|
|
replyToPostSelected(options) {
|
|
options.action = REPLY;
|
|
options.post = _postSnapshot;
|
|
this._openComposer(options);
|
|
},
|
|
|
|
replyAsNewTopicSelected(options) {
|
|
options.action = CREATE_TOPIC;
|
|
options.categoryId = this.get("composerModel.topic.category.id");
|
|
this._replyFromExisting(options, _postSnapshot, _topicSnapshot);
|
|
},
|
|
|
|
replyAsPrivateMessageSelected(options) {
|
|
let usernames;
|
|
|
|
if (_postSnapshot && !_postSnapshot.get("yours")) {
|
|
const postUsername = _postSnapshot.get("username");
|
|
if (postUsername) {
|
|
usernames = postUsername;
|
|
}
|
|
}
|
|
|
|
options.action = PRIVATE_MESSAGE;
|
|
options.usernames = usernames;
|
|
options.archetypeId = "private_message";
|
|
options.draftKey = NEW_PRIVATE_MESSAGE_KEY;
|
|
|
|
this._replyFromExisting(options, _postSnapshot, _topicSnapshot);
|
|
},
|
|
|
|
_switchCreate(options, action) {
|
|
options.action = action;
|
|
options.categoryId = this.get("composerModel.categoryId");
|
|
options.topicTitle = this.get('composerModel.title');
|
|
this._openComposer(options);
|
|
},
|
|
|
|
createTopicSelected(options) {
|
|
this._switchCreate(options, CREATE_TOPIC);
|
|
},
|
|
|
|
sharedDraftSelected(options) {
|
|
this._switchCreate(options, CREATE_SHARED_DRAFT);
|
|
},
|
|
|
|
actions: {
|
|
onSelect(value) {
|
|
let action = `${Ember.String.camelize(value)}Selected`;
|
|
if (this[action]) {
|
|
let model = this.get('composerModel');
|
|
this[action](
|
|
model.getProperties('draftKey', 'draftSequence', 'reply'),
|
|
model
|
|
);
|
|
} else {
|
|
Ember.Logger.error(`No method '${action}' found`);
|
|
}
|
|
}
|
|
}
|
|
});
|