Implemented shutdown through UI and implemented router check

This commit is contained in:
2025-11-28 10:23:57 +01:00
parent 368f60d7b6
commit b2c5d08ff4
29 changed files with 639 additions and 71 deletions

View File

@@ -5,6 +5,10 @@ exports.DefaultConfiguration = {
webServer: { webServer: {
port: 6300, port: 6300,
}, },
router: {
ip: '',
waitForStartup: true,
},
unity: { unity: {
executable: { executable: {
path: '', path: '',

View File

@@ -1 +1 @@
{"version":3,"file":"DefaultConfiguration.js","sourceRoot":"","sources":["../../src/Configuration/DefaultConfiguration.ts"],"names":[],"mappings":";;;AAEa,QAAA,oBAAoB,GAAW;IAC3C,SAAS,EAAE;QACV,IAAI,EAAE,IAAI;KACV;IACD,KAAK,EAAE;QACN,UAAU,EAAE;YACX,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,EAAE;YACb,YAAY,EAAE,IAAI;SAClB;QAED,SAAS,EAAE;YACV,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,IAAI;SACV;QAED,iBAAiB,EAAE,IAAI;QACvB,wBAAwB,EAAE,IAAI;KAC9B;IACD,YAAY,EAAE;QACb,SAAS,EAAE;YACV,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,IAAI;SACV;QAED,YAAY,EAAE,IAAI;KAClB;IACD,MAAM,EAAE;QACP,UAAU,EAAE,EAAE;QACd,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,EAAE;QACd,SAAS,EAAE,EAAE;QACb,gBAAgB,EAAE,KAAK;QACvB,iBAAiB,EAAE,EAAE;KACrB;IACD,OAAO,EAAE;QACR,SAAS,EAAE,cAAc;KACzB;CACD,CAAC"} {"version":3,"file":"DefaultConfiguration.js","sourceRoot":"","sources":["../../src/Configuration/DefaultConfiguration.ts"],"names":[],"mappings":";;;AAEa,QAAA,oBAAoB,GAAW;IAC3C,SAAS,EAAE;QACV,IAAI,EAAE,IAAI;KACV;IACD,MAAM,EAAE;QACP,EAAE,EAAE,EAAE;QACN,cAAc,EAAE,IAAI;KACpB;IACD,KAAK,EAAE;QACN,UAAU,EAAE;YACX,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,EAAE;YACb,YAAY,EAAE,IAAI;SAClB;QAED,SAAS,EAAE;YACV,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,IAAI;SACV;QAED,iBAAiB,EAAE,IAAI;QACvB,wBAAwB,EAAE,IAAI;KAC9B;IACD,YAAY,EAAE;QACb,SAAS,EAAE;YACV,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,IAAI;SACV;QAED,YAAY,EAAE,IAAI;KAClB;IACD,MAAM,EAAE;QACP,UAAU,EAAE,EAAE;QACd,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,EAAE;QACd,SAAS,EAAE,EAAE;QACb,gBAAgB,EAAE,KAAK;QACvB,iBAAiB,EAAE,EAAE;KACrB;IACD,OAAO,EAAE;QACR,SAAS,EAAE,cAAc;KACzB;CACD,CAAC"}

69
dist/Main.js vendored
View File

@@ -46,6 +46,9 @@ var UnityRunner_1 = require("./Unity/UnityRunner");
var UnityWebSocket_1 = require("./Unity/UnityWebSocket"); var UnityWebSocket_1 = require("./Unity/UnityWebSocket");
var Twilio_1 = require("./Twilio"); var Twilio_1 = require("./Twilio");
var Utils_1 = require("./Utils"); var Utils_1 = require("./Utils");
var ping = require("ping");
var Shutdown_1 = require("./Shutdown");
var PREFIX = '[Main]';
var Main = /** @class */ (function () { var Main = /** @class */ (function () {
function Main() { function Main() {
this.dataPath = (0, path_1.join)((0, os_1.homedir)(), 'MorphixProductions', 'NTSHControl'); this.dataPath = (0, path_1.join)((0, os_1.homedir)(), 'MorphixProductions', 'NTSHControl');
@@ -65,14 +68,17 @@ var Main = /** @class */ (function () {
case 0: return [4 /*yield*/, this.ConfigurationManager.load()]; case 0: return [4 /*yield*/, this.ConfigurationManager.load()];
case 1: case 1:
_b.sent(); _b.sent();
return [4 /*yield*/, this.WebServer.listen()]; return [4 /*yield*/, this.waitForRouter()];
case 2: case 2:
_b.sent(); _b.sent();
return [4 /*yield*/, this.Twilio.load()]; return [4 /*yield*/, this.WebServer.listen()];
case 3: case 3:
_b.sent(); _b.sent();
return [4 /*yield*/, this.CameraRunner.connect()]; return [4 /*yield*/, this.Twilio.load()];
case 4: case 4:
_b.sent();
return [4 /*yield*/, this.CameraRunner.connect()];
case 5:
_b.sent(); _b.sent();
setTimeout(function () { setTimeout(function () {
_this.UnityRunner.start(); _this.UnityRunner.start();
@@ -126,6 +132,63 @@ var Main = /** @class */ (function () {
}); });
}); });
}; };
Main.prototype.shutdown = function () {
return __awaiter(this, void 0, void 0, function () {
var doShutdown;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
console.log('Stopping UnityRunner...');
return [4 /*yield*/, this.UnityRunner.stop()];
case 1:
_a.sent();
doShutdown = process.argv.includes('--no-shutdown')
? false
: true;
if (doShutdown) {
console.log('Shutting down system...');
(0, Shutdown_1.shutdown)();
}
else {
console.log('Shutdown skipped due to --no-shutdown flag.');
}
process.exit(0);
return [2 /*return*/];
}
});
});
};
Main.prototype.waitForRouter = function () {
var _this = this;
var _a;
if (((_a = this.Config.router) === null || _a === void 0 ? void 0 : _a.waitForStartup) !== true)
return;
return new Promise(function (resolve) {
var check = function () {
console.log(PREFIX, 'Waiting for router...');
ping.sys.probe(_this.Config.router.ip, function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
var alive = _b.alive;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (!alive) return [3 /*break*/, 2];
console.log(PREFIX, 'Router is online');
return [4 /*yield*/, (0, Utils_1.delay)(3000)];
case 1:
_c.sent();
return [2 /*return*/, resolve()];
case 2: return [4 /*yield*/, (0, Utils_1.delay)(1000)];
case 3:
_c.sent();
check();
return [2 /*return*/];
}
});
}); });
};
check();
});
};
return Main; return Main;
}()); }());
exports.Main = Main; exports.Main = Main;

