- Added 'executables' (full list) and 'executable' (selected) fields to Game - Upload now stores ALL discoverable .exe/.com/.bat files in game metadata - Added setExecutable() to GameService that patches the .jsdos bundle (updates dosbox.conf + jsdos.json inside the ZIP) when changing executable - GameResource PATCH handler delegates executable changes to bundle patching - GameDetail edit mode shows a radio-button picker of all executables - Heuristics remain as first-guess default, user can always override - No re-upload needed to fix wrong executable selection
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
let editPublisher = $state("");
|
||||
let editDescription = $state("");
|
||||
let editPlatform = $state("");
|
||||
let editExecutable = $state("");
|
||||
|
||||
// IGDB scrape state
|
||||
let scraping = $state(false);
|
||||
@@ -65,6 +66,7 @@
|
||||
editPublisher = game.publisher || "";
|
||||
editDescription = game.description || "";
|
||||
editPlatform = game.platform || "";
|
||||
editExecutable = game.executable || "";
|
||||
editing = true;
|
||||
}
|
||||
|
||||
@@ -79,6 +81,7 @@
|
||||
publisher: editPublisher || undefined,
|
||||
description: editDescription || undefined,
|
||||
platform: editPlatform || undefined,
|
||||
executable: editExecutable || undefined,
|
||||
});
|
||||
editing = false;
|
||||
} catch (e) {
|
||||
@@ -207,6 +210,25 @@
|
||||
<option value="windows">Windows</option>
|
||||
</select>
|
||||
</div>
|
||||
{#if game.executables && game.executables.length > 0}
|
||||
<div class="edit-exec-section">
|
||||
<span class="edit-exec-label">Main executable:</span>
|
||||
<div class="edit-exec-list">
|
||||
{#each game.executables as exe}
|
||||
<label class="edit-exec-option" class:selected={editExecutable === exe}>
|
||||
<input
|
||||
type="radio"
|
||||
name="executable"
|
||||
value={exe}
|
||||
checked={editExecutable === exe}
|
||||
onchange={() => editExecutable = exe}
|
||||
/>
|
||||
<span class="edit-exec-path">{exe}</span>
|
||||
</label>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="edit-actions">
|
||||
<button class="btn btn-primary" onclick={saveEdit} disabled={saving}>
|
||||
{saving ? "Saving..." : "Save"}
|
||||
@@ -601,6 +623,62 @@
|
||||
color: #66ff66;
|
||||
}
|
||||
|
||||
/* ─── Executable Picker ────────────────────── */
|
||||
.edit-exec-section {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
.edit-exec-label {
|
||||
display: block;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-dim);
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.edit-exec-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
max-height: 180px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.edit-exec-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 8px;
|
||||
border-radius: var(--radius-sm);
|
||||
cursor: pointer;
|
||||
font-size: 0.85rem;
|
||||
font-family: var(--font-mono);
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
transition: border-color 0.15s, background 0.15s;
|
||||
}
|
||||
.edit-exec-option:hover {
|
||||
border-color: var(--phosphor-dim);
|
||||
background: var(--surface-hover);
|
||||
}
|
||||
.edit-exec-option.selected {
|
||||
border-color: var(--phosphor);
|
||||
background: var(--phosphor-burn);
|
||||
}
|
||||
.edit-exec-option input[type="radio"] {
|
||||
accent-color: var(--phosphor);
|
||||
margin: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.edit-exec-path {
|
||||
word-break: break-all;
|
||||
color: var(--text);
|
||||
}
|
||||
.edit-exec-option.selected .edit-exec-path {
|
||||
color: var(--phosphor-glow);
|
||||
}
|
||||
|
||||
/* ─── Responsive ────────────────────────────────── */
|
||||
@media (max-width: 640px) {
|
||||
.detail { padding: 16px 0; }
|
||||
|
||||
Reference in New Issue
Block a user