DEV: Convert core components to native class syntax (batch 9) (#28604)

Changes made using the ember-native-class-codemod, plus some manual tweaks
This commit is contained in:
David Taylor 2024-08-28 16:25:29 +01:00 committed by GitHub
parent 2e5502c417
commit 8cc6b214dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 377 additions and 331 deletions

View File

@ -1,38 +1,40 @@
import Component from "@ember/component";
import { alias } from "@ember/object/computed";
import { tagName } from "@ember-decorators/component";
import UppyUploadMixin from "discourse/mixins/uppy-upload";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default Component.extend(UppyUploadMixin, {
id: "uppy-backup-uploader",
tagName: "span",
type: "backup",
@tagName("span")
export default class UppyBackupUploader extends Component.extend(
UppyUploadMixin
) {
id = "uppy-backup-uploader";
type = "backup";
uploadRootPath = "/admin/backups";
uploadUrl = "/admin/backups/upload";
uploadRootPath: "/admin/backups",
uploadUrl: "/admin/backups/upload",
// local backups
@alias("localBackupStorage") useChunkedUploads;
// direct s3 backups
@discourseComputed("localBackupStorage")
useMultipartUploadsIfAvailable(localBackupStorage) {
return !localBackupStorage && this.siteSettings.enable_direct_s3_uploads;
},
// local backups
useChunkedUploads: alias("localBackupStorage"),
}
@discourseComputed("uploading", "uploadProgress")
uploadButtonText(uploading, progress) {
return uploading
? I18n.t("admin.backups.upload.uploading_progress", { progress })
: I18n.t("admin.backups.upload.label");
},
}
validateUploadedFilesOptions() {
return { skipValidation: true };
},
}
uploadDone(responseData) {
this.done(responseData.file_name);
},
});
}
}

View File

@ -4,6 +4,8 @@ import { or } from "@ember/object/computed";
import { next } from "@ember/runloop";
import { htmlSafe } from "@ember/template";
import { isEmpty } from "@ember/utils";
import { classNames } from "@ember-decorators/component";
import { on } from "@ember-decorators/object";
import $ from "jquery";
import lightbox, {
cleanupLightboxes,
@ -12,24 +14,26 @@ import lightbox, {
import { authorizesOneOrMoreExtensions } from "discourse/lib/uploads";
import UppyUploadMixin from "discourse/mixins/uppy-upload";
import { getURLWithCDN } from "discourse-common/lib/get-url";
import discourseComputed, { on } from "discourse-common/utils/decorators";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default Component.extend(UppyUploadMixin, {
classNames: ["image-uploader"],
disabled: or("notAllowed", "uploading", "processing"),
@classNames("image-uploader")
export default class UppyImageUploader extends Component.extend(
UppyUploadMixin
) {
@or("notAllowed", "uploading", "processing") disabled;
@discourseComputed("siteSettings.enable_experimental_lightbox")
experimentalLightboxEnabled(experimentalLightboxEnabled) {
return experimentalLightboxEnabled;
},
}
@discourseComputed("disabled", "notAllowed")
disabledReason(disabled, notAllowed) {
if (disabled && notAllowed) {
return I18n.t("post.errors.no_uploads_authorized");
}
},
}
@discourseComputed(
"currentUser.staff",
@ -40,12 +44,12 @@ export default Component.extend(UppyUploadMixin, {
this.currentUser?.staff,
this.siteSettings
);
},
}
@discourseComputed("imageUrl", "placeholderUrl")
showingPlaceholder(imageUrl, placeholderUrl) {
return !imageUrl && placeholderUrl;
},
}
@discourseComputed("placeholderUrl")
placeholderStyle(url) {
@ -53,7 +57,7 @@ export default Component.extend(UppyUploadMixin, {
return htmlSafe("");
}
return htmlSafe(`background-image: url(${url})`);
},
}
@discourseComputed("imageUrl")
imageCDNURL(url) {
@ -62,12 +66,12 @@ export default Component.extend(UppyUploadMixin, {
}
return getURLWithCDN(url);
},
}
@discourseComputed("imageCDNURL")
backgroundStyle(url) {
return htmlSafe(`background-image: url(${url})`);
},
}
@discourseComputed("imageUrl")
imageBaseName(imageUrl) {
@ -75,17 +79,17 @@ export default Component.extend(UppyUploadMixin, {
return;
}
return imageUrl.split("/").slice(-1)[0];
},
}
validateUploadedFilesOptions() {
return { imagesOnly: true };
},
}
_uppyReady() {
this._onPreProcessComplete(() => {
this.set("processing", false);
});
},
}
uploadDone(upload) {
this.setProperties({
@ -103,7 +107,7 @@ export default Component.extend(UppyUploadMixin, {
} else {
this.set("imageUrl", upload.url);
}
},
}
@on("didRender")
_applyLightbox() {
@ -115,7 +119,7 @@ export default Component.extend(UppyUploadMixin, {
} else {
next(() => lightbox(this.element, this.siteSettings));
}
},
}
@on("willDestroyElement")
_closeOnRemoval() {
@ -126,26 +130,25 @@ export default Component.extend(UppyUploadMixin, {
$.magnificPopup.instance.close();
}
}
},
}
@action
toggleLightbox() {
$(this.element.querySelector("a.lightbox"))?.magnificPopup("open");
},
}
actions: {
trash() {
// uppy needs to be reset to allow for more uploads
this._reset();
@action
trash() {
// uppy needs to be reset to allow for more uploads
this._reset();
// the value of the property used for imageUrl should be cleared
// in this callback. this should be done in cases where imageUrl
// is bound to a computed property of the parent component.
if (this.onUploadDeleted) {
this.onUploadDeleted();
} else {
this.setProperties({ imageUrl: null });
}
},
},
});
// the value of the property used for imageUrl should be cleared
// in this callback. this should be done in cases where imageUrl
// is bound to a computed property of the parent component.
if (this.onUploadDeleted) {
this.onUploadDeleted();
} else {
this.setProperties({ imageUrl: null });
}
}
}

