mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 09:21:24 +01:00
Implement improved save functionality with custom filename, timestamp toggle, and overwrite protection
Co-authored-by: Azgaar <26469650+Azgaar@users.noreply.github.com>
This commit is contained in:
parent
ba837ab6f8
commit
df15f74d95
4 changed files with 113 additions and 18 deletions
44
index.html
44
index.html
|
|
@ -6076,21 +6076,37 @@
|
|||
|
||||
<div id="saveMapData" style="display: none" class="dialog">
|
||||
<div style="margin-top: 0.3em">
|
||||
<strong>Save map to</strong>
|
||||
<button onclick="saveMap('machine')" data-tip="Download map file to your local disk" data-shortcut="Ctrl + S">
|
||||
machine
|
||||
</button>
|
||||
<button onclick="saveMap('dropbox')" data-tip="Save map file to your Dropbox" data-shortcut="Ctrl + C">
|
||||
dropbox
|
||||
</button>
|
||||
<button onclick="saveMap('storage')" data-tip="Save the project to browser storage only" data-shortcut="F6">
|
||||
browser
|
||||
</button>
|
||||
<div style="margin-bottom: 0.8em">
|
||||
<label for="customFileName" style="display: block; margin-bottom: 0.3em;"><strong>File name:</strong></label>
|
||||
<input type="text" id="customFileName" style="width: 250px; margin-bottom: 0.3em;" placeholder="Enter custom filename (without .map extension)">
|
||||
<div>
|
||||
<input type="checkbox" id="includeTimestamp" checked>
|
||||
<label for="includeTimestamp">Include timestamp in filename</label>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-bottom: 0.5em">
|
||||
<strong>Save map to</strong>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="saveMap('machine')" data-tip="Download map file to your local disk" data-shortcut="Ctrl + S">
|
||||
machine
|
||||
</button>
|
||||
<button onclick="saveMap('dropbox')" data-tip="Save map file to your Dropbox" data-shortcut="Ctrl + C">
|
||||
dropbox
|
||||
</button>
|
||||
<button onclick="saveMap('storage')" data-tip="Save the project to browser storage only" data-shortcut="F6">
|
||||
browser
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="background-color: #ffe6e6; border: 1px solid #ff9999; padding: 0.8em; margin-top: 0.8em; border-radius: 4px;">
|
||||
<p style="margin: 0; font-weight: bold; color: #cc0000;">⚠️ Important Backup Warning</p>
|
||||
<p style="margin: 0.3em 0 0 0;">
|
||||
Maps are saved in <i>.map</i> format, that can be loaded back via the <i>Load</i> in menu. <strong>There is no way to
|
||||
restore the progress if file is lost.</strong> Please keep old save files on your machine or cloud storage as backups.
|
||||
When saving to machine, files may be automatically renamed if a file with the same name already exists.
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
Maps are saved in <i>.map</i> format, that can be loaded back via the <i>Load</i> in menu. There is no way to
|
||||
restore the progress if file is lost. Please keep old save files on your machine or cloud storage as backups.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="loadMapData" style="display: none" class="dialog">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,24 @@ async function saveMap(method) {
|
|||
|
||||
try {
|
||||
const mapData = prepareMapData();
|
||||
const filename = getFileName() + ".map";
|
||||
|
||||
// Get custom filename settings from the dialog
|
||||
const customFileNameInput = byId("customFileName");
|
||||
const includeTimestampCheckbox = byId("includeTimestamp");
|
||||
|
||||
const customName = customFileNameInput?.value?.trim() || null;
|
||||
const includeTimestamp = includeTimestampCheckbox?.checked !== false;
|
||||
|
||||
const filename = getFileName(null, customName, includeTimestamp) + ".map";
|
||||
|
||||
// For browser storage, check if file exists and ask for confirmation
|
||||
if (method === "storage") {
|
||||
const existingFile = await checkIfStorageFileExists(filename);
|
||||
if (existingFile) {
|
||||
const confirmOverwrite = await showOverwriteConfirmation(filename);
|
||||
if (!confirmOverwrite) return;
|
||||
}
|
||||
}
|
||||
|
||||
saveToStorage(mapData, method === "storage"); // any method saves to indexedDB
|
||||
if (method === "machine") saveToMachine(mapData, filename);
|
||||
|
|
@ -259,3 +276,46 @@ function toggleSaveReminder() {
|
|||
saveReminder();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if a file exists in browser storage
|
||||
async function checkIfStorageFileExists(filename) {
|
||||
try {
|
||||
// For browser storage, we only have one slot ("lastMap"), so we don't need to check filename
|
||||
// This function is prepared for future enhancement if multiple saves are supported
|
||||
const existingFile = await ldb.get("lastMap");
|
||||
return existingFile !== null;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to show overwrite confirmation dialog
|
||||
async function showOverwriteConfirmation(filename) {
|
||||
return new Promise((resolve) => {
|
||||
alertMessage.innerHTML = /* html */ `
|
||||
<p><strong>A map is already saved in browser storage.</strong></p>
|
||||
<p>Do you want to overwrite the existing saved map with the current one?</p>
|
||||
<p style="color: #cc6600; font-style: italic;">
|
||||
⚠️ The previous map will be permanently lost if you continue.
|
||||
Consider saving to machine first as a backup.
|
||||
</p>
|
||||
`;
|
||||
|
||||
$("#alert").dialog({
|
||||
resizable: false,
|
||||
title: "Overwrite existing save?",
|
||||
width: "28em",
|
||||
buttons: {
|
||||
"Yes, overwrite": function () {
|
||||
$(this).dialog("close");
|
||||
resolve(true);
|
||||
},
|
||||
"Cancel": function () {
|
||||
$(this).dialog("close");
|
||||
resolve(false);
|
||||
}
|
||||
},
|
||||
position: {my: "center", at: "center", of: "svg"}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -892,10 +892,15 @@ function unfog(id) {
|
|||
if (!defs.selectAll("#fog path").size()) fogging.style("display", "none");
|
||||
}
|
||||
|
||||
function getFileName(dataType) {
|
||||
function getFileName(dataType, customName = null, includeTimestamp = true) {
|
||||
const formatTime = time => (time < 10 ? "0" + time : time);
|
||||
const name = mapName.value;
|
||||
const name = customName || mapName.value;
|
||||
const type = dataType ? dataType + " " : "";
|
||||
|
||||
if (!includeTimestamp) {
|
||||
return name + (type ? " " + type.trim() : "");
|
||||
}
|
||||
|
||||
const date = new Date();
|
||||
const year = date.getFullYear();
|
||||
const month = formatTime(date.getMonth() + 1);
|
||||
|
|
|
|||
|
|
@ -738,10 +738,24 @@ function showSavePane() {
|
|||
const sharableLinkContainer = byId("sharableLinkContainer");
|
||||
sharableLinkContainer.style.display = "none";
|
||||
|
||||
// Initialize the custom filename input with current map name
|
||||
const customFileNameInput = byId("customFileName");
|
||||
const includeTimestampCheckbox = byId("includeTimestamp");
|
||||
|
||||
if (customFileNameInput) {
|
||||
customFileNameInput.value = mapName.value || "Fantasy Map";
|
||||
// Store default state
|
||||
customFileNameInput.dataset.defaultValue = customFileNameInput.value;
|
||||
}
|
||||
|
||||
if (includeTimestampCheckbox) {
|
||||
includeTimestampCheckbox.checked = true;
|
||||
}
|
||||
|
||||
$("#saveMapData").dialog({
|
||||
title: "Save map",
|
||||
resizable: false,
|
||||
width: "25em",
|
||||
width: "32em",
|
||||
position: {my: "center", at: "center", of: "svg"},
|
||||
buttons: {
|
||||
Close: function () {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue