Custom colors!

This commit is contained in:
punkfairie 2023-05-14 15:44:52 -07:00
parent ce573865f6
commit 68bda87253
9 changed files with 269 additions and 136 deletions

36
package-lock.json generated
View file

@ -14,9 +14,11 @@
"electron-squirrel-startup": "^1.0.0", "electron-squirrel-startup": "^1.0.0",
"elite-matrix": "^1.0.0", "elite-matrix": "^1.0.0",
"glob": "^10.2.2", "glob": "^10.2.2",
"ini": "^4.1.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"reverse-line-reader": "^0.2.6", "reverse-line-reader": "^0.2.6",
"tail": "^2.2.6" "tail": "^2.2.6",
"xml-js": "^1.6.11"
}, },
"devDependencies": { "devDependencies": {
"@electron-forge/cli": "^6.1.1", "@electron-forge/cli": "^6.1.1",
@ -3796,6 +3798,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/global-prefix/node_modules/ini": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true
},
"node_modules/global-prefix/node_modules/which": { "node_modules/global-prefix/node_modules/which": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@ -4075,10 +4083,12 @@
"dev": true "dev": true
}, },
"node_modules/ini": { "node_modules/ini": {
"version": "1.3.8", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.0.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "integrity": "sha512-HLR38RSF2iulAzc3I/sma4CoYxQP844rPYCNfzGDOHqa/YqVlwuuZgBx6M50/X8dKgzk0cm1qRg3+47mK2N+cQ==",
"dev": true "engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
}, },
"node_modules/interpret": { "node_modules/interpret": {
"version": "3.1.1", "version": "3.1.1",
@ -5982,6 +5992,11 @@
"node": ">=14.0.0" "node": ">=14.0.0"
} }
}, },
"node_modules/sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"node_modules/semver": { "node_modules/semver": {
"version": "7.5.0", "version": "7.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
@ -6951,6 +6966,17 @@
} }
} }
}, },
"node_modules/xml-js": {
"version": "1.6.11",
"resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz",
"integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==",
"dependencies": {
"sax": "^1.2.4"
},
"bin": {
"xml-js": "bin/cli.js"
}
},
"node_modules/xmlbuilder": { "node_modules/xmlbuilder": {
"version": "15.1.1", "version": "15.1.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",

View file

@ -45,8 +45,10 @@
"electron-squirrel-startup": "^1.0.0", "electron-squirrel-startup": "^1.0.0",
"elite-matrix": "^1.0.0", "elite-matrix": "^1.0.0",
"glob": "^10.2.2", "glob": "^10.2.2",
"ini": "^4.1.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"reverse-line-reader": "^0.2.6", "reverse-line-reader": "^0.2.6",
"tail": "^2.2.6" "tail": "^2.2.6",
"xml-js": "^1.6.11"
} }
} }

View file

@ -45,9 +45,9 @@
</div> </div>
<div class="row ms-1 me-1"> <div class="row ms-1 me-1">
<div class="col col-form-label system charted"> <label class="col col-form-label system charted">
Where to get RGB matrix: Where to get RGB matrix:
</div> </label>
<div class="col-2 system charted p-0 text-center"> <div class="col-2 system charted p-0 text-center">
<button type="button" class="btn" id="matrixBtn">Select File</button> <button type="button" class="btn" id="matrixBtn">Select File</button>
<input type="hidden" id="matrixFile" name="matrixFile"> <input type="hidden" id="matrixFile" name="matrixFile">

View file

@ -98,7 +98,7 @@ div.charted b.inactive {
} }
.highlighted { .highlighted {
color: var(--secondary-dark); color: var(--background);
background: var(--main); background: var(--main);
} }

View file

