DEV: Update DiscourseRoute and ApplicationRoute to native class syntax (#28594)

Changes made using the ember-native-class-codemod, plus some manual tweaks

Also ensures our implicit injections applied to the prototype immediately. Without this, they will only be applied on the next `.extend()` call, which is now later than the first native-class extension.
This commit is contained in:
David Taylor 2024-08-28 13:05:06 +01:00 committed by GitHub
parent b092ccbdc5
commit 2bc30bd7b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 213 additions and 199 deletions

View File

@ -46,6 +46,7 @@ function setInjections(target, injections) {
extension[key] = implicitInjectionShim(lookupName, key);
}
EmberObject.reopen.call(target, extension);
target.proto();
}
let alreadyRegistered = false;

View File

@ -21,44 +21,38 @@ import getURL from "discourse-common/lib/get-url";
import I18n from "discourse-i18n";
import NotActivatedModal from "../components/modal/not-activated";
function unlessStrictlyReadOnly(method, message) {
return function () {
if (this.site.isReadOnly && !this.site.isStaffWritesOnly) {
this.dialog.alert(message);
} else {
this[method]();
}
};
function isStrictlyReadonly(site) {
return site.isReadOnly && !site.isStaffWritesOnly;
}
const ApplicationRoute = DiscourseRoute.extend({
siteTitle: setting("title"),
shortSiteDescription: setting("short_site_description"),
export default class ApplicationRoute extends DiscourseRoute {
@service clientErrorHandler;
@service composer;
@service currentUser;
@service dialog;
@service documentTitle;
@service historyStore;
@service loadingSlider;
@service login;
@service modal;
@service router;
@service site;
@service siteSettings;
@service restrictedRouting;
clientErrorHandler: service(),
composer: service(),
currentUser: service(),
dialog: service(),
documentTitle: service(),
historyStore: service(),
loadingSlider: service(),
login: service(),
modal: service(),
router: service(),
site: service(),
siteSettings: service(),
restrictedRouting: service(),
@setting("title") siteTitle;
@setting("short_site_description") shortSiteDescription;
get isOnlyOneExternalLoginMethod() {
return (
!this.siteSettings.enable_local_logins &&
this.externalLoginMethods.length === 1
);
},
}
get externalLoginMethods() {
return findAll();
},
}
@action
loading(transition) {
@ -67,7 +61,7 @@ const ApplicationRoute = DiscourseRoute.extend({
this.loadingSlider.transitionEnded();
});
return false;
},
}
@action
willTransition(transition) {
@ -85,28 +79,34 @@ const ApplicationRoute = DiscourseRoute.extend({
}
return true;
},
}
@action
willResolveModel(transition) {
this.historyStore.willResolveModel(transition);
return true;
},
}
actions: {
@action
toggleMobileView() {
mobile.toggleMobileView();
},
}
@action
toggleSidebar() {
this.controllerFor("application").send("toggleSidebar");
},
}
logout: unlessStrictlyReadOnly(
"_handleLogout",
I18n.t("read_only_mode.logout_disabled")
),
@action
logout() {
if (isStrictlyReadonly(this.site)) {
this.dialog.alert(I18n.t("read_only_mode.logout_disabled"));
return;
}
this._handleLogout();
}
@action
_collectTitleTokens(tokens) {
tokens.push(this.siteTitle);
if (
@ -117,8 +117,9 @@ const ApplicationRoute = DiscourseRoute.extend({
tokens.push(this.shortSiteDescription);
}
this.documentTitle.setTitle(tokens.join(" - "));
},
}
@action
composePrivateMessage(user, post) {
const recipients = user ? user.get("username") : "";
const reply = post
@ -140,8 +141,9 @@ const ApplicationRoute = DiscourseRoute.extend({
reply,
title,
});
},
}
@action
error(err, transition) {
const xhrOrErr = err.jqXHR ? err.jqXHR : err;
const exceptionController = this.controllerFor("exception");
@ -183,63 +185,78 @@ const ApplicationRoute = DiscourseRoute.extend({
this.intermediateTransitionTo("exception");
return shouldBubble;
},
}
showLogin: unlessStrictlyReadOnly(
"handleShowLogin",
I18n.t("read_only_mode.login_disabled")
),
@action
showLogin() {
if (isStrictlyReadonly(this.site)) {
this.dialog.alert(I18n.t("read_only_mode.login_disabled"));
return;
}
this.handleShowLogin();
}
@action
showCreateAccount(createAccountProps = {}) {
if (this.site.isReadOnly) {
this.dialog.alert(I18n.t("read_only_mode.login_disabled"));
} else {
this.handleShowCreateAccount(createAccountProps);
}
},
}
@action
showForgotPassword() {
this.modal.show(ForgotPassword);
},
}
@action
showNotActivated(props) {
this.modal.show(NotActivatedModal, { model: props });
},
}
@action
showUploadSelector() {
document.getElementById("file-uploader").click();
},
}
@action
showKeyboardShortcutsHelp() {
this.modal.show(KeyboardShortcutsHelp);
},
}
// Close the current modal, and destroy its state.
@action
closeModal(initiatedBy) {
return this.modal.close(initiatedBy);
},
}
/**
Hide the modal, but keep it with all its state so that it can be shown again later.
This is useful if you want to prompt for confirmation. hideModal, ask "Are you sure?",
user clicks "No", reopenModal. If user clicks "Yes", be sure to call closeModal.
**/
@action
hideModal() {
return this.modal.hide();
},
}
@action
reopenModal() {
return this.modal.reopen();
},
}
@action
editCategory(category) {
DiscourseURL.routeTo(`/c/${Category.slugFor(category)}/edit`);
},
}
@action
checkEmail(user) {
user.checkEmail();
},
}
@action
createNewTopicViaParams(title, body, categoryId, tags) {
deprecated(
"createNewTopicViaParam on the application route is deprecated. Use the composer service instead",
@ -251,8 +268,9 @@ const ApplicationRoute = DiscourseRoute.extend({
categoryId,
tags,
});
},
}
@action
createNewMessageViaParams({
recipients = "",
topicTitle = "",
@ -269,8 +287,7 @@ const ApplicationRoute = DiscourseRoute.extend({
body: topicBody,
hasGroups,
});
},
},
}
handleShowLogin() {
if (this.siteSettings.enable_discourse_connect) {
@ -291,7 +308,7 @@ const ApplicationRoute = DiscourseRoute.extend({
});
}
}
},
}
handleShowCreateAccount(createAccountProps) {
if (this.siteSettings.enable_discourse_connect) {
@ -307,7 +324,7 @@ const ApplicationRoute = DiscourseRoute.extend({
this.modal.show(CreateAccount, { model: createAccountProps });
}
}
},
}
_handleLogout() {
if (this.currentUser) {
@ -315,7 +332,5 @@ const ApplicationRoute = DiscourseRoute.extend({
.destroySession()
.then((response) => logout({ redirect: response["redirect_url"] }));
}
},
});
export default ApplicationRoute;
}
}

