From 7fe282351935c11d479d276f7283d0f2868f3e85 Mon Sep 17 00:00:00 2001 From: lobo Date: Wed, 30 Sep 2026 12:08:57 +0200 Subject: [PATCH] refactor(library): detail page refreshes, then assembles --- .../library/service/GameDetailService.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/main/java/core_service/modules/library/service/GameDetailService.java b/src/main/java/core_service/modules/library/service/GameDetailService.java index b9bfbd7..cc7a91a 100644 --- a/src/main/java/core_service/modules/library/service/GameDetailService.java +++ b/src/main/java/core_service/modules/library/service/GameDetailService.java @@ -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 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,