diff --git a/settings.html b/settings.html
index f7f2121..d93cd8f 100644
--- a/settings.html
+++ b/settings.html
@@ -31,7 +31,7 @@
Minimum value:
-
+
@@ -40,7 +40,7 @@
Maximum distance:
-
+
diff --git a/src/assets/index.css b/src/assets/index.css
index e971337..081ef6e 100755
--- a/src/assets/index.css
+++ b/src/assets/index.css
@@ -224,4 +224,9 @@ div b.active.landable {
.separator .btn:hover {
color: var(--accent-light);
transition: color 300ms;
+}
+
+.form-error {
+ color: var(--main);
+ margin-left: 1rem;
}
\ No newline at end of file
diff --git a/src/models/Settings.ts b/src/models/Settings.ts
index 776dc4a..ff874a9 100644
--- a/src/models/Settings.ts
+++ b/src/models/Settings.ts
@@ -1,7 +1,9 @@
-const fs = require('node:fs/promises')
-const { statSync, writeFileSync, readFileSync } = require('node:fs')
-const os = require('node:os')
-const path = require('node:path')
+const fs = require('node:fs/promises');
+const { statSync, writeFileSync, readFileSync } = require('node:fs');
+const os = require('node:os');
+const path = require('node:path');
+
+import { Log } from "./Log";
interface settingsFile {
minValue: number,
@@ -12,6 +14,7 @@ export class Settings {
static #instance: Settings;
#file: string;
+ #writing: boolean;
minValue: number;
maxDistance: number;
@@ -42,6 +45,8 @@ export class Settings {
const contents: settingsFile = JSON.parse(readFileSync(this.#file, { encoding: 'utf8' }));
this.minValue = contents.minValue;
this.maxDistance = contents.maxDistance;
+
+ this.#writing = false;
}
static get(isPackaged: boolean = false): Settings {
@@ -51,4 +56,24 @@ export class Settings {
return Settings.#instance;
}
+
+ /* -------------------------------------------------------------------------------- save ---- */
+
+ async save(settings: settingsFile): Promise {
+ if (!this.#writing) {
+ try {
+ // So we don't try to write again before this one finishes.
+ this.#writing = true;
+ await fs.writeFile(this.#file, JSON.stringify(settings));
+ this.#writing = false;
+
+ return true;
+ } catch (err) {
+ Log.write(err);
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/models/UI.js b/src/models/UI.js
index ca50983..91d58a5 100755
--- a/src/models/UI.js
+++ b/src/models/UI.js
@@ -183,4 +183,13 @@ export class UI {
static setValue(row, value) {
row.children().filter('.value').text(UI.#formatNumber(value));
}
+
+ /* ------------------------------------------------------------------------ addFormError ---- */
+
+ static addFormError(field, msg) {
+ const label = $(field).parent().parent().children().filter('label');
+ const error = $('').addClass('form-error');
+ error.text(msg);
+ label.appendChild(error);
+ }
}
\ No newline at end of file
diff --git a/src/settings.js b/src/settings.js
index d09c4a1..9decd06 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -4,8 +4,10 @@ import './assets/index.css';
import './assets/ldom.min';
const { ipcRenderer } = require('electron');
+const { setTimeout } = require('node:timers/promises');
import { Settings } from './models/Settings';
+import { UI } from './models/UI';
const settings = Settings.get();
@@ -24,4 +26,44 @@ $('.backBtn').on('click', () => {
/* ------------------------------------------------------------------- insert current values ---- */
$('#minValue').attr('value', settings.minValue);
-$('#maxDistance').attr('value', settings.maxDistance);
\ No newline at end of file
+$('#maxDistance').attr('value', settings.maxDistance);
+
+/* ---------------------------------------------------------------------------- process form ---- */
+
+$('form').on('submit', async function (event) {
+ event.preventDefault();
+ $('.form-error').remove();
+
+ // Retrieve and normalize data.
+ const formData = new FormData(event.target);
+ const data = Object.fromEntries(formData.entries());
+
+ data.minValue = parseInt(data.minValue.replace(/\D/g, ''));
+ data.maxDistance = parseInt(data.maxDistance.replace(/\D/g, ''));
+
+ // Check for any errors.
+ let errors = false;
+ if (isNaN(data.minValue)) {
+ UI.addFormError('#minValue', 'Please enter a number!');
+ errors = true;
+ }
+
+ if (isNaN(data.maxDistance)) {
+ UI.addFormError('#maxDistance', 'Please enter a number!');
+ }
+
+ // If no errors, save.
+ if (!errors) {
+ let tries = 0;
+ do {
+ let result = await settings.save(data);
+
+ if (!result) {
+ await setTimeout(3000);
+ tries++;
+ } else {
+ break;
+ }
+ } while (tries < 3);
+ }
+});
\ No newline at end of file