Fix IGDB result selection: use DOM data attributes + pass igdb_id to backend
Build & Deploy / build-and-deploy (push) Successful in 58s
Build & Deploy / build-and-deploy (push) Successful in 58s
Two issues fixed:
1. Frontend closure bug: IGDB result buttons used Svelte {#each} closure
with onclick={() => doUpload(result.name)}. When clicking the 3rd
result, the 1st result's handler sometimes fired. Fixed by reading
data-name from e.currentTarget.dataset instead of JS closure.
2. Backend scrape mismatch: when user selected 'Blood' from IGDB
results, backend's autoScrape searched for 'Blood' and could match
'Captain Blood' first (alphabetical), overwriting metadata.
Now passes igdb_id along with title so backend uses the EXACT
IGDB entry the user selected via applyIgdbId() instead of
auto-searching.
This commit is contained in:
@@ -43,10 +43,11 @@ export async function deleteGame(id) {
|
||||
}
|
||||
|
||||
/** Upload a game ZIP */
|
||||
export async function uploadGame(file, title) {
|
||||
export async function uploadGame(file, title, igdbId) {
|
||||
const form = new FormData();
|
||||
form.append("file", file);
|
||||
if (title) form.append("title", title);
|
||||
if (igdbId) form.append("igdb_id", String(igdbId));
|
||||
|
||||
const res = await fetch(`${BASE}/api/upload`, {
|
||||
method: "POST",
|
||||
|
||||
@@ -82,12 +82,12 @@
|
||||
manualSearched = false;
|
||||
}
|
||||
|
||||
async function doUpload(title) {
|
||||
async function doUpload(title, igdbId) {
|
||||
if (!pendingFile) return;
|
||||
uploading = true;
|
||||
uploadError = "";
|
||||
try {
|
||||
await uploadGame(pendingFile, title || undefined);
|
||||
await uploadGame(pendingFile, title || undefined, igdbId);
|
||||
cancelUpload();
|
||||
await loadGames();
|
||||
} catch (err) {
|
||||
@@ -139,10 +139,12 @@
|
||||
{:else if igdbResults !== null && igdbResults.length > 0}
|
||||
<p class="match-label">Select a match or enter a custom title:</p>
|
||||
<div class="upload-igdb-results">
|
||||
{#each igdbResults as result (result.igdb_id)}
|
||||
{#each igdbResults as result}
|
||||
<button
|
||||
class="igdb-result"
|
||||
onclick={() => doUpload(result.name)}
|
||||
data-name={result.name}
|
||||
data-igdb-id={result.igdb_id}
|
||||
onclick={(e) => doUpload(e.currentTarget.dataset.name, Number(e.currentTarget.dataset.igdbId))}
|
||||
disabled={uploading}
|
||||
>
|
||||
{#if result.cover_url}
|
||||
|
||||
@@ -34,7 +34,8 @@ public class UploadResource {
|
||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||
public Response upload(
|
||||
@RestForm("file") FileUpload upload,
|
||||
@RestForm("title") String title
|
||||
@RestForm("title") String title,
|
||||
@RestForm("igdb_id") Integer igdbId
|
||||
) throws Exception {
|
||||
if (upload == null) {
|
||||
return Response.status(400).entity(Map.of("error", "No file provided")).build();
|
||||
@@ -103,9 +104,13 @@ public class UploadResource {
|
||||
game.setReady(true);
|
||||
svc.save(game);
|
||||
|
||||
// Auto-populate from IGDB (non-blocking if credentials are set)
|
||||
// Auto-populate from IGDB (use provided igdb_id or auto-search)
|
||||
if (igdb.isConfigured()) {
|
||||
if (igdbId != null) {
|
||||
igdb.applyIgdbId(game, igdbId);
|
||||
} else {
|
||||
igdb.autoScrape(game);
|
||||
}
|
||||
if (game.isHasCover() || game.getYear() != null || game.getGenre() != null
|
||||
|| (game.getVideos() != null && !game.getVideos().isEmpty())
|
||||
|| (game.getScreenshots() != null && !game.getScreenshots().isEmpty())) {
|
||||
|
||||
Reference in New Issue
Block a user