Order the latest-reviews strip by created_at alone. #9
+16
-28
@@ -55,19 +55,6 @@ export interface BuildReview {
|
|||||||
* characters or matching a common test string do not qualify. They still appear in
|
* 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.
|
* 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([
|
const TEST_STRINGS = new Set([
|
||||||
'test', 'testing', 'test test', 'hello', 'hi', 'ok', 'okay', 'good', 'nice',
|
'test', 'testing', 'test test', 'hello', 'hi', 'ok', 'okay', 'good', 'nice',
|
||||||
'great', 'cool', 'gm', 'a', '.', '..', '...', 'asdf', 'qwerty', '123',
|
'great', 'cool', 'gm', 'a', '.', '..', '...', 'asdf', 'qwerty', '123',
|
||||||
@@ -227,29 +214,30 @@ export async function fetchLatestReviews(
|
|||||||
profile: null,
|
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));
|
const profiles = await fetchProfiles(candidates.map((c) => c.pubkey));
|
||||||
for (const review of candidates) review.profile = profiles.get(review.pubkey) ?? null;
|
for (const review of candidates) review.profile = profiles.get(review.pubkey) ?? null;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recent reviews with a named author come first; everything else stays newest
|
* Strict recency, newest first, as the last thing that happens to this list.
|
||||||
* first behind them.
|
|
||||||
*
|
*
|
||||||
* Most review keys have published exactly one event in their life: the review
|
* The heading says "Latest reviews", so the order under it is the event
|
||||||
* itself. Nothing can be fetched for them, so a strict recency order fills this
|
* `created_at` and nothing else. This used to float reviews whose author had a
|
||||||
* strip with anonymous npubs while a named review sits a few rows below the
|
* kind 0 to the front, which read as broken on the page: a named review from two
|
||||||
* cut. This is the home page shop window, which already drops junk bodies, so
|
* months ago sat between two reviews from this week, and the card feet said so,
|
||||||
* it prefers a review a reader can attach a person to. Nothing is hidden:
|
* because the "2mo ago" label is formatted from the very same `created_at` this
|
||||||
* every review is on its mint page, and PROMOTE_MAX_AGE_S keeps "latest"
|
* sorts on. Author names are still resolved and still shown — they just no longer
|
||||||
* meaning latest.
|
* 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;
|
candidates.sort((a, b) => b.created_at - a.created_at || a.id.localeCompare(b.id));
|
||||||
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);
|
|
||||||
|
|
||||||
return candidates.slice(0, limit);
|
return candidates.slice(0, limit);
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
Reference in New Issue
Block a user