Skip to content

Commit

Permalink
Added additional support for Spanish, Russian, Chinese and German
Browse files Browse the repository at this point in the history
  • Loading branch information
louis-e committed Jan 5, 2025
1 parent 4f749d3 commit 9ad0b5d
Show file tree
Hide file tree
Showing 8 changed files with 354 additions and 49 deletions.
36 changes: 18 additions & 18 deletions gui-src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<div class="flex-container">
<!-- Left Box: Map and BBox Input -->
<section class="section map-box" style="margin-bottom: 0; padding-bottom: 0;">
<h2>Select Location</h2>
<span id="bbox-text" style="font-size: 1.0em; display: block; margin-top: -8px; margin-bottom: 3px;">
<h2 data-localize="select_location">Select Location</h2>
<span id="bbox-text" style="font-size: 1.0em; display: block; margin-top: -8px; margin-bottom: 3px;" data-localize="zoom_in_and_choose">
Zoom in and choose your area using the rectangle tool
</span>
<iframe src="maps.html" width="100%" height="300" class="map-container" title="Map Picker"></iframe>
Expand All @@ -33,14 +33,14 @@ <h2>Select Location</h2>
<!-- Right Box: Directory Selection, Start Button, and Progress Bar -->
<section class="section controls-box">
<div class="controls-content">
<h2>Select World</h2>
<h2 data-localize="select_world">Select World</h2>

<!-- Updated Tooltip Structure -->
<div class="tooltip" style="width: 100%;">
<button type="button" onclick="openWorldPicker()" style="padding: 10px; line-height: 1.2; width: 100%;">
<button type="button" onclick="openWorldPicker()" style="padding: 10px; line-height: 1.2; width: 100%;" data-localize="choose_world">
Choose World
<br>
<span id="selected-world" style="font-size: 0.8em; color: #fecc44; display: block; margin-top: 4px;">
<span id="selected-world" style="font-size: 0.8em; color: #fecc44; display: block; margin-top: 4px;" data-localize="no_world_selected">
No world selected
</span>
</button>
Expand All @@ -50,15 +50,15 @@ <h2>Select World</h2>
</div>

<div class="button-container">
<button type="button" id="start-button" class="start-button" onclick="startGeneration()">Start Generation</button>
<button type="button" id="start-button" class="start-button" onclick="startGeneration()" data-localize="start_generation">Start Generation</button>
<button type="button" class="settings-button" onclick="openSettings()">
<i class="gear-icon"></i>
</button>
</div>
<br><br>

<div class="progress-section">
<h2>Progress</h2>
<h2 data-localize="progress">Progress</h2>
<div class="progress-bar-container">
<div class="progress-bar" id="progress-bar"></div>
</div>
Expand All @@ -75,59 +75,59 @@ <h2>Progress</h2>
<div id="world-modal" class="modal" style="display: none;">
<div class="modal-content">
<span class="close-button" onclick="closeWorldPicker()">&times;</span>
<h2>Choose World</h2>
<h2 data-localize="choose_world_modal_title">Choose World</h2>

<button type="button" id="select-world-button" class="select-world-button" onclick="selectWorld(false)">Select existing world</button>
<button type="button" id="generate-world-button" class="generate-world-button" onclick="selectWorld(true)">Generate new world</button>
<button type="button" id="select-world-button" class="select-world-button" onclick="selectWorld(false)" data-localize="select_existing_world">Select existing world</button>
<button type="button" id="generate-world-button" class="generate-world-button" onclick="selectWorld(true)" data-localize="generate_new_world">Generate new world</button>
</div>
</div>

<!-- Settings Modal -->
<div id="settings-modal" class="modal" style="display: none;">
<div class="modal-content">
<span class="close-button" onclick="closeSettings()">&times;</span>
<h2>Customization Settings</h2>
<h2 data-localize="customization_settings">Customization Settings</h2>

<!-- Winter Mode Toggle Button -->
<div class="winter-toggle-container">
<label for="winter-toggle">Winter Mode:</label>
<label for="winter-toggle" data-localize="winter_mode">Winter Mode:</label>
<input type="checkbox" id="winter-toggle" name="winter-toggle">
</div>

<!-- World Scale Slider -->
<div class="scale-slider-container">
<label for="scale-value-slider">World Scale:</label>
<label for="scale-value-slider" data-localize="world_scale">World Scale:</label>
<input type="range" id="scale-value-slider" name="scale-value-slider" min="0.30" max="2.5" step="0.1" value="1">
<span id="slider-value">1.00</span>
</div>

<!-- Bounding Box Input -->
<div class="bbox-input-container">
<label for="bbox-coords">Custom Bounding Box:</label>
<label for="bbox-coords" data-localize="custom_bounding_box">Custom Bounding Box:</label>
<input type="text" id="bbox-coords" name="bbox-coords" maxlength="55" style="width: 280px;" autocomplete="one-time-code" placeholder="Format: lat,lng,lat,lng">
</div>

