DEV: Convert core components to native class syntax (batch 2) (#28515)

Changes made using the ember-native-class-codemod, plus some manual tweaks
This commit is contained in:
David Taylor 2024-08-27 15:00:46 +01:00 committed by GitHub
parent 31c0a08f8a
commit 66b061a5a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 367 additions and 369 deletions

View File

@ -1,4 +1,5 @@
import Component from "@ember/component";
import { tagName } from "@ember-decorators/component";
import discourseComputed from "discourse-common/utils/decorators";
const LIST_TYPE = {
@ -6,10 +7,10 @@ const LIST_TYPE = {
MUTED: "muted",
};
export default Component.extend({
tagName: "",
category: null,
listType: LIST_TYPE.NORMAL,
@tagName("")
export default class CategoryListItem extends Component {
category = null;
listType = LIST_TYPE.NORMAL;
@discourseComputed("category.isHidden", "category.hasMuted", "listType")
isHidden(isHiddenCategory, hasMuted, listType) {
@ -17,7 +18,7 @@ export default Component.extend({
(isHiddenCategory && listType === LIST_TYPE.NORMAL) ||
(!hasMuted && listType === LIST_TYPE.MUTED)
);
},
}
@discourseComputed("category.isMuted", "listType")
isMuted(isMutedCategory, listType) {
@ -25,20 +26,20 @@ export default Component.extend({
(isMutedCategory && listType === LIST_TYPE.NORMAL) ||
(!isMutedCategory && listType === LIST_TYPE.MUTED)
);
},
}
@discourseComputed("topicTrackingState.messageCount")
unreadTopicsCount() {
return this.category.unreadTopicsCount;
},
}
@discourseComputed("topicTrackingState.messageCount")
newTopicsCount() {
return this.category.newTopicsCount;
},
}
@discourseComputed("category.path")
slugPath(categoryPath) {
return categoryPath.substring("/c/".length);
},
});
}
}

View File

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

View File

@ -1,43 +1,45 @@
import Component from "@ember/component";
import { action } from "@ember/object";
import { alias, equal } from "@ember/object/computed";
import { classNames } from "@ember-decorators/component";
import { observes } from "@ember-decorators/object";
import PermissionType from "discourse/models/permission-type";
import discourseComputed, { observes } from "discourse-common/utils/decorators";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
const EVERYONE = "everyone";
export default Component.extend({
classNames: ["permission-row", "row-body"],
canCreate: equal("type", PermissionType.FULL),
everyonePermissionType: alias("everyonePermission.permission_type"),
@classNames("permission-row", "row-body")
export default class CategoryPermissionRow extends Component {
@equal("type", PermissionType.FULL) canCreate;
@alias("everyonePermission.permission_type") everyonePermissionType;
@discourseComputed("type")
canReply(value) {
return (
value === PermissionType.CREATE_POST || value === PermissionType.FULL
);
},
}
@discourseComputed("type")
canReplyIcon() {
return this.canReply ? "check-square" : "far-square";
},
}
@discourseComputed("type")
canCreateIcon() {
return this.canCreate ? "check-square" : "far-square";
},
}
@discourseComputed("type")
replyGranted() {
return this.type <= PermissionType.CREATE_POST ? "reply-granted" : "";
},
}
@discourseComputed("type")
createGranted() {
return this.type === PermissionType.FULL ? "create-granted" : "";
},
}
@observes("everyonePermissionType")
inheritFromEveryone() {
@ -49,7 +51,7 @@ export default Component.extend({
if (this.everyonePermissionType < this.type) {
this.updatePermission(this.everyonePermissionType);
}
},
}
@discourseComputed("everyonePermissionType", "type")
replyDisabled(everyonePermissionType) {
@ -61,14 +63,14 @@ export default Component.extend({
return true;
}
return false;
},
}
@discourseComputed("replyDisabled")
replyTooltip(replyDisabled) {
return replyDisabled
? I18n.t("category.permissions.inherited")
: I18n.t("category.permissions.toggle_reply");
},
}
@discourseComputed("everyonePermissionType", "type")
createDisabled(everyonePermissionType) {
@ -80,47 +82,47 @@ export default Component.extend({
return true;
}
return false;
},
}
@discourseComputed("createDisabled")
createTooltip(createDisabled) {
return createDisabled
? I18n.t("category.permissions.inherited")
: I18n.t("category.permissions.toggle_full");
},
}
updatePermission(type) {
this.category.updatePermission(this.group_name, type);
},
}
@action
removeRow(event) {
event?.preventDefault();
this.category.removePermission(this.group_name);
},
}
actions: {
setPermissionReply() {
if (this.type <= PermissionType.CREATE_POST) {
this.updatePermission(PermissionType.READONLY);
} else {
this.updatePermission(PermissionType.CREATE_POST);
}
},
@action
setPermissionReply() {
if (this.type <= PermissionType.CREATE_POST) {
this.updatePermission(PermissionType.READONLY);
} else {
this.updatePermission(PermissionType.CREATE_POST);
}
}
setPermissionFull() {
if (
this.group_name !== EVERYONE &&
this.everyonePermissionType === PermissionType.FULL
) {
return;
}
@action
setPermissionFull() {
if (
this.group_name !== EVERYONE &&
this.everyonePermissionType === PermissionType.FULL
) {
return;
}
if (this.type === PermissionType.FULL) {
this.updatePermission(PermissionType.CREATE_POST);
} else {
this.updatePermission(PermissionType.FULL);
}
},
},
});
if (this.type === PermissionType.FULL) {
this.updatePermission(PermissionType.CREATE_POST);
} else {
this.updatePermission(PermissionType.FULL);
}
}
}

