import Controller from "@ember/controller"; import ModalFunctionality from "discourse/mixins/modal-functionality"; import discourseComputed from "discourse-common/utils/decorators"; import { popupAjaxError } from "discourse/lib/ajax-error"; import { htmlSafe } from "@ember/template"; import { ajax } from "discourse/lib/ajax"; import { reads } from "@ember/object/computed"; const START_OF_DAY_HOUR = 8; const REMINDER_TYPES = { AT_DESKTOP: "at_desktop", LATER_TODAY: "later_today", NEXT_BUSINESS_DAY: "next_business_day", TOMORROW: "tomorrow", NEXT_WEEK: "next_week", NEXT_MONTH: "next_month", CUSTOM: "custom" }; export default Controller.extend(ModalFunctionality, { loading: false, errorMessage: null, name: null, selectedReminderType: null, closeWithoutSaving: false, isSavingBookmarkManually: false, onCloseWithoutSaving: null, onShow() { this.setProperties({ errorMessage: null, name: null, selectedReminderType: null, closeWithoutSaving: false, isSavingBookmarkManually: false }); }, // we always want to save the bookmark unless the user specifically // clicks the save or cancel button to mimic browser behaviour onClose() { if (!this.closeWithoutSaving && !this.isSavingBookmarkManually) { this.saveBookmark(); } if (this.onCloseWithoutSaving && this.closeWithoutSaving) { this.onCloseWithoutSaving(); } }, usingMobileDevice: reads("site.mobileView"), showBookmarkReminderControls: false, @discourseComputed() reminderTypes: () => { return REMINDER_TYPES; }, @discourseComputed() showLaterToday() { return !this.laterToday().isSame(this.tomorrow(), "date"); }, @discourseComputed() laterTodayFormatted() { return htmlSafe( I18n.t("bookmarks.reminders.later_today", { date: this.laterToday().format(I18n.t("dates.time")) }) ); }, @discourseComputed() tomorrowFormatted() { return htmlSafe( I18n.t("bookmarks.reminders.tomorrow", { date: this.tomorrow().format(I18n.t("dates.time_short_day")) }) ); }, @discourseComputed() nextBusinessDayFormatted() { return htmlSafe( I18n.t("bookmarks.reminders.next_business_day", { date: this.nextBusinessDay().format(I18n.t("dates.time_short_day")) }) ); }, @discourseComputed() nextWeekFormatted() { return htmlSafe( I18n.t("bookmarks.reminders.next_week", { date: this.nextWeek().format(I18n.t("dates.long_no_year")) }) ); }, @discourseComputed() nextMonthFormatted() { return htmlSafe( I18n.t("bookmarks.reminders.next_month", { date: this.nextMonth().format(I18n.t("dates.long_no_year")) }) ); }, @discourseComputed() userHasTimezoneSet() { return !_.isEmpty(this.userTimezone()); }, saveBookmark() { const reminderAt = this.reminderAt(); const reminderAtISO = reminderAt ? reminderAt.toISOString() : null; const data = { reminder_type: this.selectedReminderType, reminder_at: reminderAtISO, name: this.name, post_id: this.model.postId }; return ajax("/bookmarks", { type: "POST", data }).then(() => { if (this.afterSave) { this.afterSave(reminderAtISO); } }); }, reminderAt() { if (!this.selectedReminderType) { return; } switch (this.selectedReminderType) { case REMINDER_TYPES.AT_DESKTOP: // TODO: Implement at desktop bookmark reminder functionality return ""; case REMINDER_TYPES.LATER_TODAY: return this.laterToday(); case REMINDER_TYPES.NEXT_BUSINESS_DAY: return this.nextBusinessDay(); case REMINDER_TYPES.TOMORROW: return this.tomorrow(); case REMINDER_TYPES.NEXT_WEEK: return this.nextWeek(); case REMINDER_TYPES.NEXT_MONTH: return this.nextMonth(); case REMINDER_TYPES.CUSTOM: // TODO: Implement custom bookmark reminder times return ""; } }, nextWeek() { return this.startOfDay(this.now().add(7, "days")); }, nextMonth() { return this.startOfDay(this.now().add(1, "month")); }, nextBusinessDay() { const currentDay = this.now().isoWeekday(); // 1=Mon, 7=Sun let next = null; // friday if (currentDay === 5) { next = this.now().add(3, "days"); // saturday } else if (currentDay === 6) { next = this.now().add(2, "days"); } else { next = this.now().add(1, "day"); } return this.startOfDay(next); }, tomorrow() { return this.startOfDay(this.now().add(1, "day")); }, startOfDay(momentDate) { return momentDate.hour(START_OF_DAY_HOUR).startOf("hour"); }, userTimezone() { return this.currentUser.timezone; }, now() { return moment.tz(this.userTimezone()); }, laterToday() { let later = this.now().add(3, "hours"); return later.minutes() < 30 ? later.minutes(30) : later.add(30, "minutes").startOf("hour"); }, actions: { saveAndClose() { this.isSavingBookmarkManually = true; this.saveBookmark() .then(() => this.send("closeModal")) .catch(e => { this.isSavingBookmarkManually = false; popupAjaxError(e); }); }, closeWithoutSavingBookmark() { this.closeWithoutSaving = true; this.send("closeModal"); }, selectReminderType(type) { this.set("selectedReminderType", type); } } });