248 lines
6.8 KiB
JavaScript
248 lines
6.8 KiB
JavaScript
import guessDateFormat from "discourse/plugins/discourse-calendar/lib/guess-best-date-format";
|
|
import { cookAsync } from "discourse/lib/text";
|
|
import WidgetGlue from "discourse/widgets/glue";
|
|
import { getRegister } from "discourse-common/lib/get-owner";
|
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
|
import { schedule } from "@ember/runloop";
|
|
|
|
function _decorateEvent(api, cooked, post) {
|
|
_attachWidget(api, cooked, post);
|
|
}
|
|
|
|
function _validEventPreview(eventContainer) {
|
|
eventContainer.innerHTML = "";
|
|
eventContainer.classList.add("discourse-post-event-preview");
|
|
|
|
const statusLocaleKey = `discourse_post_event.models.event.status.${eventContainer
|
|
.dataset.status || "public"}.title`;
|
|
if (I18n.lookup(statusLocaleKey, { locale: "en" })) {
|
|
const statusContainer = document.createElement("div");
|
|
statusContainer.classList.add("event-preview-status");
|
|
statusContainer.innerText = I18n.t(statusLocaleKey);
|
|
eventContainer.appendChild(statusContainer);
|
|
}
|
|
|
|
const datesContainer = document.createElement("div");
|
|
datesContainer.classList.add("event-preview-dates");
|
|
|
|
const startsAt = moment
|
|
.utc(eventContainer.dataset.start)
|
|
.tz(moment.tz.guess());
|
|
|
|
const endsAtValue = eventContainer.dataset.end;
|
|
const format = guessDateFormat(
|
|
startsAt,
|
|
endsAtValue && moment.utc(endsAtValue).tz(moment.tz.guess())
|
|
);
|
|
|
|
let datesString = `<span class='start'>${startsAt.format(format)}</span>`;
|
|
if (endsAtValue) {
|
|
datesString += ` → <span class='end'>${moment
|
|
.utc(endsAtValue)
|
|
.tz(moment.tz.guess())
|
|
.format(format)}</span>`;
|
|
}
|
|
datesContainer.innerHTML = datesString;
|
|
|
|
eventContainer.appendChild(datesContainer);
|
|
}
|
|
|
|
function _invalidEventPreview(eventContainer) {
|
|
eventContainer.classList.add(
|
|
"discourse-post-event-preview",
|
|
"alert",
|
|
"alert-error"
|
|
);
|
|
eventContainer.classList.remove("discourse-post-event");
|
|
eventContainer.innerText = I18n.t(
|
|
"discourse_post_event.preview.more_than_one_event"
|
|
);
|
|
}
|
|
|
|
function _decorateEventPreview(api, cooked) {
|
|
const eventContainers = cooked.querySelectorAll(".discourse-post-event");
|
|
|
|
eventContainers.forEach((eventContainer, index) => {
|
|
if (index > 0) {
|
|
_invalidEventPreview(eventContainer);
|
|
} else {
|
|
_validEventPreview(eventContainer);
|
|
}
|
|
});
|
|
}
|
|
|
|
let _glued = [];
|
|
|
|
function cleanUp() {
|
|
_glued.forEach(g => g.cleanUp());
|
|
_glued = [];
|
|
}
|
|
|
|
function _attachWidget(api, cooked, eventModel) {
|
|
const eventContainer = cooked.querySelector(".discourse-post-event");
|
|
|
|
if (eventModel && eventContainer) {
|
|
eventContainer.innerHTML = "";
|
|
|
|
const datesHeight = 50;
|
|
const urlHeight = 50;
|
|
const headerHeight = 75;
|
|
const bordersHeight = 10;
|
|
const separatorsHeight = 4;
|
|
const margins = 10;
|
|
let widgetHeight =
|
|
datesHeight + headerHeight + bordersHeight + separatorsHeight + margins;
|
|
|
|
if (eventModel.should_display_invitees) {
|
|
widgetHeight += 110;
|
|
}
|
|
|
|
if (eventModel.can_update_attendance) {
|
|
widgetHeight += 60;
|
|
}
|
|
|
|
if (eventModel.url) {
|
|
widgetHeight += urlHeight;
|
|
}
|
|
|
|
eventContainer.classList.add("is-loading");
|
|
eventContainer.style.height = `${widgetHeight}px`;
|
|
|
|
const glueContainer = document.createElement("div");
|
|
glueContainer.innerHTML = '<div class="spinner medium"></div>';
|
|
eventContainer.appendChild(glueContainer);
|
|
|
|
const startsAt = moment(eventModel.starts_at);
|
|
const format = guessDateFormat(
|
|
startsAt,
|
|
eventModel.ends_at && moment(eventModel.ends_at)
|
|
);
|
|
|
|
const siteSettings = api.container.lookup("site-settings:main");
|
|
if (siteSettings.discourse_local_dates_enabled) {
|
|
const dates = [];
|
|
|
|
dates.push(
|
|
`[date=${moment
|
|
.utc(eventModel.starts_at)
|
|
.format("YYYY-MM-DD")} time=${moment
|
|
.utc(eventModel.starts_at)
|
|
.format("HH:mm")} format=${format}]`
|
|
);
|
|
|
|
if (eventModel.ends_at) {
|
|
const endsAt = moment.utc(eventModel.ends_at);
|
|
dates.push(
|
|
`[date=${endsAt.format("YYYY-MM-DD")} time=${endsAt.format(
|
|
"HH:mm"
|
|
)} format=${format}]`
|
|
);
|
|
}
|
|
|
|
cookAsync(dates.join("<span> → </span>")).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(glueContainer);
|
|
_glued.push(glue);
|
|
|
|
schedule("afterRender", () =>
|
|
$(
|
|
".discourse-local-date",
|
|
$(`[data-post-id="${eventModel.id}"]`)
|
|
).applyLocalDates()
|
|
);
|
|
});
|
|
} else {
|
|
let localDates = `${startsAt.format(format)}`;
|
|
if (eventModel.ends_at) {
|
|
localDates += ` → ${moment(eventModel.ends_at).format(format)}`;
|
|
}
|
|
|
|
const glue = new WidgetGlue("discourse-post-event", getRegister(api), {
|
|
eventModel,
|
|
widgetHeight,
|
|
localDates
|
|
});
|
|
|
|
glue.appendTo(glueContainer);
|
|
_glued.push(glue);
|
|
}
|
|
} else if (!eventModel) {
|
|
const loadedEventContainer = cooked.querySelector(".discourse-post-event");
|
|
loadedEventContainer && loadedEventContainer.remove();
|
|
}
|
|
}
|
|
|
|
function initializeDiscoursePostEventDecorator(api) {
|
|
api.cleanupStream(cleanUp);
|
|
|
|
api.decorateCooked(
|
|
($cooked, helper) => {
|
|
if ($cooked[0].classList.contains("d-editor-preview")) {
|
|
_decorateEventPreview(api, $cooked[0]);
|
|
return;
|
|
}
|
|
|
|
if (helper) {
|
|
const post = helper.getModel();
|
|
|
|
if (post.event) {
|
|
_decorateEvent(api, $cooked[0], post.event);
|
|
}
|
|
}
|
|
},
|
|
{
|
|
id: "discourse-post-event-decorator"
|
|
}
|
|
);
|
|
|
|
api.replaceIcon(
|
|
"notification.discourse_calendar.invite_user_notification",
|
|
"calendar-day"
|
|
);
|
|
|
|
api.modifyClass("controller:topic", {
|
|
subscribe() {
|
|
this._super(...arguments);
|
|
|
|
this.messageBus.subscribe(
|
|
"/discourse-post-event/" + this.get("model.id"),
|
|
msg => {
|
|
const postNode = document.querySelector(
|
|
`.onscreen-post[data-post-id="${msg.id}"] .cooked`
|
|
);
|
|
|
|
if (postNode) {
|
|
this.store
|
|
.find("discourse-post-event-event", msg.id)
|
|
.then(eventModel => _decorateEvent(api, postNode, eventModel))
|
|
.catch(() => _decorateEvent(api, postNode));
|
|
}
|
|
}
|
|
);
|
|
},
|
|
unsubscribe() {
|
|
this.messageBus.unsubscribe("/discourse-post-event/*");
|
|
this._super(...arguments);
|
|
}
|
|
});
|
|
}
|
|
|
|
export default {
|
|
name: "discourse-post-event-decorator",
|
|
|
|
initialize(container) {
|
|
const siteSettings = container.lookup("site-settings:main");
|
|
if (siteSettings.discourse_post_event_enabled) {
|
|
withPluginApi("0.8.7", initializeDiscoursePostEventDecorator);
|
|
}
|
|
}
|
|
};
|