Merge pull request #1371 from PR0M3TH3AN/codex/add-notificationcenter-component-with-filters

Add DM NotificationCenter with filters, grouping, and NotificationItem
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-01-18 23:53:59 -05:00
commit 474071e84a
3 files changed
+317 -24

No files matched your search

+1 -1
View File
@@ -11,4 +11,4 @@
--player-modal-primary-inline-padding-lg,clamp(var(--space-sm),2.75vw,var(--space-lg))
)}}.revert-modal__layout{display:grid;gap:1.5rem}@media (min-width:1024px){.revert-modal__layout{grid-template-columns:minmax(var(--revert-modal-sidebar-min),var(--revert-modal-sidebar-width)) minmax(0,1fr)}}#playerModal.video-modal__primary{display:block}.video-modal__primary{display:flex;flex-direction:column;gap:1.5rem;min-width:0;min-height:0}#playerModal.video-modal__secondary{display:block}.video-modal__secondary{display:flex;flex-direction:column;gap:1rem;min-width:0;min-height:0;width:100%;align-self:stretch}.video-modal__similar{display:none}@media (min-width:1024px){#playerModal.video-modal__similar{display:block}.video-modal__similar{display:flex;flex-direction:column;gap:1.5rem;align-self:stretch;flex:1 1 auto;min-height:0}#playerModal .video-modal__similar .player-modal__module{height:100%;display:flex;flex:1 1 auto;min-height:0;flex-direction:column}#playerModal .video-modal__similar .player-modal__module-list{flex:1 1 auto;min-height:0}#playerModal .video-modal__similar .player-modal__module-scroll{height:100%;max-height:none;min-height:0}}#playerModal .player-modal__module-item{width:100%}#playerModal#playerModal .player-modal__module-item>.card:not(.player-modal__similar-card){display:block}#playerModal .player-modal__module-item>.card:not(.player-modal__similar-card){display:flex;width:100%;flex-direction:row;flex-wrap:nowrap;align-items:stretch;gap:var(--space-md)}#playerModal#playerModal .player-modal__module-item>.\!card:not(.player-modal__similar-card){display:block}#playerModal .player-modal__module-item>.\!card:not(.player-modal__similar-card){display:flex;width:100%;flex-direction:row;flex-wrap:nowrap;align-items:stretch;gap:var(--space-md)}#playerModal .player-modal__module-item>.card:not(.player-modal__similar-card) .video-card__media{width:clamp(var(--video-modal-item-media-min),18vw,var(--video-modal-item-media-max))}#playerModal .player-modal__module-item>.\!card:not(.player-modal__similar-card) .video-card__media{width:clamp(var(--video-modal-item-media-min),18vw,var(--video-modal-item-media-max))!important}#playerModal .player-modal__module-item>.\!card:not(.player-modal__similar-card) .video-card__media,#playerModal .player-modal__module-item>.card:not(.player-modal__similar-card) .video-card__media{flex-shrink:0;overflow:hidden;border-radius:var(--radius-lg)}#playerModal .player-modal__module-item>.card:not(.player-modal__similar-card) .video-card__content{padding:clamp(var(--space-sm),1.25vw,var(--space-md))}#playerModal .player-modal__module-item>.\!card:not(.player-modal__similar-card) .video-card__content{padding:clamp(var(--space-sm),1.25vw,var(--space-md))!important}#playerModal#playerModal .player-modal__module-item>.card:not(.player-modal__similar-card) .video-card__content{display:block}#playerModal .player-modal__module-item>.card:not(.player-modal__similar-card) .video-card__content{display:flex;min-width:0;flex:1 1 0%;flex-direction:column;gap:var(--space-sm)}#playerModal#playerModal .player-modal__module-item>.\!card:not(.player-modal__similar-card) .video-card__content{display:block}#playerModal .player-modal__module-item>.\!card:not(.player-modal__similar-card) .video-card__content{display:flex;min-width:0;flex:1 1 0%;flex-direction:column;gap:var(--space-sm)}#playerModal#playerModal .player-modal__module-item>.card:not(.player-modal__similar-card) .video-card__meta{display:block}#playerModal .player-modal__module-item>.card:not(.player-modal__similar-card) .video-card__meta{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;font-size:var(--font-size-xs);line-height:var(--line-height-tight);color:var(--text-muted-strong)}#playerModal#playerModal .player-modal__module-item>.\!card:not(.player-modal__similar-card) .video-card__meta{display:block}#playerModal .player-modal__module-item>.\!card:not(.player-modal__similar-card) .video-card__meta{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;font-size:var(--font-size-xs);line-height:var(--line-height-tight);color:var(--text-muted-strong)}#playerModal .video-modal__similar .player-modal__module-list{gap:clamp(var(--space-2xs),.85vw,var(--space-sm))}.player-modal__similar-card{outline:2px solid transparent;outline-offset:2px}.player-modal__similar-card:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:0.7;--tw-ring-offset-width:2px;--tw-ring-offset-color:var(--surface-base);transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:var(--motion-duration-fast);transition-timing-function:cubic-bezier(0,0,.2,1);--tw-ring-color:var(--color-accent)}#playerModal.player-modal__similar-card{display:block}.player-modal__similar-card{position:relative;displayLine truncated
--motion-video-card-backdrop-translate
);--video-card-backdrop-scale:1.12;--video-card-backdrop-blur:var(--blur-video-card-backdrop-strong);--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.watch-history-card:focus-visible{border-color:var(--color-accent);--tw-border-opacity:0.4;--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.watch-history-card[data-state=critical]{border-width:1px;border-color:var(--color-critical);--tw-border-opacity:0.4;background-color:var(--surface-raised-critical)}.watch-history-card[data-state=private]{background-color:var(--surface-raised-private);--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg)}.watch-history-card[data-state=disabled],.watch-history-card[data-state=private]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.watch-history-card[data-state=disabled]{opacity:.6;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.watch-history-card[data-alert=nsfw-owner]{border-width:1px;border-color:var(--color-critical);--tw-border-opacity:0.4;background-color:var(--color-black)}.watch-history-card[data-alert=nsfw-owner]:hover{--tw-border-opacity:0.6;--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.watch-history-card img[data-thumbnail-state=blurred],.watch-history-card img[data-visual-state=blurred]{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-duration:.15s;transition-duration:var(--motion-duration-base);transition-timing-function:cubic-bezier(.4,0,.2,1);filter:blur(var(--blur-thumbnail-blur));transform:scale(1.05)}.watch-history-card[data-owner-is-viewer=true][data-url-health-state=offline][data-stream-health-state=unhealthy]{border-width:1px;border-color:var(--color-critical);--tw-border-opacity:0.4;background-color:var(--surface-raised-critical)}#playerModal#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card){display:block}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card){display:flex;width:100%;flex-direction:row;flex-wrap:nowrap;align-items:stretch;gap:var(--space-md)}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__media{width:clamp(var(--video-modal-item-media-min),18vw,var(--video-modal-item-media-max));flex-shrink:0;overflow:hidden;border-radius:var(--radius-lg)}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__content{padding:clamp(var(--space-sm),1.25vw,var(--space-md))}#playerModal#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__content{display:block}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__content{display:flex;min-width:0;flex:1 1 0%;flex-direction:column;gap:var(--space-sm)}#playerModal#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__meta{display:block}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__meta{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;font-size:var(--font-size-xs);line-height:var(--line-height-tight);color:var(--text-muted-strong)}.watch-history-card[data-motion=enter]{opacity:0;animation:card-motion-enter .22s ease-out forwards}#playerModal.watch-history-card{display:block}.watch-history-card{display:flex;flex-wrap:wrap;align-items:stretch;gap:1.25rem;padding:1rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:var(--motion-duration-base);transition-timing-function:cubic-bezier(0,0,.2,1)}@media (prefers-reduced-motion:reduce){.watch-history-card,.watch-history-card[data-motion=enter]{transition-property:none}.watch-history-card[data-motion=enter]{opacity:1;animation:none}}.watch-history-card:hover{--tw-translate-y:-0.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}@media (min-width:640px){.watch-history-card{gap:1.5rem;padding:1.25rem}}.watch-history-card--private{border-color:var(--color-info);--tw-border-opacity:0.6}#playerModal.watch-histoLine truncated
);--video-card-backdrop-scale:1.12;--video-card-backdrop-blur:var(--blur-video-card-backdrop-strong);--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.watch-history-card:focus-visible{border-color:var(--color-accent);--tw-border-opacity:0.4;--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.watch-history-card[data-state=critical]{border-width:1px;border-color:var(--color-critical);--tw-border-opacity:0.4;background-color:var(--surface-raised-critical)}.watch-history-card[data-state=private]{background-color:var(--surface-raised-private);--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg)}.watch-history-card[data-state=disabled],.watch-history-card[data-state=private]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.watch-history-card[data-state=disabled]{opacity:.6;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.watch-history-card[data-alert=nsfw-owner]{border-width:1px;border-color:var(--color-critical);--tw-border-opacity:0.4;background-color:var(--color-black)}.watch-history-card[data-alert=nsfw-owner]:hover{--tw-border-opacity:0.6;--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.watch-history-card img[data-thumbnail-state=blurred],.watch-history-card img[data-visual-state=blurred]{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-duration:.15s;transition-duration:var(--motion-duration-base);transition-timing-function:cubic-bezier(.4,0,.2,1);filter:blur(var(--blur-thumbnail-blur));transform:scale(1.05)}.watch-history-card[data-owner-is-viewer=true][data-url-health-state=offline][data-stream-health-state=unhealthy]{border-width:1px;border-color:var(--color-critical);--tw-border-opacity:0.4;background-color:var(--surface-raised-critical)}#playerModal#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card){display:block}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card){display:flex;width:100%;flex-direction:row;flex-wrap:nowrap;align-items:stretch;gap:var(--space-md)}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__media{width:clamp(var(--video-modal-item-media-min),18vw,var(--video-modal-item-media-max));flex-shrink:0;overflow:hidden;border-radius:var(--radius-lg)}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__content{padding:clamp(var(--space-sm),1.25vw,var(--space-md))}#playerModal#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__content{display:block}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__content{display:flex;min-width:0;flex:1 1 0%;flex-direction:column;gap:var(--space-sm)}#playerModal#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__meta{display:block}#playerModal .player-modal__module-item>.watch-history-card:not(.player-modal__similar-card) .video-card__meta{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;font-size:var(--font-size-xs);line-height:var(--line-height-tight);color:var(--text-muted-strong)}.watch-history-card[data-motion=enter]{opacity:0;animation:card-motion-enter .22s ease-out forwards}#playerModal.watch-history-card{display:block}.watch-history-card{display:flex;flex-wrap:wrap;align-items:stretch;gap:1.25rem;padding:1rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:var(--motion-duration-base);transition-timing-function:cubic-bezier(0,0,.2,1)}@media (prefers-reduced-motion:reduce){.watch-history-card,.watch-history-card[data-motion=enter]{transition-property:none}.watch-history-card[data-motion=enter]{opacity:1;animation:none}}.watch-history-card:hover{--tw-translate-y:-0.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-shadow:var(--shadow-lg);--tw-shadow-colored:var(--shadow-lg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}@media (min-width:640px){.watch-history-card{gap:1.5rem;padding:1.25rem}}.watch-history-card--private{border-color:var(--color-info);--tw-border-opacity:0.6}#playerModal.watch-histoLine truncated
+120 -6
View File
@@ -5271,6 +5271,66 @@
}
.dm-notification-center {
display: flex;
flex-direction: column;
gap: var(--space-sm);
}
.dm-notification-center__filters {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--space-xs);
}
.dm-notification-center__filter-button {
border-radius: var(--radius-full);
border: var(--border-width-hairline) solid var(--border-subtle);
background: var(--surface-sunken);
padding: var(--space-2xs) var(--space-sm);
font-size: var(--font-size-2xs);
font-weight: 600;
color: var(--text-muted);
transition: color var(--motion-duration-fast) var(--motion-ease-out),
background var(--motion-duration-fast) var(--motion-ease-out),
border-color var(--motion-duration-fast) var(--motion-ease-out);
}
.dm-notification-center__filter-button:hover,
.dm-notification-center__filter-button:focus-visible {
outline: none;
border-color: var(--border-strong);
background: var(--surface-raised);
color: var(--text-primary);
}
.dm-notification-center__filter-button--active {
border-color: var(--border-strong);
background: var(--surface-overlay-panel);
color: var(--text-primary);
}
.dm-notification-center__groups {
display: flex;
flex-direction: column;
gap: var(--space-md);
}
.dm-notification-center__group {
display: flex;
flex-direction: column;
gap: var(--space-xs);
}
.dm-notification-center__group-title {
font-size: var(--font-size-2xs);
font-weight: 600;
text-transform: uppercase;
letter-spacing: var(--tracking-wide);
color: var(--text-muted);
}
.dm-notification-center__list {
display: flex;
flex-direction: column;
gap: var(--space-xs);
@@ -5281,33 +5341,87 @@
color: var(--text-muted);
}
.dm-notification-center__item {
padding: var(--space-xs) var(--space-sm);
.dm-notification-item {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: var(--space-sm);
padding: var(--space-sm);
border-radius: var(--radius-md);
border: var(--border-width-hairline) solid var(--border-subtle);
background: var(--surface-sunken);
font-size: var(--font-size-xs);
text-align: left;
transition: border-color var(--motion-duration-fast) var(--motion-ease-out),
background var(--motion-duration-fast) var(--motion-ease-out);
}
.dm-notification-center__item--info {
.dm-notification-item:hover,
.dm-notification-item:focus-visible {
outline: none;
border-color: var(--border-strong);
background: var(--surface-raised);
}
.dm-notification-item__icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: var(--icon-size-md);
height: var(--icon-size-md);
border-radius: var(--radius-full);
background: var(--surface-overlay-panel-soft);
color: var(--text-muted);
font-size: var(--font-size-xs);
}
.dm-notification-item__body {
display: flex;
flex-direction: column;
gap: var(--space-2xs);
min-width: 0;
}
.dm-notification-item__title {
font-weight: 600;
color: var(--text-primary);
}
.dm-notification-item__message {
color: var(--text-muted);
}
.dm-notification-item__meta {
display: flex;
align-items: center;
gap: var(--space-2xs);
color: var(--text-muted);
}
.dm-notification-item__timestamp {
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.dm-notification-item--info {
background: var(--status-info-surface);
border-color: var(--status-info-border);
color: var(--status-info-on);
}
.dm-notification-center__item--success {
.dm-notification-item--success {
background: var(--status-success-surface);
border-color: var(--status-success-border);
color: var(--status-success-on);
}
.dm-notification-center__item--warning {
.dm-notification-item--warning {
background: var(--status-warning-surface);
border-color: var(--status-warning-border);
color: var(--status-warning-on);
}
.dm-notification-center__item--error {
.dm-notification-item--error {
background: var(--status-danger-surface);
border-color: var(--status-danger-border);
color: var(--status-danger-on);
+196 -17
View File
@@ -9,32 +9,211 @@ function createElement(doc, tag, className, text) {
return element;
}
export function NotificationCenter({ document: doc, notices = [] } = {}) {
const FILTERS = [
{ id: "all", label: "All" },
{ id: "dms", label: "DMs" },
{ id: "mentions", label: "Mentions" },
{ id: "zaps", label: "Zaps" },
];
const GROUPS = [
{ id: "unread", label: "Unread" },
{ id: "new", label: "New" },
];
const GROUP_EMPTY_COPY = {
unread: "No unread notifications.",
new: "No new notifications.",
};
function isElement(value) {
return Boolean(value && typeof value === "object" && value.nodeType === 1);
}
export function NotificationItem({ document: doc, notice = {}, onSelect } = {}) {
if (!doc) {
throw new Error("NotificationItem requires a document reference.");
}
const item = createElement(doc, "button", "dm-notification-item");
item.type = "button";
if (notice.variant) {
item.classList.add(`dm-notification-item--${notice.variant}`);
}
if (notice.id) {
item.dataset.noticeId = notice.id;
}
const iconSlot = createElement(doc, "span", "dm-notification-item__icon");
if (notice.icon) {
if (isElement(notice.icon)) {
iconSlot.appendChild(notice.icon);
} else if (typeof notice.icon === "string") {
iconSlot.textContent = notice.icon;
}
}
const body = createElement(doc, "div", "dm-notification-item__body");
if (notice.title) {
const title = createElement(
doc,
"div",
"dm-notification-item__title",
notice.title,
);
body.appendChild(title);
}
const message = createElement(
doc,
"div",
"dm-notification-item__message",
notice.message || "",
);
body.appendChild(message);
const meta = createElement(doc, "div", "dm-notification-item__meta");
const timestamp = createElement(
doc,
"time",
"dm-notification-item__timestamp",
notice.timestamp || "",
);
if (notice.timestampISO) {
timestamp.dateTime = notice.timestampISO;
}
meta.appendChild(timestamp);
item.appendChild(iconSlot);
item.appendChild(body);
item.appendChild(meta);
if (typeof onSelect === "function") {
item.addEventListener("click", () => {
onSelect(notice);
});
}
return item;
}
export function NotificationCenter({
document: doc,
notices = [],
activeFilter = "all",
onFilterSelect,
onNoticeSelect,
} = {}) {
if (!doc) {
throw new Error("NotificationCenter requires a document reference.");
}
const root = createElement(doc, "section", "dm-notification-center");
let currentFilter = activeFilter;
if (!notices.length) {
const placeholder = createElement(
const filterBar = createElement(doc, "div", "dm-notification-center__filters");
const filterButtons = new Map();
const updateFilterState = (nextFilter) => {
currentFilter = nextFilter;
filterButtons.forEach((button, filterId) => {
const isActive = filterId === currentFilter;
button.classList.toggle("dm-notification-center__filter-button--active", isActive);
button.setAttribute("aria-pressed", isActive ? "true" : "false");
});
renderGroups();
};
FILTERS.forEach((filter) => {
const button = createElement(
doc,
"div",
"dm-notification-center__empty",
"You're all caught up.",
"button",
"dm-notification-center__filter-button",
filter.label,
);
root.appendChild(placeholder);
return root;
}
notices.forEach((notice) => {
const item = createElement(doc, "div", "dm-notification-center__item");
if (notice.variant) {
item.classList.add(`dm-notification-center__item--${notice.variant}`);
}
item.textContent = notice.message || "";
root.appendChild(item);
button.type = "button";
button.dataset.filterId = filter.id;
button.setAttribute("aria-pressed", "false");
button.addEventListener("click", () => {
if (filter.id === currentFilter) {
return;
}
updateFilterState(filter.id);
if (typeof onFilterSelect === "function") {
onFilterSelect(filter.id);
}
});
filterButtons.set(filter.id, button);
filterBar.appendChild(button);
});
const groupsContainer = createElement(doc, "div", "dm-notification-center__groups");
const getFilteredNotices = () => {
if (currentFilter === "all") {
return notices;
}
return notices.filter((notice) => notice.type === currentFilter);
};
const renderGroups = () => {
groupsContainer.innerHTML = "";
const filteredNotices = getFilteredNotices();
const groupMap = new Map();
filteredNotices.forEach((notice) => {
const groupId = notice.group || "new";
if (!groupMap.has(groupId)) {
groupMap.set(groupId, []);
}
groupMap.get(groupId).push(notice);
});
GROUPS.forEach((group) => {
const groupSection = createElement(
doc,
"section",
"dm-notification-center__group",
);
const title = createElement(
doc,
"div",
"dm-notification-center__group-title",
group.label,
);
const list = createElement(doc, "div", "dm-notification-center__list");
const groupNotices = groupMap.get(group.id) || [];
if (!groupNotices.length) {
list.appendChild(
createElement(
doc,
"div",
"dm-notification-center__empty",
GROUP_EMPTY_COPY[group.id] || "No notifications.",
),
);
} else {
groupNotices.forEach((notice) => {
list.appendChild(
NotificationItem({
document: doc,
notice,
onSelect: onNoticeSelect,
}),
);
});
}
groupSection.appendChild(title);
groupSection.appendChild(list);
groupsContainer.appendChild(groupSection);
});
};
root.appendChild(filterBar);
root.appendChild(groupsContainer);
updateFilterState(currentFilter);
return root;
}