Show mod downloads and release dates in the launcher MODS and Find Mods panels (#793)

* Resolve Find Mods stats from each mod's GitHub repo when the feed lacks them

A FIND MODS row now shows download/date stats even when its feed publishes
none: the row fetches the mod's own GitHub releases through the same
cached ModUpdate.fetchReleases the MODS tab uses (six-hour options cache,
so an installed mod's repo is instant). Feed-published stats still win
when present; otherwise one repo is fetched per frame -- the thumbnail
budget pattern -- so opening the tab never stalls for the whole listing.
ModUpdate.statsForReleases is the shared resolver.

* Fix crash opening the Find Mods tab: rename the stats cache field

The resolver stored results in self._findStats, which collides with the
method of the same name: self._findStats resolves through the metatable to
the function, so the or {} guard never fired and indexing it crashed the
launcher the moment the panel built. State now lives in _findStatsCache.

* Fix Find Mods crash: require ModUpdate in the find panel

buildFindPanel called ModUpdate.statsLine without a local require --
only buildModsPanel had one -- so opening the tab indexed a nil global.

* Retry Find Mods stats after failed repo fetches

A failed repo fetch (hourly GitHub API rate limit, transient network error)
was memoized as resolved, so a rate-limited first visit left those rows
empty for the whole session. Failures now schedule a 60s retry; a 404 is
still permanent so a renamed or vanished repo is fetched once.

* Add the MODS tab sort options to the Find Mods tab
This commit is contained in:
Shane McGovern
2026-08-04 15:16:44 +01:00
committed by GitHub
parent f56e82de81
commit 626080d228
5 changed files with 171 additions and 8 deletions
+14
View File
@@ -229,6 +229,20 @@ function ModUpdate.releaseDates(releases)
return { first = first, latest = latest }
end
-- One resolver over a release list: { total, first, latest } or nil when
-- the list carries neither counts nor dates. The FIND MODS rows use this
-- on the repo's fetched releases, the same source the MODS tab trusts.
function ModUpdate.statsForReleases(releases)
local dl = ModUpdate.totalDownloads(releases)
local d = ModUpdate.releaseDates(releases)
if not dl and not d then return nil end
return {
total = dl and dl.total or nil,
first = d and d.first or nil,
latest = d and d.latest or nil,
}
end
-- Thousands-separated count for the launcher ("12,345"), plain for small
-- numbers. Never throws; garbage in, "0" out.
function ModUpdate.formatCount(n)