2
dist/Main.js.map vendored
View File

@@ -1 +1 @@
{"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.ts"],"names":[],"mappings":"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"} {"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.ts"],"names":[],"mappings":"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"}

30
dist/Reboot.js vendored Normal file
View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.shutdown = shutdown;
var child_process_1 = require("child_process");
function shutdown() {
if (process.platform === 'win32') {
return shutdownWindows();
}
return Promise.resolve({
succeed: false,
message: 'Platform not supported',
});
}
function shutdownWindows() {
return new Promise(function (resolve, reject) {
(0, child_process_1.exec)('shutdown /s /t 5', function (error, stdout, stderr) {
if (error) {
console.error("Error shutting down Windows: ".concat(error.message));
return resolve({ succeed: false, message: error.message });
}
if (stderr) {
console.error("Error shutting down Windows: ".concat(stderr));
return resolve({ succeed: false, message: stderr });
}
console.log("Windows shutdown command executed: ".concat(stdout));
resolve({ succeed: true });
});
});
}
//# sourceMappingURL=Reboot.js.map

1
dist/Reboot.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"Reboot.js","sourceRoot":"","sources":["../src/Reboot.ts"],"names":[],"mappings":";;AAEA,4BASC;AAXD,+CAAqC;AAErC,SAAgB,QAAQ;IACvB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,OAAO,eAAe,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC;QACtB,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,wBAAwB;KACjC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe;IACvB,OAAO,IAAI,OAAO,CACjB,UAAC,OAAO,EAAE,MAAM;QACf,IAAA,oBAAI,EAAC,kBAAkB,EAAE,UAAC,KAAK,EAAE,MAAM,EAAE,MAAM;YAC9C,IAAI,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CACZ,uCAAgC,KAAK,CAAC,OAAO,CAAE,CAC/C,CAAC;gBACF,OAAO,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,MAAM,EAAE,CAAC;gBACZ,OAAO,CAAC,KAAK,CAAC,uCAAgC,MAAM,CAAE,CAAC,CAAC;gBACxD,OAAO,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,6CAAsC,MAAM,CAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACJ,CAAC,CACD,CAAC;AACH,CAAC"}

30
dist/Shutdown.js vendored Normal file
View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.shutdown = shutdown;
var child_process_1 = require("child_process");
function shutdown() {
if (process.platform === 'win32') {
return shutdownWindows();
}
return Promise.resolve({
succeed: false,
message: 'Platform not supported',
});
}
function shutdownWindows() {
return new Promise(function (resolve, reject) {
(0, child_process_1.exec)('shutdown /s /t 5', function (error, stdout, stderr) {
if (error) {
console.error("Error shutting down Windows: ".concat(error.message));
return resolve({ succeed: false, message: error.message });
}
if (stderr) {
console.error("Error shutting down Windows: ".concat(stderr));
return resolve({ succeed: false, message: stderr });
}
console.log("Windows shutdown command executed: ".concat(stdout));
resolve({ succeed: true });
});
});
}
//# sourceMappingURL=Shutdown.js.map

1
dist/Shutdown.js.map vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"Shutdown.js","sourceRoot":"","sources":["../src/Shutdown.ts"],"names":[],"mappings":";;AAEA,4BASC;AAXD,+CAAqC;AAErC,SAAgB,QAAQ;IACvB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,OAAO,eAAe,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC;QACtB,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,wBAAwB;KACjC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe;IACvB,OAAO,IAAI,OAAO,CACjB,UAAC,OAAO,EAAE,MAAM;QACf,IAAA,oBAAI,EAAC,kBAAkB,EAAE,UAAC,KAAK,EAAE,MAAM,EAAE,MAAM;YAC9C,IAAI,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CACZ,uCAAgC,KAAK,CAAC,OAAO,CAAE,CAC/C,CAAC;gBACF,OAAO,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,MAAM,EAAE,CAAC;gBACZ,OAAO,CAAC,KAAK,CAAC,uCAAgC,MAAM,CAAE,CAAC,CAAC;gBACxD,OAAO,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,6CAAsC,MAAM,CAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACJ,CAAC,CACD,CAAC;AACH,CAAC"}

View File

@@ -192,11 +192,17 @@ var UnityWebSocket = /** @class */ (function () {
(_a = message.heartbeat.showOutOfService) !== null && _a !== void 0 ? _a : false; (_a = message.heartbeat.showOutOfService) !== null && _a !== void 0 ? _a : false;
this.parameters.sensors = message.heartbeat.dataSensors; this.parameters.sensors = message.heartbeat.dataSensors;
this.parameters.sliders = message.heartbeat.dataSliders.map(function (slider) { this.parameters.sliders = message.heartbeat.dataSliders.map(function (slider) {
return __assign(__assign({}, slider), { decimalPlaces: slider.min == 0 && slider.max == 1 ? 2 : null }); return __assign(__assign({}, slider), { decimalPlaces: (slider.min == 0 || slider.min == -1) &&
slider.max == 1
? 2
: null });
}); });
this.parameters.advancedSliders = this.parameters.advancedSliders =
message.heartbeat.dataAdvancedSliders.map(function (slider) { message.heartbeat.dataAdvancedSliders.map(function (slider) {
return __assign(__assign({}, slider), { decimalPlaces: slider.min == 0 && slider.max == 1 ? 2 : null }); return __assign(__assign({}, slider), { decimalPlaces: (slider.min == 0 || slider.min == -1) &&
slider.max == 1
? 2
: null });
}); });
this.broadcastState(); this.broadcastState();
break; break;

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,40 @@
"use strict"; "use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) { if (ar || !(i in from)) {
@@ -16,6 +52,7 @@ var http_1 = require("http");
var DashboardRouter_1 = require("./DashboardRouter"); var DashboardRouter_1 = require("./DashboardRouter");
var path_1 = require("path"); var path_1 = require("path");
var CalibrationRouter_1 = require("./CalibrationRouter"); var CalibrationRouter_1 = require("./CalibrationRouter");
var Utils_1 = require("../Utils");
var PREFIX = '[WebServer]'; var PREFIX = '[WebServer]';
var WebServer = /** @class */ (function () { var WebServer = /** @class */ (function () {
function WebServer(Main) { function WebServer(Main) {
@@ -46,6 +83,18 @@ var WebServer = /** @class */ (function () {
_this._Main.restart(); _this._Main.restart();
callback({ succeed: true }); callback({ succeed: true });
}); });
socket.on('shutdownInstallation', function (callback) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, (0, Utils_1.delay)(1000)];
case 1:
_a.sent();
callback({ succeed: true });
this._Main.shutdown();
return [2 /*return*/];
}
});
}); });
socket.on('cameraRunner', function (command) { socket.on('cameraRunner', function (command) {
var _a; var _a;
var args = []; var args = [];

View File

@@ -1 +1 @@
{"version":3,"file":"WebServer.js","sourceRoot":"","sources":["../../src/WebServer/WebServer.ts"],"names":[],"mappings":"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"} {"version":3,"file":"WebServer.js","sourceRoot":"","sources":["../../src/WebServer/WebServer.ts"],"names":[],"mappings":"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"}

View File

@@ -73,6 +73,21 @@ var MenuBar = /** @class */ (function () {
}); });
}); }, }); },
}, },
{
type: 'icon',
text: 'Shutdown',
materialIcon: 'power_settings_new',
uniqueIdentifier: 'shutdown_installation',
click: function () { return __awaiter(_this, void 0, void 0, function () {
var mobileMenu;
return __generator(this, function (_a) {
mobileMenu = document.querySelector('.mux_mobilemenu');
mobileMenu === null || mobileMenu === void 0 ? void 0 : mobileMenu.click();
this.shutdownInstallation();
return [2 /*return*/];
});
}); },
},
], ],
right: [ right: [
{ {
@@ -100,6 +115,21 @@ var MenuBar = /** @class */ (function () {
}); });
}); }, }); },
}, },
{
type: 'normal',
text: 'Shutdown',
materialIcon: 'power_settings_new',
uniqueIdentifier: 'shutdown_installation',
click: function () { return __awaiter(_this, void 0, void 0, function () {
var mobileMenu;
return __generator(this, function (_a) {
mobileMenu = document.querySelector('.mux_mobilemenu');
mobileMenu === null || mobileMenu === void 0 ? void 0 : mobileMenu.click();
this.shutdownInstallation();
return [2 /*return*/];
});
}); },
},
{ {
type: 'normal', type: 'normal',
text: 'Dashboard', text: 'Dashboard',
@@ -215,6 +245,38 @@ var MenuBar = /** @class */ (function () {
}); });
}); });
}; };
MenuBar.prototype.shutdownInstallation = function () {
return __awaiter(this, void 0, void 0, function () {
var confirmed, shutdownContainer;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, morphux_1.MorphFeature.Confirm({
title: 'Shutdown Installation',
message: 'Are you sure you want to shutdown the installation?',
})];
case 1:
confirmed = _a.sent();
if (!confirmed)
return [2 /*return*/];
morphux_1.MorphFeature.Loader({
active: true,
message: 'Shutting down installation...',
});
shutdownContainer = document.querySelector('.ntsh_shutdown');
this._Main.socket.emit('shutdownInstallation', function (response) {
morphux_1.MorphFeature.Loader({ active: false });
if (!response.succeed)
return morphux_1.MorphFeature.Alert({
title: 'Error',
message: response.message,
});
shutdownContainer.style.display = 'flex';
});
return [2 /*return*/];
}
});
});
};
MenuBar.prototype.toggleServiceMode = function (mode, skipPin) { MenuBar.prototype.toggleServiceMode = function (mode, skipPin) {
return __awaiter(this, void 0, void 0, function () { return __awaiter(this, void 0, void 0, function () {
var newMode, servicePin; var newMode, servicePin;

File diff suppressed because one or more lines are too long

View File

@@ -309,6 +309,18 @@
</div> </div>
</div> </div>
</div> </div>
<div class="ntsh_shutdown">
<span class="material-symbols-outlined">
power_settings_new
</span>
<div class="mux_header">
Installation has been shut down
</div>
<div class="mux_text">
You can now safely turn off the power to the device.
</div>
</div>
</div> </div>
</body> </body>

View File

@@ -5297,7 +5297,7 @@
var Index = {}; var Index = {};
var name = "morphux"; var name = "morphux";
var version = "2025.9.1"; var version = "2025.11.5";
var description = "Standardized Morphix UX framework."; var description = "Standardized Morphix UX framework.";
var main = "dist/Index.js"; var main = "dist/Index.js";
var types = "dist/index.d.ts"; var types = "dist/index.d.ts";
@@ -5347,7 +5347,7 @@
var CE = {}; var CE = {};
Object.defineProperty(CE, "__esModule", { value: true }); Object.defineProperty(CE, "__esModule", { value: true });
CE.ce = ce; CE.ce = void 0;
function ce(tagName, classList, attributes, innerText, innerHTML, style) { function ce(tagName, classList, attributes, innerText, innerHTML, style) {
var _a; var _a;
var element = document.createElement(tagName); var element = document.createElement(tagName);
@@ -5371,6 +5371,7 @@
element.style[key] = style[key]; element.style[key] = style[key];
return element; return element;
} }
CE.ce = ce;
var baseComponent = {}; var baseComponent = {};
@@ -5471,7 +5472,7 @@
var TextHighlighter = {}; var TextHighlighter = {};
Object.defineProperty(TextHighlighter, "__esModule", { value: true }); Object.defineProperty(TextHighlighter, "__esModule", { value: true });
TextHighlighter.generateTextHighlights = generateTextHighlights; TextHighlighter.generateTextHighlights = void 0;
function generateTextHighlights(originalText, additionalClassnames) { function generateTextHighlights(originalText, additionalClassnames) {
var _a; var _a;
if (additionalClassnames === void 0) { additionalClassnames = []; } if (additionalClassnames === void 0) { additionalClassnames = []; }
@@ -5505,6 +5506,7 @@
} }
return div; return div;
} }
TextHighlighter.generateTextHighlights = generateTextHighlights;
var Sortable$2 = {exports: {}}; var Sortable$2 = {exports: {}};
@@ -6880,7 +6882,7 @@
settings.disableInElementsWithTags.map(function (tagname) { settings.disableInElementsWithTags.map(function (tagname) {
return tagname.toUpperCase(); return tagname.toUpperCase();
}); });
this.binds[query] = { callback: callback, settings: settings }; this.binds[query] = { callback: callback, key: key, settings: settings };
}; };
return KeyBinderOverwrite; return KeyBinderOverwrite;
}()); }());
@@ -6928,7 +6930,7 @@
settings.disableInElementsWithTags.map(function (tagname) { settings.disableInElementsWithTags.map(function (tagname) {
return tagname.toUpperCase(); return tagname.toUpperCase();
}); });
this.binds[query] = { callback: callback, settings: settings }; this.binds[query] = { callback: callback, key: key, settings: settings };
}; };
KeyBinderBase.prototype.unbind = function (key, settings) { KeyBinderBase.prototype.unbind = function (key, settings) {
if (settings == undefined) if (settings == undefined)
@@ -6971,6 +6973,20 @@
.concat(Object.keys(this.binds)) .concat(Object.keys(this.binds))
.flat())); .flat()));
}; };
KeyBinderBase.prototype.getBindsOverview = function () {
return Object.values(this.binds).map(function (_a) {
var key = _a.key, settings = _a.settings;
var combo = [];
if (settings === null || settings === void 0 ? void 0 : settings.controlKey)
combo.push('Ctrl');
if (settings === null || settings === void 0 ? void 0 : settings.shiftKey)
combo.push('Shift');
if (settings === null || settings === void 0 ? void 0 : settings.altKey)
combo.push('Alt');
combo.push(key.length < 3 ? key.toUpperCase() : key);
return [combo.join('+'), settings === null || settings === void 0 ? void 0 : settings.name];
});
};
KeyBinderBase.prototype.generateOverwriteId = function () { KeyBinderBase.prototype.generateOverwriteId = function () {
while (true) { while (true) {
var id = (Math.random() + 1).toString(36).substring(7); var id = (Math.random() + 1).toString(36).substring(7);
@@ -7041,6 +7057,10 @@
var _this = _super.call(this) || this; var _this = _super.call(this) || this;
_this.open = true; _this.open = true;
_this.container = (0, CE_1$7.ce)('div', 'mux_contextmenu'); _this.container = (0, CE_1$7.ce)('div', 'mux_contextmenu');
if ((options === null || options === void 0 ? void 0 : options.width) != undefined) {
_this.container.style.minWidth = "".concat(options.width, "px");
_this.container.style.width = "".concat(options.width, "px");
}
var align = (_a = options === null || options === void 0 ? void 0 : options.align) !== null && _a !== void 0 ? _a : 'center'; var align = (_a = options === null || options === void 0 ? void 0 : options.align) !== null && _a !== void 0 ? _a : 'center';
if ((options === null || options === void 0 ? void 0 : options.materialIconColor) != undefined) if ((options === null || options === void 0 ? void 0 : options.materialIconColor) != undefined)
_this.container.style.setProperty('--mux-contextmenu-iconcolor', options.materialIconColor); _this.container.style.setProperty('--mux-contextmenu-iconcolor', options.materialIconColor);
@@ -7220,6 +7240,29 @@
element.setAttribute('href', item.href); element.setAttribute('href', item.href);
if (item.tooltip != undefined) if (item.tooltip != undefined)
element.title = item.tooltip; element.title = item.tooltip;
if (item.uniqueIdentifier != undefined) {
element.setAttribute('uid', item.uniqueIdentifier);
}
if (item.enabled == false)
element.classList.add('mux_contextmenu-item-disabled');
var textContent = (0, CE_1$7.ce)('div', 'mux_contextmenu-item-content');
element.appendChild(textContent);
var itemContent = (0, CE_1$7.ce)('div', ['mux_text', 'mux_small'], null, (_b = item.text) !== null && _b !== void 0 ? _b : '');
if (item.customFontSize != undefined)
itemContent.style.fontSize = "".concat(item.customFontSize, "px");
textContent.appendChild(itemContent);
if (item.children == undefined && item.shortcut != undefined)
textContent.appendChild((0, CE_1$7.ce)('div', [
'mux_contextmenu-shortcut',
'mux_text',
'mux_tiny',
], null, (_c = item.shortcut) !== null && _c !== void 0 ? _c : ''));
if (item.children != undefined && item.children.length > 0) {
textContent.appendChild((0, CE_1$7.ce)('span', [
'material-symbols-outlined',
'mux_contextmenu-item-arrow',
], null, 'keyboard_arrow_right'));
}
if (item.materialIcon != undefined) { if (item.materialIcon != undefined) {
var materialIcon = (0, CE_1$7.ce)('span', [ var materialIcon = (0, CE_1$7.ce)('span', [
'mux_contextmenu-item-materialicon', 'mux_contextmenu-item-materialicon',
@@ -7234,27 +7277,6 @@
element.appendChild((0, CE_1$7.ce)('img', 'mux_contextmenu-item-icon', { element.appendChild((0, CE_1$7.ce)('img', 'mux_contextmenu-item-icon', {
src: item.icon, src: item.icon,
})); }));
if (item.uniqueIdentifier != undefined) {
element.setAttribute('uid', item.uniqueIdentifier);
}
if (item.enabled == false)
element.classList.add('mux_contextmenu-item-disabled');
var itemContent = (0, CE_1$7.ce)('div', ['mux_text', 'mux_small'], null, (_b = item.text) !== null && _b !== void 0 ? _b : '');
if (item.customFontSize != undefined)
itemContent.style.fontSize = "".concat(item.customFontSize, "px");
element.appendChild(itemContent);
if (item.children == undefined && item.shortcut != undefined)
element.appendChild((0, CE_1$7.ce)('div', [
'mux_contextmenu-shortcut',
'mux_text',
'mux_tiny',
], null, (_c = item.shortcut) !== null && _c !== void 0 ? _c : ''));
if (item.children != undefined && item.children.length > 0) {
element.appendChild((0, CE_1$7.ce)('span', [
'material-symbols-outlined',
'mux_contextmenu-item-arrow',
], null, 'keyboard_arrow_right'));
}
element.onmousemove = function () { element.onmousemove = function () {
if (_this.subContextParent == itemId) if (_this.subContextParent == itemId)
return; return;
@@ -10694,16 +10716,16 @@
var Utils = {}; var Utils = {};
Object.defineProperty(Utils, "__esModule", { value: true }); Object.defineProperty(Utils, "__esModule", { value: true });
Utils.blackPixel = void 0; Utils.delay = Utils.blackPixel = Utils.isMobile = void 0;
Utils.isMobile = isMobile;
Utils.delay = delay;
function isMobile() { function isMobile() {
return /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.test(navigator.userAgent); return /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.test(navigator.userAgent);
} }
Utils.isMobile = isMobile;
Utils.blackPixel = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='; Utils.blackPixel = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';
function delay(duration) { function delay(duration) {
return new Promise(function (resolve) { return setTimeout(resolve, duration); }); return new Promise(function (resolve) { return setTimeout(resolve, duration); });
} }
Utils.delay = delay;
var hasRequiredComponent_ImageViewer; var hasRequiredComponent_ImageViewer;
@@ -10735,8 +10757,8 @@
}); });
}; };
var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) { var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; } function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) { function step(op) {
if (f) throw new TypeError("Generator is already executing."); if (f) throw new TypeError("Generator is already executing.");
@@ -11842,7 +11864,8 @@
this.container this.container
.querySelectorAll('.mux_menubar-item') .querySelectorAll('.mux_menubar-item')
.forEach(function (item) { .forEach(function (item) {
if (item.getAttribute('uid') == uniqueIdentifier) if (item.getAttribute('uid') == uniqueIdentifier &&
uniqueIdentifier != null)
item.classList.add('mux_menubar-item-selected'); item.classList.add('mux_menubar-item-selected');
else else
item.classList.remove('mux_menubar-item-selected'); item.classList.remove('mux_menubar-item-selected');
@@ -13513,8 +13536,8 @@
}); });
}; };
var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) { var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; } function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) { function step(op) {
if (f) throw new TypeError("Generator is already executing."); if (f) throw new TypeError("Generator is already executing.");
@@ -14017,7 +14040,7 @@
if (hasRequiredFeature_Alert) return Feature_Alert; if (hasRequiredFeature_Alert) return Feature_Alert;
hasRequiredFeature_Alert = 1; hasRequiredFeature_Alert = 1;
Object.defineProperty(Feature_Alert, "__esModule", { value: true }); Object.defineProperty(Feature_Alert, "__esModule", { value: true });
Feature_Alert.FeatureAlert = FeatureAlert; Feature_Alert.FeatureAlert = void 0;
var Index_1 = requireIndex(); var Index_1 = requireIndex();
function FeatureAlert(options, callback) { function FeatureAlert(options, callback) {
return new Promise(function (resolve) { return new Promise(function (resolve) {
@@ -14038,6 +14061,7 @@
dialog.on('ok', function () { return res(); }); dialog.on('ok', function () { return res(); });
}); });
} }
Feature_Alert.FeatureAlert = FeatureAlert;
return Feature_Alert; return Feature_Alert;
} }
@@ -14050,7 +14074,7 @@
if (hasRequiredFeature_Confirm) return Feature_Confirm; if (hasRequiredFeature_Confirm) return Feature_Confirm;
hasRequiredFeature_Confirm = 1; hasRequiredFeature_Confirm = 1;
Object.defineProperty(Feature_Confirm, "__esModule", { value: true }); Object.defineProperty(Feature_Confirm, "__esModule", { value: true });
Feature_Confirm.FeatureConfirm = FeatureConfirm; Feature_Confirm.FeatureConfirm = void 0;
var Index_1 = requireIndex(); var Index_1 = requireIndex();
function FeatureConfirm(options, callback) { function FeatureConfirm(options, callback) {
return new Promise(function (resolve) { return new Promise(function (resolve) {
@@ -14071,6 +14095,7 @@
dialog.on('ok', function () { return res(true); }); dialog.on('ok', function () { return res(true); });
}); });
} }
Feature_Confirm.FeatureConfirm = FeatureConfirm;
return Feature_Confirm; return Feature_Confirm;
} }
@@ -14083,7 +14108,7 @@
if (hasRequiredFeature_Loader) return Feature_Loader; if (hasRequiredFeature_Loader) return Feature_Loader;
hasRequiredFeature_Loader = 1; hasRequiredFeature_Loader = 1;
Object.defineProperty(Feature_Loader, "__esModule", { value: true }); Object.defineProperty(Feature_Loader, "__esModule", { value: true });
Feature_Loader.FeatureLoader = FeatureLoader; Feature_Loader.FeatureLoader = void 0;
var Index_1 = requireIndex(); var Index_1 = requireIndex();
function FeatureLoader(options) { function FeatureLoader(options) {
var _a, _b; var _a, _b;
@@ -14095,6 +14120,7 @@
else else
removeExisting(); removeExisting();
} }
Feature_Loader.FeatureLoader = FeatureLoader;
function showLoader(message, progress) { function showLoader(message, progress) {
var loader = document.querySelector('.mux_loader'); var loader = document.querySelector('.mux_loader');
if (loader == null) { if (loader == null) {
@@ -14154,7 +14180,7 @@
if (hasRequiredFeature_Notification) return Feature_Notification; if (hasRequiredFeature_Notification) return Feature_Notification;
hasRequiredFeature_Notification = 1; hasRequiredFeature_Notification = 1;
Object.defineProperty(Feature_Notification, "__esModule", { value: true }); Object.defineProperty(Feature_Notification, "__esModule", { value: true });
Feature_Notification.FeatureNotification = FeatureNotification; Feature_Notification.FeatureNotification = void 0;
var Index_1 = requireIndex(); var Index_1 = requireIndex();
var NotificationHandler = new (/** @class */ (function () { var NotificationHandler = new (/** @class */ (function () {
function class_1() { function class_1() {
@@ -14227,6 +14253,7 @@
return; return;
return NotificationHandler.append(notification); return NotificationHandler.append(notification);
} }
Feature_Notification.FeatureNotification = FeatureNotification;
return Feature_Notification; return Feature_Notification;
} }
@@ -14239,7 +14266,7 @@
if (hasRequiredFeature_Prompt) return Feature_Prompt; if (hasRequiredFeature_Prompt) return Feature_Prompt;
hasRequiredFeature_Prompt = 1; hasRequiredFeature_Prompt = 1;
Object.defineProperty(Feature_Prompt, "__esModule", { value: true }); Object.defineProperty(Feature_Prompt, "__esModule", { value: true });
Feature_Prompt.FeaturePrompt = FeaturePrompt; Feature_Prompt.FeaturePrompt = void 0;
var Index_1 = requireIndex(); var Index_1 = requireIndex();
function FeaturePrompt(options, callback) { function FeaturePrompt(options, callback) {
return new Promise(function (resolve) { return new Promise(function (resolve) {
@@ -14285,6 +14312,7 @@
input.container.focus(); input.container.focus();
}); });
} }
Feature_Prompt.FeaturePrompt = FeaturePrompt;
return Feature_Prompt; return Feature_Prompt;
} }
@@ -14320,12 +14348,13 @@
var clone$1 = {}; var clone$1 = {};
Object.defineProperty(clone$1, "__esModule", { value: true }); Object.defineProperty(clone$1, "__esModule", { value: true });
clone$1.clone = clone; clone$1.clone = void 0;
function clone(object) { function clone(object) {
if (typeof object !== 'object') if (typeof object !== 'object')
return object; return object;
return JSON.parse(JSON.stringify(object !== null && object !== void 0 ? object : {})); return JSON.parse(JSON.stringify(object !== null && object !== void 0 ? object : {}));
} }
clone$1.clone = clone;
(function (exports) { (function (exports) {
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
@@ -14450,6 +14479,21 @@
}); });
}); }, }); },
}, },
{
type: 'icon',
text: 'Shutdown',
materialIcon: 'power_settings_new',
uniqueIdentifier: 'shutdown_installation',
click: function () { return __awaiter$4(_this, void 0, void 0, function () {
var mobileMenu;
return __generator$4(this, function (_a) {
mobileMenu = document.querySelector('.mux_mobilemenu');
mobileMenu === null || mobileMenu === void 0 ? void 0 : mobileMenu.click();
this.shutdownInstallation();
return [2 /*return*/];
});
}); },
},
], ],
right: [ right: [
{ {
@@ -14477,6 +14521,21 @@
}); });
}); }, }); },
}, },
{
type: 'normal',
text: 'Shutdown',
materialIcon: 'power_settings_new',
uniqueIdentifier: 'shutdown_installation',
click: function () { return __awaiter$4(_this, void 0, void 0, function () {
var mobileMenu;
return __generator$4(this, function (_a) {
mobileMenu = document.querySelector('.mux_mobilemenu');
mobileMenu === null || mobileMenu === void 0 ? void 0 : mobileMenu.click();
this.shutdownInstallation();
return [2 /*return*/];
});
}); },
},
{ {
type: 'normal', type: 'normal',
text: 'Dashboard', text: 'Dashboard',
@@ -14592,6 +14651,38 @@
}); });
}); });
}; };
MenuBar.prototype.shutdownInstallation = function () {
return __awaiter$4(this, void 0, void 0, function () {
var confirmed, shutdownContainer;
return __generator$4(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, morphux_1$5.MorphFeature.Confirm({
title: 'Shutdown Installation',
message: 'Are you sure you want to shutdown the installation?',
})];
case 1:
confirmed = _a.sent();
if (!confirmed)
return [2 /*return*/];
morphux_1$5.MorphFeature.Loader({
active: true,
message: 'Shutting down installation...',
});
shutdownContainer = document.querySelector('.ntsh_shutdown');
this._Main.socket.emit('shutdownInstallation', function (response) {
morphux_1$5.MorphFeature.Loader({ active: false });
if (!response.succeed)
return morphux_1$5.MorphFeature.Alert({
title: 'Error',
message: response.message,
});
shutdownContainer.style.display = 'flex';
});
return [2 /*return*/];
}
});
});
};
MenuBar.prototype.toggleServiceMode = function (mode, skipPin) { MenuBar.prototype.toggleServiceMode = function (mode, skipPin) {
return __awaiter$4(this, void 0, void 0, function () { return __awaiter$4(this, void 0, void 0, function () {
var newMode, servicePin; var newMode, servicePin;

File diff suppressed because one or more lines are too long

View File

@@ -17,7 +17,7 @@ body {
} }
.mux_menubar-locater.mux_left { .mux_menubar-locater.mux_left {
.mux_menubar-item:not([uid="restart_installation"]) { .mux_menubar-item:not([uid="restart_installation"], [uid="shutdown_installation"]) {
display: none; display: none;
} }
} }
@@ -78,3 +78,21 @@ body {
} }
} }
} }
.ntsh_shutdown {
position: absolute;
inset: 0px;
z-index: 10000;
background: var(--mux-bg-color);
display: none;
flex-direction: column;
justify-content: center;
align-items: center;
gap: var(--mux-edge-offset);
.material-symbols-outlined {
margin-bottom: var(--mux-edge-offset);
font-size: 60px;
color: #919191;
}
}

