refactor(library): detail page refreshes, then assembles

This commit is contained in:
lobo committed 2026-09-30 12:08:57 +02:00
1 parent 2c97e2ae96
commit 7fe2823519
1 file changed
+26 -11
@@ -77,8 +77,20 @@ public class GameDetailService {
if (userGameOpt.isEmpty() || userGameOpt.get().getRemovedAt() != null) {
return Optional.empty();
}
UserGame userGame = userGameOpt.get();
SteamGame meta = steamGameRepository.findById(appid).orElse(null);
Refreshed refreshed = refresh(userGameOpt.get(), steamId);
return Optional.of(assemble(refreshed.userGame(), meta, refreshed.hasSchema()));
}
/**
* @param userGame the game after the refresh, re-read when the finish rule changed its status
*/
private record Refreshed(UserGame userGame, boolean hasSchema) {}
// May call Steam, IGDB and speedrun.com and write.
private Refreshed refresh(UserGame userGame, String steamId) {
Long userId = userGame.getUserId();
Long appid = userGame.getAppid();
// A hidden game gets no calls to Steam, IGDB or speedrun.com; it shows what is stored.
boolean hidden = userGame.getHiddenAt() != null;
if (!hidden) {
@@ -89,7 +101,7 @@ public class GameDetailService {
// Users without a Steam ID never sync, so the time to beat of their games is asked again here.
timeToBeatService.refreshInBackground(List.of(appid));
moodService.refreshInBackground(List.of(appid));
return Optional.of(buildDto(userGame, meta, true, 0, 0, List.of()));
return new Refreshed(userGame, false);
}
if (!hidden) {
@@ -100,9 +112,8 @@ public class GameDetailService {
}
}
boolean hasSchema = schemaMetaRepository.findById(appid).map(GameAchievementSchemaMeta::isHasSchema).orElse(false);
if (!hasSchema) {
return Optional.of(buildDto(userGame, meta, true, 0, 0, List.of()));
return new Refreshed(userGame, false);
}
if (steamId != null && !hidden) {
@@ -117,7 +128,16 @@ public class GameDetailService {
if (!hidden && !userGame.isStatusSetByUser() && achievementSyncService.finishIfEndingUnlocked(userId, appid)) {
userGame = userGameRepository.findById(new UserGameId(userId, appid)).orElse(userGame);
}
return new Refreshed(userGame, true);
}
// Reads only.
private GameDetailDto assemble(UserGame userGame, SteamGame meta, boolean hasSchema) {
if (!hasSchema) {
return buildDto(userGame, meta, true, 0, 0, List.of(), List.of());
}
Long userId = userGame.getUserId();
Long appid = userGame.getAppid();
UserGameAchievementMeta userMeta = userAchievementMetaRepository.findByUserIdAndAppid(userId, appid).orElse(null);
boolean statsVisible = userMeta == null || userMeta.isStatsVisible();
int unlocked = userMeta != null ? userMeta.getAchievementsUnlocked() : 0;
@@ -145,13 +165,8 @@ public class GameDetailService {
})
.toList();
return Optional.of(buildDto(userGame, meta, statsVisible, schemaList.size(),
AchievementProgress.capped(unlocked, schemaList.size()), achievementDtos, schemaList));
}
private GameDetailDto buildDto(UserGame userGame, SteamGame meta, boolean statsVisible,
int total, int unlocked, List<AchievementDto> achievements) {
return buildDto(userGame, meta, statsVisible, total, unlocked, achievements, List.of());
return buildDto(userGame, meta, statsVisible, schemaList.size(),
AchievementProgress.capped(unlocked, schemaList.size()), achievementDtos, schemaList);
}
private GameDetailDto buildDto(UserGame userGame, SteamGame meta, boolean statsVisible, int total, int unlocked,