Group filtered carousel items

This commit is contained in:
Lim Chee Aun 2024-07-22 14:31:52 +08:00
parent 84b3106f50
commit 4c0bc62ad0
2 changed files with 72 additions and 2 deletions

View file

@ -1113,6 +1113,15 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
padding: 6px; padding: 6px;
} }
.status-carousel.boosts-carousel .timeline-item-carousel-group {
flex-direction: column;
gap: 8px;
&:before {
content: '';
}
}
.ui-state { .ui-state {
padding: 16px; padding: 16px;
text-align: center; text-align: center;

View file

@ -572,7 +572,7 @@ const TimelineItem = memo(
: `/s/${actualStatusID}`; : `/s/${actualStatusID}`;
if (items) { if (items) {
const fItems = filteredItems(items, filterContext); let fItems = filteredItems(items, filterContext);
let title = ''; let title = '';
if (type === 'boosts') { if (type === 'boosts') {
title = `${fItems.length} Boosts`; title = `${fItems.length} Boosts`;
@ -581,6 +581,7 @@ const TimelineItem = memo(
} }
const isCarousel = type === 'boosts' || type === 'pinned'; const isCarousel = type === 'boosts' || type === 'pinned';
if (isCarousel) { if (isCarousel) {
const filteredItemsIDs = new Set();
// Here, we don't hide filtered posts, but we sort them last // Here, we don't hide filtered posts, but we sort them last
fItems.sort((a, b) => { fItems.sort((a, b) => {
// if (a._filtered && !b._filtered) { // if (a._filtered && !b._filtered) {
@ -591,6 +592,8 @@ const TimelineItem = memo(
// } // }
const aFiltered = isFiltered(a.filtered, filterContext); const aFiltered = isFiltered(a.filtered, filterContext);
const bFiltered = isFiltered(b.filtered, filterContext); const bFiltered = isFiltered(b.filtered, filterContext);
if (aFiltered) filteredItemsIDs.add(a.id);
if (bFiltered) filteredItemsIDs.add(b.id);
if (aFiltered && !bFiltered) { if (aFiltered && !bFiltered) {
return 1; return 1;
} }
@ -599,11 +602,69 @@ const TimelineItem = memo(
} }
return 0; return 0;
}); });
if (filteredItemsIDs.size >= 2) {
const GROUP_SIZE = 5;
// If 2 or more, group filtered items into one, limit to GROUP_SIZE in a group
const unfiltered = [];
const filtered = [];
fItems.forEach((item) => {
if (filteredItemsIDs.has(item.id)) {
filtered.push(item);
} else {
unfiltered.push(item);
}
});
const filteredItems = [];
for (let i = 0; i < filtered.length; i += GROUP_SIZE) {
filteredItems.push({
_grouped: true,
posts: filtered.slice(i, i + GROUP_SIZE),
});
}
fItems = unfiltered.concat(filteredItems);
}
return ( return (
<li key={`timeline-${statusID}`} class="timeline-item-carousel"> <li key={`timeline-${statusID}`} class="timeline-item-carousel">
<StatusCarousel title={title} class={`${type}-carousel`}> <StatusCarousel title={title} class={`${type}-carousel`}>
{fItems.map((item) => { {fItems.map((item) => {
const { id: statusID, reblog, _pinned } = item; const { id: statusID, reblog, _pinned, _grouped } = item;
if (_grouped) {
return (
<li key={statusID} class="timeline-item-carousel-group">
{item.posts.map((item) => {
const { id: statusID, reblog, _pinned } = item;
const actualStatusID = reblog?.id || statusID;
const url = instance
? `/${instance}/s/${actualStatusID}`
: `/s/${actualStatusID}`;
if (_pinned) useItemID = false;
return (
<Link
class="status-carousel-link timeline-item-alt"
to={url}
>
{useItemID ? (
<Status
statusID={statusID}
instance={instance}
size="s"
/>
) : (
<Status
status={item}
instance={instance}
size="s"
/>
)}
</Link>
);
})}
</li>
);
}
const actualStatusID = reblog?.id || statusID; const actualStatusID = reblog?.id || statusID;
const url = instance const url = instance
? `/${instance}/s/${actualStatusID}` ? `/${instance}/s/${actualStatusID}`