View File

@ -2,10 +2,11 @@ import Component from "@ember/component";
import { and } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({
export default class CategoryReadOnlyBanner extends Component {
@and("category.read_only_banner", "readOnly", "user") shouldShow;
@discourseComputed
user() {
return this.currentUser;
},
shouldShow: and("category.read_only_banner", "readOnly", "user"),
});
}
}

View File

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

View File

@ -1,6 +1,8 @@
import Component from "@ember/component";
export default Component.extend({
tagName: "h3",
// icon name defined here so it can be easily overridden in theme components
lockIcon: "lock",
});
import { tagName } from "@ember-decorators/component";
@tagName("h3")
export default class CategoryTitleLink extends Component {}
// icon name defined on prototype so it can be easily overridden in theme components
CategoryTitleLink.prototype.lockIcon = "lock";

View File

@ -1,5 +1,6 @@
import Component from "@ember/component";
export default Component.extend({
tagName: "span",
classNames: ["category__badges"],
});
import { classNames, tagName } from "@ember-decorators/component";
@tagName("span")
@classNames("category__badges")
export default class CategoryUnread extends Component {}

View File

@ -2,14 +2,15 @@ import Component from "@ember/component";
import { action, get } from "@ember/object";
import { next } from "@ember/runloop";
import { isEmpty } from "@ember/utils";
import { observes } from "@ember-decorators/object";
import $ from "jquery";
import { searchForTerm } from "discourse/lib/search";
import { debounce, observes } from "discourse-common/utils/decorators";
import { debounce } from "discourse-common/utils/decorators";
export default Component.extend({
loading: null,
noResults: null,
messages: null,
export default class ChooseMessage extends Component {
loading = null;
noResults = null;
messages = null;
@observes("messageTitle")
messageTitleChanged() {
@ -19,7 +20,7 @@ export default Component.extend({
selectedTopicId: null,
});
this.search(this.messageTitle);
},
}
@observes("messages")
messagesChanged() {
@ -28,7 +29,7 @@ export default Component.extend({
this.set("noResults", messages.length === 0);
}
this.set("loading", false);
},
}
@debounce(300)
search(title) {
@ -53,7 +54,7 @@ export default Component.extend({
this.setProperties({ messages: null, loading: false });
}
});
},
}
@action
chooseMessage(message, event) {
@ -61,5 +62,5 @@ export default Component.extend({
const messageId = get(message, "id");
this.set("selectedTopicId", messageId);
next(() => $(`#choose-message-${messageId}`).prop("checked", "true"));
},
});
}
}

View File

@ -1,30 +1,34 @@
import Component from "@ember/component";
import { htmlSafe } from "@ember/template";
import {
attributeBindings,
classNameBindings,
tagName,
} from "@ember-decorators/component";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default Component.extend({
tagName: "button",
attributeBindings: ["style", "title"],
classNameBindings: [":colorpicker", "isUsed:used-color:unused-color"],
@tagName("button")
@attributeBindings("style", "title")
@classNameBindings(":colorpicker", "isUsed:used-color:unused-color")
export default class ColorPickerChoice extends Component {
@discourseComputed("color", "usedColors")
isUsed(color, usedColors) {
return (usedColors || []).includes(color.toUpperCase());
},
}
@discourseComputed("isUsed")
title(isUsed) {
return isUsed ? I18n.t("category.already_used") : null;
},
}
@discourseComputed("color")
style(color) {
return htmlSafe(`background-color: #${color};`);
},
}
click(e) {
e.preventDefault();
this.selectColor(this.color);
},
});
}
}

View File

@ -1,10 +1,11 @@
import Component from "@ember/component";
export default Component.extend({
classNames: "colors-container",
import { action } from "@ember/object";
import { classNames } from "@ember-decorators/component";
actions: {
selectColor(color) {
this.set("value", color);
},
},
});
@classNames("colors-container")
export default class ColorPicker extends Component {
@action
selectColor(color) {
this.set("value", color);
}
}

View File

@ -1,6 +1,7 @@
import Component from "@ember/component";
import { alias } from "@ember/object/computed";
import { htmlSafe } from "@ember/template";
import { classNames } from "@ember-decorators/component";
import {
CREATE_SHARED_DRAFT,
CREATE_TOPIC,
@ -21,10 +22,10 @@ const TITLES = {
[EDIT_SHARED_DRAFT]: "composer.edit_shared_draft",
};
export default Component.extend({
classNames: ["composer-action-title"],
options: alias("model.replyOptions"),
action: alias("model.action"),
@classNames("composer-action-title")
export default class ComposerActionTitle extends Component {
@alias("model.replyOptions") options;
@alias("model.action") action;
// Note we update when some other attributes like tag/category change to allow
// text customizations to use those.
@ -57,7 +58,7 @@ export default Component.extend({
);
}
}
},
}
_formatEditUserPost(userAvatar, userLink, postLink, originalUser) {
let editTitle = `
@ -75,7 +76,7 @@ export default Component.extend({
}
return htmlSafe(editTitle);
},
}
_formatReplyToTopic(link) {
return htmlSafe(
@ -83,12 +84,12 @@ export default Component.extend({
"model.topic.id"
)}">${link.anchor}</a>`
);
},
}
_formatReplyToUserPost(avatar, link) {
const htmlLink = `<a class="user-link" href="${link.href}">${escape(
link.anchor
)}</a>`;
return htmlSafe(`${avatar}${htmlLink}`);
},
});
}
}