@ -1,38 +1,38 @@
import type { Tail as TailType } from 'tail' import type { Tail as TailType } from 'tail';
import type { autoScan, completeFsdJump, detailedScan, journalEntry, navRoute, planetScan } from "../@types/journalLines" import type { autoScan, completeFsdJump, detailedScan, journalEntry, navRoute, planetScan } from "../@types/journalLines";
const EventEmitter = require('node:events') const EventEmitter = require('node:events');
import * as _ from 'lodash-es' import * as _ from 'lodash-es';
const path = require('node:path') const path = require('node:path');
const { readFile } = require('node:fs/promises') const { readFile } = require('node:fs/promises');
const reverseLineReader = require('reverse-line-reader') const reverseLineReader = require('reverse-line-reader');
const Tail = require('tail').Tail const Tail = require('tail').Tail;
import { System } from "./System" import { System } from "./System";
import { Log } from "./Log" import { Log } from "./Log";
import { Body } from "./Body" import { Body } from "./Body";
export class Journal extends EventEmitter { export class Journal extends EventEmitter {
#path: string #path: string;
testing: string testing: string;
location: System location: System;
navRoute: System[] navRoute: System[];
constructor(journalPath: string) { constructor(journalPath: string) {
super() super();
this.#path = journalPath this.#path = journalPath;
this.location = new System() this.location = new System();
this.navRoute = [] this.navRoute = [];
// Start ReverseLineReader chain here. // Start ReverseLineReader chain here.
Log.write(`Journal initialized. Attempting to find current location.`) Log.write(`Journal initialized. Attempting to find current location.`);
this.#getLastFsdJump() this.#getLastFsdJump();
// -> IF no FSD Jump: this.#getLastLocation() // -> IF no FSD Jump: this.#getLastLocation()
// --> this.#getScannedBodies() // --> this.#getScannedBodies()
this.testing = this.#path this.testing = this.#path;
} }
/* --------------------------------------------------------------------- #getLastFsdJump ---- */ /* --------------------------------------------------------------------- #getLastFsdJump ---- */
@ -42,22 +42,23 @@ export class Journal extends EventEmitter {
#getLastFsdJump(): void { #getLastFsdJump(): void {
reverseLineReader.eachLine(this.#path, (raw: string) => { reverseLineReader.eachLine(this.#path, (raw: string) => {
if (raw) { //skip blank line at end of file if (raw) { //skip blank line at end of file
const line: journalEntry = JSON.parse(raw) const line: journalEntry = JSON.parse(raw);
if (line.event === 'FSDJump') { if (line.event === 'FSDJump') {
this.location = new System((line as completeFsdJump)) this.location = new System((line as completeFsdJump));
Log.write(`Current location set to ${this.location.name}.`) Log.write(`Current location set to ${this.location.name}.`);
this.emit('ENTERED_NEW_SYSTEM') this.emit('ENTERED_NEW_SYSTEM');
return false return false;
} }
} }
}).then(() => { }).then(() => {
if (this.location.name === 'Unknown') { if (this.location.name === 'Unknown') {
Log.write('Unable to find last hyperspace jump. Searching for last known location.') Log
this.#getLastLocation() .write('Unable to find last hyperspace jump. Searching for last known location.');
this.#getLastLocation();
} else { } else {
Log.write('Attempting to find scanned bodies in current system.') Log.write('Attempting to find scanned bodies in current system.');
this.#getScannedBodies() this.#getScannedBodies();
} }
}) })
} }
@ -69,27 +70,27 @@ export class Journal extends EventEmitter {
reverseLineReader.eachLine(this.#path, (raw: string, last: boolean) => { reverseLineReader.eachLine(this.#path, (raw: string, last: boolean) => {
// Extra check just to be sure. // Extra check just to be sure.
if (this.location.name !== 'Unknown') { if (this.location.name !== 'Unknown') {
return false return false;
} }
if (raw) { if (raw) {
const line: journalEntry = JSON.parse(raw) const line: journalEntry = JSON.parse(raw);
if (line.event === 'Location') { if (line.event === 'Location') {
this.location = new System((line as completeFsdJump)) this.location = new System((line as completeFsdJump));
Log.write(`Current location set to ${this.location.name}.`) Log.write(`Current location set to ${this.location.name}.`);
this.emit('ENTERED_NEW_SYSTEM') this.emit('ENTERED_NEW_SYSTEM');
return false return false;
} else if (last) { } else if (last) {
Log.write('WARNING: Unable to find last known location.') Log.write('WARNING: Unable to find last known location.');
return false return false;
} }
} }
}).then(() => { }).then(() => {
if (this.location.name !== 'Unknown') { if (this.location.name !== 'Unknown') {
Log.write('Attempting to find scanned bodies in current system.') Log.write('Attempting to find scanned bodies in current system.');
this.#getScannedBodies() this.#getScannedBodies();
} }
}) })
} }
@ -102,26 +103,26 @@ export class Journal extends EventEmitter {
reverseLineReader.eachLine(this.#path, (raw: string) => { reverseLineReader.eachLine(this.#path, (raw: string) => {
if (raw) { if (raw) {
const line: journalEntry = JSON.parse(raw) const line: journalEntry = JSON.parse(raw);
// Check if previous line was ScanType = Detailed, and handle that. // Check if previous line was ScanType = Detailed, and handle that.
if (dssLine) { if (dssLine) {
if (line.event === 'SAAScanComplete') { if (line.event === 'SAAScanComplete') {
// This was a DSS, so add to list with DSS flag set to true. // This was a DSS, so add to list with DSS flag set to true.
this.location.bodies.push(new Body(dssLine, true)) this.location.bodies.push(new Body(dssLine, true));
} else { } else {
// Else, check that the body hasn't already been added (by a DSS scan line). // Else, check that the body hasn't already been added (by a DSS scan line).
const dupChecker = {'BodyName': dssLine.BodyName, 'BodyID': dssLine.BodyID} const dupChecker = {'BodyName': dssLine.BodyName, 'BodyID': dssLine.BodyID};
const r = _.find(this.location.bodies, dupChecker) const r = _.find(this.location.bodies, dupChecker);
if (r === undefined) { if (r === undefined) {
// Body was not already logged, so add to list. // Body was not already logged, so add to list.
this.location.bodies.push(new Body(dssLine)) this.location.bodies.push(new Body(dssLine));
} }
} }
// Finally, clear the variable. // Finally, clear the variable.
dssLine = null dssLine = null;
} }
// Now move on to evaluating the current line. // Now move on to evaluating the current line.
@ -130,10 +131,10 @@ export class Journal extends EventEmitter {
// the one immediately above for event = SAAScanComplete, which indicates this // the one immediately above for event = SAAScanComplete, which indicates this
// was a DSS. // was a DSS.
if (line.ScanType === 'Detailed' && !('StarType' in line)) { if (line.ScanType === 'Detailed' && !('StarType' in line)) {
dssLine = (line as detailedScan) dssLine = (line as detailedScan);
} else if ('StarType' in line) { // Save stars to bodies list. } else if ('StarType' in line) { // Save stars to bodies list.
this.location.bodies.push(new Body((line as autoScan|detailedScan))) this.location.bodies.push(new Body((line as autoScan|detailedScan)));
} else if (line.ScanType === 'AutoScan') { // Save auto/discovery scan bodies. } else if (line.ScanType === 'AutoScan') { // Save auto/discovery scan bodies.
// Check if planet, and then do the duplicate check (otherwise it's an // Check if planet, and then do the duplicate check (otherwise it's an
@ -142,33 +143,33 @@ export class Journal extends EventEmitter {
const dupChecker = { const dupChecker = {
'BodyName': (line as planetScan<'AutoScan'>).BodyName, 'BodyName': (line as planetScan<'AutoScan'>).BodyName,
'BodyID': (line as planetScan<'AutoScan'>).BodyID, 'BodyID': (line as planetScan<'AutoScan'>).BodyID,
} };
const r = _.find(this.location.bodies, dupChecker) const r = _.find(this.location.bodies, dupChecker);
if (r === undefined) { if (r === undefined) {
this.location.bodies.push(new Body((line as autoScan))) this.location.bodies.push(new Body((line as autoScan)));
} }
} else { // Asteroids. } else { // Asteroids.
this.location.bodies.push(new Body((line as autoScan))) this.location.bodies.push(new Body((line as autoScan)));
} }
} }
} else if (line.event === 'FSDJump') { } else if (line.event === 'FSDJump') {
// Stop evaluating once we reach the beginning of current system entries. // Stop evaluating once we reach the beginning of current system entries.
return false return false;
} }
} }
}).then(() => { }).then(() => {
if (this.location.bodies.length > 0) { if (this.location.bodies.length > 0) {
Log.write('No scanned bodies found in current system.') Log.write('No scanned bodies found in current system.');
this.emit('BUILD_BODY_LIST') this.emit('BUILD_BODY_LIST');
} else { } else {
Log.write('Scanned bodies found.') Log.write('Scanned bodies found.');
} }
Log.write('Checking for nav route.') Log.write('Checking for nav route.');
this.#getNavRoute() this.#getNavRoute();
}) })
} }
@ -176,40 +177,40 @@ export class Journal extends EventEmitter {
async #getNavRoute(): Promise<void> { async #getNavRoute(): Promise<void> {
this.navRoute = [] // Clear previous route, to catch overwritten routes. this.navRoute = [] // Clear previous route, to catch overwritten routes.
let routeFile: string|null = null let routeFile: string|null = null;
try { try {
const filePath: string = path.dirname(this.#path) + '/NavRoute.json' const filePath: string = path.dirname(this.#path) + '/NavRoute.json';
routeFile = await readFile(filePath, {encoding: 'utf8'}) routeFile = await readFile(filePath, {encoding: 'utf8'});
} catch (err) { } catch (err) {
Log.write(`Error reading nav route file: ${err.message}.`) Log.write(`Error reading nav route file: ${err.message}.`);
} }
if (routeFile) { if (routeFile) {
const route: navRoute = JSON.parse(routeFile) const route: navRoute = JSON.parse(routeFile);
// system -> skip // system -> skip
// CURRENT -> push = true; skip // CURRENT -> push = true; skip
// system -> push // system -> push
let push: boolean = false let push: boolean = false;
route.Route.forEach((system) => { route.Route.forEach((system) => {
if (!push && system.SystemAddress === this.location.SystemAddress) { if (!push && system.SystemAddress === this.location.SystemAddress) {
push = true push = true;
} }
if (push && system.SystemAddress !== this.location.SystemAddress) { if (push && system.SystemAddress !== this.location.SystemAddress) {
this.navRoute.push(new System(system)) this.navRoute.push(new System(system));
} }
}) })
if (this.navRoute.length > 0) { if (this.navRoute.length > 0) {
Log.write('Nav route set.') Log.write('Nav route set.');
} else { } else {
Log.write('No nav route found.') Log.write('No nav route found.');
} }
// Call this no matter what, so that cleared routes are properly dealt with. // Call this no matter what, so that cleared routes are properly dealt with.
this.emit('SET_NAV_ROUTE') this.emit('SET_NAV_ROUTE');
} }
} }
@ -217,63 +218,63 @@ export class Journal extends EventEmitter {
// Watch the journal for changes. // Watch the journal for changes.
watch(): void { watch(): void {
const tail: TailType = new Tail(this.#path, {useWatchFile: true}) const tail: TailType = new Tail(this.#path, {useWatchFile: true});
Log.write(`Watching ${path.basename(this.#path)}...`) Log.write(`Watching ${path.basename(this.#path)}...`);
tail.on('line', (data) => data ? this.#parseLine(data) : undefined) tail.on('line', (data) => data ? this.#parseLine(data) : undefined);
tail.on('error', (err) => Log.write(`Tail error in Journal.watch(): ${err}`)) tail.on('error', (err) => Log.write(`Tail error in Journal.watch(): ${err}`));
} }
/* ------------------------------------------------------------------------ #parseLine() ---- */ /* ------------------------------------------------------------------------ #parseLine() ---- */
// Parse and handle journal lines. // Parse and handle journal lines.
#parseLine(raw: string) { #parseLine(raw: string) {
const line: journalEntry = JSON.parse(raw) const line: journalEntry = JSON.parse(raw);
let dssFlag: boolean = false let dssFlag: boolean = false;
switch (line.event) { switch (line.event) {
// Hyperspace jump started (3.. 2.. 1..) // Hyperspace jump started (3.. 2.. 1..)
case 'StartJump': { case 'StartJump': {
if ('JumpType' in line && line.JumpType === 'Hyperspace') { if ('JumpType' in line && line.JumpType === 'Hyperspace') {
this.emit('ENTERING_WITCH_SPACE') this.emit('ENTERING_WITCH_SPACE');
} }
break break;
} }
// CMDR jumped to new system, so update current location. // CMDR jumped to new system, so update current location.
case 'FSDJump': { case 'FSDJump': {
this.#handleFsdJump((line as completeFsdJump)) this.#handleFsdJump((line as completeFsdJump));
break break;
} }
// CMDR completed DSS scan, so set flag for when next line processes and we want to // CMDR completed DSS scan, so set flag for when next line processes and we want to
// figure out what kind of scan occurred. // figure out what kind of scan occurred.
case 'SAAScanComplete': { case 'SAAScanComplete': {
dssFlag = true dssFlag = true;
break break;
} }
// A scan occurred, so let's hand that info off to the appropriate function and then // A scan occurred, so let's hand that info off to the appropriate function and then
// reset the DSS flag. // reset the DSS flag.
case 'Scan': { case 'Scan': {
this.#handleScanLine((line as autoScan|detailedScan), dssFlag) this.#handleScanLine((line as autoScan|detailedScan), dssFlag);
dssFlag = false dssFlag = false;
break break;
} }
// CMDR set a new nav route. // CMDR set a new nav route.
case 'NavRoute': { case 'NavRoute': {
this.#getNavRoute() this.#getNavRoute();
break break;
} }
// CMDR cleared the nav route. // CMDR cleared the nav route.
case 'NavRouteClear': { case 'NavRouteClear': {
this.navRoute = [] this.navRoute = [];
Log.write('Nav route cleared.') Log.write('Nav route cleared.');
this.emit('SET_NAV_ROUTE') this.emit('SET_NAV_ROUTE');
break break;
} }
} }
} }
@ -281,49 +282,49 @@ export class Journal extends EventEmitter {
/* ---------------------------------------------------------------------- #handleFsdJump ---- */ /* ---------------------------------------------------------------------- #handleFsdJump ---- */
#handleFsdJump(line: completeFsdJump): void { #handleFsdJump(line: completeFsdJump): void {
this.location = new System(line) this.location = new System(line);
Log.write(`FSD Jump detected, current location updated to ${this.location.name}.`) Log.write(`FSD Jump detected, current location updated to ${this.location.name}.`);
if (this.navRoute.length > 0) { if (this.navRoute.length > 0) {
_.remove(this.navRoute, (system) => { _.remove(this.navRoute, (system) => {
return system.SystemAddress === this.location.SystemAddress return system.SystemAddress === this.location.SystemAddress;
}) })
} }
this.emit('ENTERED_NEW_SYSTEM') this.emit('ENTERED_NEW_SYSTEM');
} }
/* --------------------------------------------------------------------- #handleScanLine ---- */ /* --------------------------------------------------------------------- #handleScanLine ---- */
#handleScanLine(line: autoScan|detailedScan, DSS: boolean = false) { #handleScanLine(line: autoScan|detailedScan, DSS: boolean = false) {
const dupChecker = {'BodyName': line.BodyName, 'BodyID': line.BodyID} const dupChecker = {'BodyName': line.BodyName, 'BodyID': line.BodyID};
let body: Body|null = null let body: Body|null = null;
// If it's a DSS scan, then we should have already added the body to the list. But we'll // If it's a DSS scan, then we should have already added the body to the list. But we'll
// check to make sure. // check to make sure.
if (DSS) { if (DSS) {
// Using findIndex() rather than find() so we can edit the body if found. // Using findIndex() rather than find() so we can edit the body if found.
const bodyIndex: number = _.findIndex(this.location.bodies, dupChecker) const bodyIndex: number = _.findIndex(this.location.bodies, dupChecker);
if (bodyIndex > -1) { // Body was found in list, so simply toggle the DSS flag. if (bodyIndex > -1) { // Body was found in list, so simply toggle the DSS flag.
this.location.bodies[bodyIndex].DSSDone = true this.location.bodies[bodyIndex].DSSDone = true;
} else { // Body was missed on initial journal scan, so add it to the list. } else { // Body was missed on initial journal scan, so add it to the list.
body = new Body(line, true) body = new Body(line, true);
this.location.bodies.push(body) this.location.bodies.push(body);
} }
} else { // Otherwise it's an FSS or auto scan, and needs to be added to the list. } else { // Otherwise it's an FSS or auto scan, and needs to be added to the list.
// Probably overkill, but do a duplicate check just in case. // Probably overkill, but do a duplicate check just in case.
const r = _.find(this.location.bodies, dupChecker) const r = _.find(this.location.bodies, dupChecker);
if (r === undefined) { if (r === undefined) {
body = new Body(line) body = new Body(line);
this.location.bodies.push(body) this.location.bodies.push(body);
} }
} }
Log.write(`Scan detected. Body: ${line.BodyName}.`) Log.write(`Scan detected. Body: ${line.BodyName}.`);
this.emit('BODY_SCANNED', body, DSS) this.emit('BODY_SCANNED', body, DSS);
} }
} }

