mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
v1.0.07
This commit is contained in:
parent
52e8f28cd0
commit
92a50d9810
9 changed files with 161 additions and 75 deletions
14
index.css
14
index.css
|
|
@ -996,14 +996,26 @@ div.slider .ui-slider-handle {
|
|||
top: 100%;
|
||||
border: 1px solid #5e4fa2;
|
||||
background-color: #a4879b;
|
||||
width: 44px;
|
||||
width: 3.6em;
|
||||
}
|
||||
|
||||
#loadDropdown {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 53%;
|
||||
top: 100%;
|
||||
border: 1px solid #5e4fa2;
|
||||
background-color: #a4879b;
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
#loadDropdown>div,
|
||||
#saveDropdown>div {
|
||||
padding: 2px 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#loadDropdown>div:hover,
|
||||
#saveDropdown>div:hover {
|
||||
color: white;
|
||||
}
|
||||
|
|
|
|||
10
index.html
10
index.html
|
|
@ -1814,13 +1814,17 @@
|
|||
|
||||
<div id="sticked">
|
||||
<button id="newMapButton" data-tip="Generate a new map based on options. Shortcut: F7">New Map</button>
|
||||
<button id="saveButton" data-tip="Select file format to save map">Save as</button>
|
||||
<button id="saveButton" data-tip="Select file format to save map">Save</button>
|
||||
<div id="saveDropdown">
|
||||
<div id="saveMap" data-tip="Save as fully functional map in .map format. Shortcut: Ctrl + M">.map</div>
|
||||
<div id="saveSVG" data-tip="Download the map as .svg image (open in browser or Inkscape). Shortcut: Ctrl + S">.svg</div>
|
||||
<div id="savePNG" data-tip="Download visible part of the map as image. Texture will not be shown. Shortcut: Ctrl + P">.png</div>
|
||||
</div>
|
||||
<button id="loadMap" data-tip="Load fully functional map in a .map format. Shortcut: Ctrl + L">Load</button>
|
||||
<button id="loadButton" data-tip="Load fully functional map in a .map format">Load</button>
|
||||
<div id="loadDropdown">
|
||||
<div id="loadURL" data-tip="Load .map file from URL: Ctrl + U">from URL</div>
|
||||
<div id="loadMap" data-tip="Load .map file from local disk. Shortcut: Ctrl + L">from file</div>
|
||||
</div>
|
||||
<button id="zoomReset" data-tip="Reset map zoom. Shortcut: 0">Reset Zoom</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -2945,6 +2949,7 @@
|
|||
<script defer src="modules/ui/general.js"></script>
|
||||
<script defer src="modules/ui/options.js"></script>
|
||||
<script defer src="modules/ui/measurers.js"></script>
|
||||
<script defer src="modules/save-and-load.js"></script>
|
||||
<script defer src="main.js?version=1.0"></script>
|
||||
<script defer src="modules/relief-icons.js"></script>
|
||||
<script defer src="modules/ui/tools.js"></script>
|
||||
|
|
@ -2969,7 +2974,6 @@
|
|||
<script defer src="modules/ui/diplomacy-editor.js"></script>
|
||||
<script defer src="modules/ui/zones-editor.js"></script>
|
||||
<script defer src="modules/ui/editors.js"></script>
|
||||
<script defer src="modules/save-and-load.js"></script>
|
||||
<script defer src="libs/quantize.min.js"></script>
|
||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||
</body>
|
||||
|
|
|
|||
152
main.js
152
main.js
|
|
@ -81,9 +81,8 @@ population.append("g").attr("id", "urban");
|
|||
fogging.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
||||
|
||||
// assign events separately as not a viewbox child
|
||||
scaleBar.on("mousemove", function() {tip("Click to open Units Editor")});
|
||||
legend.on("mousemove", function() {tip("Drag to change the position. Click to hide the legend")})
|
||||
.on("click", () => clearLegend());
|
||||
scaleBar.on("mousemove", () => tip("Click to open Units Editor"));
|
||||
legend.on("mousemove", () => tip("Drag to change the position. Click to hide the legend")).on("click", () => clearLegend());
|
||||
|
||||
// main data variables
|
||||
let grid = {}; // initial grapg based on jittered square grid and data
|
||||
|
|
@ -111,61 +110,52 @@ landmass.append("rect").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr
|
|||
oceanPattern.append("rect").attr("fill", "url(#oceanic)").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight);
|
||||
oceanLayers.append("rect").attr("id", "oceanBase").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight);
|
||||
|
||||
applyDefaultNamesData(); // apply default namesbase on load
|
||||
applyDefaultStyle(); // apply style on load
|
||||
generate(); // generate map on load
|
||||
focusOn(); // based on searchParams focus on point, cell or burg from MFCG
|
||||
applyPreset(); // apply saved layers preset on load
|
||||
applyDefaultNamesData(); // always apply default namesbase load as namesdata is not stored in .map file
|
||||
|
||||
// show message on load if required
|
||||
setTimeout(showWelcomeMessage, 7000);
|
||||
function showWelcomeMessage() {
|
||||
// Changelog dialog window
|
||||
if (localStorage.getItem("version") != version) {
|
||||
const link = 'https://www.reddit.com/r/FantasyMapGenerator/comments/cxu1c5/update_new_version_is_published_v_10'; // announcement on Reddit
|
||||
alertMessage.innerHTML = `The Fantasy Map Generator is updated up to version <b>${version}</b>.
|
||||
// load linked map from url or generate a random map
|
||||
void function checkLoadParameters() {
|
||||
const url = new URL(window.location.href);
|
||||
const maplink = url.searchParams.get("maplink");
|
||||
|
||||
This version is compatible with versions 0.8b and 0.9b, but not with older .map files.
|
||||
Please use an <a href='https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog' target='_blank'>archived version</a> to open old files.
|
||||
|
||||
<ul><a href=${link} target='_blank'>Main changes:</a>
|
||||
<li>Provinces and Provinces Editor</li>
|
||||
<li>Religions Layer and Religions Editor</li>
|
||||
<li>Full state names (state types)</li>
|
||||
<li>Multi-lined labels</li>
|
||||
<li>State relations (diplomacy)</li>
|
||||
<li>Custom layers (zones)</li>
|
||||
<li>Places of interest (auto-added markers)</li>
|
||||
<li>New color picker and hatching fill</li>
|
||||
<li>Legend boxes</li>
|
||||
<li>World Configurator presets</li>
|
||||
<li>Improved state labels placement</li>
|
||||
<li>Relief icons sets</li>
|
||||
<li>Fogging</li>
|
||||
<li>Custom layer presets</li>
|
||||
<li>Custom biomes</li>
|
||||
<li>State, province and burg COAs</li>
|
||||
<li>Desktop version (see <a href='https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Q&A#is-there-a-desktop-version' target='_blank'>here)</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Join our <a href='https://www.reddit.com/r/FantasyMapGenerator' target='_blank'>Reddit community</a> and
|
||||
<a href='https://discordapp.com/invite/X7E84HU' target='_blank'>Discord server</a>
|
||||
to ask questions, share maps, discuss the Generator, report bugs and propose new features.</p>
|
||||
|
||||
<p>Thanks for all supporters on <a href='https://www.patreon.com/azgaar' target='_blank'>Patreon</a>!</i></p>`;
|
||||
|
||||
$("#alert").dialog(
|
||||
{resizable: false, title: "Fantasy Map Generator update", width: 310,
|
||||
buttons: {
|
||||
OK: function() {
|
||||
localStorage.clear();
|
||||
localStorage.setItem("version", version);
|
||||
$(this).dialog("close");
|
||||
}
|
||||
},
|
||||
position: {my: "center", at: "center", of: "svg"}
|
||||
});
|
||||
// check if URL is valid
|
||||
if (maplink) {
|
||||
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
|
||||
const valid = pattern.test(maplink);
|
||||
if (valid) {loadMapFromURL(maplink, 1); return;} else
|
||||
showUploadErrorMessage("Map link is a valid URL", maplink);
|
||||
}
|
||||
generateRandomMapOnLoad();
|
||||
}()
|
||||
|
||||
function loadMapFromURL(maplink, random) {
|
||||
const URL = decodeURIComponent(maplink);
|
||||
|
||||
fetch(URL, {method: 'GET', mode: 'cors'})
|
||||
.then(response => {
|
||||
if(response.ok) return response.blob();
|
||||
throw new Error("Cannot load map from URL");
|
||||
}).then(blob => uploadFile(blob))
|
||||
.catch(error => {
|
||||
showUploadErrorMessage(error.message, URL, random);
|
||||
if (random) generateRandomMapOnLoad();
|
||||
});
|
||||
}
|
||||
|
||||
function showUploadErrorMessage(error, URL, random) {
|
||||
console.log(error);
|
||||
alertMessage.innerHTML = `
|
||||
Cannot load map from the <a href='${URL}' target='_blank'>link provided</a>.
|
||||
${random?`A new random map is generated. `:''}
|
||||
Please ensure the linked file is reachable`;
|
||||
$("#alert").dialog({title: "Loading error", width: 320, buttons: {OK: function() {$(this).dialog("close");}}});
|
||||
}
|
||||
|
||||
function generateRandomMapOnLoad() {
|
||||
applyDefaultStyle(); // apply style
|
||||
generate(); // generate map
|
||||
focusOn(); // based on searchParams focus on point, cell or burg from MFCG
|
||||
applyPreset(); // apply saved layers preset
|
||||
setTimeout(showWelcomeMessage, 7000); // show welcome message if required
|
||||
}
|
||||
|
||||
function applyDefaultNamesData() {
|
||||
|
|
@ -431,11 +421,10 @@ function findBurgForMFCG(params) {
|
|||
|
||||
const label = burgLabels.select("[data-id='" + b + "']");
|
||||
if (label.size()) {
|
||||
tip("Here stands the glorious city of " + burgs[b].name, true, "error");
|
||||
tip("Here stands the glorious city of " + burgs[b].name, true, "success", 10000);
|
||||
label.classed("drag", true).on("mouseover", function() {
|
||||
d3.select(this).classed("drag", false);
|
||||
label.on("mouseover", null);
|
||||
tip("", true);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -443,6 +432,55 @@ function findBurgForMFCG(params) {
|
|||
invokeActiveZooming();
|
||||
}
|
||||
|
||||
function showWelcomeMessage() {
|
||||
// Changelog dialog window
|
||||
if (localStorage.getItem("version") != version) {
|
||||
const link = 'https://www.reddit.com/r/FantasyMapGenerator/comments/cxu1c5/update_new_version_is_published_v_10'; // announcement on Reddit
|
||||
alertMessage.innerHTML = `The Fantasy Map Generator is updated up to version <b>${version}</b>.
|
||||
|
||||
This version is compatible with versions 0.8b and 0.9b, but not with older .map files.
|
||||
Please use an <a href='https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog' target='_blank'>archived version</a> to open old files.
|
||||
|
||||
<ul><a href=${link} target='_blank'>Main changes:</a>
|
||||
<li>Provinces and Provinces Editor</li>
|
||||
<li>Religions Layer and Religions Editor</li>
|
||||
<li>Full state names (state types)</li>
|
||||
<li>Multi-lined labels</li>
|
||||
<li>State relations (diplomacy)</li>
|
||||
<li>Custom layers (zones)</li>
|
||||
<li>Places of interest (auto-added markers)</li>
|
||||
<li>New color picker and hatching fill</li>
|
||||
<li>Legend boxes</li>
|
||||
<li>World Configurator presets</li>
|
||||
<li>Improved state labels placement</li>
|
||||
<li>Relief icons sets</li>
|
||||
<li>Fogging</li>
|
||||
<li>Custom layer presets</li>
|
||||
<li>Custom biomes</li>
|
||||
<li>State, province and burg COAs</li>
|
||||
<li>Desktop version (see <a href='https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Q&A#is-there-a-desktop-version' target='_blank'>here)</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Join our <a href='https://www.reddit.com/r/FantasyMapGenerator' target='_blank'>Reddit community</a> and
|
||||
<a href='https://discordapp.com/invite/X7E84HU' target='_blank'>Discord server</a>
|
||||
to ask questions, share maps, discuss the Generator, report bugs and propose new features.</p>
|
||||
|
||||
<p>Thanks for all supporters on <a href='https://www.patreon.com/azgaar' target='_blank'>Patreon</a>!</i></p>`;
|
||||
|
||||
$("#alert").dialog(
|
||||
{resizable: false, title: "Fantasy Map Generator update", width: 310,
|
||||
buttons: {
|
||||
OK: function() {
|
||||
localStorage.clear();
|
||||
localStorage.setItem("version", version);
|
||||
$(this).dialog("close");
|
||||
}
|
||||
},
|
||||
position: {my: "center", at: "center", of: "svg"}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function zoomed() {
|
||||
const transform = d3.event.transform;
|
||||
const scaleDiff = scale - transform.k;
|
||||
|
|
|
|||
|
|
@ -265,6 +265,8 @@
|
|||
const type = states[s].type;
|
||||
|
||||
cells.c[n].forEach(function(e) {
|
||||
if (cells.state[e] && e === states[cells.state[e]].center) return; // do not overwrite capital cells
|
||||
|
||||
const cultureCost = states[s].culture === cells.culture[e] ? -9 : 700;
|
||||
const biomeCost = getBiomeCost(cells.road[e], b, cells.biome[e], type);
|
||||
const heightCost = getHeightCost(pack.features[cells.f[e]], cells.h[e], type);
|
||||
|
|
@ -278,7 +280,6 @@
|
|||
if (cells.h[e] >= 20) cells.state[e] = s; // assign state to cell
|
||||
cost[e] = totalCost;
|
||||
queue.queue({e, p:totalCost, s, b});
|
||||
|
||||
//const points = [cells.p[n][0], cells.p[n][1], (cells.p[n][0]+cells.p[e][0])/2, (cells.p[n][1]+cells.p[e][1])/2, cells.p[e][0], cells.p[e][1]];
|
||||
//debug.append("text").attr("x", (cells.p[n][0]+cells.p[e][0])/2 - 1).attr("y", (cells.p[n][1]+cells.p[e][1])/2 - 1).text(rn(totalCost-p)).attr("font-size", .8);
|
||||
//debug.append("polyline").attr("points", points).attr("marker-mid", "url(#arrow)").attr("opacity", .6);
|
||||
|
|
|
|||
|
|
@ -210,6 +210,7 @@ function saveMap() {
|
|||
|
||||
function uploadFile(file, callback) {
|
||||
console.time("loadMap");
|
||||
closeDialogs();
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = function(fileLoadedEvent) {
|
||||
const dataLoaded = fileLoadedEvent.target.result;
|
||||
|
|
@ -423,7 +424,7 @@ function parseLoadedData(data) {
|
|||
getCurrentPreset();
|
||||
}()
|
||||
|
||||
void function restoreRulersEvents() {
|
||||
void function restoreEvents() {
|
||||
ruler.selectAll("g").call(d3.drag().on("start", dragRuler));
|
||||
ruler.selectAll("text").on("click", removeParent);
|
||||
ruler.selectAll("g.ruler circle").call(d3.drag().on("drag", dragRulerEdge));
|
||||
|
|
@ -431,6 +432,9 @@ function parseLoadedData(data) {
|
|||
ruler.selectAll("g.ruler rect").call(d3.drag().on("start", rulerCenterDrag));
|
||||
ruler.selectAll("g.opisometer circle").call(d3.drag().on("start", dragOpisometerEnd));
|
||||
ruler.selectAll("g.opisometer circle").call(d3.drag().on("start", dragOpisometerEnd));
|
||||
|
||||
scaleBar.on("mousemove", () => tip("Click to open Units Editor"));
|
||||
legend.on("mousemove", () => tip("Drag to change the position. Click to hide the legend")).on("click", () => clearLegend());
|
||||
}()
|
||||
|
||||
void function resolveVersionConflicts() {
|
||||
|
|
@ -518,6 +522,7 @@ function parseLoadedData(data) {
|
|||
changeMapSize();
|
||||
restoreDefaultEvents();
|
||||
invokeActiveZooming();
|
||||
tip("Map is loaded");
|
||||
tip("Map is successfully loaded", true, "success", 7000);
|
||||
console.timeEnd("loadMap");
|
||||
showStatistics();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ function editBurg() {
|
|||
}
|
||||
|
||||
function createNewGroup() {
|
||||
if (!this.value) {tip("Please provide a valid group name"); return;}
|
||||
if (!this.value) {tip("Please provide a valid group name", false, "error"); return;}
|
||||
let group = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, "");
|
||||
if (Number.isFinite(+group.charAt(0))) group = "g" + group;
|
||||
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ function editBurgs() {
|
|||
if (!pack.burgs[burg].port) {
|
||||
const haven = pack.cells.haven[pack.burgs[burg].cell];
|
||||
const port = haven ? pack.cells.f[haven] : -1;
|
||||
if (!haven) tip("Port haven is not found, system won't be able to make a searoute", false, "warning");
|
||||
if (!haven) tip("Port haven is not found, system won't be able to make a searoute", false, "warn");
|
||||
pack.burgs[burg].port = port;
|
||||
|
||||
const g = pack.burgs[burg].capital ? "cities" : "towns";
|
||||
|
|
|
|||
|
|
@ -18,16 +18,18 @@ const tooltip = document.getElementById("tooltip");
|
|||
document.getElementById("dialogs").addEventListener("mousemove", showDataTip);
|
||||
document.getElementById("optionsContainer").addEventListener("mousemove", showDataTip);
|
||||
|
||||
function tip(tip = "Tip is undefined", main = false, error = false) {
|
||||
const reg = "linear-gradient(0.1turn, #ffffff00, #5e5c5c66, #ffffff00)";
|
||||
const red = "linear-gradient(0.1turn, #ffffff00, #e3141499, #ffffff00)";
|
||||
function tip(tip = "Tip is undefined", main, error, time) {
|
||||
tooltip.innerHTML = tip;
|
||||
tooltip.style.background = error ? red : reg;
|
||||
if (main) tooltip.dataset.main = tip;
|
||||
tooltip.style.background = "linear-gradient(0.1turn, #ffffff00, #5e5c5c80, #ffffff00)";
|
||||
if (error === "error") tooltip.style.background = "linear-gradient(0.1turn, #ffffff00, #e11d1dcc, #ffffff00)"; else
|
||||
if (error === "warn") tooltip.style.background = "linear-gradient(0.1turn, #ffffff00, #be5d08cc, #ffffff00)"; else
|
||||
if (error === "success") tooltip.style.background = "linear-gradient(0.1turn, #ffffff00, #127912cc, #ffffff00)";
|
||||
|
||||
if (main) tooltip.dataset.main = tip; // set main tip
|
||||
if (time) setTimeout(tooltip.dataset.main = "", time); // clear main in some time
|
||||
}
|
||||
|
||||
function showMainTip() {
|
||||
tooltip.style.background = "linear-gradient(0.1turn, #aaffff00, #3a26264d, #ffffff00)";
|
||||
tooltip.innerHTML = tooltip.dataset.main;
|
||||
}
|
||||
|
||||
|
|
@ -236,7 +238,8 @@ document.addEventListener("keydown", function(event) {
|
|||
else if (ctrl && key === 80) saveAsImage("png"); // Ctrl + "P" to save as PNG
|
||||
else if (ctrl && key === 83) saveAsImage("svg"); // Ctrl + "S" to save as SVG
|
||||
else if (ctrl && key === 77) saveMap(); // Ctrl + "M" to save MAP file
|
||||
else if (ctrl && key === 76) mapToLoad.click(); // Ctrl + "L" to load MAP
|
||||
else if (ctrl && key === 85) mapToLoad.click(); // Ctrl + "U" to load MAP from URL
|
||||
else if (ctrl && key === 76) mapToLoad.click(); // Ctrl + "L" to load MAP from local file
|
||||
else if (key === 46) removeElementOnKey(); // "Delete" to remove the selected element
|
||||
|
||||
else if (shift && key === 192) console.log(pack.cells); // Shift + "`" to log cells data
|
||||
|
|
|
|||
|
|
@ -677,6 +677,7 @@ optionsContent.addEventListener("input", function(event) {
|
|||
else if (id === "provincesInput") provincesOutput.value = value;
|
||||
else if (id === "provincesOutput") provincesOutput.value = value;
|
||||
else if (id === "provincesOutput") powerOutput.value = value;
|
||||
else if (id === "powerInput") powerOutput.value = value;
|
||||
else if (id === "powerOutput") powerInput.value = value;
|
||||
else if (id === "neutralInput") neutralOutput.value = value;
|
||||
else if (id === "neutralOutput") neutralInput.value = value;
|
||||
|
|
@ -991,12 +992,14 @@ document.getElementById("sticked").addEventListener("click", function(event) {
|
|||
const id = event.target.id;
|
||||
if (id === "newMapButton") regeneratePrompt();
|
||||
else if (id === "saveButton") toggleSavePane();
|
||||
else if (id === "loadMap") mapToLoad.click();
|
||||
else if (id === "loadButton") toggleLoadPane();
|
||||
else if (id === "zoomReset") resetZoom(1000);
|
||||
else if (id === "saveMap") saveMap();
|
||||
else if (id === "saveSVG") saveAsImage("svg");
|
||||
else if (id === "savePNG") saveAsImage("png");
|
||||
if (id === "saveMap" || id === "saveSVG" || id === "savePNG") toggleSavePane();
|
||||
if (id === "loadURL") {loadURL(); toggleLoadPane()}
|
||||
if (id === "loadMap") {mapToLoad.click(); toggleLoadPane()}
|
||||
});
|
||||
|
||||
function regeneratePrompt() {
|
||||
|
|
@ -1033,12 +1036,32 @@ function toggleSavePane() {
|
|||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function toggleLoadPane() {
|
||||
if (loadDropdown.style.display === "block") {loadDropdown.style.display = "none"; return;}
|
||||
loadDropdown.style.display = "block";
|
||||
}
|
||||
|
||||
function loadURL() {
|
||||
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
|
||||
const inner = `Provide URL to a .map file: <input id="mapURL" type="url" style="width: 254px" placeholder="http://www.e-cloud.com/fantasy_map.map"">`;
|
||||
alertMessage.innerHTML = inner;
|
||||
$("#alert").dialog({resizable: false, title: "Load map from URL", width: 280,
|
||||
buttons: {
|
||||
Load: function() {
|
||||
const value = mapURL.value;
|
||||
if (!pattern.test(value)) {tip("Please provide a valid URL", false, "error"); return;}
|
||||
loadMapFromURL(value);
|
||||
$(this).dialog("close");
|
||||
},
|
||||
Cancel: function() {$(this).dialog("close");}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// load map
|
||||
document.getElementById("mapToLoad").addEventListener("change", function() {
|
||||
closeDialogs();
|
||||
const fileToLoad = this.files[0];
|
||||
this.value = "";
|
||||
uploadFile(fileToLoad);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue