SETTINGS: Validate and save; form errors.
This commit is contained in:
parent
14c02f614a
commit
d6708ed0ee
5 changed files with 88 additions and 7 deletions
|
@ -31,7 +31,7 @@
|
||||||
Minimum value:
|
Minimum value:
|
||||||
</label>
|
</label>
|
||||||
<div class="col-2 system charted p-0">
|
<div class="col-2 system charted p-0">
|
||||||
<input type="text" class="form-control" id="minValue">
|
<input type="text" class="form-control" id="minValue" name="minValue">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
Maximum distance:
|
Maximum distance:
|
||||||
</label>
|
</label>
|
||||||
<div class="col-2 system charted p-0">
|
<div class="col-2 system charted p-0">
|
||||||
<input type="text" class="form-control" id="maxDistance">
|
<input type="text" class="form-control" id="maxDistance" name="maxDistance">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -224,4 +224,9 @@ div b.active.landable {
|
||||||
.separator .btn:hover {
|
.separator .btn:hover {
|
||||||
color: var(--accent-light);
|
color: var(--accent-light);
|
||||||
transition: color 300ms;
|
transition: color 300ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-error {
|
||||||
|
color: var(--main);
|
||||||
|
margin-left: 1rem;
|
||||||
}
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
const fs = require('node:fs/promises')
|
const fs = require('node:fs/promises');
|
||||||
const { statSync, writeFileSync, readFileSync } = require('node:fs')
|
const { statSync, writeFileSync, readFileSync } = require('node:fs');
|
||||||
const os = require('node:os')
|
const os = require('node:os');
|
||||||
const path = require('node:path')
|
const path = require('node:path');
|
||||||
|
|
||||||
|
import { Log } from "./Log";
|
||||||
|
|
||||||
interface settingsFile {
|
interface settingsFile {
|
||||||
minValue: number,
|
minValue: number,
|
||||||
|
@ -12,6 +14,7 @@ export class Settings {
|
||||||
static #instance: Settings;
|
static #instance: Settings;
|
||||||
|
|
||||||
#file: string;
|
#file: string;
|
||||||
|
#writing: boolean;
|
||||||
|
|
||||||
minValue: number;
|
minValue: number;
|
||||||
maxDistance: number;
|
maxDistance: number;
|
||||||
|
@ -42,6 +45,8 @@ export class Settings {
|
||||||
const contents: settingsFile = JSON.parse(readFileSync(this.#file, { encoding: 'utf8' }));
|
const contents: settingsFile = JSON.parse(readFileSync(this.#file, { encoding: 'utf8' }));
|
||||||
this.minValue = contents.minValue;
|
this.minValue = contents.minValue;
|
||||||
this.maxDistance = contents.maxDistance;
|
this.maxDistance = contents.maxDistance;
|
||||||
|
|
||||||
|
this.#writing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get(isPackaged: boolean = false): Settings {
|
static get(isPackaged: boolean = false): Settings {
|
||||||
|
@ -51,4 +56,24 @@ export class Settings {
|
||||||
|
|
||||||
return Settings.#instance;
|
return Settings.#instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------------- save ---- */
|
||||||
|
|
||||||
|
async save(settings: settingsFile): Promise<boolean> {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -183,4 +183,13 @@ export class UI {
|
||||||
static setValue(row, value) {
|
static setValue(row, value) {
|
||||||
row.children().filter('.value').text(UI.#formatNumber(value));
|
row.children().filter('.value').text(UI.#formatNumber(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ addFormError ---- */
|
||||||
|
|
||||||
|
static addFormError(field, msg) {
|
||||||
|
const label = $(field).parent().parent().children().filter('label');
|
||||||
|
const error = $('<span>').addClass('form-error');
|
||||||
|
error.text(msg);
|
||||||
|
label.appendChild(error);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -4,8 +4,10 @@ import './assets/index.css';
|
||||||
import './assets/ldom.min';
|
import './assets/ldom.min';
|
||||||
|
|
||||||
const { ipcRenderer } = require('electron');
|
const { ipcRenderer } = require('electron');
|
||||||
|
const { setTimeout } = require('node:timers/promises');
|
||||||
|
|
||||||
import { Settings } from './models/Settings';
|
import { Settings } from './models/Settings';
|
||||||
|
import { UI } from './models/UI';
|
||||||
|
|
||||||
const settings = Settings.get();
|
const settings = Settings.get();
|
||||||
|
|
||||||
|
@ -24,4 +26,44 @@ $('.backBtn').on('click', () => {
|
||||||
/* ------------------------------------------------------------------- insert current values ---- */
|
/* ------------------------------------------------------------------- insert current values ---- */
|
||||||
|
|
||||||
$('#minValue').attr('value', settings.minValue);
|
$('#minValue').attr('value', settings.minValue);
|
||||||
$('#maxDistance').attr('value', settings.maxDistance);
|
$('#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);
|
||||||
|
}
|
||||||
|
});
|
Loading…
Reference in a new issue