DEV: Further refactor of card-contents-base (#27487)

* remove `boundCardClickHandler`
* remove jQuery usage
* explicitly pass `event` into `_positionCard()`
* move `_positionCard()` calls into the mixin
* inline variables
* remove `!target` check
* merge nested `if`s
* remove unnecessary `return`
* update the `_showCallback` comment
* move computed props below basic props
* `let` -> `const`
This commit is contained in:
Jarek Radosz 2024-06-14 23:27:29 +02:00 committed by GitHub
parent c9f8708c42
commit 516d14d59b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 35 additions and 51 deletions

View File

@ -50,8 +50,7 @@ export default Component.extend(CardContentsBase, CleansUp, {
return groupPath(group.name); return groupPath(group.name);
}, },
async _showCallback(username, $target) { async _showCallback(username) {
this._positionCard($target);
this.setProperties({ visible: true, loading: true }); this.setProperties({ visible: true, loading: true });
try { try {

View File

@ -189,8 +189,7 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
return profileHidden || inactive; return profileHidden || inactive;
}, },
async _showCallback(username, $target) { async _showCallback(username) {
this._positionCard($target);
this.setProperties({ visible: true, loading: true }); this.setProperties({ visible: true, loading: true });
const args = { const args = {

View File

@ -2,7 +2,6 @@ import { alias, match } from "@ember/object/computed";
import Mixin from "@ember/object/mixin"; import Mixin from "@ember/object/mixin";
import { schedule, throttle } from "@ember/runloop"; import { schedule, throttle } from "@ember/runloop";
import { service } from "@ember/service"; import { service } from "@ember/service";
import $ from "jquery";
import { wantsNewWindow } from "discourse/lib/intercept-click"; import { wantsNewWindow } from "discourse/lib/intercept-click";
import { headerOffset } from "discourse/lib/offset-calculator"; import { headerOffset } from "discourse/lib/offset-calculator";
import DiscourseURL from "discourse/lib/url"; import DiscourseURL from "discourse/lib/url";
@ -34,10 +33,7 @@ export default Mixin.create({
elementId: null, //click detection added for data-{elementId} elementId: null, //click detection added for data-{elementId}
triggeringLinkClass: null, //the <a> classname where this card should appear triggeringLinkClass: null, //the <a> classname where this card should appear
_showCallback: null, //username, $target - load up data for when show is called, should call this._positionCard($target) when it's done. _showCallback: null, //username - load up data for when show is called
postStream: alias("topic.postStream"),
viewingTopic: match("router.currentRouteName", /^topic\./),
visible: false, visible: false,
username: null, username: null,
@ -45,9 +41,11 @@ export default Mixin.create({
cardTarget: null, cardTarget: null,
post: null, post: null,
isDocked: false, isDocked: false,
_menuInstance: null, _menuInstance: null,
postStream: alias("topic.postStream"),
viewingTopic: match("router.currentRouteName", /^topic\./),
_show(username, target, event) { _show(username, target, event) {
// No user card for anon // No user card for anon
if (this.siteSettings.hide_user_profiles_from_public && !this.currentUser) { if (this.siteSettings.hide_user_profiles_from_public && !this.currentUser) {
@ -65,14 +63,11 @@ export default Mixin.create({
this.appEvents.trigger("card:show", username, target, event); this.appEvents.trigger("card:show", username, target, event);
const closestArticle = target.closest("article"); const postId = target.closest("article")?.dataset?.postId || null;
const postId = closestArticle?.dataset?.postId || null;
const wasVisible = this.visible;
const previousTarget = this.cardTarget;
if (wasVisible) { if (this.visible) {
this._close(); this._close();
if (target === previousTarget) { if (target === this.cardTarget) {
return; return;
} }
} }
@ -81,6 +76,7 @@ export default Mixin.create({
this.viewingTopic && postId this.viewingTopic && postId
? this.postStream.findLoadedPost(postId) ? this.postStream.findLoadedPost(postId)
: null; : null;
this.setProperties({ this.setProperties({
username, username,
loading: username, loading: username,
@ -90,7 +86,8 @@ export default Mixin.create({
document.querySelector(".card-cloak")?.classList.remove("hidden"); document.querySelector(".card-cloak")?.classList.remove("hidden");
this.appEvents.trigger("user-card:show", { username }); this.appEvents.trigger("user-card:show", { username });
this._showCallback(username, $(target)).then((user) => { this._positionCard(target, event);
this._showCallback(username).then((user) => {
this.appEvents.trigger("user-card:after-show", { user }); this.appEvents.trigger("user-card:after-show", { user });
}); });
@ -105,13 +102,8 @@ export default Mixin.create({
didInsertElement() { didInsertElement() {
this._super(...arguments); this._super(...arguments);
const id = this.elementId; const previewClickEvent = `click.discourse-preview-${this.elementId}-${this.triggeringLinkClass}`;
const previewClickEvent = `click.discourse-preview-${id}-${this.triggeringLinkClass}`; this.setProperties({ previewClickEvent });
this.setProperties({
boundCardClickHandler: this._cardClickHandler,
previewClickEvent,
});
document.addEventListener("mousedown", this._clickOutsideHandler); document.addEventListener("mousedown", this._clickOutsideHandler);
document.addEventListener("keyup", this._escListener); document.addEventListener("keyup", this._escListener);
@ -119,13 +111,13 @@ export default Mixin.create({
_cardClickListenerSelectors.forEach((selector) => { _cardClickListenerSelectors.forEach((selector) => {
document document
.querySelector(selector) .querySelector(selector)
.addEventListener("click", this.boundCardClickHandler); .addEventListener("click", this._cardClickHandler);
}); });
this.appEvents.on(previewClickEvent, this, "_previewClick"); this.appEvents.on(previewClickEvent, this, "_previewClick");
this.appEvents.on( this.appEvents.on(
`topic-header:trigger-${id}`, `topic-header:trigger-${this.elementId}`,
this, this,
"_topicHeaderTrigger" "_topicHeaderTrigger"
); );
@ -136,7 +128,7 @@ export default Mixin.create({
@bind @bind
_cardClickHandler(event) { _cardClickHandler(event) {
if (this.avatarSelector) { if (this.avatarSelector) {
let matched = this._showCardOnClick( const matched = this._showCardOnClick(
event, event,
this.avatarSelector, this.avatarSelector,
(el) => el.dataset[this.avatarDataAttrKey] (el) => el.dataset[this.avatarDataAttrKey]
@ -154,7 +146,7 @@ export default Mixin.create({
}, },
_showCardOnClick(event, selector, transformText) { _showCardOnClick(event, selector, transformText) {
let matchingEl = event.target.closest(selector); const matchingEl = event.target.closest(selector);
if (matchingEl) { if (matchingEl) {
if (wantsNewWindow(event)) { if (wantsNewWindow(event)) {
return true; return true;
@ -165,6 +157,7 @@ export default Mixin.create({
matchingEl, matchingEl,
event event
); );
if (!shouldBubble) { if (!shouldBubble) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@ -179,30 +172,27 @@ export default Mixin.create({
return this._show(username, target); return this._show(username, target);
}, },
_bindMobileScroll() { @bind
const onScroll = () => { _onScroll() {
throttle(this, this._close, 1000); throttle(this, this._close, 1000);
}; },
$(window).on(MOBILE_SCROLL_EVENT, onScroll); _bindMobileScroll() {
window.addEventListener(MOBILE_SCROLL_EVENT, this._onScroll);
}, },
_unbindMobileScroll() { _unbindMobileScroll() {
$(window).off(MOBILE_SCROLL_EVENT); window.removeEventListener(MOBILE_SCROLL_EVENT, this._onScroll);
}, },
_previewClick($target) { _previewClick(target) {
return this._show($target.text().replace(/^@/, ""), $target); return this._show(target.innerText.replace(/^@/, ""), target);
}, },
_positionCard(target) { _positionCard(target, event) {
schedule("afterRender", async () => { schedule("afterRender", async () => {
if (!target) {
return;
}
if (this.site.desktopView) { if (this.site.desktopView) {
this._menuInstance = await this.menu.show(target[0], { this._menuInstance = await this.menu.show(target, {
content: this.element, content: this.element,
autoUpdate: false, autoUpdate: false,
identifier: "card", identifier: "card",
@ -214,7 +204,7 @@ export default Mixin.create({
}, },
}); });
} else { } else {
this._menuInstance = await this.menu.show(target[0], { this._menuInstance = await this.menu.show(target, {
content: this.element, content: this.element,
strategy: "fixed", strategy: "fixed",
identifier: "card", identifier: "card",
@ -243,10 +233,8 @@ export default Mixin.create({
@bind @bind
_hide() { _hide() {
if (!this.visible) { if (!this.visible && this.site.mobileView) {
if (this.site.mobileView) { document.querySelector(".card-cloak")?.classList.add("hidden");
$(".card-cloak").addClass("hidden");
}
} }
this._menuInstance?.destroy(); this._menuInstance?.destroy();
@ -280,11 +268,10 @@ export default Mixin.create({
_cardClickListenerSelectors.forEach((selector) => { _cardClickListenerSelectors.forEach((selector) => {
document document
.querySelector(selector) .querySelector(selector)
.removeEventListener("click", this.boundCardClickHandler); .removeEventListener("click", this._cardClickHandler);
}); });
const previewClickEvent = this.previewClickEvent; this.appEvents.off(this.previewClickEvent, this, "_previewClick");
this.appEvents.off(previewClickEvent, this, "_previewClick");
this.appEvents.off( this.appEvents.off(
`topic-header:trigger-${this.elementId}`, `topic-header:trigger-${this.elementId}`,
@ -317,7 +304,6 @@ export default Mixin.create({
if (this.visible && event.key === "Escape") { if (this.visible && event.key === "Escape") {
this.cardTarget?.focus(); this.cardTarget?.focus();
this._close(); this._close();
return;
} }
}, },
}); });