مرحباً @digitaldominica! أعتذر لعدم تفقد الموضوع منذ فترة حيث أنني بصدد طرح التحديث القادم قريباً. لدى الجميع ملاحظات قيمة، ولكن إذا لم أنظر بعيداً، فسأميل إلى إضافتها إلى قائمتي الحالية بدلاً من حفظها للتحديث الذي يليه. ![]()
@Arkshine على حق. إنها طريقة ملتوية تعمل ضمن قيود السمة (الكثير من Central هو مجرد نماذج أولية حيث أنني مصمم أولاً وثانياً وثالثاً، ومطور رابعاً).
سأقدم دليلاً خطوة بخطوة حول كيفية تحقيق النموذج الأولي التقريبي في Central. ولكن تنويه، قد لا يكون هذا الحل مستقبلاً إذا قمنا بتحديث أساسي لقائمة المستخدم، وقد تكون هناك طريقة أفضل لإنشاء المكون.
الخطوة 1: إنشاء مكون قائمة مستخدم مخصص
قم بإنشاء هذه الملفات -
/javascripts/discourse/components/header-user-new.js
/javascripts/discourse/components/header-user-new.hbs
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
export default class HeaderUserNew extends Component {
@service currentUser;
@tracked isActive = false;
constructor() {
super(...arguments);
this.handleDocumentClick = this.handleDocumentClick.bind(this);
}
@action
toggleDropdown() {
this.isActive = !this.isActive;
if (this.isActive) {
setTimeout(() => {
document.addEventListener("click", this.handleDocumentClick);
}, 0);
} else {
document.removeEventListener("click", this.handleDocumentClick);
}
}
handleDocumentClick(event) {
const dropdown = document.querySelector(".header-user-new__menu");
const isClickInside = dropdown.contains(event.target);
if (!isClickInside) {
this.isActive = false;
document.removeEventListener("click", this.handleDocumentClick);
}
}
willDestroy() {
super.willDestroy();
document.removeEventListener("click", this.handleDocumentClick);
}
}
<div class={{concatClass "header-user-new" (if isActive "active")}}>
<button class="header-user-new__button" type="button" {{on "click" this.toggleDropdown}}>
{{avatar currentUser}}
</button>
<div class="header-user-new__menu">
<LinkTo class="header-user-new__profile" @route="user.summary" @model={{this.currentUser}}>
{{avatar currentUser}}
<div class="header-user-new__profile-info">
<span class="header-user-new__profile-name">
{{#if currentUser.name}}
{{currentUser.name}}
{{else}}
{{currentUser.username}}
{{/if}}
</span>
<span class="header-user-new__profile-view">
View Profile
</span>
</div>
</LinkTo>
<ul>
<li>
<LinkTo @route="userActivity.bookmarks" @model={{this.currentUser}}>
{{d-icon "bookmark"}}
<span>
{{i18n "js.user.bookmarks"}}
</span>
</LinkTo>
</li>
<li>
<LinkTo @route="preferences" @model={{this.currentUser}}>
{{d-icon "cog"}}
<span>
{{i18n "user.preferences"}}
</span>
</LinkTo>
</li>
<li>
<DButton @action={{route-action "logout"}}>
{{d-icon "sign-out-alt"}}
<span>
{{i18n "user.log_out"}}
</span>
</DButton>
</li>
</ul>
</div>
</div>
حتى الآن، سأترك التصميم باستخدام CSS لك، ولكن من المهم تضمين هذه الجزئية لتأثير التبديل -
.header-user-new {
&.active {
.header-user-new__menu {
display: flex;
}
}
.header-user-new__menu {
display: none;
}
}
الخطوة 2: تسجيل المكون كـ widget
قم بإنشاء هذا الملف -
/javascripts/discourse/widgets/header-user-new.js
import { hbs } from "ember-cli-htmlbars";
import RenderGlimmer from "discourse/widgets/render-glimmer";
import { createWidget } from "discourse/widgets/widget";
export default createWidget("header-user-new", {
tagName: "li.header-dropdown-toggle.header-user-new",
html() {
return [new RenderGlimmer(this, "div", hbs`<HeaderUserNew />`)];
},
});
الخطوة 3: إضافة الـ widget إلى الرأس، استبدال أيقونة المستخدم الحالية بأيقونة جرس الإشعارات
قم بإنشاء هذا الملف -
/javascripts/discourse/initializers/header-edit.js
import { h } from "virtual-dom";
import { withPluginApi } from "discourse/lib/plugin-api";
import { iconNode } from "discourse-common/lib/icon-library";
import I18n from "discourse-i18n";
export default {
initialize() {
withPluginApi("0.8", (api) => {
api.reopenWidget("header-notifications", {
html(attrs) {
const { user } = attrs;
let avatarAttrs = {
template: user.get("avatar_template"),
username: user.get("username"),
};
if (this.siteSettings.enable_names) {
avatarAttrs.name = user.get("name");
}
const contents = [h("div", iconNode("bell"))];
if (this.currentUser.status) {
contents.push(this.attach("user-status-bubble", this.currentUser.status));
}
if (user.isInDoNotDisturb()) {
contents.push(h("div.do-not-disturb-background", iconNode("moon")));
} else {
if (user.new_personal_messages_notifications_count) {
contents.push(
this.attach("link", {
action: attrs.action,
className: "badge-notification with-icon new-pms",
icon: "envelope",
omitSpan: true,
title: "notifications.tooltip.new_message_notification",
titleOptions: {
count: user.new_personal_messages_notifications_count,
},
attributes: {
"aria-label": I18n.t(
"notifications.tooltip.new_message_notification",
{
count: user.new_personal_messages_notifications_count,
}
),
},
})
);
} else if (user.unseen_reviewable_count) {
contents.push(
this.attach("link", {
action: attrs.action,
className: "badge-notification with-icon new-reviewables",
icon: "flag",
omitSpan: true,
title: "notifications.tooltip.new_reviewable",
titleOptions: { count: user.unseen_reviewable_count },
attributes: {
"aria-label": I18n.t(
"notifications.tooltip.new_reviewable",
{
count: user.unseen_reviewable_count,
}
),
},
})
);
} else if (user.all_unread_notifications_count) {
contents.push(
this.attach("link", {
action: attrs.action,
className: "badge-notification unread-notifications",
rawLabel: user.all_unread_notifications_count,
omitSpan: true,
title: "notifications.tooltip.regular",
titleOptions: { count: user.all_unread_notifications_count },
attributes: {
"aria-label": I18n.t("user.notifications"),
},
})
);
}
}
return contents;
},
});
const currentUser = api.container.lookup("service:current-user");
if (currentUser !== null) {
api.addToHeaderIcons("header-user-new");
}
});
},
};
التغيير الرئيسي كان استبدال avatarImg(…) بـ iconNode لاستخدام أيقونة الإشعارات بدلاً من صورة المستخدم عن طريق تعديل (أو “إعادة فتح”) الـ widget الحالي header-notifications.
كما ذكر @Arkshine، قمت بإخفاء قسم المستخدم في قائمة الإشعارات باستخدام CSS.
.d-header .panel {
.user-menu.revamped .bottom-tabs, #user-menu-button-profile {
display: none;
}
}