View File

@ -1,15 +1,14 @@
import Component from "@ember/component";
import { cancel, schedule, throttle } from "@ember/runloop";
import { classNameBindings } from "@ember-decorators/component";
import { observes } from "@ember-decorators/object";
import { headerOffset } from "discourse/lib/offset-calculator";
import positioningWorkaround from "discourse/lib/safari-hacks";
import { isiPad } from "discourse/lib/utilities";
import Composer from "discourse/models/composer";
import discourseDebounce from "discourse-common/lib/debounce";
import discourseLater from "discourse-common/lib/later";
import discourseComputed, {
bind,
observes,
} from "discourse-common/utils/decorators";
import discourseComputed, { bind } from "discourse-common/utils/decorators";
const START_DRAG_EVENTS = ["touchstart", "mousedown"];
const DRAG_EVENTS = ["touchmove", "mousemove"];
@ -21,37 +20,36 @@ function mouseYPos(e) {
return e.clientY || (e.touches && e.touches[0] && e.touches[0].clientY);
}
export default Component.extend({
elementId: "reply-control",
classNameBindings: [
"composer.creatingPrivateMessage:private-message",
"composeState",
"composer.loading",
"prefixedComposerAction",
"composer.canEditTitle:edit-title",
"composer.createdPost:created-post",
"composer.creatingTopic:topic",
"composer.whisper:composing-whisper",
"composer.sharedDraft:composing-shared-draft",
"showPreview:show-preview:hide-preview",
"currentUserPrimaryGroupClass",
],
@classNameBindings(
"composer.creatingPrivateMessage:private-message",
"composeState",
"composer.loading",
"prefixedComposerAction",
"composer.canEditTitle:edit-title",
"composer.createdPost:created-post",
"composer.creatingTopic:topic",
"composer.whisper:composing-whisper",
"composer.sharedDraft:composing-shared-draft",
"showPreview:show-preview:hide-preview",
"currentUserPrimaryGroupClass"
)
export default class ComposerBody extends Component {
elementId = "reply-control";
@discourseComputed("composer.action")
prefixedComposerAction(action) {
return action ? `composer-action-${action}` : "";
},
}
@discourseComputed("currentUser.primary_group_name")
currentUserPrimaryGroupClass(primaryGroupName) {
return primaryGroupName && `group-${primaryGroupName}`;
},
}
@discourseComputed("composer.composeState")
composeState(composeState) {
return composeState || Composer.CLOSED;
},
}
keyUp() {
this.typed();
@ -68,14 +66,14 @@ export default Component.extend({
}
this.appEvents.trigger("composer:find-similar");
}, 1000);
},
}
@observes("composeState")
disableFullscreen() {
if (this.composeState !== Composer.OPEN && positioningWorkaround.blur) {
positioningWorkaround.blur();
}
},
}
setupComposerResizeEvents() {
this.origComposerSize = 0;
@ -88,7 +86,7 @@ export default Component.extend({
passive: false,
});
});
},
}
@bind
performDragHandler() {
@ -112,14 +110,14 @@ export default Component.extend({
);
this._triggerComposerResized();
},
}
@observes("composeState", "composer.{action,canEditTopicFeaturedLink}")
_triggerComposerResized() {
schedule("afterRender", () => {
discourseDebounce(this, this.composerResized, 300);
});
},
}
composerResized() {
if (!this.element || this.isDestroying || this.isDestroyed) {
@ -127,7 +125,7 @@ export default Component.extend({
}
this.appEvents.trigger("composer:resized");
},
}
@bind
startDragHandler(event) {
@ -145,7 +143,7 @@ export default Component.extend({
});
this.appEvents.trigger("composer:resize-started");
},
}
@bind
endDragHandler() {
@ -161,16 +159,16 @@ export default Component.extend({
this.element.classList.remove("clear-transitions");
this.element.focus();
},
}
@bind
throttledPerformDrag(event) {
event.preventDefault();
throttle(this, this.performDragHandler, event, THROTTLE_RATE);
},
}
didInsertElement() {
this._super(...arguments);
super.didInsertElement(...arguments);
this.setupComposerResizeEvents();
@ -188,10 +186,10 @@ export default Component.extend({
});
positioningWorkaround(this.element);
},
}
willDestroyElement() {
this._super(...arguments);
super.willDestroyElement(...arguments);
START_DRAG_EVENTS.forEach((startDragEvent) => {
this.element
@ -200,11 +198,11 @@ export default Component.extend({
});
cancel(this._lastKeyTimeout);
},
}
click() {
this.openIfDraft();
},
}
keyDown(e) {
if (e.key === "Escape") {
@ -220,5 +218,5 @@ export default Component.extend({
e.preventDefault();
this.save(undefined, e);
}
},
});
}
}

View File

