feeds: "Most Zapped" sidebar tab ranked by zap totals (#47)

Trending-pattern clone ranked by sats from kind-9735 receipts:

- js/zapTotals.js: per-pointer receipt aggregation. The feed's metric getter
  returns the cached total and schedules a batched fetch (#a/#e chunks via
  the L1 SubscriptionManager) for unknown/stale pointers; amounts parse via
  nip57 bolt11 with the zap request's amount tag as fallback; receipts are
  deduped by id so re-fetches never double-count; zero-receipt answers are
  cached (2-min TTL).
- sorters.js: shared count-ranked sorter (metric desc, recency tie-break,
  author spread, trusted-muted sink); Trending delegates unchanged, Most
  Zapped ranks on runtime.getZapTotal.
- Full wiring: feed definition, view + info popover, change-signal re-rank
  (order settles as receipts stream in), sidebar link, viewManager registry,
  feedCoordinator case/loader, FEED_TYPES.MOST_ZAPPED, and a
  FEATURE_MOST_ZAPPED_FEED flag (default on; off hides the tab).

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Fable 5 committed 2026-07-03 21:38:53 -04:00
1 parent 35a50611fe
commit 8dfd2034b0
13 files changed
+815 -20

No files matched your search

+18 -1
View File
@@ -24,7 +24,12 @@ import r2Service from "../services/r2Service.js";
import s3UploadService from "../services/s3UploadService.js";
import RelayHealthService from "../services/relayHealthService.js";
import { createFeedEngine } from "../feedEngine/index.js";
import { URL_FIRST_ENABLED, SHORT_TIMEOUT_MS, FEATURE_TRENDING_FEED } from "../constants.js";
import {
URL_FIRST_ENABLED,
SHORT_TIMEOUT_MS,
FEATURE_TRENDING_FEED,
FEATURE_MOST_ZAPPED_FEED,
} from "../constants.js";
import { ALLOW_NSFW_CONTENT } from "../config.js";
import { relayManager } from "../relayManager.js";
import { userBlocks } from "../userBlocks.js";
@@ -284,6 +289,18 @@ export default class ApplicationBootstrap {
trendingLink.classList.add("hidden");
}
}
if (
FEATURE_MOST_ZAPPED_FEED &&
typeof app.registerMostZappedFeed === "function"
) {
app.registerMostZappedFeed();
} else if (typeof document !== "undefined") {
// Flag off: hide the always-visible Most Zapped sidebar link.
const mostZappedLink = document.getElementById("mostZappedLink");
if (mostZappedLink) {
mostZappedLink.classList.add("hidden");
}
}
app.registerSubscriptionsFeed();
app.registerWatchHistoryFeed();
// Re-run the For You feed when background watch-history resolution completes.