Skip to content

Commit a844b23

Browse files
authored
fix: actually sort layouts by collection order (#3526)
1 parent 4bf0a0c commit a844b23

1 file changed

Lines changed: 59 additions & 13 deletions

File tree

server/utils/layouts/layoutPubs.ts

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,47 @@ const getPublishDate = (pub: PubWithMetadata): Date | null => {
8686
return pub.customPublishedAt || pub.firstReleaseDate || null;
8787
};
8888

89+
const getLowestRelevantCollectionRank = (
90+
pub: PubWithMetadata,
91+
collectionIdsSet: Set<string> | null,
92+
): string | null => {
93+
let lowestRank: string | null = null;
94+
95+
for (const collectionPub of pub.collectionPubs) {
96+
if (collectionIdsSet && !collectionIdsSet.has(collectionPub.collectionId)) {
97+
continue;
98+
}
99+
100+
const rank = collectionPub.rank || '';
101+
if (lowestRank === null || rank.localeCompare(lowestRank) < 0) {
102+
lowestRank = rank;
103+
}
104+
}
105+
106+
return lowestRank;
107+
};
108+
109+
const compareCollectionRanks = (
110+
aRank: string | null,
111+
bRank: string | null,
112+
direction: PubsQueryOrdering['direction'],
113+
): number => {
114+
if (aRank === null && bRank === null) {
115+
return 0;
116+
}
117+
118+
if (aRank === null) {
119+
return direction === 'ASC' ? 1 : -1;
120+
}
121+
122+
if (bRank === null) {
123+
return direction === 'ASC' ? -1 : 1;
124+
}
125+
126+
const rankComparison = aRank.localeCompare(bRank);
127+
return direction === 'ASC' ? rankComparison : rankComparison * -1;
128+
};
129+
89130
const filterPubsByCollection = (
90131
pubs: PubWithMetadata[],
91132
collectionIds: string[],
@@ -117,23 +158,28 @@ const sortPubs = (
117158
const sorted = [...pubs];
118159
const ordering = getQueryOrdering(sort);
119160

161+
if (ordering.field === 'collectionRank') {
162+
const collectionIdsSet = collectionIds.length > 0 ? new Set(collectionIds) : null;
163+
const lowestRankByPubId = new Map(
164+
sorted.map((pub) => [pub.id, getLowestRelevantCollectionRank(pub, collectionIdsSet)]),
165+
);
166+
167+
sorted.sort((a, b) =>
168+
compareCollectionRanks(
169+
lowestRankByPubId.get(a.id) ?? null,
170+
lowestRankByPubId.get(b.id) ?? null,
171+
ordering.direction,
172+
),
173+
);
174+
175+
return sorted;
176+
}
177+
120178
sorted.sort((a, b) => {
121179
let aValue: number | null = null;
122180
let bValue: number | null = null;
123181

124-
if (ordering.field === 'collectionRank') {
125-
const getMinRank = (pub: PubWithMetadata) => {
126-
const relevantRanks = pub.collectionPubs
127-
.filter(
128-
(cp) =>
129-
collectionIds.length === 0 || collectionIds.includes(cp.collectionId),
130-
)
131-
.map((cp) => parseFloat(cp.rank));
132-
return relevantRanks.length > 0 ? Math.min(...relevantRanks) : Number.MAX_VALUE;
133-
};
134-
aValue = getMinRank(a);
135-
bValue = getMinRank(b);
136-
} else if (ordering.field === 'creationDate') {
182+
if (ordering.field === 'creationDate') {
137183
aValue = a.createdAt.getTime();
138184
bValue = b.createdAt.getTime();
139185
} else if (ordering.field === 'publishDate') {

0 commit comments

Comments
 (0)