fix(feed): pin client highlights atop Industry News for 48h
This commit is contained in:
@@ -171,14 +171,18 @@ export default function ArticleFeed({ initialPosts = [] }: ArticleFeedProps) {
|
|||||||
return matchCat && matchSource && matchSearch && matchDate;
|
return matchCat && matchSource && matchSearch && matchDate;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Recent: strict publish-date order (newest first). Promoted badges stay
|
// Sort filtered articles based on sortOrder. For every order we honor
|
||||||
// on cards but never reorder the feed. Trending/commented keep promo tier.
|
// the promoted-tier hierarchy first (premium > advertiser > general) so
|
||||||
|
// client highlights stay atop Industry News for 48h, then sink by date.
|
||||||
function promotedTier(a: ArticleItem): number {
|
function promotedTier(a: ArticleItem): number {
|
||||||
if (a.promoted_kind === "premium") return 0;
|
if (a.promoted_kind === "premium") return 0;
|
||||||
if (a.promoted_kind === "client") return 1;
|
if (a.promoted_kind === "client") return 1;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
const sortedFiltered = [...filtered].sort((a, b) => {
|
const sortedFiltered = [...filtered].sort((a, b) => {
|
||||||
|
const ta = promotedTier(a);
|
||||||
|
const tb = promotedTier(b);
|
||||||
|
if (ta !== tb) return ta - tb;
|
||||||
if (sortOrder === "recent") {
|
if (sortOrder === "recent") {
|
||||||
const da = parseArticleDate(a.date);
|
const da = parseArticleDate(a.date);
|
||||||
const db = parseArticleDate(b.date);
|
const db = parseArticleDate(b.date);
|
||||||
@@ -187,9 +191,6 @@ export default function ArticleFeed({ initialPosts = [] }: ArticleFeedProps) {
|
|||||||
if (!db) return -1;
|
if (!db) return -1;
|
||||||
return db.getTime() - da.getTime();
|
return db.getTime() - da.getTime();
|
||||||
}
|
}
|
||||||
const ta = promotedTier(a);
|
|
||||||
const tb = promotedTier(b);
|
|
||||||
if (ta !== tb) return ta - tb;
|
|
||||||
if (sortOrder === "trending") {
|
if (sortOrder === "trending") {
|
||||||
// Trending: FEATURED category gets a boost, then by recency
|
// Trending: FEATURED category gets a boost, then by recency
|
||||||
const featuredBoost = (art: ArticleItem) => (art.category === "FEATURED" ? 2 : 0);
|
const featuredBoost = (art: ArticleItem) => (art.category === "FEATURED" ? 2 : 0);
|
||||||
|
|||||||
@@ -260,7 +260,23 @@ export async function decorateHomepageFeed<T extends PromotableArticle>(
|
|||||||
return { article: a, promoted_kind: null, promoted_until: null };
|
return { article: a, promoted_kind: null, promoted_until: null };
|
||||||
});
|
});
|
||||||
|
|
||||||
// Preserve caller order (wp_published_at desc). Promotion flags are visual
|
// Sort: premium first (by position asc), then client (by date desc), then general (by date desc)
|
||||||
// badges only — the Industry News feed stays newest-to-oldest.
|
function tier(d: DecoratedArticle<T>): number {
|
||||||
|
if (d.promoted_kind === "premium") return 0;
|
||||||
|
if (d.promoted_kind === "client") return 1;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
function dateTs(d: DecoratedArticle<T>): number {
|
||||||
|
const t = new Date(d.article.date).getTime();
|
||||||
|
return isNaN(t) ? 0 : t;
|
||||||
|
}
|
||||||
|
decorated.sort((a, b) => {
|
||||||
|
const ta = tier(a);
|
||||||
|
const tb = tier(b);
|
||||||
|
if (ta !== tb) return ta - tb;
|
||||||
|
if (ta === 0) return (a.promoted_position ?? 999) - (b.promoted_position ?? 999);
|
||||||
|
return dateTs(b) - dateTs(a); // newest first
|
||||||
|
});
|
||||||
|
|
||||||
return decorated;
|
return decorated;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user