<!-- Floodfill Timeout Input -->
<div class="timeout-input-container">
<label for="floodfill-timeout">Floodfill Timeout (sec):</label>
<label for="floodfill-timeout" data-localize="floodfill_timeout">Floodfill Timeout (sec):</label>
<input type="number" id="floodfill-timeout" name="floodfill-timeout" min="0" step="1" value="20" style="width: 100px;" placeholder="Seconds">
</div><br>

<!-- Ground Level Input -->
<div class="ground-level-input-container">
<label for="ground-level">Ground Level:</label>
<label for="ground-level" data-localize="ground_level">Ground Level:</label>
<input type="number" id="ground-level" name="ground-level" min="-64" max="290" value="-62" style="width: 100px;" placeholder="Ground Level">
</div>
</div>
</div>

<!-- Footer -->
<footer class="footer">
<a href="https://github.com/louis-e/arnis" target="_blank" class="footer-link">
<a href="https://github.com/louis-e/arnis" target="_blank" class="footer-link" data-localize="footer_text">
© <span id="current-year"></span> Arnis v<span id="version-placeholder">x.x.x</span> by louis-e
</a>
</footer>
</main>
</body>

</html>
</html>
170 changes: 146 additions & 24 deletions gui-src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,133 @@ const { invoke } = window.__TAURI__.core;

// Initialize elements and start the demo progress
window.addEventListener("DOMContentLoaded", async () => {
initFooter();
await checkForUpdates();
registerMessageEvent();
window.selectWorld = selectWorld;
window.startGeneration = startGeneration;
setupProgressListener();
initSettings();
initWorldPicker();
handleBboxInput();
const language = detectLanguage();
const localization = await loadLocalization(language);
await applyLocalization(localization);
initFooter();
await checkForUpdates();
});

async function loadLocalization(language) {
const response = await fetch(`./locales/${language}.json`);
const localization = await response.json();
return localization;
}

async function applyLocalization(localization) {
const selectLocationElement = document.querySelector("h2[data-localize='select_location']");
if (selectLocationElement) {
selectLocationElement.textContent = localization.select_location;
}

const bboxTextElement = document.getElementById("bbox-text");
if (bboxTextElement) {
bboxTextElement.textContent = localization.zoom_in_and_choose;
}

const selectWorldElement = document.querySelector("h2[data-localize='select_world']");
if (selectWorldElement) {
selectWorldElement.textContent = localization.select_world;
}

const chooseWorldButton = document.querySelector("button[data-localize='choose_world']");
if (chooseWorldButton) {
chooseWorldButton.firstChild.textContent = localization.choose_world;
}

const selectedWorldElement = document.getElementById("selected-world");
if (selectedWorldElement) {
selectedWorldElement.textContent = localization.no_world_selected;
}

const startButtonElement = document.getElementById("start-button");
if (startButtonElement) {
startButtonElement.textContent = localization.start_generation;
}

const progressElement = document.querySelector("h2[data-localize='progress']");
if (progressElement) {
progressElement.textContent = localization.progress;
}

const chooseWorldModalTitle = document.querySelector("h2[data-localize='choose_world_modal_title']");
if (chooseWorldModalTitle) {
chooseWorldModalTitle.textContent = localization.choose_world_modal_title;
}

const selectExistingWorldButton = document.querySelector("button[data-localize='select_existing_world']");
if (selectExistingWorldButton) {
selectExistingWorldButton.textContent = localization.select_existing_world;
}

const generateNewWorldButton = document.querySelector("button[data-localize='generate_new_world']");
if (generateNewWorldButton) {
generateNewWorldButton.textContent = localization.generate_new_world;
}

const customizationSettingsTitle = document.querySelector("h2[data-localize='customization_settings']");
if (customizationSettingsTitle) {
customizationSettingsTitle.textContent = localization.customization_settings;
}

const winterModeLabel = document.querySelector("label[data-localize='winter_mode']");
if (winterModeLabel) {
winterModeLabel.textContent = localization.winter_mode;
}

const worldScaleLabel = document.querySelector("label[data-localize='world_scale']");
if (worldScaleLabel) {
worldScaleLabel.textContent = localization.world_scale;
}

const customBoundingBoxLabel = document.querySelector("label[data-localize='custom_bounding_box']");
if (customBoundingBoxLabel) {
customBoundingBoxLabel.textContent = localization.custom_bounding_box;
}

const floodfillTimeoutLabel = document.querySelector("label[data-localize='floodfill_timeout']");
if (floodfillTimeoutLabel) {
floodfillTimeoutLabel.textContent = localization.floodfill_timeout;
}

const groundLevelLabel = document.querySelector("label[data-localize='ground_level']");
if (groundLevelLabel) {
groundLevelLabel.textContent = localization.ground_level;
}

const footerLinkElement = document.querySelector(".footer-link");
if (footerLinkElement) {
footerLinkElement.textContent = localization.footer_text.replace("{year}", new Date().getFullYear()).replace("{version}", await invoke('gui_get_version'));
}

// Update error messages
window.localization = localization;
}

