fix: manual title input searches IGDB first, warns before uploading
Build & Deploy / build-and-deploy (push) Successful in 45s

Flow when auto-search finds nothing:
1. User types a title → presses Enter/clicks button
2. System searches IGDB with that title
3a. Results found → shown as selectable cards
3b. No results → warning + amber 'Upload anyway as xxx' button
4. Button label changes: 'Search' → 'Upload' after manual search

Also changed Enter key behavior: first press searches, second
press uploads (if no results after manual search)
This commit is contained in:
David Alvarez
2026-05-27 11:57:16 +02:00
parent 61a83cff65
commit 00267da3dd
+30 -8
View File
@@ -15,6 +15,7 @@
let searching = $state(false); let searching = $state(false);
let searchError = $state(""); let searchError = $state("");
let igdbResults = $state(null); // null=loading, []=no results, [{...}]=matches let igdbResults = $state(null); // null=loading, []=no results, [{...}]=matches
let manualSearched = $state(false); // true after user clicked Search manually
let fileInput; let fileInput;
@@ -39,6 +40,7 @@
igdbResults = null; igdbResults = null;
searching = true; searching = true;
searchError = ""; searchError = "";
manualSearched = false;
fileInput.value = ""; fileInput.value = "";
// Auto-search IGDB with the filename // Auto-search IGDB with the filename
searchIGDB(name).then(data => { searchIGDB(name).then(data => {
@@ -54,6 +56,7 @@
async function handleManualSearch() { async function handleManualSearch() {
const q = pendingTitle.trim(); const q = pendingTitle.trim();
if (!q) return; if (!q) return;
manualSearched = true;
searching = true; searching = true;
searchError = ""; searchError = "";
igdbResults = null; igdbResults = null;
@@ -61,7 +64,7 @@
const data = await searchIGDB(q); const data = await searchIGDB(q);
igdbResults = data.results || []; igdbResults = data.results || [];
if (igdbResults.length === 0) { if (igdbResults.length === 0) {
searchError = "No matches found on IGDB."; searchError = "No matches found for \"" + q + "\" on IGDB.";
} }
} catch (err) { } catch (err) {
searchError = "IGDB search failed: " + err.message; searchError = "IGDB search failed: " + err.message;
@@ -76,6 +79,7 @@
pendingTitle = ""; pendingTitle = "";
igdbResults = null; igdbResults = null;
searchError = ""; searchError = "";
manualSearched = false;
} }
async function doUpload(title) { async function doUpload(title) {
@@ -173,20 +177,27 @@
</div> </div>
{:else} {:else}
{#if searchError} {#if searchError}
<div class="status-msg error-msg">{searchError}</div> <div class="status-msg error-msg">
{searchError}
{#if manualSearched}
<button class="btn btn-sm btn-upload-anyway" onclick={() => doUpload(pendingTitle.trim())} disabled={uploading}>
{uploading ? "Uploading..." : "Upload anyway as \"" + pendingTitle.trim() + "\""}
</button>
{/if}
</div>
{:else} {:else}
<p class="match-label">No matches found on IGDB. Enter a title manually:</p> <p class="match-label">No matches found. Enter a title to search IGDB:</p>
{/if} {/if}
<div class="upload-custom-row"> <div class="upload-custom-row">
<input <input
type="text" type="text"
placeholder="Enter game title..." placeholder="Search IGDB..."
bind:value={pendingTitle} bind:value={pendingTitle}
disabled={uploading} disabled={uploading || searching}
onkeydown={(e) => e.key === "Enter" && doUpload(pendingTitle.trim())} onkeydown={(e) => e.key === "Enter" && (manualSearched ? doUpload(pendingTitle.trim()) : handleManualSearch())}
/> />
<button class="btn" onclick={() => doUpload(pendingTitle.trim())} disabled={uploading || !pendingTitle.trim()}> <button class="btn" onclick={manualSearched ? () => doUpload(pendingTitle.trim()) : handleManualSearch} disabled={uploading || searching || !pendingTitle.trim()}>
{uploading ? "Uploading..." : "Upload"} {uploading ? "Uploading..." : manualSearched ? "Upload" : "Search"}
</button> </button>
</div> </div>
<button class="btn btn-secondary" onclick={() => doUpload(pendingFileName)} disabled={uploading}> <button class="btn btn-secondary" onclick={() => doUpload(pendingFileName)} disabled={uploading}>
@@ -466,4 +477,15 @@
.btn-secondary:hover { .btn-secondary:hover {
border-color: var(--text-dim); border-color: var(--text-dim);
} }
.btn-upload-anyway {
margin-top: 8px;
width: 100%;
justify-content: center;
border-color: #cc8833;
color: #ffaa44;
}
.btn-upload-anyway:hover {
background: #332211;
border-color: #ffaa44;
}
</style> </style>