View file

@ -1,17 +1,22 @@
import { EliteMatrix } from "elite-matrix";
const EventEmitter = require('node:events');
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 ini = require('ini');
const os = require('node:os'); const os = require('node:os');
const path = require('node:path'); const path = require('node:path');
const { setTimeout } = require('node:timers/promises');
const xmlJS = require('xml-js');
import { EliteMatrix } from "elite-matrix";
import { Log } from "./Log"; import { Log } from "./Log";
interface settingsFile { interface settingsFile {
minValue: number, minValue: number,
maxDistance: number, maxDistance: number,
matrixFile: string,
} }
export class Settings { export class Settings extends EventEmitter {
static #instance: Settings; static #instance: Settings;
#file: string; #file: string;
@ -20,10 +25,12 @@ export class Settings {
minValue: number; minValue: number;
maxDistance: number; maxDistance: number;
#matrixFile?: string; #matrixFile: null|string;
matrix?: EliteMatrix; matrix?: EliteMatrix;
private constructor(isPackaged: boolean) { private constructor(isPackaged: boolean) {
super();
if (!isPackaged && os.platform() === 'linux') { if (!isPackaged && os.platform() === 'linux') {
this.#file = '/mnt/c/Users/marle/ed-safari-settings.json'; this.#file = '/mnt/c/Users/marle/ed-safari-settings.json';
} else { } else {
@ -39,6 +46,7 @@ export class Settings {
const contents: string = JSON.stringify({ const contents: string = JSON.stringify({
minValue: 500000, minValue: 500000,
maxDistance: 10000, maxDistance: 10000,
matrixFile: '',
}); });
writeFileSync(this.#file, contents); writeFileSync(this.#file, contents);
@ -49,8 +57,12 @@ 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.#matrixFile = contents.matrixFile;
this.#writing = false; this.#writing = false;
if (this.#matrixFile) {
this.#setMatrix();
}
} }
static get(isPackaged: boolean = false): Settings { static get(isPackaged: boolean = false): Settings {
@ -74,6 +86,10 @@ export class Settings {
this.#writing = false; this.#writing = false;
Log.write('Settings saved!'); Log.write('Settings saved!');
// Update Settings props.
await this.#read();
return true; return true;
} catch (err) { } catch (err) {
Log.write(err); Log.write(err);
@ -83,4 +99,73 @@ export class Settings {
return false; return false;
} }
} }
/* ------------------------------------------------------------------------------- #read ---- */
async #read(): Promise<boolean> {
try {
const file: string = await fs.readFile(this.#file, { encoding: 'utf8' });
const contents: settingsFile = JSON.parse(file);
this.minValue = contents.minValue;
this.maxDistance = contents.maxDistance;
this.#matrixFile = contents.matrixFile;
if (this.#matrixFile) {
await this.#setMatrix();
Log.write('Custom colors set!');
}
return true;
} catch (err) {
Log.write(err);
return false;
}
}
/* -------------------------------------------------------------------------- #setMatrix ---- */
async #setMatrix(): Promise<void> {
const file: string = await fs.readFile(this.#matrixFile, { encoding: 'utf8' });
let matrixRed: [number, number, number];
let matrixGreen: [number, number, number];
let matrixBlue: [number, number, number];
if (path.basename(this.#matrixFile) === 'GraphicsConfiguration.xml') {
const options = {
trim: true,
ignoreDeclaration: true,
ignoreAttributes: true,
compact: true,
textKey: '$'
};
const contents = xmlJS.xml2js(file, options);
let matrix = [
contents.GraphicsConfig.GUIColour.Default.MatrixRed.$,
contents.GraphicsConfig.GUIColour.Default.MatrixGreen.$,
contents.GraphicsConfig.GUIColour.Default.MatrixBlue.$,
];
matrix = matrix.map(v => v.replace(/\s/g, '').split(','));
matrixRed = matrix[0].length === 3 ? matrix[0] : [1,0,0];
matrixGreen = matrix[1].length === 3 ? matrix[1] : [0,1,0];
matrixBlue = matrix[2].length === 3 ? matrix[2] : [0,0,1];
this.matrix = new EliteMatrix(matrixRed, matrixGreen, matrixBlue);
} else if (path.basename(this.#matrixFile) === 'XML-Profile.ini') {
const contents = (ini.parse(file)).constants;
matrixRed = [contents.x150, contents.y150, contents.z150];
matrixGreen = [contents.x151, contents.y151, contents.z151];
matrixBlue = [contents.x152, contents.y152, contents.z152];
this.matrix = new EliteMatrix(matrixRed, matrixGreen, matrixBlue);
}
this.emit('CUSTOM_COLORS_SET');
}
} }

View file

@ -9,6 +9,17 @@ export class UI {
return Intl.NumberFormat().format(Math.round(number)); return Intl.NumberFormat().format(Math.round(number));
} }
/* --------------------------------------------------------------------------- setColors ---- */
static setColors(matrix) {
const body = $('body');
body.css('--main', matrix.filterColor('#F5A804'));
body.css('--accent-dark', matrix.filterColor('#000e5f'));
body.css('--accent-light', matrix.filterColor('#17cbd4'));
body.css('--secondary-light', matrix.filterColor('#EAA529'));
body.css('--secondary-dark', matrix.filterColor('#370C03'));
}
/* --------------------------------------------------------------------- enterWitchSpace ---- */ /* --------------------------------------------------------------------- enterWitchSpace ---- */
static enterWitchSpace() { static enterWitchSpace() {

View file

@ -35,6 +35,12 @@ if (!journal) {
safari.watchJournalDir(); safari.watchJournalDir();
journal.watch(); journal.watch();
/* ------------------------------------------------------------------------------ set colors ---- */
settings.on('CUSTOM_COLORS_SET', () => {
UI.setColors(settings.matrix);
});
/* -------------------------------------------------------------------- close window handler ---- */ /* -------------------------------------------------------------------- close window handler ---- */
$('#closeBtn').on('click', () => { $('#closeBtn').on('click', () => {
@ -130,17 +136,3 @@ edsm.on('SYSTEM_APPRAISED', (system) => {
UI.setValue(systemRow, system.estimatedValueMapped); UI.setValue(systemRow, system.estimatedValueMapped);
} }
}); });
// const matrixRed = [1.2, 0.05, 0.07];
// const matrixGreen = [0.13, 1, 1.18];
// const matrixBlue = [0.4, 1.29, 2];
// const matrix = new EliteMatrix(matrixRed, matrixGreen, matrixBlue);
// const hex = matrix.filterColor('#f5a804');
// const rgb = matrix.filterColor([245, 168, 4]);
// console.log(`rgb(${rgb})`)
// $('body').css('--main', `rgb(${rgb})`);
// $('body').css('--accent-dark', matrix.filterColor('#000e5f'));
// $('body').css('--accent-light', matrix.filterColor('#17cbd4'));
// $('body').css('--secondary-light', matrix.filterColor('#EAA529'));
// $('body').css('--secondary-dark', matrix.filterColor('#370C03'));

View file

@ -5,12 +5,23 @@ import './assets/ldom.min';
const { ipcRenderer } = require('electron'); const { ipcRenderer } = require('electron');
const { setTimeout } = require('node:timers/promises'); const { setTimeout } = require('node:timers/promises');
const { basename } = require('node:path');
import { Settings } from './models/Settings'; import { Settings } from './models/Settings';
import { UI } from './models/UI'; import { UI } from './models/UI';
const settings = Settings.get(); const settings = Settings.get();
if (settings.matrix) {
UI.setColors(settings.matrix);
}
/* ------------------------------------------------------------------------------ set colors ---- */
settings.on('CUSTOM_COLORS_SET', () => {
UI.setColors(settings.matrix);
});
/* -------------------------------------------------------------------- close window handler ---- */ /* -------------------------------------------------------------------- close window handler ---- */
$('#closeBtn').on('click', () => { $('#closeBtn').on('click', () => {
@ -61,6 +72,11 @@ $('form').on('submit', async function (event) {
errors = true; errors = true;
} }
const fileName = basename(data.matrixFile);
if (fileName !== 'XML-Profile.ini' || fileName !== 'GraphicsConfiguration.xml') {
UI.addFormError('#matrixFile', 'Invalid file.');
}
// TODO re-enable submit button if errors. // TODO re-enable submit button if errors.
// If no errors, save. // If no errors, save.