@ -4,9 +4,9 @@
@previewUpdated={{action "previewUpdated"}}
@markdownOptions={{this.markdownOptions}}
@extraButtons={{action "extraButtons"}}
@importQuote={{action "importQuote"}}
@importQuote={{this.importQuote}}
@showUploadModal={{this.showUploadModal}}
@togglePreview={{action "togglePreview"}}
@togglePreview={{this.togglePreview}}
@processPreview={{this.processPreview}}
@validation={{this.validation}}
@loading={{this.composer.loading}}

View File

@ -1,8 +1,10 @@
import Component from "@ember/component";
import EmberObject, { computed } from "@ember/object";
import EmberObject, { action, computed } from "@ember/object";
import { alias } from "@ember/object/computed";
import { getOwner } from "@ember/owner";
import { next, schedule, throttle } from "@ember/runloop";
import { classNameBindings } from "@ember-decorators/component";
import { observes } from "@ember-decorators/object";
import { BasePlugin } from "@uppy/core";
import $ from "jquery";
import { resolveAllShortUrls } from "pretty-text/upload-short-url";
@ -39,7 +41,6 @@ import { findRawTemplate } from "discourse-common/lib/raw-templates";
import discourseComputed, {
bind,
debounce,
observes,
on,
} from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
@ -109,32 +110,32 @@ export function addApiImageWrapperButtonClickEvent(fn) {
const DEBOUNCE_FETCH_MS = 450;
const DEBOUNCE_JIT_MS = 2000;
export default Component.extend(ComposerUploadUppy, {
classNameBindings: ["showToolbar:toolbar-visible", ":wmd-controls"],
@classNameBindings("showToolbar:toolbar-visible", ":wmd-controls")
export default class ComposerEditor extends Component.extend(
ComposerUploadUppy
) {
editorClass = ".d-editor";
fileUploadElementId = "file-uploader";
mobileFileUploaderId = "mobile-file-upload";
composerEventPrefix = "composer";
uploadType = "composer";
uppyId = "composer-editor-uppy";
composerModelContentKey = "reply";
editorInputClass = ".d-editor-input";
shouldBuildScrollMap = true;
scrollMap = null;
processPreview = true;
uploadMarkdownResolvers = uploadMarkdownResolvers;
uploadPreProcessors = uploadPreProcessors;
uploadHandlers = uploadHandlers;
editorClass: ".d-editor",
fileUploadElementId: "file-uploader",
mobileFileUploaderId: "mobile-file-upload",
composerEventPrefix: "composer",
uploadType: "composer",
uppyId: "composer-editor-uppy",
composerModel: alias("composer"),
composerModelContentKey: "reply",
editorInputClass: ".d-editor-input",
shouldBuildScrollMap: true,
scrollMap: null,
processPreview: true,
uploadMarkdownResolvers,
uploadPreProcessors,
uploadHandlers,
@alias("composer") composerModel;
init() {
this._super(...arguments);
super.init(...arguments);
this.warnedCannotSeeMentions = [];
this.warnedGroupMentions = [];
},
}
@discourseComputed("composer.requiredCategoryMissing")
replyPlaceholder(requiredCategoryMissing) {
@ -149,19 +150,19 @@ export default Component.extend(ComposerUploadUppy, {
: "reply_placeholder_no_images";
return `composer.${key}`;
}
},
}
@discourseComputed
showLink() {
return this.currentUser && this.currentUser.link_posting_access !== "none";
},
}
@observes("focusTarget")
setFocus() {
if (this.focusTarget === "editor") {
putCursorAtEnd(this.element.querySelector("textarea"));
}
},
}
@discourseComputed
markdownOptions() {
@ -204,7 +205,7 @@ export default Component.extend(ComposerUploadUppy, {
this.site.hashtag_configurations["topic-composer"],
hashtagIcons: this.site.hashtag_icons,
};
},
}
@bind
_afterMentionComplete(value) {
@ -216,7 +217,7 @@ export default Component.extend(ComposerUploadUppy, {
input?.blur();
input?.focus();
});
},
}
@on("didInsertElement")
_composerEditorInit() {
@ -266,7 +267,7 @@ export default Component.extend(ComposerUploadUppy, {
}
this.appEvents.trigger(`${this.composerEventPrefix}:will-open`);
},
}
@discourseComputed(
"composer.reply",
@ -313,7 +314,7 @@ export default Component.extend(ComposerUploadUppy, {
lastShownAt: lastValidatedAt,
});
}
},
}
@computed("composer.{creatingTopic,editingFirstPost,creatingSharedDraft}")
get _isNewTopic() {
@ -322,11 +323,11 @@ export default Component.extend(ComposerUploadUppy, {
this.composer.editingFirstPost ||
this.composer.creatingSharedDraft
);
},
}
_resetShouldBuildScrollMap() {
this.set("shouldBuildScrollMap", true);
},
}
@bind
_handleInputInteraction(event) {
@ -338,7 +339,7 @@ export default Component.extend(ComposerUploadUppy, {
preview.removeEventListener("scroll", this._handleInputOrPreviewScroll);
event.target.addEventListener("scroll", this._handleInputOrPreviewScroll);
},
}
@bind
_handleInputOrPreviewScroll(event) {
@ -347,7 +348,7 @@ export default Component.extend(ComposerUploadUppy, {
$(event.target),
$(this.element.querySelector(".d-editor-preview-wrapper"))
);
},
}
@bind
_handlePreviewInteraction(event) {
@ -356,7 +357,7 @@ export default Component.extend(ComposerUploadUppy, {
?.removeEventListener("scroll", this._handleInputOrPreviewScroll);
event.target?.addEventListener("scroll", this._handleInputOrPreviewScroll);
},
}
_syncScroll($callback, $input, $preview) {
if (!this.scrollMap || this.shouldBuildScrollMap) {
@ -365,7 +366,7 @@ export default Component.extend(ComposerUploadUppy, {
}
throttle(this, $callback, $input, $preview, this.scrollMap, 20);
},
}
// Adapted from https://github.com/markdown-it/markdown-it.github.io
_buildScrollMap($input, $preview) {
@ -452,7 +453,7 @@ export default Component.extend(ComposerUploadUppy, {
}
return scrollMap;
},
}
@bind
_throttledSyncEditorAndPreviewScroll(event) {
@ -465,7 +466,7 @@ export default Component.extend(ComposerUploadUppy, {
$preview,
20
);
},
}
_syncEditorAndPreviewScroll($input, $preview) {
if (!$input) {
@ -490,7 +491,7 @@ export default Component.extend(ComposerUploadUppy, {
const factor = previewHeight / inputHeight;
const desired = scrollPosition * factor;
$preview.scrollTop(desired + 50);
},
}
_renderMentions(preview, unseen) {
unseen ||= linkSeenMentions(preview, this.siteSettings);
@ -500,7 +501,7 @@ export default Component.extend(ComposerUploadUppy, {
this._warnMentionedGroups(preview);
this._warnCannotSeeMention(preview);
}
},
}
@debounce(DEBOUNCE_FETCH_MS)
_renderUnseenMentions(preview, unseen) {
@ -514,7 +515,7 @@ export default Component.extend(ComposerUploadUppy, {
this._warnCannotSeeMention(preview);
this._warnHereMention(response.here_count);
});
},
}
_renderHashtags(preview, unseen) {
const context = this.site.hashtag_configurations["topic-composer"];
@ -522,14 +523,14 @@ export default Component.extend(ComposerUploadUppy, {
if (unseen.length > 0) {
this._renderUnseenHashtags(preview, unseen, context);
}
},
}
@debounce(DEBOUNCE_FETCH_MS)
_renderUnseenHashtags(preview, unseen, context) {
fetchUnseenHashtagsInContext(context, unseen).then(() =>
linkSeenHashtagsInContext(context, preview)
);
},
}
@debounce(DEBOUNCE_FETCH_MS)
_refreshOneboxes(preview) {
@ -549,15 +550,15 @@ export default Component.extend(ComposerUploadUppy, {
if (refresh && loaded > 0) {
post.set("refreshedPost", true);
}
},
}
_expandShortUrls(preview) {
resolveAllShortUrls(ajax, this.siteSettings, preview);
},
}
_decorateCookedElement(preview) {
this.appEvents.trigger("decorate-non-stream-cooked-element", preview);
},
}
@debounce(DEBOUNCE_JIT_MS)
_warnMentionedGroups(preview) {
@ -581,7 +582,7 @@ export default Component.extend(ComposerUploadUppy, {
});
});
});
},
}
// add a delay to allow for typing, so you don't open the warning right away
// previously we would warn after @bob even if you were about to mention @bob2
@ -620,7 +621,7 @@ export default Component.extend(ComposerUploadUppy, {
isGroup: true,
});
});
},
}
_warnHereMention(hereCount) {
if (!hereCount || hereCount === 0) {
@ -628,7 +629,7 @@ export default Component.extend(ComposerUploadUppy, {
}
this.hereMention(hereCount);
},
}
@bind
_handleImageScaleButtonClick(event) {
@ -665,7 +666,7 @@ export default Component.extend(ComposerUploadUppy, {
event.preventDefault();
return;
},
}
resetImageControls(buttonWrapper) {
const imageResize = buttonWrapper.querySelector(".scale-btn-container");
@ -684,7 +685,7 @@ export default Component.extend(ComposerUploadUppy, {
readonlyContainer.removeAttribute("hidden");
buttonWrapper.removeAttribute("editing");
editContainer.setAttribute("hidden", "true");
},
}
commitAltText(buttonWrapper) {
const index = parseInt(buttonWrapper.getAttribute("data-image-index"), 10);
@ -704,7 +705,7 @@ export default Component.extend(ComposerUploadUppy, {
);
this.resetImageControls(buttonWrapper);
},
}
@bind
_handleAltTextInputKeypress(event) {
@ -720,7 +721,7 @@ export default Component.extend(ComposerUploadUppy, {
const buttonWrapper = event.target.closest(".button-wrapper");
this.commitAltText(buttonWrapper);
}
},
}
@bind
_handleAltTextEditButtonClick(event) {
@ -750,7 +751,7 @@ export default Component.extend(ComposerUploadUppy, {
editContainer.removeAttribute("hidden");
editContainerInput.focus();
event.preventDefault();
},
}
@bind
_handleAltTextOkButtonClick(event) {
@ -760,7 +761,7 @@ export default Component.extend(ComposerUploadUppy, {
const buttonWrapper = event.target.closest(".button-wrapper");
this.commitAltText(buttonWrapper);
},
}
@bind
_handleAltTextCancelButtonClick(event) {
@ -770,7 +771,7 @@ export default Component.extend(ComposerUploadUppy, {
const buttonWrapper = event.target.closest(".button-wrapper");
this.resetImageControls(buttonWrapper);
},
}
@bind
_handleImageDeleteButtonClick(event) {
@ -789,7 +790,7 @@ export default Component.extend(ComposerUploadUppy, {
"",
{ regex: IMAGE_MARKDOWN_REGEX, index }
);
},
}
@bind
_handleImageGridButtonClick(event) {
@ -818,7 +819,7 @@ export default Component.extend(ComposerUploadUppy, {
"grid_surround",
{ useBlockMode: true }
);
},
}
_registerImageAltTextButtonClick(preview) {
preview.addEventListener("click", this._handleAltTextCancelButtonClick);
@ -832,7 +833,7 @@ export default Component.extend(ComposerUploadUppy, {
apiImageWrapperBtnEvents.forEach((fn) =>
preview.addEventListener("click", fn)
);
},
}
@on("willDestroyElement")
_composerClosed() {
@ -870,17 +871,18 @@ export default Component.extend(ComposerUploadUppy, {
apiImageWrapperBtnEvents.forEach((fn) =>
preview?.removeEventListener("click", fn)
);
},
}
@action
onExpandPopupMenuOptions(toolbarEvent) {
const selected = toolbarEvent.selected;
toolbarEvent.selectText(selected.start, selected.end - selected.start);
this.storeToolbarState(toolbarEvent);
},
}
showPreview() {
this.send("togglePreview");
},
}
_isInQuote(element) {
let parent = element.parentElement;
@ -893,18 +895,18 @@ export default Component.extend(ComposerUploadUppy, {
}
return false;
},
}
_isPreviewRoot(element) {
return (
element.tagName === "DIV" &&
element.classList.contains("d-editor-preview")
);
},
}
_isQuote(element) {
return element.tagName === "ASIDE" && element.classList.contains("quote");
},
}
_cursorIsOnEmptyLine() {
const textArea = this.element.querySelector(".d-editor-input");
@ -916,7 +918,7 @@ export default Component.extend(ComposerUploadUppy, {
} else {
return false;
}
},
}
_findMatchingUploadHandler(fileName) {
return this.uploadHandlers.find((handler) => {
@ -924,62 +926,50 @@ export default Component.extend(ComposerUploadUppy, {
const regex = new RegExp(`\\.(${ext})$`, "i");
return regex.test(fileName);
});
},
}
actions: {
importQuote(toolbarEvent) {
this.importQuote(toolbarEvent);
},
@action
extraButtons(toolbar) {
toolbar.addButton({
id: "quote",
group: "fontStyles",
icon: "far-comment",
sendAction: this.importQuote,
title: "composer.quote_post_title",
unshift: true,
});
onExpandPopupMenuOptions(toolbarEvent) {
this.onExpandPopupMenuOptions(toolbarEvent);
},
togglePreview() {
this.togglePreview();
},
extraButtons(toolbar) {
if (this.allowUpload && this.uploadIcon && this.site.desktopView) {
toolbar.addButton({
id: "quote",
group: "fontStyles",
icon: "far-comment",
sendAction: this.importQuote,
title: "composer.quote_post_title",
unshift: true,
id: "upload",
group: "insertions",
icon: this.uploadIcon,
title: "upload",
sendAction: this.showUploadModal,
});
}
if (this.allowUpload && this.uploadIcon && this.site.desktopView) {
toolbar.addButton({
id: "upload",
group: "insertions",
icon: this.uploadIcon,
title: "upload",
sendAction: this.showUploadModal,
});
}
toolbar.addButton({
id: "options",
group: "extras",
icon: "cog",
title: "composer.options",
sendAction: this.onExpandPopupMenuOptions.bind(this),
popupMenu: true,
});
}
toolbar.addButton({
id: "options",
group: "extras",
icon: "cog",
title: "composer.options",
sendAction: this.onExpandPopupMenuOptions.bind(this),
popupMenu: true,
});
},
@action
previewUpdated(preview, unseenMentions, unseenHashtags) {
this._renderMentions(preview, unseenMentions);
this._renderHashtags(preview, unseenHashtags);
this._refreshOneboxes(preview);
this._expandShortUrls(preview);
previewUpdated(preview, unseenMentions, unseenHashtags) {
this._renderMentions(preview, unseenMentions);
this._renderHashtags(preview, unseenHashtags);
this._refreshOneboxes(preview);
this._expandShortUrls(preview);
if (!this.siteSettings.enable_diffhtml_preview) {
this._decorateCookedElement(preview);
}
if (!this.siteSettings.enable_diffhtml_preview) {
this._decorateCookedElement(preview);
}
this.afterRefresh(preview);
},
},
});
this.afterRefresh(preview);
}
}

View File

@ -1,23 +1,12 @@
import Component from "@ember/component";
import { getOwner } from "@ember/owner";
import deprecated from "discourse-common/lib/deprecated";
import { classNameBindings } from "@ember-decorators/component";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({
classNameBindings: [":composer-popup", "message.extraClass"],
@classNameBindings(":composer-popup", "message.extraClass")
export default class ComposerMessage extends Component {
@discourseComputed("message.templateName")
layout(templateName) {
return getOwner(this).lookup(`template:composer/${templateName}`);
},
actions: {
closeMessage() {
deprecated(
'You should use `action=(closeMessage message)` instead of `action=(action "closeMessage")`',
{ id: "discourse.composer-message.closeMessage" }
);
this.closeMessage(this.message);
},
},
});
}
}

View File

@ -2,23 +2,26 @@ import Component from "@ember/component";
import EmberObject from "@ember/object";
import { alias, or } from "@ember/object/computed";
import { next, schedule } from "@ember/runloop";
import { classNames } from "@ember-decorators/component";
import { observes } from "@ember-decorators/object";
import { load } from "pretty-text/oneboxer";
import { lookupCache } from "pretty-text/oneboxer-cache";
import { ajax } from "discourse/lib/ajax";
import putCursorAtEnd from "discourse/lib/put-cursor-at-end";
import { isTesting } from "discourse-common/config/environment";
import discourseDebounce from "discourse-common/lib/debounce";
import discourseComputed, { observes } from "discourse-common/utils/decorators";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default Component.extend({
classNames: ["title-input"],
watchForLink: alias("composer.canEditTopicFeaturedLink"),
disabled: or("composer.loading", "composer.disableTitleInput"),
isTitleFocused: false,
@classNames("title-input")
export default class ComposerTitle extends Component {
@alias("composer.canEditTopicFeaturedLink") watchForLink;
@or("composer.loading", "composer.disableTitleInput") disabled;
isTitleFocused = false;
didInsertElement() {
this._super(...arguments);
super.didInsertElement(...arguments);
const titleInput = this.element.querySelector("input");
this._focusHandler = () => this.set("isTitleFocused", true);
@ -34,17 +37,17 @@ export default Component.extend({
if (this.get("composer.titleLength") > 0) {
discourseDebounce(this, this._titleChanged, 10);
}
},
}
willDestroyElement() {
this._super(...arguments);
super.willDestroyElement(...arguments);
const titleInput = this.element.querySelector("input");
if (titleInput) {
titleInput.removeEventListener("focus", this._focusHandler);
titleInput.removeEventListener("blur", this._blurHandler);
}
},
}
@discourseComputed(
"composer.titleLength",
@ -83,14 +86,14 @@ export default Component.extend({
lastShownAt: lastValidatedAt,
});
}
},
}
@discourseComputed("watchForLink")
titleMaxLength(watchForLink) {
// maxLength gets in the way of pasting long links, so don't use it if featured links are allowed.
// Validation will display a message if titles are too long.
return watchForLink ? null : this.siteSettings.max_topic_title_length;
},
}
@observes("composer.titleLength", "watchForLink")
_titleChanged() {
@ -110,14 +113,14 @@ export default Component.extend({
} else {
discourseDebounce(this, this._checkForUrl, 500);
}
},
}
@observes("composer.replyLength")
_clearFeaturedLink() {
if (this.watchForLink && this.bodyIsDefault()) {
this.set("composer.featuredLink", null);
}
},
}
_checkForUrl() {
if (!this.element || this.isDestroying || this.isDestroyed) {
@ -169,7 +172,7 @@ export default Component.extend({
});
}
}
},
}
_updatePost(html) {
if (html) {
@ -207,13 +210,13 @@ export default Component.extend({
}
}
}
},
}
changeTitle(val) {
if (val && val.length > 0) {
this.set("composer.title", val.trim());
}
},
}
@discourseComputed("composer.title", "composer.titleLength")
isAbsoluteUrl(title, titleLength) {
@ -222,7 +225,7 @@ export default Component.extend({
/^(https?:)?\/\/[\w\.\-]+/i.test(title) &&
!/\s/.test(title)
);
},
}
bodyIsDefault() {
const reply = this.get("composer.reply") || "";
@ -230,5 +233,5 @@ export default Component.extend({
reply.length === 0 ||
reply === (this.get("composer.category.topic_template") || "")
);
},
});
}
}

