Skip to content

Commit 156e7a2

Browse files
committed
bugfix(web): Keep clearing stored game data reachable once data exists
Both the "Clear stored game data" button and the handler that gave it any effect lived inside the folder-picker step. That step only runs when there is nothing in storage, so the moment a copy existed - exactly when clearing it becomes useful - the button was hidden and unbound, and a bad copy could not be thrown away. Move the button out of the picker row into its own, bind it once at startup, and reveal it as soon as the page is working off browser storage: while a copy is being made, when one is loaded, and when a crash report is on screen. Clearing now also reloads, because the copy being removed is already in the in-memory filesystem and the engine may be running on it.
1 parent 3470eb7 commit 156e7a2

1 file changed

Lines changed: 36 additions & 11 deletions

File tree

GeneralsMD/Code/Main/web/shell.html

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@
5454
#pick { font: inherit; font-size: 14px; padding: 10px 18px; border-radius: 4px;
5555
border: 1px solid #c8a13a; background: #1a1a1a; color: #c8a13a; cursor: pointer; }
5656
#pick:hover { background: #262626; }
57-
#reset { margin-top: 14px; font-size: 12px; color: #666; background: none; border: 0;
57+
#storage { margin-top: 14px; display: none; }
58+
#reset { font-size: 12px; color: #666; background: none; border: 0;
5859
cursor: pointer; text-decoration: underline; font-family: inherit; }
60+
#reset:hover { color: #999; }
5961
#pickInput { display: none; }
6062
#source { margin-top: 20px; font-size: 12px; color: #666; display: none; }
6163
#switchSource { font-size: 12px; color: #888; background: none; border: 0;
@@ -90,12 +92,14 @@
9092
</p>
9193
<button id="pick" type="button">Select game folder</button>
9294
<input id="pickInput" type="file" webkitdirectory directory multiple>
93-
<div><button id="reset" type="button">Clear stored game data</button></div>
9495
</div>
9596
<div id="source">
9697
<span id="sourceLabel"></span>
9798
<button id="switchSource" type="button"></button>
9899
</div>
100+
<!-- Outside #setup: that row only appears while a folder is being asked for, so a
101+
stored copy could never be cleared once it existed. -->
102+
<div id="storage"><button id="reset" type="button">Clear stored game data</button></div>
99103
<div id="mods">
100104
<span id="modsLabel"></span>
101105
<span id="modButtons"></span>
@@ -112,6 +116,7 @@
112116
var pickBtn = document.getElementById('pick');
113117
var pickInput = document.getElementById('pickInput');
114118
var resetBtn = document.getElementById('reset');
119+
var storageEl = document.getElementById('storage');
115120
var sourceEl = document.getElementById('source');
116121
var sourceLabelEl = document.getElementById('sourceLabel');
117122
var switchSourceBtn = document.getElementById('switchSource');
@@ -630,6 +635,32 @@
630635
}
631636
}
632637

638+
// TheSuperHackers @bugfix githubawn 30/07/2026 Wire clearing up once, at startup, and
639+
// reveal it whenever there is something to clear. Both the button and its handler used
640+
// to live inside the folder-picker step, so the moment a copy existed the picker stopped
641+
// running and the only way to get rid of that copy went with it.
642+
function showStorageControls() {
643+
if (storageEl) storageEl.style.display = 'block';
644+
}
645+
646+
async function clearStoredData() {
647+
resetBtn.disabled = true;
648+
try {
649+
var root = await navigator.storage.getDirectory();
650+
await root.removeEntry(OPFS_DIR, { recursive: true });
651+
} catch (e) {
652+
// Already gone, or never there: either way there is nothing left to clear.
653+
console.warn('Clearing stored game data:', e);
654+
}
655+
// The copy just removed is already loaded into the in-memory filesystem, and the
656+
// engine may be running on it, so start over from a clean page rather than pretend
657+
// this took effect immediately.
658+
setStatus('Stored game data cleared. Reloading...');
659+
location.reload();
660+
}
661+
662+
if (resetBtn) resetBtn.onclick = clearStoredData;
663+
633664
async function writeStoredManifest(dir, files) {
634665
var fh = await dir.getFileHandle(OPFS_MANIFEST, { create: true });
635666
var w = await fh.createWritable();
@@ -869,15 +900,6 @@
869900
}
870901
};
871902

872-
resetBtn.onclick = async function () {
873-
try {
874-
var root = await navigator.storage.getDirectory();
875-
await root.removeEntry(OPFS_DIR, { recursive: true });
876-
setStatus('Stored game data cleared.');
877-
} catch (e) {
878-
setStatus('Nothing stored to clear.');
879-
}
880-
};
881903
});
882904
}
883905

@@ -909,6 +931,9 @@
909931
'page needs to hold the game data.');
910932
}
911933
showSourceSwitch('browser');
934+
// From here on the page is working off browser storage, so offer to clear it -
935+
// whether a copy is about to be made or one is already there.
936+
showStorageControls();
912937

913938
var manifest = await readStoredManifest();
914939
if (!manifest) {

0 commit comments

Comments
 (0)