FEATURE: Allow Markdown in post notices. (#7864)

This commit is contained in:
Dan Ungureanu 2019-07-09 14:42:02 +03:00 committed by GitHub
parent 6b0cc9e22e
commit 9f5cfa192e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 14 deletions

View File

@ -1,5 +1,6 @@
import ModalFunctionality from "discourse/mixins/modal-functionality"; import ModalFunctionality from "discourse/mixins/modal-functionality";
import computed from "ember-addons/ember-computed-decorators"; import computed from "ember-addons/ember-computed-decorators";
import { cookAsync } from "discourse/lib/text";
export default Ember.Controller.extend(ModalFunctionality, { export default Ember.Controller.extend(ModalFunctionality, {
post: null, post: null,
@ -42,10 +43,11 @@ export default Ember.Controller.extend(ModalFunctionality, {
post post
.updatePostField("notice", notice) .updatePostField("notice", notice)
.then(() => { .then(() => cookAsync(notice, { features: { onebox: false } }))
.then(cookedNotice => {
post.setProperties({ post.setProperties({
notice_type: "custom", notice_type: "custom",
notice_args: notice notice_args: cookedNotice.string
}); });
resolve(); resolve();
this.send("closeModal"); this.send("closeModal");

View File

@ -1,6 +1,7 @@
import PostCooked from "discourse/widgets/post-cooked"; import PostCooked from "discourse/widgets/post-cooked";
import DecoratorHelper from "discourse/widgets/decorator-helper"; import DecoratorHelper from "discourse/widgets/decorator-helper";
import { createWidget, applyDecorators } from "discourse/widgets/widget"; import { createWidget, applyDecorators } from "discourse/widgets/widget";
import RawHtml from "discourse/widgets/raw-html";
import { iconNode } from "discourse-common/lib/icon-library"; import { iconNode } from "discourse-common/lib/icon-library";
import { transformBasicPost } from "discourse/lib/transform-post"; import { transformBasicPost } from "discourse/lib/transform-post";
import { postTransformCallbacks } from "discourse/widgets/post-stream"; import { postTransformCallbacks } from "discourse/widgets/post-stream";
@ -459,20 +460,23 @@ createWidget("post-notice", {
let text, icon; let text, icon;
if (attrs.noticeType === "custom") { if (attrs.noticeType === "custom") {
icon = "user-shield"; icon = "user-shield";
text = attrs.noticeMessage; text = new RawHtml({ html: `<div>${attrs.noticeMessage}</div>` });
} else if (attrs.noticeType === "new_user") { } else if (attrs.noticeType === "new_user") {
icon = "hands-helping"; icon = "hands-helping";
text = I18n.t("post.notice.new_user", { user }); text = h("p", I18n.t("post.notice.new_user", { user }));
} else if (attrs.noticeType === "returning_user") { } else if (attrs.noticeType === "returning_user") {
icon = "far-smile"; icon = "far-smile";
const distance = (new Date() - new Date(attrs.noticeTime)) / 1000; const distance = (new Date() - new Date(attrs.noticeTime)) / 1000;
text = I18n.t("post.notice.returning_user", { text = h(
user, "p",
time: durationTiny(distance, { addAgo: true }) I18n.t("post.notice.returning_user", {
}); user,
time: durationTiny(distance, { addAgo: true })
})
);
} }
return h("p", [iconNode(icon), text]); return [iconNode(icon), text];
} }
}); });

View File

@ -905,11 +905,12 @@ a.mention-group {
} }
.post-notice { .post-notice {
align-items: center;
background-color: $tertiary-low; background-color: $tertiary-low;
border-top: 1px solid $primary-low; border-top: 1px solid $primary-low;
color: $primary; display: flex;
padding: 0.8em;
max-width: calc(#{$topic-body-width} + #{$topic-avatar-width} - 0.1em); max-width: calc(#{$topic-body-width} + #{$topic-avatar-width} - 0.1em);
padding: 0.8em;
&.old { &.old {
background-color: unset; background-color: unset;
@ -921,8 +922,6 @@ a.mention-group {
} }
p { p {
display: flex;
align-items: center;
margin: 0; margin: 0;
} }

View File

@ -488,7 +488,7 @@ class PostsController < ApplicationController
if params[:notice].present? if params[:notice].present?
post.custom_fields["notice_type"] = Post.notices[:custom] post.custom_fields["notice_type"] = Post.notices[:custom]
post.custom_fields["notice_args"] = params[:notice] post.custom_fields["notice_args"] = PrettyText.cook(params[:notice], features: { onebox: false })
post.save_custom_fields post.save_custom_fields
else else
post.delete_post_notices post.delete_post_notices

View File

@ -152,6 +152,7 @@ module PrettyText
#{"__optInput.disableEmojis = true" if opts[:disable_emojis]} #{"__optInput.disableEmojis = true" if opts[:disable_emojis]}
__paths = #{paths_json}; __paths = #{paths_json};
__optInput.getURL = __getURL; __optInput.getURL = __getURL;
#{"__optInput.features = #{opts[:features].to_json};" if opts[:features]}
__optInput.getCurrentUser = __getCurrentUser; __optInput.getCurrentUser = __getCurrentUser;
__optInput.lookupAvatar = __lookupAvatar; __optInput.lookupAvatar = __lookupAvatar;
__optInput.lookupPrimaryUserGroup = __lookupPrimaryUserGroup; __optInput.lookupPrimaryUserGroup = __lookupPrimaryUserGroup;

View File

@ -1789,4 +1789,27 @@ describe PostsController do
expect(public_post).not_to be_locked expect(public_post).not_to be_locked
end end
end end
describe "#notice" do
before do
sign_in(moderator)
end
it 'can create and remove notices' do
put "/posts/#{public_post.id}/notice.json", params: { notice: "Hello *world*!\n\nhttps://github.com/discourse/discourse" }
expect(response.status).to eq(200)
public_post.reload
expect(public_post.custom_fields['notice_type']).to eq(Post.notices[:custom])
expect(public_post.custom_fields['notice_args']).to include('<p>Hello <em>world</em>!</p>')
expect(public_post.custom_fields['notice_args']).not_to include('onebox')
put "/posts/#{public_post.id}/notice.json", params: { notice: nil }
expect(response.status).to eq(200)
public_post.reload
expect(public_post.custom_fields['notice_type']).to eq(nil)
expect(public_post.custom_fields['notice_args']).to eq(nil)
end
end
end end