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 */
|
/** Upload a game ZIP */
|
||||||
export async function uploadGame(file, title) {
|
export async function uploadGame(file, title, igdbId) {
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
form.append("file", file);
|
form.append("file", file);
|
||||||
if (title) form.append("title", title);
|
if (title) form.append("title", title);
|
||||||
|
if (igdbId) form.append("igdb_id", String(igdbId));
|
||||||
|
|
||||||
const res = await fetch(`${BASE}/api/upload`, {
|
const res = await fetch(`${BASE}/api/upload`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|||||||
@@ -82,12 +82,12 @@
|
|||||||
manualSearched = false;
|
manualSearched = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function doUpload(title) {
|
async function doUpload(title, igdbId) {
|
||||||
if (!pendingFile) return;
|
if (!pendingFile) return;
|
||||||
uploading = true;
|
uploading = true;
|
||||||
uploadError = "";
|
uploadError = "";
|
||||||
try {
|
try {
|
||||||
await uploadGame(pendingFile, title || undefined);
|
await uploadGame(pendingFile, title || undefined, igdbId);
|
||||||
cancelUpload();
|
cancelUpload();
|
||||||
await loadGames();
|
await loadGames();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -139,10 +139,12 @@
|
|||||||
{:else if igdbResults !== null && igdbResults.length > 0}
|
{:else if igdbResults !== null && igdbResults.length > 0}
|
||||||
<p class="match-label">Select a match or enter a custom title:</p>
|
<p class="match-label">Select a match or enter a custom title:</p>
|
||||||
<div class="upload-igdb-results">
|
<div class="upload-igdb-results">
|
||||||
{#each igdbResults as result (result.igdb_id)}
|
{#each igdbResults as result}
|
||||||
<button
|
<button
|
||||||
class="igdb-result"
|
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}
|
disabled={uploading}
|
||||||
>
|
>
|
||||||
{#if result.cover_url}
|
{#if result.cover_url}
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ public class UploadResource {
|
|||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
public Response upload(
|
public Response upload(
|
||||||
@RestForm("file") FileUpload upload,
|
@RestForm("file") FileUpload upload,
|
||||||
@RestForm("title") String title
|
@RestForm("title") String title,
|
||||||
|
@RestForm("igdb_id") Integer igdbId
|
||||||
) throws Exception {
|
) throws Exception {
|
||||||
if (upload == null) {
|
if (upload == null) {
|
||||||
return Response.status(400).entity(Map.of("error", "No file provided")).build();
|
return Response.status(400).entity(Map.of("error", "No file provided")).build();
|
||||||
@@ -103,9 +104,13 @@ public class UploadResource {
|
|||||||
game.setReady(true);
|
game.setReady(true);
|
||||||
svc.save(game);
|
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 (igdb.isConfigured()) {
|
||||||
igdb.autoScrape(game);
|
if (igdbId != null) {
|
||||||
|
igdb.applyIgdbId(game, igdbId);
|
||||||
|
} else {
|
||||||
|
igdb.autoScrape(game);
|
||||||
|
}
|
||||||
if (game.isHasCover() || game.getYear() != null || game.getGenre() != null
|
if (game.isHasCover() || game.getYear() != null || game.getGenre() != null
|
||||||
|| (game.getVideos() != null && !game.getVideos().isEmpty())
|
|| (game.getVideos() != null && !game.getVideos().isEmpty())
|
||||||
|| (game.getScreenshots() != null && !game.getScreenshots().isEmpty())) {
|
|| (game.getScreenshots() != null && !game.getScreenshots().isEmpty())) {
|
||||||
|
|||||||
Reference in New Issue
Block a user