View File

@ -1,20 +1,20 @@
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 ComposerToggles extends Component {
@discourseComputed("composeState")
toggleTitle(composeState) {
return composeState === "draft" || composeState === "saving"
? "composer.abandon"
: "composer.collapse";
},
}
@discourseComputed("showToolbar")
toggleToolbarTitle(showToolbar) {
return showToolbar ? "composer.hide_toolbar" : "composer.show_toolbar";
},
}
@discourseComputed("composeState")
fullscreenTitle(composeState) {
@ -23,14 +23,14 @@ export default Component.extend({
: composeState === "fullscreen"
? "composer.exit_fullscreen"
: "composer.enter_fullscreen";
},
}
@discourseComputed("composeState")
toggleIcon(composeState) {
return composeState === "draft" || composeState === "saving"
? "times"
: "chevron-down";
},
}
@discourseComputed("composeState")
fullscreenIcon(composeState) {
@ -39,7 +39,7 @@ export default Component.extend({
: composeState === "fullscreen"
? "discourse-compress"
: "discourse-expand";
},
}
@discourseComputed("disableTextarea")
showFullScreenButton(disableTextarea) {
@ -47,5 +47,5 @@ export default Component.extend({
return false;
}
return !disableTextarea;
},
});
}
}

View File

@ -1,19 +1,17 @@
import Component from "@ember/component";
import { action } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({
init() {
this._super(...arguments);
this.set("_groups", []);
},
export default class ComposerUserSelector extends Component {
_groups = [];
didInsertElement() {
this._super(...arguments);
super.didInsertElement(...arguments);
if (this.focusTarget === "usernames") {
this.element.querySelector(".select-kit .select-kit-header").focus();
}
},
}
@discourseComputed("recipients")
splitRecipients(recipients) {
@ -21,7 +19,7 @@ export default Component.extend({
return recipients;
}
return recipients ? recipients.split(",").filter(Boolean) : [];
},
}
_updateGroups(selected, newGroups) {
const groups = [];
@ -39,13 +37,12 @@ export default Component.extend({
_groups: groups,
hasGroups: groups.length > 0,
});
},
}
actions: {
updateRecipients(selected, content) {
const newGroups = content.filterBy("isGroup").mapBy("id");
this._updateGroups(selected, newGroups);
this.set("recipients", selected.join(","));
},
},
});
@action
updateRecipients(selected, content) {
const newGroups = content.filterBy("isGroup").mapBy("id");
this._updateGroups(selected, newGroups);
this.set("recipients", selected.join(","));
}
}

