Order the latest-reviews strip by created_at alone. #9

Merged
Michilis merged 1 commits from dev into main 2026-08-25 15:45:41 +00:00
Showing only changes of commit 1eade490c8 - Show all commits
+16 -28
View File
@@ -55,19 +55,6 @@ export interface BuildReview {
* characters or matching a common test string do not qualify. They still appear in
* full on the mint page, nothing is hidden, this strip is just a shop window.
*/
/** How many candidates to gather per card shown, so the ordering has a real choice. */
const POOL_FACTOR = 12;
/**
* How recent a review must still be to be promoted for having a named author.
*
* The ordering below prefers reviews whose author has a kind 0, and this is the leash
* on that preference. Without it the strip would headline a named review from two
* years ago under a heading that says "Latest reviews"; with it, a named review from
* within the season can lead and anything older cannot.
*/
const PROMOTE_MAX_AGE_S = 90 * 24 * 60 * 60;
const TEST_STRINGS = new Set([
'test', 'testing', 'test test', 'hello', 'hi', 'ok', 'okay', 'good', 'nice',
'great', 'cool', 'gm', 'a', '.', '..', '...', 'asdf', 'qwerty', '123',
@@ -227,29 +214,30 @@ export async function fetchLatestReviews(
profile: null,
});
if (candidates.length >= limit * POOL_FACTOR) break;
// The scan runs newest first, so the first `limit` survivors are the latest
// `limit` reviews. Nothing further down the list can outrank them.
if (candidates.length >= limit) break;
}
const profiles = await fetchProfiles(candidates.map((c) => c.pubkey));
for (const review of candidates) review.profile = profiles.get(review.pubkey) ?? null;
/*
* Recent reviews with a named author come first; everything else stays newest
* first behind them.
* Strict recency, newest first, as the last thing that happens to this list.
*
* Most review keys have published exactly one event in their life: the review
* itself. Nothing can be fetched for them, so a strict recency order fills this
* strip with anonymous npubs while a named review sits a few rows below the
* cut. This is the home page shop window, which already drops junk bodies, so
* it prefers a review a reader can attach a person to. Nothing is hidden:
* every review is on its mint page, and PROMOTE_MAX_AGE_S keeps "latest"
* meaning latest.
* The heading says "Latest reviews", so the order under it is the event
* `created_at` and nothing else. This used to float reviews whose author had a
* kind 0 to the front, which read as broken on the page: a named review from two
* months ago sat between two reviews from this week, and the card feet said so,
* because the "2mo ago" label is formatted from the very same `created_at` this
* sorts on. Author names are still resolved and still shown — they just no longer
* decide the order.
*
* Sorted here rather than left to the scan above, so that the invariant holds
* whatever the gathering loop does later, and `id` breaks ties between two events
* that share a second so two builds of the same events agree.
*/
const cutoff = Math.floor(Date.now() / 1000) - PROMOTE_MAX_AGE_S;
const promoted = (review: BuildReview): number =>
review.profile?.found && review.created_at >= cutoff ? 1 : 0;
candidates.sort((a, b) => promoted(b) - promoted(a) || b.created_at - a.created_at);
candidates.sort((a, b) => b.created_at - a.created_at || a.id.localeCompare(b.id));
return candidates.slice(0, limit);
} catch {