diff --git a/app/assets/javascripts/discourse/controllers/add-post-notice.js.es6 b/app/assets/javascripts/discourse/controllers/add-post-notice.js.es6 index d5c40b9a049..13c3927d4af 100644 --- a/app/assets/javascripts/discourse/controllers/add-post-notice.js.es6 +++ b/app/assets/javascripts/discourse/controllers/add-post-notice.js.es6 @@ -1,5 +1,6 @@ import ModalFunctionality from "discourse/mixins/modal-functionality"; import computed from "ember-addons/ember-computed-decorators"; +import { cookAsync } from "discourse/lib/text"; export default Ember.Controller.extend(ModalFunctionality, { post: null, @@ -42,10 +43,11 @@ export default Ember.Controller.extend(ModalFunctionality, { post .updatePostField("notice", notice) - .then(() => { + .then(() => cookAsync(notice, { features: { onebox: false } })) + .then(cookedNotice => { post.setProperties({ notice_type: "custom", - notice_args: notice + notice_args: cookedNotice.string }); resolve(); this.send("closeModal"); diff --git a/app/assets/javascripts/discourse/widgets/post.js.es6 b/app/assets/javascripts/discourse/widgets/post.js.es6 index 258e061868d..04bd6e15a3c 100644 --- a/app/assets/javascripts/discourse/widgets/post.js.es6 +++ b/app/assets/javascripts/discourse/widgets/post.js.es6 @@ -1,6 +1,7 @@ import PostCooked from "discourse/widgets/post-cooked"; import DecoratorHelper from "discourse/widgets/decorator-helper"; import { createWidget, applyDecorators } from "discourse/widgets/widget"; +import RawHtml from "discourse/widgets/raw-html"; import { iconNode } from "discourse-common/lib/icon-library"; import { transformBasicPost } from "discourse/lib/transform-post"; import { postTransformCallbacks } from "discourse/widgets/post-stream"; @@ -459,20 +460,23 @@ createWidget("post-notice", { let text, icon; if (attrs.noticeType === "custom") { icon = "user-shield"; - text = attrs.noticeMessage; + text = new RawHtml({ html: `
${attrs.noticeMessage}
` }); } else if (attrs.noticeType === "new_user") { 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") { icon = "far-smile"; const distance = (new Date() - new Date(attrs.noticeTime)) / 1000; - text = I18n.t("post.notice.returning_user", { - user, - time: durationTiny(distance, { addAgo: true }) - }); + text = h( + "p", + I18n.t("post.notice.returning_user", { + user, + time: durationTiny(distance, { addAgo: true }) + }) + ); } - return h("p", [iconNode(icon), text]); + return [iconNode(icon), text]; } }); diff --git a/app/assets/stylesheets/common/base/topic-post.scss b/app/assets/stylesheets/common/base/topic-post.scss index 0d86f038fd5..f0004e3bed7 100644 --- a/app/assets/stylesheets/common/base/topic-post.scss +++ b/app/assets/stylesheets/common/base/topic-post.scss @@ -905,11 +905,12 @@ a.mention-group { } .post-notice { + align-items: center; background-color: $tertiary-low; border-top: 1px solid $primary-low; - color: $primary; - padding: 0.8em; + display: flex; max-width: calc(#{$topic-body-width} + #{$topic-avatar-width} - 0.1em); + padding: 0.8em; &.old { background-color: unset; @@ -921,8 +922,6 @@ a.mention-group { } p { - display: flex; - align-items: center; margin: 0; } diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 5f469c74504..03221e65ca1 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -488,7 +488,7 @@ class PostsController < ApplicationController if params[:notice].present? 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 else post.delete_post_notices diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index 44f535bb8b4..8b9de1c2d9c 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -152,6 +152,7 @@ module PrettyText #{"__optInput.disableEmojis = true" if opts[:disable_emojis]} __paths = #{paths_json}; __optInput.getURL = __getURL; + #{"__optInput.features = #{opts[:features].to_json};" if opts[:features]} __optInput.getCurrentUser = __getCurrentUser; __optInput.lookupAvatar = __lookupAvatar; __optInput.lookupPrimaryUserGroup = __lookupPrimaryUserGroup; diff --git a/spec/requests/posts_controller_spec.rb b/spec/requests/posts_controller_spec.rb index 61880b4254d..a84048d1b5a 100644 --- a/spec/requests/posts_controller_spec.rb +++ b/spec/requests/posts_controller_spec.rb @@ -1789,4 +1789,27 @@ describe PostsController do expect(public_post).not_to be_locked 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('

Hello world!

') + 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