function detectLanguage() {
const lang = navigator.language || navigator.userLanguage;
const langCode = lang.split('-')[0];
switch (langCode) {
case 'es':
return 'es';
case 'ru':
return 'ru';
case 'de':
return 'de';
case 'zh':
return 'zh';
default:
return 'en';
}
}

// Function to initialize the footer with the current year and version
async function initFooter() {
const currentYear = new Date().getFullYear();
Expand Down Expand Up @@ -42,7 +158,7 @@ async function checkForUpdates() {
updateMessage.style.display = "block";
updateMessage.style.textDecoration = "none";

updateMessage.textContent = "There's a new version available! Click here to download it.";
updateMessage.textContent = window.localization.new_version_available;
footer.style.marginTop = "15px";
footer.appendChild(updateMessage);
}
Expand Down Expand Up @@ -179,17 +295,17 @@ function handleBboxInput() {
window.dispatchEvent(new MessageEvent('message', { data: { bboxText } }));

// Update the info text
bboxInfo.textContent = "Custom selection confirmed!";
bboxInfo.textContent = window.localization.custom_selection_confirmed;
bboxInfo.style.color = "#7bd864";
} else {
// Valid numbers but invalid order or range
bboxInfo.textContent = "Error: Coordinates are out of range or incorrectly ordered (Lat before Lng required).";
bboxInfo.textContent = window.localization.error_coordinates_out_of_range;
bboxInfo.style.color = "#fecc44";
selectedBBox = "";
}
} else {
// Input doesn't match the required format
bboxInfo.textContent = "Invalid format. Please use 'lat,lng,lat,lng' or 'lat lng lat lng'.";
bboxInfo.textContent = window.localization.invalid_format;
bboxInfo.style.color = "#fecc44";
selectedBBox = "";
}
Expand Down Expand Up @@ -222,8 +338,8 @@ function normalizeLongitude(lon) {
return ((lon + 180) % 360 + 360) % 360 - 180;
}

const threshold1 = 12332660.00;
const threshold2 = 36084700.00;
const threshold1 = 35000000.00;
const threshold2 = 50000000.00;
let selectedBBox = "";

// Function to handle incoming bbox data
Expand All @@ -248,13 +364,13 @@ function displayBboxInfoText(bboxText) {
const selectedSize = calculateBBoxSize(lng1, lat1, lng2, lat2);

if (selectedSize > threshold2) {
bboxInfo.textContent = "This area is very large and could exceed typical computing limits.";
bboxInfo.textContent = window.localization.area_too_large;
bboxInfo.style.color = "#fa7878";
} else if (selectedSize > threshold1) {
bboxInfo.textContent = "The area is quite extensive and may take significant time and resources.";
bboxInfo.textContent = window.localization.area_extensive;
bboxInfo.style.color = "#fecc44";
} else {
bboxInfo.textContent = "Selection confirmed!";
bboxInfo.textContent = window.localization.selection_confirmed;
bboxInfo.style.color = "#7bd864";
}
}
Expand All @@ -270,15 +386,27 @@ async function selectWorld(generate_new_world) {
document.getElementById('selected-world').style.color = "#fecc44";
}
} catch (error) {
worldPath = error;
console.error(error);
document.getElementById('selected-world').textContent = error;
document.getElementById('selected-world').style.color = "#fa7878";
handleWorldSelectionError(error);
}

closeWorldPicker();
}

function handleWorldSelectionError(errorCode) {
const errorMessages = {
1: window.localization.minecraft_directory_not_found,
2: window.localization.world_in_use,
3: window.localization.failed_to_create_world,
4: window.localization.no_world_selected_error
};

const errorMessage = errorMessages[errorCode] || "Unknown error";
document.getElementById('selected-world').textContent = errorMessage;
document.getElementById('selected-world').style.color = "#fa7878";
worldPath = "";
console.error(error);
}

let generationButtonEnabled = true;
async function startGeneration() {
try {
Expand All @@ -287,19 +415,13 @@ async function startGeneration() {
}

if (!selectedBBox || selectedBBox == "0.000000 0.000000 0.000000 0.000000") {
document.getElementById('bbox-info').textContent = "Select a location first!";
document.getElementById('bbox-info').textContent = window.localization.select_location_first;
document.getElementById('bbox-info').style.color = "#fa7878";
return;
}

if (
worldPath === "No world selected" ||
worldPath == "Invalid Minecraft world" ||
worldPath == "The selected world is currently in use" ||
worldPath == "Minecraft directory not found" ||
worldPath === ""
) {
document.getElementById('selected-world').textContent = "Select a Minecraft world first!";
if (!worldPath || worldPath === "") {
document.getElementById('selected-world').textContent = window.localization.select_minecraft_world_first;
document.getElementById('selected-world').style.color = "#fa7878";
return;
}
Expand Down
Loading

0 comments on commit 9ad0b5d

Please sign in to comment.