View File

@ -1,10 +1,10 @@
import Component from "@ember/component";
import { tagName } from "@ember-decorators/component";
import autoGroupFlairForUser from "discourse/lib/avatar-flair";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({
tagName: "",
@tagName("")
export default class UserAvatarFlair extends Component {
@discourseComputed("user")
flair(user) {
if (!user || !user.flair_group_id) {
@ -29,5 +29,5 @@ export default Component.extend({
flairColor: autoFlairAttrs.flair_color,
};
}
},
});
}
}

View File

@ -143,7 +143,7 @@
{{#if this.showFilter}}
<li>
<DButton
@action={{fn (action "filterPosts") this.user}}
@action={{fn this.handleFilterPosts this.user}}
@icon="filter"
@translatedLabel={{this.filterPostsLabel}}
class="btn-default"

View File

@ -1,9 +1,15 @@
import Component from "@ember/component";
import EmberObject, { action, set } from "@ember/object";
import EmberObject, { action, computed, set } from "@ember/object";
import { alias, and, gt, gte, not, or } from "@ember/object/computed";
import { dasherize } from "@ember/string";
import { isEmpty } from "@ember/utils";
import { propertyNotEqual, setting } from "discourse/lib/computed";
import {
attributeBindings,
classNameBindings,
classNames,
} from "@ember-decorators/component";
import { observes } from "@ember-decorators/object";
import { setting } from "discourse/lib/computed";
import { durationTiny } from "discourse/lib/formatter";
import { wantsNewWindow } from "discourse/lib/intercept-click";
import { prioritizeNameInUx } from "discourse/lib/settings";
@ -14,85 +20,97 @@ import CardContentsBase from "discourse/mixins/card-contents-base";
import CleansUp from "discourse/mixins/cleans-up";
import User from "discourse/models/user";
import { getURLWithCDN } from "discourse-common/lib/get-url";
import discourseComputed, { observes } from "discourse-common/utils/decorators";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
elementId: "user-card",
classNames: "user-card",
avatarSelector: "[data-user-card]",
avatarDataAttrKey: "userCard",
mentionSelector: "a.mention",
classNameBindings: [
"visible:show",
"showBadges",
"user.card_background_upload_url::no-bg",
"isFixed:fixed",
"usernameClass",
"primaryGroup",
],
attributeBindings: ["labelledBy:aria-labelledby"],
allowBackgrounds: setting("allow_profile_backgrounds"),
showBadges: setting("enable_badges"),
@classNames("user-card")
@classNameBindings(
"visible:show",
"showBadges",
"user.card_background_upload_url::no-bg",
"isFixed:fixed",
"usernameClass",
"primaryGroup"
)
@attributeBindings("labelledBy:aria-labelledby")
export default class UserCardContents extends Component.extend(
CardContentsBase,
CanCheckEmails,
CleansUp
) {
elementId = "user-card";
avatarSelector = "[data-user-card]";
avatarDataAttrKey = "userCard";
mentionSelector = "a.mention";
postStream: alias("topic.postStream"),
enoughPostsForFiltering: gte("topicPostCount", 2),
showFilter: and(
"viewingTopic",
"postStream.hasNoFilters",
"enoughPostsForFiltering"
),
showName: propertyNotEqual("user.name", "user.username"),
hasUserFilters: gt("postStream.userFilters.length", 0),
showMoreBadges: gt("moreBadgesCount", 0),
showDelete: and("viewingAdmin", "showName", "user.canBeDeleted"),
linkWebsite: not("user.isBasic"),
@setting("allow_profile_backgrounds") allowBackgrounds;
@setting("enable_badges") showBadges;
@setting("display_local_time_in_user_card") showUserLocalTime;
@alias("topic.postStream") postStream;
@gte("topicPostCount", 2) enoughPostsForFiltering;
@and("viewingTopic", "postStream.hasNoFilters", "enoughPostsForFiltering")
showFilter;
@gt("postStream.userFilters.length", 0) hasUserFilters;
@gt("moreBadgesCount", 0) showMoreBadges;
@and("viewingAdmin", "showName", "user.canBeDeleted") showDelete;
@not("user.isBasic") linkWebsite;
@or("user.suspend_reason", "user.bio_excerpt") isSuspendedOrHasBio;
@and("user.staged", "canCheckEmails") showCheckEmail;
user = null;
// If inside a topic
topicPostCount = null;
@and(
"user.featured_topic",
"siteSettings.allow_featured_topic_on_user_profiles"
)
showFeaturedTopic;
@computed("user.name", "user.username")
get showName() {
return this.user.name !== this.user.username;
}
@discourseComputed("user")
labelledBy(user) {
return user ? "discourse-user-card-title" : null;
},
}
@discourseComputed("user")
hasLocaleOrWebsite(user) {
return user.location || user.website_name || this.userTimezone;
},
}
@discourseComputed("user.status")
hasStatus() {
return this.siteSettings.enable_user_status && this.user.status;
},
}
@discourseComputed("user.status.emoji")
userStatusEmoji(emoji) {
return emojiUnescape(escapeExpression(`:${emoji}:`));
},
isSuspendedOrHasBio: or("user.suspend_reason", "user.bio_excerpt"),
showCheckEmail: and("user.staged", "canCheckEmails"),
user: null,
// If inside a topic
topicPostCount: null,
showFeaturedTopic: and(
"user.featured_topic",
"siteSettings.allow_featured_topic_on_user_profiles"
),
showUserLocalTime: setting("display_local_time_in_user_card"),
}
@discourseComputed("user.staff")
staff: (isStaff) => (isStaff ? "staff" : ""),
staff(isStaff) {
return isStaff ? "staff" : "";
}
@discourseComputed("user.trust_level")
newUser: (trustLevel) => (trustLevel === 0 ? "new-user" : ""),
newUser(trustLevel) {
return trustLevel === 0 ? "new-user" : "";
}
@discourseComputed("user.name")
nameFirst(name) {
return prioritizeNameInUx(name);
},
}
@discourseComputed("user")
userTimezone(user) {
@ -100,20 +118,22 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
return;
}
return user.get("user_option.timezone");
},
}
@discourseComputed("userTimezone")
formattedUserLocalTime(timezone) {
return moment.tz(timezone).format(I18n.t("dates.time"));
},
}
@discourseComputed("username")
usernameClass: (username) => (username ? `user-card-${username}` : ""),
usernameClass(username) {
return username ? `user-card-${username}` : "";
}
@discourseComputed("username", "topicPostCount")
filterPostsLabel(username, count) {
return I18n.t("topic.filter_to", { username, count });
},
}
@discourseComputed("user.user_fields.@each.value")
publicUserFields() {
@ -130,25 +150,27 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
})
.compact();
}
},
}
@discourseComputed("user.trust_level")
removeNoFollow(trustLevel) {
return trustLevel > 2 && !this.siteSettings.tl3_links_no_follow;
},
}
@discourseComputed("user.badge_count", "user.featured_user_badges.length")
moreBadgesCount: (badgeCount, badgeLength) => badgeCount - badgeLength,
moreBadgesCount(badgeCount, badgeLength) {
return badgeCount - badgeLength;
}
@discourseComputed("user.time_read", "user.recent_time_read")
showRecentTimeRead(timeRead, recentTimeRead) {
return timeRead !== recentTimeRead && recentTimeRead !== 0;
},
}
@discourseComputed("user.recent_time_read")
recentTimeRead(recentTimeReadSeconds) {
return durationTiny(recentTimeReadSeconds);
},
}
@discourseComputed("showRecentTimeRead", "user.time_read", "recentTimeRead")
timeReadTooltip(showRecent, timeRead, recentTimeRead) {
@ -162,7 +184,7 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
time_read: durationTiny(timeRead),
});
}
},
}
@observes("user.card_background_upload_url")
addBackground() {
@ -177,17 +199,17 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
const url = this.get("user.card_background_upload_url");
const bg = isEmpty(url) ? "" : `url(${getURLWithCDN(url)})`;
this.element.style.backgroundImage = bg;
},
}
@discourseComputed("user.primary_group_name")
primaryGroup(primaryGroup) {
return `group-${primaryGroup}`;
},
}
@discourseComputed("user.profile_hidden", "user.inactive")
contentHidden(profileHidden, inactive) {
return profileHidden || inactive;
},
}
async _showCallback(username) {
this.setProperties({ visible: true, loading: true });
@ -215,7 +237,7 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
} finally {
this.set("loading", null);
}
},
}
_close() {
this.user?.statusManager.stopTrackingStatus();
@ -225,12 +247,12 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
topicPostCount: null,
});
this._super(...arguments);
},
super._close(...arguments);
}
cleanUp() {
this._close();
},
}
@action
handleShowUser(event) {
@ -243,36 +265,40 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
// refactoring this to a glimmer component.
this.showUser(this.user);
this._close();
},
}
actions: {
close() {
this._close();
},
@action
close() {
this._close();
}
composePM(user, post) {
this._close();
this.composePrivateMessage(user, post);
},
@action
composePM(user, post) {
this._close();
this.composePrivateMessage(user, post);
}
cancelFilter() {
this.postStream.cancelFilter();
this.postStream.refresh();
this._close();
},
@action
cancelFilter() {
this.postStream.cancelFilter();
this.postStream.refresh();
this._close();
}
filterPosts() {
this.filterPosts(this.user);
this._close();
},
@action
handleFilterPosts() {
this.filterPosts(this.user);
this._close();
}
deleteUser() {
this.user.delete();
this._close();
},
@action
deleteUser() {
this.user.delete();
this._close();
}
checkEmail(user) {
user.checkEmail();
},
},
});
@action
checkEmail(user) {
user.checkEmail();
}
}

