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

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

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 d5c40b9..13c3927 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 258e061..04bd6e1 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: `<div>${attrs.noticeMessage}</div>` });
     } 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 0d86f03..f0004e3 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 5f469c7..03221e6 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 44f535b..8b9de1c 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 61880b4..a84048d 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('<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

GitHub sha: 9f5cfa19

1 Like