View File

@ -6,16 +6,16 @@ import { seenUser } from "discourse/lib/user-presence";
import deprecated from "discourse-common/lib/deprecated";
import { getOwnerWithFallback } from "discourse-common/lib/get-owner";
const DiscourseRoute = Route.extend({
router: service(),
export default class DiscourseRoute extends Route {
@service router;
willTransition() {
seenUser();
},
}
_refreshTitleOnce() {
this.send("_collectTitleTokens", []);
},
}
@action
_collectTitleTokens(tokens) {
@ -31,19 +31,19 @@ const DiscourseRoute = Route.extend({
}
}
return true;
},
}
@action
refreshTitle() {
once(this, this._refreshTitleOnce);
},
}
redirectIfLoginRequired() {
const app = this.controllerFor("application");
if (app.get("loginRequired")) {
this.router.replaceWith("login");
}
},
}
openTopicDraft() {
deprecated(
@ -55,7 +55,7 @@ const DiscourseRoute = Route.extend({
.lookup("service:composer")
.openNewTopic({ preferDraft: true });
}
},
}
isCurrentUser(user) {
if (!this.currentUser) {
@ -63,7 +63,5 @@ const DiscourseRoute = Route.extend({
}
return user.id === this.currentUser.id;
},
});
export default DiscourseRoute;
}
}