View File

@ -1,11 +1,10 @@
import Component from "@ember/component";
import { classNameBindings, classNames } from "@ember-decorators/component";
import I18n from "discourse-i18n";
export default Component.extend({
classNames: ["conditional-loading-section"],
classNameBindings: ["isLoading"],
isLoading: false,
title: I18n.t("conditional_loading_section.loading"),
});
@classNames("conditional-loading-section")
@classNameBindings("isLoading")
export default class ConditionalLoadingSection extends Component {
isLoading = false;
title = I18n.t("conditional_loading_section.loading");
}

View File

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

View File

@ -1,12 +1,13 @@
import Component from "@ember/component";
import { action } from "@ember/object";
import { tagName } from "@ember-decorators/component";
import discourseDebounce from "discourse-common/lib/debounce";
import { bind } from "discourse-common/utils/decorators";
export default Component.extend({
tagName: "",
copyIcon: "copy",
copyClass: "btn-primary",
@tagName("")
export default class CopyButton extends Component {
copyIcon = "copy";
copyClass = "btn-primary";
@bind
_restoreButton() {
@ -16,7 +17,7 @@ export default Component.extend({
this.set("copyIcon", "copy");
this.set("copyClass", "btn-primary");
},
}
@action
copy() {
@ -36,5 +37,5 @@ export default Component.extend({
discourseDebounce(this._restoreButton, 3000);
} catch (err) {}
},
});
}
}

View File

@ -1,38 +1,41 @@
import Component from "@ember/component";
import { action } from "@ember/object";
import { tagName } from "@ember-decorators/component";
import UppyUploadMixin from "discourse/mixins/uppy-upload";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend(UppyUploadMixin, {
id: "create-invite-uploader",
tagName: "div",
type: "csv",
autoStartUploads: false,
uploadUrl: "/invites/upload_csv",
preventDirectS3Uploads: true,
fileInputSelector: "#csv-file",
@tagName("div")
export default class CreateInviteUploader extends Component.extend(
UppyUploadMixin
) {
id = "create-invite-uploader";
type = "csv";
autoStartUploads = false;
uploadUrl = "/invites/upload_csv";
preventDirectS3Uploads = true;
fileInputSelector = "#csv-file";
validateUploadedFilesOptions() {
return { bypassNewUserRestriction: true, csvOnly: true };
},
}
@discourseComputed("filesAwaitingUpload", "uploading")
submitDisabled(filesAwaitingUpload, uploading) {
return !filesAwaitingUpload || uploading;
},
}
uploadDone() {
this.set("uploaded", true);
},
}
@action
startUpload() {
this._startUpload();
},
}
@action
setElement(element) {
this.set("fileInputEl", element);
this._initialize();
},
});
}
}

