DEV: Update remaining mixins to remove object-literal decorators (#29444)

These are unsupported by modern tooling (including ts/glint parsers), so we are working to remove them. The easiest path for mixins is to switch back to the mega-legacy EmberObject syntax for computed/on)
This commit is contained in:
David Taylor 2024-10-28 19:38:52 +00:00 committed by GitHub
parent 2aed7606a7
commit 9230d4e7f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 114 additions and 184 deletions

View File

@ -1,59 +0,0 @@
// Deprecated in favor of app/assets/javascripts/discourse/app/services/docking.js
import Mixin from "@ember/object/mixin";
import { cancel } from "@ember/runloop";
import discourseDebounce from "discourse-common/lib/debounce";
import discourseLater from "discourse-common/lib/later";
import { bind } from "discourse-common/utils/decorators";
const INITIAL_DELAY_MS = 50;
const DEBOUNCE_MS = 5;
export default Mixin.create({
_initialTimer: null,
_queuedTimer: null,
didInsertElement() {
this._super(...arguments);
window.addEventListener("scroll", this.queueDockCheck, { passive: true });
document.addEventListener("touchmove", this.queueDockCheck, {
passive: true,
});
// dockCheck might happen too early on full page refresh
this._initialTimer = discourseLater(
this,
this.safeDockCheck,
INITIAL_DELAY_MS
);
},
willDestroyElement() {
this._super(...arguments);
if (this._queuedTimer) {
cancel(this._queuedTimer);
}
cancel(this._initialTimer);
window.removeEventListener("scroll", this.queueDockCheck);
document.removeEventListener("touchmove", this.queueDockCheck);
},
@bind
queueDockCheck() {
this._queuedTimer = discourseDebounce(
this,
this.safeDockCheck,
DEBOUNCE_MS
);
},
@bind
safeDockCheck() {
if (this.isDestroyed || this.isDestroying) {
return;
}
this.dockCheck();
},
});

View File

