UX: replaces [wrap] by [event]

UX: replaces [wrap] by [event]

Syntax is now:

[event start="date"]
[/event]
diff --git a/assets/javascripts/discourse/controllers/discourse-post-event-builder.js.es6 b/assets/javascripts/discourse/controllers/discourse-post-event-builder.js.es6
index 35a70d7..53c66e9 100644
--- a/assets/javascripts/discourse/controllers/discourse-post-event-builder.js.es6
+++ b/assets/javascripts/discourse/controllers/discourse-post-event-builder.js.es6
@@ -102,9 +102,7 @@ export default Controller.extend(ModalFunctionality, {
       markdownParams.push(`${key}="${value}"`);
     });
 
-    this.toolbarEvent.addText(
-      `[wrap=event ${markdownParams.join(" ")}]\n[/wrap]`
-    );
+    this.toolbarEvent.addText(`[event ${markdownParams.join(" ")}]\n[/event]`);
     this.send("closeModal");
   },
 
@@ -171,16 +169,12 @@ export default Controller.extend(ModalFunctionality, {
   },
 
   _removeRawEvent(raw) {
-    const eventRegex = new RegExp(
-      `\\[wrap=event\\s(.*?)\\]\\n\\[\\/wrap\\]`,
-      "m"
-    );
-
+    const eventRegex = new RegExp(`\\[event\\s(.*?)\\]\\n\\[\\/event\\]`, "m");
     return raw.replace(eventRegex, "");
   },
 
   _replaceRawEvent(eventparams, raw) {
-    const eventRegex = new RegExp(`\\[wrap=event\\s(.*?)\\]`, "m");
+    const eventRegex = new RegExp(`\\[event\\s(.*?)\\]`, "m");
     const eventMatches = raw.match(eventRegex);
 
     if (eventMatches && eventMatches[1]) {
@@ -193,10 +187,7 @@ export default Controller.extend(ModalFunctionality, {
         }
       });
 
-      return raw.replace(
-        eventRegex,
-        `[wrap=event ${markdownParams.join(" ")}]`
-      );
+      return raw.replace(eventRegex, `[event ${markdownParams.join(" ")}]`);
     }
 
     return false;
diff --git a/assets/javascripts/discourse/widgets/discourse-post-event.js.es6 b/assets/javascripts/discourse/widgets/discourse-post-event.js.es6
index 6cf0745..7e2ee9b 100644
--- a/assets/javascripts/discourse/widgets/discourse-post-event.js.es6
+++ b/assets/javascripts/discourse/widgets/discourse-post-event.js.es6
@@ -8,14 +8,10 @@ import { createWidget } from "discourse/widgets/widget";
 import { routeAction } from "discourse/helpers/route-action";
 
 export default createWidget("discourse-post-event", {
-  tagName: "div.discourse-post-event",
+  tagName: "div.discourse-post-event-widget",
 
   buildKey: attrs => `discourse-post-event-${attrs.id}`,
 
-  buildAttributes(attrs) {
-    return { style: `height:${attrs.widgetHeight}px` };
-  },
-
   buildClasses() {
     if (this.state.event) {
       return ["has-discourse-post-event"];
diff --git a/assets/javascripts/initializers/discourse-post-event-decorator.js.es6 b/assets/javascripts/initializers/discourse-post-event-decorator.js.es6
index c8d3af6..e19d04a 100644
--- a/assets/javascripts/initializers/discourse-post-event-decorator.js.es6
+++ b/assets/javascripts/initializers/discourse-post-event-decorator.js.es6
@@ -17,10 +17,11 @@ function cleanUp() {
 }
 
 function _attachWidget(api, cooked, eventModel) {
-  const existing = cooked.querySelector(".discourse-post-event");
-  const wrap = cooked.querySelector("[data-wrap=event]");
+  const eventContainer = cooked.querySelector(".discourse-post-event");
+
+  if (eventModel && eventContainer) {
+    eventContainer.innerHTML = "";
 
-  if (eventModel && wrap) {
     let widgetHeight = 165;
 
     if (eventModel.should_display_invitees) {
@@ -31,12 +32,12 @@ function _attachWidget(api, cooked, eventModel) {
       widgetHeight += 60;
     }
 
-    const eventContainer = existing || document.createElement("div");
-    eventContainer.classList.add("discourse-post-event");
     eventContainer.classList.add("is-loading");
     eventContainer.style.height = `${widgetHeight}px`;
-    eventContainer.innerHTML = '<div class="spinner medium"></div>';
-    wrap.prepend(eventContainer);
+
+    const glueContainer = document.createElement("div");
+    glueContainer.innerHTML = '<div class="spinner medium"></div>';
+    eventContainer.appendChild(glueContainer);
 
     const dates = [];
     const startsAt = moment(eventModel.starts_at);
@@ -63,38 +64,48 @@ function _attachWidget(api, cooked, eventModel) {
     }
 
     cookAsync(dates.join(" → ")).then(result => {
+      eventContainer.classList.remove("is-loading");
+      eventContainer.classList.add("is-loaded");
+
       const glue = new WidgetGlue("discourse-post-event", getRegister(api), {
         eventModel,
         widgetHeight,
         localDates: $(result.string).html()
       });
 
-      glue.appendTo(eventContainer);
+      glue.appendTo(glueContainer);
       _glued.push(glue);
 
-      schedule("afterRender", () => {
+      schedule("afterRender", () =>
         $(
           ".discourse-local-date",
           $(`[data-post-id="${eventModel.id}"]`)
-        ).applyLocalDates();
-      });
+        ).applyLocalDates()
+      );
     });
-  } else {
-    existing && existing.remove();
+  } else if (!eventModel) {
+    const loadedEventContainer = cooked.querySelector(".discourse-post-event");
+    loadedEventContainer && loadedEventContainer.remove();
   }
 }
 
 function initializeDiscoursePostEventDecorator(api) {
   api.cleanupStream(cleanUp);
 
-  api.decorateCooked(($cooked, helper) => {
-    if (helper) {
-      const post = helper.getModel();
-      if (post.event) {
-        _decorateEvent(api, $cooked[0], post.event);
+  api.decorateCooked(
+    ($cooked, helper) => {
+      if (helper) {
+        const post = helper.getModel();
+        if (post.event) {
+          _decorateEvent(api, $cooked[0], post.event);
+        }
       }
+    },
+    {
+      onlyStream: true,
+      id: "discourse-post-event-decorator"
     }
-  });
+  );
 
   api.replaceIcon(
     "notification.discourse_calendar.invite_user_notification",
@@ -104,6 +115,7 @@ function initializeDiscoursePostEventDecorator(api) {
   api.modifyClass("controller:topic", {
     subscribe() {
       this._super(...arguments);
+
       this.messageBus.subscribe(
         "/discourse-post-event/" + this.get("model.id"),
         msg => {
diff --git a/assets/javascripts/lib/discourse-markdown/discourse-post-event-block.js.es6 b/assets/javascripts/lib/discourse-markdown/discourse-post-event-block.js.es6
new file mode 100644
index 0000000..ac0a2af
--- /dev/null
+++ b/assets/javascripts/lib/discourse-markdown/discourse-post-event-block.js.es6
@@ -0,0 +1,46 @@
+const rule = {
+  tag: "event",
+
+  wrap(token, info) {
+    if (!info.attrs.start) {
+      return false;
+    }
+
+    token.attrs = [
+      ["class", "discourse-post-event"],
+      ["data-start", info.attrs.start]
+    ];
+
+    if (info.attrs["status"]) {
+      token.attrs.push(["data-status", info.attrs.status]);
+    }
+
+    if (info.attrs["end"]) {
+      token.attrs.push(["data-end", info.attrs.end]);
+    }
+
+    if (info.attrs.name) {
+      token.attrs.push(["data-name", info.attrs.name]);
+    }
+
+    if (info.attrs.allowedGroups) {
+      token.attrs.push(["data-allowed-groups", info.attrs.allowedGroups]);
+    }
+
+    return true;
+  }
+};
+
+export function setup(helper) {
+  helper.whiteList(["div.discourse-post-event"]);
+
+  helper.registerOptions((opts, siteSettings) => {
+    opts.features.discourse_post_event =
+      siteSettings.calendar_enabled &&
+      siteSettings.discourse_post_event_enabled;
+  });
+
+  helper.registerPlugin(md =>
+    md.block.bbcode.ruler.push("discourse-post-event", rule)
+  );
+}
diff --git a/assets/stylesheets/common/discourse-post-event.scss b/assets/stylesheets/common/discourse-post-event.scss
index 582b6b7..301a3dd 100644
--- a/assets/stylesheets/common/discourse-post-event.scss
+++ b/assets/stylesheets/common/discourse-post-event.scss
@@ -1,9 +1,14 @@
 .discourse-post-event {
-  border: 1px solid $primary-low;
   display: flex;
-  flex-direction: column;
-  background: $secondary;
-  margin: 0.5em 0;
+
+  .discourse-post-event-widget {
+    border: 1px solid $primary-low;
+    display: flex;
+    background: $secondary;
+    margin: 0.5em 0;
+    flex-direction: column;
+    flex: 1 0 auto;
+  }
 

[... diff too long, it was truncated ...]

GitHub sha: 0cf857af