View File

@ -1,14 +1,14 @@
import Component from "@ember/component";
import { tagName } from "@ember-decorators/component";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default Component.extend({
tagName: "",
@tagName("")
export default class UserFlagPercentage extends Component {
@discourseComputed("percentage")
showPercentage(percentage) {
return percentage.total >= 3;
},
}
// We do a little logic to choose which icon to display and which text
@discourseComputed("agreed", "disagreed", "ignored")
@ -51,5 +51,5 @@ export default Component.extend({
});
return result;
},
});
}
}

View File

@ -1,34 +1,39 @@
import Component from "@ember/component";
import { alias } from "@ember/object/computed";
import {
attributeBindings,
classNameBindings,
} from "@ember-decorators/component";
import { prioritizeNameInUx } from "discourse/lib/settings";
import { userPath } from "discourse/lib/url";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({
classNameBindings: [":user-info", "size"],
attributeBindings: ["data-username"],
size: "small",
"data-username": alias("user.username"),
includeLink: true,
includeAvatar: true,
@classNameBindings(":user-info", "size")
@attributeBindings("dataUsername:data-username")
export default class UserInfo extends Component {
size = "small";
includeLink = true;
includeAvatar = true;
@alias("user.username") dataUsername;
didInsertElement() {
this._super(...arguments);
super.didInsertElement(...arguments);
this.user?.statusManager?.trackStatus();
},
}
willDestroyElement() {
this._super(...arguments);
super.willDestroyElement(...arguments);
this.user?.statusManager?.stopTrackingStatus();
},
}
@discourseComputed("user.username")
userPath(username) {
return userPath(username);
},
}
@discourseComputed("user.name")
nameFirst(name) {
return prioritizeNameInUx(name);
},
});
}
}