View File

@ -1,6 +1,8 @@
import Component from "@ember/component";
export default Component.extend({
tagName: "",
label: "topic.create",
btnClass: "btn-default",
});
import { tagName } from "@ember-decorators/component";
@tagName("")
export default class CreateTopicButton extends Component {
label = "topic.create";
btnClass = "btn-default";
}

View File

@ -4,11 +4,11 @@ import { hbs } from "ember-cli-htmlbars";
import { getCustomHTML } from "discourse/helpers/custom-html";
import deprecated from "discourse-common/lib/deprecated";
export default Component.extend({
triggerAppEvent: null,
export default class CustomHtml extends Component {
triggerAppEvent = null;
init() {
this._super(...arguments);
super.init(...arguments);
const name = this.name;
const html = getCustomHTML(name);
@ -25,19 +25,19 @@ export default Component.extend({
this.set("layout", template);
}
}
},
}
didInsertElement() {
this._super(...arguments);
super.didInsertElement(...arguments);
if (this.triggerAppEvent === "true") {
this.appEvents.trigger(`inserted-custom-html:${this.name}`);
}
},
}
willDestroyElement() {
this._super(...arguments);
super.willDestroyElement(...arguments);
if (this.triggerAppEvent === "true") {
this.appEvents.trigger(`destroyed-custom-html:${this.name}`);
}
},
});
}
}