위에서 사용한 unboundClassNames() 메서드는 컴포넌트 요소에 추가되는 클래스를 담당합니다. 즉, .topic-list-item 또는 .latest-topic-list-item HTML 요소를 의미합니다. 이는 여기에서
discourse/app/assets/javascripts/discourse/app/components/topic-list-item.js at ad4faf637c9caf7e6ac60a614e3838a69c928e27 · discourse/discourse · GitHub
그리고 여기에서 확인할 수 있습니다.
discourse/app/assets/javascripts/discourse/app/components/latest-topic-list-item.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub
Ember는 해당 메서드가 반환하는 문자열을 가져와 요소 자체의 class 속성으로 추가합니다.
해당 요소의 자식 요소에 클래스를 추가하려면 다른 방법을 사용해야 합니다.
posters 속성의 각 포스터는 extras라는 속성을 가지고 있습니다. 이 속성은 렌더링될 때 아바타에 추가될 클래스를 위한 플래그로 사용됩니다.
여기에서 설정되며
discourse/app/assets/javascripts/discourse/app/models/topic-list.js at d3a59e3f695c467c22d02db62532194e17ac827b · discourse/discourse · GitHub
여기에서 소비됩니다.
discourse/app/assets/javascripts/discourse/app/templates/list/posters-column.hbr at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub
따라서 해당 속성을 확장하면 조건에 따라 토픽 목록의 아바타에 클래스를 추가할 수 있습니다.
컴포넌트가 속성을 받을 때 메서드를 호출하여 이를 수행하려면 @on 데코레이터를 사용할 수 있습니다. 이미 해당 컴포넌트 클래스를 수정하고 있으므로, 위 코드에 이 새로운 동작을 통합할 수 있습니다.
최종적으로 다음과 같은 코드가 됩니다.
인셜라이저(initializer)에서
import { apiInitializer } from "discourse/lib/api";
import discourseComputed, { on } from "discourse-common/utils/decorators";
export default apiInitializer("0.11.1", (api) => {
const PLUGIN_ID = "hide-ignored-op-topics";
const IGNORED_TOPIC_CLASS_STRING = " ignored-op-topic";
const IGNORED_AVATAR_CLASS_STRING = " ignored-user-avatar";
const user = api.getCurrentUser();
if (!user) {
return;
}
const ignoredUsers = user.ignored_users;
function isIgnoredUser(poster) {
return ignoredUsers.includes(poster.user.username);
}
function addIgnoredTopicClass() {
let classList = this._super(...arguments);
const topicCreator = this.topic.posters[0];
if (isIgnoredUser(topicCreator)) {
classList += IGNORED_TOPIC_CLASS_STRING;
}
return classList;
}
function addIgnoredAvatarClass() {
this.topic.posters.forEach((poster) => {
if (isIgnoredUser(poster)) {
// default raw topic-lists
poster.extras += IGNORED_AVATAR_CLASS_STRING;
// categories page topic lists
poster.user.set("extras", IGNORED_AVATAR_CLASS_STRING);
}
});
}
api.modifyClass("component:topic-list-item", {
pluginId: PLUGIN_ID,
@discourseComputed()
unboundClassNames() {
return addIgnoredTopicClass.call(this);
},
@on("didReceiveAttrs")
ignoredAvatarClass() {
addIgnoredAvatarClass.call(this);
},
});
api.modifyClass("component:latest-topic-list-item", {
pluginId: PLUGIN_ID,
@discourseComputed()
unboundClassNames() {
return addIgnoredTopicClass.call(this);
},
@on("didReceiveAttrs")
ignoredAvatarClass() {
addIgnoredAvatarClass.call(this);
},
});
});
이것은 무시된 사용자가 시작한 토픽 목록 항목에 ignored-op-topic CSS 클래스를, 포스터 컬럼의 모든 무시된 사용자 아바타에 ignored-user-avatar CSS 클래스를 부여해야 합니다.
.ignored-op-topic에 대한 CSS는 위에서 이미 가지고 있습니다.
// load-more 동작을 방해하지 않으므로 display: none;을 여기서는 사용하지 않습니다.
.ignored-op-topic {
height: 0;
width: 0;
position: fixed;
bottom: 0;
}
이제 포스터 컬럼에서 무시된 사용자의 아바타를 숨기고 싶습니다.
그렇게 하지 마세요. 이는 많은 혼란을 초래할 것입니다.
무시된 사용자가 토픽에 답글을 작성하여 토픽이 위로 올라오(bump)는데, 아바타가 숨겨져 있다면 어떻게 될까요? 다른 누군가가 방금 토픽을 위로 올린 것처럼 보일 것입니다.
또한 카테고리 페이지의 토픽 제목 옆에는 아바타가 하나만 있습니다. 마지막 답글을 무시된 사용자가 작성한 경우 어떻게 될까요? 아바타가 없게 되나요?
이러한 사례들이 사용자에게 불쾌한 경험을 초래할 수 있음을 알 수 있습니다.
무시된 사용자의 아바타를 숨기는 대신, SVG 아이콘으로 교체할 수 있습니다. 모든 무시된 사용자는 동일한 아바타를 가지게 됩니다. CSS로 이를 수행할 수 있습니다.
.ignored-user-avatar {
background: white;
border: 1px solid transparent;
box-sizing: border-box;
opacity: 0.5;
content: svg-uri(
'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m256 0c141.385 0 256 114.615 256 256s-114.615 256-256 256-256-114.615-256-256 114.615-256 256-256zm0 105c-83.262 0-151 67.74-151 151s67.737 151 151 151 151-67.736 151-151-67.74-151-151-151zm-52.816 130.621a22.119 22.119 0 1 0 0-44.237 22.119 22.119 0 0 0 0 44.237zm127.749-22.121a22.116 22.116 0 0 0 -22.12-22.12 22.119 22.119 0 1 0 22.12 22.12zm-40.233 70.79a9.439 9.439 0 0 0 -13.35-13.347l-21.35 21.357-21.352-21.357a9.438 9.438 0 1 0 -13.348 13.347l21.352 21.352-21.352 21.358a9.438 9.438 0 1 0 13.347 13.347l21.353-21.355 21.351 21.351a9.439 9.439 0 0 0 13.349-13.343l-21.352-21.354z"/></svg>'
);
}
그리고 다음과 같이 렌더링됩니다.
latest-topic-list-item에서도 동일합니다. 원하는 아이콘으로 SVG를 변경하세요.
이 문제를 해결했으니…
질문에 답한 이유는 토픽 목록을 커스터마이징하는 방법과 이를 어떻게 수행하는지에 대해 이야기할 좋은 기회이기 때문입니다. 그러나 사용 사례에 대해 많은 우려가 있습니다. 무시된 사용자의 아바타를 숨길 필요가 있다는 것은 근본적인 문제가 있음을 시사합니다.
“이 사람은 내가 관심 없는 주제에 대해 글을 씁니다. 노이즈를 줄이기 위해 이 사람을 무시하겠습니다.”
라고 말하는 것과
“이 사람의 아바타를 보는 것만으로도 감정적 반응을 일으킵니다. 다시는 이 사람의 아바타를 보고 싶지 않습니다.”
라고 말하는 것은 전혀 다른 문제입니다.
당신은 누구보다 커뮤니티를 잘 알고 있지만… 아마도 살펴볼 가치가 있는 문제일 것입니다.