@ -1,7 +1,7 @@
import { on } from "@ember/object/evented";
import Mixin from "@ember/object/mixin";
import Eyeline from "discourse/lib/eyeline";
import Scrolling from "discourse/mixins/scrolling";
import { on } from "discourse-common/utils/decorators";
// Provides the ability to load more items for a view which is scrolled to the bottom.
export default Mixin.create(Scrolling, {
@ -9,8 +9,7 @@ export default Mixin.create(Scrolling, {
return this.eyeline?.update();
},
@on("didInsertElement")
_bindEyeline() {
_bindEyeline: on("didInsertElement", function () {
const eyeline = Eyeline.create({
selector: `${this.eyelineSelector}:last`,
});
@ -20,10 +19,9 @@ export default Mixin.create(Scrolling, {
eyeline.update(); // update once to consider current position
this.bindScrolling();
},
}),
@on("willDestroyElement")
_removeEyeline() {
_removeEyeline: on("willDestroyElement", function () {
this.unbindScrolling();
},
}),
});

View File

@ -1,12 +1,10 @@
import EmberObject from "@ember/object";
import EmberObject, { computed } from "@ember/object";
import Mixin from "@ember/object/mixin";
import { isEmpty } from "@ember/utils";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default Mixin.create({
@discourseComputed()
nameTitle() {
get nameTitle() {
return I18n.t(
this.siteSettings.full_name_required
? "user.name.title"
@ -15,8 +13,8 @@ export default Mixin.create({
},
// Validate the name.
@discourseComputed("accountName", "forceValidationReason")
nameValidation(accountName, forceValidationReason) {
nameValidation: computed("accountName", "forceValidationReason", function () {
const { accountName, forceValidationReason } = this;
if (this.siteSettings.full_name_required && isEmpty(accountName)) {
return EmberObject.create({
failed: true,
@ -28,5 +26,5 @@ export default Mixin.create({
}
return EmberObject.create({ ok: true });
},
}),
});

View File

@ -1,7 +1,6 @@
import EmberObject from "@ember/object";
import EmberObject, { computed } from "@ember/object";
import Mixin from "@ember/object/mixin";
import { isEmpty } from "@ember/utils";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default Mixin.create({
@ -13,101 +12,98 @@ export default Mixin.create({
this.set("rejectedPasswordsMessages", new Map());
},
@discourseComputed("passwordMinLength")
passwordInstructions() {
passwordInstructions: computed("passwordMinLength", function () {
return I18n.t("user.password.instructions", {
count: this.passwordMinLength,
});
},
}),
@discourseComputed("isDeveloper", "admin")
passwordMinLength(isDeveloper, admin) {
passwordMinLength: computed("isDeveloper", "admin", function () {
const { isDeveloper, admin } = this;
return isDeveloper || admin
? this.siteSettings.min_admin_password_length
: this.siteSettings.min_password_length;
},
}),
@discourseComputed(
passwordValidation: computed(
"accountPassword",
"passwordRequired",
"rejectedPasswords.[]",
"accountUsername",
"accountEmail",
"passwordMinLength",
"forceValidationReason"
)
passwordValidation(
password,
passwordRequired,
rejectedPasswords,
accountUsername,
accountEmail,
passwordMinLength,
forceValidationReason
) {
const failedAttrs = {
failed: true,
ok: false,
element: document.querySelector("#new-account-password"),
};
"forceValidationReason",
function () {
const failedAttrs = {
failed: true,
ok: false,
element: document.querySelector("#new-account-password"),
};
if (!passwordRequired) {
return EmberObject.create({ ok: true });
if (!this.passwordRequired) {
return EmberObject.create({ ok: true });
}
if (this.rejectedPasswords.includes(this.accountPassword)) {
return EmberObject.create(
Object.assign(failedAttrs, {
reason:
this.rejectedPasswordsMessages.get(this.accountPassword) ||
I18n.t("user.password.common"),
})
);
}
// If blank, fail without a reason
if (isEmpty(this.accountPassword)) {
return EmberObject.create(
Object.assign(failedAttrs, {
message: I18n.t("user.password.required"),
reason: this.forceValidationReason
? I18n.t("user.password.required")
: null,
})
);
}
// If too short
if (this.accountPassword.length < this.passwordMinLength) {
return EmberObject.create(
Object.assign(failedAttrs, {
reason: I18n.t("user.password.too_short", {
count: this.passwordMinLength,
}),
})
);
}
if (
!isEmpty(this.accountUsername) &&
this.accountPassword === this.accountUsername
) {
return EmberObject.create(
Object.assign(failedAttrs, {
reason: I18n.t("user.password.same_as_username"),
})
);
}
if (
!isEmpty(this.accountEmail) &&
this.accountPassword === this.accountEmail
) {
return EmberObject.create(
Object.assign(failedAttrs, {
reason: I18n.t("user.password.same_as_email"),
})
);
}
// Looks good!
return EmberObject.create({
ok: true,
reason: I18n.t("user.password.ok"),
});
}
if (rejectedPasswords.includes(password)) {
return EmberObject.create(
Object.assign(failedAttrs, {
reason:
this.rejectedPasswordsMessages.get(password) ||
I18n.t("user.password.common"),
})
);
}
// If blank, fail without a reason
if (isEmpty(password)) {
return EmberObject.create(
Object.assign(failedAttrs, {
message: I18n.t("user.password.required"),
reason: forceValidationReason
? I18n.t("user.password.required")
: null,
})
);
}
// If too short
if (password.length < passwordMinLength) {
return EmberObject.create(
Object.assign(failedAttrs, {
reason: I18n.t("user.password.too_short", {
count: passwordMinLength,
}),
})
);
}
if (!isEmpty(accountUsername) && password === accountUsername) {
return EmberObject.create(
Object.assign(failedAttrs, {
reason: I18n.t("user.password.same_as_username"),
})
);
}
if (!isEmpty(accountEmail) && password === accountEmail) {
return EmberObject.create(
Object.assign(failedAttrs, {
reason: I18n.t("user.password.same_as_email"),
})
);
}
// Looks good!
return EmberObject.create({
ok: true,
reason: I18n.t("user.password.ok"),
});
},
),
});

View File

@ -1,7 +1,7 @@
import EmberObject from "@ember/object";
import EmberObject, { computed } from "@ember/object";
import { on } from "@ember/object/evented";
import Mixin from "@ember/object/mixin";
import { isEmpty } from "@ember/utils";
import discourseComputed, { on } from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
const addCustomUserFieldValidationCallbacks = [];
@ -10,8 +10,7 @@ export function addCustomUserFieldValidationCallback(callback) {
}
export default Mixin.create({
@on("init")
_createUserFields() {
_createUserFields: on("init", function () {
if (!this.site) {
return;
}
@ -23,10 +22,9 @@ export default Mixin.create({
.map((f) => EmberObject.create({ value: null, field: f }));
}
this.set("userFields", userFields);
},
}),
@discourseComputed("userFields.@each.value")
userFieldsValidation() {
userFieldsValidation: computed("userFields.@each.value", function () {
if (!this.userFields) {
return EmberObject.create({ ok: true });
}
@ -76,5 +74,5 @@ export default Mixin.create({
}
return EmberObject.create({ ok: true });
},
}),
});

View File

@ -1,10 +1,9 @@
import EmberObject from "@ember/object";
import EmberObject, { computed } from "@ember/object";
import Mixin from "@ember/object/mixin";
import { isEmpty } from "@ember/utils";
import { setting } from "discourse/lib/computed";
import User from "discourse/models/user";
import discourseDebounce from "discourse-common/lib/debounce";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
function failedResult(attrs) {
@ -43,27 +42,27 @@ export default Mixin.create({
}
},
@discourseComputed(
usernameValidation: computed(
"usernameValidationResult",
"accountUsername",
"forceValidationReason"
)
usernameValidation() {
if (
this.usernameValidationResult &&
this.checkedUsername === this.accountUsername
) {
return this.usernameValidationResult;
"forceValidationReason",
function () {
if (
this.usernameValidationResult &&
this.checkedUsername === this.accountUsername
) {
return this.usernameValidationResult;
}
const result = this.basicUsernameValidation(this.accountUsername);
if (result.shouldCheck) {
discourseDebounce(this, this.checkUsernameAvailability, 500);
}
return result;
}
const result = this.basicUsernameValidation(this.accountUsername);
if (result.shouldCheck) {
discourseDebounce(this, this.checkUsernameAvailability, 500);
}
return result;
},
),
basicUsernameValidation(username) {
if (username && username === this.prefilledUsername) {