View File

@@ -802,6 +802,7 @@
.mux_contextmenu { .mux_contextmenu {
position: absolute; position: absolute;
z-index: 1101; z-index: 1101;
min-width: 120px;
border-radius: var(--mux-rounding); border-radius: var(--mux-rounding);
background: var(--mux-panel-color); background: var(--mux-panel-color);
box-shadow: var(--mux-panel-shadow); box-shadow: var(--mux-panel-shadow);
@@ -810,7 +811,7 @@
transform-origin: 50% 0%; transform-origin: 50% 0%;
transform: scale(0); transform: scale(0);
user-select: none; user-select: none;
--mux-contextmenu-iconcolor: var(--mux-text-color); --mux-contextmenu-iconcolor: #919191;
} }
.mux_contextmenu .mux_contextmenu-item { .mux_contextmenu .mux_contextmenu-item {
@@ -845,25 +846,33 @@
} }
.mux_contextmenu .mux_contextmenu-item .mux_contextmenu-item-icon { .mux_contextmenu .mux_contextmenu-item .mux_contextmenu-item-icon {
margin-right: var(--mux-edge-offset-tiny); margin-right: -2px;
height: 20px; height: 16px;
border-radius: var(--mux-rounding); border-radius: var(--mux-rounding);
} }
.mux_contextmenu .mux_contextmenu-item .mux_contextmenu-item-arrow {
font-size: 16px;
margin-right: -5px;
color: #fff;
}
.mux_contextmenu .mux_contextmenu-item .mux_contextmenu-item-materialicon { .mux_contextmenu .mux_contextmenu-item .mux_contextmenu-item-materialicon {
margin-right: var(--mux-edge-offset); margin-right: -2px;
color: var(--mux-contextmenu-iconcolor); color: var(--mux-contextmenu-iconcolor);
font-size: 20px; font-size: 16px;
} }
.mux_contextmenu .mux_contextmenu-item .mux_contextmenu-shortcut { .mux_contextmenu .mux_contextmenu-item .mux_contextmenu-item-content {
margin-left: var(--mux-edge-offset); flex-grow: 1;
display: flex;
justify-content: flex-start;
align-items: center;
gap: var(--mux-edge-offset-tiny);
padding-right: calc(var(--mux-edge-offset) * 2);
}
.mux_contextmenu .mux_contextmenu-item .mux_contextmenu-item-content .mux_contextmenu-item-arrow {
font-size: 16px;
margin-left: calc(var(--mux-edge-offset-tiny) * -1);
color: #c0c0c0;
}
.mux_contextmenu .mux_contextmenu-item .mux_contextmenu-item-content .mux_contextmenu-shortcut {
color: #b3b3b3; color: #b3b3b3;
} }
@@ -2577,7 +2586,7 @@ body {
body:not(.ntsh_service) .ntsh_buttons { body:not(.ntsh_service) .ntsh_buttons {
display: none; display: none;
} }
body:not(.ntsh_service) .mux_menubar-locater.mux_left .mux_menubar-item:not([uid=restart_installation]) { body:not(.ntsh_service) .mux_menubar-locater.mux_left .mux_menubar-item:not([uid=restart_installation], [uid=shutdown_installation]) {
display: none; display: none;
} }
body:not(.ntsh_service) .only-service { body:not(.ntsh_service) .only-service {
@@ -2622,4 +2631,21 @@ body.ntsh_service .no-service {
color: #c7c7c7; color: #c7c7c7;
} }
.ntsh_shutdown {
position: absolute;
inset: 0px;
z-index: 10000;
background: var(--mux-bg-color);
display: none;
flex-direction: column;
justify-content: center;
align-items: center;
gap: var(--mux-edge-offset);
}
.ntsh_shutdown .material-symbols-outlined {
margin-bottom: var(--mux-edge-offset);
font-size: 60px;
color: #919191;
}
/*# sourceMappingURL=style.css.map */ /*# sourceMappingURL=style.css.map */

File diff suppressed because one or more lines are too long

View File

@@ -44,6 +44,20 @@ export class MenuBar {
this.restartInstallation(); this.restartInstallation();
}, },
}, },
{
type: 'icon',
text: 'Shutdown',
materialIcon: 'power_settings_new',
uniqueIdentifier: 'shutdown_installation',
click: async () => {
const mobileMenu: HTMLDivElement =
document.querySelector('.mux_mobilemenu');
mobileMenu?.click();
this.shutdownInstallation();
},
},
], ],
right: [ right: [
{ {
@@ -70,6 +84,20 @@ export class MenuBar {
this.restartInstallation(); this.restartInstallation();
}, },
}, },
{
type: 'normal',
text: 'Shutdown',
materialIcon: 'power_settings_new',
uniqueIdentifier: 'shutdown_installation',
click: async () => {
const mobileMenu: HTMLDivElement =
document.querySelector('.mux_mobilemenu');
mobileMenu?.click();
this.shutdownInstallation();
},
},
{ {
type: 'normal', type: 'normal',
text: 'Dashboard', text: 'Dashboard',
@@ -187,6 +215,35 @@ export class MenuBar {
); );
} }
async shutdownInstallation() {
const confirmed = await MorphFeature.Confirm({
title: 'Shutdown Installation',
message: 'Are you sure you want to shutdown the installation?',
});
if (!confirmed) return;
MorphFeature.Loader({
active: true,
message: 'Shutting down installation...',
});
const shutdownContainer: HTMLDivElement =
document.querySelector('.ntsh_shutdown');
this._Main.socket.emit(
'shutdownInstallation',
(response: { succeed: boolean; message?: string }) => {
MorphFeature.Loader({ active: false });
if (!response.succeed)
return MorphFeature.Alert({
title: 'Error',
message: response.message,
});
shutdownContainer.style.display = 'flex';
}
);
}
async toggleServiceMode( async toggleServiceMode(
mode?: boolean, mode?: boolean,
skipPin?: boolean skipPin?: boolean

10
package-lock.json generated
View File

@@ -15,6 +15,7 @@
"@types/ws": "^8.18.1", "@types/ws": "^8.18.1",
"express": "^5.1.0", "express": "^5.1.0",
"fs-extra": "^11.3.2", "fs-extra": "^11.3.2",
"ping": "^1.0.0",
"socket.io": "^4.8.1", "socket.io": "^4.8.1",
"socket.io-client": "^4.8.1", "socket.io-client": "^4.8.1",
"twilio": "^5.10.3", "twilio": "^5.10.3",
@@ -1194,6 +1195,15 @@
"url": "https://opencollective.com/express" "url": "https://opencollective.com/express"
} }
}, },
"node_modules/ping": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/ping/-/ping-1.0.0.tgz",
"integrity": "sha512-3dxdgGtV+7P/EVo42JhkGSomeO/0GGicSz3mI/yK+AI+VGNAOfakw5XfcbGI4IjyBY+ZZwvuRXdhnNF2uliKew==",
"license": "MIT",
"engines": {
"node": ">=22.0.0"
}
},
"node_modules/proxy-addr": { "node_modules/proxy-addr": {
"version": "2.0.7", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",

View File

@@ -1,6 +1,6 @@
{ {
"name": "ntshcontrol", "name": "ntshcontrol",
"version": "1.0.0", "version": "2025.11.1",
"main": "dist/Entry.js", "main": "dist/Entry.js",
"scripts": { "scripts": {
"start": "node ." "start": "node ."
@@ -15,6 +15,7 @@
"@types/ws": "^8.18.1", "@types/ws": "^8.18.1",
"express": "^5.1.0", "express": "^5.1.0",
"fs-extra": "^11.3.2", "fs-extra": "^11.3.2",
"ping": "^1.0.0",
"socket.io": "^4.8.1", "socket.io": "^4.8.1",
"socket.io-client": "^4.8.1", "socket.io-client": "^4.8.1",
"twilio": "^5.10.3", "twilio": "^5.10.3",

View File

@@ -99,6 +99,7 @@ export class ConfigurationManager {
} }
export interface Config { export interface Config {
router: ConfigRouter;
webServer: ConfigWebServer; webServer: ConfigWebServer;
unity: ConfigUnity; unity: ConfigUnity;
cameraRunner: ConfigCameraRunner; cameraRunner: ConfigCameraRunner;
@@ -106,6 +107,11 @@ export interface Config {
support: ConfigSupport; support: ConfigSupport;
} }
export interface ConfigRouter {
ip: string;
waitForStartup: boolean;
}
export interface ConfigWebServer { export interface ConfigWebServer {
port: number; port: number;
} }

View File

@@ -4,6 +4,10 @@ export const DefaultConfiguration: Config = {
webServer: { webServer: {
port: 6300, port: 6300,
}, },
router: {
ip: '',
waitForStartup: true,
},
unity: { unity: {
executable: { executable: {
path: '', path: '',

View File

@@ -10,7 +10,10 @@ import { UnityRunner } from './Unity/UnityRunner';
import { UnityWebSocket } from './Unity/UnityWebSocket'; import { UnityWebSocket } from './Unity/UnityWebSocket';
import { TwilioHandler } from './Twilio'; import { TwilioHandler } from './Twilio';
import { delay } from './Utils'; import { delay } from './Utils';
import * as ping from 'ping';
import { shutdown } from './Shutdown';
const PREFIX = '[Main]';
export class Main { export class Main {
dataPath = join(homedir(), 'MorphixProductions', 'NTSHControl'); dataPath = join(homedir(), 'MorphixProductions', 'NTSHControl');
@@ -26,6 +29,9 @@ export class Main {
async start() { async start() {
await this.ConfigurationManager.load(); await this.ConfigurationManager.load();
await this.waitForRouter();
await this.WebServer.listen(); await this.WebServer.listen();
await this.Twilio.load(); await this.Twilio.load();
@@ -73,4 +79,41 @@ export class Main {
console.log('Restart complete.'); console.log('Restart complete.');
} }
async shutdown() {
console.log('Stopping UnityRunner...');
await this.UnityRunner.stop();
const doShutdown = process.argv.includes('--no-shutdown')
? false
: true;
if (doShutdown) {
console.log('Shutting down system...');
shutdown();
} else {
console.log('Shutdown skipped due to --no-shutdown flag.');
}
process.exit(0);
}
waitForRouter() {
if (this.Config.router?.waitForStartup !== true) return;
return new Promise<void>((resolve) => {
const check = () => {
console.log(PREFIX, 'Waiting for router...');
ping.sys.probe(this.Config.router.ip, async ({ alive }) => {
if (alive) {
console.log(PREFIX, 'Router is online');
await delay(3000);
return resolve();
}
await delay(1000);
check();
});
};
check();
});
}
} }

33
src/Shutdown.ts Normal file
View File

@@ -0,0 +1,33 @@
import { exec } from 'child_process';
export function shutdown(): Promise<{ succeed: boolean; message?: string }> {
if (process.platform === 'win32') {
return shutdownWindows();
}
return Promise.resolve({
succeed: false,
message: 'Platform not supported',
});
}
function shutdownWindows(): Promise<{ succeed: boolean; message?: string }> {
return new Promise<{ succeed: boolean; message?: string }>(
(resolve, reject) => {
exec('shutdown /s /t 5', (error, stdout, stderr) => {
if (error) {
console.error(
`Error shutting down Windows: ${error.message}`
);
return resolve({ succeed: false, message: error.message });
}
if (stderr) {
console.error(`Error shutting down Windows: ${stderr}`);
return resolve({ succeed: false, message: stderr });
}
console.log(`Windows shutdown command executed: ${stdout}`);
resolve({ succeed: true });
});
}
);
}

View File

@@ -180,7 +180,10 @@ export class UnityWebSocket {
return { return {
...slider, ...slider,
decimalPlaces: decimalPlaces:
slider.min == 0 && slider.max == 1 ? 2 : null, (slider.min == 0 || slider.min == -1) &&
slider.max == 1
? 2
: null,
}; };
} }
); );
@@ -189,7 +192,10 @@ export class UnityWebSocket {
return { return {
...slider, ...slider,
decimalPlaces: decimalPlaces:
slider.min == 0 && slider.max == 1 ? 2 : null, (slider.min == 0 || slider.min == -1) &&
slider.max == 1
? 2
: null,
}; };
}); });

View File

@@ -6,6 +6,7 @@ import { Main } from '../Main';
import { DashboardRouter } from './DashboardRouter'; import { DashboardRouter } from './DashboardRouter';
import { join } from 'path'; import { join } from 'path';
import { CalibrationRouter } from './CalibrationRouter'; import { CalibrationRouter } from './CalibrationRouter';
import { delay } from '../Utils';
const PREFIX = '[WebServer]'; const PREFIX = '[WebServer]';
export class WebServer { export class WebServer {
@@ -74,6 +75,20 @@ export class WebServer {
callback({ succeed: true }); callback({ succeed: true });
} }
); );
socket.on(
'shutdownInstallation',
async (
callback: (response: {
succeed: boolean;
message?: string;
}) => void
) => {
await delay(1000);
callback({ succeed: true });
this._Main.shutdown();
}
);
socket.on('cameraRunner', (command: string, ...args: any[]) => socket.on('cameraRunner', (command: string, ...args: any[]) =>
this._Main.CameraRunner.handle(command, ...args) this._Main.CameraRunner.handle(command, ...args)
); );