View File

@ -1,8 +1,10 @@
import Component from "@ember/component";
import { alias } from "@ember/object/computed";
export default Component.extend({
tagName: "a",
attributeBindings: ["href", "data-user-card"],
href: alias("user.path"),
"data-user-card": alias("user.username"),
});
import { attributeBindings, tagName } from "@ember-decorators/component";
@tagName("a")
@attributeBindings("href", "dataUserCard:data-user-card")
export default class UserLink extends Component {
@alias("user.path") href;
@alias("user.username") dataUserCard;
}

View File

@ -1,7 +1,8 @@
import Component from "@ember/component";
import { tagName } from "@ember-decorators/component";
import { i18n } from "discourse/lib/computed";
export default Component.extend({
tagName: "",
dayLabel: i18n("day", "user.notification_schedule.%@"),
});
@tagName("")
export default class UserNotificationScheduleDay extends Component {
@i18n("day", "user.notification_schedule.%@") dayLabel;
}

View File

@ -13,41 +13,41 @@ const DAYS = [
"sunday",
];
const Day = EmberObject.extend({
id: null,
startTimeOptions: null,
model: null,
class Day extends EmberObject {
id = null;
startTimeOptions = null;
model = null;
@action
onChangeStartTime(val) {
this.startingTimeChangedForDay(val);
},
}
@action
onChangeEndTime(val) {
this.set(`model.user_notification_schedule.day_${this.id}_end_time`, val);
},
}
@discourseComputed(
"model.user_notification_schedule.day_{0,1,2,3,4,5,6}_start_time"
)
startTimeValue(schedule) {
return schedule[`day_${this.id}_start_time`];
},
}
@discourseComputed(
"model.user_notification_schedule.day_{0,1,2,3,4,5,6}_start_time"
)
endTimeOptions(schedule) {
return this.buildEndTimeOptionsFor(schedule[`day_${this.id}_start_time`]);
},
}
@discourseComputed(
"model.user_notification_schedule.day_{0,1,2,3,4,5,6}_end_time"
)
endTimeValue(schedule) {
return schedule[`day_${this.id}_end_time`];
},
}
startingTimeChangedForDay(val) {
val = parseInt(val, 10);
@ -61,7 +61,7 @@ const Day = EmberObject.extend({
val + 30
);
}
},
}
buildEndTimeOptionsFor(startTime) {
startTime = parseInt(startTime, 10);
@ -72,14 +72,14 @@ const Day = EmberObject.extend({
includeNone: false,
showMidnight: true,
});
},
});
}
}
export default Component.extend({
days: null,
export default class UserNotificationSchedule extends Component {
days = null;
didInsertElement() {
this._super(...arguments);
super.didInsertElement(...arguments);
this.set(
"startTimeOptions",
this.buildTimeOptions(0, {
@ -101,7 +101,7 @@ export default Component.extend({
})
);
});
},
}
buildTimeOptions(startAt, opts = { includeNone: false, showMidnight: true }) {
let timeOptions = [];
@ -135,5 +135,5 @@ export default Component.extend({
});
}
return timeOptions;
},
});
}
}

