### UI Changes If `SiteSetting.enable_bookmarks_with_reminders` is enabled: * Clicking "Bookmark" on a topic will create a new Bookmark record instead of a post + user action * Clicking "Clear Bookmarks" on a topic will delete all the new Bookmark records on a topic * The topic bookmark buttons control the post bookmark flags correctly and vice-versa Disabled selecting the "reminder type" for bookmarks in the UI because the backend functionality is not done yet (of sending users notifications etc.) ### Other Changes * Added delete bookmark route (but no UI yet) * Added a rake task to sync the old PostAction bookmarks to the new Bookmark table, which can be run as many times as we want for a site (it will not create duplicates).
224 lines
5.4 KiB
JavaScript
224 lines
5.4 KiB
JavaScript
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);
|
|
}
|
|
}
|
|
});
|