View File

@ -1,3 +1,3 @@
import Component from "@ember/component";
export default Component.extend({});
export default class UserProfileAvatar extends Component {}

View File

@ -1,39 +1,40 @@
import Component from "@ember/component";
import { computed } from "@ember/object";
import { classNameBindings, tagName } from "@ember-decorators/component";
import { propertyEqual } from "discourse/lib/computed";
import { userPath } from "discourse/lib/url";
import { actionDescription } from "discourse/widgets/post-small-action";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({
tagName: "li",
@tagName("li")
@classNameBindings(
":user-stream-item",
":item", // DEPRECATED: 'item' class
"hidden",
"item.deleted:deleted",
"moderatorAction"
)
export default class UserStreamItem extends Component {
@propertyEqual("item.post_type", "site.post_types.moderator_action")
moderatorAction;
classNameBindings: [
":user-stream-item",
":item", // DEPRECATED: 'item' class
"hidden",
"item.deleted:deleted",
"moderatorAction",
],
hidden: computed("item.hidden", function () {
return (
this.get("item.hidden") && !(this.currentUser && this.currentUser.staff)
);
}),
moderatorAction: propertyEqual(
"item.post_type",
"site.post_types.moderator_action"
),
actionDescription: actionDescription(
@actionDescription(
"item.action_code",
"item.created_at",
"item.action_code_who",
"item.action_code_path"
),
)
actionDescription;
@computed("item.hidden")
get hidden() {
return (
this.get("item.hidden") && !(this.currentUser && this.currentUser.staff)
);
}
@discourseComputed("item.draft_username", "item.username")
userUrl(draftUsername, username) {
return userPath((draftUsername || username).toLowerCase());
},
});
}
}

View File

@ -1,8 +1,10 @@
import Component from "@ember/component";
import { on } from "@ember/object/evented";
import { action } from "@ember/object";
import { getOwner } from "@ember/owner";
import { later } from "@ember/runloop";
import { service } from "@ember/service";
import { classNames, tagName } from "@ember-decorators/component";
import { on } from "@ember-decorators/object";
import $ from "jquery";
import { popupAjaxError } from "discourse/lib/ajax-error";
import ClickTrack from "discourse/lib/click-track";
@ -13,13 +15,18 @@ import Draft from "discourse/models/draft";
import Post from "discourse/models/post";
import I18n from "discourse-i18n";
export default Component.extend(LoadMore, {
tagName: "ul",
dialog: service(),
composer: service(),
_lastDecoratedElement: null,
@tagName("ul")
@classNames("user-stream")
export default class UserStream extends Component.extend(LoadMore) {
@service dialog;
@service composer;
_initialize: on("init", function () {
loading = false;
eyelineSelector = ".user-stream .item";
_lastDecoratedElement = null;
@on("init")
_initialize() {
const filter = this.get("stream.filter");
if (filter) {
this.set("classNames", [
@ -27,13 +34,10 @@ export default Component.extend(LoadMore, {
"filter-" + filter.toString().replace(",", "-"),
]);
}
}),
}
loading: false,
eyelineSelector: ".user-stream .item",
classNames: ["user-stream"],
_inserted: on("didInsertElement", function () {
@on("didInsertElement")
_inserted() {
$(this.element).on(
"click.details-disabled",
"details.disabled",
@ -44,15 +48,16 @@ export default Component.extend(LoadMore, {
});
this._updateLastDecoratedElement();
this.appEvents.trigger("decorate-non-stream-cooked-element", this.element);
}),
}
// This view is being removed. Shut down operations
_destroyed: on("willDestroyElement", function () {
@on("willDestroyElement")
_destroyed() {
$(this.element).off("click.details-disabled", "details.disabled");
// Unbind link tracking
$(this.element).off("click.discourse-redirect", ".excerpt a");
}),
}
_updateLastDecoratedElement() {
const nodes = this.element.querySelectorAll(".user-stream-item");
@ -64,89 +69,88 @@ export default Component.extend(LoadMore, {
return;
}
this._lastDecoratedElement = lastElement;
},
}
actions: {
removeBookmark(userAction) {
const stream = this.stream;
Post.updateBookmark(userAction.get("post_id"), false)
.then(() => {
stream.remove(userAction);
@action
removeBookmark(userAction) {
const stream = this.stream;
Post.updateBookmark(userAction.get("post_id"), false)
.then(() => {
stream.remove(userAction);
})
.catch(popupAjaxError);
}
@action
resumeDraft(item) {
if (this.composer.get("model.viewOpen")) {
this.composer.close();
}
if (item.get("postUrl")) {
DiscourseURL.routeTo(item.get("postUrl"));
} else {
Draft.get(item.draft_key)
.then((d) => {
const draft = d.draft || item.data;
if (!draft) {
return;
}
this.composer.open({
draft,
draftKey: item.draft_key,
draftSequence: d.draft_sequence,
});
})
.catch(popupAjaxError);
},
.catch((error) => {
popupAjaxError(error);
});
}
}
resumeDraft(item) {
if (this.composer.get("model.viewOpen")) {
this.composer.close();
}
if (item.get("postUrl")) {
DiscourseURL.routeTo(item.get("postUrl"));
} else {
Draft.get(item.draft_key)
.then((d) => {
const draft = d.draft || item.data;
if (!draft) {
return;
@action
removeDraft(draft) {
const stream = this.stream;
this.dialog.yesNoConfirm({
message: I18n.t("drafts.remove_confirmation"),
didConfirm: () => {
Draft.clear(draft.draft_key, draft.sequence)
.then(() => {
stream.remove(draft);
if (draft.draft_key === NEW_TOPIC_KEY) {
this.currentUser.set("has_topic_draft", false);
}
this.composer.open({
draft,
draftKey: item.draft_key,
draftSequence: d.draft_sequence,
});
})
.catch((error) => {
popupAjaxError(error);
});
}
},
},
});
}
removeDraft(draft) {
const stream = this.stream;
@action
loadMore() {
if (this.loading) {
return;
}
this.dialog.yesNoConfirm({
message: I18n.t("drafts.remove_confirmation"),
didConfirm: () => {
Draft.clear(draft.draft_key, draft.sequence)
.then(() => {
stream.remove(draft);
if (draft.draft_key === NEW_TOPIC_KEY) {
this.currentUser.set("has_topic_draft", false);
}
})
.catch((error) => {
popupAjaxError(error);
});
},
this.set("loading", true);
const stream = this.stream;
stream.findItems().then(() => {
this.set("loading", false);
// The next elements are not rendered on the page yet, we need to
// wait for that before trying to decorate them.
later(() => {
let element = this._lastDecoratedElement?.nextElementSibling;
while (element) {
this.trigger("user-stream:new-item-inserted", element);
this.appEvents.trigger("decorate-non-stream-cooked-element", element);
element = element.nextElementSibling;
}
this._updateLastDecoratedElement();
});
},
loadMore() {
if (this.loading) {
return;
}
this.set("loading", true);
const stream = this.stream;
stream.findItems().then(() => {
this.set("loading", false);
// The next elements are not rendered on the page yet, we need to
// wait for that before trying to decorate them.
later(() => {
let element = this._lastDecoratedElement?.nextElementSibling;
while (element) {
this.trigger("user-stream:new-item-inserted", element);
this.appEvents.trigger(
"decorate-non-stream-cooked-element",
element
);
element = element.nextElementSibling;
}
this._updateLastDecoratedElement();
});
});
},
},
});
});
}
}

View File

@ -1,11 +1,11 @@
import Component from "@ember/component";
import { tagName } from "@ember-decorators/component";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({
tagName: "",
@tagName("")
export default class UserSummaryCategorySearch extends Component {
@discourseComputed("user", "category")
searchParams() {
return `@${this.get("user.username")} #${this.get("category.slug")}`;
},
});
}
}

View File

@ -1,4 +1,5 @@
import Component from "@ember/component";
export default Component.extend({
tagName: "li",
});
import { tagName } from "@ember-decorators/component";
@tagName("li")
export default class UserSummaryTopic extends Component {}

View File

@ -1,14 +1,14 @@
import Component from "@ember/component";
import { tagName } from "@ember-decorators/component";
import discourseComputed from "discourse-common/utils/decorators";
// should be kept in sync with 'UserSummary::MAX_SUMMARY_RESULTS'
const MAX_SUMMARY_RESULTS = 6;
export default Component.extend({
tagName: "",
@tagName("")
export default class UserSummaryTopicsList extends Component {
@discourseComputed("items.length")
hasMore(length) {
return length >= MAX_SUMMARY_RESULTS;
},
});
}
}

View File

@ -1,4 +1,5 @@
import Component from "@ember/component";
export default Component.extend({
tagName: "li",
});
import { tagName } from "@ember-decorators/component";
@tagName("li")
export default class UserSummaryUser extends Component {}

View File

@ -1,3 +1,3 @@
import Component from "@ember/component";
export default Component.extend({});
export default class UserSummaryUsersList extends Component {}